summaryrefslogtreecommitdiff
path: root/lisp/org/ox-latex.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org/ox-latex.el')
-rw-r--r--lisp/org/ox-latex.el257
1 files changed, 165 insertions, 92 deletions
diff --git a/lisp/org/ox-latex.el b/lisp/org/ox-latex.el
index 149492fa849..993c2c6431d 100644
--- a/lisp/org/ox-latex.el
+++ b/lisp/org/ox-latex.el
@@ -121,6 +121,7 @@
(:latex-classes nil nil org-latex-classes)
(:latex-default-figure-position nil nil org-latex-default-figure-position)
(:latex-default-table-environment nil nil org-latex-default-table-environment)
+ (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
(:latex-default-table-mode nil nil org-latex-default-table-mode)
(:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
(:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
@@ -296,7 +297,7 @@
("uk" "ukrainian")
("ur" "urdu")
("vi" "vietnamese"))
- "Alist between language code and corresponding Polyglossia option")
+ "Alist between language code and corresponding Polyglossia option.")
(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr")
("qbordermatrix" . "\\cr")
@@ -307,14 +308,14 @@
(format
"\\`[ \t]*\\\\begin{%s\\*?}"
(regexp-opt
- '("equation" "eqnarray" "math" "displaymath"
- "align" "gather" "multline" "flalign" "alignat"
- "xalignat" "xxalignat"
- "subequations"
- ;; breqn
- "dmath" "dseries" "dgroup" "darray"
- ;; empheq
- "empheq")))
+ '("equation" "eqnarray" "math" "displaymath"
+ "align" "gather" "multline" "flalign" "alignat"
+ "xalignat" "xxalignat"
+ "subequations"
+ ;; breqn
+ "dmath" "dseries" "dgroup" "darray"
+ ;; empheq
+ "empheq")))
"Regexp of LaTeX math environments.")
@@ -345,7 +346,7 @@ symbols are: `image', `table', `src-block' and `special-block'."
(const :tag "Special blocks" special-block))))
(defcustom org-latex-prefer-user-labels nil
- "Use user-provided labels instead of internal ones when non-nil.
+ "Use user-provided labels instead of internal ones when non-nil.
When this variable is non-nil, Org will use the value of
CUSTOM_ID property, NAME keyword or Org target as the key for the
@@ -380,6 +381,9 @@ will be exported to LaTeX as:
This is section \\ref{sec:foo}.
And this is still section \\ref{sec:foo}.
+A non-default value of `org-latex-reference-command' will change the
+command (\\ref by default) used to create label references.
+
Note, however, that setting this variable introduces a limitation
on the possible values for CUSTOM_ID and NAME. When this
variable is non-nil, Org passes their value to \\label unchanged.
@@ -399,6 +403,18 @@ references."
:version "26.1"
:package-version '(Org . "8.3"))
+(defcustom org-latex-reference-command "\\ref{%s}"
+ "Format string that takes a reference to produce a LaTeX reference command.
+
+The reference is a label such as sec:intro. A format string of \"\\ref{%s}\"
+produces numbered references and will always work. It may be desirable to make
+use of a package such as hyperref or cleveref and then change the format string
+to \"\\autoref{%s}\" or \"\\cref{%s}\" for example."
+ :group 'org-export-latex
+ :type 'string
+ :package-version '(Org . "9.5")
+ :safe t)
+
;;;; Preamble
(defcustom org-latex-default-class "article"
@@ -772,6 +788,13 @@ default we use here encompasses both."
:package-version '(Org . "8.0")
:type 'string)
+(defcustom org-latex-default-quote-environment "quote"
+ "Default environment used to `quote' blocks."
+ :group 'org-export-latex
+ :package-version '(Org . "9.5")
+ :type 'string
+ :safe t)
+
(defcustom org-latex-default-table-mode 'table
"Default mode for tables.
@@ -932,7 +955,7 @@ using customize, or with
(add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\"))
In addition, it is necessary to install pygments
-\(URL `http://pygments.org>'), and to configure the variable
+\(URL `https://pygments.org>'), and to configure the variable
`org-latex-pdf-process' so that the -shell-escape option is
passed to pdflatex.
@@ -956,7 +979,7 @@ URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'."
(tex "TeX") (latex "[LaTeX]TeX")
(shell-script "bash")
(gnuplot "Gnuplot")
- (ocaml "Caml") (caml "Caml")
+ (ocaml "[Objective]Caml") (caml "Caml")
(sql "SQL") (sqlite "sql")
(makefile "make")
(R "r"))
@@ -1157,9 +1180,11 @@ A better approach is to use a compiler suit such as `latexmk'."
:package-version '(Org . "9.0"))
(defcustom org-latex-pdf-process
- '("%latex -interaction nonstopmode -output-directory %o %f"
- "%latex -interaction nonstopmode -output-directory %o %f"
- "%latex -interaction nonstopmode -output-directory %o %f")
+ (if (executable-find "latexmk")
+ '("latexmk -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f")
+ '("%latex -interaction nonstopmode -output-directory %o %f"
+ "%latex -interaction nonstopmode -output-directory %o %f"
+ "%latex -interaction nonstopmode -output-directory %o %f"))
"Commands to process a LaTeX file to a PDF file.
This is a list of strings, each of them will be given to the
@@ -1203,7 +1228,7 @@ file name as its single argument."
(const :tag "texi2dvi"
("cd %o; LATEX=\"%latex\" texi2dvi -p -b -V %b.tex"))
(const :tag "latexmk"
- ("latexmk -g -pdf -pdflatex=\"%latex\" -outdir=%o %f"))
+ ("latexmk -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f"))
(function)))
(defcustom org-latex-logfiles-extensions
@@ -1486,7 +1511,10 @@ nil."
(pcase-let ((`(,keyword ,value) pair))
(concat keyword
(and (> (length value) 0)
- (concat "=" value)))))
+ (concat "="
+ (if (string-match-p (rx (any "[]")) value)
+ (format "{%s}" value)
+ value))))))
options
","))
@@ -1521,22 +1549,23 @@ INFO is a plist used as a communication channel. See
separator
(replace-regexp-in-string "\n" " " text)
separator)))
- ;; Handle the `protectedtexttt' special case: Protect some
- ;; special chars and use "\texttt{%s}" format string.
- (protectedtexttt
- (format "\\texttt{%s}"
- (replace-regexp-in-string
- "--\\|[\\{}$%&_#~^]"
- (lambda (m)
- (cond ((equal m "--") "-{}-")
- ((equal m "\\") "\\textbackslash{}")
- ((equal m "~") "\\textasciitilde{}")
- ((equal m "^") "\\textasciicircum{}")
- (t (org-latex--protect-text m))))
- text nil t)))
+ (protectedtexttt (org-latex--protect-texttt text))
;; Else use format string.
(t (format fmt text)))))
+(defun org-latex--protect-texttt (text)
+ "Protect special chars, then wrap TEXT in \"\\texttt{}\"."
+ (format "\\texttt{%s}"
+ (replace-regexp-in-string
+ "--\\|[\\{}$%&_#~^]"
+ (lambda (m)
+ (cond ((equal m "--") "-{}-")
+ ((equal m "\\") "\\textbackslash{}")
+ ((equal m "~") "\\textasciitilde{}")
+ ((equal m "^") "\\textasciicircum{}")
+ (t (org-latex--protect-text m))))
+ text nil t)))
+
(defun org-latex--delayed-footnotes-definitions (element info)
"Return footnotes definitions in ELEMENT as a string.
@@ -1604,9 +1633,9 @@ INFO is a plist used as a communication channel."
"Insert LaTeX_compiler info into the document.
INFO is a plist used as a communication channel."
(let ((compiler (plist-get info :latex-compiler)))
- (and (org-string-nw-p org-latex-compiler-file-string)
- (member (or compiler "") org-latex-compilers)
- (format org-latex-compiler-file-string compiler))))
+ (and (org-string-nw-p org-latex-compiler-file-string)
+ (member (or compiler "") org-latex-compilers)
+ (format org-latex-compiler-file-string compiler))))
;;; Filters
@@ -1888,10 +1917,11 @@ CONTENTS is nil. INFO is a plist holding contextual information."
(org-export-get-footnote-definition footnote-reference info)
info t)))
;; Use \footnotemark if reference is within another footnote
- ;; reference, footnote definition, table cell or item's tag.
+ ;; reference, footnote definition, table cell, verse block, or
+ ;; item's tag.
((or (org-element-lineage footnote-reference
'(footnote-reference footnote-definition
- table-cell))
+ table-cell verse-block))
(eq 'item (org-element-type
(org-export-get-parent-element footnote-reference))))
"\\footnotemark")
@@ -1903,7 +1933,8 @@ CONTENTS is nil. INFO is a plist holding contextual information."
;; Only insert a \label if there exist another
;; reference to def.
(cond ((not label) "")
- ((org-element-map (plist-get info :parse-tree) 'footnote-reference
+ ((org-element-map (plist-get info :parse-tree)
+ 'footnote-reference
(lambda (f)
(and (not (eq f footnote-reference))
(equal (org-element-property :label f) label)
@@ -1952,10 +1983,16 @@ holding contextual information."
;; Create a temporary export back-end that hard-codes
;; "\underline" within "\section" and alike.
(section-back-end
- (org-export-create-backend
- :parent 'latex
- :transcoders
- '((underline . (lambda (o c i) (format "\\underline{%s}" c))))))
+ (org-export-create-backend
+ :parent 'latex
+ :transcoders
+ '((underline . (lambda (o c i) (format "\\underline{%s}" c)))
+ ;; LaTeX isn't happy when you try to use \verb inside the argument of other
+ ;; commands (like \section, etc.), and this causes compilation to fail.
+ ;; So, within headings it's a good idea to replace any instances of \verb
+ ;; with \texttt.
+ (code . (lambda (o _ _) (org-latex--protect-texttt (org-element-property :value o))))
+ (verbatim . (lambda (o _ _) (org-latex--protect-texttt (org-element-property :value o)))))))
(text
(org-export-data-with-backend
(org-element-property :title headline) section-back-end info))
@@ -2089,8 +2126,8 @@ contextual information."
(let* ((code (org-element-property :value inline-src-block))
(separator (org-latex--find-verb-separator code)))
(cl-case (plist-get info :latex-listings)
- ;; Do not use a special package: transcode it verbatim.
- ((nil) (format "\\texttt{%s}" (org-latex--text-markup code 'code info)))
+ ;; Do not use a special package: transcode it verbatim, as code.
+ ((nil) (org-latex--text-markup code 'code info))
;; Use minted package.
(minted
(let* ((org-lang (org-element-property :language inline-src-block))
@@ -2375,8 +2412,8 @@ used as a communication channel."
((string= float "sideways") 'sideways)
((string= float "multicolumn") 'multicolumn)
((and (plist-member attr :float) (not float)) 'nonfloat)
- ((or float
- (org-element-property :caption parent)
+ (float float)
+ ((or (org-element-property :caption parent)
(org-string-nw-p (plist-get attr :caption)))
'figure)
(t 'nonfloat))))
@@ -2468,6 +2505,18 @@ used as a communication channel."
nil t))))
;; Return proper string, depending on FLOAT.
(pcase float
+ ((and (pred stringp) env-string)
+ (format "\\begin{%s}%s
+%s%s
+%s%s
+%s\\end{%s}"
+ env-string
+ placement
+ (if caption-above-p caption "")
+ (if center "\\centering" "")
+ comment-include image-code
+ (if caption-above-p "" caption)
+ env-string))
(`wrap (format "\\begin{wrapfigure}%s
%s%s
%s%s
@@ -2574,7 +2623,7 @@ INFO is a plist holding contextual information. See
(let ((label (org-latex--label destination info t)))
(if (and (not desc)
(org-export-numbered-headline-p destination info))
- (format "\\ref{%s}" label)
+ (format org-latex-reference-command label)
(format "\\hyperref[%s]{%s}" label
(or desc
(org-export-data
@@ -2582,7 +2631,7 @@ INFO is a plist holding contextual information. See
;; Fuzzy link points to a target. Do as above.
(otherwise
(let ((ref (org-latex--label destination info t)))
- (if (not desc) (format "\\ref{%s}" ref)
+ (if (not desc) (format org-latex-reference-command ref)
(format "\\hyperref[%s]{%s}" ref desc)))))))
;; Coderef: replace link with the reference name or the
;; equivalent line number.
@@ -2874,9 +2923,19 @@ channel."
"Transcode a QUOTE-BLOCK element from Org to LaTeX.
CONTENTS holds the contents of the block. INFO is a plist
holding contextual information."
- (org-latex--wrap-label
- quote-block (format "\\begin{quote}\n%s\\end{quote}" contents) info))
-
+ (let ((environment
+ (or (org-export-read-attribute :attr_latex quote-block :environment)
+ (plist-get info :latex-default-quote-environment)))
+ (options
+ (or (org-export-read-attribute :attr_latex quote-block :options)
+ "")))
+ (org-latex--wrap-label
+ quote-block (format "\\begin{%s}%s\n%s\\end{%s}"
+ environment
+ options
+ contents
+ environment)
+ info)))
;;;; Radio Target
@@ -2935,22 +2994,20 @@ contextual information."
(cond
;; Case 1. No source fontification.
((or (not lang) (not listings))
- (let* ((caption-str (org-latex--caption/label-string src-block info))
- (float-env
- (cond ((string= "multicolumn" float)
- (format "\\begin{figure*}[%s]\n%s%%s\n%s\\end{figure*}"
- (plist-get info :latex-default-figure-position)
- (if caption-above-p caption-str "")
- (if caption-above-p "" caption-str)))
- (caption (concat
- (if caption-above-p caption-str "")
- "%s"
- (if caption-above-p "" (concat "\n" caption-str))))
- (t "%s"))))
- (format
- float-env
- (concat (format "\\begin{verbatim}\n%s\\end{verbatim}"
- (org-export-format-code-default src-block info))))))
+ (let ((caption-str (org-latex--caption/label-string src-block info))
+ (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+ (org-export-format-code-default src-block info))))
+ (cond ((string= "multicolumn" float)
+ (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+ (plist-get info :latex-default-figure-position)
+ (if caption-above-p caption-str "")
+ verbatim
+ (if caption-above-p "" caption-str)))
+ (caption (concat
+ (if caption-above-p caption-str "")
+ verbatim
+ (if caption-above-p "" (concat "\n" caption-str))))
+ (t verbatim))))
;; Case 2. Custom environment.
(custom-env
(let ((caption-str (org-latex--caption/label-string src-block info))
@@ -3198,9 +3255,9 @@ centered."
(defun org-latex--decorate-table (table attributes caption above? info)
"Decorate TABLE string with caption and float environment.
-ATTRIBUTES is the plist containing is LaTeX attributes. CAPTION
-is its caption, as a string or nil. It is located above the
-table if ABOVE? is non-nil. INFO is the plist containing current
+ATTRIBUTES is the plist containing LaTeX attributes. CAPTION is
+its caption, as a string or nil. It is located above the table
+if ABOVE? is non-nil. INFO is the plist containing current
export parameters.
Return new environment, as a string."
@@ -3209,7 +3266,8 @@ Return new environment, as a string."
(cond ((and (not float) (plist-member attributes :float)) nil)
((member float '("sidewaystable" "sideways")) "sidewaystable")
((equal float "multicolumn") "table*")
- ((or float (org-string-nw-p caption)) "table")
+ (float float)
+ ((org-string-nw-p caption) "table")
(t nil))))
(placement
(or (plist-get attributes :placement)
@@ -3504,29 +3562,44 @@ channel."
"Transcode a VERSE-BLOCK element from Org to LaTeX.
CONTENTS is verse block contents. INFO is a plist holding
contextual information."
- (org-latex--wrap-label
- verse-block
- ;; In a verse environment, add a line break to each newline
- ;; character and change each white space at beginning of a line
- ;; into a space of 1 em. Also change each blank line with
- ;; a vertical space of 1 em.
- (format "\\begin{verse}\n%s\\end{verse}"
- (replace-regexp-in-string
- "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
- (replace-regexp-in-string
- "^[ \t]*\\\\\\\\$" "\\vspace*{1em}"
- (replace-regexp-in-string
- "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n"
- contents nil t) nil t) nil t))
- info))
-
+ (let* ((lin (org-export-read-attribute :attr_latex verse-block :lines))
+ (latcode (org-export-read-attribute :attr_latex verse-block :latexcode))
+ (cent (org-export-read-attribute :attr_latex verse-block :center))
+ (attr (concat
+ (if cent "[\\versewidth]" "")
+ (if lin (format "\n\\poemlines{%s}" lin) "")
+ (if latcode (format "\n%s" latcode) "")))
+ (versewidth (org-export-read-attribute :attr_latex verse-block :versewidth))
+ (vwidth (if versewidth (format "\\settowidth{\\versewidth}{%s}\n" versewidth) ""))
+ (linreset (if lin "\n\\poemlines{0}" "")))
+ (concat
+ (org-latex--wrap-label
+ verse-block
+ ;; In a verse environment, add a line break to each newline
+ ;; character and change each white space at beginning of a line
+ ;; into a space of 1 em. Also change each blank line with
+ ;; a vertical space of 1 em.
+ (format "%s\\begin{verse}%s\n%s\\end{verse}%s"
+ vwidth
+ attr
+ (replace-regexp-in-string
+ "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
+ (replace-regexp-in-string
+ "^[ \t]*\\\\\\\\$" "\\vspace*{1em}"
+ (replace-regexp-in-string
+ "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n"
+ contents nil t) nil t) nil t) linreset)
+ info)
+ ;; Insert footnote definitions, if any, after the environment, so
+ ;; the special formatting above is not applied to them.
+ (org-latex--delayed-footnotes-definitions verse-block info))))
;;; End-user functions
;;;###autoload
(defun org-latex-export-as-latex
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer as a LaTeX buffer.
If narrowing is active in the current buffer, only export its
@@ -3570,7 +3643,7 @@ command to convert it."
;;;###autoload
(defun org-latex-export-to-latex
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a LaTeX file.
If narrowing is active in the current buffer, only export its
@@ -3602,7 +3675,7 @@ file-local settings."
;;;###autoload
(defun org-latex-export-to-pdf
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to LaTeX then process through to PDF.
If narrowing is active in the current buffer, only export its
@@ -3660,12 +3733,12 @@ produced."
(match-string 0)))
"pdflatex"))
(process (if (functionp org-latex-pdf-process) org-latex-pdf-process
- ;; Replace "%latex" and "%bibtex" with,
- ;; respectively, "%L" and "%B" so as to adhere to
- ;; `format-spec' specifications.
+ ;; Replace "%latex" with "%L" and "%bib" and
+ ;; "%bibtex" with "%B" to adhere to `format-spec'
+ ;; specifications.
(mapcar (lambda (command)
(replace-regexp-in-string
- "%\\(?:bib\\|la\\)tex\\>"
+ "%\\(?:\\(?:bib\\|la\\)tex\\|bib\\)\\>"
(lambda (m) (upcase (substring m 0 2)))
command))
org-latex-pdf-process)))