From 6428103e7199acbf947cacaa5860ac39b3b78b46 Mon Sep 17 00:00:00 2001 From: Aaron Ecay Date: Fri, 8 Mar 2013 13:41:00 -0500 Subject: [PATCH 2/3] Support bibliographies for export * lisp/ox.el (org-export-options-alist): Add BIBLIOGRAPHY * lisp/ox-latex.el (org-latex-template): Support bibliographies * lisp/ox-bib.el: Add file Add export support for bibliographies. Currently only works for BibLaTeX, using the latex backend. To use, put #+BIBLIOGRAPHY: file.bib in the header of the document, and (require 'ox-bib). Then use links of the form: [[textcite:bibtex-key&&pre=foo&&post=bar][whatever]] which will be exported to: \textcite[foo][bar]{bibtex-key} Using parencite as a link type is also supported. The BIBLIOGRAPHY keyword in the header will be translated to an appropriate \addbibresource command. --- lisp/ox-bib.el | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lisp/ox-latex.el | 8 +++++ lisp/ox.el | 1 + 3 files changed, 98 insertions(+) create mode 100644 lisp/ox-bib.el diff --git a/lisp/ox-bib.el b/lisp/ox-bib.el new file mode 100644 index 0000000..a3f9de9 --- /dev/null +++ b/lisp/ox-bib.el @@ -0,0 +1,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) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index a1cacf0..08cdd18 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -1192,6 +1192,14 @@ holding export options." (or (plist-get info :description) "") (if (not (plist-get info :with-creator)) "" (plist-get info :creator)))) + ;; Bibliography + (let* ((bibs (plist-get info :bibliography)) + (bib-cmds (mapconcat (lambda (s) + (format "\\addbibresource{%s}" s)) + bibs "\n"))) + (if bibs + (concat bib-cmds "\n") + "")) ;; Document start. "\\begin{document}\n\n" ;; Title command. diff --git a/lisp/ox.el b/lisp/ox.el index 40c0617..f405eff 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -118,6 +118,7 @@ (:select-tags "SELECT_TAGS" nil org-export-select-tags split) (:time-stamp-file nil "timestamp" org-export-time-stamp-file) (:title "TITLE" nil nil space) + (:bibliography "BIBLIOGRAPHY" nil nil split) (:with-archived-trees nil "arch" org-export-with-archived-trees) (:with-author nil "author" org-export-with-author) (:with-clocks nil "c" org-export-with-clocks) -- 1.8.1.5