commit | author | age
|
76bbd0
|
1 |
;;; ox-latex.el --- LaTeX Back-End for Org Export Engine -*- lexical-binding: t; -*- |
C |
2 |
|
|
3 |
;; Copyright (C) 2011-2018 Free Software Foundation, Inc. |
|
4 |
|
|
5 |
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com> |
|
6 |
;; Keywords: outlines, hypermedia, calendar, wp |
|
7 |
|
|
8 |
;; This file is part of GNU Emacs. |
|
9 |
|
|
10 |
;; GNU Emacs is free software: you can redistribute it and/or modify |
|
11 |
;; it under the terms of the GNU General Public License as published by |
|
12 |
;; the Free Software Foundation, either version 3 of the License, or |
|
13 |
;; (at your option) any later version. |
|
14 |
|
|
15 |
;; GNU Emacs is distributed in the hope that it will be useful, |
|
16 |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
;; GNU General Public License for more details. |
|
19 |
|
|
20 |
;; You should have received a copy of the GNU General Public License |
|
21 |
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. |
|
22 |
|
|
23 |
;;; Commentary: |
|
24 |
;; |
|
25 |
;; See Org manual for details. |
|
26 |
|
|
27 |
;;; Code: |
|
28 |
|
|
29 |
(require 'cl-lib) |
|
30 |
(require 'ox) |
|
31 |
(require 'ox-publish) |
|
32 |
|
|
33 |
(defvar org-latex-default-packages-alist) |
|
34 |
(defvar org-latex-packages-alist) |
|
35 |
(defvar orgtbl-exp-regexp) |
|
36 |
|
|
37 |
|
|
38 |
|
|
39 |
;;; Define Back-End |
|
40 |
|
|
41 |
(org-export-define-backend 'latex |
|
42 |
'((bold . org-latex-bold) |
|
43 |
(center-block . org-latex-center-block) |
|
44 |
(clock . org-latex-clock) |
|
45 |
(code . org-latex-code) |
|
46 |
(drawer . org-latex-drawer) |
|
47 |
(dynamic-block . org-latex-dynamic-block) |
|
48 |
(entity . org-latex-entity) |
|
49 |
(example-block . org-latex-example-block) |
|
50 |
(export-block . org-latex-export-block) |
|
51 |
(export-snippet . org-latex-export-snippet) |
|
52 |
(fixed-width . org-latex-fixed-width) |
|
53 |
(footnote-definition . org-latex-footnote-definition) |
|
54 |
(footnote-reference . org-latex-footnote-reference) |
|
55 |
(headline . org-latex-headline) |
|
56 |
(horizontal-rule . org-latex-horizontal-rule) |
|
57 |
(inline-src-block . org-latex-inline-src-block) |
|
58 |
(inlinetask . org-latex-inlinetask) |
|
59 |
(italic . org-latex-italic) |
|
60 |
(item . org-latex-item) |
|
61 |
(keyword . org-latex-keyword) |
|
62 |
(latex-environment . org-latex-latex-environment) |
|
63 |
(latex-fragment . org-latex-latex-fragment) |
|
64 |
(line-break . org-latex-line-break) |
|
65 |
(link . org-latex-link) |
|
66 |
(node-property . org-latex-node-property) |
|
67 |
(paragraph . org-latex-paragraph) |
|
68 |
(plain-list . org-latex-plain-list) |
|
69 |
(plain-text . org-latex-plain-text) |
|
70 |
(planning . org-latex-planning) |
|
71 |
(property-drawer . org-latex-property-drawer) |
|
72 |
(quote-block . org-latex-quote-block) |
|
73 |
(radio-target . org-latex-radio-target) |
|
74 |
(section . org-latex-section) |
|
75 |
(special-block . org-latex-special-block) |
|
76 |
(src-block . org-latex-src-block) |
|
77 |
(statistics-cookie . org-latex-statistics-cookie) |
|
78 |
(strike-through . org-latex-strike-through) |
|
79 |
(subscript . org-latex-subscript) |
|
80 |
(superscript . org-latex-superscript) |
|
81 |
(table . org-latex-table) |
|
82 |
(table-cell . org-latex-table-cell) |
|
83 |
(table-row . org-latex-table-row) |
|
84 |
(target . org-latex-target) |
|
85 |
(template . org-latex-template) |
|
86 |
(timestamp . org-latex-timestamp) |
|
87 |
(underline . org-latex-underline) |
|
88 |
(verbatim . org-latex-verbatim) |
|
89 |
(verse-block . org-latex-verse-block) |
|
90 |
;; Pseudo objects and elements. |
|
91 |
(latex-math-block . org-latex-math-block) |
|
92 |
(latex-matrices . org-latex-matrices)) |
|
93 |
:menu-entry |
|
94 |
'(?l "Export to LaTeX" |
|
95 |
((?L "As LaTeX buffer" org-latex-export-as-latex) |
|
96 |
(?l "As LaTeX file" org-latex-export-to-latex) |
|
97 |
(?p "As PDF file" org-latex-export-to-pdf) |
|
98 |
(?o "As PDF file and open" |
|
99 |
(lambda (a s v b) |
|
100 |
(if a (org-latex-export-to-pdf t s v b) |
|
101 |
(org-open-file (org-latex-export-to-pdf nil s v b))))))) |
|
102 |
:filters-alist '((:filter-options . org-latex-math-block-options-filter) |
|
103 |
(:filter-paragraph . org-latex-clean-invalid-line-breaks) |
|
104 |
(:filter-parse-tree org-latex-math-block-tree-filter |
|
105 |
org-latex-matrices-tree-filter |
|
106 |
org-latex-image-link-filter) |
|
107 |
(:filter-verse-block . org-latex-clean-invalid-line-breaks)) |
|
108 |
:options-alist |
|
109 |
'((:latex-class "LATEX_CLASS" nil org-latex-default-class t) |
|
110 |
(:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t) |
|
111 |
(:latex-header "LATEX_HEADER" nil nil newline) |
|
112 |
(:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline) |
|
113 |
(:description "DESCRIPTION" nil nil parse) |
|
114 |
(:keywords "KEYWORDS" nil nil parse) |
|
115 |
(:subtitle "SUBTITLE" nil nil parse) |
|
116 |
;; Other variables. |
|
117 |
(:latex-active-timestamp-format nil nil org-latex-active-timestamp-format) |
|
118 |
(:latex-caption-above nil nil org-latex-caption-above) |
|
119 |
(:latex-classes nil nil org-latex-classes) |
|
120 |
(:latex-default-figure-position nil nil org-latex-default-figure-position) |
|
121 |
(:latex-default-table-environment nil nil org-latex-default-table-environment) |
|
122 |
(:latex-default-table-mode nil nil org-latex-default-table-mode) |
|
123 |
(:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format) |
|
124 |
(:latex-footnote-defined-format nil nil org-latex-footnote-defined-format) |
|
125 |
(:latex-footnote-separator nil nil org-latex-footnote-separator) |
|
126 |
(:latex-format-drawer-function nil nil org-latex-format-drawer-function) |
|
127 |
(:latex-format-headline-function nil nil org-latex-format-headline-function) |
|
128 |
(:latex-format-inlinetask-function nil nil org-latex-format-inlinetask-function) |
|
129 |
(:latex-hyperref-template nil nil org-latex-hyperref-template t) |
|
130 |
(:latex-image-default-height nil nil org-latex-image-default-height) |
|
131 |
(:latex-image-default-option nil nil org-latex-image-default-option) |
|
132 |
(:latex-image-default-width nil nil org-latex-image-default-width) |
|
133 |
(:latex-images-centered nil nil org-latex-images-centered) |
|
134 |
(:latex-inactive-timestamp-format nil nil org-latex-inactive-timestamp-format) |
|
135 |
(:latex-inline-image-rules nil nil org-latex-inline-image-rules) |
|
136 |
(:latex-link-with-unknown-path-format nil nil org-latex-link-with-unknown-path-format) |
|
137 |
(:latex-listings nil nil org-latex-listings) |
|
138 |
(:latex-listings-langs nil nil org-latex-listings-langs) |
|
139 |
(:latex-listings-options nil nil org-latex-listings-options) |
|
140 |
(:latex-minted-langs nil nil org-latex-minted-langs) |
|
141 |
(:latex-minted-options nil nil org-latex-minted-options) |
|
142 |
(:latex-prefer-user-labels nil nil org-latex-prefer-user-labels) |
|
143 |
(:latex-subtitle-format nil nil org-latex-subtitle-format) |
|
144 |
(:latex-subtitle-separate nil nil org-latex-subtitle-separate) |
|
145 |
(:latex-table-scientific-notation nil nil org-latex-table-scientific-notation) |
|
146 |
(:latex-tables-booktabs nil nil org-latex-tables-booktabs) |
|
147 |
(:latex-tables-centered nil nil org-latex-tables-centered) |
|
148 |
(:latex-text-markup-alist nil nil org-latex-text-markup-alist) |
|
149 |
(:latex-title-command nil nil org-latex-title-command) |
|
150 |
(:latex-toc-command nil nil org-latex-toc-command) |
|
151 |
(:latex-compiler "LATEX_COMPILER" nil org-latex-compiler) |
|
152 |
;; Redefine regular options. |
|
153 |
(:date "DATE" nil "\\today" parse))) |
|
154 |
|
|
155 |
|
|
156 |
|
|
157 |
;;; Internal Variables |
|
158 |
|
|
159 |
(defconst org-latex-babel-language-alist |
|
160 |
'(("af" . "afrikaans") |
|
161 |
("bg" . "bulgarian") |
|
162 |
("bt-br" . "brazilian") |
|
163 |
("ca" . "catalan") |
|
164 |
("cs" . "czech") |
|
165 |
("cy" . "welsh") |
|
166 |
("da" . "danish") |
|
167 |
("de" . "germanb") |
|
168 |
("de-at" . "naustrian") |
|
169 |
("de-de" . "ngerman") |
|
170 |
("el" . "greek") |
|
171 |
("en" . "english") |
|
172 |
("en-au" . "australian") |
|
173 |
("en-ca" . "canadian") |
|
174 |
("en-gb" . "british") |
|
175 |
("en-ie" . "irish") |
|
176 |
("en-nz" . "newzealand") |
|
177 |
("en-us" . "american") |
|
178 |
("es" . "spanish") |
|
179 |
("et" . "estonian") |
|
180 |
("eu" . "basque") |
|
181 |
("fi" . "finnish") |
|
182 |
("fr" . "frenchb") |
|
183 |
("fr-ca" . "canadien") |
|
184 |
("gl" . "galician") |
|
185 |
("hr" . "croatian") |
|
186 |
("hu" . "hungarian") |
|
187 |
("id" . "indonesian") |
|
188 |
("is" . "icelandic") |
|
189 |
("it" . "italian") |
|
190 |
("la" . "latin") |
|
191 |
("ms" . "malay") |
|
192 |
("nl" . "dutch") |
|
193 |
("nb" . "norsk") |
|
194 |
("nn" . "nynorsk") |
|
195 |
("no" . "norsk") |
|
196 |
("pl" . "polish") |
|
197 |
("pt" . "portuguese") |
|
198 |
("ro" . "romanian") |
|
199 |
("ru" . "russian") |
|
200 |
("sa" . "sanskrit") |
|
201 |
("sb" . "uppersorbian") |
|
202 |
("sk" . "slovak") |
|
203 |
("sl" . "slovene") |
|
204 |
("sq" . "albanian") |
|
205 |
("sr" . "serbian") |
|
206 |
("sv" . "swedish") |
|
207 |
("ta" . "tamil") |
|
208 |
("tr" . "turkish") |
|
209 |
("uk" . "ukrainian")) |
|
210 |
"Alist between language code and corresponding Babel option.") |
|
211 |
|
|
212 |
(defconst org-latex-polyglossia-language-alist |
|
213 |
'(("am" "amharic") |
|
214 |
("ast" "asturian") |
|
215 |
("ar" "arabic") |
|
216 |
("bo" "tibetan") |
|
217 |
("bn" "bengali") |
|
218 |
("bg" "bulgarian") |
|
219 |
("br" "breton") |
|
220 |
("bt-br" "brazilian") |
|
221 |
("ca" "catalan") |
|
222 |
("cop" "coptic") |
|
223 |
("cs" "czech") |
|
224 |
("cy" "welsh") |
|
225 |
("da" "danish") |
|
226 |
("de" "german" "german") |
|
227 |
("de-at" "german" "austrian") |
|
228 |
("de-de" "german" "german") |
|
229 |
("dv" "divehi") |
|
230 |
("el" "greek") |
|
231 |
("en" "english" "usmax") |
|
232 |
("en-au" "english" "australian") |
|
233 |
("en-gb" "english" "uk") |
|
234 |
("en-nz" "english" "newzealand") |
|
235 |
("en-us" "english" "usmax") |
|
236 |
("eo" "esperanto") |
|
237 |
("es" "spanish") |
|
238 |
("et" "estonian") |
|
239 |
("eu" "basque") |
|
240 |
("fa" "farsi") |
|
241 |
("fi" "finnish") |
|
242 |
("fr" "french") |
|
243 |
("fu" "friulan") |
|
244 |
("ga" "irish") |
|
245 |
("gd" "scottish") |
|
246 |
("gl" "galician") |
|
247 |
("he" "hebrew") |
|
248 |
("hi" "hindi") |
|
249 |
("hr" "croatian") |
|
250 |
("hu" "magyar") |
|
251 |
("hy" "armenian") |
|
252 |
("id" "bahasai") |
|
253 |
("ia" "interlingua") |
|
254 |
("is" "icelandic") |
|
255 |
("it" "italian") |
|
256 |
("kn" "kannada") |
|
257 |
("la" "latin" "modern") |
|
258 |
("la-modern" "latin" "modern") |
|
259 |
("la-classic" "latin" "classic") |
|
260 |
("la-medieval" "latin" "medieval") |
|
261 |
("lo" "lao") |
|
262 |
("lt" "lithuanian") |
|
263 |
("lv" "latvian") |
|
264 |
("mr" "maranthi") |
|
265 |
("ml" "malayalam") |
|
266 |
("nl" "dutch") |
|
267 |
("nb" "norsk") |
|
268 |
("nn" "nynorsk") |
|
269 |
("nko" "nko") |
|
270 |
("no" "norsk") |
|
271 |
("oc" "occitan") |
|
272 |
("pl" "polish") |
|
273 |
("pms" "piedmontese") |
|
274 |
("pt" "portuges") |
|
275 |
("rm" "romansh") |
|
276 |
("ro" "romanian") |
|
277 |
("ru" "russian") |
|
278 |
("sa" "sanskrit") |
|
279 |
("hsb" "usorbian") |
|
280 |
("dsb" "lsorbian") |
|
281 |
("sk" "slovak") |
|
282 |
("sl" "slovenian") |
|
283 |
("se" "samin") |
|
284 |
("sq" "albanian") |
|
285 |
("sr" "serbian") |
|
286 |
("sv" "swedish") |
|
287 |
("syr" "syriac") |
|
288 |
("ta" "tamil") |
|
289 |
("te" "telugu") |
|
290 |
("th" "thai") |
|
291 |
("tk" "turkmen") |
|
292 |
("tr" "turkish") |
|
293 |
("uk" "ukrainian") |
|
294 |
("ur" "urdu") |
|
295 |
("vi" "vietnamese")) |
|
296 |
"Alist between language code and corresponding Polyglossia option") |
|
297 |
|
|
298 |
|
|
299 |
|
|
300 |
(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr") |
|
301 |
("qbordermatrix" . "\\cr") |
|
302 |
("kbordermatrix" . "\\\\")) |
|
303 |
"Alist between matrix macros and their row ending.") |
|
304 |
|
|
305 |
(defconst org-latex-math-environments-re |
|
306 |
(format |
|
307 |
"\\`[ \t]*\\\\begin{%s\\*?}" |
|
308 |
(regexp-opt |
|
309 |
'("equation" "eqnarray" "math" "displaymath" |
|
310 |
"align" "gather" "multline" "flalign" "alignat" |
|
311 |
"xalignat" "xxalignat" |
|
312 |
"subequations" |
|
313 |
;; breqn |
|
314 |
"dmath" "dseries" "dgroup" "darray" |
|
315 |
;; empheq |
|
316 |
"empheq"))) |
|
317 |
"Regexp of LaTeX math environments.") |
|
318 |
|
|
319 |
|
|
320 |
;;; User Configurable Variables |
|
321 |
|
|
322 |
(defgroup org-export-latex nil |
|
323 |
"Options for exporting Org mode files to LaTeX." |
|
324 |
:tag "Org Export LaTeX" |
|
325 |
:group 'org-export) |
|
326 |
|
|
327 |
;;;; Generic |
|
328 |
|
|
329 |
(defcustom org-latex-caption-above '(table) |
|
330 |
"When non-nil, place caption string at the beginning of elements. |
|
331 |
Otherwise, place it near the end. When value is a list of |
|
332 |
symbols, put caption above selected elements only. Allowed |
|
333 |
symbols are: `image', `table', `src-block' and `special-block'." |
|
334 |
:group 'org-export-latex |
|
335 |
:version "26.1" |
|
336 |
:package-version '(Org . "8.3") |
|
337 |
:type '(choice |
|
338 |
(const :tag "For all elements" t) |
|
339 |
(const :tag "For no element" nil) |
|
340 |
(set :tag "For the following elements only" :greedy t |
|
341 |
(const :tag "Images" image) |
|
342 |
(const :tag "Tables" table) |
|
343 |
(const :tag "Source code" src-block) |
|
344 |
(const :tag "Special blocks" special-block)))) |
|
345 |
|
|
346 |
(defcustom org-latex-prefer-user-labels nil |
|
347 |
"Use user-provided labels instead of internal ones when non-nil. |
|
348 |
|
|
349 |
When this variable is non-nil, Org will use the value of |
|
350 |
CUSTOM_ID property, NAME keyword or Org target as the key for the |
|
351 |
\\label commands generated. |
|
352 |
|
|
353 |
By default, Org generates its own internal labels during LaTeX |
|
354 |
export. This process ensures that the \\label keys are unique |
|
355 |
and valid, but it means the keys are not available in advance of |
|
356 |
the export process. |
|
357 |
|
|
358 |
Setting this variable gives you control over how Org generates |
|
359 |
labels during LaTeX export, so that you may know their keys in |
|
360 |
advance. One reason to do this is that it allows you to refer to |
|
361 |
various elements using a single label both in Org's link syntax |
|
362 |
and in embedded LaTeX code. |
|
363 |
|
|
364 |
For example, when this variable is non-nil, a headline like this: |
|
365 |
|
|
366 |
** Some section |
|
367 |
:PROPERTIES: |
|
368 |
:CUSTOM_ID: sec:foo |
|
369 |
:END: |
|
370 |
This is section [[#sec:foo]]. |
|
371 |
#+BEGIN_EXPORT latex |
|
372 |
And this is still section \\ref{sec:foo}. |
|
373 |
#+END_EXPORT |
|
374 |
|
|
375 |
will be exported to LaTeX as: |
|
376 |
|
|
377 |
\\subsection{Some section} |
|
378 |
\\label{sec:foo} |
|
379 |
This is section \\ref{sec:foo}. |
|
380 |
And this is still section \\ref{sec:foo}. |
|
381 |
|
|
382 |
Note, however, that setting this variable introduces a limitation |
|
383 |
on the possible values for CUSTOM_ID and NAME. When this |
|
384 |
variable is non-nil, Org passes their value to \\label unchanged. |
|
385 |
You are responsible for ensuring that the value is a valid LaTeX |
|
386 |
\\label key, and that no other \\label commands with the same key |
|
387 |
appear elsewhere in your document. (Keys may contain letters, |
|
388 |
numbers, and the following punctuation: '_' '.' '-' ':'.) There |
|
389 |
are no such limitations on CUSTOM_ID and NAME when this variable |
|
390 |
is nil. |
|
391 |
|
|
392 |
For headlines that do not define the CUSTOM_ID property or |
|
393 |
elements without a NAME, Org will continue to use its default |
|
394 |
labeling scheme to generate labels and resolve links into proper |
|
395 |
references." |
|
396 |
:group 'org-export-latex |
|
397 |
:type 'boolean |
|
398 |
:version "26.1" |
|
399 |
:package-version '(Org . "8.3")) |
|
400 |
|
|
401 |
;;;; Preamble |
|
402 |
|
|
403 |
(defcustom org-latex-default-class "article" |
|
404 |
"The default LaTeX class." |
|
405 |
:group 'org-export-latex |
|
406 |
:type '(string :tag "LaTeX class")) |
|
407 |
|
|
408 |
(defcustom org-latex-classes |
|
409 |
'(("article" |
|
410 |
"\\documentclass[11pt]{article}" |
|
411 |
("\\section{%s}" . "\\section*{%s}") |
|
412 |
("\\subsection{%s}" . "\\subsection*{%s}") |
|
413 |
("\\subsubsection{%s}" . "\\subsubsection*{%s}") |
|
414 |
("\\paragraph{%s}" . "\\paragraph*{%s}") |
|
415 |
("\\subparagraph{%s}" . "\\subparagraph*{%s}")) |
|
416 |
("report" |
|
417 |
"\\documentclass[11pt]{report}" |
|
418 |
("\\part{%s}" . "\\part*{%s}") |
|
419 |
("\\chapter{%s}" . "\\chapter*{%s}") |
|
420 |
("\\section{%s}" . "\\section*{%s}") |
|
421 |
("\\subsection{%s}" . "\\subsection*{%s}") |
|
422 |
("\\subsubsection{%s}" . "\\subsubsection*{%s}")) |
|
423 |
("book" |
|
424 |
"\\documentclass[11pt]{book}" |
|
425 |
("\\part{%s}" . "\\part*{%s}") |
|
426 |
("\\chapter{%s}" . "\\chapter*{%s}") |
|
427 |
("\\section{%s}" . "\\section*{%s}") |
|
428 |
("\\subsection{%s}" . "\\subsection*{%s}") |
|
429 |
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))) |
|
430 |
"Alist of LaTeX classes and associated header and structure. |
|
431 |
If #+LATEX_CLASS is set in the buffer, use its value and the |
|
432 |
associated information. Here is the structure of each cell: |
|
433 |
|
|
434 |
(class-name |
|
435 |
header-string |
|
436 |
(numbered-section . unnumbered-section) |
|
437 |
...) |
|
438 |
|
|
439 |
The header string |
|
440 |
----------------- |
|
441 |
|
|
442 |
The HEADER-STRING is the header that will be inserted into the |
|
443 |
LaTeX file. It should contain the \\documentclass macro, and |
|
444 |
anything else that is needed for this setup. To this header, the |
|
445 |
following commands will be added: |
|
446 |
|
|
447 |
- Calls to \\usepackage for all packages mentioned in the |
|
448 |
variables `org-latex-default-packages-alist' and |
|
449 |
`org-latex-packages-alist'. Thus, your header definitions |
|
450 |
should avoid to also request these packages. |
|
451 |
|
|
452 |
- Lines specified via \"#+LATEX_HEADER:\" and |
|
453 |
\"#+LATEX_HEADER_EXTRA:\" keywords. |
|
454 |
|
|
455 |
If you need more control about the sequence in which the header |
|
456 |
is built up, or if you want to exclude one of these building |
|
457 |
blocks for a particular class, you can use the following |
|
458 |
macro-like placeholders. |
|
459 |
|
|
460 |
[DEFAULT-PACKAGES] \\usepackage statements for default packages |
|
461 |
[NO-DEFAULT-PACKAGES] do not include any of the default packages |
|
462 |
[PACKAGES] \\usepackage statements for packages |
|
463 |
[NO-PACKAGES] do not include the packages |
|
464 |
[EXTRA] the stuff from #+LATEX_HEADER(_EXTRA) |
|
465 |
[NO-EXTRA] do not include #+LATEX_HEADER(_EXTRA) stuff |
|
466 |
|
|
467 |
So a header like |
|
468 |
|
|
469 |
\\documentclass{article} |
|
470 |
[NO-DEFAULT-PACKAGES] |
|
471 |
[EXTRA] |
|
472 |
\\providecommand{\\alert}[1]{\\textbf{#1}} |
|
473 |
[PACKAGES] |
|
474 |
|
|
475 |
will omit the default packages, and will include the |
|
476 |
#+LATEX_HEADER and #+LATEX_HEADER_EXTRA lines, then have a call |
|
477 |
to \\providecommand, and then place \\usepackage commands based |
|
478 |
on the content of `org-latex-packages-alist'. |
|
479 |
|
|
480 |
If your header, `org-latex-default-packages-alist' or |
|
481 |
`org-latex-packages-alist' inserts \"\\usepackage[AUTO]{inputenc}\", |
|
482 |
AUTO will automatically be replaced with a coding system derived |
|
483 |
from `buffer-file-coding-system'. See also the variable |
|
484 |
`org-latex-inputenc-alist' for a way to influence this mechanism. |
|
485 |
|
|
486 |
Likewise, if your header contains \"\\usepackage[AUTO]{babel}\" |
|
487 |
or \"\\usepackage[AUTO]{polyglossia}\", AUTO will be replaced |
|
488 |
with the language related to the language code specified by |
|
489 |
`org-export-default-language'. Note that constructions such as |
|
490 |
\"\\usepackage[french,AUTO,english]{babel}\" are permitted. For |
|
491 |
Polyglossia the language will be set via the macros |
|
492 |
\"\\setmainlanguage\" and \"\\setotherlanguage\". See also |
|
493 |
`org-latex-guess-babel-language' and |
|
494 |
`org-latex-guess-polyglossia-language'. |
|
495 |
|
|
496 |
The sectioning structure |
|
497 |
------------------------ |
|
498 |
|
|
499 |
The sectioning structure of the class is given by the elements |
|
500 |
following the header string. For each sectioning level, a number |
|
501 |
of strings is specified. A %s formatter is mandatory in each |
|
502 |
section string and will be replaced by the title of the section. |
|
503 |
|
|
504 |
Instead of a cons cell (numbered . unnumbered), you can also |
|
505 |
provide a list of 2 or 4 elements, |
|
506 |
|
|
507 |
(numbered-open numbered-close) |
|
508 |
|
|
509 |
or |
|
510 |
|
|
511 |
(numbered-open numbered-close unnumbered-open unnumbered-close) |
|
512 |
|
|
513 |
providing opening and closing strings for a LaTeX environment |
|
514 |
that should represent the document section. The opening clause |
|
515 |
should have a %s to represent the section title. |
|
516 |
|
|
517 |
Instead of a list of sectioning commands, you can also specify |
|
518 |
a function name. That function will be called with two |
|
519 |
parameters, the (reduced) level of the headline, and a predicate |
|
520 |
non-nil when the headline should be numbered. It must return |
|
521 |
a format string in which the section title will be added." |
|
522 |
:group 'org-export-latex |
|
523 |
:type '(repeat |
|
524 |
(list (string :tag "LaTeX class") |
|
525 |
(string :tag "LaTeX header") |
|
526 |
(repeat :tag "Levels" :inline t |
|
527 |
(choice |
|
528 |
(cons :tag "Heading" |
|
529 |
(string :tag " numbered") |
|
530 |
(string :tag "unnumbered")) |
|
531 |
(list :tag "Environment" |
|
532 |
(string :tag "Opening (numbered)") |
|
533 |
(string :tag "Closing (numbered)") |
|
534 |
(string :tag "Opening (unnumbered)") |
|
535 |
(string :tag "Closing (unnumbered)")) |
|
536 |
(function :tag "Hook computing sectioning")))))) |
|
537 |
|
|
538 |
(defcustom org-latex-inputenc-alist nil |
|
539 |
"Alist of inputenc coding system names, and what should really be used. |
|
540 |
For example, adding an entry |
|
541 |
|
|
542 |
(\"utf8\" . \"utf8x\") |
|
543 |
|
|
544 |
will cause \\usepackage[utf8x]{inputenc} to be used for buffers that |
|
545 |
are written as utf8 files." |
|
546 |
:group 'org-export-latex |
|
547 |
:type '(repeat |
|
548 |
(cons |
|
549 |
(string :tag "Derived from buffer") |
|
550 |
(string :tag "Use this instead")))) |
|
551 |
|
|
552 |
(defcustom org-latex-title-command "\\maketitle" |
|
553 |
"The command used to insert the title just after \\begin{document}. |
|
554 |
|
|
555 |
This format string may contain these elements: |
|
556 |
|
|
557 |
%a for AUTHOR keyword |
|
558 |
%t for TITLE keyword |
|
559 |
%s for SUBTITLE keyword |
|
560 |
%k for KEYWORDS line |
|
561 |
%d for DESCRIPTION line |
|
562 |
%c for CREATOR line |
|
563 |
%l for Language keyword |
|
564 |
%L for capitalized language keyword |
|
565 |
%D for DATE keyword |
|
566 |
|
|
567 |
If you need to use a \"%\" character, you need to escape it |
|
568 |
like that: \"%%\". |
|
569 |
|
|
570 |
Setting :latex-title-command in publishing projects will take |
|
571 |
precedence over this variable." |
|
572 |
:group 'org-export-latex |
|
573 |
:type '(string :tag "Format string")) |
|
574 |
|
|
575 |
(defcustom org-latex-subtitle-format "\\\\\\medskip\n\\large %s" |
|
576 |
"Format string used for transcoded subtitle. |
|
577 |
The format string should have at most one \"%s\"-expression, |
|
578 |
which is replaced with the subtitle." |
|
579 |
:group 'org-export-latex |
|
580 |
:version "26.1" |
|
581 |
:package-version '(Org . "8.3") |
|
582 |
:type '(string :tag "Format string")) |
|
583 |
|
|
584 |
(defcustom org-latex-subtitle-separate nil |
|
585 |
"Non-nil means the subtitle is not typeset as part of title." |
|
586 |
:group 'org-export-latex |
|
587 |
:version "26.1" |
|
588 |
:package-version '(Org . "8.3") |
|
589 |
:type 'boolean) |
|
590 |
|
|
591 |
(defcustom org-latex-toc-command "\\tableofcontents\n\n" |
|
592 |
"LaTeX command to set the table of contents, list of figures, etc. |
|
593 |
This command only applies to the table of contents generated with |
|
594 |
the toc:nil option, not to those generated with #+TOC keyword." |
|
595 |
:group 'org-export-latex |
|
596 |
:type 'string) |
|
597 |
|
|
598 |
(defcustom org-latex-hyperref-template |
|
599 |
"\\hypersetup{\n pdfauthor={%a},\n pdftitle={%t},\n pdfkeywords={%k}, |
|
600 |
pdfsubject={%d},\n pdfcreator={%c}, \n pdflang={%L}}\n" |
|
601 |
"Template for hyperref package options. |
|
602 |
|
|
603 |
This format string may contain these elements: |
|
604 |
|
|
605 |
%a for AUTHOR keyword |
|
606 |
%t for TITLE keyword |
|
607 |
%s for SUBTITLE keyword |
|
608 |
%k for KEYWORDS line |
|
609 |
%d for DESCRIPTION line |
|
610 |
%c for CREATOR line |
|
611 |
%l for Language keyword |
|
612 |
%L for capitalized language keyword |
|
613 |
%D for DATE keyword |
|
614 |
|
|
615 |
If you need to use a \"%\" character, you need to escape it |
|
616 |
like that: \"%%\". |
|
617 |
|
|
618 |
As a special case, a nil value prevents template from being |
|
619 |
inserted. |
|
620 |
|
|
621 |
Setting :latex-hyperref-template in publishing projects will take |
|
622 |
precedence over this variable." |
|
623 |
:group 'org-export-latex |
|
624 |
:version "26.1" |
|
625 |
:package-version '(Org . "8.3") |
|
626 |
:type '(choice (const :tag "No template" nil) |
|
627 |
(string :tag "Format string"))) |
|
628 |
|
|
629 |
;;;; Headline |
|
630 |
|
|
631 |
(defcustom org-latex-format-headline-function |
|
632 |
'org-latex-format-headline-default-function |
|
633 |
"Function for formatting the headline's text. |
|
634 |
|
|
635 |
This function will be called with six arguments: |
|
636 |
TODO the todo keyword (string or nil) |
|
637 |
TODO-TYPE the type of todo (symbol: `todo', `done', nil) |
|
638 |
PRIORITY the priority of the headline (integer or nil) |
|
639 |
TEXT the main headline text (string) |
|
640 |
TAGS the tags (list of strings or nil) |
|
641 |
INFO the export options (plist) |
|
642 |
|
|
643 |
The function result will be used in the section format string." |
|
644 |
:group 'org-export-latex |
|
645 |
:version "24.4" |
|
646 |
:package-version '(Org . "8.0") |
|
647 |
:type 'function) |
|
648 |
|
|
649 |
|
|
650 |
;;;; Footnotes |
|
651 |
|
|
652 |
(defcustom org-latex-footnote-separator "\\textsuperscript{,}\\," |
|
653 |
"Text used to separate footnotes." |
|
654 |
:group 'org-export-latex |
|
655 |
:type 'string) |
|
656 |
|
|
657 |
(defcustom org-latex-footnote-defined-format "\\textsuperscript{\\ref{%s}}" |
|
658 |
"Format string used to format reference to footnote already defined. |
|
659 |
%s will be replaced by the label of the referred footnote." |
|
660 |
:group 'org-export-latex |
|
661 |
:type '(choice |
|
662 |
(const :tag "Use plain superscript (default)" "\\textsuperscript{\\ref{%s}}") |
|
663 |
(const :tag "Use Memoir/KOMA-Script footref" "\\footref{%s}") |
|
664 |
(string :tag "Other format string")) |
|
665 |
:version "26.1" |
|
666 |
:package-version '(Org . "9.0")) |
|
667 |
|
|
668 |
;;;; Timestamps |
|
669 |
|
|
670 |
(defcustom org-latex-active-timestamp-format "\\textit{%s}" |
|
671 |
"A printf format string to be applied to active timestamps." |
|
672 |
:group 'org-export-latex |
|
673 |
:type 'string) |
|
674 |
|
|
675 |
(defcustom org-latex-inactive-timestamp-format "\\textit{%s}" |
|
676 |
"A printf format string to be applied to inactive timestamps." |
|
677 |
:group 'org-export-latex |
|
678 |
:type 'string) |
|
679 |
|
|
680 |
(defcustom org-latex-diary-timestamp-format "\\textit{%s}" |
|
681 |
"A printf format string to be applied to diary timestamps." |
|
682 |
:group 'org-export-latex |
|
683 |
:type 'string) |
|
684 |
|
|
685 |
|
|
686 |
;;;; Links |
|
687 |
|
|
688 |
(defcustom org-latex-images-centered t |
|
689 |
"When non-nil, images are centered." |
|
690 |
:group 'org-export-latex |
|
691 |
:version "26.1" |
|
692 |
:package-version '(Org . "9.0") |
|
693 |
:type 'boolean |
|
694 |
:safe #'booleanp) |
|
695 |
|
|
696 |
(defcustom org-latex-image-default-option "" |
|
697 |
"Default option for images." |
|
698 |
:group 'org-export-latex |
|
699 |
:version "24.4" |
|
700 |
:package-version '(Org . "8.0") |
|
701 |
:type 'string) |
|
702 |
|
|
703 |
(defcustom org-latex-image-default-width ".9\\linewidth" |
|
704 |
"Default width for images. |
|
705 |
This value will not be used if a height is provided." |
|
706 |
:group 'org-export-latex |
|
707 |
:version "24.4" |
|
708 |
:package-version '(Org . "8.0") |
|
709 |
:type 'string) |
|
710 |
|
|
711 |
(defcustom org-latex-image-default-height "" |
|
712 |
"Default height for images. |
|
713 |
This value will not be used if a width is provided, or if the |
|
714 |
image is wrapped within a \"figure\" or \"wrapfigure\" |
|
715 |
environment." |
|
716 |
:group 'org-export-latex |
|
717 |
:version "24.4" |
|
718 |
:package-version '(Org . "8.0") |
|
719 |
:type 'string) |
|
720 |
|
|
721 |
(defcustom org-latex-default-figure-position "htbp" |
|
722 |
"Default position for LaTeX figures." |
|
723 |
:group 'org-export-latex |
|
724 |
:type 'string |
|
725 |
:version "26.1" |
|
726 |
:package-version '(Org . "9.0") |
|
727 |
:safe #'stringp) |
|
728 |
|
|
729 |
(defcustom org-latex-inline-image-rules |
|
730 |
`(("file" . ,(regexp-opt |
|
731 |
'("pdf" "jpeg" "jpg" "png" "ps" "eps" "tikz" "pgf" "svg")))) |
|
732 |
"Rules characterizing image files that can be inlined into LaTeX. |
|
733 |
|
|
734 |
A rule consists in an association whose key is the type of link |
|
735 |
to consider, and value is a regexp that will be matched against |
|
736 |
link's path. |
|
737 |
|
|
738 |
Note that, by default, the image extension *actually* allowed |
|
739 |
depend on the way the LaTeX file is processed. When used with |
|
740 |
pdflatex, pdf, jpg and png images are OK. When processing |
|
741 |
through dvi to Postscript, only ps and eps are allowed. The |
|
742 |
default we use here encompasses both." |
|
743 |
:group 'org-export-latex |
|
744 |
:version "24.4" |
|
745 |
:package-version '(Org . "8.0") |
|
746 |
:type '(alist :key-type (string :tag "Type") |
|
747 |
:value-type (regexp :tag "Path"))) |
|
748 |
|
|
749 |
(defcustom org-latex-link-with-unknown-path-format "\\texttt{%s}" |
|
750 |
"Format string for links with unknown path type." |
|
751 |
:group 'org-export-latex |
|
752 |
:type 'string) |
|
753 |
|
|
754 |
|
|
755 |
;;;; Tables |
|
756 |
|
|
757 |
(defcustom org-latex-default-table-environment "tabular" |
|
758 |
"Default environment used to build tables." |
|
759 |
:group 'org-export-latex |
|
760 |
:version "24.4" |
|
761 |
:package-version '(Org . "8.0") |
|
762 |
:type 'string) |
|
763 |
|
|
764 |
(defcustom org-latex-default-table-mode 'table |
|
765 |
"Default mode for tables. |
|
766 |
|
|
767 |
Value can be a symbol among: |
|
768 |
|
|
769 |
`table' Regular LaTeX table. |
|
770 |
|
|
771 |
`math' In this mode, every cell is considered as being in math |
|
772 |
mode and the complete table will be wrapped within a math |
|
773 |
environment. It is particularly useful to write matrices. |
|
774 |
|
|
775 |
`inline-math' This mode is almost the same as `math', but the |
|
776 |
math environment will be inlined. |
|
777 |
|
|
778 |
`verbatim' The table is exported as it appears in the Org |
|
779 |
buffer, within a verbatim environment. |
|
780 |
|
|
781 |
This value can be overridden locally with, i.e. \":mode math\" in |
|
782 |
LaTeX attributes. |
|
783 |
|
|
784 |
When modifying this variable, it may be useful to change |
|
785 |
`org-latex-default-table-environment' accordingly." |
|
786 |
:group 'org-export-latex |
|
787 |
:version "24.4" |
|
788 |
:package-version '(Org . "8.0") |
|
789 |
:type '(choice (const :tag "Table" table) |
|
790 |
(const :tag "Matrix" math) |
|
791 |
(const :tag "Inline matrix" inline-math) |
|
792 |
(const :tag "Verbatim" verbatim)) |
|
793 |
:safe (lambda (s) (memq s '(table math inline-math verbatim)))) |
|
794 |
|
|
795 |
(defcustom org-latex-tables-centered t |
|
796 |
"When non-nil, tables are exported in a center environment." |
|
797 |
:group 'org-export-latex |
|
798 |
:type 'boolean |
|
799 |
:safe #'booleanp) |
|
800 |
|
|
801 |
(defcustom org-latex-tables-booktabs nil |
|
802 |
"When non-nil, display tables in a formal \"booktabs\" style. |
|
803 |
This option assumes that the \"booktabs\" package is properly |
|
804 |
loaded in the header of the document. This value can be ignored |
|
805 |
locally with \":booktabs t\" and \":booktabs nil\" LaTeX |
|
806 |
attributes." |
|
807 |
:group 'org-export-latex |
|
808 |
:version "24.4" |
|
809 |
:package-version '(Org . "8.0") |
|
810 |
:type 'boolean |
|
811 |
:safe #'booleanp) |
|
812 |
|
|
813 |
(defcustom org-latex-table-scientific-notation "%s\\,(%s)" |
|
814 |
"Format string to display numbers in scientific notation. |
|
815 |
The format should have \"%s\" twice, for mantissa and exponent |
|
816 |
\(i.e., \"%s\\\\times10^{%s}\"). |
|
817 |
|
|
818 |
When nil, no transformation is made." |
|
819 |
:group 'org-export-latex |
|
820 |
:version "24.4" |
|
821 |
:package-version '(Org . "8.0") |
|
822 |
:type '(choice |
|
823 |
(string :tag "Format string") |
|
824 |
(const :tag "No formatting" nil))) |
|
825 |
|
|
826 |
;;;; Text markup |
|
827 |
|
|
828 |
(defcustom org-latex-text-markup-alist '((bold . "\\textbf{%s}") |
|
829 |
(code . protectedtexttt) |
|
830 |
(italic . "\\emph{%s}") |
|
831 |
(strike-through . "\\sout{%s}") |
|
832 |
(underline . "\\uline{%s}") |
|
833 |
(verbatim . protectedtexttt)) |
|
834 |
"Alist of LaTeX expressions to convert text markup. |
|
835 |
|
|
836 |
The key must be a symbol among `bold', `code', `italic', |
|
837 |
`strike-through', `underline' and `verbatim'. The value is |
|
838 |
a formatting string to wrap fontified text with. |
|
839 |
|
|
840 |
Value can also be set to the following symbols: `verb' and |
|
841 |
`protectedtexttt'. For the former, Org will use \"\\verb\" to |
|
842 |
create a format string and select a delimiter character that |
|
843 |
isn't in the string. For the latter, Org will use \"\\texttt\" |
|
844 |
to typeset and try to protect special characters. |
|
845 |
|
|
846 |
If no association can be found for a given markup, text will be |
|
847 |
returned as-is." |
|
848 |
:group 'org-export-latex |
|
849 |
:version "26.1" |
|
850 |
:package-version '(Org . "8.3") |
|
851 |
:type 'alist |
|
852 |
:options '(bold code italic strike-through underline verbatim)) |
|
853 |
|
|
854 |
|
|
855 |
;;;; Drawers |
|
856 |
|
|
857 |
(defcustom org-latex-format-drawer-function (lambda (_ contents) contents) |
|
858 |
"Function called to format a drawer in LaTeX code. |
|
859 |
|
|
860 |
The function must accept two parameters: |
|
861 |
NAME the drawer name, like \"LOGBOOK\" |
|
862 |
CONTENTS the contents of the drawer. |
|
863 |
|
|
864 |
The function should return the string to be exported. |
|
865 |
|
|
866 |
The default function simply returns the value of CONTENTS." |
|
867 |
:group 'org-export-latex |
|
868 |
:version "26.1" |
|
869 |
:package-version '(Org . "8.3") |
|
870 |
:type 'function) |
|
871 |
|
|
872 |
|
|
873 |
;;;; Inlinetasks |
|
874 |
|
|
875 |
(defcustom org-latex-format-inlinetask-function |
|
876 |
'org-latex-format-inlinetask-default-function |
|
877 |
"Function called to format an inlinetask in LaTeX code. |
|
878 |
|
|
879 |
The function must accept seven parameters: |
|
880 |
TODO the todo keyword (string or nil) |
|
881 |
TODO-TYPE the todo type (symbol: `todo', `done', nil) |
|
882 |
PRIORITY the inlinetask priority (integer or nil) |
|
883 |
NAME the inlinetask name (string) |
|
884 |
TAGS the inlinetask tags (list of strings or nil) |
|
885 |
CONTENTS the contents of the inlinetask (string or nil) |
|
886 |
INFO the export options (plist) |
|
887 |
|
|
888 |
The function should return the string to be exported." |
|
889 |
:group 'org-export-latex |
|
890 |
:type 'function |
|
891 |
:version "26.1" |
|
892 |
:package-version '(Org . "8.3")) |
|
893 |
|
|
894 |
|
|
895 |
;; Src blocks |
|
896 |
|
|
897 |
(defcustom org-latex-listings nil |
|
898 |
"Non-nil means export source code using the listings package. |
|
899 |
|
|
900 |
This package will fontify source code, possibly even with color. |
|
901 |
If you want to use this, you also need to make LaTeX use the |
|
902 |
listings package, and if you want to have color, the color |
|
903 |
package. Just add these to `org-latex-packages-alist', for |
|
904 |
example using customize, or with something like: |
|
905 |
|
|
906 |
(require \\='ox-latex) |
|
907 |
(add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\")) |
|
908 |
(add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\")) |
|
909 |
|
|
910 |
Alternatively, |
|
911 |
|
|
912 |
(setq org-latex-listings \\='minted) |
|
913 |
|
|
914 |
causes source code to be exported using the minted package as |
|
915 |
opposed to listings. If you want to use minted, you need to add |
|
916 |
the minted package to `org-latex-packages-alist', for example |
|
917 |
using customize, or with |
|
918 |
|
|
919 |
(require \\='ox-latex) |
|
920 |
(add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\")) |
|
921 |
|
|
922 |
In addition, it is necessary to install pygments |
|
923 |
\(URL `http://pygments.org>'), and to configure the variable |
|
924 |
`org-latex-pdf-process' so that the -shell-escape option is |
|
925 |
passed to pdflatex. |
|
926 |
|
|
927 |
The minted choice has possible repercussions on the preview of |
|
928 |
latex fragments (see `org-preview-latex-fragment'). If you run |
|
929 |
into previewing problems, please consult |
|
930 |
URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'." |
|
931 |
:group 'org-export-latex |
|
932 |
:type '(choice |
|
933 |
(const :tag "Use listings" t) |
|
934 |
(const :tag "Use minted" minted) |
|
935 |
(const :tag "Export verbatim" nil)) |
|
936 |
:safe (lambda (s) (memq s '(t nil minted)))) |
|
937 |
|
|
938 |
(defcustom org-latex-listings-langs |
|
939 |
'((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp") |
|
940 |
(c "C") (cc "C++") |
|
941 |
(fortran "fortran") |
|
942 |
(perl "Perl") (cperl "Perl") (python "Python") (ruby "Ruby") |
|
943 |
(html "HTML") (xml "XML") |
|
944 |
(tex "TeX") (latex "[LaTeX]TeX") |
|
945 |
(shell-script "bash") |
|
946 |
(gnuplot "Gnuplot") |
|
947 |
(ocaml "Caml") (caml "Caml") |
|
948 |
(sql "SQL") (sqlite "sql") |
|
949 |
(makefile "make") |
|
950 |
(R "r")) |
|
951 |
"Alist mapping languages to their listing language counterpart. |
|
952 |
The key is a symbol, the major mode symbol without the \"-mode\". |
|
953 |
The value is the string that should be inserted as the language |
|
954 |
parameter for the listings package. If the mode name and the |
|
955 |
listings name are the same, the language does not need an entry |
|
956 |
in this list - but it does not hurt if it is present." |
|
957 |
:group 'org-export-latex |
|
958 |
:version "26.1" |
|
959 |
:package-version '(Org . "8.3") |
|
960 |
:type '(repeat |
|
961 |
(list |
|
962 |
(symbol :tag "Major mode ") |
|
963 |
(string :tag "Listings language")))) |
|
964 |
|
|
965 |
(defcustom org-latex-listings-options nil |
|
966 |
"Association list of options for the latex listings package. |
|
967 |
|
|
968 |
These options are supplied as a comma-separated list to the |
|
969 |
\\lstset command. Each element of the association list should be |
|
970 |
a list containing two strings: the name of the option, and the |
|
971 |
value. For example, |
|
972 |
|
|
973 |
(setq org-latex-listings-options |
|
974 |
\\='((\"basicstyle\" \"\\\\small\") |
|
975 |
(\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\"))) |
|
976 |
|
|
977 |
will typeset the code in a small size font with underlined, bold |
|
978 |
black keywords. |
|
979 |
|
|
980 |
Note that the same options will be applied to blocks of all |
|
981 |
languages. If you need block-specific options, you may use the |
|
982 |
following syntax: |
|
983 |
|
|
984 |
#+ATTR_LATEX: :options key1=value1,key2=value2 |
|
985 |
#+BEGIN_SRC <LANG> |
|
986 |
... |
|
987 |
#+END_SRC" |
|
988 |
:group 'org-export-latex |
|
989 |
:type '(repeat |
|
990 |
(list |
|
991 |
(string :tag "Listings option name ") |
|
992 |
(string :tag "Listings option value")))) |
|
993 |
|
|
994 |
(defcustom org-latex-minted-langs |
|
995 |
'((emacs-lisp "common-lisp") |
|
996 |
(cc "c++") |
|
997 |
(cperl "perl") |
|
998 |
(shell-script "bash") |
|
999 |
(caml "ocaml")) |
|
1000 |
"Alist mapping languages to their minted language counterpart. |
|
1001 |
The key is a symbol, the major mode symbol without the \"-mode\". |
|
1002 |
The value is the string that should be inserted as the language |
|
1003 |
parameter for the minted package. If the mode name and the |
|
1004 |
listings name are the same, the language does not need an entry |
|
1005 |
in this list - but it does not hurt if it is present. |
|
1006 |
|
|
1007 |
Note that minted uses all lower case for language identifiers, |
|
1008 |
and that the full list of language identifiers can be obtained |
|
1009 |
with: |
|
1010 |
|
|
1011 |
pygmentize -L lexers" |
|
1012 |
:group 'org-export-latex |
|
1013 |
:type '(repeat |
|
1014 |
(list |
|
1015 |
(symbol :tag "Major mode ") |
|
1016 |
(string :tag "Minted language")))) |
|
1017 |
|
|
1018 |
(defcustom org-latex-minted-options nil |
|
1019 |
"Association list of options for the latex minted package. |
|
1020 |
|
|
1021 |
These options are supplied within square brackets in |
|
1022 |
\\begin{minted} environments. Each element of the alist should |
|
1023 |
be a list containing two strings: the name of the option, and the |
|
1024 |
value. For example, |
|
1025 |
|
|
1026 |
(setq org-latex-minted-options |
|
1027 |
\\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\"))) |
|
1028 |
|
|
1029 |
will result in src blocks being exported with |
|
1030 |
|
|
1031 |
\\begin{minted}[bgcolor=bg,frame=lines]{<LANG>} |
|
1032 |
|
|
1033 |
as the start of the minted environment. Note that the same |
|
1034 |
options will be applied to blocks of all languages. If you need |
|
1035 |
block-specific options, you may use the following syntax: |
|
1036 |
|
|
1037 |
#+ATTR_LATEX: :options key1=value1,key2=value2 |
|
1038 |
#+BEGIN_SRC <LANG> |
|
1039 |
... |
|
1040 |
#+END_SRC" |
|
1041 |
:group 'org-export-latex |
|
1042 |
:type '(repeat |
|
1043 |
(list |
|
1044 |
(string :tag "Minted option name ") |
|
1045 |
(string :tag "Minted option value")))) |
|
1046 |
|
|
1047 |
(defcustom org-latex-custom-lang-environments nil |
|
1048 |
"Alist mapping languages to language-specific LaTeX environments. |
|
1049 |
|
|
1050 |
It is used during export of src blocks by the listings and minted |
|
1051 |
latex packages. The environment may be a simple string, composed of |
|
1052 |
only letters and numbers. In this case, the string is directly the |
|
1053 |
name of the latex environment to use. The environment may also be |
|
1054 |
a format string. In this case the format string will be directly |
|
1055 |
exported. This format string may contain these elements: |
|
1056 |
|
|
1057 |
%s for the formatted source |
|
1058 |
%c for the caption |
|
1059 |
%f for the float attribute |
|
1060 |
%l for an appropriate label |
|
1061 |
%o for the LaTeX attributes |
|
1062 |
|
|
1063 |
For example, |
|
1064 |
|
|
1065 |
(setq org-latex-custom-lang-environments |
|
1066 |
\\='((python \"pythoncode\") |
|
1067 |
(ocaml \"\\\\begin{listing} |
|
1068 |
\\\\begin{minted}[%o]{ocaml} |
|
1069 |
%s\\\\end{minted} |
|
1070 |
\\\\caption{%c} |
|
1071 |
\\\\label{%l}\"))) |
|
1072 |
|
|
1073 |
would have the effect that if Org encounters a Python source block |
|
1074 |
during LaTeX export it will produce |
|
1075 |
|
|
1076 |
\\begin{pythoncode} |
|
1077 |
<src block body> |
|
1078 |
\\end{pythoncode} |
|
1079 |
|
|
1080 |
and if Org encounters an Ocaml source block during LaTeX export it |
|
1081 |
will produce |
|
1082 |
|
|
1083 |
\\begin{listing} |
|
1084 |
\\begin{minted}[<attr_latex options>]{ocaml} |
|
1085 |
<src block body> |
|
1086 |
\\end{minted} |
|
1087 |
\\caption{<caption>} |
|
1088 |
\\label{<label>} |
|
1089 |
\\end{listing}" |
|
1090 |
:group 'org-export-latex |
|
1091 |
:type '(repeat |
|
1092 |
(list |
|
1093 |
(symbol :tag "Language name ") |
|
1094 |
(string :tag "Environment name or format string"))) |
|
1095 |
:version "26.1" |
|
1096 |
:package-version '(Org . "9.0")) |
|
1097 |
|
|
1098 |
|
|
1099 |
;;;; Compilation |
|
1100 |
|
|
1101 |
(defcustom org-latex-compiler-file-string "%% Intended LaTeX compiler: %s\n" |
|
1102 |
"LaTeX compiler format-string. |
|
1103 |
See also `org-latex-compiler'." |
|
1104 |
:group 'org-export-latex |
|
1105 |
:type '(choice |
|
1106 |
(const :tag "Comment" "%% Intended LaTeX compiler: %s\n") |
|
1107 |
(const :tag "latex-mode file variable" "%% -*- latex-run-command: %s -*-\n") |
|
1108 |
(const :tag "AUCTeX file variable" "%% -*- LaTeX-command: %s -*-\n") |
|
1109 |
(string :tag "custom format" "%% %s")) |
|
1110 |
:version "26.1" |
|
1111 |
:package-version '(Org . "9.0")) |
|
1112 |
|
|
1113 |
(defcustom org-latex-compiler "pdflatex" |
|
1114 |
"LaTeX compiler to use. |
|
1115 |
|
|
1116 |
Must be an element in `org-latex-compilers' or the empty quote. |
|
1117 |
Can also be set in buffers via #+LATEX_COMPILER. See also |
|
1118 |
`org-latex-compiler-file-string'." |
|
1119 |
:group 'org-export-latex |
|
1120 |
:type '(choice |
|
1121 |
(const :tag "pdfLaTeX" "pdflatex") |
|
1122 |
(const :tag "XeLaTeX" "xelatex") |
|
1123 |
(const :tag "LuaLaTeX" "lualatex") |
|
1124 |
(const :tag "Unset" "")) |
|
1125 |
:version "26.1" |
|
1126 |
:package-version '(Org . "9.0")) |
|
1127 |
|
|
1128 |
(defconst org-latex-compilers '("pdflatex" "xelatex" "lualatex") |
|
1129 |
"Known LaTeX compilers. |
|
1130 |
See also `org-latex-compiler'.") |
|
1131 |
|
|
1132 |
(defcustom org-latex-bib-compiler "bibtex" |
|
1133 |
"Command to process a LaTeX file's bibliography. |
|
1134 |
|
|
1135 |
The shorthand %bib in `org-latex-pdf-process' is replaced with |
|
1136 |
this value. |
|
1137 |
|
|
1138 |
A better approach is to use a compiler suit such as `latexmk'." |
|
1139 |
:group 'org-export-latex |
|
1140 |
:type '(choice (const :tag "BibTeX" "bibtex") |
|
1141 |
(const :tag "Biber" "biber") |
|
1142 |
(string :tag "Other process")) |
|
1143 |
:version "26.1" |
|
1144 |
:package-version '(Org . "9.0")) |
|
1145 |
|
|
1146 |
(defcustom org-latex-pdf-process |
|
1147 |
'("%latex -interaction nonstopmode -output-directory %o %f" |
|
1148 |
"%latex -interaction nonstopmode -output-directory %o %f" |
|
1149 |
"%latex -interaction nonstopmode -output-directory %o %f") |
|
1150 |
"Commands to process a LaTeX file to a PDF file. |
|
1151 |
|
|
1152 |
This is a list of strings, each of them will be given to the |
|
1153 |
shell as a command. %f in the command will be replaced by the |
|
1154 |
relative file name, %F by the absolute file name, %b by the file |
|
1155 |
base name (i.e. without directory and extension parts), %o by the |
|
1156 |
base directory of the file, %O by the absolute file name of the |
|
1157 |
output file, %latex is the LaTeX compiler (see |
|
1158 |
`org-latex-compiler'), and %bib is the BibTeX-like compiler (see |
|
1159 |
`org-latex-bib-compiler'). |
|
1160 |
|
|
1161 |
The reason why this is a list is that it usually takes several |
|
1162 |
runs of `pdflatex', maybe mixed with a call to `bibtex'. Org |
|
1163 |
does not have a clever mechanism to detect which of these |
|
1164 |
commands have to be run to get to a stable result, and it also |
|
1165 |
does not do any error checking. |
|
1166 |
|
|
1167 |
Consider a smart LaTeX compiler such as `texi2dvi' or `latexmk', |
|
1168 |
which calls the \"correct\" combinations of auxiliary programs. |
|
1169 |
|
|
1170 |
Alternatively, this may be a Lisp function that does the |
|
1171 |
processing, so you could use this to apply the machinery of |
|
1172 |
AUCTeX or the Emacs LaTeX mode. This function should accept the |
|
1173 |
file name as its single argument." |
|
1174 |
:group 'org-export-pdf |
|
1175 |
:type '(choice |
|
1176 |
(repeat :tag "Shell command sequence" |
|
1177 |
(string :tag "Shell command")) |
|
1178 |
(const :tag "2 runs of latex" |
|
1179 |
("%latex -interaction nonstopmode -output-directory %o %f" |
|
1180 |
"%latex -interaction nonstopmode -output-directory %o %f")) |
|
1181 |
(const :tag "3 runs of latex" |
|
1182 |
("%latex -interaction nonstopmode -output-directory %o %f" |
|
1183 |
"%latex -interaction nonstopmode -output-directory %o %f" |
|
1184 |
"%latex -interaction nonstopmode -output-directory %o %f")) |
|
1185 |
(const :tag "latex,bibtex,latex,latex" |
|
1186 |
("%latex -interaction nonstopmode -output-directory %o %f" |
|
1187 |
"%bib %b" |
|
1188 |
"%latex -interaction nonstopmode -output-directory %o %f" |
|
1189 |
"%latex -interaction nonstopmode -output-directory %o %f")) |
|
1190 |
(const :tag "texi2dvi" |
|
1191 |
("cd %o; LATEX=\"%latex\" texi2dvi -p -b -V %b.tex")) |
|
1192 |
(const :tag "latexmk" |
|
1193 |
("latexmk -g -pdf -pdflatex=\"%latex\" -outdir=%o %f")) |
|
1194 |
(function))) |
|
1195 |
|
|
1196 |
(defcustom org-latex-logfiles-extensions |
|
1197 |
'("aux" "bcf" "blg" "fdb_latexmk" "fls" "figlist" "idx" "log" "nav" "out" |
|
1198 |
"ptc" "run.xml" "snm" "toc" "vrb" "xdv") |
|
1199 |
"The list of file extensions to consider as LaTeX logfiles. |
|
1200 |
The logfiles will be removed if `org-latex-remove-logfiles' is |
|
1201 |
non-nil." |
|
1202 |
:group 'org-export-latex |
|
1203 |
:version "26.1" |
|
1204 |
:package-version '(Org . "8.3") |
|
1205 |
:type '(repeat (string :tag "Extension"))) |
|
1206 |
|
|
1207 |
(defcustom org-latex-remove-logfiles t |
|
1208 |
"Non-nil means remove the logfiles produced by PDF production. |
|
1209 |
By default, logfiles are files with these extensions: .aux, .idx, |
|
1210 |
.log, .out, .toc, .nav, .snm and .vrb. To define the set of |
|
1211 |
logfiles to remove, set `org-latex-logfiles-extensions'." |
|
1212 |
:group 'org-export-latex |
|
1213 |
:type 'boolean) |
|
1214 |
|
|
1215 |
(defcustom org-latex-known-warnings |
|
1216 |
'(("Reference.*?undefined" . "[undefined reference]") |
|
1217 |
("Runaway argument" . "[runaway argument]") |
|
1218 |
("Underfull \\hbox" . "[underfull hbox]") |
|
1219 |
("Overfull \\hbox" . "[overfull hbox]") |
|
1220 |
("Citation.*?undefined" . "[undefined citation]") |
|
1221 |
("Undefined control sequence" . "[undefined control sequence]")) |
|
1222 |
"Alist of regular expressions and associated messages for the user. |
|
1223 |
The regular expressions are used to find possible warnings in the |
|
1224 |
log of a latex-run. These warnings will be reported after |
|
1225 |
calling `org-latex-compile'." |
|
1226 |
:group 'org-export-latex |
|
1227 |
:version "26.1" |
|
1228 |
:package-version '(Org . "8.3") |
|
1229 |
:type '(repeat |
|
1230 |
(cons |
|
1231 |
(string :tag "Regexp") |
|
1232 |
(string :tag "Message")))) |
|
1233 |
|
|
1234 |
|
|
1235 |
|
|
1236 |
;;; Internal Functions |
|
1237 |
|
|
1238 |
(defun org-latex--caption-above-p (element info) |
|
1239 |
"Non nil when caption is expected to be located above ELEMENT. |
|
1240 |
INFO is a plist holding contextual information." |
|
1241 |
(let ((above (plist-get info :latex-caption-above))) |
|
1242 |
(if (symbolp above) above |
|
1243 |
(let ((type (org-element-type element))) |
|
1244 |
(memq (if (eq type 'link) 'image type) above))))) |
|
1245 |
|
|
1246 |
(defun org-latex--label (datum info &optional force full) |
|
1247 |
"Return an appropriate label for DATUM. |
|
1248 |
DATUM is an element or a `target' type object. INFO is the |
|
1249 |
current export state, as a plist. |
|
1250 |
|
|
1251 |
Return nil if element DATUM has no NAME or VALUE affiliated |
|
1252 |
keyword or no CUSTOM_ID property, unless FORCE is non-nil. In |
|
1253 |
this case always return a unique label. |
|
1254 |
|
|
1255 |
Eventually, if FULL is non-nil, wrap label within \"\\label{}\"." |
|
1256 |
(let* ((type (org-element-type datum)) |
|
1257 |
(user-label |
|
1258 |
(org-element-property |
|
1259 |
(cl-case type |
|
1260 |
((headline inlinetask) :CUSTOM_ID) |
|
1261 |
(target :value) |
|
1262 |
(otherwise :name)) |
|
1263 |
datum)) |
|
1264 |
(label |
|
1265 |
(and (or user-label force) |
|
1266 |
(if (and user-label (plist-get info :latex-prefer-user-labels)) |
|
1267 |
user-label |
|
1268 |
(concat (cl-case type |
|
1269 |
(headline "sec:") |
|
1270 |
(table "tab:") |
|
1271 |
(latex-environment |
|
1272 |
(and (string-match-p |
|
1273 |
org-latex-math-environments-re |
|
1274 |
(org-element-property :value datum)) |
|
1275 |
"eq:")) |
|
1276 |
(paragraph |
|
1277 |
(and (org-element-property :caption datum) |
|
1278 |
"fig:"))) |
|
1279 |
(org-export-get-reference datum info)))))) |
|
1280 |
(cond ((not full) label) |
|
1281 |
(label (format "\\label{%s}%s" |
|
1282 |
label |
|
1283 |
(if (eq type 'target) "" "\n"))) |
|
1284 |
(t "")))) |
|
1285 |
|
|
1286 |
(defun org-latex--caption/label-string (element info) |
|
1287 |
"Return caption and label LaTeX string for ELEMENT. |
|
1288 |
|
|
1289 |
INFO is a plist holding contextual information. If there's no |
|
1290 |
caption nor label, return the empty string. |
|
1291 |
|
|
1292 |
For non-floats, see `org-latex--wrap-label'." |
|
1293 |
(let* ((label (org-latex--label element info nil t)) |
|
1294 |
(main (org-export-get-caption element)) |
|
1295 |
(attr (org-export-read-attribute :attr_latex element)) |
|
1296 |
(type (org-element-type element)) |
|
1297 |
(nonfloat (or (and (plist-member attr :float) |
|
1298 |
(not (plist-get attr :float)) |
|
1299 |
main) |
|
1300 |
(and (eq type 'src-block) |
|
1301 |
(not (plist-get attr :float)) |
|
1302 |
(null (plist-get info :latex-listings))))) |
|
1303 |
(short (org-export-get-caption element t)) |
|
1304 |
(caption-from-attr-latex (plist-get attr :caption))) |
|
1305 |
(cond |
|
1306 |
((org-string-nw-p caption-from-attr-latex) |
|
1307 |
(concat caption-from-attr-latex "\n")) |
|
1308 |
((and (not main) (equal label "")) "") |
|
1309 |
((not main) label) |
|
1310 |
;; Option caption format with short name. |
|
1311 |
(t |
|
1312 |
(format (if nonfloat "\\captionof{%s}%s{%s%s}\n" |
|
1313 |
"\\caption%s%s{%s%s}\n") |
|
1314 |
(let ((type* (if (eq type 'latex-environment) |
|
1315 |
(org-latex--environment-type element) |
|
1316 |
type))) |
|
1317 |
(if nonfloat |
|
1318 |
(cl-case type* |
|
1319 |
(paragraph "figure") |
|
1320 |
(image "figure") |
|
1321 |
(special-block "figure") |
|
1322 |
(src-block (if (plist-get info :latex-listings) |
|
1323 |
"listing" |
|
1324 |
"figure")) |
|
1325 |
(t (symbol-name type*))) |
|
1326 |
"")) |
|
1327 |
(if short (format "[%s]" (org-export-data short info)) "") |
|
1328 |
label |
|
1329 |
(org-export-data main info)))))) |
|
1330 |
|
|
1331 |
(defun org-latex-guess-inputenc (header) |
|
1332 |
"Set the coding system in inputenc to what the buffer is. |
|
1333 |
|
|
1334 |
HEADER is the LaTeX header string. This function only applies |
|
1335 |
when specified inputenc option is \"AUTO\". |
|
1336 |
|
|
1337 |
Return the new header, as a string." |
|
1338 |
(let* ((cs (or (ignore-errors |
|
1339 |
(latexenc-coding-system-to-inputenc |
|
1340 |
(or org-export-coding-system buffer-file-coding-system))) |
|
1341 |
"utf8"))) |
|
1342 |
(if (not cs) header |
|
1343 |
;; First translate if that is requested. |
|
1344 |
(setq cs (or (cdr (assoc cs org-latex-inputenc-alist)) cs)) |
|
1345 |
;; Then find the \usepackage statement and replace the option. |
|
1346 |
(replace-regexp-in-string "\\\\usepackage\\[\\(AUTO\\)\\]{inputenc}" |
|
1347 |
cs header t nil 1)))) |
|
1348 |
|
|
1349 |
(defun org-latex-guess-babel-language (header info) |
|
1350 |
"Set Babel's language according to LANGUAGE keyword. |
|
1351 |
|
|
1352 |
HEADER is the LaTeX header string. INFO is the plist used as |
|
1353 |
a communication channel. |
|
1354 |
|
|
1355 |
Insertion of guessed language only happens when Babel package has |
|
1356 |
explicitly been loaded. Then it is added to the rest of |
|
1357 |
package's options. |
|
1358 |
|
|
1359 |
The argument to Babel may be \"AUTO\" which is then replaced with |
|
1360 |
the language of the document or `org-export-default-language' |
|
1361 |
unless language in question is already loaded. |
|
1362 |
|
|
1363 |
Return the new header." |
|
1364 |
(let ((language-code (plist-get info :language))) |
|
1365 |
;; If no language is set or Babel package is not loaded, return |
|
1366 |
;; HEADER as-is. |
|
1367 |
(if (or (not (stringp language-code)) |
|
1368 |
(not (string-match "\\\\usepackage\\[\\(.*\\)\\]{babel}" header))) |
|
1369 |
header |
|
1370 |
(let ((options (save-match-data |
|
1371 |
(org-split-string (match-string 1 header) ",[ \t]*"))) |
|
1372 |
(language (cdr (assoc-string language-code |
|
1373 |
org-latex-babel-language-alist t)))) |
|
1374 |
;; If LANGUAGE is already loaded, return header without AUTO. |
|
1375 |
;; Otherwise, replace AUTO with language or append language if |
|
1376 |
;; AUTO is not present. |
|
1377 |
(replace-match |
|
1378 |
(mapconcat (lambda (option) (if (equal "AUTO" option) language option)) |
|
1379 |
(cond ((member language options) (delete "AUTO" options)) |
|
1380 |
((member "AUTO" options) options) |
|
1381 |
(t (append options (list language)))) |
|
1382 |
", ") |
|
1383 |
t nil header 1))))) |
|
1384 |
|
|
1385 |
(defun org-latex-guess-polyglossia-language (header info) |
|
1386 |
"Set the Polyglossia language according to the LANGUAGE keyword. |
|
1387 |
|
|
1388 |
HEADER is the LaTeX header string. INFO is the plist used as |
|
1389 |
a communication channel. |
|
1390 |
|
|
1391 |
Insertion of guessed language only happens when the Polyglossia |
|
1392 |
package has been explicitly loaded. |
|
1393 |
|
|
1394 |
The argument to Polyglossia may be \"AUTO\" which is then |
|
1395 |
replaced with the language of the document or |
|
1396 |
`org-export-default-language'. Note, the language is really set |
|
1397 |
using \setdefaultlanguage and not as an option to the package. |
|
1398 |
|
|
1399 |
Return the new header." |
|
1400 |
(let ((language (plist-get info :language))) |
|
1401 |
;; If no language is set or Polyglossia is not loaded, return |
|
1402 |
;; HEADER as-is. |
|
1403 |
(if (or (not (stringp language)) |
|
1404 |
(not (string-match |
|
1405 |
"\\\\usepackage\\(?:\\[\\([^]]+?\\)\\]\\){polyglossia}\n" |
|
1406 |
header))) |
|
1407 |
header |
|
1408 |
(let* ((options (org-string-nw-p (match-string 1 header))) |
|
1409 |
(languages (and options |
|
1410 |
;; Reverse as the last loaded language is |
|
1411 |
;; the main language. |
|
1412 |
(nreverse |
|
1413 |
(delete-dups |
|
1414 |
(save-match-data |
|
1415 |
(org-split-string |
|
1416 |
(replace-regexp-in-string |
|
1417 |
"AUTO" language options t) |
|
1418 |
",[ \t]*")))))) |
|
1419 |
(main-language-set |
|
1420 |
(string-match-p "\\\\setmainlanguage{.*?}" header))) |
|
1421 |
(replace-match |
|
1422 |
(concat "\\usepackage{polyglossia}\n" |
|
1423 |
(mapconcat |
|
1424 |
(lambda (l) |
|
1425 |
(let ((l (or (assoc l org-latex-polyglossia-language-alist) |
|
1426 |
l))) |
|
1427 |
(format (if main-language-set "\\setotherlanguage%s{%s}\n" |
|
1428 |
(setq main-language-set t) |
|
1429 |
"\\setmainlanguage%s{%s}\n") |
|
1430 |
(if (and (consp l) (= (length l) 3)) |
|
1431 |
(format "[variant=%s]" (nth 2 l)) |
|
1432 |
"") |
|
1433 |
(nth 1 l)))) |
|
1434 |
languages |
|
1435 |
"")) |
|
1436 |
t t header 0))))) |
|
1437 |
|
|
1438 |
(defun org-latex--remove-packages (pkg-alist info) |
|
1439 |
"Remove packages based on the current LaTeX compiler. |
|
1440 |
|
|
1441 |
If the fourth argument of an element is set in pkg-alist, and it |
|
1442 |
is not a member of the LaTeX compiler of the document, the packages |
|
1443 |
is removed. See also `org-latex-compiler'. |
|
1444 |
|
|
1445 |
Return modified pkg-alist." |
|
1446 |
(let ((compiler (or (plist-get info :latex-compiler) ""))) |
|
1447 |
(if (member-ignore-case compiler org-latex-compilers) |
|
1448 |
(delq nil |
|
1449 |
(mapcar |
|
1450 |
(lambda (pkg) |
|
1451 |
(unless (and |
|
1452 |
(listp pkg) |
|
1453 |
(let ((third (nth 3 pkg))) |
|
1454 |
(and third |
|
1455 |
(not (member-ignore-case |
|
1456 |
compiler |
|
1457 |
(if (listp third) third (list third))))))) |
|
1458 |
pkg)) |
|
1459 |
pkg-alist)) |
|
1460 |
pkg-alist))) |
|
1461 |
|
|
1462 |
(defun org-latex--find-verb-separator (s) |
|
1463 |
"Return a character not used in string S. |
|
1464 |
This is used to choose a separator for constructs like \\verb." |
|
1465 |
(let ((ll "~,./?;':\"|!@#%^&-_=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>()[]{}")) |
|
1466 |
(cl-loop for c across ll |
|
1467 |
when (not (string-match (regexp-quote (char-to-string c)) s)) |
|
1468 |
return (char-to-string c)))) |
|
1469 |
|
|
1470 |
(defun org-latex--make-option-string (options) |
|
1471 |
"Return a comma separated string of keywords and values. |
|
1472 |
OPTIONS is an alist where the key is the options keyword as |
|
1473 |
a string, and the value a list containing the keyword value, or |
|
1474 |
nil." |
|
1475 |
(mapconcat (lambda (pair) |
|
1476 |
(pcase-let ((`(,keyword ,value) pair)) |
|
1477 |
(concat keyword |
|
1478 |
(and (> (length value) 0) |
|
1479 |
(concat "=" value))))) |
|
1480 |
options |
|
1481 |
",")) |
|
1482 |
|
|
1483 |
(defun org-latex--wrap-label (element output info) |
|
1484 |
"Wrap label associated to ELEMENT around OUTPUT, if appropriate. |
|
1485 |
INFO is the current export state, as a plist. This function |
|
1486 |
should not be used for floats. See |
|
1487 |
`org-latex--caption/label-string'." |
|
1488 |
(if (not (and (org-string-nw-p output) (org-element-property :name element))) |
|
1489 |
output |
|
1490 |
(concat (format "\\phantomsection\n\\label{%s}\n" |
|
1491 |
(org-latex--label element info)) |
|
1492 |
output))) |
|
1493 |
|
|
1494 |
(defun org-latex--protect-text (text) |
|
1495 |
"Protect special characters in string TEXT and return it." |
|
1496 |
(replace-regexp-in-string "[\\{}$%&_#~^]" "\\\\\\&" text)) |
|
1497 |
|
|
1498 |
(defun org-latex--text-markup (text markup info) |
|
1499 |
"Format TEXT depending on MARKUP text markup. |
|
1500 |
INFO is a plist used as a communication channel. See |
|
1501 |
`org-latex-text-markup-alist' for details." |
|
1502 |
(let ((fmt (cdr (assq markup (plist-get info :latex-text-markup-alist))))) |
|
1503 |
(cl-case fmt |
|
1504 |
;; No format string: Return raw text. |
|
1505 |
((nil) text) |
|
1506 |
;; Handle the `verb' special case: Find an appropriate separator |
|
1507 |
;; and use "\\verb" command. |
|
1508 |
(verb |
|
1509 |
(let ((separator (org-latex--find-verb-separator text))) |
|
1510 |
(concat "\\verb" |
|
1511 |
separator |
|
1512 |
(replace-regexp-in-string "\n" " " text) |
|
1513 |
separator))) |
|
1514 |
;; Handle the `protectedtexttt' special case: Protect some |
|
1515 |
;; special chars and use "\texttt{%s}" format string. |
|
1516 |
(protectedtexttt |
|
1517 |
(format "\\texttt{%s}" |
|
1518 |
(replace-regexp-in-string |
|
1519 |
"--\\|[\\{}$%&_#~^]" |
|
1520 |
(lambda (m) |
|
1521 |
(cond ((equal m "--") "-{}-") |
|
1522 |
((equal m "\\") "\\textbackslash{}") |
|
1523 |
((equal m "~") "\\textasciitilde{}") |
|
1524 |
((equal m "^") "\\textasciicircum{}") |
|
1525 |
(t (org-latex--protect-text m)))) |
|
1526 |
text nil t))) |
|
1527 |
;; Else use format string. |
|
1528 |
(t (format fmt text))))) |
|
1529 |
|
|
1530 |
(defun org-latex--delayed-footnotes-definitions (element info) |
|
1531 |
"Return footnotes definitions in ELEMENT as a string. |
|
1532 |
|
|
1533 |
INFO is a plist used as a communication channel. |
|
1534 |
|
|
1535 |
Footnotes definitions are returned within \"\\footnotetext{}\" |
|
1536 |
commands. |
|
1537 |
|
|
1538 |
This function is used within constructs that don't support |
|
1539 |
\"\\footnote{}\" command (e.g., an item tag). In that case, |
|
1540 |
\"\\footnotemark\" is used within the construct and the function |
|
1541 |
just outside of it." |
|
1542 |
(mapconcat |
|
1543 |
(lambda (ref) |
|
1544 |
(let ((def (org-export-get-footnote-definition ref info))) |
|
1545 |
(format "\\footnotetext[%d]{%s%s}" |
|
1546 |
(org-export-get-footnote-number ref info) |
|
1547 |
(org-trim (org-latex--label def info t t)) |
|
1548 |
(org-trim (org-export-data def info))))) |
|
1549 |
;; Find every footnote reference in ELEMENT. |
|
1550 |
(letrec ((all-refs nil) |
|
1551 |
(search-refs |
|
1552 |
(lambda (data) |
|
1553 |
;; Return a list of all footnote references never seen |
|
1554 |
;; before in DATA. |
|
1555 |
(org-element-map data 'footnote-reference |
|
1556 |
(lambda (ref) |
|
1557 |
(when (org-export-footnote-first-reference-p ref info) |
|
1558 |
(push ref all-refs) |
|
1559 |
(when (eq (org-element-property :type ref) 'standard) |
|
1560 |
(funcall search-refs |
|
1561 |
(org-export-get-footnote-definition ref info))))) |
|
1562 |
info) |
|
1563 |
(reverse all-refs)))) |
|
1564 |
(funcall search-refs element)) |
|
1565 |
"")) |
|
1566 |
|
|
1567 |
(defun org-latex--translate (s info) |
|
1568 |
"Translate string S according to specified language. |
|
1569 |
INFO is a plist used as a communication channel." |
|
1570 |
(org-export-translate s :latex info)) |
|
1571 |
|
|
1572 |
(defun org-latex--format-spec (info) |
|
1573 |
"Create a format-spec for document meta-data. |
|
1574 |
INFO is a plist used as a communication channel." |
|
1575 |
(let ((language (let ((lang (plist-get info :language))) |
|
1576 |
(or (cdr (assoc-string lang org-latex-babel-language-alist t)) |
|
1577 |
(nth 1 (assoc-string lang org-latex-polyglossia-language-alist t)) |
|
1578 |
lang)))) |
|
1579 |
`((?a . ,(org-export-data (plist-get info :author) info)) |
|
1580 |
(?t . ,(org-export-data (plist-get info :title) info)) |
|
1581 |
(?k . ,(org-export-data (org-latex--wrap-latex-math-block |
|
1582 |
(plist-get info :keywords) info) |
|
1583 |
info)) |
|
1584 |
(?d . ,(org-export-data (org-latex--wrap-latex-math-block |
|
1585 |
(plist-get info :description) info) |
|
1586 |
info)) |
|
1587 |
(?c . ,(plist-get info :creator)) |
|
1588 |
(?l . ,language) |
|
1589 |
(?L . ,(capitalize language)) |
|
1590 |
(?D . ,(org-export-get-date info))))) |
|
1591 |
|
|
1592 |
(defun org-latex--insert-compiler (info) |
|
1593 |
"Insert LaTeX_compiler info into the document. |
|
1594 |
INFO is a plist used as a communication channel." |
|
1595 |
(let ((compiler (plist-get info :latex-compiler))) |
|
1596 |
(and (org-string-nw-p org-latex-compiler-file-string) |
|
1597 |
(member (or compiler "") org-latex-compilers) |
|
1598 |
(format org-latex-compiler-file-string compiler)))) |
|
1599 |
|
|
1600 |
|
|
1601 |
;;; Filters |
|
1602 |
|
|
1603 |
(defun org-latex-matrices-tree-filter (tree _backend info) |
|
1604 |
(org-latex--wrap-latex-matrices tree info)) |
|
1605 |
|
|
1606 |
(defun org-latex-math-block-tree-filter (tree _backend info) |
|
1607 |
(org-latex--wrap-latex-math-block tree info)) |
|
1608 |
|
|
1609 |
(defun org-latex-math-block-options-filter (info _backend) |
|
1610 |
(dolist (prop '(:author :date :title) info) |
|
1611 |
(plist-put info prop |
|
1612 |
(org-latex--wrap-latex-math-block (plist-get info prop) info)))) |
|
1613 |
|
|
1614 |
(defun org-latex-clean-invalid-line-breaks (data _backend _info) |
|
1615 |
(replace-regexp-in-string |
|
1616 |
"\\(\\end{[A-Za-z0-9*]+}\\|^\\)[ \t]*\\\\\\\\[ \t]*$" "\\1" |
|
1617 |
data)) |
|
1618 |
|
|
1619 |
|
|
1620 |
;;; Template |
|
1621 |
|
|
1622 |
;;;###autoload |
|
1623 |
(defun org-latex-make-preamble (info &optional template snippet?) |
|
1624 |
"Return a formatted LaTeX preamble. |
|
1625 |
INFO is a plist used as a communication channel. Optional |
|
1626 |
argument TEMPLATE, when non-nil, is the header template string, |
|
1627 |
as expected by `org-splice-latex-header'. When SNIPPET? is |
|
1628 |
non-nil, only includes packages relevant to image generation, as |
|
1629 |
specified in `org-latex-default-packages-alist' or |
|
1630 |
`org-latex-packages-alist'." |
|
1631 |
(let* ((class (plist-get info :latex-class)) |
|
1632 |
(class-template |
|
1633 |
(or template |
|
1634 |
(let* ((class-options (plist-get info :latex-class-options)) |
|
1635 |
(header (nth 1 (assoc class (plist-get info :latex-classes))))) |
|
1636 |
(and (stringp header) |
|
1637 |
(if (not class-options) header |
|
1638 |
(replace-regexp-in-string |
|
1639 |
"^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)" |
|
1640 |
class-options header t nil 1)))) |
|
1641 |
(user-error "Unknown LaTeX class `%s'" class)))) |
|
1642 |
(org-latex-guess-polyglossia-language |
|
1643 |
(org-latex-guess-babel-language |
|
1644 |
(org-latex-guess-inputenc |
|
1645 |
(org-element-normalize-string |
|
1646 |
(org-splice-latex-header |
|
1647 |
class-template |
|
1648 |
(org-latex--remove-packages org-latex-default-packages-alist info) |
|
1649 |
(org-latex--remove-packages org-latex-packages-alist info) |
|
1650 |
snippet? |
|
1651 |
(mapconcat #'org-element-normalize-string |
|
1652 |
(list (plist-get info :latex-header) |
|
1653 |
(and (not snippet?) |
|
1654 |
(plist-get info :latex-header-extra))) |
|
1655 |
"")))) |
|
1656 |
info) |
|
1657 |
info))) |
|
1658 |
|
|
1659 |
(defun org-latex-template (contents info) |
|
1660 |
"Return complete document string after LaTeX conversion. |
|
1661 |
CONTENTS is the transcoded contents string. INFO is a plist |
|
1662 |
holding export options." |
|
1663 |
(let ((title (org-export-data (plist-get info :title) info)) |
|
1664 |
(spec (org-latex--format-spec info))) |
|
1665 |
(concat |
|
1666 |
;; Time-stamp. |
|
1667 |
(and (plist-get info :time-stamp-file) |
|
1668 |
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n")) |
|
1669 |
;; LaTeX compiler. |
|
1670 |
(org-latex--insert-compiler info) |
|
1671 |
;; Document class and packages. |
|
1672 |
(org-latex-make-preamble info) |
|
1673 |
;; Possibly limit depth for headline numbering. |
|
1674 |
(let ((sec-num (plist-get info :section-numbers))) |
|
1675 |
(when (integerp sec-num) |
|
1676 |
(format "\\setcounter{secnumdepth}{%d}\n" sec-num))) |
|
1677 |
;; Author. |
|
1678 |
(let ((author (and (plist-get info :with-author) |
|
1679 |
(let ((auth (plist-get info :author))) |
|
1680 |
(and auth (org-export-data auth info))))) |
|
1681 |
(email (and (plist-get info :with-email) |
|
1682 |
(org-export-data (plist-get info :email) info)))) |
|
1683 |
(cond ((and author email (not (string= "" email))) |
|
1684 |
(format "\\author{%s\\thanks{%s}}\n" author email)) |
|
1685 |
((or author email) (format "\\author{%s}\n" (or author email))))) |
|
1686 |
;; Date. |
|
1687 |
(let ((date (and (plist-get info :with-date) (org-export-get-date info)))) |
|
1688 |
(format "\\date{%s}\n" (org-export-data date info))) |
|
1689 |
;; Title and subtitle. |
|
1690 |
(let* ((subtitle (plist-get info :subtitle)) |
|
1691 |
(formatted-subtitle |
|
1692 |
(when subtitle |
|
1693 |
(format (plist-get info :latex-subtitle-format) |
|
1694 |
(org-export-data subtitle info)))) |
|
1695 |
(separate (plist-get info :latex-subtitle-separate))) |
|
1696 |
(concat |
|
1697 |
(format "\\title{%s%s}\n" title |
|
1698 |
(if separate "" (or formatted-subtitle ""))) |
|
1699 |
(when (and separate subtitle) |
|
1700 |
(concat formatted-subtitle "\n")))) |
|
1701 |
;; Hyperref options. |
|
1702 |
(let ((template (plist-get info :latex-hyperref-template))) |
|
1703 |
(and (stringp template) |
|
1704 |
(format-spec template spec))) |
|
1705 |
;; Document start. |
|
1706 |
"\\begin{document}\n\n" |
|
1707 |
;; Title command. |
|
1708 |
(let* ((title-command (plist-get info :latex-title-command)) |
|
1709 |
(command (and (stringp title-command) |
|
1710 |
(format-spec title-command spec)))) |
|
1711 |
(org-element-normalize-string |
|
1712 |
(cond ((not (plist-get info :with-title)) nil) |
|
1713 |
((string= "" title) nil) |
|
1714 |
((not (stringp command)) nil) |
|
1715 |
((string-match "\\(?:[^%]\\|^\\)%s" command) |
|
1716 |
(format command title)) |
|
1717 |
(t command)))) |
|
1718 |
;; Table of contents. |
|
1719 |
(let ((depth (plist-get info :with-toc))) |
|
1720 |
(when depth |
|
1721 |
(concat (when (integerp depth) |
|
1722 |
(format "\\setcounter{tocdepth}{%d}\n" depth)) |
|
1723 |
(plist-get info :latex-toc-command)))) |
|
1724 |
;; Document's body. |
|
1725 |
contents |
|
1726 |
;; Creator. |
|
1727 |
(and (plist-get info :with-creator) |
|
1728 |
(concat (plist-get info :creator) "\n")) |
|
1729 |
;; Document end. |
|
1730 |
"\\end{document}"))) |
|
1731 |
|
|
1732 |
|
|
1733 |
|
|
1734 |
;;; Transcode Functions |
|
1735 |
|
|
1736 |
;;;; Bold |
|
1737 |
|
|
1738 |
(defun org-latex-bold (_bold contents info) |
|
1739 |
"Transcode BOLD from Org to LaTeX. |
|
1740 |
CONTENTS is the text with bold markup. INFO is a plist holding |
|
1741 |
contextual information." |
|
1742 |
(org-latex--text-markup contents 'bold info)) |
|
1743 |
|
|
1744 |
|
|
1745 |
;;;; Center Block |
|
1746 |
|
|
1747 |
(defun org-latex-center-block (center-block contents info) |
|
1748 |
"Transcode a CENTER-BLOCK element from Org to LaTeX. |
|
1749 |
CONTENTS holds the contents of the center block. INFO is a plist |
|
1750 |
holding contextual information." |
|
1751 |
(org-latex--wrap-label |
|
1752 |
center-block (format "\\begin{center}\n%s\\end{center}" contents) info)) |
|
1753 |
|
|
1754 |
|
|
1755 |
;;;; Clock |
|
1756 |
|
|
1757 |
(defun org-latex-clock (clock _contents info) |
|
1758 |
"Transcode a CLOCK element from Org to LaTeX. |
|
1759 |
CONTENTS is nil. INFO is a plist holding contextual |
|
1760 |
information." |
|
1761 |
(concat |
|
1762 |
"\\noindent" |
|
1763 |
(format "\\textbf{%s} " org-clock-string) |
|
1764 |
(format (plist-get info :latex-inactive-timestamp-format) |
|
1765 |
(concat (org-timestamp-translate (org-element-property :value clock)) |
|
1766 |
(let ((time (org-element-property :duration clock))) |
|
1767 |
(and time (format " (%s)" time))))) |
|
1768 |
"\\\\")) |
|
1769 |
|
|
1770 |
|
|
1771 |
;;;; Code |
|
1772 |
|
|
1773 |
(defun org-latex-code (code _contents info) |
|
1774 |
"Transcode a CODE object from Org to LaTeX. |
|
1775 |
CONTENTS is nil. INFO is a plist used as a communication |
|
1776 |
channel." |
|
1777 |
(org-latex--text-markup (org-element-property :value code) 'code info)) |
|
1778 |
|
|
1779 |
|
|
1780 |
;;;; Drawer |
|
1781 |
|
|
1782 |
(defun org-latex-drawer (drawer contents info) |
|
1783 |
"Transcode a DRAWER element from Org to LaTeX. |
|
1784 |
CONTENTS holds the contents of the block. INFO is a plist |
|
1785 |
holding contextual information." |
|
1786 |
(let* ((name (org-element-property :drawer-name drawer)) |
|
1787 |
(output (funcall (plist-get info :latex-format-drawer-function) |
|
1788 |
name contents))) |
|
1789 |
(org-latex--wrap-label drawer output info))) |
|
1790 |
|
|
1791 |
|
|
1792 |
;;;; Dynamic Block |
|
1793 |
|
|
1794 |
(defun org-latex-dynamic-block (dynamic-block contents info) |
|
1795 |
"Transcode a DYNAMIC-BLOCK element from Org to LaTeX. |
|
1796 |
CONTENTS holds the contents of the block. INFO is a plist |
|
1797 |
holding contextual information. See `org-export-data'." |
|
1798 |
(org-latex--wrap-label dynamic-block contents info)) |
|
1799 |
|
|
1800 |
|
|
1801 |
;;;; Entity |
|
1802 |
|
|
1803 |
(defun org-latex-entity (entity _contents _info) |
|
1804 |
"Transcode an ENTITY object from Org to LaTeX. |
|
1805 |
CONTENTS are the definition itself. INFO is a plist holding |
|
1806 |
contextual information." |
|
1807 |
(org-element-property :latex entity)) |
|
1808 |
|
|
1809 |
|
|
1810 |
;;;; Example Block |
|
1811 |
|
|
1812 |
(defun org-latex-example-block (example-block _contents info) |
|
1813 |
"Transcode an EXAMPLE-BLOCK element from Org to LaTeX. |
|
1814 |
CONTENTS is nil. INFO is a plist holding contextual |
|
1815 |
information." |
|
1816 |
(when (org-string-nw-p (org-element-property :value example-block)) |
|
1817 |
(let ((environment (or (org-export-read-attribute |
|
1818 |
:attr_latex example-block :environment) |
|
1819 |
"verbatim"))) |
|
1820 |
(org-latex--wrap-label |
|
1821 |
example-block |
|
1822 |
(format "\\begin{%s}\n%s\\end{%s}" |
|
1823 |
environment |
|
1824 |
(org-export-format-code-default example-block info) |
|
1825 |
environment) |
|
1826 |
info)))) |
|
1827 |
|
|
1828 |
|
|
1829 |
;;;; Export Block |
|
1830 |
|
|
1831 |
(defun org-latex-export-block (export-block _contents _info) |
|
1832 |
"Transcode a EXPORT-BLOCK element from Org to LaTeX. |
|
1833 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
1834 |
(when (member (org-element-property :type export-block) '("LATEX" "TEX")) |
|
1835 |
(org-remove-indentation (org-element-property :value export-block)))) |
|
1836 |
|
|
1837 |
|
|
1838 |
;;;; Export Snippet |
|
1839 |
|
|
1840 |
(defun org-latex-export-snippet (export-snippet _contents _info) |
|
1841 |
"Transcode a EXPORT-SNIPPET object from Org to LaTeX. |
|
1842 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
1843 |
(when (eq (org-export-snippet-backend export-snippet) 'latex) |
|
1844 |
(org-element-property :value export-snippet))) |
|
1845 |
|
|
1846 |
|
|
1847 |
;;;; Fixed Width |
|
1848 |
|
|
1849 |
(defun org-latex-fixed-width (fixed-width _contents info) |
|
1850 |
"Transcode a FIXED-WIDTH element from Org to LaTeX. |
|
1851 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
1852 |
(org-latex--wrap-label |
|
1853 |
fixed-width |
|
1854 |
(format "\\begin{verbatim}\n%s\\end{verbatim}" |
|
1855 |
(org-remove-indentation |
|
1856 |
(org-element-property :value fixed-width))) |
|
1857 |
info)) |
|
1858 |
|
|
1859 |
|
|
1860 |
;;;; Footnote Reference |
|
1861 |
|
|
1862 |
(defun org-latex-footnote-reference (footnote-reference _contents info) |
|
1863 |
"Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX. |
|
1864 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
1865 |
(let ((label (org-element-property :label footnote-reference))) |
|
1866 |
(concat |
|
1867 |
;; Insert separator between two footnotes in a row. |
|
1868 |
(let ((prev (org-export-get-previous-element footnote-reference info))) |
|
1869 |
(when (eq (org-element-type prev) 'footnote-reference) |
|
1870 |
(plist-get info :latex-footnote-separator))) |
|
1871 |
(cond |
|
1872 |
;; Use `:latex-footnote-defined-format' if the footnote has |
|
1873 |
;; already been defined. |
|
1874 |
((not (org-export-footnote-first-reference-p footnote-reference info)) |
|
1875 |
(format (plist-get info :latex-footnote-defined-format) |
|
1876 |
(org-latex--label |
|
1877 |
(org-export-get-footnote-definition footnote-reference info) |
|
1878 |
info t))) |
|
1879 |
;; Use \footnotemark if reference is within another footnote |
|
1880 |
;; reference, footnote definition or table cell. |
|
1881 |
((org-element-lineage footnote-reference |
|
1882 |
'(footnote-reference footnote-definition table-cell)) |
|
1883 |
"\\footnotemark") |
|
1884 |
;; Otherwise, define it with \footnote command. |
|
1885 |
(t |
|
1886 |
(let ((def (org-export-get-footnote-definition footnote-reference info))) |
|
1887 |
(concat |
|
1888 |
(format "\\footnote{%s%s}" (org-trim (org-export-data def info)) |
|
1889 |
;; Only insert a \label if there exist another |
|
1890 |
;; reference to def. |
|
1891 |
(cond ((not label) "") |
|
1892 |
((org-element-map (plist-get info :parse-tree) 'footnote-reference |
|
1893 |
(lambda (f) |
|
1894 |
(and (not (eq f footnote-reference)) |
|
1895 |
(equal (org-element-property :label f) label) |
|
1896 |
(org-trim (org-latex--label def info t t)))) |
|
1897 |
info t)) |
|
1898 |
(t ""))) |
|
1899 |
;; Retrieve all footnote references within the footnote and |
|
1900 |
;; add their definition after it, since LaTeX doesn't support |
|
1901 |
;; them inside. |
|
1902 |
(org-latex--delayed-footnotes-definitions def info)))))))) |
|
1903 |
|
|
1904 |
|
|
1905 |
;;;; Headline |
|
1906 |
|
|
1907 |
(defun org-latex-headline (headline contents info) |
|
1908 |
"Transcode a HEADLINE element from Org to LaTeX. |
|
1909 |
CONTENTS holds the contents of the headline. INFO is a plist |
|
1910 |
holding contextual information." |
|
1911 |
(unless (org-element-property :footnote-section-p headline) |
|
1912 |
(let* ((class (plist-get info :latex-class)) |
|
1913 |
(level (org-export-get-relative-level headline info)) |
|
1914 |
(numberedp (org-export-numbered-headline-p headline info)) |
|
1915 |
(class-sectioning (assoc class (plist-get info :latex-classes))) |
|
1916 |
;; Section formatting will set two placeholders: one for |
|
1917 |
;; the title and the other for the contents. |
|
1918 |
(section-fmt |
|
1919 |
(let ((sec (if (functionp (nth 2 class-sectioning)) |
|
1920 |
(funcall (nth 2 class-sectioning) level numberedp) |
|
1921 |
(nth (1+ level) class-sectioning)))) |
|
1922 |
(cond |
|
1923 |
;; No section available for that LEVEL. |
|
1924 |
((not sec) nil) |
|
1925 |
;; Section format directly returned by a function. Add |
|
1926 |
;; placeholder for contents. |
|
1927 |
((stringp sec) (concat sec "\n%s")) |
|
1928 |
;; (numbered-section . unnumbered-section) |
|
1929 |
((not (consp (cdr sec))) |
|
1930 |
(concat (funcall (if numberedp #'car #'cdr) sec) "\n%s")) |
|
1931 |
;; (numbered-open numbered-close) |
|
1932 |
((= (length sec) 2) |
|
1933 |
(when numberedp (concat (car sec) "\n%s" (nth 1 sec)))) |
|
1934 |
;; (num-in num-out no-num-in no-num-out) |
|
1935 |
((= (length sec) 4) |
|
1936 |
(if numberedp (concat (car sec) "\n%s" (nth 1 sec)) |
|
1937 |
(concat (nth 2 sec) "\n%s" (nth 3 sec))))))) |
|
1938 |
;; Create a temporary export back-end that hard-codes |
|
1939 |
;; "\underline" within "\section" and alike. |
|
1940 |
(section-back-end |
|
1941 |
(org-export-create-backend |
|
1942 |
:parent 'latex |
|
1943 |
:transcoders |
|
1944 |
'((underline . (lambda (o c i) (format "\\underline{%s}" c)))))) |
|
1945 |
(text |
|
1946 |
(org-export-data-with-backend |
|
1947 |
(org-element-property :title headline) section-back-end info)) |
|
1948 |
(todo |
|
1949 |
(and (plist-get info :with-todo-keywords) |
|
1950 |
(let ((todo (org-element-property :todo-keyword headline))) |
|
1951 |
(and todo (org-export-data todo info))))) |
|
1952 |
(todo-type (and todo (org-element-property :todo-type headline))) |
|
1953 |
(tags (and (plist-get info :with-tags) |
|
1954 |
(org-export-get-tags headline info))) |
|
1955 |
(priority (and (plist-get info :with-priority) |
|
1956 |
(org-element-property :priority headline))) |
|
1957 |
;; Create the headline text along with a no-tag version. |
|
1958 |
;; The latter is required to remove tags from toc. |
|
1959 |
(full-text (funcall (plist-get info :latex-format-headline-function) |
|
1960 |
todo todo-type priority text tags info)) |
|
1961 |
;; Associate \label to the headline for internal links. |
|
1962 |
(headline-label (org-latex--label headline info t t)) |
|
1963 |
(pre-blanks |
|
1964 |
(make-string (org-element-property :pre-blank headline) ?\n))) |
|
1965 |
(if (or (not section-fmt) (org-export-low-level-p headline info)) |
|
1966 |
;; This is a deep sub-tree: export it as a list item. Also |
|
1967 |
;; export as items headlines for which no section format has |
|
1968 |
;; been found. |
|
1969 |
(let ((low-level-body |
|
1970 |
(concat |
|
1971 |
;; If headline is the first sibling, start a list. |
|
1972 |
(when (org-export-first-sibling-p headline info) |
|
1973 |
(format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize))) |
|
1974 |
;; Itemize headline |
|
1975 |
"\\item" |
|
1976 |
(and full-text |
|
1977 |
(string-match-p "\\`[ \t]*\\[" full-text) |
|
1978 |
"\\relax") |
|
1979 |
" " full-text "\n" |
|
1980 |
headline-label |
|
1981 |
pre-blanks |
|
1982 |
contents))) |
|
1983 |
;; If headline is not the last sibling simply return |
|
1984 |
;; LOW-LEVEL-BODY. Otherwise, also close the list, before |
|
1985 |
;; any blank line. |
|
1986 |
(if (not (org-export-last-sibling-p headline info)) low-level-body |
|
1987 |
(replace-regexp-in-string |
|
1988 |
"[ \t\n]*\\'" |
|
1989 |
(format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize)) |
|
1990 |
low-level-body))) |
|
1991 |
;; This is a standard headline. Export it as a section. Add |
|
1992 |
;; an alternative heading when possible, and when this is not |
|
1993 |
;; identical to the usual heading. |
|
1994 |
(let ((opt-title |
|
1995 |
(funcall (plist-get info :latex-format-headline-function) |
|
1996 |
todo todo-type priority |
|
1997 |
(org-export-data-with-backend |
|
1998 |
(org-export-get-alt-title headline info) |
|
1999 |
section-back-end info) |
|
2000 |
(and (eq (plist-get info :with-tags) t) tags) |
|
2001 |
info)) |
|
2002 |
;; Maybe end local TOC (see `org-latex-keyword'). |
|
2003 |
(contents |
|
2004 |
(concat |
|
2005 |
contents |
|
2006 |
(let ((case-fold-search t) |
|
2007 |
(section |
|
2008 |
(let ((first (car (org-element-contents headline)))) |
|
2009 |
(and (eq (org-element-type first) 'section) first)))) |
|
2010 |
(org-element-map section 'keyword |
|
2011 |
(lambda (k) |
|
2012 |
(and (equal (org-element-property :key k) "TOC") |
|
2013 |
(let ((v (org-element-property :value k))) |
|
2014 |
(and (string-match-p "\\<headlines\\>" v) |
|
2015 |
(string-match-p "\\<local\\>" v) |
|
2016 |
(format "\\stopcontents[level-%d]" level))))) |
|
2017 |
info t))))) |
|
2018 |
(if (and opt-title |
|
2019 |
(not (equal opt-title full-text)) |
|
2020 |
(string-match "\\`\\\\\\(.+?\\){" section-fmt)) |
|
2021 |
(format (replace-match "\\1[%s]" nil nil section-fmt 1) |
|
2022 |
;; Replace square brackets with parenthesis |
|
2023 |
;; since square brackets are not supported in |
|
2024 |
;; optional arguments. |
|
2025 |
(replace-regexp-in-string |
|
2026 |
"\\[" "(" (replace-regexp-in-string "\\]" ")" opt-title)) |
|
2027 |
full-text |
|
2028 |
(concat headline-label pre-blanks contents)) |
|
2029 |
;; Impossible to add an alternative heading. Fallback to |
|
2030 |
;; regular sectioning format string. |
|
2031 |
(format section-fmt full-text |
|
2032 |
(concat headline-label pre-blanks contents)))))))) |
|
2033 |
|
|
2034 |
(defun org-latex-format-headline-default-function |
|
2035 |
(todo _todo-type priority text tags _info) |
|
2036 |
"Default format function for a headline. |
|
2037 |
See `org-latex-format-headline-function' for details." |
|
2038 |
(concat |
|
2039 |
(and todo (format "{\\bfseries\\sffamily %s} " todo)) |
|
2040 |
(and priority (format "\\framebox{\\#%c} " priority)) |
|
2041 |
text |
|
2042 |
(and tags |
|
2043 |
(format "\\hfill{}\\textsc{%s}" |
|
2044 |
(mapconcat #'org-latex--protect-text tags ":"))))) |
|
2045 |
|
|
2046 |
|
|
2047 |
;;;; Horizontal Rule |
|
2048 |
|
|
2049 |
(defun org-latex-horizontal-rule (horizontal-rule _contents info) |
|
2050 |
"Transcode an HORIZONTAL-RULE object from Org to LaTeX. |
|
2051 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
2052 |
(let ((attr (org-export-read-attribute :attr_latex horizontal-rule)) |
|
2053 |
(prev (org-export-get-previous-element horizontal-rule info))) |
|
2054 |
(concat |
|
2055 |
;; Make sure the rule doesn't start at the end of the current |
|
2056 |
;; line by separating it with a blank line from previous element. |
|
2057 |
(when (and prev |
|
2058 |
(let ((prev-blank (org-element-property :post-blank prev))) |
|
2059 |
(or (not prev-blank) (zerop prev-blank)))) |
|
2060 |
"\n") |
|
2061 |
(org-latex--wrap-label |
|
2062 |
horizontal-rule |
|
2063 |
(format "\\noindent\\rule{%s}{%s}" |
|
2064 |
(or (plist-get attr :width) "\\textwidth") |
|
2065 |
(or (plist-get attr :thickness) "0.5pt")) |
|
2066 |
info)))) |
|
2067 |
|
|
2068 |
|
|
2069 |
;;;; Inline Src Block |
|
2070 |
|
|
2071 |
(defun org-latex-inline-src-block (inline-src-block _contents info) |
|
2072 |
"Transcode an INLINE-SRC-BLOCK element from Org to LaTeX. |
|
2073 |
CONTENTS holds the contents of the item. INFO is a plist holding |
|
2074 |
contextual information." |
|
2075 |
(let* ((code (org-element-property :value inline-src-block)) |
|
2076 |
(separator (org-latex--find-verb-separator code))) |
|
2077 |
(cl-case (plist-get info :latex-listings) |
|
2078 |
;; Do not use a special package: transcode it verbatim. |
|
2079 |
((nil) (format "\\texttt{%s}" (org-latex--text-markup code 'code info))) |
|
2080 |
;; Use minted package. |
|
2081 |
(minted |
|
2082 |
(let* ((org-lang (org-element-property :language inline-src-block)) |
|
2083 |
(mint-lang (or (cadr (assq (intern org-lang) |
|
2084 |
(plist-get info :latex-minted-langs))) |
|
2085 |
(downcase org-lang))) |
|
2086 |
(options (org-latex--make-option-string |
|
2087 |
(plist-get info :latex-minted-options)))) |
|
2088 |
(format "\\mintinline%s{%s}{%s}" |
|
2089 |
(if (string= options "") "" (format "[%s]" options)) |
|
2090 |
mint-lang |
|
2091 |
code))) |
|
2092 |
;; Use listings package. |
|
2093 |
(otherwise |
|
2094 |
;; Maybe translate language's name. |
|
2095 |
(let* ((org-lang (org-element-property :language inline-src-block)) |
|
2096 |
(lst-lang (or (cadr (assq (intern org-lang) |
|
2097 |
(plist-get info :latex-listings-langs))) |
|
2098 |
org-lang)) |
|
2099 |
(options (org-latex--make-option-string |
|
2100 |
(append (plist-get info :latex-listings-options) |
|
2101 |
`(("language" ,lst-lang)))))) |
|
2102 |
(concat (format "\\lstinline[%s]" options) |
|
2103 |
separator code separator)))))) |
|
2104 |
|
|
2105 |
|
|
2106 |
;;;; Inlinetask |
|
2107 |
|
|
2108 |
(defun org-latex-inlinetask (inlinetask contents info) |
|
2109 |
"Transcode an INLINETASK element from Org to LaTeX. |
|
2110 |
CONTENTS holds the contents of the block. INFO is a plist |
|
2111 |
holding contextual information." |
|
2112 |
(let ((title (org-export-data (org-element-property :title inlinetask) info)) |
|
2113 |
(todo (and (plist-get info :with-todo-keywords) |
|
2114 |
(let ((todo (org-element-property :todo-keyword inlinetask))) |
|
2115 |
(and todo (org-export-data todo info))))) |
|
2116 |
(todo-type (org-element-property :todo-type inlinetask)) |
|
2117 |
(tags (and (plist-get info :with-tags) |
|
2118 |
(org-export-get-tags inlinetask info))) |
|
2119 |
(priority (and (plist-get info :with-priority) |
|
2120 |
(org-element-property :priority inlinetask))) |
|
2121 |
(contents (concat (org-latex--label inlinetask info) contents))) |
|
2122 |
(funcall (plist-get info :latex-format-inlinetask-function) |
|
2123 |
todo todo-type priority title tags contents info))) |
|
2124 |
|
|
2125 |
(defun org-latex-format-inlinetask-default-function |
|
2126 |
(todo _todo-type priority title tags contents _info) |
|
2127 |
"Default format function for inlinetasks. |
|
2128 |
See `org-latex-format-inlinetask-function' for details." |
|
2129 |
(let ((full-title |
|
2130 |
(concat (when todo (format "\\textbf{\\textsf{\\textsc{%s}}} " todo)) |
|
2131 |
(when priority (format "\\framebox{\\#%c} " priority)) |
|
2132 |
title |
|
2133 |
(when tags |
|
2134 |
(format "\\hfill{}\\textsc{:%s:}" |
|
2135 |
(mapconcat #'org-latex--protect-text tags ":")))))) |
|
2136 |
(concat "\\begin{center}\n" |
|
2137 |
"\\fbox{\n" |
|
2138 |
"\\begin{minipage}[c]{.6\\textwidth}\n" |
|
2139 |
full-title "\n\n" |
|
2140 |
(and (org-string-nw-p contents) |
|
2141 |
(concat "\\rule[.8em]{\\textwidth}{2pt}\n\n" contents)) |
|
2142 |
"\\end{minipage}\n" |
|
2143 |
"}\n" |
|
2144 |
"\\end{center}"))) |
|
2145 |
|
|
2146 |
|
|
2147 |
;;;; Italic |
|
2148 |
|
|
2149 |
(defun org-latex-italic (_italic contents info) |
|
2150 |
"Transcode ITALIC from Org to LaTeX. |
|
2151 |
CONTENTS is the text with italic markup. INFO is a plist holding |
|
2152 |
contextual information." |
|
2153 |
(org-latex--text-markup contents 'italic info)) |
|
2154 |
|
|
2155 |
|
|
2156 |
;;;; Item |
|
2157 |
|
|
2158 |
(defun org-latex-item (item contents info) |
|
2159 |
"Transcode an ITEM element from Org to LaTeX. |
|
2160 |
CONTENTS holds the contents of the item. INFO is a plist holding |
|
2161 |
contextual information." |
|
2162 |
(let* ((counter |
|
2163 |
(let ((count (org-element-property :counter item)) |
|
2164 |
(level |
|
2165 |
;; Determine level of current item to determine the |
|
2166 |
;; correct LaTeX counter to use (enumi, enumii...). |
|
2167 |
(let ((parent item) (level 0)) |
|
2168 |
(while (memq (org-element-type |
|
2169 |
(setq parent (org-export-get-parent parent))) |
|
2170 |
'(plain-list item)) |
|
2171 |
(when (and (eq (org-element-type parent) 'plain-list) |
|
2172 |
(eq (org-element-property :type parent) |
|
2173 |
'ordered)) |
|
2174 |
(cl-incf level))) |
|
2175 |
level))) |
|
2176 |
(and count |
|
2177 |
(< level 5) |
|
2178 |
(format "\\setcounter{enum%s}{%s}\n" |
|
2179 |
(nth (1- level) '("i" "ii" "iii" "iv")) |
|
2180 |
(1- count))))) |
|
2181 |
(checkbox (cl-case (org-element-property :checkbox item) |
|
2182 |
(on "$\\boxtimes$") |
|
2183 |
(off "$\\square$") |
|
2184 |
(trans "$\\boxminus$"))) |
|
2185 |
(tag (let ((tag (org-element-property :tag item))) |
|
2186 |
(and tag (org-export-data tag info))))) |
|
2187 |
(concat counter |
|
2188 |
"\\item" |
|
2189 |
(cond |
|
2190 |
((and checkbox tag) (format "[{%s %s}] " checkbox tag)) |
|
2191 |
((or checkbox tag) (format "[{%s}] " (or checkbox tag))) |
|
2192 |
;; Without a tag or a check-box, if CONTENTS starts with |
|
2193 |
;; an opening square bracket, add "\relax" to "\item", |
|
2194 |
;; unless the brackets comes from an initial export |
|
2195 |
;; snippet (i.e. it is inserted willingly by the user). |
|
2196 |
((and contents |
|
2197 |
(string-match-p "\\`[ \t]*\\[" contents) |
|
2198 |
(not (let ((e (car (org-element-contents item)))) |
|
2199 |
(and (eq (org-element-type e) 'paragraph) |
|
2200 |
(let ((o (car (org-element-contents e)))) |
|
2201 |
(and (eq (org-element-type o) 'export-snippet) |
|
2202 |
(eq (org-export-snippet-backend o) |
|
2203 |
'latex))))))) |
|
2204 |
"\\relax ") |
|
2205 |
(t " ")) |
|
2206 |
(and contents (org-trim contents)) |
|
2207 |
;; If there are footnotes references in tag, be sure to |
|
2208 |
;; add their definition at the end of the item. This |
|
2209 |
;; workaround is necessary since "\footnote{}" command is |
|
2210 |
;; not supported in tags. |
|
2211 |
(and tag |
|
2212 |
(org-latex--delayed-footnotes-definitions |
|
2213 |
(org-element-property :tag item) info))))) |
|
2214 |
|
|
2215 |
|
|
2216 |
;;;; Keyword |
|
2217 |
|
|
2218 |
(defun org-latex-keyword (keyword _contents info) |
|
2219 |
"Transcode a KEYWORD element from Org to LaTeX. |
|
2220 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
2221 |
(let ((key (org-element-property :key keyword)) |
|
2222 |
(value (org-element-property :value keyword))) |
|
2223 |
(cond |
|
2224 |
((string= key "LATEX") value) |
|
2225 |
((string= key "INDEX") (format "\\index{%s}" value)) |
|
2226 |
((string= key "TOC") |
|
2227 |
(let ((case-fold-search t)) |
|
2228 |
(cond |
|
2229 |
((string-match-p "\\<headlines\\>" value) |
|
2230 |
(let* ((localp (string-match-p "\\<local\\>" value)) |
|
2231 |
(parent (org-element-lineage keyword '(headline))) |
|
2232 |
(level (if (not (and localp parent)) 0 |
|
2233 |
(org-export-get-relative-level parent info))) |
|
2234 |
(depth |
|
2235 |
(and (string-match "\\<[0-9]+\\>" value) |
|
2236 |
(format |
|
2237 |
"\\setcounter{tocdepth}{%d}" |
|
2238 |
(+ (string-to-number (match-string 0 value)) level))))) |
|
2239 |
(if (and localp parent) |
|
2240 |
;; Start local TOC, assuming package "titletoc" is |
|
2241 |
;; required. |
|
2242 |
(format "\\startcontents[level-%d] |
|
2243 |
\\printcontents[level-%d]{}{0}{%s}" |
|
2244 |
level level (or depth "")) |
|
2245 |
(concat depth (and depth "\n") "\\tableofcontents")))) |
|
2246 |
((string-match-p "\\<tables\\>" value) "\\listoftables") |
|
2247 |
((string-match-p "\\<listings\\>" value) |
|
2248 |
(cl-case (plist-get info :latex-listings) |
|
2249 |
((nil) "\\listoffigures") |
|
2250 |
(minted "\\listoflistings") |
|
2251 |
(otherwise "\\lstlistoflistings"))))))))) |
|
2252 |
|
|
2253 |
|
|
2254 |
;;;; Latex Environment |
|
2255 |
|
|
2256 |
(defun org-latex--environment-type (latex-environment) |
|
2257 |
"Return the TYPE of LATEX-ENVIRONMENT. |
|
2258 |
|
|
2259 |
The TYPE is determined from the actual latex environment, and |
|
2260 |
could be a member of `org-latex-caption-above' or `math'." |
|
2261 |
(let* ((latex-begin-re "\\\\begin{\\([A-Za-z0-9*]+\\)}") |
|
2262 |
(value (org-remove-indentation |
|
2263 |
(org-element-property :value latex-environment))) |
|
2264 |
(env (or (and (string-match latex-begin-re value) |
|
2265 |
(match-string 1 value)) |
|
2266 |
""))) |
|
2267 |
(cond |
|
2268 |
((string-match-p org-latex-math-environments-re value) 'math) |
|
2269 |
((string-match-p |
|
2270 |
(eval-when-compile |
|
2271 |
(regexp-opt '("table" "longtable" "tabular" "tabu" "longtabu"))) |
|
2272 |
env) |
|
2273 |
'table) |
|
2274 |
((string-match-p "figure" env) 'image) |
|
2275 |
((string-match-p |
|
2276 |
(eval-when-compile |
|
2277 |
(regexp-opt '("lstlisting" "listing" "verbatim" "minted"))) |
|
2278 |
env) |
|
2279 |
'src-block) |
|
2280 |
(t 'special-block)))) |
|
2281 |
|
|
2282 |
(defun org-latex-latex-environment (latex-environment _contents info) |
|
2283 |
"Transcode a LATEX-ENVIRONMENT element from Org to LaTeX. |
|
2284 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
2285 |
(when (plist-get info :with-latex) |
|
2286 |
(let* ((value (org-remove-indentation |
|
2287 |
(org-element-property :value latex-environment))) |
|
2288 |
(type (org-latex--environment-type latex-environment)) |
|
2289 |
(caption (if (eq type 'math) |
|
2290 |
(org-latex--label latex-environment info nil t) |
|
2291 |
(org-latex--caption/label-string latex-environment info))) |
|
2292 |
(caption-above-p |
|
2293 |
(memq type (append (plist-get info :latex-caption-above) '(math))))) |
|
2294 |
(if (not (or (org-element-property :name latex-environment) |
|
2295 |
(org-element-property :caption latex-environment))) |
|
2296 |
value |
|
2297 |
;; Environment is labeled: label must be within the environment |
|
2298 |
;; (otherwise, a reference pointing to that element will count |
|
2299 |
;; the section instead). Also insert caption if `latex-environment' |
|
2300 |
;; is not a math environment. |
|
2301 |
(with-temp-buffer |
|
2302 |
(insert value) |
|
2303 |
(if caption-above-p |
|
2304 |
(progn |
|
2305 |
(goto-char (point-min)) |
|
2306 |
(forward-line)) |
|
2307 |
(goto-char (point-max)) |
|
2308 |
(forward-line -1)) |
|
2309 |
(insert caption) |
|
2310 |
(buffer-string)))))) |
|
2311 |
|
|
2312 |
;;;; Latex Fragment |
|
2313 |
|
|
2314 |
(defun org-latex-latex-fragment (latex-fragment _contents _info) |
|
2315 |
"Transcode a LATEX-FRAGMENT object from Org to LaTeX. |
|
2316 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
2317 |
(let ((value (org-element-property :value latex-fragment))) |
|
2318 |
;; Trim math markers since the fragment is enclosed within |
|
2319 |
;; a latex-math-block object anyway. |
|
2320 |
(cond ((string-match-p "\\`\\$[^$]" value) (substring value 1 -1)) |
|
2321 |
((string-prefix-p "\\(" value) (substring value 2 -2)) |
|
2322 |
(t value)))) |
|
2323 |
|
|
2324 |
|
|
2325 |
;;;; Line Break |
|
2326 |
|
|
2327 |
(defun org-latex-line-break (_line-break _contents _info) |
|
2328 |
"Transcode a LINE-BREAK object from Org to LaTeX. |
|
2329 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
2330 |
"\\\\\n") |
|
2331 |
|
|
2332 |
|
|
2333 |
;;;; Link |
|
2334 |
|
|
2335 |
(defun org-latex-image-link-filter (data _backend info) |
|
2336 |
(org-export-insert-image-links data info org-latex-inline-image-rules)) |
|
2337 |
|
|
2338 |
(defun org-latex--inline-image (link info) |
|
2339 |
"Return LaTeX code for an inline image. |
|
2340 |
LINK is the link pointing to the inline image. INFO is a plist |
|
2341 |
used as a communication channel." |
|
2342 |
(let* ((parent (org-export-get-parent-element link)) |
|
2343 |
(path (let ((raw-path (org-element-property :path link))) |
|
2344 |
(if (not (file-name-absolute-p raw-path)) raw-path |
|
2345 |
(expand-file-name raw-path)))) |
|
2346 |
(filetype (file-name-extension path)) |
|
2347 |
(caption (org-latex--caption/label-string parent info)) |
|
2348 |
(caption-above-p (org-latex--caption-above-p link info)) |
|
2349 |
;; Retrieve latex attributes from the element around. |
|
2350 |
(attr (org-export-read-attribute :attr_latex parent)) |
|
2351 |
(float (let ((float (plist-get attr :float))) |
|
2352 |
(cond ((string= float "wrap") 'wrap) |
|
2353 |
((string= float "sideways") 'sideways) |
|
2354 |
((string= float "multicolumn") 'multicolumn) |
|
2355 |
((and (plist-member attr :float) (not float)) 'nonfloat) |
|
2356 |
((or float |
|
2357 |
(org-element-property :caption parent) |
|
2358 |
(org-string-nw-p (plist-get attr :caption))) |
|
2359 |
'figure) |
|
2360 |
(t 'nonfloat)))) |
|
2361 |
(placement |
|
2362 |
(let ((place (plist-get attr :placement))) |
|
2363 |
(cond |
|
2364 |
(place (format "%s" place)) |
|
2365 |
((eq float 'wrap) "{l}{0.5\\textwidth}") |
|
2366 |
((eq float 'figure) |
|
2367 |
(format "[%s]" (plist-get info :latex-default-figure-position))) |
|
2368 |
(t "")))) |
|
2369 |
(center |
|
2370 |
(if (plist-member attr :center) (plist-get attr :center) |
|
2371 |
(plist-get info :latex-images-centered))) |
|
2372 |
(comment-include (if (plist-get attr :comment-include) "%" "")) |
|
2373 |
;; It is possible to specify width and height in the |
|
2374 |
;; ATTR_LATEX line, and also via default variables. |
|
2375 |
(width (cond ((plist-get attr :width)) |
|
2376 |
((plist-get attr :height) "") |
|
2377 |
((eq float 'wrap) "0.48\\textwidth") |
|
2378 |
(t (plist-get info :latex-image-default-width)))) |
|
2379 |
(height (cond ((plist-get attr :height)) |
|
2380 |
((or (plist-get attr :width) |
|
2381 |
(memq float '(figure wrap))) "") |
|
2382 |
(t (plist-get info :latex-image-default-height)))) |
|
2383 |
(options (let ((opt (or (plist-get attr :options) |
|
2384 |
(plist-get info :latex-image-default-option)))) |
|
2385 |
(if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt |
|
2386 |
(match-string 1 opt)))) |
|
2387 |
image-code) |
|
2388 |
(if (member filetype '("tikz" "pgf")) |
|
2389 |
;; For tikz images: |
|
2390 |
;; - use \input to read in image file. |
|
2391 |
;; - if options are present, wrap in a tikzpicture environment. |
|
2392 |
;; - if width or height are present, use \resizebox to change |
|
2393 |
;; the image size. |
|
2394 |
(progn |
|
2395 |
(setq image-code (format "\\input{%s}" path)) |
|
2396 |
(when (org-string-nw-p options) |
|
2397 |
(setq image-code |
|
2398 |
(format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}" |
|
2399 |
options |
|
2400 |
image-code))) |
|
2401 |
(when (or (org-string-nw-p width) (org-string-nw-p height)) |
|
2402 |
(setq image-code (format "\\resizebox{%s}{%s}{%s}" |
|
2403 |
(if (org-string-nw-p width) width "!") |
|
2404 |
(if (org-string-nw-p height) height "!") |
|
2405 |
image-code)))) |
|
2406 |
;; For other images: |
|
2407 |
;; - add width and height to options. |
|
2408 |
;; - include the image with \includegraphics. |
|
2409 |
(when (org-string-nw-p width) |
|
2410 |
(setq options (concat options ",width=" width))) |
|
2411 |
(when (org-string-nw-p height) |
|
2412 |
(setq options (concat options ",height=" height))) |
|
2413 |
(let ((search-option (org-element-property :search-option link))) |
|
2414 |
(when (and search-option |
|
2415 |
(equal filetype "pdf") |
|
2416 |
(string-match-p "\\`[0-9]+\\'" search-option) |
|
2417 |
(not (string-match-p "page=" options))) |
|
2418 |
(setq options (concat options ",page=" search-option)))) |
|
2419 |
(setq image-code |
|
2420 |
(format "\\includegraphics%s{%s}" |
|
2421 |
(cond ((not (org-string-nw-p options)) "") |
|
2422 |
((string-prefix-p "," options) |
|
2423 |
(format "[%s]" (substring options 1))) |
|
2424 |
(t (format "[%s]" options))) |
|
2425 |
path)) |
|
2426 |
(when (equal filetype "svg") |
|
2427 |
(setq image-code (replace-regexp-in-string "^\\\\includegraphics" |
|
2428 |
"\\includesvg" |
|
2429 |
image-code |
|
2430 |
nil t)) |
|
2431 |
(setq image-code (replace-regexp-in-string "\\.svg}" |
|
2432 |
"}" |
|
2433 |
image-code |
|
2434 |
nil t)))) |
|
2435 |
;; Return proper string, depending on FLOAT. |
|
2436 |
(pcase float |
|
2437 |
(`wrap (format "\\begin{wrapfigure}%s |
|
2438 |
%s%s |
|
2439 |
%s%s |
|
2440 |
%s\\end{wrapfigure}" |
|
2441 |
placement |
|
2442 |
(if caption-above-p caption "") |
|
2443 |
(if center "\\centering" "") |
|
2444 |
comment-include image-code |
|
2445 |
(if caption-above-p "" caption))) |
|
2446 |
(`sideways (format "\\begin{sidewaysfigure} |
|
2447 |
%s%s |
|
2448 |
%s%s |
|
2449 |
%s\\end{sidewaysfigure}" |
|
2450 |
(if caption-above-p caption "") |
|
2451 |
(if center "\\centering" "") |
|
2452 |
comment-include image-code |
|
2453 |
(if caption-above-p "" caption))) |
|
2454 |
(`multicolumn (format "\\begin{figure*}%s |
|
2455 |
%s%s |
|
2456 |
%s%s |
|
2457 |
%s\\end{figure*}" |
|
2458 |
placement |
|
2459 |
(if caption-above-p caption "") |
|
2460 |
(if center "\\centering" "") |
|
2461 |
comment-include image-code |
|
2462 |
(if caption-above-p "" caption))) |
|
2463 |
(`figure (format "\\begin{figure}%s |
|
2464 |
%s%s |
|
2465 |
%s%s |
|
2466 |
%s\\end{figure}" |
|
2467 |
placement |
|
2468 |
(if caption-above-p caption "") |
|
2469 |
(if center "\\centering" "") |
|
2470 |
comment-include image-code |
|
2471 |
(if caption-above-p "" caption))) |
|
2472 |
((guard center) |
|
2473 |
(format "\\begin{center} |
|
2474 |
%s%s |
|
2475 |
%s\\end{center}" |
|
2476 |
(if caption-above-p caption "") |
|
2477 |
image-code |
|
2478 |
(if caption-above-p "" caption))) |
|
2479 |
(_ |
|
2480 |
(concat (if caption-above-p caption "") |
|
2481 |
image-code |
|
2482 |
(if caption-above-p caption "")))))) |
|
2483 |
|
|
2484 |
(defun org-latex-link (link desc info) |
|
2485 |
"Transcode a LINK object from Org to LaTeX. |
|
2486 |
|
|
2487 |
DESC is the description part of the link, or the empty string. |
|
2488 |
INFO is a plist holding contextual information. See |
|
2489 |
`org-export-data'." |
|
2490 |
(let* ((type (org-element-property :type link)) |
|
2491 |
(raw-path (org-element-property :path link)) |
|
2492 |
;; Ensure DESC really exists, or set it to nil. |
|
2493 |
(desc (and (not (string= desc "")) desc)) |
|
2494 |
(imagep (org-export-inline-image-p |
|
2495 |
link (plist-get info :latex-inline-image-rules))) |
|
2496 |
(path (org-latex--protect-text |
|
2497 |
(cond ((member type '("http" "https" "ftp" "mailto" "doi")) |
|
2498 |
(concat type ":" raw-path)) |
|
2499 |
((string= type "file") (org-export-file-uri raw-path)) |
|
2500 |
(t raw-path))))) |
|
2501 |
(cond |
|
2502 |
;; Link type is handled by a special function. |
|
2503 |
((org-export-custom-protocol-maybe link desc 'latex)) |
|
2504 |
;; Image file. |
|
2505 |
(imagep (org-latex--inline-image link info)) |
|
2506 |
;; Radio link: Transcode target's contents and use them as link's |
|
2507 |
;; description. |
|
2508 |
((string= type "radio") |
|
2509 |
(let ((destination (org-export-resolve-radio-link link info))) |
|
2510 |
(if (not destination) desc |
|
2511 |
(format "\\hyperref[%s]{%s}" |
|
2512 |
(org-export-get-reference destination info) |
|
2513 |
desc)))) |
|
2514 |
;; Links pointing to a headline: Find destination and build |
|
2515 |
;; appropriate referencing command. |
|
2516 |
((member type '("custom-id" "fuzzy" "id")) |
|
2517 |
(let ((destination (if (string= type "fuzzy") |
|
2518 |
(org-export-resolve-fuzzy-link link info) |
|
2519 |
(org-export-resolve-id-link link info)))) |
|
2520 |
(cl-case (org-element-type destination) |
|
2521 |
;; Id link points to an external file. |
|
2522 |
(plain-text |
|
2523 |
(if desc (format "\\href{%s}{%s}" destination desc) |
|
2524 |
(format "\\url{%s}" destination))) |
|
2525 |
;; Fuzzy link points nowhere. |
|
2526 |
((nil) |
|
2527 |
(format (plist-get info :latex-link-with-unknown-path-format) |
|
2528 |
(or desc |
|
2529 |
(org-export-data |
|
2530 |
(org-element-property :raw-link link) info)))) |
|
2531 |
;; LINK points to a headline. If headlines are numbered |
|
2532 |
;; and the link has no description, display headline's |
|
2533 |
;; number. Otherwise, display description or headline's |
|
2534 |
;; title. |
|
2535 |
(headline |
|
2536 |
(let ((label (org-latex--label destination info t))) |
|
2537 |
(if (and (not desc) |
|
2538 |
(org-export-numbered-headline-p destination info)) |
|
2539 |
(format "\\ref{%s}" label) |
|
2540 |
(format "\\hyperref[%s]{%s}" label |
|
2541 |
(or desc |
|
2542 |
(org-export-data |
|
2543 |
(org-element-property :title destination) info)))))) |
|
2544 |
;; Fuzzy link points to a target. Do as above. |
|
2545 |
(otherwise |
|
2546 |
(let ((ref (org-latex--label destination info t))) |
|
2547 |
(if (not desc) (format "\\ref{%s}" ref) |
|
2548 |
(format "\\hyperref[%s]{%s}" ref desc))))))) |
|
2549 |
;; Coderef: replace link with the reference name or the |
|
2550 |
;; equivalent line number. |
|
2551 |
((string= type "coderef") |
|
2552 |
(format (org-export-get-coderef-format path desc) |
|
2553 |
(org-export-resolve-coderef path info))) |
|
2554 |
;; External link with a description part. |
|
2555 |
((and path desc) (format "\\href{%s}{%s}" path desc)) |
|
2556 |
;; External link without a description part. |
|
2557 |
(path (format "\\url{%s}" path)) |
|
2558 |
;; No path, only description. Try to do something useful. |
|
2559 |
(t (format (plist-get info :latex-link-with-unknown-path-format) desc))))) |
|
2560 |
|
|
2561 |
|
|
2562 |
;;;; Node Property |
|
2563 |
|
|
2564 |
(defun org-latex-node-property (node-property _contents _info) |
|
2565 |
"Transcode a NODE-PROPERTY element from Org to LaTeX. |
|
2566 |
CONTENTS is nil. INFO is a plist holding contextual |
|
2567 |
information." |
|
2568 |
(format "%s:%s" |
|
2569 |
(org-element-property :key node-property) |
|
2570 |
(let ((value (org-element-property :value node-property))) |
|
2571 |
(if value (concat " " value) "")))) |
|
2572 |
|
|
2573 |
|
|
2574 |
;;;; Paragraph |
|
2575 |
|
|
2576 |
(defun org-latex-paragraph (_paragraph contents _info) |
|
2577 |
"Transcode a PARAGRAPH element from Org to LaTeX. |
|
2578 |
CONTENTS is the contents of the paragraph, as a string. INFO is |
|
2579 |
the plist used as a communication channel." |
|
2580 |
contents) |
|
2581 |
|
|
2582 |
|
|
2583 |
;;;; Plain List |
|
2584 |
|
|
2585 |
(defun org-latex-plain-list (plain-list contents info) |
|
2586 |
"Transcode a PLAIN-LIST element from Org to LaTeX. |
|
2587 |
CONTENTS is the contents of the list. INFO is a plist holding |
|
2588 |
contextual information." |
|
2589 |
(let* ((type (org-element-property :type plain-list)) |
|
2590 |
(attr (org-export-read-attribute :attr_latex plain-list)) |
|
2591 |
(latex-type (let ((env (plist-get attr :environment))) |
|
2592 |
(cond (env (format "%s" env)) |
|
2593 |
((eq type 'ordered) "enumerate") |
|
2594 |
((eq type 'descriptive) "description") |
|
2595 |
(t "itemize"))))) |
|
2596 |
(org-latex--wrap-label |
|
2597 |
plain-list |
|
2598 |
(format "\\begin{%s}%s\n%s\\end{%s}" |
|
2599 |
latex-type |
|
2600 |
(or (plist-get attr :options) "") |
|
2601 |
contents |
|
2602 |
latex-type) |
|
2603 |
info))) |
|
2604 |
|
|
2605 |
|
|
2606 |
;;;; Plain Text |
|
2607 |
|
|
2608 |
(defun org-latex-plain-text (text info) |
|
2609 |
"Transcode a TEXT string from Org to LaTeX. |
|
2610 |
TEXT is the string to transcode. INFO is a plist holding |
|
2611 |
contextual information." |
|
2612 |
(let* ((specialp (plist-get info :with-special-strings)) |
|
2613 |
(output |
|
2614 |
;; Turn LaTeX into \LaTeX{} and TeX into \TeX{}. |
|
2615 |
(let ((case-fold-search nil)) |
|
2616 |
(replace-regexp-in-string |
|
2617 |
"\\<\\(?:La\\)?TeX\\>" "\\\\\\&{}" |
|
2618 |
;; Protect ^, ~, %, #, &, $, _, { and }. Also protect \. |
|
2619 |
;; However, if special strings are used, be careful not |
|
2620 |
;; to protect "\" in "\-" constructs. |
|
2621 |
(replace-regexp-in-string |
|
2622 |
(concat "[%$#&{}_~^]\\|\\\\" (and specialp "\\([^-]\\|$\\)")) |
|
2623 |
(lambda (m) |
|
2624 |
(cl-case (string-to-char m) |
|
2625 |
(?\\ "$\\\\backslash$\\1") |
|
2626 |
(?~ "\\\\textasciitilde{}") |
|
2627 |
(?^ "\\\\^{}") |
|
2628 |
(t "\\\\\\&"))) |
|
2629 |
text))))) |
|
2630 |
;; Activate smart quotes. Be sure to provide original TEXT string |
|
2631 |
;; since OUTPUT may have been modified. |
|
2632 |
(when (plist-get info :with-smart-quotes) |
|
2633 |
(setq output (org-export-activate-smart-quotes output :latex info text))) |
|
2634 |
;; Convert special strings. |
|
2635 |
(when specialp |
|
2636 |
(setq output (replace-regexp-in-string "\\.\\.\\." "\\\\ldots{}" output))) |
|
2637 |
;; Handle break preservation if required. |
|
2638 |
(when (plist-get info :preserve-breaks) |
|
2639 |
(setq output (replace-regexp-in-string |
|
2640 |
"\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" output nil t))) |
|
2641 |
;; Return value. |
|
2642 |
output)) |
|
2643 |
|
|
2644 |
|
|
2645 |
;;;; Planning |
|
2646 |
|
|
2647 |
(defun org-latex-planning (planning _contents info) |
|
2648 |
"Transcode a PLANNING element from Org to LaTeX. |
|
2649 |
CONTENTS is nil. INFO is a plist holding contextual |
|
2650 |
information." |
|
2651 |
(concat |
|
2652 |
"\\noindent" |
|
2653 |
(mapconcat |
|
2654 |
'identity |
|
2655 |
(delq nil |
|
2656 |
(list |
|
2657 |
(let ((closed (org-element-property :closed planning))) |
|
2658 |
(when closed |
|
2659 |
(concat |
|
2660 |
(format "\\textbf{%s} " org-closed-string) |
|
2661 |
(format (plist-get info :latex-inactive-timestamp-format) |
|
2662 |
(org-timestamp-translate closed))))) |
|
2663 |
(let ((deadline (org-element-property :deadline planning))) |
|
2664 |
(when deadline |
|
2665 |
(concat |
|
2666 |
(format "\\textbf{%s} " org-deadline-string) |
|
2667 |
(format (plist-get info :latex-active-timestamp-format) |
|
2668 |
(org-timestamp-translate deadline))))) |
|
2669 |
(let ((scheduled (org-element-property :scheduled planning))) |
|
2670 |
(when scheduled |
|
2671 |
(concat |
|
2672 |
(format "\\textbf{%s} " org-scheduled-string) |
|
2673 |
(format (plist-get info :latex-active-timestamp-format) |
|
2674 |
(org-timestamp-translate scheduled))))))) |
|
2675 |
" ") |
|
2676 |
"\\\\")) |
|
2677 |
|
|
2678 |
|
|
2679 |
;;;; Property Drawer |
|
2680 |
|
|
2681 |
(defun org-latex-property-drawer (_property-drawer contents _info) |
|
2682 |
"Transcode a PROPERTY-DRAWER element from Org to LaTeX. |
|
2683 |
CONTENTS holds the contents of the drawer. INFO is a plist |
|
2684 |
holding contextual information." |
|
2685 |
(and (org-string-nw-p contents) |
|
2686 |
(format "\\begin{verbatim}\n%s\\end{verbatim}" contents))) |
|
2687 |
|
|
2688 |
|
|
2689 |
;;;; Pseudo Element: LaTeX Matrices |
|
2690 |
|
|
2691 |
;; `latex-matrices' elements have the following properties: |
|
2692 |
;; `:caption', `:post-blank' and `:markup' (`inline', `equation' or |
|
2693 |
;; `math'). |
|
2694 |
|
|
2695 |
(defun org-latex--wrap-latex-matrices (data info) |
|
2696 |
"Merge contiguous tables with the same mode within a pseudo-element. |
|
2697 |
DATA is a parse tree or a secondary string. INFO is a plist |
|
2698 |
containing export options. Modify DATA by side-effect and return |
|
2699 |
it." |
|
2700 |
(org-element-map data 'table |
|
2701 |
(lambda (table) |
|
2702 |
(when (eq (org-element-property :type table) 'org) |
|
2703 |
(let ((mode (or (org-export-read-attribute :attr_latex table :mode) |
|
2704 |
(plist-get info :latex-default-table-mode)))) |
|
2705 |
(when (and (member mode '("inline-math" "math")) |
|
2706 |
;; Do not wrap twice the same table. |
|
2707 |
(not (eq (org-element-type |
|
2708 |
(org-element-property :parent table)) |
|
2709 |
'latex-matrices))) |
|
2710 |
(let* ((caption (and (not (string= mode "inline-math")) |
|
2711 |
(org-element-property :caption table))) |
|
2712 |
(matrices |
|
2713 |
(list 'latex-matrices |
|
2714 |
(list :caption caption |
|
2715 |
:markup |
|
2716 |
(cond ((string= mode "inline-math") 'inline) |
|
2717 |
(caption 'equation) |
|
2718 |
(t 'math))))) |
|
2719 |
(previous table) |
|
2720 |
(next (org-export-get-next-element table info))) |
|
2721 |
(org-element-insert-before matrices table) |
|
2722 |
;; Swallow all contiguous tables sharing the same mode. |
|
2723 |
(while (and |
|
2724 |
(zerop (or (org-element-property :post-blank previous) 0)) |
|
2725 |
(setq next (org-export-get-next-element previous info)) |
|
2726 |
(eq (org-element-type next) 'table) |
|
2727 |
(eq (org-element-property :type next) 'org) |
|
2728 |
(string= (or (org-export-read-attribute |
|
2729 |
:attr_latex next :mode) |
|
2730 |
(plist-get info :latex-default-table-mode)) |
|
2731 |
mode)) |
|
2732 |
(org-element-extract-element previous) |
|
2733 |
(org-element-adopt-elements matrices previous) |
|
2734 |
(setq previous next)) |
|
2735 |
;; Inherit `:post-blank' from the value of the last |
|
2736 |
;; swallowed table. Set the latter's `:post-blank' |
|
2737 |
;; value to 0 so as to not duplicate empty lines. |
|
2738 |
(org-element-put-property |
|
2739 |
matrices :post-blank (org-element-property :post-blank previous)) |
|
2740 |
(org-element-put-property previous :post-blank 0) |
|
2741 |
(org-element-extract-element previous) |
|
2742 |
(org-element-adopt-elements matrices previous)))))) |
|
2743 |
info) |
|
2744 |
data) |
|
2745 |
|
|
2746 |
(defun org-latex-matrices (matrices contents _info) |
|
2747 |
"Transcode a MATRICES element from Org to LaTeX. |
|
2748 |
CONTENTS is a string. INFO is a plist used as a communication |
|
2749 |
channel." |
|
2750 |
(format (cl-case (org-element-property :markup matrices) |
|
2751 |
(inline "\\(%s\\)") |
|
2752 |
(equation "\\begin{equation}\n%s\\end{equation}") |
|
2753 |
(t "\\[\n%s\\]")) |
|
2754 |
contents)) |
|
2755 |
|
|
2756 |
|
|
2757 |
;;;; Pseudo Object: LaTeX Math Block |
|
2758 |
|
|
2759 |
;; `latex-math-block' objects have the following property: |
|
2760 |
;; `:post-blank'. |
|
2761 |
|
|
2762 |
(defun org-latex--wrap-latex-math-block (data info) |
|
2763 |
"Merge contiguous math objects in a pseudo-object container. |
|
2764 |
DATA is a parse tree or a secondary string. INFO is a plist |
|
2765 |
containing export options. Modify DATA by side-effect and return it." |
|
2766 |
(let ((valid-object-p |
|
2767 |
;; Non-nil when OBJ can be added to the latex math block B. |
|
2768 |
(lambda (obj b) |
|
2769 |
(pcase (org-element-type obj) |
|
2770 |
(`entity (org-element-property :latex-math-p obj)) |
|
2771 |
(`latex-fragment |
|
2772 |
(let ((value (org-element-property :value obj))) |
|
2773 |
(or (string-prefix-p "\\(" value) |
|
2774 |
(string-match-p "\\`\\$[^$]" value)))) |
|
2775 |
((and type (or `subscript `superscript)) |
|
2776 |
(not (memq type (mapcar #'org-element-type |
|
2777 |
(org-element-contents b))))))))) |
|
2778 |
(org-element-map data '(entity latex-fragment subscript superscript) |
|
2779 |
(lambda (object) |
|
2780 |
;; Skip objects already wrapped. |
|
2781 |
(when (and (not (eq (org-element-type |
|
2782 |
(org-element-property :parent object)) |
|
2783 |
'latex-math-block)) |
|
2784 |
(funcall valid-object-p object nil)) |
|
2785 |
(let ((math-block (list 'latex-math-block nil)) |
|
2786 |
(next-elements (org-export-get-next-element object info t)) |
|
2787 |
(last object)) |
|
2788 |
;; Wrap MATH-BLOCK around OBJECT in DATA. |
|
2789 |
(org-element-insert-before math-block object) |
|
2790 |
(org-element-extract-element object) |
|
2791 |
(org-element-adopt-elements math-block object) |
|
2792 |
(when (zerop (or (org-element-property :post-blank object) 0)) |
|
2793 |
;; MATH-BLOCK swallows consecutive math objects. |
|
2794 |
(catch 'exit |
|
2795 |
(dolist (next next-elements) |
|
2796 |
(unless (funcall valid-object-p next math-block) |
|
2797 |
(throw 'exit nil)) |
|
2798 |
(org-element-extract-element next) |
|
2799 |
(org-element-adopt-elements math-block next) |
|
2800 |
;; Eschew the case: \beta$x$ -> \(\betax\). |
|
2801 |
(unless (memq (org-element-type next) |
|
2802 |
'(subscript superscript)) |
|
2803 |
(org-element-put-property last :post-blank 1)) |
|
2804 |
(setq last next) |
|
2805 |
(when (> (or (org-element-property :post-blank next) 0) 0) |
|
2806 |
(throw 'exit nil))))) |
|
2807 |
(org-element-put-property |
|
2808 |
math-block :post-blank (org-element-property :post-blank last))))) |
|
2809 |
info nil '(subscript superscript latex-math-block) t) |
|
2810 |
;; Return updated DATA. |
|
2811 |
data)) |
|
2812 |
|
|
2813 |
(defun org-latex-math-block (_math-block contents _info) |
|
2814 |
"Transcode a MATH-BLOCK object from Org to LaTeX. |
|
2815 |
CONTENTS is a string. INFO is a plist used as a communication |
|
2816 |
channel." |
|
2817 |
(when (org-string-nw-p contents) |
|
2818 |
(format "\\(%s\\)" (org-trim contents)))) |
|
2819 |
|
|
2820 |
;;;; Quote Block |
|
2821 |
|
|
2822 |
(defun org-latex-quote-block (quote-block contents info) |
|
2823 |
"Transcode a QUOTE-BLOCK element from Org to LaTeX. |
|
2824 |
CONTENTS holds the contents of the block. INFO is a plist |
|
2825 |
holding contextual information." |
|
2826 |
(org-latex--wrap-label |
|
2827 |
quote-block (format "\\begin{quote}\n%s\\end{quote}" contents) info)) |
|
2828 |
|
|
2829 |
|
|
2830 |
;;;; Radio Target |
|
2831 |
|
|
2832 |
(defun org-latex-radio-target (radio-target text info) |
|
2833 |
"Transcode a RADIO-TARGET object from Org to LaTeX. |
|
2834 |
TEXT is the text of the target. INFO is a plist holding |
|
2835 |
contextual information." |
|
2836 |
(format "\\label{%s}%s" (org-export-get-reference radio-target info) text)) |
|
2837 |
|
|
2838 |
|
|
2839 |
;;;; Section |
|
2840 |
|
|
2841 |
(defun org-latex-section (_section contents _info) |
|
2842 |
"Transcode a SECTION element from Org to LaTeX. |
|
2843 |
CONTENTS holds the contents of the section. INFO is a plist |
|
2844 |
holding contextual information." |
|
2845 |
contents) |
|
2846 |
|
|
2847 |
|
|
2848 |
;;;; Special Block |
|
2849 |
|
|
2850 |
(defun org-latex-special-block (special-block contents info) |
|
2851 |
"Transcode a SPECIAL-BLOCK element from Org to LaTeX. |
|
2852 |
CONTENTS holds the contents of the block. INFO is a plist |
|
2853 |
holding contextual information." |
|
2854 |
(let ((type (org-element-property :type special-block)) |
|
2855 |
(opt (org-export-read-attribute :attr_latex special-block :options)) |
|
2856 |
(caption (org-latex--caption/label-string special-block info)) |
|
2857 |
(caption-above-p (org-latex--caption-above-p special-block info))) |
|
2858 |
(concat (format "\\begin{%s}%s\n" type (or opt "")) |
|
2859 |
(and caption-above-p caption) |
|
2860 |
contents |
|
2861 |
(and (not caption-above-p) caption) |
|
2862 |
(format "\\end{%s}" type)))) |
|
2863 |
|
|
2864 |
|
|
2865 |
;;;; Src Block |
|
2866 |
|
|
2867 |
(defun org-latex-src-block (src-block _contents info) |
|
2868 |
"Transcode a SRC-BLOCK element from Org to LaTeX. |
|
2869 |
CONTENTS holds the contents of the item. INFO is a plist holding |
|
2870 |
contextual information." |
|
2871 |
(when (org-string-nw-p (org-element-property :value src-block)) |
|
2872 |
(let* ((lang (org-element-property :language src-block)) |
|
2873 |
(caption (org-element-property :caption src-block)) |
|
2874 |
(caption-above-p (org-latex--caption-above-p src-block info)) |
|
2875 |
(label (org-element-property :name src-block)) |
|
2876 |
(custom-env (and lang |
|
2877 |
(cadr (assq (intern lang) |
|
2878 |
org-latex-custom-lang-environments)))) |
|
2879 |
(num-start (org-export-get-loc src-block info)) |
|
2880 |
(retain-labels (org-element-property :retain-labels src-block)) |
|
2881 |
(attributes (org-export-read-attribute :attr_latex src-block)) |
|
2882 |
(float (plist-get attributes :float)) |
|
2883 |
(listings (plist-get info :latex-listings))) |
|
2884 |
(cond |
|
2885 |
;; Case 1. No source fontification. |
|
2886 |
((not listings) |
|
2887 |
(let* ((caption-str (org-latex--caption/label-string src-block info)) |
|
2888 |
(float-env |
|
2889 |
(cond ((string= "multicolumn" float) |
|
2890 |
(format "\\begin{figure*}[%s]\n%s%%s\n%s\\end{figure*}" |
|
2891 |
(plist-get info :latex-default-figure-position) |
|
2892 |
(if caption-above-p caption-str "") |
|
2893 |
(if caption-above-p "" caption-str))) |
|
2894 |
(caption (concat |
|
2895 |
(if caption-above-p caption-str "") |
|
2896 |
"%s" |
|
2897 |
(if caption-above-p "" (concat "\n" caption-str)))) |
|
2898 |
(t "%s")))) |
|
2899 |
(format |
|
2900 |
float-env |
|
2901 |
(concat (format "\\begin{verbatim}\n%s\\end{verbatim}" |
|
2902 |
(org-export-format-code-default src-block info)))))) |
|
2903 |
;; Case 2. Custom environment. |
|
2904 |
(custom-env |
|
2905 |
(let ((caption-str (org-latex--caption/label-string src-block info)) |
|
2906 |
(formatted-src (org-export-format-code-default src-block info))) |
|
2907 |
(if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env) |
|
2908 |
(format "\\begin{%s}\n%s\\end{%s}\n" |
|
2909 |
custom-env |
|
2910 |
(concat (and caption-above-p caption-str) |
|
2911 |
formatted-src |
|
2912 |
(and (not caption-above-p) caption-str)) |
|
2913 |
custom-env) |
|
2914 |
(format-spec custom-env |
|
2915 |
`((?s . ,formatted-src) |
|
2916 |
(?c . ,caption) |
|
2917 |
(?f . ,float) |
|
2918 |
(?l . ,(org-latex--label src-block info)) |
|
2919 |
(?o . ,(or (plist-get attributes :options) ""))))))) |
|
2920 |
;; Case 3. Use minted package. |
|
2921 |
((eq listings 'minted) |
|
2922 |
(let* ((caption-str (org-latex--caption/label-string src-block info)) |
|
2923 |
(float-env |
|
2924 |
(cond |
|
2925 |
((string= "multicolumn" float) |
|
2926 |
(format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}" |
|
2927 |
(plist-get info :latex-default-figure-position) |
|
2928 |
(if caption-above-p caption-str "") |
|
2929 |
(if caption-above-p "" caption-str))) |
|
2930 |
(caption |
|
2931 |
(format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}" |
|
2932 |
(plist-get info :latex-default-figure-position) |
|
2933 |
(if caption-above-p caption-str "") |
|
2934 |
(if caption-above-p "" caption-str))) |
|
2935 |
((string= "t" float) |
|
2936 |
(concat (format "\\begin{listing}[%s]\n" |
|
2937 |
(plist-get info :latex-default-figure-position)) |
|
2938 |
"%s\n\\end{listing}")) |
|
2939 |
(t "%s"))) |
|
2940 |
(options (plist-get info :latex-minted-options)) |
|
2941 |
(body |
|
2942 |
(format |
|
2943 |
"\\begin{minted}[%s]{%s}\n%s\\end{minted}" |
|
2944 |
;; Options. |
|
2945 |
(concat |
|
2946 |
(org-latex--make-option-string |
|
2947 |
(if (or (not num-start) (assoc "linenos" options)) |
|
2948 |
options |
|
2949 |
(append |
|
2950 |
`(("linenos") |
|
2951 |
("firstnumber" ,(number-to-string (1+ num-start)))) |
|
2952 |
options))) |
|
2953 |
(let ((local-options (plist-get attributes :options))) |
|
2954 |
(and local-options (concat "," local-options)))) |
|
2955 |
;; Language. |
|
2956 |
(or (cadr (assq (intern lang) |
|
2957 |
(plist-get info :latex-minted-langs))) |
|
2958 |
(downcase lang)) |
|
2959 |
;; Source code. |
|
2960 |
(let* ((code-info (org-export-unravel-code src-block)) |
|
2961 |
(max-width |
|
2962 |
(apply 'max |
|
2963 |
(mapcar 'length |
|
2964 |
(org-split-string (car code-info) |
|
2965 |
"\n"))))) |
|
2966 |
(org-export-format-code |
|
2967 |
(car code-info) |
|
2968 |
(lambda (loc _num ref) |
|
2969 |
(concat |
|
2970 |
loc |
|
2971 |
(when ref |
|
2972 |
;; Ensure references are flushed to the right, |
|
2973 |
;; separated with 6 spaces from the widest line |
|
2974 |
;; of code. |
|
2975 |
(concat (make-string (+ (- max-width (length loc)) 6) |
|
2976 |
?\s) |
|
2977 |
(format "(%s)" ref))))) |
|
2978 |
nil (and retain-labels (cdr code-info))))))) |
|
2979 |
;; Return value. |
|
2980 |
(format float-env body))) |
|
2981 |
;; Case 4. Use listings package. |
|
2982 |
(t |
|
2983 |
(let ((lst-lang |
|
2984 |
(or (cadr (assq (intern lang) |
|
2985 |
(plist-get info :latex-listings-langs))) |
|
2986 |
lang)) |
|
2987 |
(caption-str |
|
2988 |
(when caption |
|
2989 |
(let ((main (org-export-get-caption src-block)) |
|
2990 |
(secondary (org-export-get-caption src-block t))) |
|
2991 |
(if (not secondary) |
|
2992 |
(format "{%s}" (org-export-data main info)) |
|
2993 |
(format "{[%s]%s}" |
|
2994 |
(org-export-data secondary info) |
|
2995 |
(org-export-data main info)))))) |
|
2996 |
(lst-opt (plist-get info :latex-listings-options))) |
|
2997 |
(concat |
|
2998 |
;; Options. |
|
2999 |
(format |
|
3000 |
"\\lstset{%s}\n" |
|
3001 |
(concat |
|
3002 |
(org-latex--make-option-string |
|
3003 |
(append |
|
3004 |
lst-opt |
|
3005 |
(cond |
|
3006 |
((and (not float) (plist-member attributes :float)) nil) |
|
3007 |
((string= "multicolumn" float) '(("float" "*"))) |
|
3008 |
((and float (not (assoc "float" lst-opt))) |
|
3009 |
`(("float" ,(plist-get info :latex-default-figure-position))))) |
|
3010 |
`(("language" ,lst-lang)) |
|
3011 |
(if label |
|
3012 |
`(("label" ,(org-latex--label src-block info))) |
|
3013 |
'(("label" " "))) |
|
3014 |
(if caption-str `(("caption" ,caption-str)) '(("caption" " "))) |
|
3015 |
`(("captionpos" ,(if caption-above-p "t" "b"))) |
|
3016 |
(cond ((assoc "numbers" lst-opt) nil) |
|
3017 |
((not num-start) '(("numbers" "none"))) |
|
3018 |
(t `(("firstnumber" ,(number-to-string (1+ num-start))) |
|
3019 |
("numbers" "left")))))) |
|
3020 |
(let ((local-options (plist-get attributes :options))) |
|
3021 |
(and local-options (concat "," local-options))))) |
|
3022 |
;; Source code. |
|
3023 |
(format |
|
3024 |
"\\begin{lstlisting}\n%s\\end{lstlisting}" |
|
3025 |
(let* ((code-info (org-export-unravel-code src-block)) |
|
3026 |
(max-width |
|
3027 |
(apply 'max |
|
3028 |
(mapcar 'length |
|
3029 |
(org-split-string (car code-info) "\n"))))) |
|
3030 |
(org-export-format-code |
|
3031 |
(car code-info) |
|
3032 |
(lambda (loc _num ref) |
|
3033 |
(concat |
|
3034 |
loc |
|
3035 |
(when ref |
|
3036 |
;; Ensure references are flushed to the right, |
|
3037 |
;; separated with 6 spaces from the widest line of |
|
3038 |
;; code |
|
3039 |
(concat (make-string (+ (- max-width (length loc)) 6) ?\s) |
|
3040 |
(format "(%s)" ref))))) |
|
3041 |
nil (and retain-labels (cdr code-info)))))))))))) |
|
3042 |
|
|
3043 |
|
|
3044 |
;;;; Statistics Cookie |
|
3045 |
|
|
3046 |
(defun org-latex-statistics-cookie (statistics-cookie _contents _info) |
|
3047 |
"Transcode a STATISTICS-COOKIE object from Org to LaTeX. |
|
3048 |
CONTENTS is nil. INFO is a plist holding contextual information." |
|
3049 |
(replace-regexp-in-string |
|
3050 |
"%" "\\%" (org-element-property :value statistics-cookie) nil t)) |
|
3051 |
|
|
3052 |
|
|
3053 |
;;;; Strike-Through |
|
3054 |
|
|
3055 |
(defun org-latex-strike-through (_strike-through contents info) |
|
3056 |
"Transcode STRIKE-THROUGH from Org to LaTeX. |
|
3057 |
CONTENTS is the text with strike-through markup. INFO is a plist |
|
3058 |
holding contextual information." |
|
3059 |
(org-latex--text-markup contents 'strike-through info)) |
|
3060 |
|
|
3061 |
|
|
3062 |
;;;; Subscript |
|
3063 |
|
|
3064 |
(defun org-latex--script-size (object info) |
|
3065 |
"Transcode a subscript or superscript object. |
|
3066 |
OBJECT is an Org object. INFO is a plist used as a communication |
|
3067 |
channel." |
|
3068 |
(let ((output "")) |
|
3069 |
(org-element-map (org-element-contents object) |
|
3070 |
(cons 'plain-text org-element-all-objects) |
|
3071 |
(lambda (obj) |
|
3072 |
(cl-case (org-element-type obj) |
|
3073 |
((entity latex-fragment) |
|
3074 |
(let ((data (org-trim (org-export-data obj info)))) |
|
3075 |
(string-match |
|
3076 |
"\\`\\(?:\\\\[([]\\|\\$+\\)?\\(.*?\\)\\(?:\\\\[])]\\|\\$+\\)?\\'" |
|
3077 |
data) |
|
3078 |
(setq output |
|
3079 |
(concat output |
|
3080 |
(match-string 1 data) |
|
3081 |
(let ((blank (org-element-property :post-blank obj))) |
|
3082 |
(and blank (> blank 0) "\\ ")))))) |
|
3083 |
(plain-text |
|
3084 |
(setq output |
|
3085 |
(format "%s\\text{%s}" output (org-export-data obj info)))) |
|
3086 |
(otherwise |
|
3087 |
(setq output |
|
3088 |
(concat output |
|
3089 |
(org-export-data obj info) |
|
3090 |
(let ((blank (org-element-property :post-blank obj))) |
|
3091 |
(and blank (> blank 0) "\\ "))))))) |
|
3092 |
info nil org-element-recursive-objects) |
|
3093 |
;; Result. Do not wrap into curly brackets if OUTPUT is a single |
|
3094 |
;; character. |
|
3095 |
(concat (if (eq (org-element-type object) 'subscript) "_" "^") |
|
3096 |
(and (> (length output) 1) "{") |
|
3097 |
output |
|
3098 |
(and (> (length output) 1) "}")))) |
|
3099 |
|
|
3100 |
(defun org-latex-subscript (subscript _contents info) |
|
3101 |
"Transcode a SUBSCRIPT object from Org to LaTeX. |
|
3102 |
CONTENTS is the contents of the object. INFO is a plist holding |
|
3103 |
contextual information." |
|
3104 |
(org-latex--script-size subscript info)) |
|
3105 |
|
|
3106 |
|
|
3107 |
;;;; Superscript |
|
3108 |
|
|
3109 |
(defun org-latex-superscript (superscript _contents info) |
|
3110 |
"Transcode a SUPERSCRIPT object from Org to LaTeX. |
|
3111 |
CONTENTS is the contents of the object. INFO is a plist holding |
|
3112 |
contextual information." |
|
3113 |
(org-latex--script-size superscript info)) |
|
3114 |
|
|
3115 |
|
|
3116 |
;;;; Table |
|
3117 |
;; |
|
3118 |
;; `org-latex-table' is the entry point for table transcoding. It |
|
3119 |
;; takes care of tables with a "verbatim" mode. Otherwise, it |
|
3120 |
;; delegates the job to either `org-latex--table.el-table', |
|
3121 |
;; `org-latex--org-table' or `org-latex--math-table' functions, |
|
3122 |
;; depending of the type of the table and the mode requested. |
|
3123 |
;; |
|
3124 |
;; `org-latex--align-string' is a subroutine used to build alignment |
|
3125 |
;; string for Org tables. |
|
3126 |
|
|
3127 |
(defun org-latex-table (table contents info) |
|
3128 |
"Transcode a TABLE element from Org to LaTeX. |
|
3129 |
CONTENTS is the contents of the table. INFO is a plist holding |
|
3130 |
contextual information." |
|
3131 |
(if (eq (org-element-property :type table) 'table.el) |
|
3132 |
;; "table.el" table. Convert it using appropriate tools. |
|
3133 |
(org-latex--table.el-table table info) |
|
3134 |
(let ((type (or (org-export-read-attribute :attr_latex table :mode) |
|
3135 |
(plist-get info :latex-default-table-mode)))) |
|
3136 |
(cond |
|
3137 |
;; Case 1: Verbatim table. |
|
3138 |
((string= type "verbatim") |
|
3139 |
(format "\\begin{verbatim}\n%s\n\\end{verbatim}" |
|
3140 |
;; Re-create table, without affiliated keywords. |
|
3141 |
(org-trim (org-element-interpret-data |
|
3142 |
`(table nil ,@(org-element-contents table)))))) |
|
3143 |
;; Case 2: Matrix. |
|
3144 |
((or (string= type "math") (string= type "inline-math")) |
|
3145 |
(org-latex--math-table table info)) |
|
3146 |
;; Case 3: Standard table. |
|
3147 |
(t (concat (org-latex--org-table table contents info) |
|
3148 |
;; When there are footnote references within the |
|
3149 |
;; table, insert their definition just after it. |
|
3150 |
(org-latex--delayed-footnotes-definitions table info))))))) |
|
3151 |
|
|
3152 |
(defun org-latex--align-string (table info &optional math?) |
|
3153 |
"Return an appropriate LaTeX alignment string. |
|
3154 |
TABLE is the considered table. INFO is a plist used as |
|
3155 |
a communication channel. When optional argument MATH? is |
|
3156 |
non-nil, TABLE is meant to be a matrix, where all cells are |
|
3157 |
centered." |
|
3158 |
(or (org-export-read-attribute :attr_latex table :align) |
|
3159 |
(let (align) |
|
3160 |
;; Extract column groups and alignment from first (non-rule) |
|
3161 |
;; row. |
|
3162 |
(org-element-map |
|
3163 |
(org-element-map table 'table-row |
|
3164 |
(lambda (row) |
|
3165 |
(and (eq (org-element-property :type row) 'standard) row)) |
|
3166 |
info 'first-match) |
|
3167 |
'table-cell |
|
3168 |
(lambda (cell) |
|
3169 |
(let ((borders (org-export-table-cell-borders cell info))) |
|
3170 |
;; Check left border for the first cell only. |
|
3171 |
(when (and (memq 'left borders) (not align)) |
|
3172 |
(push "|" align)) |
|
3173 |
(push (if math? "c" ;center cells in matrices |
|
3174 |
(cl-case (org-export-table-cell-alignment cell info) |
|
3175 |
(left "l") |
|
3176 |
(right "r") |
|
3177 |
(center "c"))) |
|
3178 |
align) |
|
3179 |
(when (memq 'right borders) (push "|" align)))) |
|
3180 |
info) |
|
3181 |
(apply 'concat (nreverse align))))) |
|
3182 |
|
|
3183 |
(defun org-latex--org-table (table contents info) |
|
3184 |
"Return appropriate LaTeX code for an Org table. |
|
3185 |
|
|
3186 |
TABLE is the table type element to transcode. CONTENTS is its |
|
3187 |
contents, as a string. INFO is a plist used as a communication |
|
3188 |
channel. |
|
3189 |
|
|
3190 |
This function assumes TABLE has `org' as its `:type' property and |
|
3191 |
`table' as its `:mode' attribute." |
|
3192 |
(let* ((caption (org-latex--caption/label-string table info)) |
|
3193 |
(attr (org-export-read-attribute :attr_latex table)) |
|
3194 |
;; Determine alignment string. |
|
3195 |
(alignment (org-latex--align-string table info)) |
|
3196 |
;; Determine environment for the table: longtable, tabular... |
|
3197 |
(table-env (or (plist-get attr :environment) |
|
3198 |
(plist-get info :latex-default-table-environment))) |
|
3199 |
;; If table is a float, determine environment: table, table* |
|
3200 |
;; or sidewaystable. |
|
3201 |
(float-env (unless (member table-env '("longtable" "longtabu")) |
|
3202 |
(let ((float (plist-get attr :float))) |
|
3203 |
(cond |
|
3204 |
((and (not float) (plist-member attr :float)) nil) |
|
3205 |
((or (string= float "sidewaystable") |
|
3206 |
(string= float "sideways")) "sidewaystable") |
|
3207 |
((string= float "multicolumn") "table*") |
|
3208 |
((or float |
|
3209 |
(org-element-property :caption table) |
|
3210 |
(org-string-nw-p (plist-get attr :caption))) |
|
3211 |
"table"))))) |
|
3212 |
;; Extract others display options. |
|
3213 |
(fontsize (let ((font (plist-get attr :font))) |
|
3214 |
(and font (concat font "\n")))) |
|
3215 |
;; "tabular" environment doesn't allow to define a width. |
|
3216 |
(width (and (not (equal table-env "tabular")) (plist-get attr :width))) |
|
3217 |
(spreadp (plist-get attr :spread)) |
|
3218 |
(placement |
|
3219 |
(or (plist-get attr :placement) |
|
3220 |
(format "[%s]" (plist-get info :latex-default-figure-position)))) |
|
3221 |
(centerp (if (plist-member attr :center) (plist-get attr :center) |
|
3222 |
(plist-get info :latex-tables-centered))) |
|
3223 |
(caption-above-p (org-latex--caption-above-p table info))) |
|
3224 |
;; Prepare the final format string for the table. |
|
3225 |
(cond |
|
3226 |
;; Longtable. |
|
3227 |
((equal "longtable" table-env) |
|
3228 |
(concat (and fontsize (concat "{" fontsize)) |
|
3229 |
(format "\\begin{longtable}{%s}\n" alignment) |
|
3230 |
(and caption-above-p |
|
3231 |
(org-string-nw-p caption) |
|
3232 |
(concat caption "\\\\\n")) |
|
3233 |
contents |
|
3234 |
(and (not caption-above-p) |
|
3235 |
(org-string-nw-p caption) |
|
3236 |
(concat caption "\\\\\n")) |
|
3237 |
"\\end{longtable}\n" |
|
3238 |
(and fontsize "}"))) |
|
3239 |
;; Longtabu |
|
3240 |
((equal "longtabu" table-env) |
|
3241 |
(concat (and fontsize (concat "{" fontsize)) |
|
3242 |
(format "\\begin{longtabu}%s{%s}\n" |
|
3243 |
(if width |
|
3244 |
(format " %s %s " |
|
3245 |
(if spreadp "spread" "to") width) "") |
|
3246 |
alignment) |
|
3247 |
(and caption-above-p |
|
3248 |
(org-string-nw-p caption) |
|
3249 |
(concat caption "\\\\\n")) |
|
3250 |
contents |
|
3251 |
(and (not caption-above-p) |
|
3252 |
(org-string-nw-p caption) |
|
3253 |
(concat caption "\\\\\n")) |
|
3254 |
"\\end{longtabu}\n" |
|
3255 |
(and fontsize "}"))) |
|
3256 |
;; Others. |
|
3257 |
(t (concat (cond |
|
3258 |
(float-env |
|
3259 |
(concat (format "\\begin{%s}%s\n" float-env placement) |
|
3260 |
(if caption-above-p caption "") |
|
3261 |
(when centerp "\\centering\n") |
|
3262 |
fontsize)) |
|
3263 |
((and (not float-env) caption) |
|
3264 |
(concat |
|
3265 |
(and centerp "\\begin{center}\n" ) |
|
3266 |
(if caption-above-p caption "") |
|
3267 |
(cond ((and fontsize centerp) fontsize) |
|
3268 |
(fontsize (concat "{" fontsize))))) |
|
3269 |
(centerp (concat "\\begin{center}\n" fontsize)) |
|
3270 |
(fontsize (concat "{" fontsize))) |
|
3271 |
(cond ((equal "tabu" table-env) |
|
3272 |
(format "\\begin{tabu}%s{%s}\n%s\\end{tabu}" |
|
3273 |
(if width (format |
|
3274 |
(if spreadp " spread %s " " to %s ") |
|
3275 |
width) "") |
|
3276 |
alignment |
|
3277 |
contents)) |
|
3278 |
(t (format "\\begin{%s}%s{%s}\n%s\\end{%s}" |
|
3279 |
table-env |
|
3280 |
(if width (format "{%s}" width) "") |
|
3281 |
alignment |
|
3282 |
contents |
|
3283 |
table-env))) |
|
3284 |
(cond |
|
3285 |
(float-env |
|
3286 |
(concat (if caption-above-p "" (concat "\n" caption)) |
|
3287 |
(format "\n\\end{%s}" float-env))) |
|
3288 |
((and (not float-env) caption) |
|
3289 |
(concat |
|
3290 |
(if caption-above-p "" (concat "\n" caption)) |
|
3291 |
(and centerp "\n\\end{center}") |
|
3292 |
(and fontsize (not centerp) "}"))) |
|
3293 |
(centerp "\n\\end{center}") |
|
3294 |
(fontsize "}"))))))) |
|
3295 |
|
|
3296 |
(defun org-latex--table.el-table (table info) |
|
3297 |
"Return appropriate LaTeX code for a table.el table. |
|
3298 |
|
|
3299 |
TABLE is the table type element to transcode. INFO is a plist |
|
3300 |
used as a communication channel. |
|
3301 |
|
|
3302 |
This function assumes TABLE has `table.el' as its `:type' |
|
3303 |
property." |
|
3304 |
(require 'table) |
|
3305 |
;; Ensure "*org-export-table*" buffer is empty. |
|
3306 |
(with-current-buffer (get-buffer-create "*org-export-table*") |
|
3307 |
(erase-buffer)) |
|
3308 |
(let ((output (with-temp-buffer |
|
3309 |
(insert (org-element-property :value table)) |
|
3310 |
(goto-char 1) |
|
3311 |
(re-search-forward "^[ \t]*|[^|]" nil t) |
|
3312 |
(table-generate-source 'latex "*org-export-table*") |
|
3313 |
(with-current-buffer "*org-export-table*" |
|
3314 |
(org-trim (buffer-string)))))) |
|
3315 |
(kill-buffer (get-buffer "*org-export-table*")) |
|
3316 |
;; Remove left out comments. |
|
3317 |
(while (string-match "^%.*\n" output) |
|
3318 |
(setq output (replace-match "" t t output))) |
|
3319 |
(let ((attr (org-export-read-attribute :attr_latex table))) |
|
3320 |
(when (plist-get attr :rmlines) |
|
3321 |
;; When the "rmlines" attribute is provided, remove all hlines |
|
3322 |
;; but the the one separating heading from the table body. |
|
3323 |
(let ((n 0) (pos 0)) |
|
3324 |
(while (and (< (length output) pos) |
|
3325 |
(setq pos (string-match "^\\\\hline\n?" output pos))) |
|
3326 |
(cl-incf n) |
|
3327 |
(unless (= n 2) (setq output (replace-match "" nil nil output)))))) |
|
3328 |
(let ((centerp (if (plist-member attr :center) (plist-get attr :center) |
|
3329 |
(plist-get info :latex-tables-centered)))) |
|
3330 |
(if (not centerp) output |
|
3331 |
(format "\\begin{center}\n%s\n\\end{center}" output)))))) |
|
3332 |
|
|
3333 |
(defun org-latex--math-table (table info) |
|
3334 |
"Return appropriate LaTeX code for a matrix. |
|
3335 |
|
|
3336 |
TABLE is the table type element to transcode. INFO is a plist |
|
3337 |
used as a communication channel. |
|
3338 |
|
|
3339 |
This function assumes TABLE has `org' as its `:type' property and |
|
3340 |
`inline-math' or `math' as its `:mode' attribute." |
|
3341 |
(let* ((attr (org-export-read-attribute :attr_latex table)) |
|
3342 |
(env (or (plist-get attr :environment) |
|
3343 |
(plist-get info :latex-default-table-environment))) |
|
3344 |
(contents |
|
3345 |
(mapconcat |
|
3346 |
(lambda (row) |
|
3347 |
(if (eq (org-element-property :type row) 'rule) "\\hline" |
|
3348 |
;; Return each cell unmodified. |
|
3349 |
(concat |
|
3350 |
(mapconcat |
|
3351 |
(lambda (cell) |
|
3352 |
(substring (org-element-interpret-data cell) 0 -1)) |
|
3353 |
(org-element-map row 'table-cell #'identity info) "&") |
|
3354 |
(or (cdr (assoc env org-latex-table-matrix-macros)) "\\\\") |
|
3355 |
"\n"))) |
|
3356 |
(org-element-map table 'table-row #'identity info) ""))) |
|
3357 |
(concat |
|
3358 |
;; Prefix. |
|
3359 |
(plist-get attr :math-prefix) |
|
3360 |
;; Environment. Also treat special cases. |
|
3361 |
(cond ((member env '("array" "tabular")) |
|
3362 |
(format "\\begin{%s}{%s}\n%s\\end{%s}" |
|
3363 |
env (org-latex--align-string table info t) contents env)) |
|
3364 |
((assoc env org-latex-table-matrix-macros) |
|
3365 |
(format "\\%s%s{\n%s}" |
|
3366 |
env |
|
3367 |
(or (plist-get attr :math-arguments) "") |
|
3368 |
contents)) |
|
3369 |
(t (format "\\begin{%s}\n%s\\end{%s}" env contents env))) |
|
3370 |
;; Suffix. |
|
3371 |
(plist-get attr :math-suffix)))) |
|
3372 |
|
|
3373 |
|
|
3374 |
;;;; Table Cell |
|
3375 |
|
|
3376 |
(defun org-latex-table-cell (table-cell contents info) |
|
3377 |
"Transcode a TABLE-CELL element from Org to LaTeX. |
|
3378 |
CONTENTS is the cell contents. INFO is a plist used as |
|
3379 |
a communication channel." |
|
3380 |
(concat |
|
3381 |
(let ((scientific-format (plist-get info :latex-table-scientific-notation))) |
|
3382 |
(if (and contents |
|
3383 |
scientific-format |
|
3384 |
(string-match orgtbl-exp-regexp contents)) |
|
3385 |
;; Use appropriate format string for scientific |
|
3386 |
;; notation. |
|
3387 |
(format scientific-format |
|
3388 |
(match-string 1 contents) |
|
3389 |
(match-string 2 contents)) |
|
3390 |
contents)) |
|
3391 |
(when (org-export-get-next-element table-cell info) " & "))) |
|
3392 |
|
|
3393 |
|
|
3394 |
;;;; Table Row |
|
3395 |
|
|
3396 |
(defun org-latex-table-row (table-row contents info) |
|
3397 |
"Transcode a TABLE-ROW element from Org to LaTeX. |
|
3398 |
CONTENTS is the contents of the row. INFO is a plist used as |
|
3399 |
a communication channel." |
|
3400 |
(let* ((attr (org-export-read-attribute :attr_latex |
|
3401 |
(org-export-get-parent table-row))) |
|
3402 |
(booktabsp (if (plist-member attr :booktabs) (plist-get attr :booktabs) |
|
3403 |
(plist-get info :latex-tables-booktabs))) |
|
3404 |
(longtablep |
|
3405 |
(member (or (plist-get attr :environment) |
|
3406 |
(plist-get info :latex-default-table-environment)) |
|
3407 |
'("longtable" "longtabu")))) |
|
3408 |
(if (eq (org-element-property :type table-row) 'rule) |
|
3409 |
(cond |
|
3410 |
((not booktabsp) "\\hline") |
|
3411 |
((not (org-export-get-previous-element table-row info)) "\\toprule") |
|
3412 |
((not (org-export-get-next-element table-row info)) "\\bottomrule") |
|
3413 |
((and longtablep |
|
3414 |
(org-export-table-row-ends-header-p |
|
3415 |
(org-export-get-previous-element table-row info) info)) |
|
3416 |
"") |
|
3417 |
(t "\\midrule")) |
|
3418 |
(concat |
|
3419 |
;; When BOOKTABS are activated enforce top-rule even when no |
|
3420 |
;; hline was specifically marked. |
|
3421 |
(and booktabsp (not (org-export-get-previous-element table-row info)) |
|
3422 |
"\\toprule\n") |
|
3423 |
contents "\\\\\n" |
|
3424 |
(cond |
|
3425 |
;; Special case for long tables. Define header and footers. |
|
3426 |
((and longtablep (org-export-table-row-ends-header-p table-row info)) |
|
3427 |
(let ((columns (cdr (org-export-table-dimensions |
|
3428 |
(org-export-get-parent-table table-row) info)))) |
|
3429 |
(format "%s |
|
3430 |
\\endfirsthead |
|
3431 |
\\multicolumn{%d}{l}{%s} \\\\ |
|
3432 |
%s |
|
3433 |
%s \\\\\n |
|
3434 |
%s |
|
3435 |
\\endhead |
|
3436 |
%s\\multicolumn{%d}{r}{%s} \\\\ |
|
3437 |
\\endfoot |
|
3438 |
\\endlastfoot" |
|
3439 |
(if booktabsp "\\midrule" "\\hline") |
|
3440 |
columns |
|
3441 |
(org-latex--translate "Continued from previous page" info) |
|
3442 |
(cond |
|
3443 |
((not (org-export-table-row-starts-header-p table-row info)) |
|
3444 |
"") |
|
3445 |
(booktabsp "\\toprule\n") |
|
3446 |
(t "\\hline\n")) |
|
3447 |
contents |
|
3448 |
(if booktabsp "\\midrule" "\\hline") |
|
3449 |
(if booktabsp "\\midrule" "\\hline") |
|
3450 |
columns |
|
3451 |
(org-latex--translate "Continued on next page" info)))) |
|
3452 |
;; When BOOKTABS are activated enforce bottom rule even when |
|
3453 |
;; no hline was specifically marked. |
|
3454 |
((and booktabsp (not (org-export-get-next-element table-row info))) |
|
3455 |
"\\bottomrule")))))) |
|
3456 |
|
|
3457 |
|
|
3458 |
;;;; Target |
|
3459 |
|
|
3460 |
(defun org-latex-target (target _contents info) |
|
3461 |
"Transcode a TARGET object from Org to LaTeX. |
|
3462 |
CONTENTS is nil. INFO is a plist holding contextual |
|
3463 |
information." |
|
3464 |
(format "\\label{%s}" (org-latex--label target info))) |
|
3465 |
|
|
3466 |
|
|
3467 |
;;;; Timestamp |
|
3468 |
|
|
3469 |
(defun org-latex-timestamp (timestamp _contents info) |
|
3470 |
"Transcode a TIMESTAMP object from Org to LaTeX. |
|
3471 |
CONTENTS is nil. INFO is a plist holding contextual |
|
3472 |
information." |
|
3473 |
(let ((value (org-latex-plain-text (org-timestamp-translate timestamp) info))) |
|
3474 |
(format |
|
3475 |
(plist-get info |
|
3476 |
(cl-case (org-element-property :type timestamp) |
|
3477 |
((active active-range) :latex-active-timestamp-format) |
|
3478 |
((inactive inactive-range) :latex-inactive-timestamp-format) |
|
3479 |
(otherwise :latex-diary-timestamp-format))) |
|
3480 |
value))) |
|
3481 |
|
|
3482 |
|
|
3483 |
;;;; Underline |
|
3484 |
|
|
3485 |
(defun org-latex-underline (_underline contents info) |
|
3486 |
"Transcode UNDERLINE from Org to LaTeX. |
|
3487 |
CONTENTS is the text with underline markup. INFO is a plist |
|
3488 |
holding contextual information." |
|
3489 |
(org-latex--text-markup contents 'underline info)) |
|
3490 |
|
|
3491 |
|
|
3492 |
;;;; Verbatim |
|
3493 |
|
|
3494 |
(defun org-latex-verbatim (verbatim _contents info) |
|
3495 |
"Transcode a VERBATIM object from Org to LaTeX. |
|
3496 |
CONTENTS is nil. INFO is a plist used as a communication |
|
3497 |
channel." |
|
3498 |
(org-latex--text-markup |
|
3499 |
(org-element-property :value verbatim) 'verbatim info)) |
|
3500 |
|
|
3501 |
|
|
3502 |
;;;; Verse Block |
|
3503 |
|
|
3504 |
(defun org-latex-verse-block (verse-block contents info) |
|
3505 |
"Transcode a VERSE-BLOCK element from Org to LaTeX. |
|
3506 |
CONTENTS is verse block contents. INFO is a plist holding |
|
3507 |
contextual information." |
|
3508 |
(org-latex--wrap-label |
|
3509 |
verse-block |
|
3510 |
;; In a verse environment, add a line break to each newline |
|
3511 |
;; character and change each white space at beginning of a line |
|
3512 |
;; into a space of 1 em. Also change each blank line with |
|
3513 |
;; a vertical space of 1 em. |
|
3514 |
(format "\\begin{verse}\n%s\\end{verse}" |
|
3515 |
(replace-regexp-in-string |
|
3516 |
"^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m))) |
|
3517 |
(replace-regexp-in-string |
|
3518 |
"^[ \t]*\\\\\\\\$" "\\vspace*{1em}" |
|
3519 |
(replace-regexp-in-string |
|
3520 |
"\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" |
|
3521 |
contents nil t) nil t) nil t)) |
|
3522 |
info)) |
|
3523 |
|
|
3524 |
|
|
3525 |
|
|
3526 |
;;; End-user functions |
|
3527 |
|
|
3528 |
;;;###autoload |
|
3529 |
(defun org-latex-export-as-latex |
|
3530 |
(&optional async subtreep visible-only body-only ext-plist) |
|
3531 |
"Export current buffer as a LaTeX buffer. |
|
3532 |
|
|
3533 |
If narrowing is active in the current buffer, only export its |
|
3534 |
narrowed part. |
|
3535 |
|
|
3536 |
If a region is active, export that region. |
|
3537 |
|
|
3538 |
A non-nil optional argument ASYNC means the process should happen |
|
3539 |
asynchronously. The resulting buffer should be accessible |
|
3540 |
through the `org-export-stack' interface. |
|
3541 |
|
|
3542 |
When optional argument SUBTREEP is non-nil, export the sub-tree |
|
3543 |
at point, extracting information from the headline properties |
|
3544 |
first. |
|
3545 |
|
|
3546 |
When optional argument VISIBLE-ONLY is non-nil, don't export |
|
3547 |
contents of hidden elements. |
|
3548 |
|
|
3549 |
When optional argument BODY-ONLY is non-nil, only write code |
|
3550 |
between \"\\begin{document}\" and \"\\end{document}\". |
|
3551 |
|
|
3552 |
EXT-PLIST, when provided, is a property list with external |
|
3553 |
parameters overriding Org default settings, but still inferior to |
|
3554 |
file-local settings. |
|
3555 |
|
|
3556 |
Export is done in a buffer named \"*Org LATEX Export*\", which |
|
3557 |
will be displayed when `org-export-show-temporary-export-buffer' |
|
3558 |
is non-nil." |
|
3559 |
(interactive) |
|
3560 |
(org-export-to-buffer 'latex "*Org LATEX Export*" |
|
3561 |
async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode)))) |
|
3562 |
|
|
3563 |
;;;###autoload |
|
3564 |
(defun org-latex-convert-region-to-latex () |
|
3565 |
"Assume the current region has Org syntax, and convert it to LaTeX. |
|
3566 |
This can be used in any buffer. For example, you can write an |
|
3567 |
itemized list in Org syntax in an LaTeX buffer and use this |
|
3568 |
command to convert it." |
|
3569 |
(interactive) |
|
3570 |
(org-export-replace-region-by 'latex)) |
|
3571 |
|
|
3572 |
;;;###autoload |
|
3573 |
(defun org-latex-export-to-latex |
|
3574 |
(&optional async subtreep visible-only body-only ext-plist) |
|
3575 |
"Export current buffer to a LaTeX file. |
|
3576 |
|
|
3577 |
If narrowing is active in the current buffer, only export its |
|
3578 |
narrowed part. |
|
3579 |
|
|
3580 |
If a region is active, export that region. |
|
3581 |
|
|
3582 |
A non-nil optional argument ASYNC means the process should happen |
|
3583 |
asynchronously. The resulting file should be accessible through |
|
3584 |
the `org-export-stack' interface. |
|
3585 |
|
|
3586 |
When optional argument SUBTREEP is non-nil, export the sub-tree |
|
3587 |
at point, extracting information from the headline properties |
|
3588 |
first. |
|
3589 |
|
|
3590 |
When optional argument VISIBLE-ONLY is non-nil, don't export |
|
3591 |
contents of hidden elements. |
|
3592 |
|
|
3593 |
When optional argument BODY-ONLY is non-nil, only write code |
|
3594 |
between \"\\begin{document}\" and \"\\end{document}\". |
|
3595 |
|
|
3596 |
EXT-PLIST, when provided, is a property list with external |
|
3597 |
parameters overriding Org default settings, but still inferior to |
|
3598 |
file-local settings." |
|
3599 |
(interactive) |
|
3600 |
(let ((outfile (org-export-output-file-name ".tex" subtreep))) |
|
3601 |
(org-export-to-file 'latex outfile |
|
3602 |
async subtreep visible-only body-only ext-plist))) |
|
3603 |
|
|
3604 |
;;;###autoload |
|
3605 |
(defun org-latex-export-to-pdf |
|
3606 |
(&optional async subtreep visible-only body-only ext-plist) |
|
3607 |
"Export current buffer to LaTeX then process through to PDF. |
|
3608 |
|
|
3609 |
If narrowing is active in the current buffer, only export its |
|
3610 |
narrowed part. |
|
3611 |
|
|
3612 |
If a region is active, export that region. |
|
3613 |
|
|
3614 |
A non-nil optional argument ASYNC means the process should happen |
|
3615 |
asynchronously. The resulting file should be accessible through |
|
3616 |
the `org-export-stack' interface. |
|
3617 |
|
|
3618 |
When optional argument SUBTREEP is non-nil, export the sub-tree |
|
3619 |
at point, extracting information from the headline properties |
|
3620 |
first. |
|
3621 |
|
|
3622 |
When optional argument VISIBLE-ONLY is non-nil, don't export |
|
3623 |
contents of hidden elements. |
|
3624 |
|
|
3625 |
When optional argument BODY-ONLY is non-nil, only write code |
|
3626 |
between \"\\begin{document}\" and \"\\end{document}\". |
|
3627 |
|
|
3628 |
EXT-PLIST, when provided, is a property list with external |
|
3629 |
parameters overriding Org default settings, but still inferior to |
|
3630 |
file-local settings. |
|
3631 |
|
|
3632 |
Return PDF file's name." |
|
3633 |
(interactive) |
|
3634 |
(let ((outfile (org-export-output-file-name ".tex" subtreep))) |
|
3635 |
(org-export-to-file 'latex outfile |
|
3636 |
async subtreep visible-only body-only ext-plist |
|
3637 |
(lambda (file) (org-latex-compile file))))) |
|
3638 |
|
|
3639 |
(defun org-latex-compile (texfile &optional snippet) |
|
3640 |
"Compile a TeX file. |
|
3641 |
|
|
3642 |
TEXFILE is the name of the file being compiled. Processing is |
|
3643 |
done through the command specified in `org-latex-pdf-process', |
|
3644 |
which see. Output is redirected to \"*Org PDF LaTeX Output*\" |
|
3645 |
buffer. |
|
3646 |
|
|
3647 |
When optional argument SNIPPET is non-nil, TEXFILE is a temporary |
|
3648 |
file used to preview a LaTeX snippet. In this case, do not |
|
3649 |
create a log buffer and do not remove log files. |
|
3650 |
|
|
3651 |
Return PDF file name or raise an error if it couldn't be |
|
3652 |
produced." |
|
3653 |
(unless snippet (message "Processing LaTeX file %s..." texfile)) |
|
3654 |
(let* ((compiler |
|
3655 |
(or (with-temp-buffer |
|
3656 |
(save-excursion (insert-file-contents texfile)) |
|
3657 |
(and (search-forward-regexp (regexp-opt org-latex-compilers) |
|
3658 |
(line-end-position 2) |
|
3659 |
t) |
|
3660 |
(progn (beginning-of-line) (looking-at-p "%")) |
|
3661 |
(match-string 0))) |
|
3662 |
"pdflatex")) |
|
3663 |
(process (if (functionp org-latex-pdf-process) org-latex-pdf-process |
|
3664 |
;; Replace "%latex" and "%bibtex" with, |
|
3665 |
;; respectively, "%L" and "%B" so as to adhere to |
|
3666 |
;; `format-spec' specifications. |
|
3667 |
(mapcar (lambda (command) |
|
3668 |
(replace-regexp-in-string |
|
3669 |
"%\\(?:bib\\|la\\)tex\\>" |
|
3670 |
(lambda (m) (upcase (substring m 0 2))) |
|
3671 |
command)) |
|
3672 |
org-latex-pdf-process))) |
|
3673 |
(spec `((?B . ,(shell-quote-argument org-latex-bib-compiler)) |
|
3674 |
(?L . ,(shell-quote-argument compiler)))) |
|
3675 |
(log-buf-name "*Org PDF LaTeX Output*") |
|
3676 |
(log-buf (and (not snippet) (get-buffer-create log-buf-name))) |
|
3677 |
(outfile (org-compile-file texfile process "pdf" |
|
3678 |
(format "See %S for details" log-buf-name) |
|
3679 |
log-buf spec))) |
|
3680 |
(unless snippet |
|
3681 |
(when org-latex-remove-logfiles |
|
3682 |
(mapc #'delete-file |
|
3683 |
(directory-files |
|
3684 |
(file-name-directory outfile) |
|
3685 |
t |
|
3686 |
(concat (regexp-quote (file-name-base outfile)) |
|
3687 |
"\\(?:\\.[0-9]+\\)?\\." |
|
3688 |
(regexp-opt org-latex-logfiles-extensions)) |
|
3689 |
t))) |
|
3690 |
(let ((warnings (org-latex--collect-warnings log-buf))) |
|
3691 |
(message (concat "PDF file produced" |
|
3692 |
(cond |
|
3693 |
((eq warnings 'error) " with errors.") |
|
3694 |
(warnings (concat " with warnings: " warnings)) |
|
3695 |
(t ".")))))) |
|
3696 |
;; Return output file name. |
|
3697 |
outfile)) |
|
3698 |
|
|
3699 |
(defun org-latex--collect-warnings (buffer) |
|
3700 |
"Collect some warnings from \"pdflatex\" command output. |
|
3701 |
BUFFER is the buffer containing output. Return collected |
|
3702 |
warnings types as a string, `error' if a LaTeX error was |
|
3703 |
encountered or nil if there was none." |
|
3704 |
(with-current-buffer buffer |
|
3705 |
(save-excursion |
|
3706 |
(goto-char (point-max)) |
|
3707 |
(when (re-search-backward "^[ \t]*This is .*?TeX.*?Version" nil t) |
|
3708 |
(if (re-search-forward "^!" nil t) 'error |
|
3709 |
(let ((case-fold-search t) |
|
3710 |
(warnings "")) |
|
3711 |
(dolist (warning org-latex-known-warnings) |
|
3712 |
(when (save-excursion (re-search-forward (car warning) nil t)) |
|
3713 |
(setq warnings (concat warnings " " (cdr warning))))) |
|
3714 |
(org-string-nw-p (org-trim warnings)))))))) |
|
3715 |
|
|
3716 |
;;;###autoload |
|
3717 |
(defun org-latex-publish-to-latex (plist filename pub-dir) |
|
3718 |
"Publish an Org file to LaTeX. |
|
3719 |
|
|
3720 |
FILENAME is the filename of the Org file to be published. PLIST |
|
3721 |
is the property list for the given project. PUB-DIR is the |
|
3722 |
publishing directory. |
|
3723 |
|
|
3724 |
Return output file name." |
|
3725 |
(org-publish-org-to 'latex filename ".tex" plist pub-dir)) |
|
3726 |
|
|
3727 |
;;;###autoload |
|
3728 |
(defun org-latex-publish-to-pdf (plist filename pub-dir) |
|
3729 |
"Publish an Org file to PDF (via LaTeX). |
|
3730 |
|
|
3731 |
FILENAME is the filename of the Org file to be published. PLIST |
|
3732 |
is the property list for the given project. PUB-DIR is the |
|
3733 |
publishing directory. |
|
3734 |
|
|
3735 |
Return output file name." |
|
3736 |
;; Unlike to `org-latex-publish-to-latex', PDF file is generated |
|
3737 |
;; in working directory and then moved to publishing directory. |
|
3738 |
(org-publish-attachment |
|
3739 |
plist |
|
3740 |
;; Default directory could be anywhere when this function is |
|
3741 |
;; called. We ensure it is set to source file directory during |
|
3742 |
;; compilation so as to not break links to external documents. |
|
3743 |
(let ((default-directory (file-name-directory filename))) |
|
3744 |
(org-latex-compile |
|
3745 |
(org-publish-org-to |
|
3746 |
'latex filename ".tex" plist (file-name-directory filename)))) |
|
3747 |
pub-dir)) |
|
3748 |
|
|
3749 |
|
|
3750 |
(provide 'ox-latex) |
|
3751 |
|
|
3752 |
;; Local variables: |
|
3753 |
;; generated-autoload-file: "org-loaddefs.el" |
|
3754 |
;; End: |
|
3755 |
|
|
3756 |
;;; ox-latex.el ends here |