emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
blob d726e31b8cc9f8d4b20ca3236130e94395d9abb8 3439 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
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
 
(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)))))

(defun ox-bib-get-key (path &optional desc)
  "Extract cite key from a link path and desc.

Currently expects links in the format:
\[[type:key;pre;post;][desc]]"
  (nth 0 (split-string path ";")))

(defun ox-bib-get-pre (path &optional desc)
  "Extract pre-citation arg from a link path and desc.

Currently expects links in the format:
\[[type:key;pre;post;][desc]]"
  (or (nth 1 (split-string path ";")) ""))

(defun ox-bib-get-post (path &optional desc)
  "Extract post-citation arg from a link path and desc.

Currently expects links in the format:
\[[type:key;pre;post;][desc]]"
  (or (nth 2 (split-string path ";")) ""))

;; 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)
  (cond
   ((org-export-derived-backend-p format 'latex)
    (let ((key (ox-bib-get-key path desc))
	  (pre (ox-bib-get-pre path desc))
	  (post (ox-bib-get-post path desc)))
      (format "\\textcite[%s][%s]{%s}" pre post key)))
   (t
    (format "<textcite to: %s>" path))))

(defun ox-bib-parencite-export (path desc format)
  (cond
   ((org-export-derived-backend-p format 'latex)
    (let ((key (ox-bib-get-key path desc))
          (pre (ox-bib-get-pre path desc))
          (post (ox-bib-get-post path desc)))
      (format "\\parencite[%s][%s]{%s}" pre 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)

debug log:

solving d726e31 ...
found d726e31 in https://list.orgmode.org/orgmode/876213lqfk.fsf@gmail.com/

applying [1/1] https://list.orgmode.org/orgmode/876213lqfk.fsf@gmail.com/
diff --git a/lisp/ox-bib.el b/lisp/ox-bib.el
new file mode 100644
index 0000000..d726e31

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

index at:
100644 d726e31b8cc9f8d4b20ca3236130e94395d9abb8	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).