oc-*: Make use of conditional preamble for export

* lisp/oc-natbib.el (org-cite-natbib-use-package): Refactor to make use
of the conditional/generated preamble.

* lisp/oc-csl.el (org-cite-csl-finalizer): Refactor to make use of
the conditional/generated preamble.

* lisp/oc-biblatex.el (org-cite-biblatex-prepare-preamble): Refactor to
make use of the conditional/generated preamble.
This commit is contained in:
TEC 2023-02-06 00:01:41 +08:00
parent 6be558e9cd
commit 180972266c
Signed by: tec
SSH Key Fingerprint: SHA256:eobz41Mnm0/iYWBvWThftS0ElEs1ftBr6jamutnXc/A
4 changed files with 63 additions and 84 deletions

View File

@ -376,61 +376,47 @@ INFO is the export state, as a property list."
(other (other
(user-error "Invalid entry %S in `org-cite-biblatex-styles'" other)))))) (user-error "Invalid entry %S in `org-cite-biblatex-styles'" other))))))
(defun org-cite-biblatex-prepare-preamble (output _keys files style &rest _) (defun org-cite-biblatex--generate-latex-usepackage (info)
"Prepare document preamble for \"biblatex\" usage. "Ensure that the biblatex package is loaded.
This is performed by extracting relevant information from the
INFO export plist, and modifying any existing
\\usepackage{biblatex} statement in the LaTeX header."
(let ((style (org-cite-bibliography-style info))
(usepackage-rx (rx "\\usepackage"
(opt (group "[" (*? anything) "]"))
"{biblatex}")))
(concat
(if (string-match usepackage-rx (plist-get info :latex-full-header))
;; "biblatex" package loaded, but with none (or different) options.
;; Replace with style-including command.
(plist-put info :latex-full-header
(replace-match
(format "\\usepackage%s{biblatex}"
(save-match-data
(org-cite-biblatex--package-options nil style)))
t t
(plist-get info :latex-full-header)))
;; No "biblatex" package loaded. Insert "usepackage" command
;; with appropriate options, including style.
(format "\\usepackage%s{biblatex}\n"
(org-cite-biblatex--package-options
org-cite-biblatex-options style))))))
OUTPUT is the final output of the export process. FILES is the list of file (defun org-cite-biblatex--generate-latex-bibresources (info)
names used as the bibliography. "From INFO generate LaTeX that loads the relevant bibliography resource files."
(let ((files (plist-get info :bibliography)))
This function ensures \"biblatex\" package is required. It also adds resources (mapconcat (lambda (f)
to the document, and set styles." (format "\\addbibresource%s{%s}"
(with-temp-buffer (if (org-url-p f) "[location=remote]" "")
(save-excursion (insert output)) f))
(when (search-forward "\\begin{document}" nil t) files
;; Ensure there is a \usepackage{biblatex} somewhere or add one. "\n")))
;; Then set options.
(goto-char (match-beginning 0))
(let ((re (rx "\\usepackage"
(opt (group "[" (*? anything) "]"))
"{biblatex}")))
(cond
;; No "biblatex" package loaded. Insert "usepackage" command
;; with appropriate options, including style.
((not (re-search-backward re nil t))
(save-excursion
(insert
(format "\\usepackage%s{biblatex}\n"
(org-cite-biblatex--package-options
org-cite-biblatex-options style)))))
;; "biblatex" package loaded, but without any option.
;; Include style only.
((not (match-beginning 1))
(search-forward "{" nil t)
(insert (org-cite-biblatex--package-options nil style)))
;; "biblatex" package loaded with some options set. Override
;; style-related options with ours.
(t
(replace-match
(save-match-data
(org-cite-biblatex--package-options (match-string 1) style))
nil nil nil 1))))
;; Insert resources below.
(forward-line)
(insert (mapconcat (lambda (f)
(format "\\addbibresource%s{%s}"
(if (org-url-p f) "[location=remote]" "")
f))
files
"\n")
"\n"))
(buffer-string)))
;;; Register `biblatex' processor ;;; Register `biblatex' processor
(org-cite-register-processor 'biblatex (org-cite-register-processor 'biblatex
:export-bibliography #'org-cite-biblatex-export-bibliography :export-bibliography #'org-cite-biblatex-export-bibliography
:export-citation #'org-cite-biblatex-export-citation :export-citation #'org-cite-biblatex-export-citation
:export-finalizer #'org-cite-biblatex-prepare-preamble
:cite-styles #'org-cite-biblatex-list-styles) :cite-styles #'org-cite-biblatex-list-styles)
(provide 'oc-biblatex) (provide 'oc-biblatex)

View File

@ -847,27 +847,11 @@ INFO is the export state, as a property list."
;; process. ;; process.
(org-cite-parse-elements output))))) (org-cite-parse-elements output)))))
(defun org-cite-csl-finalizer (output _keys _files _style _backend info)
"Add \"hanging\" package if missing from LaTeX output.
OUTPUT is the export document, as a string. INFO is the export state, as a
property list."
(org-cite-csl--barf-without-citeproc)
(if (not (eq 'org-latex (org-cite-csl--output-format info)))
output
(with-temp-buffer
(save-excursion (insert output))
(when (search-forward "\\begin{document}" nil t)
(goto-char (match-beginning 0))
;; Insert the CSL-specific parts of the LaTeX preamble.
(insert (org-cite-csl--generate-latex-preamble info)))
(buffer-string))))
;;; Register `csl' processor ;;; Register `csl' processor
(org-cite-register-processor 'csl (org-cite-register-processor 'csl
:export-citation #'org-cite-csl-render-citation :export-citation #'org-cite-csl-render-citation
:export-bibliography #'org-cite-csl-render-bibliography :export-bibliography #'org-cite-csl-render-bibliography
:export-finalizer #'org-cite-csl-finalizer
:cite-styles :cite-styles
'((("author" "a") ("bare" "b") ("caps" "c") ("full" "f") ("bare-caps" "bc") ("caps-full" "cf") ("bare-caps-full" "bcf")) '((("author" "a") ("bare" "b") ("caps" "c") ("full" "f") ("bare-caps" "bc") ("caps-full" "cf") ("bare-caps-full" "bcf"))
(("noauthor" "na") ("bare" "b") ("caps" "c") ("bare-caps" "bc")) (("noauthor" "na") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))

View File

@ -168,32 +168,25 @@ state, as a property list."
(org-cite-natbib--build-optional-arguments citation info) (org-cite-natbib--build-optional-arguments citation info)
(org-cite-natbib--build-arguments citation))) (org-cite-natbib--build-arguments citation)))
(defun org-cite-natbib-use-package (output &rest _) (defun org-cite-natbib--generate-latex-preamble (info)
"Ensure output requires \"natbib\" package. "Ensure that the \"natbib\" package is loaded.
OUTPUT is the final output of the export process." INFO is a plist used as a communication channel."
(with-temp-buffer (and (not (string-match
(save-excursion (insert output)) (rx "\\usepackage" (opt "[" (*? nonl) "]") "{natbib}")
(when (search-forward "\\begin{document}" nil t) (plist-get info :latex-full-header)))
;; Ensure there is a \usepackage{natbib} somewhere or add one. (format "\\usepackage%s{natbib}\n"
(goto-char (match-beginning 0)) (if (null org-cite-natbib-options)
(let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{natbib}"))) ""
(unless (re-search-backward re nil t) (format "[%s]"
(insert (mapconcat #'symbol-name
(format "\\usepackage%s{natbib}\n" org-cite-natbib-options
(if (null org-cite-natbib-options) ","))))))
""
(format "[%s]"
(mapconcat #'symbol-name
org-cite-natbib-options
","))))))))
(buffer-string)))
;;; Register `natbib' processor ;;; Register `natbib' processor
(org-cite-register-processor 'natbib (org-cite-register-processor 'natbib
:export-bibliography #'org-cite-natbib-export-bibliography :export-bibliography #'org-cite-natbib-export-bibliography
:export-citation #'org-cite-natbib-export-citation :export-citation #'org-cite-natbib-export-citation
:export-finalizer #'org-cite-natbib-use-package
:cite-styles :cite-styles
'((("author" "a") ("caps" "a") ("full" "f")) '((("author" "a") ("caps" "a") ("full" "f"))
(("noauthor" "na") ("bare" "b")) (("noauthor" "na") ("bare" "b"))

View File

@ -1460,6 +1460,22 @@ default values of which are given by `org-latex-engraved-preamble' and
"% WARNING syntax highlighting unavailable as engrave-faces-latex was missing.\n") "% WARNING syntax highlighting unavailable as engrave-faces-latex was missing.\n")
"\n"))) "\n")))
;; Citation features
(org-export-update-features 'latex
(bibliography-csl
:condition (eq (org-cite-processor info) 'csl)
:when bibliography
:snippet org-cite-csl--generate-latex-preamble)
(bibliography-biblatex
:condition (eq (org-cite-processor info) 'biblatex)
:when bibliography
:snippet org-cite-biblatex--generate-latex-preamble)
(bibliography-natbib
:condition (eq (org-cite-processor info) 'natbib)
:when bibliography
:snippet org-cite-natbib--generate-latex-preamble))
;;;; Compilation ;;;; Compilation
(defcustom org-latex-compiler-file-string "%% Intended LaTeX compiler: %s\n" (defcustom org-latex-compiler-file-string "%% Intended LaTeX compiler: %s\n"