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
(user-error "Invalid entry %S in `org-cite-biblatex-styles'" other))))))
(defun org-cite-biblatex-prepare-preamble (output _keys files style &rest _)
"Prepare document preamble for \"biblatex\" usage.
(defun org-cite-biblatex--generate-latex-usepackage (info)
"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
names used as the bibliography.
This function ensures \"biblatex\" package is required. It also adds resources
to the document, and set styles."
(with-temp-buffer
(save-excursion (insert output))
(when (search-forward "\\begin{document}" nil t)
;; Ensure there is a \usepackage{biblatex} somewhere or add one.
;; 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)))
(defun org-cite-biblatex--generate-latex-bibresources (info)
"From INFO generate LaTeX that loads the relevant bibliography resource files."
(let ((files (plist-get info :bibliography)))
(mapconcat (lambda (f)
(format "\\addbibresource%s{%s}"
(if (org-url-p f) "[location=remote]" "")
f))
files
"\n")))
;;; Register `biblatex' processor
(org-cite-register-processor 'biblatex
:export-bibliography #'org-cite-biblatex-export-bibliography
:export-citation #'org-cite-biblatex-export-citation
:export-finalizer #'org-cite-biblatex-prepare-preamble
:cite-styles #'org-cite-biblatex-list-styles)
(provide 'oc-biblatex)

View File

@ -847,27 +847,11 @@ INFO is the export state, as a property list."
;; process.
(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
(org-cite-register-processor 'csl
:export-citation #'org-cite-csl-render-citation
:export-bibliography #'org-cite-csl-render-bibliography
:export-finalizer #'org-cite-csl-finalizer
:cite-styles
'((("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"))

View File

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