forked from mirrors/org-mode
oc-csl: Improve LaTeX bibliography formatting
* lisp/oc-csl.el (org-cite-csl--output-format): Use the dedicated 'org-latex' citeproc formatter to export references in LaTeX. (org-cite-csl-latex-preamble, org-cite-csl--generate-latex-preamble, org-cite-csl-finalizer): Insert a preamble fragment compatible with the 'org-latex' citeproc formatter. (org-cite-csl-latex-label-separator, org-cite-csl-latex-label-width-per-char): Introduce additional variables to control bibliography formatting. * etc/ORG-NEWS: Describe the introduced new options.
This commit is contained in:
parent
e5a3a07cac
commit
29103fc602
27
etc/ORG-NEWS
27
etc/ORG-NEWS
|
@ -13,6 +13,33 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
|
|||
|
||||
* Version 9.7 (not released yet)
|
||||
** New options
|
||||
*** New custom settings for the "csl" citation export processor's LaTeX output
|
||||
|
||||
The settings ~org-cite-csl-latex-label-separator~ and
|
||||
~org-cite-csl-latex-label-width-per-char~ allow the user to control
|
||||
the indentation of entries for labeled bibliography styles when the
|
||||
"csl" citation processor is used for LaTeX export. The indentation
|
||||
length is computed as the sum of ~org-cite-csl-latex-label-separator~
|
||||
and the maximal label width, for example:
|
||||
|
||||
#+begin_example
|
||||
indentation length
|
||||
<------------------------->
|
||||
max. label width separator
|
||||
<---------------><-------->
|
||||
[Doe22] John Doe. A title...
|
||||
[DoeSmithJones19] John Doe, Jane Smith and...
|
||||
[SmithDoe02] Jane Smith and John Doe...
|
||||
#+end_example
|
||||
|
||||
The maximal label width, in turn, is calculated as the product of
|
||||
~org-cite-csl-latex-label-width-per-char~ and the maximal label length
|
||||
measured in characters.
|
||||
|
||||
The setting ~org-cite-csl-latex-preamble~ makes it possible to
|
||||
customize the entire LaTeX fragment that the "csl" citation processor injects
|
||||
into the preamble.
|
||||
|
||||
*** New ~org-latex-listings-src-omit-language~ customization for LaTeX export
|
||||
|
||||
The ~org-latex-listings-src-omit-language~ customization variable
|
||||
|
|
145
lisp/oc-csl.el
145
lisp/oc-csl.el
|
@ -214,6 +214,111 @@ Used only when `second-field-align' is activated by the used CSL style."
|
|||
:type 'string
|
||||
:safe #'stringp)
|
||||
|
||||
(defcustom org-cite-csl-latex-label-separator "0.6em"
|
||||
"Distance between citation label and bibliography item for LaTeX
|
||||
output in valid LaTeX units. Used only when `second-field-align'
|
||||
is activated by the used CSL style.
|
||||
|
||||
The indentation length in these cases is computed as the sum of
|
||||
`org-cite-csl-latex-label-separator' and the maximal label width,
|
||||
for example,
|
||||
|
||||
indentation length
|
||||
<------------------------->
|
||||
max. label width separator
|
||||
<---------------><-------->
|
||||
[Doe22] John Doe. A title...
|
||||
[DoeSmithJones19] John Doe, Jane Smith and...
|
||||
[SmithDoe02] Jane Smith and John Doe...
|
||||
|
||||
The maximal label width, in turn, is calculated as the product of
|
||||
`org-cite-csl-latex-label-width-per-char' and the maximal label
|
||||
length measured in characters."
|
||||
:group 'org-cite
|
||||
:package-version '(Org . "9.7")
|
||||
:type 'string
|
||||
:safe #'stringp)
|
||||
|
||||
(defcustom org-cite-csl-latex-label-width-per-char "0.45em"
|
||||
"Character width in LaTeX units for calculating entry label widths.
|
||||
Used only when `second-field-align' is activated by the used CSL
|
||||
style.
|
||||
|
||||
See the documentation of `org-cite-csl-latex-label-separator' for
|
||||
details."
|
||||
:group 'org-cite
|
||||
:package-version '(Org . "9.7")
|
||||
:type 'string
|
||||
:safe #'stringp)
|
||||
|
||||
;; The following was inspired by and in many details follows how
|
||||
;; Pandoc's (<https://github.com/jgm/pandoc>) default LaTeX template
|
||||
;; handles CSL output. Many thanks to the author, John MacFarlane!
|
||||
(defcustom org-cite-csl-latex-preamble
|
||||
"\\usepackage{calc}
|
||||
\\newlength{\\cslhangindent}
|
||||
\\setlength{\\cslhangindent}{[CSL-HANGINDENT]}
|
||||
\\newlength{\\csllabelsep}
|
||||
\\setlength{\\csllabelsep}{[CSL-LABELSEP]}
|
||||
\\newlength{\\csllabelwidth}
|
||||
\\setlength{\\csllabelwidth}{[CSL-LABELWIDTH-PER-CHAR] * [CSL-MAXLABEL-CHARS]}
|
||||
\\newenvironment{cslbibliography}[2] % 1st arg. is hanging-indent, 2nd entry spacing.
|
||||
{% By default, paragraphs are not indented.
|
||||
\\setlength{\\parindent}{0pt}
|
||||
% Hanging indent is turned on when first argument is 1.
|
||||
\\ifodd #1
|
||||
\\let\\oldpar\\par
|
||||
\\def\\par{\\hangindent=\\cslhangindent\\oldpar}
|
||||
\\fi
|
||||
% Set entry spacing based on the second argument.
|
||||
\\setlength{\\parskip}{\\parskip + #2\\baselineskip}
|
||||
}%
|
||||
{}
|
||||
\\newcommand{\\cslblock}[1]{#1\\hfill\\break}
|
||||
\\newcommand{\\cslleftmargin}[1]{\\parbox[t]{\\csllabelsep + \\csllabelwidth}{#1}}
|
||||
\\newcommand{\\cslrightinline}[1]
|
||||
{\\parbox[t]{\\linewidth - \\csllabelsep - \\csllabelwidth}{#1}\\break}
|
||||
\\newcommand{\\cslindent}[1]{\\hspace{\\cslhangindent}#1}
|
||||
\\newcommand{\\cslbibitem}[2]
|
||||
{\\leavevmode\\vadjust pre{\\hypertarget{citeproc_bib_item_#1}{}}#2}
|
||||
\\makeatletter
|
||||
\\newcommand{\\cslcitation}[2]
|
||||
{\\protect\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}
|
||||
\\makeatother"
|
||||
"LaTeX preamble content inserted by the `csl' citation processor.
|
||||
|
||||
This preamble can be anything as long as it provides definitions
|
||||
for the environment and commands that Citeproc's `org-latex'
|
||||
formatter uses for formatting citations and bibliographies. In
|
||||
particular, it has to define
|
||||
- the commands \\cslblock{<text>}, \\cslleftmargin{<text>},
|
||||
\\cslrightinline{<text>} and \\cslindent{<text>} for formatting
|
||||
text that have, respectively, the CSL display attributes
|
||||
`block', `left-margin', `right-inline' and `indent';
|
||||
- the commands \\cslcitation{<item_no>}{<item_text>} and
|
||||
\\cslbibitem{<item_no>}{<item_text>}, which are used to
|
||||
format individual citations and bibliography items, including
|
||||
hyperlinking citations to the corresponding bibliography entry
|
||||
using their numerical id, which is passed as the first,
|
||||
<item_no> argument;
|
||||
- and the environment \\cslbibliography{<hanging-indent>}{<entry-spacing>},
|
||||
in which bibliographies are wrapped; the value of the
|
||||
<hanging-indent> argument is 1 if hanging indent should be
|
||||
applied and 0 if not, while the <entry-spacing> argument is an
|
||||
integer specifying the number of extra line-heights
|
||||
required between bibliography entries in addition to normal
|
||||
line spacing.
|
||||
|
||||
When present, the placeholders [CSL-HANGINDENT], [CSL-LABELSEP],
|
||||
[CSL-LABELWIDTH-PER-CHAR] and [CSL-MAXLABEL-CHARS] are replaced,
|
||||
respectively, by the contents of the customizable variables
|
||||
`org-cite-csl-latex-hanging-indent', `org-cite-csl-latex-label-separator',
|
||||
`org-cite-csl-latex-label-width-per-char', and the maximal label length
|
||||
in the bibliography measured in characters."
|
||||
:group 'org-cite
|
||||
:type 'string
|
||||
:package-version '(Org . "9.7"))
|
||||
|
||||
|
||||
;;; Internal variables
|
||||
(defconst org-cite-csl--etc-dir
|
||||
|
@ -413,7 +518,7 @@ corresponding to one of the output formats supported by Citeproc: `html',
|
|||
(let ((backend (plist-get info :back-end)))
|
||||
(cond
|
||||
((org-export-derived-backend-p backend 'html) 'html)
|
||||
((org-export-derived-backend-p backend 'latex) 'latex)
|
||||
((org-export-derived-backend-p backend 'latex) 'org-latex)
|
||||
(t 'org))))
|
||||
|
||||
(defun org-cite-csl--style-file (info)
|
||||
|
@ -670,6 +775,21 @@ value is the bibliography as rendered by Citeproc."
|
|||
(plist-put info :cite-citeproc-rendered-bibliographies result)
|
||||
result)))))
|
||||
|
||||
(defun org-cite-csl--generate-latex-preamble (info)
|
||||
"Generate the CSL-related part of the LaTeX preamble.
|
||||
INFO is the export state, as a property list."
|
||||
(let* ((parameters (cadr (org-cite-csl--rendered-bibliographies info)))
|
||||
(max-offset (cdr (assq 'max-offset parameters)))
|
||||
(result org-cite-csl-latex-preamble))
|
||||
(map-do (lambda (placeholder replacement)
|
||||
(when (string-match placeholder result)
|
||||
(setq result (replace-match replacement t t result))))
|
||||
`("\\[CSL-HANGINDENT\\]" ,org-cite-csl-latex-hanging-indent
|
||||
"\\[CSL-LABELSEP\\]" ,org-cite-csl-latex-label-separator
|
||||
"\\[CSL-LABELWIDTH-PER-CHAR\\]" ,org-cite-csl-latex-label-width-per-char
|
||||
"\\[CSL-MAXLABEL-CHARS\\]" ,(number-to-string max-offset)))
|
||||
result))
|
||||
|
||||
|
||||
;;; Export capability
|
||||
(defun org-cite-csl-render-citation (citation _style _backend info)
|
||||
|
@ -688,8 +808,8 @@ INFO is the export state, as a property list."
|
|||
INFO is the export state, as a property list."
|
||||
(org-cite-csl--barf-without-citeproc)
|
||||
(pcase-let* ((format (org-cite-csl--output-format info))
|
||||
(`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
|
||||
(output (cdr (assoc props outputs))))
|
||||
(`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
|
||||
(output (cdr (assoc props outputs))))
|
||||
(pcase format
|
||||
('html
|
||||
(concat
|
||||
|
@ -714,12 +834,7 @@ INFO is the export state, as a property list."
|
|||
org-cite-csl-html-hanging-indent
|
||||
org-cite-csl-html-hanging-indent))
|
||||
output))
|
||||
('latex
|
||||
(if (cdr (assq 'hanging-indent parameters))
|
||||
(format "\\begin{hangparas}{%s}{1}\n%s\n\\end{hangparas}"
|
||||
org-cite-csl-latex-hanging-indent
|
||||
output)
|
||||
output))
|
||||
('org-latex output)
|
||||
(_
|
||||
;; Parse Org output to re-export it during the regular export
|
||||
;; process.
|
||||
|
@ -730,18 +845,14 @@ INFO is the export state, as a property list."
|
|||
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 'latex (org-cite-csl--output-format info)))
|
||||
(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))
|
||||
;; Ensure that \citeprocitem is defined for citeproc-el.
|
||||
(insert "\\makeatletter\n\\newcommand{\\citeprocitem}[2]{\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}\n\\makeatother\n\n")
|
||||
;; Ensure there is a \usepackage{hanging} somewhere or add one.
|
||||
(let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{hanging}")))
|
||||
(unless (re-search-backward re nil t)
|
||||
(insert "\\usepackage[notquote]{hanging}\n"))))
|
||||
(goto-char (match-beginning 0))
|
||||
;; Insert the CSL-specific parts of the LaTeX preamble.
|
||||
(insert (org-cite-csl--generate-latex-preamble info)))
|
||||
(buffer-string))))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue