Commit | Line | Data |
---|---|---|
c8d0cf5c | 1 | ;;; org-latex.el --- LaTeX exporter for org-mode |
72a81656 | 2 | ;; |
cbd20947 | 3 | ;; Copyright (C) 2007-2011 Free Software Foundation, Inc. |
15841868 JW |
4 | ;; |
5 | ;; Emacs Lisp Archive Entry | |
c8d0cf5c | 6 | ;; Filename: org-latex.el |
3ab2c837 | 7 | ;; Version: 7.7 |
72a81656 | 8 | ;; Author: Bastien Guerry <bzg AT altern DOT org> |
c8d0cf5c | 9 | ;; Maintainer: Carsten Dominik <carsten.dominik AT gmail DOT com> |
15841868 JW |
10 | ;; Keywords: org, wp, tex |
11 | ;; Description: Converts an org-mode buffer into LaTeX | |
b1fc2b50 | 12 | |
72a81656 | 13 | ;; This file is part of GNU Emacs. |
b1fc2b50 GM |
14 | |
15 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
16 | ;; it under the terms of the GNU General Public License as published by | |
17 | ;; the Free Software Foundation, either version 3 of the License, or | |
18 | ;; (at your option) any later version. | |
19 | ||
20 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 | ;; GNU General Public License for more details. | |
24 | ||
db9c3fb1 | 25 | ;; You should have received a copy of the GNU General Public License |
b1fc2b50 GM |
26 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
27 | ||
72a81656 | 28 | ;;; Commentary: |
0b8568f5 JW |
29 | ;; |
30 | ;; This library implements a LaTeX exporter for org-mode. | |
db9c3fb1 | 31 | ;; |
c8d0cf5c | 32 | ;; It is part of Org and will be autoloaded |
db9c3fb1 | 33 | ;; |
72a81656 | 34 | ;; The interactive functions are similar to those of the HTML exporter: |
db9c3fb1 | 35 | ;; |
72a81656 | 36 | ;; M-x `org-export-as-latex' |
71d35b24 CD |
37 | ;; M-x `org-export-as-pdf' |
38 | ;; M-x `org-export-as-pdf-and-open' | |
72a81656 CD |
39 | ;; M-x `org-export-as-latex-batch' |
40 | ;; M-x `org-export-as-latex-to-buffer' | |
41 | ;; M-x `org-export-region-as-latex' | |
42 | ;; M-x `org-replace-region-by-latex' | |
4b67ea89 | 43 | ;; |
72a81656 CD |
44 | ;;; Code: |
45 | ||
0b8568f5 JW |
46 | (eval-when-compile |
47 | (require 'cl)) | |
48 | ||
72a81656 | 49 | (require 'footnote) |
0b8568f5 | 50 | (require 'org) |
20908596 | 51 | (require 'org-exp) |
8d642074 | 52 | (require 'org-macs) |
ed21c5c8 | 53 | (require 'org-beamer) |
72a81656 | 54 | |
0b8568f5 | 55 | ;;; Variables: |
db9c3fb1 | 56 | (defvar org-export-latex-class nil) |
ed21c5c8 | 57 | (defvar org-export-latex-class-options nil) |
db9c3fb1 CD |
58 | (defvar org-export-latex-header nil) |
59 | (defvar org-export-latex-append-header nil) | |
60 | (defvar org-export-latex-options-plist nil) | |
61 | (defvar org-export-latex-todo-keywords-1 nil) | |
c8d0cf5c CD |
62 | (defvar org-export-latex-complex-heading-re nil) |
63 | (defvar org-export-latex-not-done-keywords nil) | |
64 | (defvar org-export-latex-done-keywords nil) | |
65 | (defvar org-export-latex-display-custom-times nil) | |
db9c3fb1 CD |
66 | (defvar org-export-latex-all-targets-re nil) |
67 | (defvar org-export-latex-add-level 0) | |
3ab2c837 BG |
68 | (defvar org-export-latex-footmark-seen nil |
69 | "List of footnotes markers seen so far by exporter.") | |
db9c3fb1 CD |
70 | (defvar org-export-latex-sectioning "") |
71 | (defvar org-export-latex-sectioning-depth 0) | |
0bd48b37 CD |
72 | (defvar org-export-latex-special-keyword-regexp |
73 | (concat "\\<\\(" org-scheduled-string "\\|" | |
74 | org-deadline-string "\\|" | |
75 | org-closed-string"\\)") | |
76 | "Regexp matching special time planning keywords plus the time after it.") | |
72a81656 | 77 | |
3ab2c837 BG |
78 | (defvar org-re-quote) ; dynamically scoped from org.el |
79 | (defvar org-commentsp) ; dynamically scoped from org.el | |
0b8568f5 | 80 | |
db9c3fb1 | 81 | ;;; User variables: |
72a81656 | 82 | |
621f83e4 CD |
83 | (defgroup org-export-latex nil |
84 | "Options for exporting Org-mode files to LaTeX." | |
85 | :tag "Org Export LaTeX" | |
86 | :group 'org-export) | |
87 | ||
db9c3fb1 CD |
88 | (defcustom org-export-latex-default-class "article" |
89 | "The default LaTeX class." | |
90 | :group 'org-export-latex | |
91 | :type '(string :tag "LaTeX class")) | |
72a81656 | 92 | |
db9c3fb1 CD |
93 | (defcustom org-export-latex-classes |
94 | '(("article" | |
ed21c5c8 | 95 | "\\documentclass[11pt]{article}" |
db9c3fb1 CD |
96 | ("\\section{%s}" . "\\section*{%s}") |
97 | ("\\subsection{%s}" . "\\subsection*{%s}") | |
98 | ("\\subsubsection{%s}" . "\\subsubsection*{%s}") | |
99 | ("\\paragraph{%s}" . "\\paragraph*{%s}") | |
100 | ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) | |
101 | ("report" | |
ed21c5c8 | 102 | "\\documentclass[11pt]{report}" |
db9c3fb1 CD |
103 | ("\\part{%s}" . "\\part*{%s}") |
104 | ("\\chapter{%s}" . "\\chapter*{%s}") | |
105 | ("\\section{%s}" . "\\section*{%s}") | |
106 | ("\\subsection{%s}" . "\\subsection*{%s}") | |
107 | ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) | |
108 | ("book" | |
ed21c5c8 | 109 | "\\documentclass[11pt]{book}" |
db9c3fb1 CD |
110 | ("\\part{%s}" . "\\part*{%s}") |
111 | ("\\chapter{%s}" . "\\chapter*{%s}") | |
112 | ("\\section{%s}" . "\\section*{%s}") | |
113 | ("\\subsection{%s}" . "\\subsection*{%s}") | |
ed21c5c8 CD |
114 | ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) |
115 | ("beamer" | |
116 | "\\documentclass{beamer}" | |
117 | org-beamer-sectioning | |
118 | )) | |
db9c3fb1 CD |
119 | "Alist of LaTeX classes and associated header and structure. |
120 | If #+LaTeX_CLASS is set in the buffer, use its value and the | |
121 | associated information. Here is the structure of each cell: | |
122 | ||
123 | \(class-name | |
124 | header-string | |
71d35b24 | 125 | (numbered-section . unnumbered-section\) |
db9c3fb1 CD |
126 | ...\) |
127 | ||
ed21c5c8 CD |
128 | The header string |
129 | ----------------- | |
130 | ||
131 | The HEADER-STRING is the header that will be inserted into the LaTeX file. | |
132 | It should contain the \\documentclass macro, and anything else that is needed | |
133 | for this setup. To this header, the following commands will be added: | |
134 | ||
135 | - Calls to \\usepackage for all packages mentioned in the variables | |
136 | `org-export-latex-default-packages-alist' and | |
137 | `org-export-latex-packages-alist'. Thus, your header definitions should | |
138 | avoid to also request these packages. | |
139 | ||
140 | - Lines specified via \"#+LaTeX_HEADER:\" | |
141 | ||
142 | If you need more control about the sequence in which the header is built | |
143 | up, or if you want to exclude one of these building blocks for a particular | |
144 | class, you can use the following macro-like placeholders. | |
145 | ||
146 | [DEFAULT-PACKAGES] \\usepackage statements for default packages | |
147 | [NO-DEFAULT-PACKAGES] do not include any of the default packages | |
86fbb8ca | 148 | [PACKAGES] \\usepackage statements for packages |
ed21c5c8 CD |
149 | [NO-PACKAGES] do not include the packages |
150 | [EXTRA] the stuff from #+LaTeX_HEADER | |
151 | [NO-EXTRA] do not include #+LaTeX_HEADER stuff | |
86fbb8ca | 152 | [BEAMER-HEADER-EXTRA] the beamer extra headers |
ed21c5c8 CD |
153 | |
154 | So a header like | |
155 | ||
156 | \\documentclass{article} | |
157 | [NO-DEFAULT-PACKAGES] | |
158 | [EXTRA] | |
159 | \\providecommand{\\alert}[1]{\\textbf{#1}} | |
160 | [PACKAGES] | |
161 | ||
162 | will omit the default packages, and will include the #+LaTeX_HEADER lines, | |
163 | then have a call to \\providecommand, and then place \\usepackage commands | |
164 | based on the content of `org-export-latex-packages-alist'. | |
165 | ||
166 | If your header or `org-export-latex-default-packages-alist' inserts | |
167 | \"\\usepackage[AUTO]{inputenc}\", AUTO will automatically be replaced with | |
168 | a coding system derived from `buffer-file-coding-system'. See also the | |
169 | variable `org-export-latex-inputenc-alist' for a way to influence this | |
170 | mechanism. | |
171 | ||
172 | The sectioning structure | |
173 | ------------------------ | |
174 | ||
175 | The sectioning structure of the class is given by the elements following | |
176 | the header string. For each sectioning level, a number of strings is | |
177 | specified. A %s formatter is mandatory in each section string and will | |
178 | be replaced by the title of the section. | |
71d35b24 CD |
179 | |
180 | Instead of a cons cell (numbered . unnumbered), you can also provide a list | |
ed21c5c8 | 181 | of 2 or 4 elements, |
71d35b24 CD |
182 | |
183 | (numbered-open numbered-close) | |
184 | ||
185 | or | |
186 | ||
187 | (numbered-open numbered-close unnumbered-open unnumbered-close) | |
188 | ||
ed21c5c8 | 189 | providing opening and closing strings for a LaTeX environment that should |
71d35b24 | 190 | represent the document section. The opening clause should have a %s |
ed21c5c8 CD |
191 | to represent the section title. |
192 | ||
193 | Instead of a list of sectioning commands, you can also specify a | |
194 | function name. That function will be called with two parameters, | |
195 | the (reduced) level of the headline, and the headline text. The function | |
196 | must return a cons cell with the (possibly modified) headline text, and the | |
197 | sectioning list in the cdr." | |
72a81656 | 198 | :group 'org-export-latex |
ff4be292 | 199 | :type '(repeat |
db9c3fb1 CD |
200 | (list (string :tag "LaTeX class") |
201 | (string :tag "LaTeX header") | |
71d35b24 CD |
202 | (repeat :tag "Levels" :inline t |
203 | (choice | |
204 | (cons :tag "Heading" | |
ed21c5c8 CD |
205 | (string :tag " numbered") |
206 | (string :tag "unnumbered")) | |
71d35b24 | 207 | (list :tag "Environment" |
ed21c5c8 CD |
208 | (string :tag "Opening (numbered)") |
209 | (string :tag "Closing (numbered)") | |
71d35b24 | 210 | (string :tag "Opening (unnumbered)") |
ed21c5c8 CD |
211 | (string :tag "Closing (unnumbered)")) |
212 | (function :tag "Hook computing sectioning")))))) | |
213 | ||
214 | (defcustom org-export-latex-inputenc-alist nil | |
215 | "Alist of inputenc coding system names, and what should really be used. | |
216 | For example, adding an entry | |
217 | ||
218 | (\"utf8\" . \"utf8x\") | |
219 | ||
220 | will cause \\usepackage[utf8x]{inputenc} to be used for buffers that | |
221 | are written as utf8 files." | |
222 | :group 'org-export-latex | |
223 | :type '(repeat | |
224 | (cons | |
225 | (string :tag "Derived from buffer") | |
226 | (string :tag "Use this instead")))) | |
227 | ||
72a81656 CD |
228 | |
229 | (defcustom org-export-latex-emphasis-alist | |
15841868 JW |
230 | '(("*" "\\textbf{%s}" nil) |
231 | ("/" "\\emph{%s}" nil) | |
232 | ("_" "\\underline{%s}" nil) | |
54a0dee5 | 233 | ("+" "\\st{%s}" nil) |
3ab2c837 | 234 | ("=" "\\protectedtexttt" t) |
c8d0cf5c | 235 | ("~" "\\verb" t)) |
15841868 JW |
236 | "Alist of LaTeX expressions to convert emphasis fontifiers. |
237 | Each element of the list is a list of three elements. | |
238 | The first element is the character used as a marker for fontification. | |
239 | The second element is a formatting string to wrap fontified text with. | |
8bfe682a | 240 | If it is \"\\verb\", Org will automatically select a delimiter |
3ab2c837 BG |
241 | character that is not in the string. \"\\protectedtexttt\" will use \\texttt |
242 | to typeset and try to protect special characters. | |
15841868 JW |
243 | The third element decides whether to protect converted text from other |
244 | conversions." | |
72a81656 CD |
245 | :group 'org-export-latex |
246 | :type 'alist) | |
247 | ||
15841868 JW |
248 | (defcustom org-export-latex-title-command "\\maketitle" |
249 | "The command used to insert the title just after \\begin{document}. | |
250 | If this string contains the formatting specification \"%s\" then | |
251 | it will be used as a formatting string, passing the title as an | |
252 | argument." | |
253 | :group 'org-export-latex | |
254 | :type 'string) | |
255 | ||
c8d0cf5c CD |
256 | (defcustom org-export-latex-import-inbuffer-stuff nil |
257 | "Non-nil means define TeX macros for Org's inbuffer definitions. | |
258 | For example \orgTITLE for #+TITLE." | |
259 | :group 'org-export-latex | |
260 | :type 'boolean) | |
261 | ||
db9c3fb1 | 262 | (defcustom org-export-latex-date-format |
3ab2c837 | 263 | "\\today" |
72a81656 CD |
264 | "Format string for \\date{...}." |
265 | :group 'org-export-latex | |
266 | :type 'string) | |
267 | ||
c8d0cf5c CD |
268 | (defcustom org-export-latex-todo-keyword-markup "\\textbf{%s}" |
269 | "Markup for TODO keywords, as a printf format. | |
270 | This can be a single format for all keywords, a cons cell with separate | |
271 | formats for not-done and done states, or an association list with setup | |
272 | for individual keywords. If a keyword shows up for which there is no | |
273 | markup defined, the first one in the association list will be used." | |
274 | :group 'org-export-latex | |
275 | :type '(choice | |
276 | (string :tag "Default") | |
277 | (cons :tag "Distinguish undone and done" | |
278 | (string :tag "Not-DONE states") | |
279 | (string :tag "DONE states")) | |
280 | (repeat :tag "Per keyword markup" | |
281 | (cons | |
282 | (string :tag "Keyword") | |
283 | (string :tag "Markup"))))) | |
284 | ||
afe98dfa CD |
285 | (defcustom org-export-latex-tag-markup "\\textbf{%s}" |
286 | "Markup for tags, as a printf format." | |
287 | :group 'org-export-latex | |
288 | :type 'string) | |
289 | ||
c8d0cf5c CD |
290 | (defcustom org-export-latex-timestamp-markup "\\textit{%s}" |
291 | "A printf format string to be applied to time stamps." | |
292 | :group 'org-export-latex | |
293 | :type 'string) | |
294 | ||
3ab2c837 BG |
295 | (defcustom org-export-latex-timestamp-inactive-markup "\\textit{%s}" |
296 | "A printf format string to be applied to inactive time stamps." | |
297 | :group 'org-export-latex | |
298 | :type 'string) | |
299 | ||
c8d0cf5c CD |
300 | (defcustom org-export-latex-timestamp-keyword-markup "\\texttt{%s}" |
301 | "A printf format string to be applied to time stamps." | |
302 | :group 'org-export-latex | |
303 | :type 'string) | |
304 | ||
acedf35c CD |
305 | (defcustom org-export-latex-href-format "\\href{%s}{%s}" |
306 | "A printf format string to be applied to href links. | |
7877f373 JB |
307 | The format must contain either two %s instances or just one. |
308 | If it contains two %s instances, the first will be filled with | |
3ab2c837 BG |
309 | the link, the second with the link description. If it contains |
310 | only one, the %s will be filled with the link." | |
acedf35c CD |
311 | :group 'org-export-latex |
312 | :type 'string) | |
313 | ||
314 | (defcustom org-export-latex-hyperref-format "\\hyperref[%s]{%s}" | |
ed21c5c8 | 315 | "A printf format string to be applied to hyperref links. |
3ab2c837 BG |
316 | The format must contain one or two %s instances. The first one |
317 | will be filled with the link, the second with its description." | |
ed21c5c8 CD |
318 | :group 'org-export-latex |
319 | :type 'string) | |
320 | ||
3ab2c837 BG |
321 | (defcustom org-export-latex-footnote-separator "\\textsuperscript{,}\\," |
322 | "Text used to separate footnotes." | |
323 | :group 'org-export-latex | |
324 | :type 'string) | |
325 | ||
326 | (defcustom org-export-latex-quotes | |
327 | '(("fr" ("\\(\\s-\\|[[(]\\)\"" . "«~") ("\\(\\S-\\)\"" . "~»") ("\\(\\s-\\|(\\)'" . "'")) | |
328 | ("en" ("\\(\\s-\\|[[(]\\)\"" . "``") ("\\(\\S-\\)\"" . "''") ("\\(\\s-\\|(\\)'" . "`"))) | |
329 | "Alist for quotes to use when converting english double-quotes. | |
330 | ||
331 | The CAR of each item in this alist is the language code. | |
332 | The CDR of each item in this alist is a list of three CONS: | |
333 | - the first CONS defines the opening quote; | |
334 | - the second CONS defines the closing quote; | |
335 | - the last CONS defines single quotes. | |
336 | ||
337 | For each item in a CONS, the first string is a regexp | |
338 | for allowed characters before/after the quote, the second | |
339 | string defines the replacement string for this quote." | |
340 | :group 'org-export-latex | |
341 | :type '(list | |
342 | (cons :tag "Opening quote" | |
343 | (string :tag "Regexp for char before") | |
344 | (string :tag "Replacement quote ")) | |
345 | (cons :tag "Closing quote" | |
346 | (string :tag "Regexp for char after ") | |
347 | (string :tag "Replacement quote ")) | |
348 | (cons :tag "Single quote" | |
349 | (string :tag "Regexp for char before") | |
350 | (string :tag "Replacement quote ")))) | |
351 | ||
d5098885 | 352 | (defcustom org-export-latex-tables-verbatim nil |
621f83e4 | 353 | "When non-nil, tables are exported verbatim." |
d5098885 JW |
354 | :group 'org-export-latex |
355 | :type 'boolean) | |
356 | ||
c8d0cf5c CD |
357 | (defcustom org-export-latex-tables-centered t |
358 | "When non-nil, tables are exported in a center environment." | |
359 | :group 'org-export-latex | |
360 | :type 'boolean) | |
361 | ||
db9c3fb1 | 362 | (defcustom org-export-latex-tables-column-borders nil |
c8d0cf5c CD |
363 | "When non-nil, grouping columns can cause outer vertical lines in tables. |
364 | When nil, grouping causes only separation lines between groups." | |
db9c3fb1 CD |
365 | :group 'org-export-latex |
366 | :type 'boolean) | |
72a81656 | 367 | |
c8d0cf5c | 368 | (defcustom org-export-latex-low-levels 'itemize |
621f83e4 CD |
369 | "How to convert sections below the current level of sectioning. |
370 | This is specified by the `org-export-headline-levels' option or the | |
371 | value of \"H:\" in Org's #+OPTION line. | |
15841868 | 372 | |
c8d0cf5c CD |
373 | This can be either nil (skip the sections), `description', `itemize', |
374 | or `enumerate' (convert the sections as the corresponding list type), or | |
375 | a string to be used instead of \\section{%s}. In this latter case, | |
376 | the %s stands here for the inserted headline and is mandatory. | |
377 | ||
378 | It may also be a list of three string to define a user-defined environment | |
379 | that should be used. The first string should be the like | |
380 | \"\\begin{itemize}\", the second should be like \"\\item %s %s\" with up | |
8bfe682a | 381 | to two occurrences of %s for the title and a label, respectively. The third |
c8d0cf5c | 382 | string should be like \"\\end{itemize\"." |
72a81656 CD |
383 | :group 'org-export-latex |
384 | :type '(choice (const :tag "Ignore" nil) | |
c8d0cf5c CD |
385 | (const :tag "Convert as descriptive list" description) |
386 | (const :tag "Convert as itemized list" itemize) | |
387 | (const :tag "Convert as enumerated list" enumerate) | |
388 | (list :tag "User-defined environment" | |
389 | :value ("\\begin{itemize}" "\\end{itemize}" "\\item %s") | |
390 | (string :tag "Start") | |
391 | (string :tag "End") | |
392 | (string :tag "item")) | |
72a81656 CD |
393 | (string :tag "Use a section string" :value "\\subparagraph{%s}"))) |
394 | ||
0bd48b37 | 395 | (defcustom org-export-latex-list-parameters |
3ab2c837 | 396 | '(:cbon "$\\boxtimes$" :cboff "$\\Box$" :cbtrans "$\\boxminus$") |
0bd48b37 CD |
397 | "Parameters for the LaTeX list exporter. |
398 | These parameters will be passed on to `org-list-to-latex', which in turn | |
399 | will pass them (combined with the LaTeX default list parameters) to | |
400 | `org-list-to-generic'." | |
401 | :group 'org-export-latex | |
402 | :type 'plist) | |
403 | ||
c8d0cf5c CD |
404 | (defcustom org-export-latex-verbatim-wrap |
405 | '("\\begin{verbatim}\n" . "\\end{verbatim}\n") | |
406 | "Environment to be wrapped around a fixed-width section in LaTeX export. | |
407 | This is a cons with two strings, to be added before and after the | |
408 | fixed-with text. | |
409 | ||
410 | Defaults to \\begin{verbatim} and \\end{verbatim}." | |
411 | :group 'org-export-translation | |
412 | :group 'org-export-latex | |
413 | :type '(cons (string :tag "Open") | |
414 | (string :tag "Close"))) | |
415 | ||
54a0dee5 | 416 | (defcustom org-export-latex-listings nil |
ed21c5c8 | 417 | "Non-nil means export source code using the listings package. |
54a0dee5 CD |
418 | This package will fontify source code, possibly even with color. |
419 | If you want to use this, you also need to make LaTeX use the | |
420 | listings package, and if you want to have color, the color | |
421 | package. Just add these to `org-export-latex-packages-alist', | |
422 | for example using customize, or with something like | |
423 | ||
424 | (require 'org-latex) | |
425 | (add-to-list 'org-export-latex-packages-alist '(\"\" \"listings\")) | |
afe98dfa CD |
426 | (add-to-list 'org-export-latex-packages-alist '(\"\" \"color\")) |
427 | ||
428 | Alternatively, | |
429 | ||
430 | (setq org-export-latex-listings 'minted) | |
431 | ||
432 | causes source code to be exported using the minted package as | |
3ab2c837 | 433 | opposed to listings. If you want to use minted, you need to add |
afe98dfa CD |
434 | the minted package to `org-export-latex-packages-alist', for |
435 | example using customize, or with | |
436 | ||
437 | (require 'org-latex) | |
438 | (add-to-list 'org-export-latex-packages-alist '(\"\" \"minted\")) | |
439 | ||
3ab2c837 BG |
440 | In addition, it is necessary to install |
441 | pygments (http://pygments.org), and to configure the variable | |
afe98dfa CD |
442 | `org-latex-to-pdf-process' so that the -shell-escape option is |
443 | passed to pdflatex. | |
444 | " | |
54a0dee5 CD |
445 | :group 'org-export-latex |
446 | :type 'boolean) | |
447 | ||
448 | (defcustom org-export-latex-listings-langs | |
afe98dfa | 449 | '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp") |
54a0dee5 CD |
450 | (c "C") (cc "C++") |
451 | (fortran "fortran") | |
452 | (perl "Perl") (cperl "Perl") (python "Python") (ruby "Ruby") | |
453 | (html "HTML") (xml "XML") | |
454 | (tex "TeX") (latex "TeX") | |
455 | (shell-script "bash") | |
456 | (gnuplot "Gnuplot") | |
457 | (ocaml "Caml") (caml "Caml") | |
86fbb8ca | 458 | (sql "SQL") (sqlite "sql")) |
54a0dee5 CD |
459 | "Alist mapping languages to their listing language counterpart. |
460 | The key is a symbol, the major mode symbol without the \"-mode\". | |
461 | The value is the string that should be inserted as the language parameter | |
462 | for the listings package. If the mode name and the listings name are | |
463 | the same, the language does not need an entry in this list - but it does not | |
464 | hurt if it is present." | |
465 | :group 'org-export-latex | |
466 | :type '(repeat | |
467 | (list | |
468 | (symbol :tag "Major mode ") | |
469 | (string :tag "Listings language")))) | |
470 | ||
afe98dfa CD |
471 | (defcustom org-export-latex-listings-w-names t |
472 | "Non-nil means export names of named code blocks. | |
473 | Code blocks exported with the listings package (controlled by the | |
474 | `org-export-latex-listings' variable) can be named in the style | |
475 | of noweb." | |
476 | :group 'org-export-latex | |
477 | :type 'boolean) | |
478 | ||
479 | (defcustom org-export-latex-minted-langs | |
480 | '((emacs-lisp "common-lisp") | |
481 | (cc "c++") | |
482 | (cperl "perl") | |
483 | (shell-script "bash") | |
484 | (caml "ocaml")) | |
485 | "Alist mapping languages to their minted language counterpart. | |
486 | The key is a symbol, the major mode symbol without the \"-mode\". | |
487 | The value is the string that should be inserted as the language parameter | |
488 | for the minted package. If the mode name and the listings name are | |
489 | the same, the language does not need an entry in this list - but it does not | |
490 | hurt if it is present. | |
491 | ||
492 | Note that minted uses all lower case for language identifiers, | |
493 | and that the full list of language identifiers can be obtained | |
494 | with: | |
495 | pygmentize -L lexers | |
496 | " | |
497 | :group 'org-export-latex | |
498 | :type '(repeat | |
499 | (list | |
500 | (symbol :tag "Major mode ") | |
501 | (string :tag "Listings language")))) | |
502 | ||
3ab2c837 BG |
503 | (defcustom org-export-latex-listings-options nil |
504 | "Association list of options for the latex listings package. | |
505 | ||
506 | These options are supplied as a comma-separated list to the | |
507 | \\lstset command. Each element of the association list should be | |
508 | a list containing two strings: the name of the option, and the | |
509 | value. For example, | |
510 | ||
511 | (setq org-export-latex-listings-options | |
512 | '((\"basicstyle\" \"\\small\") | |
513 | (\"keywordstyle\" \"\\color{black}\\bfseries\\underbar\"))) | |
514 | ||
515 | will typeset the code in a small size font with underlined, bold | |
516 | black keywords. | |
517 | ||
518 | Note that the same options will be applied to blocks of all | |
519 | languages." | |
520 | :group 'org-export-latex | |
521 | :type '(repeat | |
522 | (list | |
523 | (string :tag "Listings option name ") | |
524 | (string :tag "Listings option value")))) | |
525 | ||
526 | (defcustom org-export-latex-minted-options nil | |
527 | "Association list of options for the latex minted package. | |
528 | ||
529 | These options are supplied within square brackets in | |
530 | \\begin{minted} environments. Each element of the alist should be | |
531 | a list containing two strings: the name of the option, and the | |
532 | value. For example, | |
533 | ||
534 | (setq org-export-latex-minted-options | |
535 | '((\"bgcolor\" \"bg\") (\"frame\" \"lines\"))) | |
536 | ||
537 | will result in src blocks being exported with | |
538 | ||
539 | \\begin{minted}[bgcolor=bg,frame=lines]{<LANG>} | |
540 | ||
541 | as the start of the minted environment. Note that the same | |
542 | options will be applied to blocks of all languages." | |
543 | :group 'org-export-latex | |
544 | :type '(repeat | |
545 | (list | |
546 | (string :tag "Minted option name ") | |
547 | (string :tag "Minted option value")))) | |
548 | ||
549 | (defvar org-export-latex-custom-lang-environments nil | |
550 | "Association list mapping languages to language-specific latex | |
551 | environments used during export of src blocks by the listings | |
552 | and minted latex packages. For example, | |
553 | ||
554 | (setq org-export-latex-custom-lang-environments | |
555 | '((python \"pythoncode\"))) | |
556 | ||
557 | would have the effect that if org encounters begin_src python | |
558 | during latex export it will output | |
559 | ||
560 | \\begin{pythoncode} | |
561 | <src block body> | |
562 | \\end{pythoncode}") | |
563 | ||
d5098885 | 564 | (defcustom org-export-latex-remove-from-headlines |
0bd48b37 | 565 | '(:todo nil :priority nil :tags nil) |
86fbb8ca | 566 | "A plist of keywords to remove from headlines. OBSOLETE. |
72a81656 CD |
567 | Non-nil means remove this keyword type from the headline. |
568 | ||
0bd48b37 CD |
569 | Don't remove the keys, just change their values. |
570 | ||
571 | Obsolete, this variable is no longer used. Use the separate | |
572 | variables `org-export-with-todo-keywords', `org-export-with-priority', | |
573 | and `org-export-with-tags' instead." | |
72a81656 CD |
574 | :type 'plist |
575 | :group 'org-export-latex) | |
576 | ||
3ab2c837 | 577 | (defcustom org-export-latex-image-default-option "width=.9\\linewidth" |
72a81656 CD |
578 | "Default option for images." |
579 | :group 'org-export-latex | |
db9c3fb1 | 580 | :type 'string) |
72a81656 | 581 | |
3ab2c837 BG |
582 | (defcustom org-latex-default-figure-position "htb" |
583 | "Default position for latex figures." | |
584 | :group 'org-export-latex | |
585 | :type 'string) | |
586 | ||
86fbb8ca CD |
587 | (defcustom org-export-latex-tabular-environment "tabular" |
588 | "Default environment used to build tables." | |
589 | :group 'org-export-latex | |
590 | :type 'string) | |
591 | ||
0bd48b37 | 592 | (defcustom org-export-latex-inline-image-extensions |
c8d0cf5c | 593 | '("pdf" "jpeg" "jpg" "png" "ps" "eps") |
0bd48b37 | 594 | "Extensions of image files that can be inlined into LaTeX. |
c8d0cf5c CD |
595 | Note that the image extension *actually* allowed depend on the way the |
596 | LaTeX file is processed. When used with pdflatex, pdf, jpg and png images | |
7877f373 | 597 | are OK. When processing through dvi to PostScript, only ps and eps are |
c8d0cf5c CD |
598 | allowed. The default we use here encompasses both." |
599 | :group 'org-export-latex | |
0bd48b37 CD |
600 | :type '(repeat (string :tag "Extension"))) |
601 | ||
72a81656 | 602 | (defcustom org-export-latex-coding-system nil |
86fbb8ca | 603 | "Coding system for the exported LaTeX file." |
72a81656 CD |
604 | :group 'org-export-latex |
605 | :type 'coding-system) | |
606 | ||
71d35b24 CD |
607 | (defgroup org-export-pdf nil |
608 | "Options for exporting Org-mode files to PDF, via LaTeX." | |
ed21c5c8 | 609 | :tag "Org Export PDF" |
71d35b24 CD |
610 | :group 'org-export-latex |
611 | :group 'org-export) | |
612 | ||
c8d0cf5c | 613 | (defcustom org-latex-to-pdf-process |
afe98dfa CD |
614 | '("pdflatex -interaction nonstopmode -output-directory %o %f" |
615 | "pdflatex -interaction nonstopmode -output-directory %o %f" | |
616 | "pdflatex -interaction nonstopmode -output-directory %o %f") | |
c8d0cf5c CD |
617 | "Commands to process a LaTeX file to a PDF file. |
618 | This is a list of strings, each of them will be given to the shell | |
afe98dfa CD |
619 | as a command. %f in the command will be replaced by the full file name, %b |
620 | by the file base name (i.e. without extension) and %o by the base directory | |
621 | of the file. | |
622 | ||
c8d0cf5c | 623 | The reason why this is a list is that it usually takes several runs of |
afe98dfa | 624 | `pdflatex', maybe mixed with a call to `bibtex'. Org does not have a clever |
8bfe682a | 625 | mechanism to detect which of these commands have to be run to get to a stable |
c8d0cf5c CD |
626 | result, and it also does not do any error checking. |
627 | ||
afe98dfa CD |
628 | By default, Org uses 3 runs of `pdflatex' to do the processing. If you |
629 | have texi2dvi on your system and if that does not cause the infamous | |
630 | egrep/locale bug: | |
631 | ||
632 | http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html | |
633 | ||
634 | then `texi2dvi' is the superior choice. Org does offer it as one | |
635 | of the customize options. | |
636 | ||
c8d0cf5c CD |
637 | Alternatively, this may be a Lisp function that does the processing, so you |
638 | could use this to apply the machinery of AUCTeX or the Emacs LaTeX mode. | |
8bfe682a | 639 | This function should accept the file name as its single argument." |
ed21c5c8 | 640 | :group 'org-export-pdf |
afe98dfa CD |
641 | :type '(choice |
642 | (repeat :tag "Shell command sequence" | |
c8d0cf5c | 643 | (string :tag "Shell command")) |
afe98dfa CD |
644 | (const :tag "2 runs of pdflatex" |
645 | ("pdflatex -interaction nonstopmode -output-directory %o %f" | |
646 | "pdflatex -interaction nonstopmode -output-directory %o %f")) | |
647 | (const :tag "3 runs of pdflatex" | |
648 | ("pdflatex -interaction nonstopmode -output-directory %o %f" | |
649 | "pdflatex -interaction nonstopmode -output-directory %o %f" | |
650 | "pdflatex -interaction nonstopmode -output-directory %o %f")) | |
651 | (const :tag "pdflatex,bibtex,pdflatex,pdflatex" | |
652 | ("pdflatex -interaction nonstopmode -output-directory %o %f" | |
653 | "bibtex %b" | |
654 | "pdflatex -interaction nonstopmode -output-directory %o %f" | |
655 | "pdflatex -interaction nonstopmode -output-directory %o %f")) | |
656 | (const :tag "texi2dvi" | |
657 | ("texi2dvi -p -b -c -V %f")) | |
658 | (const :tag "rubber" | |
659 | ("rubber -d --into %o %f")) | |
660 | (function))) | |
c8d0cf5c | 661 | |
ed21c5c8 CD |
662 | (defcustom org-export-pdf-logfiles |
663 | '("aux" "idx" "log" "out" "toc" "nav" "snm" "vrb") | |
664 | "The list of file extensions to consider as LaTeX logfiles." | |
665 | :group 'org-export-pdf | |
666 | :type '(repeat (string :tag "Extension"))) | |
667 | ||
71d35b24 | 668 | (defcustom org-export-pdf-remove-logfiles t |
ed21c5c8 | 669 | "Non-nil means remove the logfiles produced by PDF production. |
71d35b24 | 670 | These are the .aux, .log, .out, and .toc files." |
c8d0cf5c | 671 | :group 'org-export-pdf |
71d35b24 CD |
672 | :type 'boolean) |
673 | ||
c8d0cf5c CD |
674 | ;;; Hooks |
675 | ||
ed21c5c8 CD |
676 | (defvar org-export-latex-after-initial-vars-hook nil |
677 | "Hook run before LaTeX export. | |
678 | The exact moment is after the initial variables like org-export-latex-class | |
679 | have been determined from the environment.") | |
680 | ||
c8d0cf5c CD |
681 | (defvar org-export-latex-after-blockquotes-hook nil |
682 | "Hook run during LaTeX export, after blockquote, verse, center are done.") | |
683 | ||
8d642074 CD |
684 | (defvar org-export-latex-final-hook nil |
685 | "Hook run in the finalized LaTeX buffer.") | |
686 | ||
ed21c5c8 CD |
687 | (defvar org-export-latex-after-save-hook nil |
688 | "Hook run in the finalized LaTeX buffer, after it has been saved.") | |
689 | ||
0b8568f5 | 690 | ;;; Autoload functions: |
db9c3fb1 | 691 | |
72a81656 CD |
692 | ;;;###autoload |
693 | (defun org-export-as-latex-batch () | |
621f83e4 CD |
694 | "Call `org-export-as-latex', may be used in batch processing. |
695 | For example: | |
696 | ||
33306645 CD |
697 | emacs --batch |
698 | --load=$HOME/lib/emacs/org.el | |
699 | --eval \"(setq org-export-headline-levels 2)\" | |
700 | --visit=MyFile --funcall org-export-as-latex-batch" | |
72a81656 CD |
701 | (org-export-as-latex org-export-headline-levels 'hidden)) |
702 | ||
703 | ;;;###autoload | |
704 | (defun org-export-as-latex-to-buffer (arg) | |
33306645 | 705 | "Call `org-export-as-latex` with output to a temporary buffer. |
72a81656 CD |
706 | No file is created. The prefix ARG is passed through to `org-export-as-latex'." |
707 | (interactive "P") | |
708 | (org-export-as-latex arg nil nil "*Org LaTeX Export*") | |
c8d0cf5c CD |
709 | (when org-export-show-temporary-export-buffer |
710 | (switch-to-buffer-other-window "*Org LaTeX Export*"))) | |
72a81656 CD |
711 | |
712 | ;;;###autoload | |
713 | (defun org-replace-region-by-latex (beg end) | |
714 | "Replace the region from BEG to END with its LaTeX export. | |
715 | It assumes the region has `org-mode' syntax, and then convert it to | |
db9c3fb1 | 716 | LaTeX. This can be used in any buffer. For example, you could |
72a81656 CD |
717 | write an itemized list in `org-mode' syntax in an LaTeX buffer and |
718 | then use this command to convert it." | |
719 | (interactive "r") | |
720 | (let (reg latex buf) | |
721 | (save-window-excursion | |
722 | (if (org-mode-p) | |
723 | (setq latex (org-export-region-as-latex | |
724 | beg end t 'string)) | |
725 | (setq reg (buffer-substring beg end) | |
726 | buf (get-buffer-create "*Org tmp*")) | |
81ad75af | 727 | (with-current-buffer buf |
72a81656 CD |
728 | (erase-buffer) |
729 | (insert reg) | |
730 | (org-mode) | |
731 | (setq latex (org-export-region-as-latex | |
732 | (point-min) (point-max) t 'string))) | |
733 | (kill-buffer buf))) | |
734 | (delete-region beg end) | |
735 | (insert latex))) | |
736 | ||
737 | ;;;###autoload | |
738 | (defun org-export-region-as-latex (beg end &optional body-only buffer) | |
739 | "Convert region from BEG to END in `org-mode' buffer to LaTeX. | |
740 | If prefix arg BODY-ONLY is set, omit file header, footer, and table of | |
741 | contents, and only produce the region of converted text, useful for | |
742 | cut-and-paste operations. | |
743 | If BUFFER is a buffer or a string, use/create that buffer as a target | |
744 | of the converted LaTeX. If BUFFER is the symbol `string', return the | |
c8d0cf5c | 745 | produced LaTeX as a string and leave no buffer behind. For example, |
72a81656 CD |
746 | a Lisp program could call this function in the following way: |
747 | ||
748 | (setq latex (org-export-region-as-latex beg end t 'string)) | |
749 | ||
750 | When called interactively, the output buffer is selected, and shown | |
c8d0cf5c | 751 | in a window. A non-interactive call will only return the buffer." |
72a81656 | 752 | (interactive "r\nP") |
3ab2c837 | 753 | (when (org-called-interactively-p 'any) |
72a81656 CD |
754 | (setq buffer "*Org LaTeX Export*")) |
755 | (let ((transient-mark-mode t) (zmacs-regions t) | |
c8d0cf5c | 756 | ext-plist rtn) |
8bfe682a | 757 | (setq ext-plist (plist-put ext-plist :ignore-subtree-p t)) |
72a81656 CD |
758 | (goto-char end) |
759 | (set-mark (point)) ;; to activate the region | |
760 | (goto-char beg) | |
761 | (setq rtn (org-export-as-latex | |
c8d0cf5c | 762 | nil nil ext-plist |
72a81656 CD |
763 | buffer body-only)) |
764 | (if (fboundp 'deactivate-mark) (deactivate-mark)) | |
3ab2c837 | 765 | (if (and (org-called-interactively-p 'any) (bufferp rtn)) |
72a81656 CD |
766 | (switch-to-buffer-other-window rtn) |
767 | rtn))) | |
768 | ||
769 | ;;;###autoload | |
770 | (defun org-export-as-latex (arg &optional hidden ext-plist | |
4b67ea89 | 771 | to-buffer body-only pub-dir) |
db9c3fb1 CD |
772 | "Export current buffer to a LaTeX file. |
773 | If there is an active region, export only the region. The prefix | |
774 | ARG specifies how many levels of the outline should become | |
775 | headlines. The default is 3. Lower levels will be exported | |
776 | depending on `org-export-latex-low-levels'. The default is to | |
c8d0cf5c CD |
777 | convert them as description lists. |
778 | HIDDEN is obsolete and does nothing. | |
779 | EXT-PLIST is a property list with | |
db9c3fb1 CD |
780 | external parameters overriding org-mode's default settings, but |
781 | still inferior to file-local settings. When TO-BUFFER is | |
782 | non-nil, create a buffer with that name and export to that | |
783 | buffer. If TO-BUFFER is the symbol `string', don't leave any | |
784 | buffer behind but just return the resulting LaTeX as a string. | |
785 | When BODY-ONLY is set, don't produce the file header and footer, | |
86fbb8ca CD |
786 | simply return the content of \\begin{document}...\\end{document}, |
787 | without even the \\begin{document} and \\end{document} commands. | |
4b67ea89 | 788 | when PUB-DIR is set, use this as the publishing directory." |
72a81656 | 789 | (interactive "P") |
86fbb8ca | 790 | (when (and (not body-only) arg (listp arg)) (setq body-only t)) |
ed21c5c8 CD |
791 | (run-hooks 'org-export-first-hook) |
792 | ||
72a81656 CD |
793 | ;; Make sure we have a file name when we need it. |
794 | (when (and (not (or to-buffer body-only)) | |
795 | (not buffer-file-name)) | |
796 | (if (buffer-base-buffer) | |
797 | (org-set-local 'buffer-file-name | |
798 | (with-current-buffer (buffer-base-buffer) | |
799 | buffer-file-name)) | |
800 | (error "Need a file name to be able to export"))) | |
801 | ||
802 | (message "Exporting to LaTeX...") | |
c8d0cf5c | 803 | (org-unmodified |
ed21c5c8 CD |
804 | (let ((inhibit-read-only t)) |
805 | (remove-text-properties (point-min) (point-max) | |
806 | '(:org-license-to-kill nil)))) | |
72a81656 | 807 | (org-update-radio-target-regexp) |
db9c3fb1 | 808 | (org-export-latex-set-initial-vars ext-plist arg) |
3ab2c837 BG |
809 | (setq org-export-opt-plist org-export-latex-options-plist |
810 | org-export-footnotes-data (org-footnote-all-labels 'with-defs) | |
811 | org-export-footnotes-seen nil | |
812 | org-export-latex-footmark-seen nil) | |
ed21c5c8 CD |
813 | (org-install-letbind) |
814 | (run-hooks 'org-export-latex-after-initial-vars-hook) | |
15841868 | 815 | (let* ((wcf (current-window-configuration)) |
3ab2c837 BG |
816 | (opt-plist |
817 | (org-export-process-option-filters org-export-latex-options-plist)) | |
db9c3fb1 | 818 | (region-p (org-region-active-p)) |
b349f79f CD |
819 | (rbeg (and region-p (region-beginning))) |
820 | (rend (and region-p (region-end))) | |
db9c3fb1 | 821 | (subtree-p |
8bfe682a | 822 | (if (plist-get opt-plist :ignore-subtree-p) |
c8d0cf5c CD |
823 | nil |
824 | (when region-p | |
825 | (save-excursion | |
826 | (goto-char rbeg) | |
827 | (and (org-at-heading-p) | |
828 | (>= (org-end-of-subtree t t) rend)))))) | |
829 | (opt-plist (setq org-export-opt-plist | |
830 | (if subtree-p | |
831 | (org-export-add-subtree-options opt-plist rbeg) | |
832 | opt-plist))) | |
b349f79f | 833 | ;; Make sure the variable contains the updated values. |
ed21c5c8 CD |
834 | (org-export-latex-options-plist (setq org-export-opt-plist opt-plist)) |
835 | ;; The following two are dynamically scoped into other | |
836 | ;; routines below. | |
837 | (org-current-export-dir | |
838 | (or pub-dir (org-export-directory :html opt-plist))) | |
839 | (org-current-export-file buffer-file-name) | |
db9c3fb1 CD |
840 | (title (or (and subtree-p (org-export-get-title-from-subtree)) |
841 | (plist-get opt-plist :title) | |
842 | (and (not | |
843 | (plist-get opt-plist :skip-before-1st-heading)) | |
844 | (org-export-grab-title-from-buffer)) | |
ed21c5c8 CD |
845 | (and buffer-file-name |
846 | (file-name-sans-extension | |
847 | (file-name-nondirectory buffer-file-name))) | |
848 | "No Title")) | |
849 | (filename | |
850 | (and (not to-buffer) | |
851 | (concat | |
852 | (file-name-as-directory | |
853 | (or pub-dir | |
854 | (org-export-directory :LaTeX ext-plist))) | |
855 | (file-name-sans-extension | |
856 | (or (and subtree-p | |
857 | (org-entry-get rbeg "EXPORT_FILE_NAME" t)) | |
858 | (file-name-nondirectory ;sans-extension | |
859 | (or buffer-file-name | |
86fbb8ca | 860 | (error "Don't know which export file to use"))))) |
ed21c5c8 CD |
861 | ".tex"))) |
862 | (filename | |
863 | (and filename | |
864 | (if (equal (file-truename filename) | |
865 | (file-truename (or buffer-file-name "dummy.org"))) | |
866 | (concat filename ".tex") | |
867 | filename))) | |
72a81656 CD |
868 | (buffer (if to-buffer |
869 | (cond | |
870 | ((eq to-buffer 'string) (get-buffer-create | |
871 | "*Org LaTeX Export*")) | |
872 | (t (get-buffer-create to-buffer))) | |
873 | (find-file-noselect filename))) | |
72a81656 | 874 | (odd org-odd-levels-only) |
db9c3fb1 | 875 | (header (org-export-latex-make-header title opt-plist)) |
4b67ea89 | 876 | (skip (cond (subtree-p nil) |
db55f368 | 877 | (region-p nil) |
4b67ea89 | 878 | (t (plist-get opt-plist :skip-before-1st-heading)))) |
72a81656 | 879 | (text (plist-get opt-plist :text)) |
c8d0cf5c CD |
880 | (org-export-preprocess-hook |
881 | (cons | |
882 | `(lambda () (org-set-local 'org-complex-heading-regexp | |
883 | ,org-export-latex-complex-heading-re)) | |
884 | org-export-preprocess-hook)) | |
65c439fd | 885 | (first-lines (if skip "" (org-export-latex-first-lines |
c8d0cf5c CD |
886 | opt-plist |
887 | (if subtree-p | |
888 | (save-excursion | |
889 | (goto-char rbeg) | |
890 | (point-at-bol 2)) | |
891 | rbeg) | |
892 | (if region-p rend)))) | |
72a81656 CD |
893 | (coding-system (and (boundp 'buffer-file-coding-system) |
894 | buffer-file-coding-system)) | |
895 | (coding-system-for-write (or org-export-latex-coding-system | |
896 | coding-system)) | |
897 | (save-buffer-coding-system (or org-export-latex-coding-system | |
898 | coding-system)) | |
33306645 | 899 | (region (buffer-substring |
72a81656 CD |
900 | (if region-p (region-beginning) (point-min)) |
901 | (if region-p (region-end) (point-max)))) | |
ed21c5c8 CD |
902 | (text |
903 | (and text (string-match "\\S-" text) | |
904 | (org-export-preprocess-string | |
905 | text | |
906 | :emph-multiline t | |
3ab2c837 | 907 | :for-backend 'latex |
ed21c5c8 CD |
908 | :comments nil |
909 | :tags (plist-get opt-plist :tags) | |
910 | :priority (plist-get opt-plist :priority) | |
911 | :footnotes (plist-get opt-plist :footnotes) | |
912 | :drawers (plist-get opt-plist :drawers) | |
913 | :timestamps (plist-get opt-plist :timestamps) | |
914 | :todo-keywords (plist-get opt-plist :todo-keywords) | |
3ab2c837 | 915 | :tasks (plist-get opt-plist :tasks) |
ed21c5c8 CD |
916 | :add-text nil |
917 | :skip-before-1st-heading skip | |
918 | :select-tags nil | |
919 | :exclude-tags nil | |
920 | :LaTeX-fragments nil))) | |
72a81656 | 921 | (string-for-export |
20908596 | 922 | (org-export-preprocess-string |
db55f368 CD |
923 | region |
924 | :emph-multiline t | |
3ab2c837 | 925 | :for-backend 'latex |
db55f368 CD |
926 | :comments nil |
927 | :tags (plist-get opt-plist :tags) | |
928 | :priority (plist-get opt-plist :priority) | |
0bd48b37 | 929 | :footnotes (plist-get opt-plist :footnotes) |
1bcdebed | 930 | :drawers (plist-get opt-plist :drawers) |
0bd48b37 | 931 | :timestamps (plist-get opt-plist :timestamps) |
db55f368 | 932 | :todo-keywords (plist-get opt-plist :todo-keywords) |
3ab2c837 | 933 | :tasks (plist-get opt-plist :tasks) |
db55f368 CD |
934 | :add-text (if (eq to-buffer 'string) nil text) |
935 | :skip-before-1st-heading skip | |
936 | :select-tags (plist-get opt-plist :select-tags) | |
937 | :exclude-tags (plist-get opt-plist :exclude-tags) | |
938 | :LaTeX-fragments nil))) | |
15841868 | 939 | |
db9c3fb1 | 940 | (set-buffer buffer) |
72a81656 | 941 | (erase-buffer) |
c8d0cf5c | 942 | (org-install-letbind) |
0b8568f5 | 943 | |
15841868 JW |
944 | (and (fboundp 'set-buffer-file-coding-system) |
945 | (set-buffer-file-coding-system coding-system-for-write)) | |
946 | ||
db9c3fb1 | 947 | ;; insert the header and initial document commands |
15841868 | 948 | (unless (or (eq to-buffer 'string) body-only) |
db9c3fb1 | 949 | (insert header)) |
15841868 JW |
950 | |
951 | ;; insert text found in #+TEXT | |
952 | (when (and text (not (eq to-buffer 'string))) | |
db9c3fb1 CD |
953 | (insert (org-export-latex-content |
954 | text '(lists tables fixed-width keywords)) | |
955 | "\n\n")) | |
15841868 JW |
956 | |
957 | ;; insert lines before the first headline | |
3ab2c837 | 958 | (unless (or skip (string-match "^\\*" first-lines)) |
15841868 | 959 | (insert first-lines)) |
72a81656 | 960 | |
15841868 | 961 | ;; export the content of headlines |
72a81656 CD |
962 | (org-export-latex-global |
963 | (with-temp-buffer | |
964 | (insert string-for-export) | |
965 | (goto-char (point-min)) | |
15841868 JW |
966 | (when (re-search-forward "^\\(\\*+\\) " nil t) |
967 | (let* ((asters (length (match-string 1))) | |
968 | (level (if odd (- asters 2) (- asters 1)))) | |
db9c3fb1 | 969 | (setq org-export-latex-add-level |
15841868 JW |
970 | (if odd (1- (/ (1+ asters) 2)) (1- asters))) |
971 | (org-export-latex-parse-global level odd))))) | |
972 | ||
973 | ;; finalization | |
72a81656 | 974 | (unless body-only (insert "\n\\end{document}")) |
c8d0cf5c | 975 | |
ed21c5c8 CD |
976 | ;; Attach description terms to the \item macro |
977 | (goto-char (point-min)) | |
978 | (while (re-search-forward "^[ \t]*\\\\item\\([ \t]+\\)\\[" nil t) | |
979 | (delete-region (match-beginning 1) (match-end 1))) | |
980 | ||
c8d0cf5c CD |
981 | ;; Relocate the table of contents |
982 | (goto-char (point-min)) | |
983 | (when (re-search-forward "\\[TABLE-OF-CONTENTS\\]" nil t) | |
984 | (goto-char (point-min)) | |
985 | (while (re-search-forward "\\\\tableofcontents\\>[ \t]*\n?" nil t) | |
986 | (replace-match "")) | |
987 | (goto-char (point-min)) | |
988 | (and (re-search-forward "\\[TABLE-OF-CONTENTS\\]" nil t) | |
989 | (replace-match "\\tableofcontents" t t))) | |
990 | ||
ed21c5c8 CD |
991 | ;; Cleanup forced line ends in items where they are not needed |
992 | (goto-char (point-min)) | |
993 | (while (re-search-forward | |
994 | "^[ \t]*\\\\item\\>.*\\(\\\\\\\\\\)[ \t]*\\(\n\\\\label.*\\)*\n\\\\begin" | |
995 | nil t) | |
996 | (delete-region (match-beginning 1) (match-end 1))) | |
997 | (goto-char (point-min)) | |
998 | (while (re-search-forward | |
999 | "^[ \t]*\\\\item\\>.*\\(\\\\\\\\\\)[ \t]*\\(\n\\\\label.*\\)*" | |
1000 | nil t) | |
1001 | (if (looking-at "[\n \t]+") | |
1002 | (replace-match "\n"))) | |
1003 | ||
8d642074 | 1004 | (run-hooks 'org-export-latex-final-hook) |
86fbb8ca CD |
1005 | (if to-buffer |
1006 | (unless (eq major-mode 'latex-mode) (latex-mode)) | |
1007 | (save-buffer)) | |
ed21c5c8 CD |
1008 | (org-export-latex-fix-inputenc) |
1009 | (run-hooks 'org-export-latex-after-save-hook) | |
72a81656 | 1010 | (goto-char (point-min)) |
c8d0cf5c CD |
1011 | (or (org-export-push-to-kill-ring "LaTeX") |
1012 | (message "Exporting to LaTeX...done")) | |
15841868 JW |
1013 | (prog1 |
1014 | (if (eq to-buffer 'string) | |
1015 | (prog1 (buffer-substring (point-min) (point-max)) | |
1016 | (kill-buffer (current-buffer))) | |
1017 | (current-buffer)) | |
1018 | (set-window-configuration wcf)))) | |
1019 | ||
71d35b24 CD |
1020 | ;;;###autoload |
1021 | (defun org-export-as-pdf (arg &optional hidden ext-plist | |
1022 | to-buffer body-only pub-dir) | |
1023 | "Export as LaTeX, then process through to PDF." | |
1024 | (interactive "P") | |
1025 | (message "Exporting to PDF...") | |
1026 | (let* ((wconfig (current-window-configuration)) | |
1027 | (lbuf (org-export-as-latex arg hidden ext-plist | |
1028 | to-buffer body-only pub-dir)) | |
1029 | (file (buffer-file-name lbuf)) | |
1030 | (base (file-name-sans-extension (buffer-file-name lbuf))) | |
c8d0cf5c | 1031 | (pdffile (concat base ".pdf")) |
3ab2c837 BG |
1032 | (cmds (if (eq org-export-latex-listings 'minted) |
1033 | ;; automatically add -shell-escape when needed | |
1034 | (mapcar (lambda (cmd) | |
1035 | (replace-regexp-in-string | |
1036 | "pdflatex " "pdflatex -shell-escape " cmd)) | |
1037 | org-latex-to-pdf-process) | |
1038 | org-latex-to-pdf-process)) | |
c8d0cf5c CD |
1039 | (outbuf (get-buffer-create "*Org PDF LaTeX Output*")) |
1040 | (bibtex-p (with-current-buffer lbuf | |
1041 | (save-excursion | |
1042 | (goto-char (point-min)) | |
1043 | (re-search-forward "\\\\bibliography{" nil t)))) | |
afe98dfa | 1044 | cmd output-dir errors) |
c8d0cf5c | 1045 | (with-current-buffer outbuf (erase-buffer)) |
afe98dfa CD |
1046 | (message (concat "Processing LaTeX file " file "...")) |
1047 | (setq output-dir (file-name-directory file)) | |
3ab2c837 BG |
1048 | (with-current-buffer lbuf |
1049 | (save-excursion | |
1050 | (if (and cmds (symbolp cmds)) | |
1051 | (funcall cmds (shell-quote-argument file)) | |
1052 | (while cmds | |
1053 | (setq cmd (pop cmds)) | |
1054 | (while (string-match "%b" cmd) | |
1055 | (setq cmd (replace-match | |
1056 | (save-match-data | |
1057 | (shell-quote-argument base)) | |
1058 | t t cmd))) | |
1059 | (while (string-match "%f" cmd) | |
1060 | (setq cmd (replace-match | |
1061 | (save-match-data | |
1062 | (shell-quote-argument file)) | |
1063 | t t cmd))) | |
1064 | (while (string-match "%o" cmd) | |
1065 | (setq cmd (replace-match | |
1066 | (save-match-data | |
1067 | (shell-quote-argument output-dir)) | |
1068 | t t cmd))) | |
1069 | (shell-command cmd outbuf))))) | |
afe98dfa CD |
1070 | (message (concat "Processing LaTeX file " file "...done")) |
1071 | (setq errors (org-export-latex-get-error outbuf)) | |
71d35b24 | 1072 | (if (not (file-exists-p pdffile)) |
afe98dfa CD |
1073 | (error (concat "PDF file " pdffile " was not produced" |
1074 | (if errors (concat ":" errors "") ""))) | |
71d35b24 CD |
1075 | (set-window-configuration wconfig) |
1076 | (when org-export-pdf-remove-logfiles | |
ed21c5c8 | 1077 | (dolist (ext org-export-pdf-logfiles) |
71d35b24 CD |
1078 | (setq file (concat base "." ext)) |
1079 | (and (file-exists-p file) (delete-file file)))) | |
afe98dfa CD |
1080 | (message (concat |
1081 | "Exporting to PDF...done" | |
1082 | (if errors | |
1083 | (concat ", with some errors:" errors) | |
1084 | ""))) | |
71d35b24 CD |
1085 | pdffile))) |
1086 | ||
afe98dfa CD |
1087 | (defun org-export-latex-get-error (buf) |
1088 | "Collect the kinds of errors that remain in pdflatex processing." | |
1089 | (with-current-buffer buf | |
1090 | (save-excursion | |
1091 | (goto-char (point-max)) | |
1092 | (when (re-search-backward "^[ \t]*This is pdf.*?TeX.*?Version" nil t) | |
1093 | ;; OK, we are at the location of the final run | |
1094 | (let ((pos (point)) (errors "") (case-fold-search t)) | |
1095 | (if (re-search-forward "Reference.*?undefined" nil t) | |
1096 | (setq errors (concat errors " [undefined reference]"))) | |
1097 | (goto-char pos) | |
1098 | (if (re-search-forward "Citation.*?undefined" nil t) | |
1099 | (setq errors (concat errors " [undefined citation]"))) | |
1100 | (goto-char pos) | |
1101 | (if (re-search-forward "Undefined control sequence" nil t) | |
1102 | (setq errors (concat errors " [undefined control sequence]"))) | |
1103 | (and (org-string-nw-p errors) errors)))))) | |
1104 | ||
71d35b24 CD |
1105 | ;;;###autoload |
1106 | (defun org-export-as-pdf-and-open (arg) | |
1107 | "Export as LaTeX, then process through to PDF, and open." | |
1108 | (interactive "P") | |
1109 | (let ((pdffile (org-export-as-pdf arg))) | |
1110 | (if pdffile | |
ed21c5c8 CD |
1111 | (progn |
1112 | (org-open-file pdffile) | |
1113 | (when org-export-kill-product-buffer-when-displayed | |
1114 | (kill-buffer (find-buffer-visiting | |
1115 | (concat (file-name-sans-extension (buffer-file-name)) | |
1116 | ".tex"))))) | |
71d35b24 CD |
1117 | (error "PDF file was not produced")))) |
1118 | ||
0b8568f5 | 1119 | ;;; Parsing functions: |
db9c3fb1 | 1120 | |
72a81656 CD |
1121 | (defun org-export-latex-parse-global (level odd) |
1122 | "Parse the current buffer recursively, starting at LEVEL. | |
1123 | If ODD is non-nil, assume the buffer only contains odd sections. | |
db9c3fb1 | 1124 | Return a list reflecting the document structure." |
72a81656 CD |
1125 | (save-excursion |
1126 | (goto-char (point-min)) | |
1127 | (let* ((cnt 0) output | |
db9c3fb1 | 1128 | (depth org-export-latex-sectioning-depth)) |
ed21c5c8 | 1129 | (while (org-re-search-forward-unprotected |
72a81656 CD |
1130 | (concat "^\\(\\(?:\\*\\)\\{" |
1131 | (number-to-string (+ (if odd 2 1) level)) | |
1132 | "\\}\\) \\(.*\\)$") | |
1133 | ;; make sure that there is no upper heading | |
1134 | (when (> level 0) | |
1135 | (save-excursion | |
1136 | (save-match-data | |
ed21c5c8 | 1137 | (org-re-search-forward-unprotected |
72a81656 CD |
1138 | (concat "^\\(\\(?:\\*\\)\\{" |
1139 | (number-to-string level) | |
1140 | "\\}\\) \\(.*\\)$") nil t)))) t) | |
1141 | (setq cnt (1+ cnt)) | |
1142 | (let* ((pos (match-beginning 0)) | |
1143 | (heading (match-string 2)) | |
1144 | (nlevel (if odd (/ (+ 3 level) 2) (1+ level)))) | |
1145 | (save-excursion | |
1146 | (narrow-to-region | |
1147 | (point) | |
1148 | (save-match-data | |
ed21c5c8 | 1149 | (if (org-re-search-forward-unprotected |
72a81656 CD |
1150 | (concat "^\\(\\(?:\\*\\)\\{" |
1151 | (number-to-string (+ (if odd 2 1) level)) | |
1152 | "\\}\\) \\(.*\\)$") nil t) | |
1153 | (match-beginning 0) | |
1154 | (point-max)))) | |
1155 | (goto-char (point-min)) | |
1156 | (setq output | |
1157 | (append output | |
1158 | (list | |
1159 | (list | |
1160 | `(pos . ,pos) | |
1161 | `(level . ,nlevel) | |
1162 | `(occur . ,cnt) | |
1163 | `(heading . ,heading) | |
1164 | `(content . ,(org-export-latex-parse-content)) | |
db9c3fb1 | 1165 | `(subcontent . ,(org-export-latex-parse-subcontent |
72a81656 CD |
1166 | level odd))))))) |
1167 | (widen))) | |
1168 | (list output)))) | |
1169 | ||
1170 | (defun org-export-latex-parse-content () | |
1171 | "Extract the content of a section." | |
1172 | (let ((beg (point)) | |
ed21c5c8 | 1173 | (end (if (org-re-search-forward-unprotected "^\\(\\*\\)+ .*$" nil t) |
72a81656 CD |
1174 | (progn (beginning-of-line) (point)) |
1175 | (point-max)))) | |
1176 | (buffer-substring beg end))) | |
1177 | ||
1178 | (defun org-export-latex-parse-subcontent (level odd) | |
1179 | "Extract the subcontent of a section at LEVEL. | |
1180 | If ODD Is non-nil, assume subcontent only contains odd sections." | |
ed21c5c8 | 1181 | (if (not (org-re-search-forward-unprotected |
72a81656 CD |
1182 | (concat "^\\(\\(?:\\*\\)\\{" |
1183 | (number-to-string (+ (if odd 4 2) level)) | |
1184 | "\\}\\) \\(.*\\)$") | |
1185 | nil t)) | |
1186 | nil ; subcontent is nil | |
1187 | (org-export-latex-parse-global (+ (if odd 2 1) level) odd))) | |
1188 | ||
0b8568f5 | 1189 | ;;; Rendering functions: |
72a81656 CD |
1190 | (defun org-export-latex-global (content) |
1191 | "Export CONTENT to LaTeX. | |
1192 | CONTENT is an element of the list produced by | |
1193 | `org-export-latex-parse-global'." | |
1194 | (if (eq (car content) 'subcontent) | |
1195 | (mapc 'org-export-latex-sub (cdr content)) | |
1196 | (org-export-latex-sub (car content)))) | |
1197 | ||
1198 | (defun org-export-latex-sub (subcontent) | |
1199 | "Export the list SUBCONTENT to LaTeX. | |
1200 | SUBCONTENT is an alist containing information about the headline | |
1201 | and its content." | |
db9c3fb1 | 1202 | (let ((num (plist-get org-export-latex-options-plist :section-numbers))) |
d5098885 | 1203 | (mapc (lambda(x) (org-export-latex-subcontent x num)) subcontent))) |
72a81656 | 1204 | |
d5098885 | 1205 | (defun org-export-latex-subcontent (subcontent num) |
621f83e4 | 1206 | "Export each cell of SUBCONTENT to LaTeX. |
3ab2c837 BG |
1207 | If NUM is non-nil export numbered sections, otherwise use unnumbered |
1208 | sections. If NUM is an integer, export the highest NUM levels as | |
1209 | numbered sections and lower levels as unnumbered sections." | |
ed21c5c8 | 1210 | (let* ((heading (cdr (assoc 'heading subcontent))) |
621f83e4 CD |
1211 | (level (- (cdr (assoc 'level subcontent)) |
1212 | org-export-latex-add-level)) | |
1213 | (occur (number-to-string (cdr (assoc 'occur subcontent)))) | |
1214 | (content (cdr (assoc 'content subcontent))) | |
1215 | (subcontent (cadr (assoc 'subcontent subcontent))) | |
ce4fdcb9 CD |
1216 | (label (org-get-text-property-any 0 'target heading)) |
1217 | (label-list (cons label (cdr (assoc label | |
ed21c5c8 CD |
1218 | org-export-target-aliases)))) |
1219 | (sectioning org-export-latex-sectioning) | |
1220 | (depth org-export-latex-sectioning-depth) | |
1221 | main-heading sub-heading) | |
1222 | (when (symbolp (car sectioning)) | |
1223 | (setq sectioning (funcall (car sectioning) level heading)) | |
1224 | (when sectioning | |
1225 | (setq heading (car sectioning) | |
1226 | sectioning (cdr sectioning) | |
1227 | ;; target property migh have changed... | |
1228 | label (org-get-text-property-any 0 'target heading) | |
1229 | label-list (cons label (cdr (assoc label | |
1230 | org-export-target-aliases))))) | |
1231 | (if sectioning (setq sectioning (make-list 10 sectioning))) | |
1232 | (setq depth (if sectioning 10000 0))) | |
1233 | (if (string-match "[ \t]*\\\\\\\\[ \t]*" heading) | |
1234 | (setq main-heading (substring heading 0 (match-beginning 0)) | |
1235 | sub-heading (substring heading (match-end 0)))) | |
1236 | (setq heading (org-export-latex-fontify-headline heading) | |
1237 | sub-heading (and sub-heading | |
1238 | (org-export-latex-fontify-headline sub-heading)) | |
1239 | main-heading (and main-heading | |
1240 | (org-export-latex-fontify-headline main-heading))) | |
db9c3fb1 | 1241 | (cond |
72a81656 | 1242 | ;; Normal conversion |
ed21c5c8 CD |
1243 | ((<= level depth) |
1244 | (let* ((sec (nth (1- level) sectioning)) | |
3ab2c837 BG |
1245 | (num (if (integerp num) |
1246 | (>= num level) | |
1247 | num)) | |
71d35b24 CD |
1248 | start end) |
1249 | (if (consp (cdr sec)) | |
1250 | (setq start (nth (if num 0 2) sec) | |
1251 | end (nth (if num 1 3) sec)) | |
1252 | (setq start (if num (car sec) (cdr sec)))) | |
ed21c5c8 CD |
1253 | (insert (format start (if main-heading main-heading heading) |
1254 | (or sub-heading ""))) | |
1255 | (insert "\n") | |
ce4fdcb9 CD |
1256 | (when label |
1257 | (insert (mapconcat (lambda (l) (format "\\label{%s}" l)) | |
1258 | label-list "\n") "\n")) | |
71d35b24 CD |
1259 | (insert (org-export-latex-content content)) |
1260 | (cond ((stringp subcontent) (insert subcontent)) | |
ed21c5c8 CD |
1261 | ((listp subcontent) |
1262 | (while (org-looking-back "\n\n") (backward-delete-char 1)) | |
1263 | (org-export-latex-sub subcontent))) | |
1264 | (when (and end (string-match "[^ \t]" end)) | |
1265 | (let ((hook (org-get-text-property-any 0 'org-insert-hook end))) | |
1266 | (and (functionp hook) (funcall hook))) | |
1267 | (insert end "\n")))) | |
72a81656 | 1268 | ;; At a level under the hl option: we can drop this subsection |
ed21c5c8 | 1269 | ((> level depth) |
72a81656 | 1270 | (cond ((eq org-export-latex-low-levels 'description) |
c8d0cf5c CD |
1271 | (if (string-match "% ends low level$" |
1272 | (buffer-substring (point-at-bol 0) (point))) | |
1273 | (delete-region (point-at-bol 0) (point)) | |
1274 | (insert "\\begin{description}\n")) | |
ed21c5c8 | 1275 | (insert (format "\n\\item[%s]%s~\n" |
621f83e4 CD |
1276 | heading |
1277 | (if label (format "\\label{%s}" label) ""))) | |
72a81656 CD |
1278 | (insert (org-export-latex-content content)) |
1279 | (cond ((stringp subcontent) (insert subcontent)) | |
1280 | ((listp subcontent) (org-export-latex-sub subcontent))) | |
c8d0cf5c CD |
1281 | (insert "\\end{description} % ends low level\n")) |
1282 | ((memq org-export-latex-low-levels '(itemize enumerate)) | |
1283 | (if (string-match "% ends low level$" | |
1284 | (buffer-substring (point-at-bol 0) (point))) | |
1285 | (delete-region (point-at-bol 0) (point)) | |
1286 | (insert (format "\\begin{%s}\n" | |
1287 | (symbol-name org-export-latex-low-levels)))) | |
ed21c5c8 | 1288 | (insert (format "\n\\item %s\\\\\n%s%%" |
c8d0cf5c CD |
1289 | heading |
1290 | (if label (format "\\label{%s}" label) ""))) | |
1291 | (insert (org-export-latex-content content)) | |
1292 | (cond ((stringp subcontent) (insert subcontent)) | |
1293 | ((listp subcontent) (org-export-latex-sub subcontent))) | |
1294 | (insert (format "\\end{%s} %% ends low level\n" | |
1295 | (symbol-name org-export-latex-low-levels)))) | |
1296 | ||
1297 | ((listp org-export-latex-low-levels) | |
1298 | (if (string-match "% ends low level$" | |
1299 | (buffer-substring (point-at-bol 0) (point))) | |
1300 | (delete-region (point-at-bol 0) (point)) | |
1301 | (insert (car org-export-latex-low-levels) "\n")) | |
1302 | (insert (format (nth 2 org-export-latex-low-levels) | |
1303 | heading | |
1304 | (if label (format "\\label{%s}" label) ""))) | |
1305 | (insert (org-export-latex-content content)) | |
1306 | (cond ((stringp subcontent) (insert subcontent)) | |
1307 | ((listp subcontent) (org-export-latex-sub subcontent))) | |
1308 | (insert (nth 1 org-export-latex-low-levels) | |
1309 | " %% ends low level\n")) | |
1310 | ||
72a81656 CD |
1311 | ((stringp org-export-latex-low-levels) |
1312 | (insert (format org-export-latex-low-levels heading) "\n") | |
621f83e4 | 1313 | (when label (insert (format "\\label{%s}\n" label))) |
72a81656 CD |
1314 | (insert (org-export-latex-content content)) |
1315 | (cond ((stringp subcontent) (insert subcontent)) | |
1316 | ((listp subcontent) (org-export-latex-sub subcontent))))))))) | |
1317 | ||
0b8568f5 | 1318 | ;;; Exporting internals: |
db9c3fb1 | 1319 | (defun org-export-latex-set-initial-vars (ext-plist level) |
0b8568f5 | 1320 | "Store org local variables required for LaTeX export. |
db9c3fb1 CD |
1321 | EXT-PLIST is an optional additional plist. |
1322 | LEVEL indicates the default depth for export." | |
1323 | (setq org-export-latex-todo-keywords-1 org-todo-keywords-1 | |
c8d0cf5c CD |
1324 | org-export-latex-done-keywords org-done-keywords |
1325 | org-export-latex-not-done-keywords org-not-done-keywords | |
1326 | org-export-latex-complex-heading-re org-complex-heading-regexp | |
1327 | org-export-latex-display-custom-times org-display-custom-times | |
db9c3fb1 | 1328 | org-export-latex-all-targets-re |
0b8568f5 | 1329 | (org-make-target-link-regexp (org-all-targets)) |
db9c3fb1 | 1330 | org-export-latex-options-plist |
0b8568f5 JW |
1331 | (org-combine-plists (org-default-export-plist) ext-plist |
1332 | (org-infile-export-plist)) | |
db9c3fb1 | 1333 | org-export-latex-class |
0bd48b37 CD |
1334 | (or (and (org-region-active-p) |
1335 | (save-excursion | |
1336 | (goto-char (region-beginning)) | |
1337 | (and (looking-at org-complex-heading-regexp) | |
1338 | (org-entry-get nil "LaTeX_CLASS" 'selective)))) | |
1339 | (save-excursion | |
1340 | (save-restriction | |
1341 | (widen) | |
1342 | (goto-char (point-min)) | |
86fbb8ca | 1343 | (and (re-search-forward "^#\\+LaTeX_CLASS:[ \t]*\\(-[a-zA-Z]+\\)" nil t) |
0bd48b37 | 1344 | (match-string 1)))) |
8d642074 | 1345 | (plist-get org-export-latex-options-plist :latex-class) |
0bd48b37 | 1346 | org-export-latex-default-class) |
ed21c5c8 CD |
1347 | org-export-latex-class-options |
1348 | (or (and (org-region-active-p) | |
1349 | (save-excursion | |
1350 | (goto-char (region-beginning)) | |
1351 | (and (looking-at org-complex-heading-regexp) | |
1352 | (org-entry-get nil "LaTeX_CLASS_OPTIONS" 'selective)))) | |
1353 | (save-excursion | |
1354 | (save-restriction | |
1355 | (widen) | |
1356 | (goto-char (point-min)) | |
1357 | (and (re-search-forward "^#\\+LaTeX_CLASS_OPTIONS:[ \t]*\\(.*?\\)[ \t]*$" nil t) | |
1358 | (match-string 1)))) | |
1359 | (plist-get org-export-latex-options-plist :latex-class-options)) | |
0bd48b37 CD |
1360 | org-export-latex-class |
1361 | (or (car (assoc org-export-latex-class org-export-latex-classes)) | |
1362 | (error "No definition for class `%s' in `org-export-latex-classes'" | |
1363 | org-export-latex-class)) | |
db9c3fb1 CD |
1364 | org-export-latex-header |
1365 | (cadr (assoc org-export-latex-class org-export-latex-classes)) | |
1366 | org-export-latex-sectioning | |
1367 | (cddr (assoc org-export-latex-class org-export-latex-classes)) | |
1368 | org-export-latex-sectioning-depth | |
1369 | (or level | |
1370 | (let ((hl-levels | |
1371 | (plist-get org-export-latex-options-plist :headline-levels)) | |
1372 | (sec-depth (length org-export-latex-sectioning))) | |
ed21c5c8 CD |
1373 | (if (> hl-levels sec-depth) sec-depth hl-levels)))) |
1374 | (when (and org-export-latex-class-options | |
1375 | (string-match "\\S-" org-export-latex-class-options) | |
1376 | (string-match "^[ \t]*\\(\\\\documentclass\\)\\(\\[.*?\\]\\)?" | |
1377 | org-export-latex-header)) | |
1378 | (setq org-export-latex-header | |
1379 | (concat (substring org-export-latex-header 0 (match-end 1)) | |
1380 | org-export-latex-class-options | |
1381 | (substring org-export-latex-header (match-end 0)))))) | |
1382 | ||
1383 | (defvar org-export-latex-format-toc-function | |
1384 | 'org-export-latex-format-toc-default | |
86fbb8ca | 1385 | "The function formatting returning the string to create the table of contents. |
ed21c5c8 | 1386 | The function mus take one parameter, the depth of the table of contents.") |
db9c3fb1 CD |
1387 | |
1388 | (defun org-export-latex-make-header (title opt-plist) | |
1389 | "Make the LaTeX header and return it as a string. | |
1390 | TITLE is the current title from the buffer or region. | |
1391 | OPT-PLIST is the options plist for current buffer." | |
1392 | (let ((toc (plist-get opt-plist :table-of-contents)) | |
ed21c5c8 | 1393 | (author (org-export-apply-macros-in-string |
3ab2c837 BG |
1394 | (plist-get opt-plist :author))) |
1395 | (email (replace-regexp-in-string | |
1396 | "_" "\\\\_" | |
1397 | (org-export-apply-macros-in-string | |
1398 | (plist-get opt-plist :email))))) | |
db9c3fb1 | 1399 | (concat |
15841868 | 1400 | (if (plist-get opt-plist :time-stamp-file) |
6671980f | 1401 | (format-time-string "%% Created %Y-%m-%d %a %H:%M\n")) |
ed21c5c8 CD |
1402 | ;; insert LaTeX custom header and packages from the list |
1403 | (org-splice-latex-header | |
1404 | (org-export-apply-macros-in-string org-export-latex-header) | |
1405 | org-export-latex-default-packages-alist | |
86fbb8ca | 1406 | org-export-latex-packages-alist nil |
ed21c5c8 CD |
1407 | (org-export-apply-macros-in-string |
1408 | (plist-get opt-plist :latex-header-extra))) | |
1409 | ;; append another special variable | |
c8d0cf5c | 1410 | (org-export-apply-macros-in-string org-export-latex-append-header) |
afe98dfa | 1411 | ;; define alert if not yet defined |
ed21c5c8 | 1412 | "\n\\providecommand{\\alert}[1]{\\textbf{#1}}" |
15841868 | 1413 | ;; insert the title |
db9c3fb1 CD |
1414 | (format |
1415 | "\n\n\\title{%s}\n" | |
acedf35c | 1416 | (org-export-latex-fontify-headline title)) |
15841868 JW |
1417 | ;; insert author info |
1418 | (if (plist-get opt-plist :author-info) | |
3ab2c837 BG |
1419 | (format "\\author{%s%s}\n" |
1420 | (org-export-latex-fontify-headline (or author user-full-name)) | |
1421 | (if (and (plist-get opt-plist :email-info) email | |
1422 | (string-match "\\S-" email)) | |
1423 | (format "\\thanks{%s}" email) | |
1424 | "")) | |
15841868 | 1425 | (format "%%\\author{%s}\n" |
ed21c5c8 | 1426 | (org-export-latex-fontify-headline (or author user-full-name)))) |
15841868 JW |
1427 | ;; insert the date |
1428 | (format "\\date{%s}\n" | |
db9c3fb1 | 1429 | (format-time-string |
15841868 JW |
1430 | (or (plist-get opt-plist :date) |
1431 | org-export-latex-date-format))) | |
3ab2c837 BG |
1432 | ;; beginning of the document |
1433 | "\n\\begin{document}\n\n" | |
15841868 | 1434 | ;; insert the title command |
c8d0cf5c CD |
1435 | (when (string-match "\\S-" title) |
1436 | (if (string-match "%s" org-export-latex-title-command) | |
1437 | (format org-export-latex-title-command title) | |
1438 | org-export-latex-title-command)) | |
15841868 | 1439 | "\n\n" |
15841868 | 1440 | ;; table of contents |
db9c3fb1 | 1441 | (when (and org-export-with-toc |
15841868 | 1442 | (plist-get opt-plist :section-numbers)) |
ed21c5c8 CD |
1443 | (funcall org-export-latex-format-toc-function |
1444 | (cond ((numberp toc) | |
1445 | (min toc (plist-get opt-plist :headline-levels))) | |
1446 | (toc (plist-get opt-plist :headline-levels)))))))) | |
1447 | ||
1448 | (defun org-export-latex-format-toc-default (depth) | |
1449 | (when depth | |
1450 | (format "\\setcounter{tocdepth}{%s}\n\\tableofcontents\n\\vspace*{1cm}\n" | |
1451 | depth))) | |
0b8568f5 | 1452 | |
c8d0cf5c | 1453 | (defun org-export-latex-first-lines (opt-plist &optional beg end) |
0b8568f5 | 1454 | "Export the first lines before first headline. |
c8d0cf5c CD |
1455 | If BEG is non-nil, it is the beginning of the region. |
1456 | If END is non-nil, it is the end of the region." | |
0b8568f5 | 1457 | (save-excursion |
db55f368 | 1458 | (goto-char (or beg (point-min))) |
8d642074 | 1459 | (let* ((pt (point)) |
3ab2c837 BG |
1460 | (end (if (re-search-forward |
1461 | (concat "^" (org-get-limited-outline-regexp)) end t) | |
8d642074 CD |
1462 | (goto-char (match-beginning 0)) |
1463 | (goto-char (or end (point-max)))))) | |
db55f368 CD |
1464 | (prog1 |
1465 | (org-export-latex-content | |
1466 | (org-export-preprocess-string | |
1467 | (buffer-substring pt end) | |
3ab2c837 | 1468 | :for-backend 'latex |
db55f368 CD |
1469 | :emph-multiline t |
1470 | :add-text nil | |
1471 | :comments nil | |
1472 | :skip-before-1st-heading nil | |
1e4f816a CD |
1473 | :LaTeX-fragments nil |
1474 | :timestamps (plist-get opt-plist :timestamps) | |
1475 | :footnotes (plist-get opt-plist :footnotes))) | |
c8d0cf5c | 1476 | (org-unmodified |
86fbb8ca CD |
1477 | (let ((inhibit-read-only t) |
1478 | (limit (max pt (1- end)))) | |
1479 | (add-text-properties pt limit | |
1480 | '(:org-license-to-kill t)) | |
1481 | (save-excursion | |
1482 | (goto-char pt) | |
afe98dfa CD |
1483 | (while (re-search-forward "^[ \t]*#\\+.*\n?" limit t) |
1484 | (let ((case-fold-search t)) | |
1485 | (unless (org-string-match-p | |
1486 | "^[ \t]*#\\+\\(attr_\\|caption\\>\\|label\\>\\)" | |
1487 | (match-string 0)) | |
1488 | (remove-text-properties (match-beginning 0) (match-end 0) | |
1489 | '(:org-license-to-kill t)))))))))))) | |
3ab2c837 | 1490 | |
c8d0cf5c CD |
1491 | |
1492 | (defvar org-export-latex-header-defs nil | |
1493 | "The header definitions that might be used in the LaTeX body.") | |
0b8568f5 | 1494 | |
db9c3fb1 CD |
1495 | (defun org-export-latex-content (content &optional exclude-list) |
1496 | "Convert CONTENT string to LaTeX. | |
1497 | Don't perform conversions that are in EXCLUDE-LIST. Recognized | |
1498 | conversion types are: quotation-marks, emphasis, sub-superscript, | |
1499 | links, keywords, lists, tables, fixed-width" | |
1500 | (with-temp-buffer | |
3ab2c837 BG |
1501 | (org-install-letbind) |
1502 | (insert content) | |
1503 | (unless (memq 'timestamps exclude-list) | |
1504 | (org-export-latex-time-stamps)) | |
1505 | (unless (memq 'quotation-marks exclude-list) | |
1506 | (org-export-latex-quotation-marks)) | |
1507 | (unless (memq 'emphasis exclude-list) | |
1508 | (when (plist-get org-export-latex-options-plist :emphasize) | |
1509 | (org-export-latex-fontify))) | |
1510 | (unless (memq 'sub-superscript exclude-list) | |
1511 | (org-export-latex-special-chars | |
1512 | (plist-get org-export-latex-options-plist :sub-superscript))) | |
1513 | (unless (memq 'links exclude-list) | |
1514 | (org-export-latex-links)) | |
1515 | (unless (memq 'keywords exclude-list) | |
1516 | (org-export-latex-keywords)) | |
1517 | (unless (memq 'lists exclude-list) | |
1518 | (org-export-latex-lists)) | |
1519 | (unless (memq 'tables exclude-list) | |
1520 | (org-export-latex-tables | |
1521 | (plist-get org-export-latex-options-plist :tables))) | |
1522 | (unless (memq 'fixed-width exclude-list) | |
1523 | (org-export-latex-fixed-width | |
1524 | (plist-get org-export-latex-options-plist :fixed-width))) | |
db9c3fb1 | 1525 | ;; return string |
3ab2c837 | 1526 | (buffer-substring (point-min) (point-max)))) |
db9c3fb1 CD |
1527 | |
1528 | (defun org-export-latex-protect-string (s) | |
621f83e4 | 1529 | "Add the org-protected property to string S." |
db9c3fb1 CD |
1530 | (add-text-properties 0 (length s) '(org-protected t) s) s) |
1531 | ||
1532 | (defun org-export-latex-protect-char-in-string (char-list string) | |
1533 | "Add org-protected text-property to char from CHAR-LIST in STRING." | |
1534 | (with-temp-buffer | |
1535 | (save-match-data | |
1536 | (insert string) | |
1537 | (goto-char (point-min)) | |
1538 | (while (re-search-forward (regexp-opt char-list) nil t) | |
1539 | (add-text-properties (match-beginning 0) | |
1540 | (match-end 0) '(org-protected t))) | |
1541 | (buffer-string)))) | |
1542 | ||
0bd48b37 | 1543 | (defun org-export-latex-keywords-maybe (&optional remove-list) |
72a81656 CD |
1544 | "Maybe remove keywords depending on rules in REMOVE-LIST." |
1545 | (goto-char (point-min)) | |
db9c3fb1 | 1546 | (let ((re-todo (mapconcat 'identity org-export-latex-todo-keywords-1 "\\|")) |
c8d0cf5c CD |
1547 | (case-fold-search nil) |
1548 | (todo-markup org-export-latex-todo-keyword-markup) | |
1549 | fmt) | |
72a81656 CD |
1550 | ;; convert TODO keywords |
1551 | (when (re-search-forward (concat "^\\(" re-todo "\\)") nil t) | |
1552 | (if (plist-get remove-list :todo) | |
1553 | (replace-match "") | |
c8d0cf5c CD |
1554 | (setq fmt (cond |
1555 | ((stringp todo-markup) todo-markup) | |
1556 | ((and (consp todo-markup) (stringp (car todo-markup))) | |
1557 | (if (member (match-string 1) org-export-latex-done-keywords) | |
1558 | (cdr todo-markup) (car todo-markup))) | |
1559 | (t (cdr (or (assoc (match-string 1) todo-markup) | |
1560 | (car todo-markup)))))) | |
86fbb8ca CD |
1561 | (replace-match (org-export-latex-protect-string |
1562 | (format fmt (match-string 1))) t t))) | |
72a81656 CD |
1563 | ;; convert priority string |
1564 | (when (re-search-forward "\\[\\\\#.\\]" nil t) | |
1565 | (if (plist-get remove-list :priority) | |
1566 | (replace-match "") | |
0bd48b37 | 1567 | (replace-match (format "\\textbf{%s}" (match-string 0)) t t))) |
72a81656 | 1568 | ;; convert tags |
afe98dfa | 1569 | (when (re-search-forward "\\(:[a-zA-Z0-9_@#%]+\\)+:" nil t) |
0b8568f5 JW |
1570 | (if (or (not org-export-with-tags) |
1571 | (plist-get remove-list :tags)) | |
72a81656 | 1572 | (replace-match "") |
621f83e4 | 1573 | (replace-match |
2c3ad40d | 1574 | (org-export-latex-protect-string |
afe98dfa | 1575 | (format org-export-latex-tag-markup |
33306645 CD |
1576 | (save-match-data |
1577 | (replace-regexp-in-string | |
3ab2c837 | 1578 | "\\([_#]\\)" "\\\\\\1" (match-string 0))))) |
33306645 | 1579 | t t))))) |
72a81656 | 1580 | |
db9c3fb1 | 1581 | (defun org-export-latex-fontify-headline (string) |
621f83e4 | 1582 | "Fontify special words in STRING." |
72a81656 CD |
1583 | (with-temp-buffer |
1584 | ;; FIXME: org-inside-LaTeX-fragment-p doesn't work when the $...$ is at | |
1585 | ;; the beginning of the buffer - inserting "\n" is safe here though. | |
db9c3fb1 | 1586 | (insert "\n" string) |
acedf35c CD |
1587 | |
1588 | ;; Preserve math snippets | |
3ab2c837 | 1589 | |
acedf35c CD |
1590 | (let* ((matchers (plist-get org-format-latex-options :matchers)) |
1591 | (re-list org-latex-regexps) | |
1592 | beg end re e m n block off) | |
1593 | ;; Check the different regular expressions | |
1594 | (while (setq e (pop re-list)) | |
1595 | (setq m (car e) re (nth 1 e) n (nth 2 e) | |
1596 | block (if (nth 3 e) "\n\n" "")) | |
1597 | (setq off (if (member m '("$" "$1")) 1 0)) | |
1598 | (when (and (member m matchers) (not (equal m "begin"))) | |
1599 | (goto-char (point-min)) | |
1600 | (while (re-search-forward re nil t) | |
1601 | (setq beg (+ (match-beginning 0) off) end (- (match-end 0) 0)) | |
1602 | (add-text-properties beg end | |
1603 | '(org-protected t org-latex-math t)))))) | |
1604 | ||
1605 | ;; Convert LaTeX to \LaTeX{} and TeX to \TeX{} | |
1606 | (goto-char (point-min)) | |
1607 | (let ((case-fold-search nil)) | |
1608 | (while (re-search-forward "\\<\\(\\(La\\)?TeX\\)\\>" nil t) | |
1609 | (unless (eq (char-before (match-beginning 1)) ?\\) | |
1610 | (org-if-unprotected-1 | |
1611 | (replace-match (org-export-latex-protect-string | |
1612 | (concat "\\" (match-string 1) | |
1613 | "{}")) t t))))) | |
72a81656 | 1614 | (goto-char (point-min)) |
ed21c5c8 CD |
1615 | (let ((re (concat "\\\\\\([a-zA-Z]+\\)" |
1616 | "\\(?:<[^<>\n]*>\\)*" | |
1617 | "\\(?:\\[[^][\n]*?\\]\\)*" | |
1618 | "\\(?:<[^<>\n]*>\\)*" | |
1619 | "\\(" | |
1620 | (org-create-multibrace-regexp "{" "}" 3) | |
1621 | "\\)\\{1,3\\}"))) | |
8bfe682a | 1622 | (while (re-search-forward re nil t) |
ed21c5c8 CD |
1623 | (unless (or |
1624 | ;; check for comment line | |
1625 | (save-excursion (goto-char (match-beginning 0)) | |
86fbb8ca | 1626 | (org-in-indented-comment-line)) |
ed21c5c8 CD |
1627 | ;; Check if this is a defined entity, so that is may need conversion |
1628 | (org-entity-get (match-string 1))) | |
8bfe682a CD |
1629 | (add-text-properties (match-beginning 0) (match-end 0) |
1630 | '(org-protected t))))) | |
db9c3fb1 | 1631 | (when (plist-get org-export-latex-options-plist :emphasize) |
0b8568f5 | 1632 | (org-export-latex-fontify)) |
3ab2c837 BG |
1633 | (org-export-latex-time-stamps) |
1634 | (org-export-latex-quotation-marks) | |
0bd48b37 | 1635 | (org-export-latex-keywords-maybe) |
2c3ad40d CD |
1636 | (org-export-latex-special-chars |
1637 | (plist-get org-export-latex-options-plist :sub-superscript)) | |
72a81656 | 1638 | (org-export-latex-links) |
621f83e4 | 1639 | (org-trim (buffer-string)))) |
72a81656 | 1640 | |
c8d0cf5c CD |
1641 | (defun org-export-latex-time-stamps () |
1642 | "Format time stamps." | |
1643 | (goto-char (point-min)) | |
1644 | (let ((org-display-custom-times org-export-latex-display-custom-times)) | |
1645 | (while (re-search-forward org-ts-regexp-both nil t) | |
1646 | (org-if-unprotected-at (1- (point)) | |
1647 | (replace-match | |
1648 | (org-export-latex-protect-string | |
3ab2c837 BG |
1649 | (format (if (string= "<" (substring (match-string 0) 0 1)) |
1650 | org-export-latex-timestamp-markup | |
1651 | org-export-latex-timestamp-inactive-markup) | |
c8d0cf5c CD |
1652 | (substring (org-translate-time (match-string 0)) 1 -1))) |
1653 | t t))))) | |
1654 | ||
72a81656 | 1655 | (defun org-export-latex-quotation-marks () |
621f83e4 | 1656 | "Export quotation marks depending on language conventions." |
3ab2c837 BG |
1657 | (mapc (lambda(l) |
1658 | (goto-char (point-min)) | |
1659 | (while (re-search-forward (car l) nil t) | |
1660 | (let ((rpl (concat (match-string 1) | |
1661 | (org-export-latex-protect-string | |
1662 | (copy-sequence (cdr l)))))) | |
1663 | (org-if-unprotected-1 | |
1664 | (replace-match rpl t t))))) | |
1665 | (cdr (or (assoc (plist-get org-export-latex-options-plist :language) | |
1666 | org-export-latex-quotes) | |
1667 | ;; falls back on english | |
1668 | (assoc "en" org-export-latex-quotes))))) | |
72a81656 | 1669 | |
72a81656 CD |
1670 | (defun org-export-latex-special-chars (sub-superscript) |
1671 | "Export special characters to LaTeX. | |
1672 | If SUB-SUPERSCRIPT is non-nil, convert \\ and ^. | |
1673 | See the `org-export-latex.el' code for a complete conversion table." | |
1674 | (goto-char (point-min)) | |
1675 | (mapc (lambda(c) | |
1676 | (goto-char (point-min)) | |
1677 | (while (re-search-forward c nil t) | |
1678 | ;; Put the point where to check for org-protected | |
3ab2c837 BG |
1679 | (unless (or (get-text-property (match-beginning 2) 'org-protected) |
1680 | (save-match-data (org-at-table.el-p))) | |
72a81656 | 1681 | (cond ((member (match-string 2) '("\\$" "$")) |
15841868 | 1682 | (if (equal (match-string 2) "\\$") |
0bd48b37 CD |
1683 | nil |
1684 | (replace-match "\\$" t t))) | |
15841868 JW |
1685 | ((member (match-string 2) '("&" "%" "#")) |
1686 | (if (equal (match-string 1) "\\") | |
1687 | (replace-match (match-string 2) t t) | |
1688 | (replace-match (concat (match-string 1) "\\" | |
ed21c5c8 CD |
1689 | (match-string 2)) t t) |
1690 | (backward-char 1))) | |
db9c3fb1 CD |
1691 | ((equal (match-string 2) "...") |
1692 | (replace-match | |
1693 | (concat (match-string 1) | |
1694 | (org-export-latex-protect-string "\\ldots{}")) t t)) | |
15841868 JW |
1695 | ((equal (match-string 2) "~") |
1696 | (cond ((equal (match-string 1) "\\") nil) | |
1697 | ((eq 'org-link (get-text-property 0 'face (match-string 2))) | |
1698 | (replace-match (concat (match-string 1) "\\~") t t)) | |
db9c3fb1 | 1699 | (t (replace-match |
15841868 JW |
1700 | (org-export-latex-protect-string |
1701 | (concat (match-string 1) "\\~{}")) t t)))) | |
1702 | ((member (match-string 2) '("{" "}")) | |
0bd48b37 | 1703 | (unless (save-match-data (org-inside-latex-math-p)) |
15841868 JW |
1704 | (if (equal (match-string 1) "\\") |
1705 | (replace-match (match-string 2) t t) | |
1706 | (replace-match (concat (match-string 1) "\\" | |
1707 | (match-string 2)) t t))))) | |
0bd48b37 | 1708 | (unless (save-match-data (org-inside-latex-math-p)) |
15841868 JW |
1709 | (cond ((equal (match-string 2) "\\") |
1710 | (replace-match (or (save-match-data | |
1711 | (org-export-latex-treat-backslash-char | |
1712 | (match-string 1) | |
e9aab93b | 1713 | (or (match-string 3) ""))) |
ed21c5c8 CD |
1714 | "") t t) |
1715 | (when (and (get-text-property (1- (point)) 'org-entity) | |
1716 | (looking-at "{}")) | |
1717 | ;; OK, this was an entity replacement, and the user | |
1718 | ;; had terminated the entity with {}. Make sure | |
1719 | ;; {} is protected as well, and remove the extra {} | |
1720 | ;; inserted by the conversion. | |
1721 | (put-text-property (point) (+ 2 (point)) 'org-protected t) | |
1722 | (if (save-excursion (goto-char (max (- (point) 2) (point-min))) | |
1723 | (looking-at "{}")) | |
1724 | (replace-match "")) | |
1725 | (forward-char 2)) | |
1726 | (backward-char 1)) | |
15841868 JW |
1727 | ((member (match-string 2) '("_" "^")) |
1728 | (replace-match (or (save-match-data | |
1729 | (org-export-latex-treat-sub-super-char | |
1730 | sub-superscript | |
15841868 | 1731 | (match-string 2) |
621f83e4 | 1732 | (match-string 1) |
c8d0cf5c CD |
1733 | (match-string 3))) "") t t) |
1734 | (backward-char 1))))))) | |
0bd48b37 CD |
1735 | '(;"^\\([^\n$]*?\\|^\\)\\(\\\\?\\$\\)\\([^\n$]*\\)$" |
1736 | "\\(\\(\\\\?\\$\\)\\)" | |
ed21c5c8 CD |
1737 | "\\([a-zA-Z0-9()]+\\|[ \t\n]\\|\\b\\|\\\\\\)\\(_\\|\\^\\)\\({[^{}]+}\\|[a-zA-Z0-9]+\\|[ \t\n]\\|[:punct:]\\|)\\|{[a-zA-Z0-9]+}\\|([a-zA-Z0-9]+)\\)" |
1738 | "\\(.\\|^\\)\\(\\\\\\)\\([ \t\n]\\|\\([&#%{}\"]\\|[a-zA-Z][a-zA-Z0-9]*\\)\\)" | |
3ab2c837 | 1739 | "\\(^\\|.\\)\\([&#%{}~]\\|\\.\\.\\.\\)" |
15841868 JW |
1740 | ;; (?\< . "\\textless{}") |
1741 | ;; (?\> . "\\textgreater{}") | |
1742 | ))) | |
72a81656 | 1743 | |
0bd48b37 CD |
1744 | (defun org-inside-latex-math-p () |
1745 | (get-text-property (point) 'org-latex-math)) | |
1746 | ||
72a81656 | 1747 | (defun org-export-latex-treat-sub-super-char |
621f83e4 | 1748 | (subsup char string-before string-after) |
72a81656 CD |
1749 | "Convert the \"_\" and \"^\" characters to LaTeX. |
1750 | SUBSUP corresponds to the ^: option in the #+OPTIONS line. | |
1751 | Convert CHAR depending on STRING-BEFORE and STRING-AFTER." | |
1752 | (cond ((equal string-before "\\") | |
1753 | (concat string-before char string-after)) | |
8d642074 CD |
1754 | ((and (string-match "\\S-+" string-after)) |
1755 | ;; this is part of a math formula | |
0b8568f5 | 1756 | (cond ((eq 'org-link (get-text-property 0 'face char)) |
72a81656 | 1757 | (concat string-before "\\" char string-after)) |
0bd48b37 | 1758 | ((save-match-data (org-inside-latex-math-p)) |
72a81656 CD |
1759 | (if subsup |
1760 | (cond ((eq 1 (length string-after)) | |
1761 | (concat string-before char string-after)) | |
1762 | ((string-match "[({]?\\([^)}]+\\)[)}]?" string-after) | |
db9c3fb1 | 1763 | (format "%s%s{%s}" string-before char |
72a81656 | 1764 | (match-string 1 string-after)))))) |
71d35b24 CD |
1765 | ((and (> (length string-after) 1) |
1766 | (or (eq subsup t) | |
1767 | (and (equal subsup '{}) (eq (string-to-char string-after) ?\{))) | |
86fbb8ca CD |
1768 | (or (string-match "[{]?\\([^}]+\\)[}]?" string-after) |
1769 | (string-match "[(]?\\([^)]+\\)[)]?" string-after))) | |
1770 | ||
c8d0cf5c CD |
1771 | (org-export-latex-protect-string |
1772 | (format "%s$%s{%s}$" string-before char | |
1773 | (if (and (> (match-end 1) (1+ (match-beginning 1))) | |
1774 | (not (equal (substring string-after 0 2) "{\\"))) | |
1775 | (concat "\\mathrm{" (match-string 1 string-after) "}") | |
1776 | (match-string 1 string-after))))) | |
71d35b24 | 1777 | ((eq subsup t) (concat string-before "$" char string-after "$")) |
15841868 | 1778 | (t (org-export-latex-protect-string |
d5098885 | 1779 | (concat string-before "\\" char "{}" string-after))))) |
15841868 | 1780 | (t (org-export-latex-protect-string |
d5098885 | 1781 | (concat string-before "\\" char "{}" string-after))))) |
72a81656 CD |
1782 | |
1783 | (defun org-export-latex-treat-backslash-char (string-before string-after) | |
1784 | "Convert the \"$\" special character to LaTeX. | |
1785 | The conversion is made depending of STRING-BEFORE and STRING-AFTER." | |
ed21c5c8 CD |
1786 | (let ((ass (org-entity-get string-after))) |
1787 | (cond | |
1788 | (ass (org-add-props | |
1789 | (if (nth 2 ass) | |
1790 | (concat string-before | |
1791 | (org-export-latex-protect-string | |
1792 | (concat "$" (nth 1 ass) "$"))) | |
1793 | (concat string-before (org-export-latex-protect-string | |
1794 | (nth 1 ass)))) | |
1795 | nil 'org-entity t)) | |
1796 | ((and (not (string-match "^[ \n\t]" string-after)) | |
1797 | (not (string-match "[ \t]\\'\\|^" string-before))) | |
1798 | ;; backslash is inside a word | |
1799 | (concat string-before | |
1800 | (org-export-latex-protect-string | |
1801 | (concat "\\textbackslash{}" string-after)))) | |
1802 | ((not (or (equal string-after "") | |
1803 | (string-match "^[ \t\n]" string-after))) | |
1804 | ;; backslash might escape a character (like \#) or a user TeX | |
1805 | ;; macro (like \setcounter) | |
1806 | (concat string-before | |
1807 | (org-export-latex-protect-string (concat "\\" string-after)))) | |
1808 | ((and (string-match "^[ \t\n]" string-after) | |
1809 | (string-match "[ \t\n]\\'" string-before)) | |
1810 | ;; backslash is alone, convert it to $\backslash$ | |
1811 | (org-export-latex-protect-string | |
1812 | (concat string-before "\\textbackslash{}" string-after))) | |
1813 | (t (org-export-latex-protect-string | |
1814 | (concat string-before "\\textbackslash{}" string-after)))))) | |
72a81656 | 1815 | |
0bd48b37 CD |
1816 | (defun org-export-latex-keywords () |
1817 | "Convert special keywords to LaTeX." | |
1818 | (goto-char (point-min)) | |
c8d0cf5c CD |
1819 | (while (re-search-forward org-export-latex-special-keyword-regexp nil t) |
1820 | (replace-match (format org-export-latex-timestamp-keyword-markup | |
1821 | (match-string 0)) t t) | |
1822 | (save-excursion | |
1823 | (beginning-of-line 1) | |
ed21c5c8 | 1824 | (unless (looking-at ".*\n[ \t]*\n") |
c8d0cf5c | 1825 | (end-of-line 1) |
ed21c5c8 | 1826 | (insert "\n"))))) |
db9c3fb1 | 1827 | |
72a81656 CD |
1828 | (defun org-export-latex-fixed-width (opt) |
1829 | "When OPT is non-nil convert fixed-width sections to LaTeX." | |
1830 | (goto-char (point-min)) | |
0bd48b37 | 1831 | (while (re-search-forward "^[ \t]*:\\([ \t]\\|$\\)" nil t) |
86fbb8ca CD |
1832 | (unless (get-text-property (point) 'org-example) |
1833 | (if opt | |
1834 | (progn (goto-char (match-beginning 0)) | |
1835 | (insert "\\begin{verbatim}\n") | |
1836 | (while (looking-at "^\\([ \t]*\\):\\(\\([ \t]\\|$\\).*\\)$") | |
1837 | (replace-match (concat (match-string 1) | |
1838 | (match-string 2)) t t) | |
1839 | (forward-line)) | |
1840 | (insert "\\end{verbatim}\n\n")) | |
1841 | (progn (goto-char (match-beginning 0)) | |
1842 | (while (looking-at "^\\([ \t]*\\):\\(\\([ \t]\\|$\\).*\\)$") | |
1843 | (replace-match (concat "%" (match-string 1) | |
1844 | (match-string 2)) t t) | |
1845 | (forward-line))))))) | |
20908596 CD |
1846 | |
1847 | (defvar org-table-last-alignment) ; defined in org-table.el | |
54a0dee5 | 1848 | (defvar org-table-last-column-widths) ; defined in org-table.el |
20908596 | 1849 | (declare-function orgtbl-to-latex "org-table" (table params) t) |
15841868 JW |
1850 | (defun org-export-latex-tables (insert) |
1851 | "Convert tables to LaTeX and INSERT it." | |
ed21c5c8 CD |
1852 | ;; First, get the table.el tables |
1853 | (goto-char (point-min)) | |
1854 | (while (re-search-forward "^[ \t]*\\(\\+-[-+]*\\+\\)[ \t]*\n[ \t]*|" nil t) | |
1855 | (org-if-unprotected | |
1856 | (require 'table) | |
1857 | (org-export-latex-convert-table.el-table))) | |
1858 | ||
1859 | ;; And now the Org-mode tables | |
72a81656 CD |
1860 | (goto-char (point-min)) |
1861 | (while (re-search-forward "^\\([ \t]*\\)|" nil t) | |
8bfe682a CD |
1862 | (org-if-unprotected-at (1- (point)) |
1863 | (org-table-align) | |
1864 | (let* ((beg (org-table-begin)) | |
1865 | (end (org-table-end)) | |
1866 | (raw-table (buffer-substring beg end)) | |
1867 | (org-table-last-alignment (copy-sequence org-table-last-alignment)) | |
1868 | (org-table-last-column-widths (copy-sequence | |
1869 | org-table-last-column-widths)) | |
1870 | fnum fields line lines olines gr colgropen line-fmt align | |
3ab2c837 BG |
1871 | caption width shortn label attr floatp placement |
1872 | longtblp tblenv tabular-env) | |
8bfe682a CD |
1873 | (if org-export-latex-tables-verbatim |
1874 | (let* ((tbl (concat "\\begin{verbatim}\n" raw-table | |
1875 | "\\end{verbatim}\n"))) | |
1876 | (apply 'delete-region (list beg end)) | |
1877 | (insert (org-export-latex-protect-string tbl))) | |
1878 | (progn | |
1879 | (setq caption (org-find-text-property-in-string | |
1880 | 'org-caption raw-table) | |
86fbb8ca CD |
1881 | shortn (org-find-text-property-in-string |
1882 | 'org-caption-shortn raw-table) | |
8bfe682a CD |
1883 | attr (org-find-text-property-in-string |
1884 | 'org-attributes raw-table) | |
1885 | label (org-find-text-property-in-string | |
1886 | 'org-label raw-table) | |
1887 | longtblp (and attr (stringp attr) | |
1888 | (string-match "\\<longtable\\>" attr)) | |
3ab2c837 BG |
1889 | tblenv (if (and attr (stringp attr) |
1890 | (or (string-match (regexp-quote "table*") attr) | |
1891 | (string-match "\\<multicolumn\\>" attr))) | |
1892 | "table*" "table") | |
1893 | tabular-env | |
1894 | (if (and attr (stringp attr) | |
1895 | (string-match "\\(tabular.\\)" attr)) | |
1896 | (match-string 1 attr) | |
1897 | org-export-latex-tabular-environment) | |
1898 | width (and attr (stringp attr) | |
1899 | (string-match "\\<width=\\([^ \t\n\r]+\\)" attr) | |
1900 | (match-string 1 attr)) | |
8bfe682a | 1901 | align (and attr (stringp attr) |
86fbb8ca | 1902 | (string-match "\\<align=\\([^ \t\n\r]+\\)" attr) |
8bfe682a | 1903 | (match-string 1 attr)) |
3ab2c837 BG |
1904 | floatp (or caption label (string= "table*" tblenv)) |
1905 | placement (if (and attr | |
afe98dfa CD |
1906 | (stringp attr) |
1907 | (string-match "[ \t]*\\<placement=\\(\\S-+\\)" attr)) | |
1908 | (match-string 1 attr) | |
3ab2c837 BG |
1909 | (concat |
1910 | "[" org-latex-default-figure-position "]"))) | |
ed21c5c8 | 1911 | (setq caption (and caption (org-export-latex-fontify-headline caption))) |
8bfe682a CD |
1912 | (setq lines (org-split-string raw-table "\n")) |
1913 | (apply 'delete-region (list beg end)) | |
1914 | (when org-export-table-remove-special-lines | |
1915 | (setq lines (org-table-clean-before-export lines 'maybe-quoted))) | |
1916 | (when org-table-clean-did-remove-column | |
54a0dee5 CD |
1917 | (pop org-table-last-alignment) |
1918 | (pop org-table-last-column-widths)) | |
8bfe682a CD |
1919 | ;; make a formatting string to reflect alignment |
1920 | (setq olines lines) | |
1921 | (while (and (not line-fmt) (setq line (pop olines))) | |
1922 | (unless (string-match "^[ \t]*|-" line) | |
1923 | (setq fields (org-split-string line "[ \t]*|[ \t]*")) | |
1924 | (setq fnum (make-vector (length fields) 0)) | |
1925 | (setq line-fmt | |
1926 | (mapconcat | |
1927 | (lambda (x) | |
1928 | (setq gr (pop org-table-colgroup-info)) | |
1929 | (format "%s%%s%s" | |
1930 | (cond ((eq gr :start) | |
1931 | (prog1 (if colgropen "|" "|") | |
1932 | (setq colgropen t))) | |
1933 | ((eq gr :startend) | |
1934 | (prog1 (if colgropen "|" "|") | |
1935 | (setq colgropen nil))) | |
1936 | (t "")) | |
1937 | (if (memq gr '(:end :startend)) | |
1938 | (progn (setq colgropen nil) "|") | |
1939 | ""))) | |
1940 | fnum "")))) | |
1941 | ;; fix double || in line-fmt | |
1942 | (setq line-fmt (replace-regexp-in-string "||" "|" line-fmt)) | |
1943 | ;; maybe remove the first and last "|" | |
1944 | (when (and (not org-export-latex-tables-column-borders) | |
1945 | (string-match "^\\(|\\)?\\(.+\\)|$" line-fmt)) | |
1946 | (setq line-fmt (match-string 2 line-fmt))) | |
1947 | ;; format alignment | |
1948 | (unless align | |
1949 | (setq align (apply 'format | |
1950 | (cons line-fmt | |
1951 | (mapcar (lambda (x) (if x "r" "l")) | |
1952 | org-table-last-alignment))))) | |
1953 | ;; prepare the table to send to orgtbl-to-latex | |
1954 | (setq lines | |
1955 | (mapcar | |
1956 | (lambda(elem) | |
1957 | (or (and (string-match "[ \t]*|-+" elem) 'hline) | |
3ab2c837 BG |
1958 | (org-split-string |
1959 | (progn (set-text-properties 0 (length elem) nil elem) | |
1960 | (org-trim elem)) "|"))) | |
8bfe682a CD |
1961 | lines)) |
1962 | (when insert | |
1963 | (insert (org-export-latex-protect-string | |
1964 | (concat | |
1965 | (if longtblp | |
1966 | (concat "\\begin{longtable}{" align "}\n") | |
3ab2c837 BG |
1967 | (if floatp |
1968 | (format "\\begin{%s}%s\n" tblenv placement))) | |
ed21c5c8 | 1969 | (if floatp |
8bfe682a | 1970 | (format |
afe98dfa | 1971 | "\\caption%s{%s} %s" |
86fbb8ca | 1972 | (if shortn (concat "[" shortn "]") "") |
afe98dfa CD |
1973 | (or caption "") |
1974 | (if label (format "\\label{%s}" label) ""))) | |
ed21c5c8 | 1975 | (if (and longtblp caption) "\\\\\n" "\n") |
8bfe682a CD |
1976 | (if (and org-export-latex-tables-centered (not longtblp)) |
1977 | "\\begin{center}\n") | |
86fbb8ca | 1978 | (if (not longtblp) |
3ab2c837 BG |
1979 | (format "\\begin{%s}%s{%s}\n" |
1980 | tabular-env | |
1981 | (if width (format "{%s}" width) "") | |
1982 | align)) | |
8bfe682a CD |
1983 | (orgtbl-to-latex |
1984 | lines | |
1985 | `(:tstart nil :tend nil | |
1986 | :hlend ,(if longtblp | |
1987 | (format "\\\\ | |
db55f368 CD |
1988 | \\hline |
1989 | \\endhead | |
1990 | \\hline\\multicolumn{%d}{r}{Continued on next page}\\ | |
1991 | \\endfoot | |
1992 | \\endlastfoot" (length org-table-last-alignment)) | |
8bfe682a | 1993 | nil))) |
3ab2c837 | 1994 | (if (not longtblp) (format "\n\\end{%s}" tabular-env)) |
8bfe682a CD |
1995 | (if longtblp "\n" (if org-export-latex-tables-centered |
1996 | "\n\\end{center}\n" "\n")) | |
1997 | (if longtblp | |
1998 | "\\end{longtable}" | |
3ab2c837 | 1999 | (if floatp (format "\\end{%s}" tblenv))))) |
8bfe682a | 2000 | "\n\n")))))))) |
72a81656 | 2001 | |
ed21c5c8 CD |
2002 | (defun org-export-latex-convert-table.el-table () |
2003 | "Replace table.el table at point with LaTeX code." | |
86fbb8ca | 2004 | (let (tbl caption shortn label line floatp attr align rmlines) |
ed21c5c8 CD |
2005 | (setq line (buffer-substring (point-at-bol) (point-at-eol)) |
2006 | label (org-get-text-property-any 0 'org-label line) | |
2007 | caption (org-get-text-property-any 0 'org-caption line) | |
86fbb8ca | 2008 | shortn (org-get-text-property-any 0 'org-caption-shortn line) |
ed21c5c8 CD |
2009 | attr (org-get-text-property-any 0 'org-attributes line) |
2010 | align (and attr (stringp attr) | |
2011 | (string-match "\\<align=\\([^ \t\n\r,]+\\)" attr) | |
2012 | (match-string 1 attr)) | |
2013 | rmlines (and attr (stringp attr) | |
2014 | (string-match "\\<rmlines\\>" attr)) | |
2015 | floatp (or label caption)) | |
2016 | (and (get-buffer "*org-export-table*") | |
2017 | (kill-buffer (get-buffer "*org-export-table*"))) | |
2018 | (table-generate-source 'latex "*org-export-table*" "caption") | |
2019 | (setq tbl (with-current-buffer "*org-export-table*" | |
2020 | (buffer-string))) | |
2021 | (while (string-match "^%.*\n" tbl) | |
2022 | (setq tbl (replace-match "" t t tbl))) | |
2023 | ;; fix the hlines | |
2024 | (when rmlines | |
2025 | (let ((n 0) lines) | |
2026 | (setq lines (mapcar (lambda (x) | |
2027 | (if (string-match "^\\\\hline$" x) | |
2028 | (progn | |
2029 | (setq n (1+ n)) | |
2030 | (if (= n 2) x nil)) | |
2031 | x)) | |
2032 | (org-split-string tbl "\n"))) | |
2033 | (setq tbl (mapconcat 'identity (delq nil lines) "\n")))) | |
2034 | (when (and align (string-match "\\\\begin{tabular}{.*}" tbl)) | |
2035 | (setq tbl (replace-match (concat "\\begin{tabular}{" align "}") | |
2036 | t t tbl))) | |
2037 | (and (get-buffer "*org-export-table*") | |
2038 | (kill-buffer (get-buffer "*org-export-table*"))) | |
2039 | (beginning-of-line 0) | |
2040 | (while (looking-at "[ \t]*\\(|\\|\\+-\\)") | |
2041 | (delete-region (point) (1+ (point-at-eol)))) | |
2042 | (when org-export-latex-tables-centered | |
2043 | (setq tbl (concat "\\begin{center}\n" tbl "\\end{center}"))) | |
2044 | (when floatp | |
2045 | (setq tbl (concat "\\begin{table}\n" | |
3ab2c837 | 2046 | (format "\\caption%s{%s%s}\n" |
86fbb8ca | 2047 | (if shortn (format "[%s]" shortn) "") |
ed21c5c8 CD |
2048 | (if label (format "\\label{%s}" label) "") |
2049 | (or caption "")) | |
2050 | tbl | |
2051 | "\n\\end{table}\n"))) | |
2052 | (insert (org-export-latex-protect-string tbl)))) | |
2053 | ||
72a81656 CD |
2054 | (defun org-export-latex-fontify () |
2055 | "Convert fontification to LaTeX." | |
2056 | (goto-char (point-min)) | |
2057 | (while (re-search-forward org-emph-re nil t) | |
5dec9555 | 2058 | ;; The match goes one char after the *string*, except at the end of a line |
db9c3fb1 CD |
2059 | (let ((emph (assoc (match-string 3) |
2060 | org-export-latex-emphasis-alist)) | |
0bd48b37 CD |
2061 | (beg (match-beginning 0)) |
2062 | (end (match-end 0)) | |
8bfe682a | 2063 | rpl s) |
c8d0cf5c CD |
2064 | (unless emph |
2065 | (message "`org-export-latex-emphasis-alist' has no entry for formatting triggered by \"%s\"" | |
2066 | (match-string 3))) | |
8bfe682a CD |
2067 | (unless (or (and (get-text-property (- (point) 2) 'org-protected) |
2068 | (not (get-text-property | |
2069 | (- (point) 2) 'org-verbatim-emph))) | |
86fbb8ca CD |
2070 | (equal (char-after (match-beginning 3)) |
2071 | (char-after (1+ (match-beginning 3)))) | |
0bd48b37 CD |
2072 | (save-excursion |
2073 | (goto-char (match-beginning 1)) | |
2074 | (save-match-data | |
2075 | (and (org-at-table-p) | |
2076 | (string-match | |
ed21c5c8 CD |
2077 | "[|\n]" (buffer-substring beg end))))) |
2078 | (and (equal (match-string 3) "+") | |
2079 | (save-match-data | |
2080 | (string-match "\\`-+\\'" (match-string 4))))) | |
8bfe682a | 2081 | (setq s (match-string 4)) |
15841868 | 2082 | (setq rpl (concat (match-string 1) |
c8d0cf5c CD |
2083 | (org-export-latex-emph-format (cadr emph) |
2084 | (match-string 4)) | |
15841868 | 2085 | (match-string 5))) |
db9c3fb1 | 2086 | (if (caddr emph) |
8bfe682a CD |
2087 | (setq rpl (org-export-latex-protect-string rpl)) |
2088 | (save-match-data | |
ed21c5c8 | 2089 | (if (string-match "\\`.?\\(\\\\[a-z]+{\\)\\(.*\\)\\(}\\).?\\'" rpl) |
8bfe682a CD |
2090 | (progn |
2091 | (add-text-properties (match-beginning 1) (match-end 1) | |
2092 | '(org-protected t) rpl) | |
2093 | (add-text-properties (match-beginning 3) (match-end 3) | |
2094 | '(org-protected t) rpl))))) | |
15841868 JW |
2095 | (replace-match rpl t t))) |
2096 | (backward-char))) | |
72a81656 | 2097 | |
c8d0cf5c CD |
2098 | (defun org-export-latex-emph-format (format string) |
2099 | "Format an emphasis string and handle the \\verb special case." | |
3ab2c837 | 2100 | (when (member format '("\\verb" "\\protectedtexttt")) |
c8d0cf5c | 2101 | (save-match-data |
3ab2c837 | 2102 | (if (equal format "\\verb") |
c8d0cf5c CD |
2103 | (let ((ll "~,./?;':\"|!@#%^&-_=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>()[]{}")) |
2104 | (catch 'exit | |
2105 | (loop for i from 0 to (1- (length ll)) do | |
2106 | (if (not (string-match (regexp-quote (substring ll i (1+ i))) | |
2107 | string)) | |
2108 | (progn | |
2109 | (setq format (concat "\\verb" (substring ll i (1+ i)) | |
2110 | "%s" (substring ll i (1+ i)))) | |
2111 | (throw 'exit nil)))))) | |
2112 | (let ((start 0) | |
8d642074 CD |
2113 | (trans '(("\\" . "\\textbackslash{}") |
2114 | ("~" . "\\textasciitilde{}") | |
2115 | ("^" . "\\textasciicircum{}"))) | |
c8d0cf5c CD |
2116 | (rtn "") char) |
2117 | (while (string-match "[\\{}$%&_#~^]" string) | |
2118 | (setq char (match-string 0 string)) | |
2119 | (if (> (match-beginning 0) 0) | |
2120 | (setq rtn (concat rtn (substring string | |
2121 | 0 (match-beginning 0))))) | |
2122 | (setq string (substring string (1+ (match-beginning 0)))) | |
2123 | (setq char (or (cdr (assoc char trans)) (concat "\\" char)) | |
2124 | rtn (concat rtn char))) | |
3ab2c837 BG |
2125 | (setq string (concat rtn string) format "\\texttt{%s}") |
2126 | (while (string-match "--" string) | |
2127 | (setq string (replace-match "-{}-" t t string))))))) | |
8bfe682a | 2128 | (format format string)) |
c8d0cf5c | 2129 | |
72a81656 CD |
2130 | (defun org-export-latex-links () |
2131 | ;; Make sure to use the LaTeX hyperref and graphicx package | |
2132 | ;; or send some warnings. | |
2133 | "Convert links to LaTeX." | |
2134 | (goto-char (point-min)) | |
0bd48b37 | 2135 | (while (re-search-forward org-bracket-link-analytic-regexp++ nil t) |
8bfe682a | 2136 | (org-if-unprotected-1 |
72a81656 | 2137 | (goto-char (match-beginning 0)) |
db9c3fb1 | 2138 | (let* ((re-radio org-export-latex-all-targets-re) |
72a81656 | 2139 | (remove (list (match-beginning 0) (match-end 0))) |
2c3ad40d | 2140 | (raw-path (org-extract-attributes (match-string 3))) |
72a81656 CD |
2141 | (full-raw-path (concat (match-string 1) raw-path)) |
2142 | (desc (match-string 5)) | |
db55f368 CD |
2143 | (type (or (match-string 2) |
2144 | (if (or (file-name-absolute-p raw-path) | |
2145 | (string-match "^\\.\\.?/" raw-path)) | |
2146 | "file"))) | |
0bd48b37 | 2147 | (coderefp (equal type "coderef")) |
db55f368 | 2148 | (caption (org-find-text-property-in-string 'org-caption raw-path)) |
86fbb8ca | 2149 | (shortn (org-find-text-property-in-string 'org-caption-shortn raw-path)) |
c8d0cf5c CD |
2150 | (attr (or (org-find-text-property-in-string 'org-attributes raw-path) |
2151 | (plist-get org-export-latex-options-plist :latex-image-options))) | |
db55f368 | 2152 | (label (org-find-text-property-in-string 'org-label raw-path)) |
86fbb8ca | 2153 | imgp radiop fnc |
72a81656 CD |
2154 | ;; define the path of the link |
2155 | (path (cond | |
0bd48b37 CD |
2156 | ((member type '("coderef")) |
2157 | raw-path) | |
72a81656 CD |
2158 | ((member type '("http" "https" "ftp")) |
2159 | (concat type ":" raw-path)) | |
2160 | ((and re-radio (string-match re-radio raw-path)) | |
33306645 | 2161 | (setq radiop t)) |
72a81656 CD |
2162 | ((equal type "mailto") |
2163 | (concat type ":" raw-path)) | |
2164 | ((equal type "file") | |
0bd48b37 CD |
2165 | (if (and (org-file-image-p |
2166 | (expand-file-name | |
2167 | raw-path) | |
2168 | org-export-latex-inline-image-extensions) | |
c8d0cf5c CD |
2169 | (or (get-text-property 0 'org-no-description |
2170 | raw-path) | |
2171 | (equal desc full-raw-path))) | |
72a81656 CD |
2172 | (setq imgp t) |
2173 | (progn (when (string-match "\\(.+\\)::.+" raw-path) | |
2174 | (setq raw-path (match-string 1 raw-path))) | |
2175 | (if (file-exists-p raw-path) | |
2176 | (concat type "://" (expand-file-name raw-path)) | |
2177 | (concat type "://" (org-export-directory | |
db9c3fb1 | 2178 | :LaTeX org-export-latex-options-plist) |
72a81656 CD |
2179 | raw-path)))))))) |
2180 | ;; process with link inserting | |
2181 | (apply 'delete-region remove) | |
ed21c5c8 | 2182 | (setq caption (and caption (org-export-latex-fontify-headline caption))) |
8bfe682a CD |
2183 | (cond ((and imgp |
2184 | (plist-get org-export-latex-options-plist :inline-images)) | |
2185 | ;; OK, we need to inline an image | |
db55f368 | 2186 | (insert |
86fbb8ca | 2187 | (org-export-latex-format-image raw-path caption label attr shortn))) |
0bd48b37 CD |
2188 | (coderefp |
2189 | (insert (format | |
2190 | (org-export-get-coderef-format path desc) | |
2191 | (cdr (assoc path org-export-code-refs))))) | |
acedf35c | 2192 | (radiop (insert (format org-export-latex-hyperref-format |
621f83e4 CD |
2193 | (org-solidify-link-text raw-path) desc))) |
2194 | ((not type) | |
acedf35c | 2195 | (insert (format org-export-latex-hyperref-format |
c8d0cf5c | 2196 | (org-remove-initial-hash |
54a0dee5 CD |
2197 | (org-solidify-link-text raw-path)) |
2198 | desc))) | |
ed21c5c8 | 2199 | (path |
54a0dee5 CD |
2200 | (when (org-at-table-p) |
2201 | ;; There is a strange problem when we have a link in a table, | |
2202 | ;; ampersands then cause a problem. I think this must be | |
2203 | ;; a LaTeX issue, but we here implement a work-around anyway. | |
2204 | (setq path (org-export-latex-protect-amp path) | |
2205 | desc (org-export-latex-protect-amp desc))) | |
7877f373 | 2206 | (insert |
3ab2c837 BG |
2207 | (if (string-match "%s.*%s" org-export-latex-href-format) |
2208 | (format org-export-latex-href-format path desc) | |
2209 | (format org-export-latex-href-format path)))) | |
86fbb8ca CD |
2210 | |
2211 | ((functionp (setq fnc (nth 2 (assoc type org-link-protocols)))) | |
2212 | ;; The link protocol has a function for formatting the link | |
2213 | (insert | |
2214 | (save-match-data | |
2215 | (funcall fnc (org-link-unescape raw-path) desc 'latex)))) | |
2216 | ||
72a81656 CD |
2217 | (t (insert "\\texttt{" desc "}"))))))) |
2218 | ||
8bfe682a | 2219 | |
86fbb8ca | 2220 | (defun org-export-latex-format-image (path caption label attr &optional shortn) |
8bfe682a | 2221 | "Format the image element, depending on user settings." |
86fbb8ca | 2222 | (let (ind floatp wrapp multicolumnp placement figenv) |
8bfe682a | 2223 | (setq floatp (or caption label)) |
ed21c5c8 | 2224 | (setq ind (org-get-text-property-any 0 'original-indentation path)) |
8bfe682a CD |
2225 | (when (and attr (stringp attr)) |
2226 | (if (string-match "[ \t]*\\<wrap\\>" attr) | |
2227 | (setq wrapp t floatp nil attr (replace-match "" t t attr))) | |
2228 | (if (string-match "[ \t]*\\<float\\>" attr) | |
86fbb8ca CD |
2229 | (setq wrapp nil floatp t attr (replace-match "" t t attr))) |
2230 | (if (string-match "[ \t]*\\<multicolumn\\>" attr) | |
2231 | (setq multicolumnp t attr (replace-match "" t t attr)))) | |
ed21c5c8 | 2232 | |
8bfe682a CD |
2233 | (setq placement |
2234 | (cond | |
2235 | (wrapp "{l}{0.5\\textwidth}") | |
3ab2c837 | 2236 | (floatp (concat "[" org-latex-default-figure-position "]")) |
8bfe682a CD |
2237 | (t ""))) |
2238 | ||
2239 | (when (and attr (stringp attr) | |
2240 | (string-match "[ \t]*\\<placement=\\(\\S-+\\)" attr)) | |
2241 | (setq placement (match-string 1 attr) | |
2242 | attr (replace-match "" t t attr))) | |
2243 | (setq attr (and attr (org-trim attr))) | |
2244 | (when (or (not attr) (= (length attr) 0)) | |
2245 | (setq attr (cond (floatp "width=0.7\\textwidth") | |
2246 | (wrapp "width=0.48\\textwidth") | |
2247 | (t attr)))) | |
2248 | (setq figenv | |
2249 | (cond | |
2250 | (wrapp "\\begin{wrapfigure}%placement | |
2251 | \\centering | |
2252 | \\includegraphics[%attr]{%path} | |
86fbb8ca | 2253 | \\caption%shortn{%labelcmd%caption} |
8bfe682a | 2254 | \\end{wrapfigure}") |
86fbb8ca CD |
2255 | (multicolumnp "\\begin{figure*}%placement |
2256 | \\centering | |
2257 | \\includegraphics[%attr]{%path} | |
3ab2c837 | 2258 | \\caption%shortn{%labelcmd%caption} |
86fbb8ca | 2259 | \\end{figure*}") |
8bfe682a CD |
2260 | (floatp "\\begin{figure}%placement |
2261 | \\centering | |
2262 | \\includegraphics[%attr]{%path} | |
3ab2c837 | 2263 | \\caption%shortn{%labelcmd%caption} |
8bfe682a CD |
2264 | \\end{figure}") |
2265 | (t "\\includegraphics[%attr]{%path}"))) | |
2266 | ||
ed21c5c8 CD |
2267 | |
2268 | (setq figenv (mapconcat 'identity (split-string figenv "\n") | |
2269 | (save-excursion (beginning-of-line 1) | |
2270 | (looking-at "[ \t]*") | |
2271 | (concat "\n" (match-string 0))))) | |
2272 | ||
8bfe682a CD |
2273 | (if (and (not label) (not caption) |
2274 | (string-match "^\\\\caption{.*\n" figenv)) | |
2275 | (setq figenv (replace-match "" t t figenv))) | |
ed21c5c8 CD |
2276 | (org-add-props |
2277 | (org-fill-template | |
2278 | figenv | |
2279 | (list (cons "path" | |
2280 | (if (file-name-absolute-p path) | |
2281 | (expand-file-name path) | |
2282 | path)) | |
2283 | (cons "attr" attr) | |
86fbb8ca | 2284 | (cons "shortn" (if shortn (format "[%s]" shortn) "")) |
ed21c5c8 CD |
2285 | (cons "labelcmd" (if label (format "\\label{%s}" |
2286 | label)"")) | |
2287 | (cons "caption" (or caption "")) | |
2288 | (cons "placement" (or placement "")))) | |
2289 | nil 'original-indentation ind))) | |
8bfe682a | 2290 | |
54a0dee5 CD |
2291 | (defun org-export-latex-protect-amp (s) |
2292 | (while (string-match "\\([^\\\\]\\)\\(&\\)" s) | |
2293 | (setq s (replace-match (concat (match-string 1 s) "\\" (match-string 2 s)) | |
2294 | t t s))) | |
2295 | s) | |
2296 | ||
c8d0cf5c CD |
2297 | (defun org-remove-initial-hash (s) |
2298 | (if (string-match "\\`#" s) | |
2299 | (substring s 1) | |
2300 | s)) | |
db9c3fb1 | 2301 | (defvar org-latex-entities) ; defined below |
71d35b24 | 2302 | (defvar org-latex-entities-regexp) ; defined below |
db9c3fb1 | 2303 | |
c8d0cf5c | 2304 | (defun org-export-latex-preprocess (parameters) |
72a81656 | 2305 | "Clean stuff in the LaTeX export." |
3ab2c837 BG |
2306 | ;; Replace footnotes. |
2307 | (when (plist-get parameters :footnotes) | |
2308 | (goto-char (point-min)) | |
2309 | (let (ref) | |
2310 | (while (setq ref (org-footnote-get-next-reference)) | |
2311 | (let* ((beg (nth 1 ref)) | |
2312 | (lbl (car ref)) | |
2313 | (def (nth 1 (assoc (string-to-number lbl) | |
2314 | (mapcar (lambda (e) (cdr e)) | |
2315 | org-export-footnotes-seen))))) | |
2316 | ;; Fix body for footnotes ending on a link or a list and | |
2317 | ;; remove definition from buffer. | |
2318 | (setq def | |
2319 | (concat def | |
2320 | (if (string-match "ORG-LIST-END-MARKER\\'" def) | |
2321 | "\n" " "))) | |
2322 | (org-footnote-delete-definitions lbl) | |
2323 | ;; Compute string to insert (FNOTE), and protect the outside | |
2324 | ;; macro from further transformation. When footnote at | |
2325 | ;; point is referring to a previously defined footnote, use | |
2326 | ;; \footnotemark. Otherwise, use \footnote. | |
2327 | (let ((fnote (if (member lbl org-export-latex-footmark-seen) | |
2328 | (org-export-latex-protect-string | |
2329 | (format "\\footnotemark[%s]" lbl)) | |
2330 | (push lbl org-export-latex-footmark-seen) | |
2331 | (concat (org-export-latex-protect-string "\\footnote{") | |
2332 | def | |
2333 | (org-export-latex-protect-string "}")))) | |
2334 | ;; Check if another footnote is immediately following. | |
2335 | ;; If so, add a separator in-between. | |
2336 | (sep (org-export-latex-protect-string | |
2337 | (if (save-excursion (goto-char (1- (nth 2 ref))) | |
2338 | (let ((next (org-footnote-get-next-reference))) | |
2339 | (and next (= (nth 1 next) (nth 2 ref))))) | |
2340 | org-export-latex-footnote-separator "")))) | |
2341 | (when (org-on-heading-p) | |
2342 | (setq fnote (concat (org-export-latex-protect-string "\\protect") | |
2343 | fnote))) | |
2344 | ;; Ensure a footnote at column 0 cannot end a list | |
2345 | ;; containing it. | |
2346 | (put-text-property 0 (length fnote) 'original-indentation 1000 fnote) | |
2347 | ;; Replace footnote reference with FNOTE and, maybe, SEP. | |
2348 | ;; `save-excursion' is required if there are two footnotes | |
2349 | ;; in a row. In that case, point would be left at the | |
2350 | ;; beginning of the second one, and | |
2351 | ;; `org-footnote-get-next-reference' would then skip it. | |
2352 | (goto-char beg) | |
2353 | (delete-region beg (nth 2 ref)) | |
2354 | (save-excursion (insert fnote sep))))))) | |
2355 | ||
2356 | ;; Remove footnote section tag for LaTeX | |
2357 | (goto-char (point-min)) | |
2358 | (while (re-search-forward | |
2359 | (concat "^" footnote-section-tag-regexp) nil t) | |
2360 | (org-if-unprotected | |
2361 | (replace-match ""))) | |
2362 | ;; Remove any left-over footnote definition. | |
2363 | (mapc (lambda (fn) (org-footnote-delete-definitions (car fn))) | |
2364 | org-export-footnotes-data) | |
2365 | (mapc (lambda (fn) (org-footnote-delete-definitions fn)) | |
2366 | org-export-latex-footmark-seen) | |
2367 | ||
0b8568f5 | 2368 | ;; Preserve line breaks |
72a81656 CD |
2369 | (goto-char (point-min)) |
2370 | (while (re-search-forward "\\\\\\\\" nil t) | |
2371 | (add-text-properties (match-beginning 0) (match-end 0) | |
2372 | '(org-protected t))) | |
2373 | ||
621f83e4 CD |
2374 | ;; Preserve latex environments |
2375 | (goto-char (point-min)) | |
c8d0cf5c | 2376 | (while (re-search-forward "^[ \t]*\\\\begin{\\([a-zA-Z]+\\*?\\)}" nil t) |
86fbb8ca CD |
2377 | (org-if-unprotected |
2378 | (let* ((start (progn (beginning-of-line) (point))) | |
3ab2c837 BG |
2379 | (end (and (re-search-forward |
2380 | (concat "^[ \t]*\\\\end{" | |
2381 | (regexp-quote (match-string 1)) | |
2382 | "}") nil t) | |
2383 | (point-at-eol)))) | |
2384 | (if end | |
2385 | (add-text-properties start end '(org-protected t)) | |
2386 | (goto-char (point-at-eol)))))) | |
621f83e4 | 2387 | |
0bd48b37 | 2388 | ;; Preserve math snippets |
0bd48b37 CD |
2389 | (let* ((matchers (plist-get org-format-latex-options :matchers)) |
2390 | (re-list org-latex-regexps) | |
2391 | beg end re e m n block off) | |
2392 | ;; Check the different regular expressions | |
2393 | (while (setq e (pop re-list)) | |
2394 | (setq m (car e) re (nth 1 e) n (nth 2 e) | |
2395 | block (if (nth 3 e) "\n\n" "")) | |
2396 | (setq off (if (member m '("$" "$1")) 1 0)) | |
2397 | (when (and (member m matchers) (not (equal m "begin"))) | |
2398 | (goto-char (point-min)) | |
2399 | (while (re-search-forward re nil t) | |
2400 | (setq beg (+ (match-beginning 0) off) end (- (match-end 0) 0)) | |
2401 | (add-text-properties beg end '(org-protected t org-latex-math t)))))) | |
2402 | ||
ed21c5c8 | 2403 | ;; Convert LaTeX to \LaTeX{} and TeX to \TeX{} |
72a81656 | 2404 | (goto-char (point-min)) |
65c439fd | 2405 | (let ((case-fold-search nil)) |
ed21c5c8 CD |
2406 | (while (re-search-forward "\\<\\(\\(La\\)?TeX\\)\\>" nil t) |
2407 | (unless (eq (char-before (match-beginning 1)) ?\\) | |
2408 | (org-if-unprotected-1 | |
2409 | (replace-match (org-export-latex-protect-string | |
2410 | (concat "\\" (match-string 1) | |
2411 | "{}")) t t))))) | |
72a81656 | 2412 | |
b349f79f CD |
2413 | ;; Convert blockquotes |
2414 | (goto-char (point-min)) | |
621f83e4 | 2415 | (while (search-forward "ORG-BLOCKQUOTE-START" nil t) |
c8d0cf5c | 2416 | (org-replace-match-keep-properties "\\begin{quote}" t t)) |
b349f79f | 2417 | (goto-char (point-min)) |
621f83e4 | 2418 | (while (search-forward "ORG-BLOCKQUOTE-END" nil t) |
c8d0cf5c | 2419 | (org-replace-match-keep-properties "\\end{quote}" t t)) |
b349f79f CD |
2420 | |
2421 | ;; Convert verse | |
2422 | (goto-char (point-min)) | |
621f83e4 | 2423 | (while (search-forward "ORG-VERSE-START" nil t) |
c8d0cf5c CD |
2424 | (org-replace-match-keep-properties "\\begin{verse}" t t) |
2425 | (beginning-of-line 2) | |
2426 | (while (and (not (looking-at "[ \t]*ORG-VERSE-END.*")) (not (eobp))) | |
2427 | (when (looking-at "\\([ \t]+\\)\\([^ \t\n]\\)") | |
2428 | (goto-char (match-end 1)) | |
2429 | (org-replace-match-keep-properties | |
2430 | (org-export-latex-protect-string | |
2431 | (concat "\\hspace*{1cm}" (match-string 2))) t t) | |
2432 | (beginning-of-line 1)) | |
8d642074 | 2433 | (if (looking-at "[ \t]*$") |
8bfe682a | 2434 | (insert (org-export-latex-protect-string "\\vspace*{1em}")) |
8d642074 CD |
2435 | (unless (looking-at ".*?[^ \t\n].*?\\\\\\\\[ \t]*$") |
2436 | (end-of-line 1) | |
2437 | (insert "\\\\"))) | |
c8d0cf5c CD |
2438 | (beginning-of-line 2)) |
2439 | (and (looking-at "[ \t]*ORG-VERSE-END.*") | |
2440 | (org-replace-match-keep-properties "\\end{verse}" t t))) | |
2441 | ||
3ab2c837 BG |
2442 | ;; Convert #+INDEX to LaTeX \\index. |
2443 | (goto-char (point-min)) | |
2444 | (let ((case-fold-search t) entry) | |
2445 | (while (re-search-forward | |
2446 | "^[ \t]*#\\+index:[ \t]*\\([^ \t\r\n].*?\\)[ \t]*$" | |
2447 | nil t) | |
2448 | (setq entry | |
2449 | (save-match-data | |
2450 | (org-export-latex-protect-string | |
2451 | (org-export-latex-fontify-headline (match-string 1))))) | |
2452 | (replace-match (format "\\index{%s}" entry) t t))) | |
2453 | ||
c8d0cf5c CD |
2454 | ;; Convert center |
2455 | (goto-char (point-min)) | |
2456 | (while (search-forward "ORG-CENTER-START" nil t) | |
2457 | (org-replace-match-keep-properties "\\begin{center}" t t)) | |
b349f79f | 2458 | (goto-char (point-min)) |
c8d0cf5c CD |
2459 | (while (search-forward "ORG-CENTER-END" nil t) |
2460 | (org-replace-match-keep-properties "\\end{center}" t t)) | |
2461 | ||
2462 | (run-hooks 'org-export-latex-after-blockquotes-hook) | |
b349f79f | 2463 | |
0b8568f5 | 2464 | ;; Convert horizontal rules |
72a81656 | 2465 | (goto-char (point-min)) |
3ab2c837 | 2466 | (while (re-search-forward "^[ \t]*-\\{5,\\}[ \t]*$" nil t) |
0bd48b37 CD |
2467 | (org-if-unprotected |
2468 | (replace-match (org-export-latex-protect-string "\\hrule") t t))) | |
72a81656 | 2469 | |
33306645 | 2470 | ;; Protect LaTeX commands like \command[...]{...} or \command{...} |
ed21c5c8 CD |
2471 | (goto-char (point-min)) |
2472 | (let ((re (concat | |
3ab2c837 | 2473 | "\\\\\\([a-zA-Z]+\\*?\\)" |
ed21c5c8 CD |
2474 | "\\(?:<[^<>\n]*>\\)*" |
2475 | "\\(?:\\[[^][\n]*?\\]\\)*" | |
2476 | "\\(?:<[^<>\n]*>\\)*" | |
2477 | "\\(" (org-create-multibrace-regexp "{" "}" 3) "\\)\\{1,3\\}"))) | |
c8d0cf5c | 2478 | (while (re-search-forward re nil t) |
86fbb8ca | 2479 | (unless (or |
3ab2c837 | 2480 | ;; Check for comment line. |
ed21c5c8 | 2481 | (save-excursion (goto-char (match-beginning 0)) |
86fbb8ca | 2482 | (org-in-indented-comment-line)) |
3ab2c837 BG |
2483 | ;; Check if this is a defined entity, so that is may |
2484 | ;; need conversion. | |
ed21c5c8 | 2485 | (org-entity-get (match-string 1)) |
3ab2c837 BG |
2486 | ;; Do not protect interior of footnotes. Those have |
2487 | ;; already been taken care of earlier in the function. | |
2488 | ;; Yet, keep looking inside them for more commands. | |
2489 | (and (equal (match-string 1) "footnote") | |
2490 | (goto-char (match-end 1)))) | |
8d642074 CD |
2491 | (add-text-properties (match-beginning 0) (match-end 0) |
2492 | '(org-protected t))))) | |
d5098885 | 2493 | |
86fbb8ca CD |
2494 | ;; Special case for \nbsp |
2495 | (goto-char (point-min)) | |
2496 | (while (re-search-forward "\\\\nbsp\\({}\\|\\>\\)" nil t) | |
2497 | (org-if-unprotected | |
2498 | (replace-match (org-export-latex-protect-string "~")))) | |
2499 | ||
db9c3fb1 CD |
2500 | ;; Protect LaTeX entities |
2501 | (goto-char (point-min)) | |
86fbb8ca CD |
2502 | (while (re-search-forward org-latex-entities-regexp nil t) |
2503 | (org-if-unprotected | |
2504 | (add-text-properties (match-beginning 0) (match-end 0) | |
2505 | '(org-protected t)))) | |
db9c3fb1 | 2506 | |
72a81656 CD |
2507 | ;; Replace radio links |
2508 | (goto-char (point-min)) | |
d5098885 | 2509 | (while (re-search-forward |
db9c3fb1 | 2510 | (concat "<<<?" org-export-latex-all-targets-re |
d5098885 | 2511 | ">>>?\\((INVISIBLE)\\)?") nil t) |
8bfe682a | 2512 | (org-if-unprotected-at (+ (match-beginning 0) 2) |
3ab2c837 BG |
2513 | (replace-match |
2514 | (concat | |
2515 | (org-export-latex-protect-string | |
2516 | (format "\\label{%s}" (save-match-data (org-solidify-link-text | |
2517 | (match-string 1))))) | |
2518 | (if (match-string 2) "" (match-string 1))) | |
2519 | t t))) | |
d5098885 | 2520 | |
0b8568f5 | 2521 | ;; Delete @<...> constructs |
0b8568f5 | 2522 | ;; Thanks to Daniel Clemente for this regexp |
4b67ea89 | 2523 | (goto-char (point-min)) |
0b8568f5 | 2524 | (while (re-search-forward "@<\\(?:[^\"\n]\\|\".*\"\\)*?>" nil t) |
0bd48b37 | 2525 | (org-if-unprotected |
3ab2c837 | 2526 | (replace-match "")))) |
72a81656 | 2527 | |
ed21c5c8 | 2528 | (defun org-export-latex-fix-inputenc () |
86fbb8ca | 2529 | "Set the coding system in inputenc to what the buffer is." |
ed21c5c8 CD |
2530 | (let* ((cs buffer-file-coding-system) |
2531 | (opt (or (ignore-errors (latexenc-coding-system-to-inputenc cs)) | |
2532 | "utf8"))) | |
2533 | (when opt | |
2534 | ;; Translate if that is requested | |
2535 | (setq opt (or (cdr (assoc opt org-export-latex-inputenc-alist)) opt)) | |
2536 | ;; find the \usepackage statement and replace the option | |
2537 | (goto-char (point-min)) | |
2538 | (while (re-search-forward "\\\\usepackage\\[\\(AUTO\\)\\]{inputenc}" | |
2539 | nil t) | |
2540 | (goto-char (match-beginning 1)) | |
2541 | (delete-region (match-beginning 1) (match-end 1)) | |
2542 | (insert opt)) | |
2543 | (and buffer-file-name | |
2544 | (save-buffer))))) | |
2545 | ||
db9c3fb1 CD |
2546 | ;;; List handling: |
2547 | ||
2548 | (defun org-export-latex-lists () | |
0bd48b37 | 2549 | "Convert plain text lists in current buffer into LaTeX lists." |
3ab2c837 BG |
2550 | ;; `org-list-end-re' output has changed since preprocess from |
2551 | ;; org-exp.el. Make sure it is taken into account. | |
2552 | (let ((org-list-ending-method | |
2553 | (if (eq org-list-ending-method 'regexp) 'regexp 'both)) | |
2554 | (org-list-end-re "^ORG-LIST-END-MARKER\n")) | |
2555 | (mapc | |
2556 | (lambda (e) | |
2557 | ;; For each type of context allowed for list export (E), find | |
2558 | ;; every list, parse it, delete it and insert resulting | |
2559 | ;; conversion to latex (RES), while keeping the same | |
2560 | ;; `original-indentation' property. | |
2561 | (let (res) | |
2562 | (goto-char (point-min)) | |
2563 | (while (re-search-forward (org-item-beginning-re) nil t) | |
2564 | (when (and (eq (get-text-property (point) 'list-context) e) | |
2565 | (not (get-text-property (point) 'org-example))) | |
2566 | (beginning-of-line) | |
2567 | (setq res | |
2568 | (org-list-to-latex | |
2569 | ;; Narrowing is needed because we're converting | |
2570 | ;; from inner functions to outer ones. | |
2571 | (save-restriction | |
2572 | (narrow-to-region (point) (point-max)) | |
2573 | (org-list-parse-list t)) | |
2574 | org-export-latex-list-parameters)) | |
2575 | ;; Extend previous value of original-indentation to the | |
2576 | ;; whole string | |
2577 | (insert (org-add-props res nil 'original-indentation | |
2578 | (org-find-text-property-in-string | |
2579 | 'original-indentation res))))))) | |
2580 | ;; List of allowed contexts for export, and the default one. | |
2581 | (append org-list-export-context '(nil))))) | |
db9c3fb1 | 2582 | |
db9c3fb1 CD |
2583 | (defconst org-latex-entities |
2584 | '("\\!" | |
2585 | "\\'" | |
2586 | "\\+" | |
2587 | "\\," | |
2588 | "\\-" | |
2589 | "\\:" | |
2590 | "\\;" | |
2591 | "\\<" | |
2592 | "\\=" | |
2593 | "\\>" | |
2594 | "\\Huge" | |
2595 | "\\LARGE" | |
2596 | "\\Large" | |
2597 | "\\Styles" | |
2598 | "\\\\" | |
2599 | "\\`" | |
3ab2c837 | 2600 | "\\\"" |
db9c3fb1 CD |
2601 | "\\addcontentsline" |
2602 | "\\address" | |
2603 | "\\addtocontents" | |
2604 | "\\addtocounter" | |
2605 | "\\addtolength" | |
2606 | "\\addvspace" | |
2607 | "\\alph" | |
2608 | "\\appendix" | |
2609 | "\\arabic" | |
2610 | "\\author" | |
2611 | "\\begin{array}" | |
2612 | "\\begin{center}" | |
2613 | "\\begin{description}" | |
2614 | "\\begin{enumerate}" | |
2615 | "\\begin{eqnarray}" | |
2616 | "\\begin{equation}" | |
2617 | "\\begin{figure}" | |
2618 | "\\begin{flushleft}" | |
2619 | "\\begin{flushright}" | |
2620 | "\\begin{itemize}" | |
2621 | "\\begin{list}" | |
2622 | "\\begin{minipage}" | |
2623 | "\\begin{picture}" | |
2624 | "\\begin{quotation}" | |
2625 | "\\begin{quote}" | |
2626 | "\\begin{tabbing}" | |
2627 | "\\begin{table}" | |
2628 | "\\begin{tabular}" | |
2629 | "\\begin{thebibliography}" | |
2630 | "\\begin{theorem}" | |
2631 | "\\begin{titlepage}" | |
2632 | "\\begin{verbatim}" | |
2633 | "\\begin{verse}" | |
2634 | "\\bf" | |
2635 | "\\bf" | |
2636 | "\\bibitem" | |
2637 | "\\bigskip" | |
2638 | "\\cdots" | |
2639 | "\\centering" | |
2640 | "\\circle" | |
2641 | "\\cite" | |
2642 | "\\cleardoublepage" | |
2643 | "\\clearpage" | |
2644 | "\\cline" | |
2645 | "\\closing" | |
2646 | "\\dashbox" | |
2647 | "\\date" | |
2648 | "\\ddots" | |
2649 | "\\dotfill" | |
2650 | "\\em" | |
2651 | "\\fbox" | |
2652 | "\\flushbottom" | |
2653 | "\\fnsymbol" | |
2654 | "\\footnote" | |
2655 | "\\footnotemark" | |
2656 | "\\footnotesize" | |
2657 | "\\footnotetext" | |
2658 | "\\frac" | |
2659 | "\\frame" | |
2660 | "\\framebox" | |
2661 | "\\hfill" | |
2662 | "\\hline" | |
2663 | "\\hrulespace" | |
2664 | "\\hspace" | |
2665 | "\\huge" | |
2666 | "\\hyphenation" | |
2667 | "\\include" | |
2668 | "\\includeonly" | |
2669 | "\\indent" | |
2670 | "\\input" | |
2671 | "\\it" | |
2672 | "\\kill" | |
2673 | "\\label" | |
2674 | "\\large" | |
2675 | "\\ldots" | |
2676 | "\\line" | |
2677 | "\\linebreak" | |
2678 | "\\linethickness" | |
2679 | "\\listoffigures" | |
2680 | "\\listoftables" | |
2681 | "\\location" | |
2682 | "\\makebox" | |
2683 | "\\maketitle" | |
2684 | "\\mark" | |
2685 | "\\mbox" | |
2686 | "\\medskip" | |
2687 | "\\multicolumn" | |
2688 | "\\multiput" | |
2689 | "\\newcommand" | |
2690 | "\\newcounter" | |
2691 | "\\newenvironment" | |
2692 | "\\newfont" | |
2693 | "\\newlength" | |
2694 | "\\newline" | |
2695 | "\\newpage" | |
2696 | "\\newsavebox" | |
2697 | "\\newtheorem" | |
2698 | "\\nocite" | |
2699 | "\\nofiles" | |
2700 | "\\noindent" | |
2701 | "\\nolinebreak" | |
2702 | "\\nopagebreak" | |
2703 | "\\normalsize" | |
2704 | "\\onecolumn" | |
2705 | "\\opening" | |
2706 | "\\oval" | |
2707 | "\\overbrace" | |
2708 | "\\overline" | |
2709 | "\\pagebreak" | |
2710 | "\\pagenumbering" | |
2711 | "\\pageref" | |
2712 | "\\pagestyle" | |
2713 | "\\par" | |
2714 | "\\parbox" | |
2715 | "\\put" | |
2716 | "\\raggedbottom" | |
2717 | "\\raggedleft" | |
2718 | "\\raggedright" | |
2719 | "\\raisebox" | |
2720 | "\\ref" | |
2721 | "\\rm" | |
2722 | "\\roman" | |
2723 | "\\rule" | |
2724 | "\\savebox" | |
2725 | "\\sc" | |
2726 | "\\scriptsize" | |
2727 | "\\setcounter" | |
2728 | "\\setlength" | |
2729 | "\\settowidth" | |
2730 | "\\sf" | |
2731 | "\\shortstack" | |
2732 | "\\signature" | |
2733 | "\\sl" | |
2734 | "\\small" | |
2735 | "\\smallskip" | |
2736 | "\\sqrt" | |
2737 | "\\tableofcontents" | |
2738 | "\\telephone" | |
2739 | "\\thanks" | |
2740 | "\\thispagestyle" | |
2741 | "\\tiny" | |
2742 | "\\title" | |
2743 | "\\tt" | |
2744 | "\\twocolumn" | |
2745 | "\\typein" | |
2746 | "\\typeout" | |
2747 | "\\underbrace" | |
2748 | "\\underline" | |
2749 | "\\usebox" | |
2750 | "\\usecounter" | |
2751 | "\\value" | |
2752 | "\\vdots" | |
2753 | "\\vector" | |
2754 | "\\verb" | |
2755 | "\\vfill" | |
2756 | "\\vline" | |
2757 | "\\vspace") | |
2758 | "A list of LaTeX commands to be protected when performing conversion.") | |
2759 | ||
71d35b24 CD |
2760 | (defconst org-latex-entities-regexp |
2761 | (let (names rest) | |
2762 | (dolist (x org-latex-entities) | |
8bfe682a | 2763 | (if (string-match "[a-zA-Z]$" x) |
71d35b24 CD |
2764 | (push x names) |
2765 | (push x rest))) | |
2766 | (concat "\\(" (regexp-opt (nreverse names)) "\\>\\)" | |
2767 | "\\|\\(" (regexp-opt (nreverse rest)) "\\)"))) | |
2768 | ||
72a81656 | 2769 | (provide 'org-export-latex) |
c8d0cf5c | 2770 | (provide 'org-latex) |
72a81656 | 2771 | |
5b409b39 | 2772 | |
b349f79f | 2773 | |
c8d0cf5c | 2774 | ;;; org-latex.el ends here |