emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
blob a3f9de9df72acef95c508e7a7c82c4b05af63241 2733 bytes (raw)
name: lisp/ox-bib.el 	 # note: path name is non-authoritative(*)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 
(require 'bibtex)
(require 'ox)

(defvar ox-bib-find-entries-in-org-file nil
  "Whether to look for bibliogrpahy entries in an org mode file
or a bibtex file.")

(defun ox-bib-get-bibliography ()
  (mapcar (lambda (s)
            (org-no-properties s))
	  ;; Don't explode if before the first headline
          (or
           (condition-case nil
               (plist-get (org-export-get-environment nil t) :bibliography)
             (error nil))
           (save-excursion
             (widen)
             (goto-char (point-min))
             (plist-get (org-export-get-environment) :bibliography)))))

;; Adapted from org-find-entry-with-custom-id; there might be a better
;; way to do this
(defun org-find-entry-with-custom-id (ident)
  (let ((id ident)
        (case-fold-search nil))
    (save-excursion
      (save-restriction
        (widen)
        (goto-char (point-min))
        (when (re-search-forward
               (concat "^[ \t]*:CUSTOM_ID:[ \t]+" (regexp-quote id) "[ \t]*$")
               nil t)
          (org-back-to-heading t)
          (point))))))

(defun ox-bib-cite-follow (path)
  (let* ((files (ox-bib-get-bibliography))
	 (key (ox-bib-get-key path))
	 file done)
    (when ox-bib-find-entries-in-org-file
      (setq files
	    (mapcar (lambda (s)
		      (replace-regexp-in-string "\\.bib\\'" ".org" s))
		    files)))
    (while (and (car-safe files) (not done))
      (setq file (car-safe files))
      (when (file-exists-p file)
        (let* ((buf (find-file-noselect file))

	       (pos (with-current-buffer buf
		      (cond
		       (ox-bib-find-entries-in-org-file
			(org-find-entry-with-custom-id key))
		       (t (bibtex-search-entry key))))))
	  (when pos
	    (setq done (cons buf pos)))))
      (setq files (cdr files)))
    (if done
	(progn
          (pop-to-buffer (car done))
	  (goto-char (cdr done))
          (when ox-bib-find-entries-in-org-file
            (org-show-context)))
      (message "Citation not found: %s" key))))

(defun ox-bib-textcite-export (path desc format &optional props)
  (cond
   ((org-export-derived-backend-p format 'latex)
    (format "\\textcite[%s][%s]{%s}"
	    (plist-get props :pre)
	    (plist-get props :post)
	    key))
   (t
    (format "[textcite to: %s]" path))))

(defun ox-bib-parencite-export (path desc format &optional props)
  (cond
   ((org-export-derived-backend-p format 'latex)
    (format "\\parencite[%s][%s]{%s}"
            (plist-get props :pre)
            (plist-get props :post)
            key))
   (t
    (format "[parencite to: %s]" path))))

(org-add-link-type "textcite" #'ox-bib-cite-follow #'ox-bib-textcite-export)
(org-add-link-type "parencite" #'ox-bib-cite-follow #'ox-bib-parencite-export)

(provide 'ox-bib)

debug log:

solving a3f9de9 ...
found a3f9de9 in https://yhetil.org/orgmode/87wqthk7vj.fsf@gmail.com/

applying [1/1] https://yhetil.org/orgmode/87wqthk7vj.fsf@gmail.com/
diff --git a/lisp/ox-bib.el b/lisp/ox-bib.el
new file mode 100644
index 0000000..a3f9de9

Checking patch lisp/ox-bib.el...
Applied patch lisp/ox-bib.el cleanly.

index at:
100644 a3f9de9df72acef95c508e7a7c82c4b05af63241	lisp/ox-bib.el

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).