org-export: Fix expansion of babel calls in included files
[org-mode.git] / contrib / lisp / org-export.el
blobc004fb4a47957fd2a1bf928b2d76d2b4cfbb1d78
1 ;;; org-export.el --- Generic Export Engine For Org
3 ;; Copyright (C) 2012 Free Software Foundation, Inc.
5 ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
6 ;; Keywords: outlines, hypermedia, calendar, wp
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ;;; Commentary:
23 ;; This library implements a generic export engine for Org, built on
24 ;; its syntactical parser: Org Elements.
26 ;; Besides that parser, the generic exporter is made of three distinct
27 ;; parts:
29 ;; - The communication channel consists in a property list, which is
30 ;; created and updated during the process. Its use is to offer
31 ;; every piece of information, would it be about initial environment
32 ;; or contextual data, all in a single place. The exhaustive list
33 ;; of properties is given in "The Communication Channel" section of
34 ;; this file.
36 ;; - The transcoder walks the parse tree, ignores or treat as plain
37 ;; text elements and objects according to export options, and
38 ;; eventually calls back-end specific functions to do the real
39 ;; transcoding, concatenating their return value along the way.
41 ;; - The filter system is activated at the very beginning and the very
42 ;; end of the export process, and each time an element or an object
43 ;; has been converted. It is the entry point to fine-tune standard
44 ;; output from back-end transcoders. See "The Filter System"
45 ;; section for more information.
47 ;; The core function is `org-export-as'. It returns the transcoded
48 ;; buffer as a string.
50 ;; An export back-end is defined with `org-export-define-backend',
51 ;; which sets one mandatory variable: his translation table. Its name
52 ;; is always `org-BACKEND-translate-alist' where BACKEND stands for
53 ;; the name chosen for the back-end. Its value is an alist whose keys
54 ;; are elements and objects types and values translator functions.
55 ;; See function's docstring for more information about translators.
57 ;; Optionally, `org-export-define-backend' can also support specific
58 ;; buffer keywords, OPTION keyword's items and filters. Also refer to
59 ;; function documentation for more information.
61 ;; If the new back-end shares most properties with another one,
62 ;; `org-export-define-derived-backend' can be used to simplify the
63 ;; process.
65 ;; Any back-end can define its own variables. Among them, those
66 ;; customizable should belong to the `org-export-BACKEND' group.
68 ;; Tools for common tasks across back-ends are implemented in the
69 ;; penultimate part of this file. A dispatcher for standard back-ends
70 ;; is provided in the last one.
72 ;;; Code:
74 (eval-when-compile (require 'cl))
75 (require 'org-element)
77 (declare-function org-e-publish "org-e-publish" (project &optional force))
78 (declare-function org-e-publish-all "org-e-publish" (&optional force))
79 (declare-function org-e-publish-current-file "org-e-publish" (&optional force))
80 (declare-function org-e-publish-current-project "org-e-publish"
81 (&optional force))
82 (declare-function org-export-blocks-preprocess "ob-exp")
84 (defvar org-e-publish-project-alist)
85 (defvar org-table-number-fraction)
86 (defvar org-table-number-regexp)
90 ;;; Internal Variables
92 ;; Among internal variables, the most important is
93 ;; `org-export-options-alist'. This variable define the global export
94 ;; options, shared between every exporter, and how they are acquired.
96 (defconst org-export-max-depth 19
97 "Maximum nesting depth for headlines, counting from 0.")
99 (defconst org-export-options-alist
100 '((:author "AUTHOR" nil user-full-name t)
101 (:creator "CREATOR" nil org-export-creator-string)
102 (:date "DATE" nil nil t)
103 (:description "DESCRIPTION" nil nil newline)
104 (:email "EMAIL" nil user-mail-address t)
105 (:exclude-tags "EXCLUDE_TAGS" nil org-export-exclude-tags split)
106 (:headline-levels nil "H" org-export-headline-levels)
107 (:keywords "KEYWORDS" nil nil space)
108 (:language "LANGUAGE" nil org-export-default-language t)
109 (:preserve-breaks nil "\\n" org-export-preserve-breaks)
110 (:section-numbers nil "num" org-export-with-section-numbers)
111 (:select-tags "SELECT_TAGS" nil org-export-select-tags split)
112 (:time-stamp-file nil "timestamp" org-export-time-stamp-file)
113 (:title "TITLE" nil nil space)
114 (:with-archived-trees nil "arch" org-export-with-archived-trees)
115 (:with-author nil "author" org-export-with-author)
116 (:with-clocks nil "c" org-export-with-clocks)
117 (:with-creator nil "creator" org-export-with-creator)
118 (:with-drawers nil "d" org-export-with-drawers)
119 (:with-email nil "email" org-export-with-email)
120 (:with-emphasize nil "*" org-export-with-emphasize)
121 (:with-entities nil "e" org-export-with-entities)
122 (:with-fixed-width nil ":" org-export-with-fixed-width)
123 (:with-footnotes nil "f" org-export-with-footnotes)
124 (:with-inlinetasks nil "inline" org-export-with-inlinetasks)
125 (:with-plannings nil "p" org-export-with-planning)
126 (:with-priority nil "pri" org-export-with-priority)
127 (:with-smart-quotes nil "'" org-export-with-smart-quotes)
128 (:with-special-strings nil "-" org-export-with-special-strings)
129 (:with-statistics-cookies nil "stat" org-export-with-statistics-cookies)
130 (:with-sub-superscript nil "^" org-export-with-sub-superscripts)
131 (:with-toc nil "toc" org-export-with-toc)
132 (:with-tables nil "|" org-export-with-tables)
133 (:with-tags nil "tags" org-export-with-tags)
134 (:with-tasks nil "tasks" org-export-with-tasks)
135 (:with-timestamps nil "<" org-export-with-timestamps)
136 (:with-todo-keywords nil "todo" org-export-with-todo-keywords))
137 "Alist between export properties and ways to set them.
139 The CAR of the alist is the property name, and the CDR is a list
140 like (KEYWORD OPTION DEFAULT BEHAVIOUR) where:
142 KEYWORD is a string representing a buffer keyword, or nil. Each
143 property defined this way can also be set, during subtree
144 export, through an headline property named after the keyword
145 with the \"EXPORT_\" prefix (i.e. DATE keyword and EXPORT_DATE
146 property).
147 OPTION is a string that could be found in an #+OPTIONS: line.
148 DEFAULT is the default value for the property.
149 BEHAVIOUR determine how Org should handle multiple keywords for
150 the same property. It is a symbol among:
151 nil Keep old value and discard the new one.
152 t Replace old value with the new one.
153 `space' Concatenate the values, separating them with a space.
154 `newline' Concatenate the values, separating them with
155 a newline.
156 `split' Split values at white spaces, and cons them to the
157 previous list.
159 KEYWORD and OPTION have precedence over DEFAULT.
161 All these properties should be back-end agnostic. Back-end
162 specific properties are set through `org-export-define-backend'.
163 Properties redefined there have precedence over these.")
165 (defconst org-export-special-keywords '("SETUP_FILE" "OPTIONS")
166 "List of in-buffer keywords that require special treatment.
167 These keywords are not directly associated to a property. The
168 way they are handled must be hard-coded into
169 `org-export--get-inbuffer-options' function.")
171 (defconst org-export-filters-alist
172 '((:filter-bold . org-export-filter-bold-functions)
173 (:filter-babel-call . org-export-filter-babel-call-functions)
174 (:filter-center-block . org-export-filter-center-block-functions)
175 (:filter-clock . org-export-filter-clock-functions)
176 (:filter-code . org-export-filter-code-functions)
177 (:filter-comment . org-export-filter-comment-functions)
178 (:filter-comment-block . org-export-filter-comment-block-functions)
179 (:filter-drawer . org-export-filter-drawer-functions)
180 (:filter-dynamic-block . org-export-filter-dynamic-block-functions)
181 (:filter-entity . org-export-filter-entity-functions)
182 (:filter-example-block . org-export-filter-example-block-functions)
183 (:filter-export-block . org-export-filter-export-block-functions)
184 (:filter-export-snippet . org-export-filter-export-snippet-functions)
185 (:filter-final-output . org-export-filter-final-output-functions)
186 (:filter-fixed-width . org-export-filter-fixed-width-functions)
187 (:filter-footnote-definition . org-export-filter-footnote-definition-functions)
188 (:filter-footnote-reference . org-export-filter-footnote-reference-functions)
189 (:filter-headline . org-export-filter-headline-functions)
190 (:filter-horizontal-rule . org-export-filter-horizontal-rule-functions)
191 (:filter-inline-babel-call . org-export-filter-inline-babel-call-functions)
192 (:filter-inline-src-block . org-export-filter-inline-src-block-functions)
193 (:filter-inlinetask . org-export-filter-inlinetask-functions)
194 (:filter-italic . org-export-filter-italic-functions)
195 (:filter-item . org-export-filter-item-functions)
196 (:filter-keyword . org-export-filter-keyword-functions)
197 (:filter-latex-environment . org-export-filter-latex-environment-functions)
198 (:filter-latex-fragment . org-export-filter-latex-fragment-functions)
199 (:filter-line-break . org-export-filter-line-break-functions)
200 (:filter-link . org-export-filter-link-functions)
201 (:filter-macro . org-export-filter-macro-functions)
202 (:filter-node-property . org-export-filter-node-property-functions)
203 (:filter-paragraph . org-export-filter-paragraph-functions)
204 (:filter-parse-tree . org-export-filter-parse-tree-functions)
205 (:filter-plain-list . org-export-filter-plain-list-functions)
206 (:filter-plain-text . org-export-filter-plain-text-functions)
207 (:filter-planning . org-export-filter-planning-functions)
208 (:filter-property-drawer . org-export-filter-property-drawer-functions)
209 (:filter-quote-block . org-export-filter-quote-block-functions)
210 (:filter-quote-section . org-export-filter-quote-section-functions)
211 (:filter-radio-target . org-export-filter-radio-target-functions)
212 (:filter-section . org-export-filter-section-functions)
213 (:filter-special-block . org-export-filter-special-block-functions)
214 (:filter-src-block . org-export-filter-src-block-functions)
215 (:filter-statistics-cookie . org-export-filter-statistics-cookie-functions)
216 (:filter-strike-through . org-export-filter-strike-through-functions)
217 (:filter-subscript . org-export-filter-subscript-functions)
218 (:filter-superscript . org-export-filter-superscript-functions)
219 (:filter-table . org-export-filter-table-functions)
220 (:filter-table-cell . org-export-filter-table-cell-functions)
221 (:filter-table-row . org-export-filter-table-row-functions)
222 (:filter-target . org-export-filter-target-functions)
223 (:filter-timestamp . org-export-filter-timestamp-functions)
224 (:filter-underline . org-export-filter-underline-functions)
225 (:filter-verbatim . org-export-filter-verbatim-functions)
226 (:filter-verse-block . org-export-filter-verse-block-functions))
227 "Alist between filters properties and initial values.
229 The key of each association is a property name accessible through
230 the communication channel. Its value is a configurable global
231 variable defining initial filters.
233 This list is meant to install user specified filters. Back-end
234 developers may install their own filters using
235 `org-export-define-backend'. Filters defined there will always
236 be prepended to the current list, so they always get applied
237 first.")
239 (defconst org-export-default-inline-image-rule
240 `(("file" .
241 ,(format "\\.%s\\'"
242 (regexp-opt
243 '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm"
244 "xpm" "pbm" "pgm" "ppm") t))))
245 "Default rule for link matching an inline image.
246 This rule applies to links with no description. By default, it
247 will be considered as an inline image if it targets a local file
248 whose extension is either \"png\", \"jpeg\", \"jpg\", \"gif\",
249 \"tiff\", \"tif\", \"xbm\", \"xpm\", \"pbm\", \"pgm\" or \"ppm\".
250 See `org-export-inline-image-p' for more information about
251 rules.")
255 ;;; User-configurable Variables
257 ;; Configuration for the masses.
259 ;; They should never be accessed directly, as their value is to be
260 ;; stored in a property list (cf. `org-export-options-alist').
261 ;; Back-ends will read their value from there instead.
263 (defgroup org-export nil
264 "Options for exporting Org mode files."
265 :tag "Org Export"
266 :group 'org)
268 (defgroup org-export-general nil
269 "General options for export engine."
270 :tag "Org Export General"
271 :group 'org-export)
273 (defcustom org-export-with-archived-trees 'headline
274 "Whether sub-trees with the ARCHIVE tag should be exported.
276 This can have three different values:
277 nil Do not export, pretend this tree is not present.
278 t Do export the entire tree.
279 `headline' Only export the headline, but skip the tree below it.
281 This option can also be set with the #+OPTIONS line,
282 e.g. \"arch:nil\"."
283 :group 'org-export-general
284 :type '(choice
285 (const :tag "Not at all" nil)
286 (const :tag "Headline only" 'headline)
287 (const :tag "Entirely" t)))
289 (defcustom org-export-with-author t
290 "Non-nil means insert author name into the exported file.
291 This option can also be set with the #+OPTIONS line,
292 e.g. \"author:nil\"."
293 :group 'org-export-general
294 :type 'boolean)
296 (defcustom org-export-with-clocks nil
297 "Non-nil means export CLOCK keywords.
298 This option can also be set with the #+OPTIONS line,
299 e.g. \"c:t\"."
300 :group 'org-export-general
301 :type 'boolean)
303 (defcustom org-export-with-creator 'comment
304 "Non-nil means the postamble should contain a creator sentence.
306 The sentence can be set in `org-export-creator-string' and
307 defaults to \"Generated by Org mode XX in Emacs XXX.\".
309 If the value is `comment' insert it as a comment."
310 :group 'org-export-general
311 :type '(choice
312 (const :tag "No creator sentence" nil)
313 (const :tag "Sentence as a comment" 'comment)
314 (const :tag "Insert the sentence" t)))
316 (defcustom org-export-creator-string
317 (format "Generated by Org mode %s in Emacs %s."
318 (if (fboundp 'org-version) (org-version) "(Unknown)")
319 emacs-version)
320 "String to insert at the end of the generated document."
321 :group 'org-export-general
322 :type '(string :tag "Creator string"))
324 (defcustom org-export-with-drawers t
325 "Non-nil means export contents of standard drawers.
327 When t, all drawers are exported. This may also be a list of
328 drawer names to export. This variable doesn't apply to
329 properties drawers.
331 This option can also be set with the #+OPTIONS line,
332 e.g. \"d:nil\"."
333 :group 'org-export-general
334 :type '(choice
335 (const :tag "All drawers" t)
336 (const :tag "None" nil)
337 (repeat :tag "Selected drawers"
338 (string :tag "Drawer name"))))
340 (defcustom org-export-with-email nil
341 "Non-nil means insert author email into the exported file.
342 This option can also be set with the #+OPTIONS line,
343 e.g. \"email:t\"."
344 :group 'org-export-general
345 :type 'boolean)
347 (defcustom org-export-with-emphasize t
348 "Non-nil means interpret *word*, /word/, and _word_ as emphasized text.
350 If the export target supports emphasizing text, the word will be
351 typeset in bold, italic, or underlined, respectively. Not all
352 export backends support this.
354 This option can also be set with the #+OPTIONS line, e.g. \"*:nil\"."
355 :group 'org-export-general
356 :type 'boolean)
358 (defcustom org-export-exclude-tags '("noexport")
359 "Tags that exclude a tree from export.
361 All trees carrying any of these tags will be excluded from
362 export. This is without condition, so even subtrees inside that
363 carry one of the `org-export-select-tags' will be removed.
365 This option can also be set with the #+EXCLUDE_TAGS: keyword."
366 :group 'org-export-general
367 :type '(repeat (string :tag "Tag")))
369 (defcustom org-export-with-fixed-width t
370 "Non-nil means lines starting with \":\" will be in fixed width font.
372 This can be used to have pre-formatted text, fragments of code
373 etc. For example:
374 : ;; Some Lisp examples
375 : (while (defc cnt)
376 : (ding))
377 will be looking just like this in also HTML. See also the QUOTE
378 keyword. Not all export backends support this.
380 This option can also be set with the #+OPTIONS line, e.g. \"::nil\"."
381 :group 'org-export-translation
382 :type 'boolean)
384 (defcustom org-export-with-footnotes t
385 "Non-nil means Org footnotes should be exported.
386 This option can also be set with the #+OPTIONS line,
387 e.g. \"f:nil\"."
388 :group 'org-export-general
389 :type 'boolean)
391 (defcustom org-export-headline-levels 3
392 "The last level which is still exported as a headline.
394 Inferior levels will produce itemize lists when exported.
396 This option can also be set with the #+OPTIONS line, e.g. \"H:2\"."
397 :group 'org-export-general
398 :type 'integer)
400 (defcustom org-export-default-language "en"
401 "The default language for export and clocktable translations, as a string.
402 This may have an association in
403 `org-clock-clocktable-language-setup'."
404 :group 'org-export-general
405 :type '(string :tag "Language"))
407 (defcustom org-export-preserve-breaks nil
408 "Non-nil means preserve all line breaks when exporting.
410 Normally, in HTML output paragraphs will be reformatted.
412 This option can also be set with the #+OPTIONS line,
413 e.g. \"\\n:t\"."
414 :group 'org-export-general
415 :type 'boolean)
417 (defcustom org-export-with-entities t
418 "Non-nil means interpret entities when exporting.
420 For example, HTML export converts \\alpha to &alpha; and \\AA to
421 &Aring;.
423 For a list of supported names, see the constant `org-entities'
424 and the user option `org-entities-user'.
426 This option can also be set with the #+OPTIONS line,
427 e.g. \"e:nil\"."
428 :group 'org-export-general
429 :type 'boolean)
431 (defcustom org-export-with-inlinetasks t
432 "Non-nil means inlinetasks should be exported.
433 This option can also be set with the #+OPTIONS line,
434 e.g. \"inline:nil\"."
435 :group 'org-export-general
436 :type 'boolean)
438 (defcustom org-export-with-planning nil
439 "Non-nil means include planning info in export.
440 This option can also be set with the #+OPTIONS: line,
441 e.g. \"p:t\"."
442 :group 'org-export-general
443 :type 'boolean)
445 (defcustom org-export-with-priority nil
446 "Non-nil means include priority cookies in export.
447 This option can also be set with the #+OPTIONS line,
448 e.g. \"pri:t\"."
449 :group 'org-export-general
450 :type 'boolean)
452 (defcustom org-export-with-section-numbers t
453 "Non-nil means add section numbers to headlines when exporting.
455 When set to an integer n, numbering will only happen for
456 headlines whose relative level is higher or equal to n.
458 This option can also be set with the #+OPTIONS line,
459 e.g. \"num:t\"."
460 :group 'org-export-general
461 :type 'boolean)
463 (defcustom org-export-select-tags '("export")
464 "Tags that select a tree for export.
466 If any such tag is found in a buffer, all trees that do not carry
467 one of these tags will be ignored during export. Inside trees
468 that are selected like this, you can still deselect a subtree by
469 tagging it with one of the `org-export-exclude-tags'.
471 This option can also be set with the #+SELECT_TAGS: keyword."
472 :group 'org-export-general
473 :type '(repeat (string :tag "Tag")))
475 (defcustom org-export-with-smart-quotes nil
476 "Non-nil means activate smart quotes during export.
477 This option can also be set with the #+OPTIONS: line,
478 e.g. \"':t\"."
479 :group 'org-export-general
480 :type 'boolean)
482 (defcustom org-export-with-special-strings t
483 "Non-nil means interpret \"\\-\", \"--\" and \"---\" for export.
485 When this option is turned on, these strings will be exported as:
487 Org HTML LaTeX UTF-8
488 -----+----------+--------+-------
489 \\- &shy; \\-
490 -- &ndash; -- –
491 --- &mdash; --- —
492 ... &hellip; \\ldots …
494 This option can also be set with the #+OPTIONS line,
495 e.g. \"-:nil\"."
496 :group 'org-export-general
497 :type 'boolean)
499 (defcustom org-export-with-statistics-cookies t
500 "Non-nil means include statistics cookies in export.
501 This option can also be set with the #+OPTIONS: line,
502 e.g. \"stat:nil\""
503 :group 'org-export-general
504 :type 'boolean)
506 (defcustom org-export-with-sub-superscripts t
507 "Non-nil means interpret \"_\" and \"^\" for export.
509 When this option is turned on, you can use TeX-like syntax for
510 sub- and superscripts. Several characters after \"_\" or \"^\"
511 will be considered as a single item - so grouping with {} is
512 normally not needed. For example, the following things will be
513 parsed as single sub- or superscripts.
515 10^24 or 10^tau several digits will be considered 1 item.
516 10^-12 or 10^-tau a leading sign with digits or a word
517 x^2-y^3 will be read as x^2 - y^3, because items are
518 terminated by almost any nonword/nondigit char.
519 x_{i^2} or x^(2-i) braces or parenthesis do grouping.
521 Still, ambiguity is possible - so when in doubt use {} to enclose
522 the sub/superscript. If you set this variable to the symbol
523 `{}', the braces are *required* in order to trigger
524 interpretations as sub/superscript. This can be helpful in
525 documents that need \"_\" frequently in plain text.
527 This option can also be set with the #+OPTIONS line,
528 e.g. \"^:nil\"."
529 :group 'org-export-general
530 :type '(choice
531 (const :tag "Interpret them" t)
532 (const :tag "Curly brackets only" {})
533 (const :tag "Do not interpret them" nil)))
535 (defcustom org-export-with-toc t
536 "Non-nil means create a table of contents in exported files.
538 The TOC contains headlines with levels up
539 to`org-export-headline-levels'. When an integer, include levels
540 up to N in the toc, this may then be different from
541 `org-export-headline-levels', but it will not be allowed to be
542 larger than the number of headline levels. When nil, no table of
543 contents is made.
545 This option can also be set with the #+OPTIONS line,
546 e.g. \"toc:nil\" or \"toc:3\"."
547 :group 'org-export-general
548 :type '(choice
549 (const :tag "No Table of Contents" nil)
550 (const :tag "Full Table of Contents" t)
551 (integer :tag "TOC to level")))
553 (defcustom org-export-with-tables t
554 "If non-nil, lines starting with \"|\" define a table.
555 For example:
557 | Name | Address | Birthday |
558 |-------------+----------+-----------|
559 | Arthur Dent | England | 29.2.2100 |
561 This option can also be set with the #+OPTIONS line, e.g. \"|:nil\"."
562 :group 'org-export-general
563 :type 'boolean)
565 (defcustom org-export-with-tags t
566 "If nil, do not export tags, just remove them from headlines.
568 If this is the symbol `not-in-toc', tags will be removed from
569 table of contents entries, but still be shown in the headlines of
570 the document.
572 This option can also be set with the #+OPTIONS line,
573 e.g. \"tags:nil\"."
574 :group 'org-export-general
575 :type '(choice
576 (const :tag "Off" nil)
577 (const :tag "Not in TOC" not-in-toc)
578 (const :tag "On" t)))
580 (defcustom org-export-with-tasks t
581 "Non-nil means include TODO items for export.
582 This may have the following values:
583 t include tasks independent of state.
584 todo include only tasks that are not yet done.
585 done include only tasks that are already done.
586 nil remove all tasks before export
587 list of keywords keep only tasks with these keywords"
588 :group 'org-export-general
589 :type '(choice
590 (const :tag "All tasks" t)
591 (const :tag "No tasks" nil)
592 (const :tag "Not-done tasks" todo)
593 (const :tag "Only done tasks" done)
594 (repeat :tag "Specific TODO keywords"
595 (string :tag "Keyword"))))
597 (defcustom org-export-time-stamp-file t
598 "Non-nil means insert a time stamp into the exported file.
599 The time stamp shows when the file was created.
601 This option can also be set with the #+OPTIONS line,
602 e.g. \"timestamp:nil\"."
603 :group 'org-export-general
604 :type 'boolean)
606 (defcustom org-export-with-timestamps t
607 "Non nil means allow timestamps in export.
609 It can be set to `active', `inactive', t or nil, in order to
610 export, respectively, only active timestamps, only inactive ones,
611 all of them or none.
613 This option can also be set with the #+OPTIONS line, e.g.
614 \"<:nil\"."
615 :group 'org-export-general
616 :type '(choice
617 (const :tag "All timestamps" t)
618 (const :tag "Only active timestamps" active)
619 (const :tag "Only inactive timestamps" inactive)
620 (const :tag "No timestamp" nil)))
622 (defcustom org-export-with-todo-keywords t
623 "Non-nil means include TODO keywords in export.
624 When nil, remove all these keywords from the export."
625 :group 'org-export-general
626 :type 'boolean)
628 (defcustom org-export-allow-BIND 'confirm
629 "Non-nil means allow #+BIND to define local variable values for export.
630 This is a potential security risk, which is why the user must
631 confirm the use of these lines."
632 :group 'org-export-general
633 :type '(choice
634 (const :tag "Never" nil)
635 (const :tag "Always" t)
636 (const :tag "Ask a confirmation for each file" confirm)))
638 (defcustom org-export-snippet-translation-alist nil
639 "Alist between export snippets back-ends and exporter back-ends.
641 This variable allows to provide shortcuts for export snippets.
643 For example, with a value of '\(\(\"h\" . \"e-html\"\)\), the
644 HTML back-end will recognize the contents of \"@@h:<b>@@\" as
645 HTML code while every other back-end will ignore it."
646 :group 'org-export-general
647 :type '(repeat
648 (cons
649 (string :tag "Shortcut")
650 (string :tag "Back-end"))))
652 (defcustom org-export-coding-system nil
653 "Coding system for the exported file."
654 :group 'org-export-general
655 :type 'coding-system)
657 (defcustom org-export-copy-to-kill-ring t
658 "Non-nil means exported stuff will also be pushed onto the kill ring."
659 :group 'org-export-general
660 :type 'boolean)
662 (defcustom org-export-initial-scope 'buffer
663 "The initial scope when exporting with `org-export-dispatch'.
664 This variable can be either set to `buffer' or `subtree'."
665 :group 'org-export-general
666 :type '(choice
667 (const :tag "Export current buffer" 'buffer)
668 (const :tag "Export current subtree" 'subtree)))
670 (defcustom org-export-show-temporary-export-buffer t
671 "Non-nil means show buffer after exporting to temp buffer.
672 When Org exports to a file, the buffer visiting that file is ever
673 shown, but remains buried. However, when exporting to
674 a temporary buffer, that buffer is popped up in a second window.
675 When this variable is nil, the buffer remains buried also in
676 these cases."
677 :group 'org-export-general
678 :type 'boolean)
680 (defcustom org-export-dispatch-use-expert-ui nil
681 "Non-nil means using a non-intrusive `org-export-dispatch'.
682 In that case, no help buffer is displayed. Though, an indicator
683 for current export scope is added to the prompt (\"b\" when
684 output is restricted to body only, \"s\" when it is restricted to
685 the current subtree, \"v\" when only visible elements are
686 considered for export and \"f\" when publishing functions should
687 be passed the FORCE argument). Also, \[?] allows to switch back
688 to standard mode."
689 :group 'org-export-general
690 :type 'boolean)
694 ;;; Defining New Back-ends
696 ;; `org-export-define-backend' is the standard way to define an export
697 ;; back-end. It allows to specify translators, filters, buffer
698 ;; options and a menu entry. If the new back-end shares translators
699 ;; with another back-end, `org-export-define-derived-backend' may be
700 ;; used instead.
702 ;; Eventually `org-export-barf-if-invalid-backend' returns an error
703 ;; when a given back-end hasn't been registered yet.
705 (defmacro org-export-define-backend (backend translators &rest body)
706 "Define a new back-end BACKEND.
708 TRANSLATORS is an alist between object or element types and
709 functions handling them.
711 These functions should return a string without any trailing
712 space, or nil. They must accept three arguments: the object or
713 element itself, its contents or nil when it isn't recursive and
714 the property list used as a communication channel.
716 Contents, when not nil, are stripped from any global indentation
717 \(although the relative one is preserved). They also always end
718 with a single newline character.
720 If, for a given type, no function is found, that element or
721 object type will simply be ignored, along with any blank line or
722 white space at its end. The same will happen if the function
723 returns the nil value. If that function returns the empty
724 string, the type will be ignored, but the blank lines or white
725 spaces will be kept.
727 In addition to element and object types, one function can be
728 associated to the `template' symbol and another one to the
729 `plain-text' symbol.
731 The former returns the final transcoded string, and can be used
732 to add a preamble and a postamble to document's body. It must
733 accept two arguments: the transcoded string and the property list
734 containing export options.
736 The latter, when defined, is to be called on every text not
737 recognized as an element or an object. It must accept two
738 arguments: the text string and the information channel. It is an
739 appropriate place to protect special chars relative to the
740 back-end.
742 BODY can start with pre-defined keyword arguments. The following
743 keywords are understood:
745 :export-block
747 String, or list of strings, representing block names that
748 will not be parsed. This is used to specify blocks that will
749 contain raw code specific to the back-end. These blocks
750 still have to be handled by the relative `export-block' type
751 translator.
753 :filters-alist
755 Alist between filters and function, or list of functions,
756 specific to the back-end. See `org-export-filters-alist' for
757 a list of all allowed filters. Filters defined here
758 shouldn't make a back-end test, as it may prevent back-ends
759 derived from this one to behave properly.
761 :menu-entry
763 Menu entry for the export dispatcher. It should be a list
764 like:
766 \(KEY DESCRIPTION ACTION-OR-MENU)
768 where :
770 KEY is a free character selecting the back-end.
771 DESCRIPTION is a string naming the back-end.
772 ACTION-OR-MENU is either a function or an alist.
774 If it is an action, it will be called with three arguments:
775 SUBTREEP, VISIBLE-ONLY and BODY-ONLY. See `org-export-as'
776 for further explanations.
778 If it is an alist, associations should follow the
779 pattern:
781 \(KEY DESCRIPTION ACTION)
783 where KEY, DESCRIPTION and ACTION are described above.
785 Valid values include:
787 \(?m \"My Special Back-end\" my-special-export-function)
791 \(?l \"Export to LaTeX\"
792 \((?b \"TEX (buffer)\" org-e-latex-export-as-latex)
793 \(?l \"TEX (file)\" org-e-latex-export-to-latex)
794 \(?p \"PDF file\" org-e-latex-export-to-pdf)
795 \(?o \"PDF file and open\"
796 \(lambda (subtree visible body-only)
797 \(org-open-file
798 \(org-e-latex-export-to-pdf subtree visible body-only))))))
800 :options-alist
802 Alist between back-end specific properties introduced in
803 communication channel and how their value are acquired. See
804 `org-export-options-alist' for more information about
805 structure of the values."
806 (declare (debug (&define name sexp [&rest [keywordp sexp]] defbody))
807 (indent 1))
808 (let (export-block filters menu-entry options)
809 (while (keywordp (car body))
810 (case (pop body)
811 (:export-block (let ((names (pop body)))
812 (setq export-block
813 (if (consp names) (mapcar 'upcase names)
814 (list (upcase names))))))
815 (:filters-alist (setq filters (pop body)))
816 (:menu-entry (setq menu-entry (pop body)))
817 (:options-alist (setq options (pop body)))
818 (t (pop body))))
819 `(progn
820 ;; Define translators.
821 (defvar ,(intern (format "org-%s-translate-alist" backend)) ',translators
822 "Alist between element or object types and translators.")
823 ;; Define options.
824 ,(when options
825 `(defconst ,(intern (format "org-%s-options-alist" backend)) ',options
826 ,(format "Alist between %s export properties and ways to set them.
827 See `org-export-options-alist' for more information on the
828 structure of the values."
829 backend)))
830 ;; Define filters.
831 ,(when filters
832 `(defconst ,(intern (format "org-%s-filters-alist" backend)) ',filters
833 "Alist between filters keywords and back-end specific filters.
834 See `org-export-filters-alist' for more information."))
835 ;; Tell parser to not parse EXPORT-BLOCK blocks.
836 ,(when export-block
837 `(mapc
838 (lambda (name)
839 (add-to-list 'org-element-block-name-alist
840 `(,name . org-element-export-block-parser)))
841 ',export-block))
842 ;; Add an entry for back-end in `org-export-dispatch'.
843 ,(when menu-entry
844 `(unless (assq (car ',menu-entry) org-export-dispatch-menu-entries)
845 (add-to-list 'org-export-dispatch-menu-entries ',menu-entry)))
846 ;; Splice in the body, if any.
847 ,@body)))
849 (defmacro org-export-define-derived-backend (child parent &rest body)
850 "Create a new back-end as a variant of an existing one.
852 CHILD is the name of the derived back-end. PARENT is the name of
853 the parent back-end.
855 BODY can start with pre-defined keyword arguments. The following
856 keywords are understood:
858 :export-block
860 String, or list of strings, representing block names that
861 will not be parsed. This is used to specify blocks that will
862 contain raw code specific to the back-end. These blocks
863 still have to be handled by the relative `export-block' type
864 translator.
866 :filters-alist
868 Alist of filters that will overwrite or complete filters
869 defined in PARENT back-end. See `org-export-filters-alist'
870 for a list of allowed filters.
872 :menu-entry
874 Menu entry for the export dispatcher. See
875 `org-export-define-backend' for more information about the
876 expected value.
878 :options-alist
880 Alist of back-end specific properties that will overwrite or
881 complete those defined in PARENT back-end. Refer to
882 `org-export-options-alist' for more information about
883 structure of the values.
885 :sub-menu-entry
887 Append entries to an existing menu in the export dispatcher.
888 The associated value should be a list whose CAR is the
889 character selecting the menu to expand and CDR a list of
890 entries following the pattern:
892 \(KEY DESCRIPTION ACTION)
894 where KEY is a free character triggering the action,
895 DESCRIPTION is a string defining the action, and ACTION is
896 a function that will be called with three arguments:
897 SUBTREEP, VISIBLE-ONLY and BODY-ONLY. See `org-export-as'
898 for further explanations.
900 Valid values include:
902 \(?l (?P \"As PDF file (Beamer)\" org-e-beamer-export-to-pdf)
903 \(?O \"As PDF file and open (Beamer)\"
904 \(lambda (s v b)
905 \(org-open-file (org-e-beamer-export-to-pdf s v b)))))
907 :translate-alist
909 Alist of element and object types and transcoders that will
910 overwrite or complete transcode table from PARENT back-end.
911 Refer to `org-export-define-backend' for detailed information
912 about transcoders.
914 As an example, here is how one could define \"my-latex\" back-end
915 as a variant of `e-latex' back-end with a custom template
916 function:
918 \(org-export-define-derived-backend my-latex e-latex
919 :translate-alist ((template . my-latex-template-fun)))
921 The back-end could then be called with, for example:
923 \(org-export-to-buffer 'my-latex \"*Test my-latex*\")"
924 (declare (debug (&define name sexp [&rest [keywordp sexp]] def-body))
925 (indent 2))
926 (let (export-block filters menu-entry options sub-menu-entry translate)
927 (while (keywordp (car body))
928 (case (pop body)
929 (:export-block (let ((names (pop body)))
930 (setq export-block
931 (if (consp names) (mapcar 'upcase names)
932 (list (upcase names))))))
933 (:filters-alist (setq filters (pop body)))
934 (:menu-entry (setq menu-entry (pop body)))
935 (:options-alist (setq options (pop body)))
936 (:sub-menu-entry (setq sub-menu-entry (pop body)))
937 (:translate-alist (setq translate (pop body)))
938 (t (pop body))))
939 `(progn
940 ;; Tell parser to not parse EXPORT-BLOCK blocks.
941 ,(when export-block
942 `(mapc
943 (lambda (name)
944 (add-to-list 'org-element-block-name-alist
945 `(,name . org-element-export-block-parser)))
946 ',export-block))
947 ;; Define filters.
948 ,(let ((parent-filters (intern (format "org-%s-filters-alist" parent))))
949 (when (or (boundp parent-filters) filters)
950 `(defconst ,(intern (format "org-%s-filters-alist" child))
951 ',(append filters
952 (and (boundp parent-filters)
953 (copy-sequence (symbol-value parent-filters))))
954 "Alist between filters keywords and back-end specific filters.
955 See `org-export-filters-alist' for more information.")))
956 ;; Define options.
957 ,(let ((parent-options (intern (format "org-%s-options-alist" parent))))
958 (when (or (boundp parent-options) options)
959 `(defconst ,(intern (format "org-%s-options-alist" child))
960 ',(append options
961 (and (boundp parent-options)
962 (copy-sequence (symbol-value parent-options))))
963 ,(format "Alist between %s export properties and ways to set them.
964 See `org-export-options-alist' for more information on the
965 structure of the values."
966 child))))
967 ;; Define translators.
968 (defvar ,(intern (format "org-%s-translate-alist" child))
969 ',(append translate
970 (copy-sequence
971 (symbol-value
972 (intern (format "org-%s-translate-alist" parent)))))
973 "Alist between element or object types and translators.")
974 ;; Add an entry for back-end in `org-export-dispatch'.
975 ,(when menu-entry
976 `(unless (assq (car ',menu-entry) org-export-dispatch-menu-entries)
977 (add-to-list 'org-export-dispatch-menu-entries ',menu-entry)))
978 ,(when sub-menu-entry
979 (let ((menu (nth 2 (assq (car sub-menu-entry)
980 org-export-dispatch-menu-entries))))
981 (when menu `(nconc ',menu
982 ',(org-remove-if (lambda (e) (member e menu))
983 (cdr sub-menu-entry))))))
984 ;; Splice in the body, if any.
985 ,@body)))
987 (defun org-export-barf-if-invalid-backend (backend)
988 "Signal an error if BACKEND isn't defined."
989 (unless (boundp (intern (format "org-%s-translate-alist" backend)))
990 (error "Unknown \"%s\" back-end: Aborting export" backend)))
994 ;;; The Communication Channel
996 ;; During export process, every function has access to a number of
997 ;; properties. They are of two types:
999 ;; 1. Environment options are collected once at the very beginning of
1000 ;; the process, out of the original buffer and configuration.
1001 ;; Collecting them is handled by `org-export-get-environment'
1002 ;; function.
1004 ;; Most environment options are defined through the
1005 ;; `org-export-options-alist' variable.
1007 ;; 2. Tree properties are extracted directly from the parsed tree,
1008 ;; just before export, by `org-export-collect-tree-properties'.
1010 ;; Here is the full list of properties available during transcode
1011 ;; process, with their category and their value type.
1013 ;; + `:author' :: Author's name.
1014 ;; - category :: option
1015 ;; - type :: string
1017 ;; + `:back-end' :: Current back-end used for transcoding.
1018 ;; - category :: tree
1019 ;; - type :: symbol
1021 ;; + `:creator' :: String to write as creation information.
1022 ;; - category :: option
1023 ;; - type :: string
1025 ;; + `:date' :: String to use as date.
1026 ;; - category :: option
1027 ;; - type :: string
1029 ;; + `:description' :: Description text for the current data.
1030 ;; - category :: option
1031 ;; - type :: string
1033 ;; + `:email' :: Author's email.
1034 ;; - category :: option
1035 ;; - type :: string
1037 ;; + `:exclude-tags' :: Tags for exclusion of subtrees from export
1038 ;; process.
1039 ;; - category :: option
1040 ;; - type :: list of strings
1042 ;; + `:exported-data' :: Hash table used for memoizing
1043 ;; `org-export-data'.
1044 ;; - category :: tree
1045 ;; - type :: hash table
1047 ;; + `:footnote-definition-alist' :: Alist between footnote labels and
1048 ;; their definition, as parsed data. Only non-inlined footnotes
1049 ;; are represented in this alist. Also, every definition isn't
1050 ;; guaranteed to be referenced in the parse tree. The purpose of
1051 ;; this property is to preserve definitions from oblivion
1052 ;; (i.e. when the parse tree comes from a part of the original
1053 ;; buffer), it isn't meant for direct use in a back-end. To
1054 ;; retrieve a definition relative to a reference, use
1055 ;; `org-export-get-footnote-definition' instead.
1056 ;; - category :: option
1057 ;; - type :: alist (STRING . LIST)
1059 ;; + `:headline-levels' :: Maximum level being exported as an
1060 ;; headline. Comparison is done with the relative level of
1061 ;; headlines in the parse tree, not necessarily with their
1062 ;; actual level.
1063 ;; - category :: option
1064 ;; - type :: integer
1066 ;; + `:headline-offset' :: Difference between relative and real level
1067 ;; of headlines in the parse tree. For example, a value of -1
1068 ;; means a level 2 headline should be considered as level
1069 ;; 1 (cf. `org-export-get-relative-level').
1070 ;; - category :: tree
1071 ;; - type :: integer
1073 ;; + `:headline-numbering' :: Alist between headlines and their
1074 ;; numbering, as a list of numbers
1075 ;; (cf. `org-export-get-headline-number').
1076 ;; - category :: tree
1077 ;; - type :: alist (INTEGER . LIST)
1079 ;; + `:id-alist' :: Alist between ID strings and destination file's
1080 ;; path, relative to current directory. It is used by
1081 ;; `org-export-resolve-id-link' to resolve ID links targeting an
1082 ;; external file.
1083 ;; - category :: option
1084 ;; - type :: alist (STRING . STRING)
1086 ;; + `:ignore-list' :: List of elements and objects that should be
1087 ;; ignored during export.
1088 ;; - category :: tree
1089 ;; - type :: list of elements and objects
1091 ;; + `:input-file' :: Full path to input file, if any.
1092 ;; - category :: option
1093 ;; - type :: string or nil
1095 ;; + `:keywords' :: List of keywords attached to data.
1096 ;; - category :: option
1097 ;; - type :: string
1099 ;; + `:language' :: Default language used for translations.
1100 ;; - category :: option
1101 ;; - type :: string
1103 ;; + `:parse-tree' :: Whole parse tree, available at any time during
1104 ;; transcoding.
1105 ;; - category :: option
1106 ;; - type :: list (as returned by `org-element-parse-buffer')
1108 ;; + `:preserve-breaks' :: Non-nil means transcoding should preserve
1109 ;; all line breaks.
1110 ;; - category :: option
1111 ;; - type :: symbol (nil, t)
1113 ;; + `:section-numbers' :: Non-nil means transcoding should add
1114 ;; section numbers to headlines.
1115 ;; - category :: option
1116 ;; - type :: symbol (nil, t)
1118 ;; + `:select-tags' :: List of tags enforcing inclusion of sub-trees
1119 ;; in transcoding. When such a tag is present, subtrees without
1120 ;; it are de facto excluded from the process. See
1121 ;; `use-select-tags'.
1122 ;; - category :: option
1123 ;; - type :: list of strings
1125 ;; + `:target-list' :: List of targets encountered in the parse tree.
1126 ;; This is used to partly resolve "fuzzy" links
1127 ;; (cf. `org-export-resolve-fuzzy-link').
1128 ;; - category :: tree
1129 ;; - type :: list of strings
1131 ;; + `:time-stamp-file' :: Non-nil means transcoding should insert
1132 ;; a time stamp in the output.
1133 ;; - category :: option
1134 ;; - type :: symbol (nil, t)
1136 ;; + `:translate-alist' :: Alist between element and object types and
1137 ;; transcoding functions relative to the current back-end.
1138 ;; Special keys `template' and `plain-text' are also possible.
1139 ;; - category :: option
1140 ;; - type :: alist (SYMBOL . FUNCTION)
1142 ;; + `:with-archived-trees' :: Non-nil when archived subtrees should
1143 ;; also be transcoded. If it is set to the `headline' symbol,
1144 ;; only the archived headline's name is retained.
1145 ;; - category :: option
1146 ;; - type :: symbol (nil, t, `headline')
1148 ;; + `:with-author' :: Non-nil means author's name should be included
1149 ;; in the output.
1150 ;; - category :: option
1151 ;; - type :: symbol (nil, t)
1153 ;; + `:with-clocks' :: Non-nild means clock keywords should be exported.
1154 ;; - category :: option
1155 ;; - type :: symbol (nil, t)
1157 ;; + `:with-creator' :: Non-nild means a creation sentence should be
1158 ;; inserted at the end of the transcoded string. If the value
1159 ;; is `comment', it should be commented.
1160 ;; - category :: option
1161 ;; - type :: symbol (`comment', nil, t)
1163 ;; + `:with-drawers' :: Non-nil means drawers should be exported. If
1164 ;; its value is a list of names, only drawers with such names
1165 ;; will be transcoded.
1166 ;; - category :: option
1167 ;; - type :: symbol (nil, t) or list of strings
1169 ;; + `:with-email' :: Non-nil means output should contain author's
1170 ;; email.
1171 ;; - category :: option
1172 ;; - type :: symbol (nil, t)
1174 ;; + `:with-emphasize' :: Non-nil means emphasized text should be
1175 ;; interpreted.
1176 ;; - category :: option
1177 ;; - type :: symbol (nil, t)
1179 ;; + `:with-fixed-width' :: Non-nil if transcoder should interpret
1180 ;; strings starting with a colon as a fixed-with (verbatim) area.
1181 ;; - category :: option
1182 ;; - type :: symbol (nil, t)
1184 ;; + `:with-footnotes' :: Non-nil if transcoder should interpret
1185 ;; footnotes.
1186 ;; - category :: option
1187 ;; - type :: symbol (nil, t)
1189 ;; + `:with-plannings' :: Non-nil means transcoding should include
1190 ;; planning info.
1191 ;; - category :: option
1192 ;; - type :: symbol (nil, t)
1194 ;; + `:with-priority' :: Non-nil means transcoding should include
1195 ;; priority cookies.
1196 ;; - category :: option
1197 ;; - type :: symbol (nil, t)
1199 ;; + `:with-smart-quotes' :: Non-nil means activate smart quotes in
1200 ;; plain text.
1201 ;; - category :: option
1202 ;; - type :: symbol (nil, t)
1204 ;; + `:with-special-strings' :: Non-nil means transcoding should
1205 ;; interpret special strings in plain text.
1206 ;; - category :: option
1207 ;; - type :: symbol (nil, t)
1209 ;; + `:with-sub-superscript' :: Non-nil means transcoding should
1210 ;; interpret subscript and superscript. With a value of "{}",
1211 ;; only interpret those using curly brackets.
1212 ;; - category :: option
1213 ;; - type :: symbol (nil, {}, t)
1215 ;; + `:with-tables' :: Non-nil means transcoding should interpret
1216 ;; tables.
1217 ;; - category :: option
1218 ;; - type :: symbol (nil, t)
1220 ;; + `:with-tags' :: Non-nil means transcoding should keep tags in
1221 ;; headlines. A `not-in-toc' value will remove them from the
1222 ;; table of contents, if any, nonetheless.
1223 ;; - category :: option
1224 ;; - type :: symbol (nil, t, `not-in-toc')
1226 ;; + `:with-tasks' :: Non-nil means transcoding should include
1227 ;; headlines with a TODO keyword. A `todo' value will only
1228 ;; include headlines with a todo type keyword while a `done'
1229 ;; value will do the contrary. If a list of strings is provided,
1230 ;; only tasks with keywords belonging to that list will be kept.
1231 ;; - category :: option
1232 ;; - type :: symbol (t, todo, done, nil) or list of strings
1234 ;; + `:with-timestamps' :: Non-nil means transcoding should include
1235 ;; time stamps. Special value `active' (resp. `inactive') ask to
1236 ;; export only active (resp. inactive) timestamps. Otherwise,
1237 ;; completely remove them.
1238 ;; - category :: option
1239 ;; - type :: symbol: (`active', `inactive', t, nil)
1241 ;; + `:with-toc' :: Non-nil means that a table of contents has to be
1242 ;; added to the output. An integer value limits its depth.
1243 ;; - category :: option
1244 ;; - type :: symbol (nil, t or integer)
1246 ;; + `:with-todo-keywords' :: Non-nil means transcoding should
1247 ;; include TODO keywords.
1248 ;; - category :: option
1249 ;; - type :: symbol (nil, t)
1252 ;;;; Environment Options
1254 ;; Environment options encompass all parameters defined outside the
1255 ;; scope of the parsed data. They come from five sources, in
1256 ;; increasing precedence order:
1258 ;; - Global variables,
1259 ;; - Buffer's attributes,
1260 ;; - Options keyword symbols,
1261 ;; - Buffer keywords,
1262 ;; - Subtree properties.
1264 ;; The central internal function with regards to environment options
1265 ;; is `org-export-get-environment'. It updates global variables with
1266 ;; "#+BIND:" keywords, then retrieve and prioritize properties from
1267 ;; the different sources.
1269 ;; The internal functions doing the retrieval are:
1270 ;; `org-export--get-global-options',
1271 ;; `org-export--get-buffer-attributes',
1272 ;; `org-export--parse-option-keyword',
1273 ;; `org-export--get-subtree-options' and
1274 ;; `org-export--get-inbuffer-options'
1276 ;; Also, `org-export--confirm-letbind' and `org-export--install-letbind'
1277 ;; take care of the part relative to "#+BIND:" keywords.
1279 (defun org-export-get-environment (&optional backend subtreep ext-plist)
1280 "Collect export options from the current buffer.
1282 Optional argument BACKEND is a symbol specifying which back-end
1283 specific options to read, if any.
1285 When optional argument SUBTREEP is non-nil, assume the export is
1286 done against the current sub-tree.
1288 Third optional argument EXT-PLIST is a property list with
1289 external parameters overriding Org default settings, but still
1290 inferior to file-local settings."
1291 ;; First install #+BIND variables.
1292 (org-export--install-letbind-maybe)
1293 ;; Get and prioritize export options...
1294 (org-combine-plists
1295 ;; ... from global variables...
1296 (org-export--get-global-options backend)
1297 ;; ... from buffer's attributes...
1298 (org-export--get-buffer-attributes)
1299 ;; ... from an external property list...
1300 ext-plist
1301 ;; ... from in-buffer settings...
1302 (org-export--get-inbuffer-options
1303 backend
1304 (and buffer-file-name (org-remove-double-quotes buffer-file-name)))
1305 ;; ... and from subtree, when appropriate.
1306 (and subtreep (org-export--get-subtree-options backend))
1307 ;; Eventually install back-end symbol and its translation table.
1308 `(:back-end
1309 ,backend
1310 :translate-alist
1311 ,(let ((trans-alist (intern (format "org-%s-translate-alist" backend))))
1312 (when (boundp trans-alist) (symbol-value trans-alist))))))
1314 (defun org-export--parse-option-keyword (options &optional backend)
1315 "Parse an OPTIONS line and return values as a plist.
1316 Optional argument BACKEND is a symbol specifying which back-end
1317 specific items to read, if any."
1318 (let* ((all
1319 (append org-export-options-alist
1320 (and backend
1321 (let ((var (intern
1322 (format "org-%s-options-alist" backend))))
1323 (and (boundp var) (eval var))))))
1324 ;; Build an alist between #+OPTION: item and property-name.
1325 (alist (delq nil
1326 (mapcar (lambda (e)
1327 (when (nth 2 e) (cons (regexp-quote (nth 2 e))
1328 (car e))))
1329 all)))
1330 plist)
1331 (mapc (lambda (e)
1332 (when (string-match (concat "\\(\\`\\|[ \t]\\)"
1333 (car e)
1334 ":\\(([^)\n]+)\\|[^ \t\n\r;,.]*\\)")
1335 options)
1336 (setq plist (plist-put plist
1337 (cdr e)
1338 (car (read-from-string
1339 (match-string 2 options)))))))
1340 alist)
1341 plist))
1343 (defun org-export--get-subtree-options (&optional backend)
1344 "Get export options in subtree at point.
1345 Optional argument BACKEND is a symbol specifying back-end used
1346 for export. Return options as a plist."
1347 ;; For each buffer keyword, create an headline property setting the
1348 ;; same property in communication channel. The name for the property
1349 ;; is the keyword with "EXPORT_" appended to it.
1350 (org-with-wide-buffer
1351 (let (prop plist)
1352 ;; Make sure point is at an heading.
1353 (unless (org-at-heading-p) (org-back-to-heading t))
1354 ;; Take care of EXPORT_TITLE. If it isn't defined, use headline's
1355 ;; title as its fallback value.
1356 (when (setq prop (progn (looking-at org-todo-line-regexp)
1357 (or (save-match-data
1358 (org-entry-get (point) "EXPORT_TITLE"))
1359 (org-match-string-no-properties 3))))
1360 (setq plist
1361 (plist-put
1362 plist :title
1363 (org-element-parse-secondary-string
1364 prop (org-element-restriction 'keyword)))))
1365 ;; EXPORT_OPTIONS are parsed in a non-standard way.
1366 (when (setq prop (org-entry-get (point) "EXPORT_OPTIONS"))
1367 (setq plist
1368 (nconc plist (org-export--parse-option-keyword prop backend))))
1369 ;; Handle other keywords. TITLE keyword is excluded as it has
1370 ;; already been handled already.
1371 (let ((seen '("TITLE")))
1372 (mapc
1373 (lambda (option)
1374 (let ((property (nth 1 option)))
1375 (when (and property (not (member property seen)))
1376 (let* ((subtree-prop (concat "EXPORT_" property))
1377 ;; Export properties are not case-sensitive.
1378 (value (let ((case-fold-search t))
1379 (org-entry-get (point) subtree-prop))))
1380 (push property seen)
1381 (when value
1382 (setq plist
1383 (plist-put
1384 plist
1385 (car option)
1386 ;; Parse VALUE if required.
1387 (if (member property org-element-document-properties)
1388 (org-element-parse-secondary-string
1389 value (org-element-restriction 'keyword))
1390 value))))))))
1391 ;; Also look for both general keywords and back-end specific
1392 ;; options if BACKEND is provided.
1393 (append (and backend
1394 (let ((var (intern
1395 (format "org-%s-options-alist" backend))))
1396 (and (boundp var) (symbol-value var))))
1397 org-export-options-alist)))
1398 ;; Return value.
1399 plist)))
1401 (defun org-export--get-inbuffer-options (&optional backend files)
1402 "Return current buffer export options, as a plist.
1404 Optional argument BACKEND, when non-nil, is a symbol specifying
1405 which back-end specific options should also be read in the
1406 process.
1408 Optional argument FILES is a list of setup files names read so
1409 far, used to avoid circular dependencies.
1411 Assume buffer is in Org mode. Narrowing, if any, is ignored."
1412 (org-with-wide-buffer
1413 (goto-char (point-min))
1414 (let ((case-fold-search t) plist)
1415 ;; 1. Special keywords, as in `org-export-special-keywords'.
1416 (let ((special-re
1417 (format "^[ \t]*#\\+%s:" (regexp-opt org-export-special-keywords))))
1418 (while (re-search-forward special-re nil t)
1419 (let ((element (org-element-at-point)))
1420 (when (eq (org-element-type element) 'keyword)
1421 (let* ((key (org-element-property :key element))
1422 (val (org-element-property :value element))
1423 (prop
1424 (cond
1425 ((string= key "SETUP_FILE")
1426 (let ((file
1427 (expand-file-name
1428 (org-remove-double-quotes (org-trim val)))))
1429 ;; Avoid circular dependencies.
1430 (unless (member file files)
1431 (with-temp-buffer
1432 (insert (org-file-contents file 'noerror))
1433 (org-mode)
1434 (org-export--get-inbuffer-options
1435 backend (cons file files))))))
1436 ((string= key "OPTIONS")
1437 (org-export--parse-option-keyword val backend)))))
1438 (setq plist (org-combine-plists plist prop)))))))
1439 ;; 2. Standard options, as in `org-export-options-alist'.
1440 (let* ((all (append org-export-options-alist
1441 ;; Also look for back-end specific options
1442 ;; if BACKEND is defined.
1443 (and backend
1444 (let ((var
1445 (intern
1446 (format "org-%s-options-alist" backend))))
1447 (and (boundp var) (eval var))))))
1448 ;; Build ALIST between keyword name and property name.
1449 (alist
1450 (delq nil (mapcar
1451 (lambda (e) (when (nth 1 e) (cons (nth 1 e) (car e))))
1452 all)))
1453 ;; Build regexp matching all keywords associated to export
1454 ;; options. Note: the search is case insensitive.
1455 (opt-re (format "^[ \t]*#\\+%s:"
1456 (regexp-opt
1457 (delq nil (mapcar (lambda (e) (nth 1 e)) all))))))
1458 (goto-char (point-min))
1459 (while (re-search-forward opt-re nil t)
1460 (let ((element (org-element-at-point)))
1461 (when (eq (org-element-type element) 'keyword)
1462 (let* ((key (org-element-property :key element))
1463 (val (org-element-property :value element))
1464 (prop (cdr (assoc key alist)))
1465 (behaviour (nth 4 (assq prop all))))
1466 (setq plist
1467 (plist-put
1468 plist prop
1469 ;; Handle value depending on specified BEHAVIOUR.
1470 (case behaviour
1471 (space
1472 (if (not (plist-get plist prop)) (org-trim val)
1473 (concat (plist-get plist prop) " " (org-trim val))))
1474 (newline
1475 (org-trim
1476 (concat (plist-get plist prop) "\n" (org-trim val))))
1477 (split
1478 `(,@(plist-get plist prop) ,@(org-split-string val)))
1479 ('t val)
1480 (otherwise (if (not (plist-member plist prop)) val
1481 (plist-get plist prop))))))))))
1482 ;; Parse keywords specified in
1483 ;; `org-element-document-properties'.
1484 (mapc
1485 (lambda (key)
1486 (let* ((prop (cdr (assoc key alist)))
1487 (value (and prop (plist-get plist prop))))
1488 (when (stringp value)
1489 (setq plist
1490 (plist-put
1491 plist prop
1492 (org-element-parse-secondary-string
1493 value (org-element-restriction 'keyword)))))))
1494 org-element-document-properties))
1495 ;; 3. Return final value.
1496 plist)))
1498 (defun org-export--get-buffer-attributes ()
1499 "Return properties related to buffer attributes, as a plist."
1500 (let ((visited-file (buffer-file-name (buffer-base-buffer))))
1501 (list
1502 ;; Store full path of input file name, or nil. For internal use.
1503 :input-file visited-file
1504 :title (or (and visited-file
1505 (file-name-sans-extension
1506 (file-name-nondirectory visited-file)))
1507 (buffer-name (buffer-base-buffer)))
1508 :footnote-definition-alist
1509 ;; Footnotes definitions must be collected in the original
1510 ;; buffer, as there's no insurance that they will still be in the
1511 ;; parse tree, due to possible narrowing.
1512 (let (alist)
1513 (org-with-wide-buffer
1514 (goto-char (point-min))
1515 (while (re-search-forward org-footnote-definition-re nil t)
1516 (let ((def (save-match-data (org-element-at-point))))
1517 (when (eq (org-element-type def) 'footnote-definition)
1518 (push
1519 (cons (org-element-property :label def)
1520 (let ((cbeg (org-element-property :contents-begin def)))
1521 (when cbeg
1522 (org-element--parse-elements
1523 cbeg (org-element-property :contents-end def)
1524 nil nil nil nil (list 'org-data nil)))))
1525 alist))))
1526 alist))
1527 :id-alist
1528 ;; Collect id references.
1529 (let (alist)
1530 (org-with-wide-buffer
1531 (goto-char (point-min))
1532 (while (re-search-forward "\\[\\[id:\\S-+?\\]" nil t)
1533 (let ((link (org-element-context)))
1534 (when (eq (org-element-type link) 'link)
1535 (let* ((id (org-element-property :path link))
1536 (file (org-id-find-id-file id)))
1537 (when file
1538 (push (cons id (file-relative-name file)) alist)))))))
1539 alist))))
1541 (defun org-export--get-global-options (&optional backend)
1542 "Return global export options as a plist.
1544 Optional argument BACKEND, if non-nil, is a symbol specifying
1545 which back-end specific export options should also be read in the
1546 process."
1547 (let ((all (append org-export-options-alist
1548 (and backend
1549 (let ((var (intern
1550 (format "org-%s-options-alist" backend))))
1551 (and (boundp var) (symbol-value var))))))
1552 ;; Output value.
1553 plist)
1554 (mapc
1555 (lambda (cell)
1556 (setq plist
1557 (plist-put
1558 plist
1559 (car cell)
1560 ;; Eval default value provided. If keyword is a member
1561 ;; of `org-element-document-properties', parse it as
1562 ;; a secondary string before storing it.
1563 (let ((value (eval (nth 3 cell))))
1564 (if (not (stringp value)) value
1565 (let ((keyword (nth 1 cell)))
1566 (if (not (member keyword org-element-document-properties))
1567 value
1568 (org-element-parse-secondary-string
1569 value (org-element-restriction 'keyword)))))))))
1570 all)
1571 ;; Return value.
1572 plist))
1574 (defvar org-export--allow-BIND-local nil)
1575 (defun org-export--confirm-letbind ()
1576 "Can we use #+BIND values during export?
1577 By default this will ask for confirmation by the user, to divert
1578 possible security risks."
1579 (cond
1580 ((not org-export-allow-BIND) nil)
1581 ((eq org-export-allow-BIND t) t)
1582 ((local-variable-p 'org-export--allow-BIND-local)
1583 org-export--allow-BIND-local)
1584 (t (org-set-local 'org-export--allow-BIND-local
1585 (yes-or-no-p "Allow BIND values in this buffer? ")))))
1587 (defun org-export--install-letbind-maybe ()
1588 "Install the values from #+BIND lines as local variables.
1589 Variables must be installed before in-buffer options are
1590 retrieved."
1591 (let ((case-fold-search t) letbind pair)
1592 (org-with-wide-buffer
1593 (goto-char (point-min))
1594 (while (re-search-forward "^[ \t]*#\\+BIND:" nil t)
1595 (let* ((element (org-element-at-point))
1596 (value (org-element-property :value element)))
1597 (when (and (eq (org-element-type element) 'keyword)
1598 (not (equal value ""))
1599 (org-export--confirm-letbind))
1600 (push (read (format "(%s)" value)) letbind)))))
1601 (dolist (pair (nreverse letbind))
1602 (org-set-local (car pair) (nth 1 pair)))))
1605 ;;;; Tree Properties
1607 ;; Tree properties are information extracted from parse tree. They
1608 ;; are initialized at the beginning of the transcoding process by
1609 ;; `org-export-collect-tree-properties'.
1611 ;; Dedicated functions focus on computing the value of specific tree
1612 ;; properties during initialization. Thus,
1613 ;; `org-export--populate-ignore-list' lists elements and objects that
1614 ;; should be skipped during export, `org-export--get-min-level' gets
1615 ;; the minimal exportable level, used as a basis to compute relative
1616 ;; level for headlines. Eventually
1617 ;; `org-export--collect-headline-numbering' builds an alist between
1618 ;; headlines and their numbering.
1620 (defun org-export-collect-tree-properties (data info)
1621 "Extract tree properties from parse tree.
1623 DATA is the parse tree from which information is retrieved. INFO
1624 is a list holding export options.
1626 Following tree properties are set or updated:
1628 `:exported-data' Hash table used to memoize results from
1629 `org-export-data'.
1631 `:footnote-definition-alist' List of footnotes definitions in
1632 original buffer and current parse tree.
1634 `:headline-offset' Offset between true level of headlines and
1635 local level. An offset of -1 means an headline
1636 of level 2 should be considered as a level
1637 1 headline in the context.
1639 `:headline-numbering' Alist of all headlines as key an the
1640 associated numbering as value.
1642 `:ignore-list' List of elements that should be ignored during
1643 export.
1645 `:target-list' List of all targets in the parse tree.
1647 Return updated plist."
1648 ;; Install the parse tree in the communication channel, in order to
1649 ;; use `org-export-get-genealogy' and al.
1650 (setq info (plist-put info :parse-tree data))
1651 ;; Get the list of elements and objects to ignore, and put it into
1652 ;; `:ignore-list'. Do not overwrite any user ignore that might have
1653 ;; been done during parse tree filtering.
1654 (setq info
1655 (plist-put info
1656 :ignore-list
1657 (append (org-export--populate-ignore-list data info)
1658 (plist-get info :ignore-list))))
1659 ;; Compute `:headline-offset' in order to be able to use
1660 ;; `org-export-get-relative-level'.
1661 (setq info
1662 (plist-put info
1663 :headline-offset
1664 (- 1 (org-export--get-min-level data info))))
1665 ;; Update footnotes definitions list with definitions in parse tree.
1666 ;; This is required since buffer expansion might have modified
1667 ;; boundaries of footnote definitions contained in the parse tree.
1668 ;; This way, definitions in `footnote-definition-alist' are bound to
1669 ;; match those in the parse tree.
1670 (let ((defs (plist-get info :footnote-definition-alist)))
1671 (org-element-map
1672 data 'footnote-definition
1673 (lambda (fn)
1674 (push (cons (org-element-property :label fn)
1675 `(org-data nil ,@(org-element-contents fn)))
1676 defs)))
1677 (setq info (plist-put info :footnote-definition-alist defs)))
1678 ;; Properties order doesn't matter: get the rest of the tree
1679 ;; properties.
1680 (nconc
1681 `(:target-list
1682 ,(org-element-map
1683 data '(keyword target)
1684 (lambda (blob)
1685 (when (or (eq (org-element-type blob) 'target)
1686 (string= (org-element-property :key blob) "TARGET"))
1687 blob)) info)
1688 :headline-numbering ,(org-export--collect-headline-numbering data info)
1689 :exported-data ,(make-hash-table :test 'eq :size 4001))
1690 info))
1692 (defun org-export--get-min-level (data options)
1693 "Return minimum exportable headline's level in DATA.
1694 DATA is parsed tree as returned by `org-element-parse-buffer'.
1695 OPTIONS is a plist holding export options."
1696 (catch 'exit
1697 (let ((min-level 10000))
1698 (mapc
1699 (lambda (blob)
1700 (when (and (eq (org-element-type blob) 'headline)
1701 (not (memq blob (plist-get options :ignore-list))))
1702 (setq min-level
1703 (min (org-element-property :level blob) min-level)))
1704 (when (= min-level 1) (throw 'exit 1)))
1705 (org-element-contents data))
1706 ;; If no headline was found, for the sake of consistency, set
1707 ;; minimum level to 1 nonetheless.
1708 (if (= min-level 10000) 1 min-level))))
1710 (defun org-export--collect-headline-numbering (data options)
1711 "Return numbering of all exportable headlines in a parse tree.
1713 DATA is the parse tree. OPTIONS is the plist holding export
1714 options.
1716 Return an alist whose key is an headline and value is its
1717 associated numbering \(in the shape of a list of numbers\)."
1718 (let ((numbering (make-vector org-export-max-depth 0)))
1719 (org-element-map
1720 data
1721 'headline
1722 (lambda (headline)
1723 (let ((relative-level
1724 (1- (org-export-get-relative-level headline options))))
1725 (cons
1726 headline
1727 (loop for n across numbering
1728 for idx from 0 to org-export-max-depth
1729 when (< idx relative-level) collect n
1730 when (= idx relative-level) collect (aset numbering idx (1+ n))
1731 when (> idx relative-level) do (aset numbering idx 0)))))
1732 options)))
1734 (defun org-export--populate-ignore-list (data options)
1735 "Return list of elements and objects to ignore during export.
1736 DATA is the parse tree to traverse. OPTIONS is the plist holding
1737 export options."
1738 (let* (ignore
1739 walk-data
1740 ;; First find trees containing a select tag, if any.
1741 (selected (org-export--selected-trees data options))
1742 (walk-data
1743 (lambda (data)
1744 ;; Collect ignored elements or objects into IGNORE-LIST.
1745 (let ((type (org-element-type data)))
1746 (if (org-export--skip-p data options selected) (push data ignore)
1747 (if (and (eq type 'headline)
1748 (eq (plist-get options :with-archived-trees) 'headline)
1749 (org-element-property :archivedp data))
1750 ;; If headline is archived but tree below has
1751 ;; to be skipped, add it to ignore list.
1752 (mapc (lambda (e) (push e ignore))
1753 (org-element-contents data))
1754 ;; Move into secondary string, if any.
1755 (let ((sec-prop
1756 (cdr (assq type org-element-secondary-value-alist))))
1757 (when sec-prop
1758 (mapc walk-data (org-element-property sec-prop data))))
1759 ;; Move into recursive objects/elements.
1760 (mapc walk-data (org-element-contents data))))))))
1761 ;; Main call.
1762 (funcall walk-data data)
1763 ;; Return value.
1764 ignore))
1766 (defun org-export--selected-trees (data info)
1767 "Return list of headlines containing a select tag in their tree.
1768 DATA is parsed data as returned by `org-element-parse-buffer'.
1769 INFO is a plist holding export options."
1770 (let* (selected-trees
1771 walk-data ; for byte-compiler.
1772 (walk-data
1773 (function
1774 (lambda (data genealogy)
1775 (case (org-element-type data)
1776 (org-data (mapc (lambda (el) (funcall walk-data el genealogy))
1777 (org-element-contents data)))
1778 (headline
1779 (let ((tags (org-element-property :tags data)))
1780 (if (loop for tag in (plist-get info :select-tags)
1781 thereis (member tag tags))
1782 ;; When a select tag is found, mark full
1783 ;; genealogy and every headline within the tree
1784 ;; as acceptable.
1785 (setq selected-trees
1786 (append
1787 genealogy
1788 (org-element-map data 'headline 'identity)
1789 selected-trees))
1790 ;; Else, continue searching in tree, recursively.
1791 (mapc
1792 (lambda (el) (funcall walk-data el (cons data genealogy)))
1793 (org-element-contents data))))))))))
1794 (funcall walk-data data nil) selected-trees))
1796 (defun org-export--skip-p (blob options selected)
1797 "Non-nil when element or object BLOB should be skipped during export.
1798 OPTIONS is the plist holding export options. SELECTED, when
1799 non-nil, is a list of headlines belonging to a tree with a select
1800 tag."
1801 (case (org-element-type blob)
1802 (clock (not (plist-get options :with-clocks)))
1803 (drawer
1804 (or (not (plist-get options :with-drawers))
1805 (and (consp (plist-get options :with-drawers))
1806 (not (member (org-element-property :drawer-name blob)
1807 (plist-get options :with-drawers))))))
1808 (headline
1809 (let ((with-tasks (plist-get options :with-tasks))
1810 (todo (org-element-property :todo-keyword blob))
1811 (todo-type (org-element-property :todo-type blob))
1812 (archived (plist-get options :with-archived-trees))
1813 (tags (org-element-property :tags blob)))
1815 ;; Ignore subtrees with an exclude tag.
1816 (loop for k in (plist-get options :exclude-tags)
1817 thereis (member k tags))
1818 ;; When a select tag is present in the buffer, ignore any tree
1819 ;; without it.
1820 (and selected (not (memq blob selected)))
1821 ;; Ignore commented sub-trees.
1822 (org-element-property :commentedp blob)
1823 ;; Ignore archived subtrees if `:with-archived-trees' is nil.
1824 (and (not archived) (org-element-property :archivedp blob))
1825 ;; Ignore tasks, if specified by `:with-tasks' property.
1826 (and todo
1827 (or (not with-tasks)
1828 (and (memq with-tasks '(todo done))
1829 (not (eq todo-type with-tasks)))
1830 (and (consp with-tasks) (not (member todo with-tasks))))))))
1831 (inlinetask (not (plist-get options :with-inlinetasks)))
1832 (planning (not (plist-get options :with-plannings)))
1833 (statistics-cookie (not (plist-get options :with-statistics-cookies)))
1834 (table-cell
1835 (and (org-export-table-has-special-column-p
1836 (org-export-get-parent-table blob))
1837 (not (org-export-get-previous-element blob options))))
1838 (table-row (org-export-table-row-is-special-p blob options))
1839 (timestamp
1840 (case (plist-get options :with-timestamps)
1841 ;; No timestamp allowed.
1842 ('nil t)
1843 ;; Only active timestamps allowed and the current one isn't
1844 ;; active.
1845 (active
1846 (not (memq (org-element-property :type blob)
1847 '(active active-range))))
1848 ;; Only inactive timestamps allowed and the current one isn't
1849 ;; inactive.
1850 (inactive
1851 (not (memq (org-element-property :type blob)
1852 '(inactive inactive-range))))))))
1856 ;;; The Transcoder
1858 ;; `org-export-data' reads a parse tree (obtained with, i.e.
1859 ;; `org-element-parse-buffer') and transcodes it into a specified
1860 ;; back-end output. It takes care of filtering out elements or
1861 ;; objects according to export options and organizing the output blank
1862 ;; lines and white space are preserved. The function memoizes its
1863 ;; results, so it is cheap to call it within translators.
1865 ;; Internally, three functions handle the filtering of objects and
1866 ;; elements during the export. In particular,
1867 ;; `org-export-ignore-element' marks an element or object so future
1868 ;; parse tree traversals skip it, `org-export--interpret-p' tells which
1869 ;; elements or objects should be seen as real Org syntax and
1870 ;; `org-export-expand' transforms the others back into their original
1871 ;; shape
1873 ;; `org-export-transcoder' is an accessor returning appropriate
1874 ;; translator function for a given element or object.
1876 (defun org-export-transcoder (blob info)
1877 "Return appropriate transcoder for BLOB.
1878 INFO is a plist containing export directives."
1879 (let ((type (org-element-type blob)))
1880 ;; Return contents only for complete parse trees.
1881 (if (eq type 'org-data) (lambda (blob contents info) contents)
1882 (let ((transcoder (cdr (assq type (plist-get info :translate-alist)))))
1883 (and (functionp transcoder) transcoder)))))
1885 (defun org-export-data (data info)
1886 "Convert DATA into current back-end format.
1888 DATA is a parse tree, an element or an object or a secondary
1889 string. INFO is a plist holding export options.
1891 Return transcoded string."
1892 (let ((memo (gethash data (plist-get info :exported-data) 'no-memo)))
1893 (if (not (eq memo 'no-memo)) memo
1894 (let* ((type (org-element-type data))
1895 (results
1896 (cond
1897 ;; Ignored element/object.
1898 ((memq data (plist-get info :ignore-list)) nil)
1899 ;; Plain text. All residual text properties from parse
1900 ;; tree (i.e. `:parent' property) are removed.
1901 ((eq type 'plain-text)
1902 (org-no-properties
1903 (org-export-filter-apply-functions
1904 (plist-get info :filter-plain-text)
1905 (let ((transcoder (org-export-transcoder data info)))
1906 (if transcoder (funcall transcoder data info) data))
1907 info)))
1908 ;; Uninterpreted element/object: change it back to Org
1909 ;; syntax and export again resulting raw string.
1910 ((not (org-export--interpret-p data info))
1911 (org-export-data
1912 (org-export-expand
1913 data
1914 (mapconcat (lambda (blob) (org-export-data blob info))
1915 (org-element-contents data)
1916 ""))
1917 info))
1918 ;; Secondary string.
1919 ((not type)
1920 (mapconcat (lambda (obj) (org-export-data obj info)) data ""))
1921 ;; Element/Object without contents or, as a special case,
1922 ;; headline with archive tag and archived trees restricted
1923 ;; to title only.
1924 ((or (not (org-element-contents data))
1925 (and (eq type 'headline)
1926 (eq (plist-get info :with-archived-trees) 'headline)
1927 (org-element-property :archivedp data)))
1928 (let ((transcoder (org-export-transcoder data info)))
1929 (and (functionp transcoder)
1930 (funcall transcoder data nil info))))
1931 ;; Element/Object with contents.
1933 (let ((transcoder (org-export-transcoder data info)))
1934 (when transcoder
1935 (let* ((greaterp (memq type org-element-greater-elements))
1936 (objectp
1937 (and (not greaterp)
1938 (memq type org-element-recursive-objects)))
1939 (contents
1940 (mapconcat
1941 (lambda (element) (org-export-data element info))
1942 (org-element-contents
1943 (if (or greaterp objectp) data
1944 ;; Elements directly containing objects
1945 ;; must have their indentation normalized
1946 ;; first.
1947 (org-element-normalize-contents
1948 data
1949 ;; When normalizing contents of the first
1950 ;; paragraph in an item or a footnote
1951 ;; definition, ignore first line's
1952 ;; indentation: there is none and it
1953 ;; might be misleading.
1954 (when (eq type 'paragraph)
1955 (let ((parent (org-export-get-parent data)))
1956 (and
1957 (eq (car (org-element-contents parent))
1958 data)
1959 (memq (org-element-type parent)
1960 '(footnote-definition item))))))))
1961 "")))
1962 (funcall transcoder data
1963 (if (not greaterp) contents
1964 (org-element-normalize-string contents))
1965 info))))))))
1966 ;; Final result will be memoized before being returned.
1967 (puthash
1968 data
1969 (cond
1970 ((not results) nil)
1971 ((memq type '(org-data plain-text nil)) results)
1972 ;; Append the same white space between elements or objects as in
1973 ;; the original buffer, and call appropriate filters.
1975 (let ((results
1976 (org-export-filter-apply-functions
1977 (plist-get info (intern (format ":filter-%s" type)))
1978 (let ((post-blank (or (org-element-property :post-blank data)
1979 0)))
1980 (if (memq type org-element-all-elements)
1981 (concat (org-element-normalize-string results)
1982 (make-string post-blank ?\n))
1983 (concat results (make-string post-blank ? ))))
1984 info)))
1985 results)))
1986 (plist-get info :exported-data))))))
1988 (defun org-export--interpret-p (blob info)
1989 "Non-nil if element or object BLOB should be interpreted as Org syntax.
1990 Check is done according to export options INFO, stored as
1991 a plist."
1992 (case (org-element-type blob)
1993 ;; ... entities...
1994 (entity (plist-get info :with-entities))
1995 ;; ... emphasis...
1996 (emphasis (plist-get info :with-emphasize))
1997 ;; ... fixed-width areas.
1998 (fixed-width (plist-get info :with-fixed-width))
1999 ;; ... footnotes...
2000 ((footnote-definition footnote-reference)
2001 (plist-get info :with-footnotes))
2002 ;; ... sub/superscripts...
2003 ((subscript superscript)
2004 (let ((sub/super-p (plist-get info :with-sub-superscript)))
2005 (if (eq sub/super-p '{})
2006 (org-element-property :use-brackets-p blob)
2007 sub/super-p)))
2008 ;; ... tables...
2009 (table (plist-get info :with-tables))
2010 (otherwise t)))
2012 (defun org-export-expand (blob contents)
2013 "Expand a parsed element or object to its original state.
2014 BLOB is either an element or an object. CONTENTS is its
2015 contents, as a string or nil."
2016 (funcall
2017 (intern (format "org-element-%s-interpreter" (org-element-type blob)))
2018 blob contents))
2020 (defun org-export-ignore-element (element info)
2021 "Add ELEMENT to `:ignore-list' in INFO.
2023 Any element in `:ignore-list' will be skipped when using
2024 `org-element-map'. INFO is modified by side effects."
2025 (plist-put info :ignore-list (cons element (plist-get info :ignore-list))))
2029 ;;; The Filter System
2031 ;; Filters allow end-users to tweak easily the transcoded output.
2032 ;; They are the functional counterpart of hooks, as every filter in
2033 ;; a set is applied to the return value of the previous one.
2035 ;; Every set is back-end agnostic. Although, a filter is always
2036 ;; called, in addition to the string it applies to, with the back-end
2037 ;; used as argument, so it's easy for the end-user to add back-end
2038 ;; specific filters in the set. The communication channel, as
2039 ;; a plist, is required as the third argument.
2041 ;; From the developer side, filters sets can be installed in the
2042 ;; process with the help of `org-export-define-backend', which
2043 ;; internally sets `org-BACKEND-filters-alist' variable. Each
2044 ;; association has a key among the following symbols and a function or
2045 ;; a list of functions as value.
2047 ;; - `:filter-parse-tree' applies directly on the complete parsed
2048 ;; tree. It's the only filters set that doesn't apply to a string.
2049 ;; Users can set it through `org-export-filter-parse-tree-functions'
2050 ;; variable.
2052 ;; - `:filter-final-output' applies to the final transcoded string.
2053 ;; Users can set it with `org-export-filter-final-output-functions'
2054 ;; variable
2056 ;; - `:filter-plain-text' applies to any string not recognized as Org
2057 ;; syntax. `org-export-filter-plain-text-functions' allows users to
2058 ;; configure it.
2060 ;; - `:filter-TYPE' applies on the string returned after an element or
2061 ;; object of type TYPE has been transcoded. An user can modify
2062 ;; `org-export-filter-TYPE-functions'
2064 ;; All filters sets are applied with
2065 ;; `org-export-filter-apply-functions' function. Filters in a set are
2066 ;; applied in a LIFO fashion. It allows developers to be sure that
2067 ;; their filters will be applied first.
2069 ;; Filters properties are installed in communication channel with
2070 ;; `org-export-install-filters' function.
2072 ;; Eventually, a hook (`org-export-before-parsing-hook') is run just
2073 ;; before parsing to allow for heavy structure modifications.
2076 ;;;; Before Parsing Hook
2078 (defvar org-export-before-parsing-hook nil
2079 "Hook run before parsing an export buffer.
2081 This is run after include keywords have been expanded and Babel
2082 code executed, on a copy of original buffer's area being
2083 exported. Visibility is the same as in the original one. Point
2084 is left at the beginning of the new one.
2086 Every function in this hook will be called with one argument: the
2087 back-end currently used, as a symbol.")
2090 ;;;; Special Filters
2092 (defvar org-export-filter-parse-tree-functions nil
2093 "List of functions applied to the parsed tree.
2094 Each filter is called with three arguments: the parse tree, as
2095 returned by `org-element-parse-buffer', the back-end, as
2096 a symbol, and the communication channel, as a plist. It must
2097 return the modified parse tree to transcode.")
2099 (defvar org-export-filter-final-output-functions nil
2100 "List of functions applied to the transcoded string.
2101 Each filter is called with three arguments: the full transcoded
2102 string, the back-end, as a symbol, and the communication channel,
2103 as a plist. It must return a string that will be used as the
2104 final export output.")
2106 (defvar org-export-filter-plain-text-functions nil
2107 "List of functions applied to plain text.
2108 Each filter is called with three arguments: a string which
2109 contains no Org syntax, the back-end, as a symbol, and the
2110 communication channel, as a plist. It must return a string or
2111 nil.")
2114 ;;;; Elements Filters
2116 (defvar org-export-filter-babel-call-functions nil
2117 "List of functions applied to a transcoded babel-call.
2118 Each filter is called with three arguments: the transcoded data,
2119 as a string, the back-end, as a symbol, and the communication
2120 channel, as a plist. It must return a string or nil.")
2122 (defvar org-export-filter-center-block-functions nil
2123 "List of functions applied to a transcoded center block.
2124 Each filter is called with three arguments: the transcoded data,
2125 as a string, the back-end, as a symbol, and the communication
2126 channel, as a plist. It must return a string or nil.")
2128 (defvar org-export-filter-clock-functions nil
2129 "List of functions applied to a transcoded clock.
2130 Each filter is called with three arguments: the transcoded data,
2131 as a string, the back-end, as a symbol, and the communication
2132 channel, as a plist. It must return a string or nil.")
2134 (defvar org-export-filter-comment-functions nil
2135 "List of functions applied to a transcoded comment.
2136 Each filter is called with three arguments: the transcoded data,
2137 as a string, the back-end, as a symbol, and the communication
2138 channel, as a plist. It must return a string or nil.")
2140 (defvar org-export-filter-comment-block-functions nil
2141 "List of functions applied to a transcoded comment-comment.
2142 Each filter is called with three arguments: the transcoded data,
2143 as a string, the back-end, as a symbol, and the communication
2144 channel, as a plist. It must return a string or nil.")
2146 (defvar org-export-filter-drawer-functions nil
2147 "List of functions applied to a transcoded drawer.
2148 Each filter is called with three arguments: the transcoded data,
2149 as a string, the back-end, as a symbol, and the communication
2150 channel, as a plist. It must return a string or nil.")
2152 (defvar org-export-filter-dynamic-block-functions nil
2153 "List of functions applied to a transcoded dynamic-block.
2154 Each filter is called with three arguments: the transcoded data,
2155 as a string, the back-end, as a symbol, and the communication
2156 channel, as a plist. It must return a string or nil.")
2158 (defvar org-export-filter-example-block-functions nil
2159 "List of functions applied to a transcoded example-block.
2160 Each filter is called with three arguments: the transcoded data,
2161 as a string, the back-end, as a symbol, and the communication
2162 channel, as a plist. It must return a string or nil.")
2164 (defvar org-export-filter-export-block-functions nil
2165 "List of functions applied to a transcoded export-block.
2166 Each filter is called with three arguments: the transcoded data,
2167 as a string, the back-end, as a symbol, and the communication
2168 channel, as a plist. It must return a string or nil.")
2170 (defvar org-export-filter-fixed-width-functions nil
2171 "List of functions applied to a transcoded fixed-width.
2172 Each filter is called with three arguments: the transcoded data,
2173 as a string, the back-end, as a symbol, and the communication
2174 channel, as a plist. It must return a string or nil.")
2176 (defvar org-export-filter-footnote-definition-functions nil
2177 "List of functions applied to a transcoded footnote-definition.
2178 Each filter is called with three arguments: the transcoded data,
2179 as a string, the back-end, as a symbol, and the communication
2180 channel, as a plist. It must return a string or nil.")
2182 (defvar org-export-filter-headline-functions nil
2183 "List of functions applied to a transcoded headline.
2184 Each filter is called with three arguments: the transcoded data,
2185 as a string, the back-end, as a symbol, and the communication
2186 channel, as a plist. It must return a string or nil.")
2188 (defvar org-export-filter-horizontal-rule-functions nil
2189 "List of functions applied to a transcoded horizontal-rule.
2190 Each filter is called with three arguments: the transcoded data,
2191 as a string, the back-end, as a symbol, and the communication
2192 channel, as a plist. It must return a string or nil.")
2194 (defvar org-export-filter-inlinetask-functions nil
2195 "List of functions applied to a transcoded inlinetask.
2196 Each filter is called with three arguments: the transcoded data,
2197 as a string, the back-end, as a symbol, and the communication
2198 channel, as a plist. It must return a string or nil.")
2200 (defvar org-export-filter-item-functions nil
2201 "List of functions applied to a transcoded item.
2202 Each filter is called with three arguments: the transcoded data,
2203 as a string, the back-end, as a symbol, and the communication
2204 channel, as a plist. It must return a string or nil.")
2206 (defvar org-export-filter-keyword-functions nil
2207 "List of functions applied to a transcoded keyword.
2208 Each filter is called with three arguments: the transcoded data,
2209 as a string, the back-end, as a symbol, and the communication
2210 channel, as a plist. It must return a string or nil.")
2212 (defvar org-export-filter-latex-environment-functions nil
2213 "List of functions applied to a transcoded latex-environment.
2214 Each filter is called with three arguments: the transcoded data,
2215 as a string, the back-end, as a symbol, and the communication
2216 channel, as a plist. It must return a string or nil.")
2218 (defvar org-export-filter-node-property-functions nil
2219 "List of functions applied to a transcoded node-property.
2220 Each filter is called with three arguments: the transcoded data,
2221 as a string, the back-end, as a symbol, and the communication
2222 channel, as a plist. It must return a string or nil.")
2224 (defvar org-export-filter-paragraph-functions nil
2225 "List of functions applied to a transcoded paragraph.
2226 Each filter is called with three arguments: the transcoded data,
2227 as a string, the back-end, as a symbol, and the communication
2228 channel, as a plist. It must return a string or nil.")
2230 (defvar org-export-filter-plain-list-functions nil
2231 "List of functions applied to a transcoded plain-list.
2232 Each filter is called with three arguments: the transcoded data,
2233 as a string, the back-end, as a symbol, and the communication
2234 channel, as a plist. It must return a string or nil.")
2236 (defvar org-export-filter-planning-functions nil
2237 "List of functions applied to a transcoded planning.
2238 Each filter is called with three arguments: the transcoded data,
2239 as a string, the back-end, as a symbol, and the communication
2240 channel, as a plist. It must return a string or nil.")
2242 (defvar org-export-filter-property-drawer-functions nil
2243 "List of functions applied to a transcoded property-drawer.
2244 Each filter is called with three arguments: the transcoded data,
2245 as a string, the back-end, as a symbol, and the communication
2246 channel, as a plist. It must return a string or nil.")
2248 (defvar org-export-filter-quote-block-functions nil
2249 "List of functions applied to a transcoded quote block.
2250 Each filter is called with three arguments: the transcoded quote
2251 data, as a string, the back-end, as a symbol, and the
2252 communication channel, as a plist. It must return a string or
2253 nil.")
2255 (defvar org-export-filter-quote-section-functions nil
2256 "List of functions applied to a transcoded quote-section.
2257 Each filter is called with three arguments: the transcoded data,
2258 as a string, the back-end, as a symbol, and the communication
2259 channel, as a plist. It must return a string or nil.")
2261 (defvar org-export-filter-section-functions nil
2262 "List of functions applied to a transcoded section.
2263 Each filter is called with three arguments: the transcoded data,
2264 as a string, the back-end, as a symbol, and the communication
2265 channel, as a plist. It must return a string or nil.")
2267 (defvar org-export-filter-special-block-functions nil
2268 "List of functions applied to a transcoded special block.
2269 Each filter is called with three arguments: the transcoded data,
2270 as a string, the back-end, as a symbol, and the communication
2271 channel, as a plist. It must return a string or nil.")
2273 (defvar org-export-filter-src-block-functions nil
2274 "List of functions applied to a transcoded src-block.
2275 Each filter is called with three arguments: the transcoded data,
2276 as a string, the back-end, as a symbol, and the communication
2277 channel, as a plist. It must return a string or nil.")
2279 (defvar org-export-filter-table-functions nil
2280 "List of functions applied to a transcoded table.
2281 Each filter is called with three arguments: the transcoded data,
2282 as a string, the back-end, as a symbol, and the communication
2283 channel, as a plist. It must return a string or nil.")
2285 (defvar org-export-filter-table-cell-functions nil
2286 "List of functions applied to a transcoded table-cell.
2287 Each filter is called with three arguments: the transcoded data,
2288 as a string, the back-end, as a symbol, and the communication
2289 channel, as a plist. It must return a string or nil.")
2291 (defvar org-export-filter-table-row-functions nil
2292 "List of functions applied to a transcoded table-row.
2293 Each filter is called with three arguments: the transcoded data,
2294 as a string, the back-end, as a symbol, and the communication
2295 channel, as a plist. It must return a string or nil.")
2297 (defvar org-export-filter-verse-block-functions nil
2298 "List of functions applied to a transcoded verse block.
2299 Each filter is called with three arguments: the transcoded data,
2300 as a string, the back-end, as a symbol, and the communication
2301 channel, as a plist. It must return a string or nil.")
2304 ;;;; Objects Filters
2306 (defvar org-export-filter-bold-functions nil
2307 "List of functions applied to transcoded bold text.
2308 Each filter is called with three arguments: the transcoded data,
2309 as a string, the back-end, as a symbol, and the communication
2310 channel, as a plist. It must return a string or nil.")
2312 (defvar org-export-filter-code-functions nil
2313 "List of functions applied to transcoded code text.
2314 Each filter is called with three arguments: the transcoded data,
2315 as a string, the back-end, as a symbol, and the communication
2316 channel, as a plist. It must return a string or nil.")
2318 (defvar org-export-filter-entity-functions nil
2319 "List of functions applied to a transcoded entity.
2320 Each filter is called with three arguments: the transcoded data,
2321 as a string, the back-end, as a symbol, and the communication
2322 channel, as a plist. It must return a string or nil.")
2324 (defvar org-export-filter-export-snippet-functions nil
2325 "List of functions applied to a transcoded export-snippet.
2326 Each filter is called with three arguments: the transcoded data,
2327 as a string, the back-end, as a symbol, and the communication
2328 channel, as a plist. It must return a string or nil.")
2330 (defvar org-export-filter-footnote-reference-functions nil
2331 "List of functions applied to a transcoded footnote-reference.
2332 Each filter is called with three arguments: the transcoded data,
2333 as a string, the back-end, as a symbol, and the communication
2334 channel, as a plist. It must return a string or nil.")
2336 (defvar org-export-filter-inline-babel-call-functions nil
2337 "List of functions applied to a transcoded inline-babel-call.
2338 Each filter is called with three arguments: the transcoded data,
2339 as a string, the back-end, as a symbol, and the communication
2340 channel, as a plist. It must return a string or nil.")
2342 (defvar org-export-filter-inline-src-block-functions nil
2343 "List of functions applied to a transcoded inline-src-block.
2344 Each filter is called with three arguments: the transcoded data,
2345 as a string, the back-end, as a symbol, and the communication
2346 channel, as a plist. It must return a string or nil.")
2348 (defvar org-export-filter-italic-functions nil
2349 "List of functions applied to transcoded italic text.
2350 Each filter is called with three arguments: the transcoded data,
2351 as a string, the back-end, as a symbol, and the communication
2352 channel, as a plist. It must return a string or nil.")
2354 (defvar org-export-filter-latex-fragment-functions nil
2355 "List of functions applied to a transcoded latex-fragment.
2356 Each filter is called with three arguments: the transcoded data,
2357 as a string, the back-end, as a symbol, and the communication
2358 channel, as a plist. It must return a string or nil.")
2360 (defvar org-export-filter-line-break-functions nil
2361 "List of functions applied to a transcoded line-break.
2362 Each filter is called with three arguments: the transcoded data,
2363 as a string, the back-end, as a symbol, and the communication
2364 channel, as a plist. It must return a string or nil.")
2366 (defvar org-export-filter-link-functions nil
2367 "List of functions applied to a transcoded link.
2368 Each filter is called with three arguments: the transcoded data,
2369 as a string, the back-end, as a symbol, and the communication
2370 channel, as a plist. It must return a string or nil.")
2372 (defvar org-export-filter-macro-functions nil
2373 "List of functions applied to a transcoded macro.
2374 Each filter is called with three arguments: the transcoded data,
2375 as a string, the back-end, as a symbol, and the communication
2376 channel, as a plist. It must return a string or nil.")
2378 (defvar org-export-filter-radio-target-functions nil
2379 "List of functions applied to a transcoded radio-target.
2380 Each filter is called with three arguments: the transcoded data,
2381 as a string, the back-end, as a symbol, and the communication
2382 channel, as a plist. It must return a string or nil.")
2384 (defvar org-export-filter-statistics-cookie-functions nil
2385 "List of functions applied to a transcoded statistics-cookie.
2386 Each filter is called with three arguments: the transcoded data,
2387 as a string, the back-end, as a symbol, and the communication
2388 channel, as a plist. It must return a string or nil.")
2390 (defvar org-export-filter-strike-through-functions nil
2391 "List of functions applied to transcoded strike-through text.
2392 Each filter is called with three arguments: the transcoded data,
2393 as a string, the back-end, as a symbol, and the communication
2394 channel, as a plist. It must return a string or nil.")
2396 (defvar org-export-filter-subscript-functions nil
2397 "List of functions applied to a transcoded subscript.
2398 Each filter is called with three arguments: the transcoded data,
2399 as a string, the back-end, as a symbol, and the communication
2400 channel, as a plist. It must return a string or nil.")
2402 (defvar org-export-filter-superscript-functions nil
2403 "List of functions applied to a transcoded superscript.
2404 Each filter is called with three arguments: the transcoded data,
2405 as a string, the back-end, as a symbol, and the communication
2406 channel, as a plist. It must return a string or nil.")
2408 (defvar org-export-filter-target-functions nil
2409 "List of functions applied to a transcoded target.
2410 Each filter is called with three arguments: the transcoded data,
2411 as a string, the back-end, as a symbol, and the communication
2412 channel, as a plist. It must return a string or nil.")
2414 (defvar org-export-filter-timestamp-functions nil
2415 "List of functions applied to a transcoded timestamp.
2416 Each filter is called with three arguments: the transcoded data,
2417 as a string, the back-end, as a symbol, and the communication
2418 channel, as a plist. It must return a string or nil.")
2420 (defvar org-export-filter-underline-functions nil
2421 "List of functions applied to transcoded underline text.
2422 Each filter is called with three arguments: the transcoded data,
2423 as a string, the back-end, as a symbol, and the communication
2424 channel, as a plist. It must return a string or nil.")
2426 (defvar org-export-filter-verbatim-functions nil
2427 "List of functions applied to transcoded verbatim text.
2428 Each filter is called with three arguments: the transcoded data,
2429 as a string, the back-end, as a symbol, and the communication
2430 channel, as a plist. It must return a string or nil.")
2433 ;;;; Filters Tools
2435 ;; Internal function `org-export-install-filters' installs filters
2436 ;; hard-coded in back-ends (developer filters) and filters from global
2437 ;; variables (user filters) in the communication channel.
2439 ;; Internal function `org-export-filter-apply-functions' takes care
2440 ;; about applying each filter in order to a given data. It ignores
2441 ;; filters returning a nil value but stops whenever a filter returns
2442 ;; an empty string.
2444 (defun org-export-filter-apply-functions (filters value info)
2445 "Call every function in FILTERS.
2447 Functions are called with arguments VALUE, current export
2448 back-end and INFO. A function returning a nil value will be
2449 skipped. If it returns the empty string, the process ends and
2450 VALUE is ignored.
2452 Call is done in a LIFO fashion, to be sure that developer
2453 specified filters, if any, are called first."
2454 (catch 'exit
2455 (dolist (filter filters value)
2456 (let ((result (funcall filter value (plist-get info :back-end) info)))
2457 (cond ((not result) value)
2458 ((equal value "") (throw 'exit nil))
2459 (t (setq value result)))))))
2461 (defun org-export-install-filters (info)
2462 "Install filters properties in communication channel.
2464 INFO is a plist containing the current communication channel.
2466 Return the updated communication channel."
2467 (let (plist)
2468 ;; Install user defined filters with `org-export-filters-alist'.
2469 (mapc (lambda (p)
2470 (setq plist (plist-put plist (car p) (eval (cdr p)))))
2471 org-export-filters-alist)
2472 ;; Prepend back-end specific filters to that list.
2473 (let ((back-end-filters (intern (format "org-%s-filters-alist"
2474 (plist-get info :back-end)))))
2475 (when (boundp back-end-filters)
2476 (mapc (lambda (p)
2477 ;; Single values get consed, lists are prepended.
2478 (let ((key (car p)) (value (cdr p)))
2479 (when value
2480 (setq plist
2481 (plist-put
2482 plist key
2483 (if (atom value) (cons value (plist-get plist key))
2484 (append value (plist-get plist key))))))))
2485 (eval back-end-filters))))
2486 ;; Return new communication channel.
2487 (org-combine-plists info plist)))
2491 ;;; Core functions
2493 ;; This is the room for the main function, `org-export-as', along with
2494 ;; its derivatives, `org-export-to-buffer' and `org-export-to-file'.
2495 ;; They differ only by the way they output the resulting code.
2497 ;; `org-export-output-file-name' is an auxiliary function meant to be
2498 ;; used with `org-export-to-file'. With a given extension, it tries
2499 ;; to provide a canonical file name to write export output to.
2501 ;; Note that `org-export-as' doesn't really parse the current buffer,
2502 ;; but a copy of it (with the same buffer-local variables and
2503 ;; visibility), where macros and include keywords are expanded and
2504 ;; Babel blocks are executed, if appropriate.
2505 ;; `org-export-with-current-buffer-copy' macro prepares that copy.
2507 ;; File inclusion is taken care of by
2508 ;; `org-export-expand-include-keyword' and
2509 ;; `org-export--prepare-file-contents'. Structure wise, including
2510 ;; a whole Org file in a buffer often makes little sense. For
2511 ;; example, if the file contains an headline and the include keyword
2512 ;; was within an item, the item should contain the headline. That's
2513 ;; why file inclusion should be done before any structure can be
2514 ;; associated to the file, that is before parsing.
2516 ;; Macro are expanded with `org-export-expand-macro'.
2518 (defun org-export-as
2519 (backend &optional subtreep visible-only body-only ext-plist noexpand)
2520 "Transcode current Org buffer into BACKEND code.
2522 If narrowing is active in the current buffer, only transcode its
2523 narrowed part.
2525 If a region is active, transcode that region.
2527 When optional argument SUBTREEP is non-nil, transcode the
2528 sub-tree at point, extracting information from the headline
2529 properties first.
2531 When optional argument VISIBLE-ONLY is non-nil, don't export
2532 contents of hidden elements.
2534 When optional argument BODY-ONLY is non-nil, only return body
2535 code, without preamble nor postamble.
2537 Optional argument EXT-PLIST, when provided, is a property list
2538 with external parameters overriding Org default settings, but
2539 still inferior to file-local settings.
2541 Optional argument NOEXPAND, when non-nil, prevents included files
2542 to be expanded and Babel code to be executed.
2544 Return code as a string."
2545 ;; Barf if BACKEND isn't registered.
2546 (org-export-barf-if-invalid-backend backend)
2547 (save-excursion
2548 (save-restriction
2549 ;; Narrow buffer to an appropriate region or subtree for
2550 ;; parsing. If parsing subtree, be sure to remove main headline
2551 ;; too.
2552 (cond ((org-region-active-p)
2553 (narrow-to-region (region-beginning) (region-end)))
2554 (subtreep
2555 (org-narrow-to-subtree)
2556 (goto-char (point-min))
2557 (forward-line)
2558 (narrow-to-region (point) (point-max))))
2559 ;; 1. Get export environment from original buffer. Also install
2560 ;; user's and developer's filters.
2561 (let* ((info (org-export-install-filters
2562 (org-export-get-environment backend subtreep ext-plist)))
2563 ;; 2. Get parse tree. Buffer isn't parsed directly.
2564 ;; Instead, a temporary copy is created, where include
2565 ;; keywords and macros are expanded and code blocks
2566 ;; are evaluated.
2567 (tree (org-export-with-current-buffer-copy
2568 (unless noexpand
2569 (org-export-expand-include-keyword)
2570 ;; Update radio targets since keyword
2571 ;; inclusion might have added some more.
2572 (org-update-radio-target-regexp)
2573 (org-export-expand-macro info)
2574 ;; TODO: Setting `org-current-export-file' is
2575 ;; required by Org Babel to properly resolve
2576 ;; noweb references. Once "org-exp.el" is
2577 ;; removed, modify
2578 ;; `org-export-blocks-preprocess' so it
2579 ;; accepts the value as an argument instead.
2580 (let ((org-current-export-file (current-buffer)))
2581 (org-export-blocks-preprocess)))
2582 (goto-char (point-min))
2583 ;; Run hook
2584 ;; `org-export-before-parsing-hook'. with current
2585 ;; back-end as argument.
2586 (run-hook-with-args
2587 'org-export-before-parsing-hook backend)
2588 ;; Eventually parse buffer.
2589 (org-element-parse-buffer nil visible-only))))
2590 ;; 3. Call parse-tree filters to get the final tree.
2591 (setq tree
2592 (org-export-filter-apply-functions
2593 (plist-get info :filter-parse-tree) tree info))
2594 ;; 4. Now tree is complete, compute its properties and add
2595 ;; them to communication channel.
2596 (setq info
2597 (org-combine-plists
2598 info (org-export-collect-tree-properties tree info)))
2599 ;; 5. Eventually transcode TREE. Wrap the resulting string
2600 ;; into a template, if required. Eventually call
2601 ;; final-output filter.
2602 (let* ((body (org-element-normalize-string (org-export-data tree info)))
2603 (template (cdr (assq 'template
2604 (plist-get info :translate-alist))))
2605 (output (org-export-filter-apply-functions
2606 (plist-get info :filter-final-output)
2607 (if (or (not (functionp template)) body-only) body
2608 (funcall template body info))
2609 info)))
2610 ;; Maybe add final OUTPUT to kill ring, then return it.
2611 (when org-export-copy-to-kill-ring (org-kill-new output))
2612 output)))))
2614 (defun org-export-to-buffer
2615 (backend buffer &optional subtreep visible-only body-only ext-plist noexpand)
2616 "Call `org-export-as' with output to a specified buffer.
2618 BACKEND is the back-end used for transcoding, as a symbol.
2620 BUFFER is the output buffer. If it already exists, it will be
2621 erased first, otherwise, it will be created.
2623 Optional arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY, EXT-PLIST
2624 and NOEXPAND are similar to those used in `org-export-as', which
2625 see.
2627 Return buffer."
2628 (let ((out (org-export-as
2629 backend subtreep visible-only body-only ext-plist noexpand))
2630 (buffer (get-buffer-create buffer)))
2631 (with-current-buffer buffer
2632 (erase-buffer)
2633 (insert out)
2634 (goto-char (point-min)))
2635 buffer))
2637 (defun org-export-to-file
2638 (backend file &optional subtreep visible-only body-only ext-plist noexpand)
2639 "Call `org-export-as' with output to a specified file.
2641 BACKEND is the back-end used for transcoding, as a symbol. FILE
2642 is the name of the output file, as a string.
2644 Optional arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY, EXT-PLIST
2645 and NOEXPAND are similar to those used in `org-export-as', which
2646 see.
2648 Return output file's name."
2649 ;; Checks for FILE permissions. `write-file' would do the same, but
2650 ;; we'd rather avoid needless transcoding of parse tree.
2651 (unless (file-writable-p file) (error "Output file not writable"))
2652 ;; Insert contents to a temporary buffer and write it to FILE.
2653 (let ((out (org-export-as
2654 backend subtreep visible-only body-only ext-plist noexpand)))
2655 (with-temp-buffer
2656 (insert out)
2657 (let ((coding-system-for-write org-export-coding-system))
2658 (write-file file))))
2659 ;; Return full path.
2660 file)
2662 (defun org-export-output-file-name (extension &optional subtreep pub-dir)
2663 "Return output file's name according to buffer specifications.
2665 EXTENSION is a string representing the output file extension,
2666 with the leading dot.
2668 With a non-nil optional argument SUBTREEP, try to determine
2669 output file's name by looking for \"EXPORT_FILE_NAME\" property
2670 of subtree at point.
2672 When optional argument PUB-DIR is set, use it as the publishing
2673 directory.
2675 When optional argument VISIBLE-ONLY is non-nil, don't export
2676 contents of hidden elements.
2678 Return file name as a string, or nil if it couldn't be
2679 determined."
2680 (let ((base-name
2681 ;; File name may come from EXPORT_FILE_NAME subtree property,
2682 ;; assuming point is at beginning of said sub-tree.
2683 (file-name-sans-extension
2684 (or (and subtreep
2685 (org-entry-get
2686 (save-excursion
2687 (ignore-errors (org-back-to-heading) (point)))
2688 "EXPORT_FILE_NAME" t))
2689 ;; File name may be extracted from buffer's associated
2690 ;; file, if any.
2691 (let ((visited-file (buffer-file-name (buffer-base-buffer))))
2692 (and visited-file (file-name-nondirectory visited-file)))
2693 ;; Can't determine file name on our own: Ask user.
2694 (let ((read-file-name-function
2695 (and org-completion-use-ido 'ido-read-file-name)))
2696 (read-file-name
2697 "Output file: " pub-dir nil nil nil
2698 (lambda (name)
2699 (string= (file-name-extension name t) extension))))))))
2700 ;; Build file name. Enforce EXTENSION over whatever user may have
2701 ;; come up with. PUB-DIR, if defined, always has precedence over
2702 ;; any provided path.
2703 (cond
2704 (pub-dir
2705 (concat (file-name-as-directory pub-dir)
2706 (file-name-nondirectory base-name)
2707 extension))
2708 ((file-name-absolute-p base-name) (concat base-name extension))
2709 (t (concat (file-name-as-directory ".") base-name extension)))))
2711 (defmacro org-export-with-current-buffer-copy (&rest body)
2712 "Apply BODY in a copy of the current buffer.
2714 The copy preserves local variables and visibility of the original
2715 buffer.
2717 Point is at buffer's beginning when BODY is applied."
2718 (declare (debug (body)))
2719 (org-with-gensyms (original-buffer offset buffer-string overlays region)
2720 `(let* ((,original-buffer (current-buffer))
2721 (,region (list (point-min) (point-max)))
2722 (,buffer-string (org-with-wide-buffer (buffer-string)))
2723 (,overlays (mapcar 'copy-overlay (apply 'overlays-in ,region))))
2724 (with-temp-buffer
2725 (let ((buffer-invisibility-spec nil))
2726 (org-clone-local-variables
2727 ,original-buffer
2728 "^\\(org-\\|orgtbl-\\|major-mode$\\|outline-\\(regexp\\|level\\)$\\)")
2729 (insert ,buffer-string)
2730 (apply 'narrow-to-region ,region)
2731 (mapc (lambda (ov)
2732 (move-overlay
2733 ov (overlay-start ov) (overlay-end ov) (current-buffer)))
2734 ,overlays)
2735 (goto-char (point-min))
2736 (progn ,@body))))))
2738 (defun org-export-expand-macro (info)
2739 "Expand every macro in buffer.
2740 INFO is a plist containing export options and buffer properties."
2741 ;; First update macro templates since #+INCLUDE keywords might have
2742 ;; added some new ones.
2743 (org-macro-initialize-templates)
2744 (org-macro-replace-all
2745 ;; Before expanding macros, install {{{author}}}, {{{date}}},
2746 ;; {{{email}}} and {{{title}}} templates.
2747 (nconc
2748 (list (cons "author"
2749 (org-element-interpret-data (plist-get info :author)))
2750 (cons "date"
2751 (org-element-interpret-data (plist-get info :date)))
2752 ;; EMAIL is not a parsed keyword: store it as-is.
2753 (cons "email" (or (plist-get info :email) ""))
2754 (cons "title"
2755 (org-element-interpret-data (plist-get info :title))))
2756 org-macro-templates)))
2758 (defun org-export-expand-include-keyword (&optional included dir)
2759 "Expand every include keyword in buffer.
2760 Optional argument INCLUDED is a list of included file names along
2761 with their line restriction, when appropriate. It is used to
2762 avoid infinite recursion. Optional argument DIR is the current
2763 working directory. It is used to properly resolve relative
2764 paths."
2765 (let ((case-fold-search t))
2766 (goto-char (point-min))
2767 (while (re-search-forward "^[ \t]*#\\+INCLUDE: \\(.*\\)" nil t)
2768 (when (eq (org-element-type (save-match-data (org-element-at-point)))
2769 'keyword)
2770 (beginning-of-line)
2771 ;; Extract arguments from keyword's value.
2772 (let* ((value (match-string 1))
2773 (ind (org-get-indentation))
2774 (file (and (string-match "^\"\\(\\S-+\\)\"" value)
2775 (prog1 (expand-file-name (match-string 1 value) dir)
2776 (setq value (replace-match "" nil nil value)))))
2777 (lines
2778 (and (string-match
2779 ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\"" value)
2780 (prog1 (match-string 1 value)
2781 (setq value (replace-match "" nil nil value)))))
2782 (env (cond ((string-match "\\<example\\>" value) 'example)
2783 ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
2784 (match-string 1 value))))
2785 ;; Minimal level of included file defaults to the child
2786 ;; level of the current headline, if any, or one. It
2787 ;; only applies is the file is meant to be included as
2788 ;; an Org one.
2789 (minlevel
2790 (and (not env)
2791 (if (string-match ":minlevel +\\([0-9]+\\)" value)
2792 (prog1 (string-to-number (match-string 1 value))
2793 (setq value (replace-match "" nil nil value)))
2794 (let ((cur (org-current-level)))
2795 (if cur (1+ (org-reduced-level cur)) 1))))))
2796 ;; Remove keyword.
2797 (delete-region (point) (progn (forward-line) (point)))
2798 (cond
2799 ((not (file-readable-p file)) (error "Cannot include file %s" file))
2800 ;; Check if files has already been parsed. Look after
2801 ;; inclusion lines too, as different parts of the same file
2802 ;; can be included too.
2803 ((member (list file lines) included)
2804 (error "Recursive file inclusion: %s" file))
2806 (cond
2807 ((eq env 'example)
2808 (insert
2809 (let ((ind-str (make-string ind ? ))
2810 (contents
2811 (org-escape-code-in-string
2812 (org-export--prepare-file-contents file lines))))
2813 (format "%s#+BEGIN_EXAMPLE\n%s%s#+END_EXAMPLE\n"
2814 ind-str contents ind-str))))
2815 ((stringp env)
2816 (insert
2817 (let ((ind-str (make-string ind ? ))
2818 (contents
2819 (org-escape-code-in-string
2820 (org-export--prepare-file-contents file lines))))
2821 (format "%s#+BEGIN_SRC %s\n%s%s#+END_SRC\n"
2822 ind-str env contents ind-str))))
2824 (insert
2825 (with-temp-buffer
2826 (org-mode)
2827 (insert
2828 (org-export--prepare-file-contents file lines ind minlevel))
2829 (org-export-expand-include-keyword
2830 (cons (list file lines) included)
2831 (file-name-directory file))
2832 (buffer-string))))))))))))
2834 (defun org-export--prepare-file-contents (file &optional lines ind minlevel)
2835 "Prepare the contents of FILE for inclusion and return them as a string.
2837 When optional argument LINES is a string specifying a range of
2838 lines, include only those lines.
2840 Optional argument IND, when non-nil, is an integer specifying the
2841 global indentation of returned contents. Since its purpose is to
2842 allow an included file to stay in the same environment it was
2843 created \(i.e. a list item), it doesn't apply past the first
2844 headline encountered.
2846 Optional argument MINLEVEL, when non-nil, is an integer
2847 specifying the level that any top-level headline in the included
2848 file should have."
2849 (with-temp-buffer
2850 (insert-file-contents file)
2851 (when lines
2852 (let* ((lines (split-string lines "-"))
2853 (lbeg (string-to-number (car lines)))
2854 (lend (string-to-number (cadr lines)))
2855 (beg (if (zerop lbeg) (point-min)
2856 (goto-char (point-min))
2857 (forward-line (1- lbeg))
2858 (point)))
2859 (end (if (zerop lend) (point-max)
2860 (goto-char (point-min))
2861 (forward-line (1- lend))
2862 (point))))
2863 (narrow-to-region beg end)))
2864 ;; Remove blank lines at beginning and end of contents. The logic
2865 ;; behind that removal is that blank lines around include keyword
2866 ;; override blank lines in included file.
2867 (goto-char (point-min))
2868 (org-skip-whitespace)
2869 (beginning-of-line)
2870 (delete-region (point-min) (point))
2871 (goto-char (point-max))
2872 (skip-chars-backward " \r\t\n")
2873 (forward-line)
2874 (delete-region (point) (point-max))
2875 ;; If IND is set, preserve indentation of include keyword until
2876 ;; the first headline encountered.
2877 (when ind
2878 (unless (eq major-mode 'org-mode) (org-mode))
2879 (goto-char (point-min))
2880 (let ((ind-str (make-string ind ? )))
2881 (while (not (or (eobp) (looking-at org-outline-regexp-bol)))
2882 ;; Do not move footnote definitions out of column 0.
2883 (unless (and (looking-at org-footnote-definition-re)
2884 (eq (org-element-type (org-element-at-point))
2885 'footnote-definition))
2886 (insert ind-str))
2887 (forward-line))))
2888 ;; When MINLEVEL is specified, compute minimal level for headlines
2889 ;; in the file (CUR-MIN), and remove stars to each headline so
2890 ;; that headlines with minimal level have a level of MINLEVEL.
2891 (when minlevel
2892 (unless (eq major-mode 'org-mode) (org-mode))
2893 (org-with-limited-levels
2894 (let ((levels (org-map-entries
2895 (lambda () (org-reduced-level (org-current-level))))))
2896 (when levels
2897 (let ((offset (- minlevel (apply 'min levels))))
2898 (unless (zerop offset)
2899 (when org-odd-levels-only (setq offset (* offset 2)))
2900 ;; Only change stars, don't bother moving whole
2901 ;; sections.
2902 (org-map-entries
2903 (lambda () (if (< offset 0) (delete-char (abs offset))
2904 (insert (make-string offset ?*)))))))))))
2905 (buffer-string)))
2908 ;;; Tools For Back-Ends
2910 ;; A whole set of tools is available to help build new exporters. Any
2911 ;; function general enough to have its use across many back-ends
2912 ;; should be added here.
2914 ;;;; For Affiliated Keywords
2916 ;; `org-export-read-attribute' reads a property from a given element
2917 ;; as a plist. It can be used to normalize affiliated keywords'
2918 ;; syntax.
2920 ;; Since captions can span over multiple lines and accept dual values,
2921 ;; their internal representation is a bit tricky. Therefore,
2922 ;; `org-export-get-caption' transparently returns a given element's
2923 ;; caption as a secondary string.
2925 (defun org-export-read-attribute (attribute element &optional property)
2926 "Turn ATTRIBUTE property from ELEMENT into a plist.
2928 When optional argument PROPERTY is non-nil, return the value of
2929 that property within attributes.
2931 This function assumes attributes are defined as \":keyword
2932 value\" pairs. It is appropriate for `:attr_html' like
2933 properties."
2934 (let ((attributes
2935 (let ((value (org-element-property attribute element)))
2936 (and value
2937 (read (format "(%s)" (mapconcat 'identity value " ")))))))
2938 (if property (plist-get attributes property) attributes)))
2940 (defun org-export-get-caption (element &optional shortp)
2941 "Return caption from ELEMENT as a secondary string.
2943 When optional argument SHORTP is non-nil, return short caption,
2944 as a secondary string, instead.
2946 Caption lines are separated by a white space."
2947 (let ((full-caption (org-element-property :caption element)) caption)
2948 (dolist (line full-caption (cdr caption))
2949 (let ((cap (funcall (if shortp 'cdr 'car) line)))
2950 (when cap
2951 (setq caption (nconc (list " ") (copy-sequence cap) caption)))))))
2954 ;;;; For Export Snippets
2956 ;; Every export snippet is transmitted to the back-end. Though, the
2957 ;; latter will only retain one type of export-snippet, ignoring
2958 ;; others, based on the former's target back-end. The function
2959 ;; `org-export-snippet-backend' returns that back-end for a given
2960 ;; export-snippet.
2962 (defun org-export-snippet-backend (export-snippet)
2963 "Return EXPORT-SNIPPET targeted back-end as a symbol.
2964 Translation, with `org-export-snippet-translation-alist', is
2965 applied."
2966 (let ((back-end (org-element-property :back-end export-snippet)))
2967 (intern
2968 (or (cdr (assoc back-end org-export-snippet-translation-alist))
2969 back-end))))
2972 ;;;; For Footnotes
2974 ;; `org-export-collect-footnote-definitions' is a tool to list
2975 ;; actually used footnotes definitions in the whole parse tree, or in
2976 ;; an headline, in order to add footnote listings throughout the
2977 ;; transcoded data.
2979 ;; `org-export-footnote-first-reference-p' is a predicate used by some
2980 ;; back-ends, when they need to attach the footnote definition only to
2981 ;; the first occurrence of the corresponding label.
2983 ;; `org-export-get-footnote-definition' and
2984 ;; `org-export-get-footnote-number' provide easier access to
2985 ;; additional information relative to a footnote reference.
2987 (defun org-export-collect-footnote-definitions (data info)
2988 "Return an alist between footnote numbers, labels and definitions.
2990 DATA is the parse tree from which definitions are collected.
2991 INFO is the plist used as a communication channel.
2993 Definitions are sorted by order of references. They either
2994 appear as Org data or as a secondary string for inlined
2995 footnotes. Unreferenced definitions are ignored."
2996 (let* (num-alist
2997 collect-fn ; for byte-compiler.
2998 (collect-fn
2999 (function
3000 (lambda (data)
3001 ;; Collect footnote number, label and definition in DATA.
3002 (org-element-map
3003 data 'footnote-reference
3004 (lambda (fn)
3005 (when (org-export-footnote-first-reference-p fn info)
3006 (let ((def (org-export-get-footnote-definition fn info)))
3007 (push
3008 (list (org-export-get-footnote-number fn info)
3009 (org-element-property :label fn)
3010 def)
3011 num-alist)
3012 ;; Also search in definition for nested footnotes.
3013 (when (eq (org-element-property :type fn) 'standard)
3014 (funcall collect-fn def)))))
3015 ;; Don't enter footnote definitions since it will happen
3016 ;; when their first reference is found.
3017 info nil 'footnote-definition)))))
3018 (funcall collect-fn (plist-get info :parse-tree))
3019 (reverse num-alist)))
3021 (defun org-export-footnote-first-reference-p (footnote-reference info)
3022 "Non-nil when a footnote reference is the first one for its label.
3024 FOOTNOTE-REFERENCE is the footnote reference being considered.
3025 INFO is the plist used as a communication channel."
3026 (let ((label (org-element-property :label footnote-reference)))
3027 ;; Anonymous footnotes are always a first reference.
3028 (if (not label) t
3029 ;; Otherwise, return the first footnote with the same LABEL and
3030 ;; test if it is equal to FOOTNOTE-REFERENCE.
3031 (let* (search-refs ; for byte-compiler.
3032 (search-refs
3033 (function
3034 (lambda (data)
3035 (org-element-map
3036 data 'footnote-reference
3037 (lambda (fn)
3038 (cond
3039 ((string= (org-element-property :label fn) label)
3040 (throw 'exit fn))
3041 ;; If FN isn't inlined, be sure to traverse its
3042 ;; definition before resuming search. See
3043 ;; comments in `org-export-get-footnote-number'
3044 ;; for more information.
3045 ((eq (org-element-property :type fn) 'standard)
3046 (funcall search-refs
3047 (org-export-get-footnote-definition fn info)))))
3048 ;; Don't enter footnote definitions since it will
3049 ;; happen when their first reference is found.
3050 info 'first-match 'footnote-definition)))))
3051 (eq (catch 'exit (funcall search-refs (plist-get info :parse-tree)))
3052 footnote-reference)))))
3054 (defun org-export-get-footnote-definition (footnote-reference info)
3055 "Return definition of FOOTNOTE-REFERENCE as parsed data.
3056 INFO is the plist used as a communication channel."
3057 (let ((label (org-element-property :label footnote-reference)))
3058 (or (org-element-property :inline-definition footnote-reference)
3059 (cdr (assoc label (plist-get info :footnote-definition-alist))))))
3061 (defun org-export-get-footnote-number (footnote info)
3062 "Return number associated to a footnote.
3064 FOOTNOTE is either a footnote reference or a footnote definition.
3065 INFO is the plist used as a communication channel."
3066 (let* ((label (org-element-property :label footnote))
3067 seen-refs
3068 search-ref ; For byte-compiler.
3069 (search-ref
3070 (function
3071 (lambda (data)
3072 ;; Search footnote references through DATA, filling
3073 ;; SEEN-REFS along the way.
3074 (org-element-map
3075 data 'footnote-reference
3076 (lambda (fn)
3077 (let ((fn-lbl (org-element-property :label fn)))
3078 (cond
3079 ;; Anonymous footnote match: return number.
3080 ((and (not fn-lbl) (eq fn footnote))
3081 (throw 'exit (1+ (length seen-refs))))
3082 ;; Labels match: return number.
3083 ((and label (string= label fn-lbl))
3084 (throw 'exit (1+ (length seen-refs))))
3085 ;; Anonymous footnote: it's always a new one. Also,
3086 ;; be sure to return nil from the `cond' so
3087 ;; `first-match' doesn't get us out of the loop.
3088 ((not fn-lbl) (push 'inline seen-refs) nil)
3089 ;; Label not seen so far: add it so SEEN-REFS.
3091 ;; Also search for subsequent references in
3092 ;; footnote definition so numbering follows reading
3093 ;; logic. Note that we don't have to care about
3094 ;; inline definitions, since `org-element-map'
3095 ;; already traverses them at the right time.
3097 ;; Once again, return nil to stay in the loop.
3098 ((not (member fn-lbl seen-refs))
3099 (push fn-lbl seen-refs)
3100 (funcall search-ref
3101 (org-export-get-footnote-definition fn info))
3102 nil))))
3103 ;; Don't enter footnote definitions since it will happen
3104 ;; when their first reference is found.
3105 info 'first-match 'footnote-definition)))))
3106 (catch 'exit (funcall search-ref (plist-get info :parse-tree)))))
3109 ;;;; For Headlines
3111 ;; `org-export-get-relative-level' is a shortcut to get headline
3112 ;; level, relatively to the lower headline level in the parsed tree.
3114 ;; `org-export-get-headline-number' returns the section number of an
3115 ;; headline, while `org-export-number-to-roman' allows to convert it
3116 ;; to roman numbers.
3118 ;; `org-export-low-level-p', `org-export-first-sibling-p' and
3119 ;; `org-export-last-sibling-p' are three useful predicates when it
3120 ;; comes to fulfill the `:headline-levels' property.
3122 (defun org-export-get-relative-level (headline info)
3123 "Return HEADLINE relative level within current parsed tree.
3124 INFO is a plist holding contextual information."
3125 (+ (org-element-property :level headline)
3126 (or (plist-get info :headline-offset) 0)))
3128 (defun org-export-low-level-p (headline info)
3129 "Non-nil when HEADLINE is considered as low level.
3131 INFO is a plist used as a communication channel.
3133 A low level headlines has a relative level greater than
3134 `:headline-levels' property value.
3136 Return value is the difference between HEADLINE relative level
3137 and the last level being considered as high enough, or nil."
3138 (let ((limit (plist-get info :headline-levels)))
3139 (when (wholenump limit)
3140 (let ((level (org-export-get-relative-level headline info)))
3141 (and (> level limit) (- level limit))))))
3143 (defun org-export-get-headline-number (headline info)
3144 "Return HEADLINE numbering as a list of numbers.
3145 INFO is a plist holding contextual information."
3146 (cdr (assoc headline (plist-get info :headline-numbering))))
3148 (defun org-export-numbered-headline-p (headline info)
3149 "Return a non-nil value if HEADLINE element should be numbered.
3150 INFO is a plist used as a communication channel."
3151 (let ((sec-num (plist-get info :section-numbers))
3152 (level (org-export-get-relative-level headline info)))
3153 (if (wholenump sec-num) (<= level sec-num) sec-num)))
3155 (defun org-export-number-to-roman (n)
3156 "Convert integer N into a roman numeral."
3157 (let ((roman '((1000 . "M") (900 . "CM") (500 . "D") (400 . "CD")
3158 ( 100 . "C") ( 90 . "XC") ( 50 . "L") ( 40 . "XL")
3159 ( 10 . "X") ( 9 . "IX") ( 5 . "V") ( 4 . "IV")
3160 ( 1 . "I")))
3161 (res ""))
3162 (if (<= n 0)
3163 (number-to-string n)
3164 (while roman
3165 (if (>= n (caar roman))
3166 (setq n (- n (caar roman))
3167 res (concat res (cdar roman)))
3168 (pop roman)))
3169 res)))
3171 (defun org-export-get-tags (element info &optional tags inherited)
3172 "Return list of tags associated to ELEMENT.
3174 ELEMENT has either an `headline' or an `inlinetask' type. INFO
3175 is a plist used as a communication channel.
3177 Select tags (see `org-export-select-tags') and exclude tags (see
3178 `org-export-exclude-tags') are removed from the list.
3180 When non-nil, optional argument TAGS should be a list of strings.
3181 Any tag belonging to this list will also be removed.
3183 When optional argument INHERITED is non-nil, tags can also be
3184 inherited from parent headlines.."
3185 (org-remove-if
3186 (lambda (tag) (or (member tag (plist-get info :select-tags))
3187 (member tag (plist-get info :exclude-tags))
3188 (member tag tags)))
3189 (if (not inherited) (org-element-property :tags element)
3190 ;; Build complete list of inherited tags.
3191 (let ((current-tag-list (org-element-property :tags element)))
3192 (mapc
3193 (lambda (parent)
3194 (mapc
3195 (lambda (tag)
3196 (when (and (memq (org-element-type parent) '(headline inlinetask))
3197 (not (member tag current-tag-list)))
3198 (push tag current-tag-list)))
3199 (org-element-property :tags parent)))
3200 (org-export-get-genealogy element))
3201 current-tag-list))))
3203 (defun org-export-get-node-property (property blob &optional inherited)
3204 "Return node PROPERTY value for BLOB.
3206 PROPERTY is normalized symbol (i.e. `:cookie-data'). BLOB is an
3207 element or object.
3209 If optional argument INHERITED is non-nil, the value can be
3210 inherited from a parent headline.
3212 Return value is a string or nil."
3213 (let ((headline (if (eq (org-element-type blob) 'headline) blob
3214 (org-export-get-parent-headline blob))))
3215 (if (not inherited) (org-element-property property blob)
3216 (let ((parent headline) value)
3217 (catch 'found
3218 (while parent
3219 (when (plist-member (nth 1 parent) property)
3220 (throw 'found (org-element-property property parent)))
3221 (setq parent (org-element-property :parent parent))))))))
3223 (defun org-export-first-sibling-p (headline info)
3224 "Non-nil when HEADLINE is the first sibling in its sub-tree.
3225 INFO is a plist used as a communication channel."
3226 (not (eq (org-element-type (org-export-get-previous-element headline info))
3227 'headline)))
3229 (defun org-export-last-sibling-p (headline info)
3230 "Non-nil when HEADLINE is the last sibling in its sub-tree.
3231 INFO is a plist used as a communication channel."
3232 (not (org-export-get-next-element headline info)))
3235 ;;;; For Links
3237 ;; `org-export-solidify-link-text' turns a string into a safer version
3238 ;; for links, replacing most non-standard characters with hyphens.
3240 ;; `org-export-get-coderef-format' returns an appropriate format
3241 ;; string for coderefs.
3243 ;; `org-export-inline-image-p' returns a non-nil value when the link
3244 ;; provided should be considered as an inline image.
3246 ;; `org-export-resolve-fuzzy-link' searches destination of fuzzy links
3247 ;; (i.e. links with "fuzzy" as type) within the parsed tree, and
3248 ;; returns an appropriate unique identifier when found, or nil.
3250 ;; `org-export-resolve-id-link' returns the first headline with
3251 ;; specified id or custom-id in parse tree, the path to the external
3252 ;; file with the id or nil when neither was found.
3254 ;; `org-export-resolve-coderef' associates a reference to a line
3255 ;; number in the element it belongs, or returns the reference itself
3256 ;; when the element isn't numbered.
3258 (defun org-export-solidify-link-text (s)
3259 "Take link text S and make a safe target out of it."
3260 (save-match-data
3261 (mapconcat 'identity (org-split-string s "[^a-zA-Z0-9_.-]+") "-")))
3263 (defun org-export-get-coderef-format (path desc)
3264 "Return format string for code reference link.
3265 PATH is the link path. DESC is its description."
3266 (save-match-data
3267 (cond ((not desc) "%s")
3268 ((string-match (regexp-quote (concat "(" path ")")) desc)
3269 (replace-match "%s" t t desc))
3270 (t desc))))
3272 (defun org-export-inline-image-p (link &optional rules)
3273 "Non-nil if LINK object points to an inline image.
3275 Optional argument is a set of RULES defining inline images. It
3276 is an alist where associations have the following shape:
3278 \(TYPE . REGEXP)
3280 Applying a rule means apply REGEXP against LINK's path when its
3281 type is TYPE. The function will return a non-nil value if any of
3282 the provided rules is non-nil. The default rule is
3283 `org-export-default-inline-image-rule'.
3285 This only applies to links without a description."
3286 (and (not (org-element-contents link))
3287 (let ((case-fold-search t)
3288 (rules (or rules org-export-default-inline-image-rule)))
3289 (catch 'exit
3290 (mapc
3291 (lambda (rule)
3292 (and (string= (org-element-property :type link) (car rule))
3293 (string-match (cdr rule)
3294 (org-element-property :path link))
3295 (throw 'exit t)))
3296 rules)
3297 ;; Return nil if no rule matched.
3298 nil))))
3300 (defun org-export-resolve-coderef (ref info)
3301 "Resolve a code reference REF.
3303 INFO is a plist used as a communication channel.
3305 Return associated line number in source code, or REF itself,
3306 depending on src-block or example element's switches."
3307 (org-element-map
3308 (plist-get info :parse-tree) '(example-block src-block)
3309 (lambda (el)
3310 (with-temp-buffer
3311 (insert (org-trim (org-element-property :value el)))
3312 (let* ((label-fmt (regexp-quote
3313 (or (org-element-property :label-fmt el)
3314 org-coderef-label-format)))
3315 (ref-re
3316 (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
3317 (replace-regexp-in-string "%s" ref label-fmt nil t))))
3318 ;; Element containing REF is found. Resolve it to either
3319 ;; a label or a line number, as needed.
3320 (when (re-search-backward ref-re nil t)
3321 (cond
3322 ((org-element-property :use-labels el) ref)
3323 ((eq (org-element-property :number-lines el) 'continued)
3324 (+ (org-export-get-loc el info) (line-number-at-pos)))
3325 (t (line-number-at-pos)))))))
3326 info 'first-match))
3328 (defun org-export-resolve-fuzzy-link (link info)
3329 "Return LINK destination.
3331 INFO is a plist holding contextual information.
3333 Return value can be an object, an element, or nil:
3335 - If LINK path matches a target object (i.e. <<path>>) or
3336 element (i.e. \"#+TARGET: path\"), return it.
3338 - If LINK path exactly matches the name affiliated keyword
3339 \(i.e. #+NAME: path) of an element, return that element.
3341 - If LINK path exactly matches any headline name, return that
3342 element. If more than one headline share that name, priority
3343 will be given to the one with the closest common ancestor, if
3344 any, or the first one in the parse tree otherwise.
3346 - Otherwise, return nil.
3348 Assume LINK type is \"fuzzy\"."
3349 (let* ((path (org-element-property :path link))
3350 (match-title-p (eq (aref path 0) ?*)))
3351 (cond
3352 ;; First try to find a matching "<<path>>" unless user specified
3353 ;; he was looking for an headline (path starts with a *
3354 ;; character).
3355 ((and (not match-title-p)
3356 (loop for target in (plist-get info :target-list)
3357 when (string= (org-element-property :value target) path)
3358 return target)))
3359 ;; Then try to find an element with a matching "#+NAME: path"
3360 ;; affiliated keyword.
3361 ((and (not match-title-p)
3362 (org-element-map
3363 (plist-get info :parse-tree) org-element-all-elements
3364 (lambda (el)
3365 (when (string= (org-element-property :name el) path) el))
3366 info 'first-match)))
3367 ;; Last case: link either points to an headline or to
3368 ;; nothingness. Try to find the source, with priority given to
3369 ;; headlines with the closest common ancestor. If such candidate
3370 ;; is found, return it, otherwise return nil.
3372 (let ((find-headline
3373 (function
3374 ;; Return first headline whose `:raw-value' property
3375 ;; is NAME in parse tree DATA, or nil.
3376 (lambda (name data)
3377 (org-element-map
3378 data 'headline
3379 (lambda (headline)
3380 (when (string=
3381 (org-element-property :raw-value headline)
3382 name)
3383 headline))
3384 info 'first-match)))))
3385 ;; Search among headlines sharing an ancestor with link,
3386 ;; from closest to farthest.
3387 (or (catch 'exit
3388 (mapc
3389 (lambda (parent)
3390 (when (eq (org-element-type parent) 'headline)
3391 (let ((foundp (funcall find-headline path parent)))
3392 (when foundp (throw 'exit foundp)))))
3393 (org-export-get-genealogy link)) nil)
3394 ;; No match with a common ancestor: try the full parse-tree.
3395 (funcall find-headline
3396 (if match-title-p (substring path 1) path)
3397 (plist-get info :parse-tree))))))))
3399 (defun org-export-resolve-id-link (link info)
3400 "Return headline referenced as LINK destination.
3402 INFO is a plist used as a communication channel.
3404 Return value can be the headline element matched in current parse
3405 tree, a file name or nil. Assume LINK type is either \"id\" or
3406 \"custom-id\"."
3407 (let ((id (org-element-property :path link)))
3408 ;; First check if id is within the current parse tree.
3409 (or (org-element-map
3410 (plist-get info :parse-tree) 'headline
3411 (lambda (headline)
3412 (when (or (string= (org-element-property :id headline) id)
3413 (string= (org-element-property :custom-id headline) id))
3414 headline))
3415 info 'first-match)
3416 ;; Otherwise, look for external files.
3417 (cdr (assoc id (plist-get info :id-alist))))))
3419 (defun org-export-resolve-radio-link (link info)
3420 "Return radio-target object referenced as LINK destination.
3422 INFO is a plist used as a communication channel.
3424 Return value can be a radio-target object or nil. Assume LINK
3425 has type \"radio\"."
3426 (let ((path (org-element-property :path link)))
3427 (org-element-map
3428 (plist-get info :parse-tree) 'radio-target
3429 (lambda (radio)
3430 (when (equal (org-element-property :value radio) path) radio))
3431 info 'first-match)))
3434 ;;;; For References
3436 ;; `org-export-get-ordinal' associates a sequence number to any object
3437 ;; or element.
3439 (defun org-export-get-ordinal (element info &optional types predicate)
3440 "Return ordinal number of an element or object.
3442 ELEMENT is the element or object considered. INFO is the plist
3443 used as a communication channel.
3445 Optional argument TYPES, when non-nil, is a list of element or
3446 object types, as symbols, that should also be counted in.
3447 Otherwise, only provided element's type is considered.
3449 Optional argument PREDICATE is a function returning a non-nil
3450 value if the current element or object should be counted in. It
3451 accepts two arguments: the element or object being considered and
3452 the plist used as a communication channel. This allows to count
3453 only a certain type of objects (i.e. inline images).
3455 Return value is a list of numbers if ELEMENT is an headline or an
3456 item. It is nil for keywords. It represents the footnote number
3457 for footnote definitions and footnote references. If ELEMENT is
3458 a target, return the same value as if ELEMENT was the closest
3459 table, item or headline containing the target. In any other
3460 case, return the sequence number of ELEMENT among elements or
3461 objects of the same type."
3462 ;; A target keyword, representing an invisible target, never has
3463 ;; a sequence number.
3464 (unless (eq (org-element-type element) 'keyword)
3465 ;; Ordinal of a target object refer to the ordinal of the closest
3466 ;; table, item, or headline containing the object.
3467 (when (eq (org-element-type element) 'target)
3468 (setq element
3469 (loop for parent in (org-export-get-genealogy element)
3470 when
3471 (memq
3472 (org-element-type parent)
3473 '(footnote-definition footnote-reference headline item
3474 table))
3475 return parent)))
3476 (case (org-element-type element)
3477 ;; Special case 1: An headline returns its number as a list.
3478 (headline (org-export-get-headline-number element info))
3479 ;; Special case 2: An item returns its number as a list.
3480 (item (let ((struct (org-element-property :structure element)))
3481 (org-list-get-item-number
3482 (org-element-property :begin element)
3483 struct
3484 (org-list-prevs-alist struct)
3485 (org-list-parents-alist struct))))
3486 ((footnote-definition footnote-reference)
3487 (org-export-get-footnote-number element info))
3488 (otherwise
3489 (let ((counter 0))
3490 ;; Increment counter until ELEMENT is found again.
3491 (org-element-map
3492 (plist-get info :parse-tree) (or types (org-element-type element))
3493 (lambda (el)
3494 (cond
3495 ((eq element el) (1+ counter))
3496 ((not predicate) (incf counter) nil)
3497 ((funcall predicate el info) (incf counter) nil)))
3498 info 'first-match))))))
3501 ;;;; For Src-Blocks
3503 ;; `org-export-get-loc' counts number of code lines accumulated in
3504 ;; src-block or example-block elements with a "+n" switch until
3505 ;; a given element, excluded. Note: "-n" switches reset that count.
3507 ;; `org-export-unravel-code' extracts source code (along with a code
3508 ;; references alist) from an `element-block' or `src-block' type
3509 ;; element.
3511 ;; `org-export-format-code' applies a formatting function to each line
3512 ;; of code, providing relative line number and code reference when
3513 ;; appropriate. Since it doesn't access the original element from
3514 ;; which the source code is coming, it expects from the code calling
3515 ;; it to know if lines should be numbered and if code references
3516 ;; should appear.
3518 ;; Eventually, `org-export-format-code-default' is a higher-level
3519 ;; function (it makes use of the two previous functions) which handles
3520 ;; line numbering and code references inclusion, and returns source
3521 ;; code in a format suitable for plain text or verbatim output.
3523 (defun org-export-get-loc (element info)
3524 "Return accumulated lines of code up to ELEMENT.
3526 INFO is the plist used as a communication channel.
3528 ELEMENT is excluded from count."
3529 (let ((loc 0))
3530 (org-element-map
3531 (plist-get info :parse-tree)
3532 `(src-block example-block ,(org-element-type element))
3533 (lambda (el)
3534 (cond
3535 ;; ELEMENT is reached: Quit the loop.
3536 ((eq el element))
3537 ;; Only count lines from src-block and example-block elements
3538 ;; with a "+n" or "-n" switch. A "-n" switch resets counter.
3539 ((not (memq (org-element-type el) '(src-block example-block))) nil)
3540 ((let ((linums (org-element-property :number-lines el)))
3541 (when linums
3542 ;; Accumulate locs or reset them.
3543 (let ((lines (org-count-lines
3544 (org-trim (org-element-property :value el)))))
3545 (setq loc (if (eq linums 'new) lines (+ loc lines))))))
3546 ;; Return nil to stay in the loop.
3547 nil)))
3548 info 'first-match)
3549 ;; Return value.
3550 loc))
3552 (defun org-export-unravel-code (element)
3553 "Clean source code and extract references out of it.
3555 ELEMENT has either a `src-block' an `example-block' type.
3557 Return a cons cell whose CAR is the source code, cleaned from any
3558 reference and protective comma and CDR is an alist between
3559 relative line number (integer) and name of code reference on that
3560 line (string)."
3561 (let* ((line 0) refs
3562 ;; Get code and clean it. Remove blank lines at its
3563 ;; beginning and end.
3564 (code (let ((c (replace-regexp-in-string
3565 "\\`\\([ \t]*\n\\)+" ""
3566 (replace-regexp-in-string
3567 "\\(:?[ \t]*\n\\)*[ \t]*\\'" "\n"
3568 (org-element-property :value element)))))
3569 ;; If appropriate, remove global indentation.
3570 (if (or org-src-preserve-indentation
3571 (org-element-property :preserve-indent element))
3573 (org-remove-indentation c))))
3574 ;; Get format used for references.
3575 (label-fmt (regexp-quote
3576 (or (org-element-property :label-fmt element)
3577 org-coderef-label-format)))
3578 ;; Build a regexp matching a loc with a reference.
3579 (with-ref-re
3580 (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)[ \t]*\\)$"
3581 (replace-regexp-in-string
3582 "%s" "\\([-a-zA-Z0-9_ ]+\\)" label-fmt nil t))))
3583 ;; Return value.
3584 (cons
3585 ;; Code with references removed.
3586 (org-element-normalize-string
3587 (mapconcat
3588 (lambda (loc)
3589 (incf line)
3590 (if (not (string-match with-ref-re loc)) loc
3591 ;; Ref line: remove ref, and signal its position in REFS.
3592 (push (cons line (match-string 3 loc)) refs)
3593 (replace-match "" nil nil loc 1)))
3594 (org-split-string code "\n") "\n"))
3595 ;; Reference alist.
3596 refs)))
3598 (defun org-export-format-code (code fun &optional num-lines ref-alist)
3599 "Format CODE by applying FUN line-wise and return it.
3601 CODE is a string representing the code to format. FUN is
3602 a function. It must accept three arguments: a line of
3603 code (string), the current line number (integer) or nil and the
3604 reference associated to the current line (string) or nil.
3606 Optional argument NUM-LINES can be an integer representing the
3607 number of code lines accumulated until the current code. Line
3608 numbers passed to FUN will take it into account. If it is nil,
3609 FUN's second argument will always be nil. This number can be
3610 obtained with `org-export-get-loc' function.
3612 Optional argument REF-ALIST can be an alist between relative line
3613 number (i.e. ignoring NUM-LINES) and the name of the code
3614 reference on it. If it is nil, FUN's third argument will always
3615 be nil. It can be obtained through the use of
3616 `org-export-unravel-code' function."
3617 (let ((--locs (org-split-string code "\n"))
3618 (--line 0))
3619 (org-element-normalize-string
3620 (mapconcat
3621 (lambda (--loc)
3622 (incf --line)
3623 (let ((--ref (cdr (assq --line ref-alist))))
3624 (funcall fun --loc (and num-lines (+ num-lines --line)) --ref)))
3625 --locs "\n"))))
3627 (defun org-export-format-code-default (element info)
3628 "Return source code from ELEMENT, formatted in a standard way.
3630 ELEMENT is either a `src-block' or `example-block' element. INFO
3631 is a plist used as a communication channel.
3633 This function takes care of line numbering and code references
3634 inclusion. Line numbers, when applicable, appear at the
3635 beginning of the line, separated from the code by two white
3636 spaces. Code references, on the other hand, appear flushed to
3637 the right, separated by six white spaces from the widest line of
3638 code."
3639 ;; Extract code and references.
3640 (let* ((code-info (org-export-unravel-code element))
3641 (code (car code-info))
3642 (code-lines (org-split-string code "\n"))
3643 (refs (and (org-element-property :retain-labels element)
3644 (cdr code-info)))
3645 ;; Handle line numbering.
3646 (num-start (case (org-element-property :number-lines element)
3647 (continued (org-export-get-loc element info))
3648 (new 0)))
3649 (num-fmt
3650 (and num-start
3651 (format "%%%ds "
3652 (length (number-to-string
3653 (+ (length code-lines) num-start))))))
3654 ;; Prepare references display, if required. Any reference
3655 ;; should start six columns after the widest line of code,
3656 ;; wrapped with parenthesis.
3657 (max-width
3658 (+ (apply 'max (mapcar 'length code-lines))
3659 (if (not num-start) 0 (length (format num-fmt num-start))))))
3660 (org-export-format-code
3661 code
3662 (lambda (loc line-num ref)
3663 (let ((number-str (and num-fmt (format num-fmt line-num))))
3664 (concat
3665 number-str
3667 (and ref
3668 (concat (make-string
3669 (- (+ 6 max-width)
3670 (+ (length loc) (length number-str))) ? )
3671 (format "(%s)" ref))))))
3672 num-start refs)))
3675 ;;;; For Tables
3677 ;; `org-export-table-has-special-column-p' and and
3678 ;; `org-export-table-row-is-special-p' are predicates used to look for
3679 ;; meta-information about the table structure.
3681 ;; `org-table-has-header-p' tells when the rows before the first rule
3682 ;; should be considered as table's header.
3684 ;; `org-export-table-cell-width', `org-export-table-cell-alignment'
3685 ;; and `org-export-table-cell-borders' extract information from
3686 ;; a table-cell element.
3688 ;; `org-export-table-dimensions' gives the number on rows and columns
3689 ;; in the table, ignoring horizontal rules and special columns.
3690 ;; `org-export-table-cell-address', given a table-cell object, returns
3691 ;; the absolute address of a cell. On the other hand,
3692 ;; `org-export-get-table-cell-at' does the contrary.
3694 ;; `org-export-table-cell-starts-colgroup-p',
3695 ;; `org-export-table-cell-ends-colgroup-p',
3696 ;; `org-export-table-row-starts-rowgroup-p',
3697 ;; `org-export-table-row-ends-rowgroup-p',
3698 ;; `org-export-table-row-starts-header-p' and
3699 ;; `org-export-table-row-ends-header-p' indicate position of current
3700 ;; row or cell within the table.
3702 (defun org-export-table-has-special-column-p (table)
3703 "Non-nil when TABLE has a special column.
3704 All special columns will be ignored during export."
3705 ;; The table has a special column when every first cell of every row
3706 ;; has an empty value or contains a symbol among "/", "#", "!", "$",
3707 ;; "*" "_" and "^". Though, do not consider a first row containing
3708 ;; only empty cells as special.
3709 (let ((special-column-p 'empty))
3710 (catch 'exit
3711 (mapc
3712 (lambda (row)
3713 (when (eq (org-element-property :type row) 'standard)
3714 (let ((value (org-element-contents
3715 (car (org-element-contents row)))))
3716 (cond ((member value '(("/") ("#") ("!") ("$") ("*") ("_") ("^")))
3717 (setq special-column-p 'special))
3718 ((not value))
3719 (t (throw 'exit nil))))))
3720 (org-element-contents table))
3721 (eq special-column-p 'special))))
3723 (defun org-export-table-has-header-p (table info)
3724 "Non-nil when TABLE has an header.
3726 INFO is a plist used as a communication channel.
3728 A table has an header when it contains at least two row groups."
3729 (let ((rowgroup 1) row-flag)
3730 (org-element-map
3731 table 'table-row
3732 (lambda (row)
3733 (cond
3734 ((> rowgroup 1) t)
3735 ((and row-flag (eq (org-element-property :type row) 'rule))
3736 (incf rowgroup) (setq row-flag nil))
3737 ((and (not row-flag) (eq (org-element-property :type row) 'standard))
3738 (setq row-flag t) nil)))
3739 info)))
3741 (defun org-export-table-row-is-special-p (table-row info)
3742 "Non-nil if TABLE-ROW is considered special.
3744 INFO is a plist used as the communication channel.
3746 All special rows will be ignored during export."
3747 (when (eq (org-element-property :type table-row) 'standard)
3748 (let ((first-cell (org-element-contents
3749 (car (org-element-contents table-row)))))
3750 ;; A row is special either when...
3752 ;; ... it starts with a field only containing "/",
3753 (equal first-cell '("/"))
3754 ;; ... the table contains a special column and the row start
3755 ;; with a marking character among, "^", "_", "$" or "!",
3756 (and (org-export-table-has-special-column-p
3757 (org-export-get-parent table-row))
3758 (member first-cell '(("^") ("_") ("$") ("!"))))
3759 ;; ... it contains only alignment cookies and empty cells.
3760 (let ((special-row-p 'empty))
3761 (catch 'exit
3762 (mapc
3763 (lambda (cell)
3764 (let ((value (org-element-contents cell)))
3765 ;; Since VALUE is a secondary string, the following
3766 ;; checks avoid expanding it with `org-export-data'.
3767 (cond ((not value))
3768 ((and (not (cdr value))
3769 (stringp (car value))
3770 (string-match "\\`<[lrc]?\\([0-9]+\\)?>\\'"
3771 (car value)))
3772 (setq special-row-p 'cookie))
3773 (t (throw 'exit nil)))))
3774 (org-element-contents table-row))
3775 (eq special-row-p 'cookie)))))))
3777 (defun org-export-table-row-group (table-row info)
3778 "Return TABLE-ROW's group.
3780 INFO is a plist used as the communication channel.
3782 Return value is the group number, as an integer, or nil special
3783 rows and table rules. Group 1 is also table's header."
3784 (unless (or (eq (org-element-property :type table-row) 'rule)
3785 (org-export-table-row-is-special-p table-row info))
3786 (let ((group 0) row-flag)
3787 (catch 'found
3788 (mapc
3789 (lambda (row)
3790 (cond
3791 ((and (eq (org-element-property :type row) 'standard)
3792 (not (org-export-table-row-is-special-p row info)))
3793 (unless row-flag (incf group) (setq row-flag t)))
3794 ((eq (org-element-property :type row) 'rule)
3795 (setq row-flag nil)))
3796 (when (eq table-row row) (throw 'found group)))
3797 (org-element-contents (org-export-get-parent table-row)))))))
3799 (defun org-export-table-cell-width (table-cell info)
3800 "Return TABLE-CELL contents width.
3802 INFO is a plist used as the communication channel.
3804 Return value is the width given by the last width cookie in the
3805 same column as TABLE-CELL, or nil."
3806 (let* ((row (org-export-get-parent table-cell))
3807 (column (let ((cells (org-element-contents row)))
3808 (- (length cells) (length (memq table-cell cells)))))
3809 (table (org-export-get-parent-table table-cell))
3810 cookie-width)
3811 (mapc
3812 (lambda (row)
3813 (cond
3814 ;; In a special row, try to find a width cookie at COLUMN.
3815 ((org-export-table-row-is-special-p row info)
3816 (let ((value (org-element-contents
3817 (elt (org-element-contents row) column))))
3818 ;; The following checks avoid expanding unnecessarily the
3819 ;; cell with `org-export-data'
3820 (when (and value
3821 (not (cdr value))
3822 (stringp (car value))
3823 (string-match "\\`<[lrc]?\\([0-9]+\\)?>\\'" (car value))
3824 (match-string 1 (car value)))
3825 (setq cookie-width
3826 (string-to-number (match-string 1 (car value)))))))
3827 ;; Ignore table rules.
3828 ((eq (org-element-property :type row) 'rule))))
3829 (org-element-contents table))
3830 ;; Return value.
3831 cookie-width))
3833 (defun org-export-table-cell-alignment (table-cell info)
3834 "Return TABLE-CELL contents alignment.
3836 INFO is a plist used as the communication channel.
3838 Return alignment as specified by the last alignment cookie in the
3839 same column as TABLE-CELL. If no such cookie is found, a default
3840 alignment value will be deduced from fraction of numbers in the
3841 column (see `org-table-number-fraction' for more information).
3842 Possible values are `left', `right' and `center'."
3843 (let* ((row (org-export-get-parent table-cell))
3844 (column (let ((cells (org-element-contents row)))
3845 (- (length cells) (length (memq table-cell cells)))))
3846 (table (org-export-get-parent-table table-cell))
3847 (number-cells 0)
3848 (total-cells 0)
3849 cookie-align)
3850 (mapc
3851 (lambda (row)
3852 (cond
3853 ;; In a special row, try to find an alignment cookie at
3854 ;; COLUMN.
3855 ((org-export-table-row-is-special-p row info)
3856 (let ((value (org-element-contents
3857 (elt (org-element-contents row) column))))
3858 ;; Since VALUE is a secondary string, the following checks
3859 ;; avoid useless expansion through `org-export-data'.
3860 (when (and value
3861 (not (cdr value))
3862 (stringp (car value))
3863 (string-match "\\`<\\([lrc]\\)?\\([0-9]+\\)?>\\'"
3864 (car value))
3865 (match-string 1 (car value)))
3866 (setq cookie-align (match-string 1 (car value))))))
3867 ;; Ignore table rules.
3868 ((eq (org-element-property :type row) 'rule))
3869 ;; In a standard row, check if cell's contents are expressing
3870 ;; some kind of number. Increase NUMBER-CELLS accordingly.
3871 ;; Though, don't bother if an alignment cookie has already
3872 ;; defined cell's alignment.
3873 ((not cookie-align)
3874 (let ((value (org-export-data
3875 (org-element-contents
3876 (elt (org-element-contents row) column))
3877 info)))
3878 (incf total-cells)
3879 (when (string-match org-table-number-regexp value)
3880 (incf number-cells))))))
3881 (org-element-contents table))
3882 ;; Return value. Alignment specified by cookies has precedence
3883 ;; over alignment deduced from cells contents.
3884 (cond ((equal cookie-align "l") 'left)
3885 ((equal cookie-align "r") 'right)
3886 ((equal cookie-align "c") 'center)
3887 ((>= (/ (float number-cells) total-cells) org-table-number-fraction)
3888 'right)
3889 (t 'left))))
3891 (defun org-export-table-cell-borders (table-cell info)
3892 "Return TABLE-CELL borders.
3894 INFO is a plist used as a communication channel.
3896 Return value is a list of symbols, or nil. Possible values are:
3897 `top', `bottom', `above', `below', `left' and `right'. Note:
3898 `top' (resp. `bottom') only happen for a cell in the first
3899 row (resp. last row) of the table, ignoring table rules, if any.
3901 Returned borders ignore special rows."
3902 (let* ((row (org-export-get-parent table-cell))
3903 (table (org-export-get-parent-table table-cell))
3904 borders)
3905 ;; Top/above border? TABLE-CELL has a border above when a rule
3906 ;; used to demarcate row groups can be found above. Hence,
3907 ;; finding a rule isn't sufficient to push `above' in BORDERS:
3908 ;; another regular row has to be found above that rule.
3909 (let (rule-flag)
3910 (catch 'exit
3911 (mapc (lambda (row)
3912 (cond ((eq (org-element-property :type row) 'rule)
3913 (setq rule-flag t))
3914 ((not (org-export-table-row-is-special-p row info))
3915 (if rule-flag (throw 'exit (push 'above borders))
3916 (throw 'exit nil)))))
3917 ;; Look at every row before the current one.
3918 (cdr (memq row (reverse (org-element-contents table)))))
3919 ;; No rule above, or rule found starts the table (ignoring any
3920 ;; special row): TABLE-CELL is at the top of the table.
3921 (when rule-flag (push 'above borders))
3922 (push 'top borders)))
3923 ;; Bottom/below border? TABLE-CELL has a border below when next
3924 ;; non-regular row below is a rule.
3925 (let (rule-flag)
3926 (catch 'exit
3927 (mapc (lambda (row)
3928 (cond ((eq (org-element-property :type row) 'rule)
3929 (setq rule-flag t))
3930 ((not (org-export-table-row-is-special-p row info))
3931 (if rule-flag (throw 'exit (push 'below borders))
3932 (throw 'exit nil)))))
3933 ;; Look at every row after the current one.
3934 (cdr (memq row (org-element-contents table))))
3935 ;; No rule below, or rule found ends the table (modulo some
3936 ;; special row): TABLE-CELL is at the bottom of the table.
3937 (when rule-flag (push 'below borders))
3938 (push 'bottom borders)))
3939 ;; Right/left borders? They can only be specified by column
3940 ;; groups. Column groups are defined in a row starting with "/".
3941 ;; Also a column groups row only contains "<", "<>", ">" or blank
3942 ;; cells.
3943 (catch 'exit
3944 (let ((column (let ((cells (org-element-contents row)))
3945 (- (length cells) (length (memq table-cell cells))))))
3946 (mapc
3947 (lambda (row)
3948 (unless (eq (org-element-property :type row) 'rule)
3949 (when (equal (org-element-contents
3950 (car (org-element-contents row)))
3951 '("/"))
3952 (let ((column-groups
3953 (mapcar
3954 (lambda (cell)
3955 (let ((value (org-element-contents cell)))
3956 (when (member value '(("<") ("<>") (">") nil))
3957 (car value))))
3958 (org-element-contents row))))
3959 ;; There's a left border when previous cell, if
3960 ;; any, ends a group, or current one starts one.
3961 (when (or (and (not (zerop column))
3962 (member (elt column-groups (1- column))
3963 '(">" "<>")))
3964 (member (elt column-groups column) '("<" "<>")))
3965 (push 'left borders))
3966 ;; There's a right border when next cell, if any,
3967 ;; starts a group, or current one ends one.
3968 (when (or (and (/= (1+ column) (length column-groups))
3969 (member (elt column-groups (1+ column))
3970 '("<" "<>")))
3971 (member (elt column-groups column) '(">" "<>")))
3972 (push 'right borders))
3973 (throw 'exit nil)))))
3974 ;; Table rows are read in reverse order so last column groups
3975 ;; row has precedence over any previous one.
3976 (reverse (org-element-contents table)))))
3977 ;; Return value.
3978 borders))
3980 (defun org-export-table-cell-starts-colgroup-p (table-cell info)
3981 "Non-nil when TABLE-CELL is at the beginning of a row group.
3982 INFO is a plist used as a communication channel."
3983 ;; A cell starts a column group either when it is at the beginning
3984 ;; of a row (or after the special column, if any) or when it has
3985 ;; a left border.
3986 (or (eq (org-element-map
3987 (org-export-get-parent table-cell)
3988 'table-cell 'identity info 'first-match)
3989 table-cell)
3990 (memq 'left (org-export-table-cell-borders table-cell info))))
3992 (defun org-export-table-cell-ends-colgroup-p (table-cell info)
3993 "Non-nil when TABLE-CELL is at the end of a row group.
3994 INFO is a plist used as a communication channel."
3995 ;; A cell ends a column group either when it is at the end of a row
3996 ;; or when it has a right border.
3997 (or (eq (car (last (org-element-contents
3998 (org-export-get-parent table-cell))))
3999 table-cell)
4000 (memq 'right (org-export-table-cell-borders table-cell info))))
4002 (defun org-export-table-row-starts-rowgroup-p (table-row info)
4003 "Non-nil when TABLE-ROW is at the beginning of a column group.
4004 INFO is a plist used as a communication channel."
4005 (unless (or (eq (org-element-property :type table-row) 'rule)
4006 (org-export-table-row-is-special-p table-row info))
4007 (let ((borders (org-export-table-cell-borders
4008 (car (org-element-contents table-row)) info)))
4009 (or (memq 'top borders) (memq 'above borders)))))
4011 (defun org-export-table-row-ends-rowgroup-p (table-row info)
4012 "Non-nil when TABLE-ROW is at the end of a column group.
4013 INFO is a plist used as a communication channel."
4014 (unless (or (eq (org-element-property :type table-row) 'rule)
4015 (org-export-table-row-is-special-p table-row info))
4016 (let ((borders (org-export-table-cell-borders
4017 (car (org-element-contents table-row)) info)))
4018 (or (memq 'bottom borders) (memq 'below borders)))))
4020 (defun org-export-table-row-starts-header-p (table-row info)
4021 "Non-nil when TABLE-ROW is the first table header's row.
4022 INFO is a plist used as a communication channel."
4023 (and (org-export-table-has-header-p
4024 (org-export-get-parent-table table-row) info)
4025 (org-export-table-row-starts-rowgroup-p table-row info)
4026 (= (org-export-table-row-group table-row info) 1)))
4028 (defun org-export-table-row-ends-header-p (table-row info)
4029 "Non-nil when TABLE-ROW is the last table header's row.
4030 INFO is a plist used as a communication channel."
4031 (and (org-export-table-has-header-p
4032 (org-export-get-parent-table table-row) info)
4033 (org-export-table-row-ends-rowgroup-p table-row info)
4034 (= (org-export-table-row-group table-row info) 1)))
4036 (defun org-export-table-dimensions (table info)
4037 "Return TABLE dimensions.
4039 INFO is a plist used as a communication channel.
4041 Return value is a CONS like (ROWS . COLUMNS) where
4042 ROWS (resp. COLUMNS) is the number of exportable
4043 rows (resp. columns)."
4044 (let (first-row (columns 0) (rows 0))
4045 ;; Set number of rows, and extract first one.
4046 (org-element-map
4047 table 'table-row
4048 (lambda (row)
4049 (when (eq (org-element-property :type row) 'standard)
4050 (incf rows)
4051 (unless first-row (setq first-row row)))) info)
4052 ;; Set number of columns.
4053 (org-element-map first-row 'table-cell (lambda (cell) (incf columns)) info)
4054 ;; Return value.
4055 (cons rows columns)))
4057 (defun org-export-table-cell-address (table-cell info)
4058 "Return address of a regular TABLE-CELL object.
4060 TABLE-CELL is the cell considered. INFO is a plist used as
4061 a communication channel.
4063 Address is a CONS cell (ROW . COLUMN), where ROW and COLUMN are
4064 zero-based index. Only exportable cells are considered. The
4065 function returns nil for other cells."
4066 (let* ((table-row (org-export-get-parent table-cell))
4067 (table (org-export-get-parent-table table-cell)))
4068 ;; Ignore cells in special rows or in special column.
4069 (unless (or (org-export-table-row-is-special-p table-row info)
4070 (and (org-export-table-has-special-column-p table)
4071 (eq (car (org-element-contents table-row)) table-cell)))
4072 (cons
4073 ;; Row number.
4074 (let ((row-count 0))
4075 (org-element-map
4076 table 'table-row
4077 (lambda (row)
4078 (cond ((eq (org-element-property :type row) 'rule) nil)
4079 ((eq row table-row) row-count)
4080 (t (incf row-count) nil)))
4081 info 'first-match))
4082 ;; Column number.
4083 (let ((col-count 0))
4084 (org-element-map
4085 table-row 'table-cell
4086 (lambda (cell)
4087 (if (eq cell table-cell) col-count (incf col-count) nil))
4088 info 'first-match))))))
4090 (defun org-export-get-table-cell-at (address table info)
4091 "Return regular table-cell object at ADDRESS in TABLE.
4093 Address is a CONS cell (ROW . COLUMN), where ROW and COLUMN are
4094 zero-based index. TABLE is a table type element. INFO is
4095 a plist used as a communication channel.
4097 If no table-cell, among exportable cells, is found at ADDRESS,
4098 return nil."
4099 (let ((column-pos (cdr address)) (column-count 0))
4100 (org-element-map
4101 ;; Row at (car address) or nil.
4102 (let ((row-pos (car address)) (row-count 0))
4103 (org-element-map
4104 table 'table-row
4105 (lambda (row)
4106 (cond ((eq (org-element-property :type row) 'rule) nil)
4107 ((= row-count row-pos) row)
4108 (t (incf row-count) nil)))
4109 info 'first-match))
4110 'table-cell
4111 (lambda (cell)
4112 (if (= column-count column-pos) cell
4113 (incf column-count) nil))
4114 info 'first-match)))
4117 ;;;; For Tables Of Contents
4119 ;; `org-export-collect-headlines' builds a list of all exportable
4120 ;; headline elements, maybe limited to a certain depth. One can then
4121 ;; easily parse it and transcode it.
4123 ;; Building lists of tables, figures or listings is quite similar.
4124 ;; Once the generic function `org-export-collect-elements' is defined,
4125 ;; `org-export-collect-tables', `org-export-collect-figures' and
4126 ;; `org-export-collect-listings' can be derived from it.
4128 (defun org-export-collect-headlines (info &optional n)
4129 "Collect headlines in order to build a table of contents.
4131 INFO is a plist used as a communication channel.
4133 When optional argument N is an integer, it specifies the depth of
4134 the table of contents. Otherwise, it is set to the value of the
4135 last headline level. See `org-export-headline-levels' for more
4136 information.
4138 Return a list of all exportable headlines as parsed elements."
4139 (unless (wholenump n) (setq n (plist-get info :headline-levels)))
4140 (org-element-map
4141 (plist-get info :parse-tree)
4142 'headline
4143 (lambda (headline)
4144 ;; Strip contents from HEADLINE.
4145 (let ((relative-level (org-export-get-relative-level headline info)))
4146 (unless (> relative-level n) headline)))
4147 info))
4149 (defun org-export-collect-elements (type info &optional predicate)
4150 "Collect referenceable elements of a determined type.
4152 TYPE can be a symbol or a list of symbols specifying element
4153 types to search. Only elements with a caption are collected.
4155 INFO is a plist used as a communication channel.
4157 When non-nil, optional argument PREDICATE is a function accepting
4158 one argument, an element of type TYPE. It returns a non-nil
4159 value when that element should be collected.
4161 Return a list of all elements found, in order of appearance."
4162 (org-element-map
4163 (plist-get info :parse-tree) type
4164 (lambda (element)
4165 (and (org-element-property :caption element)
4166 (or (not predicate) (funcall predicate element))
4167 element))
4168 info))
4170 (defun org-export-collect-tables (info)
4171 "Build a list of tables.
4172 INFO is a plist used as a communication channel.
4174 Return a list of table elements with a caption."
4175 (org-export-collect-elements 'table info))
4177 (defun org-export-collect-figures (info predicate)
4178 "Build a list of figures.
4180 INFO is a plist used as a communication channel. PREDICATE is
4181 a function which accepts one argument: a paragraph element and
4182 whose return value is non-nil when that element should be
4183 collected.
4185 A figure is a paragraph type element, with a caption, verifying
4186 PREDICATE. The latter has to be provided since a \"figure\" is
4187 a vague concept that may depend on back-end.
4189 Return a list of elements recognized as figures."
4190 (org-export-collect-elements 'paragraph info predicate))
4192 (defun org-export-collect-listings (info)
4193 "Build a list of src blocks.
4195 INFO is a plist used as a communication channel.
4197 Return a list of src-block elements with a caption."
4198 (org-export-collect-elements 'src-block info))
4201 ;;;; Smart Quotes
4203 (defconst org-export-smart-quotes-alist
4204 '(("de"
4205 (opening-double-quote :utf-8 "„" :html "&bdquo;" :latex "\"`"
4206 :texinfo "@quotedblbase{}")
4207 (closing-double-quote :utf-8 "“" :html "&ldquo;" :latex "\"'"
4208 :texinfo "@quotedblleft{}")
4209 (opening-single-quote :utf-8 "‚" :html "&sbquo;" :latex "\\glq{}"
4210 :texinfo "@quotesinglbase{}")
4211 (closing-single-quote :utf-8 "‘" :html "&lsquo;" :latex "\\grq{}"
4212 :texinfo "@quoteleft{}")
4213 (apostrophe :utf-8 "’" :html "&rsquo;"))
4214 ("en"
4215 (opening-double-quote :utf-8 "“" :html "&ldquo;" :latex "``" :texinfo "``")
4216 (closing-double-quote :utf-8 "”" :html "&rdquo;" :latex "''" :texinfo "''")
4217 (opening-single-quote :utf-8 "‘" :html "&lsquo;" :latex "`" :texinfo "`")
4218 (closing-single-quote :utf-8 "’" :html "&rsquo;" :latex "'" :texinfo "'")
4219 (apostrophe :utf-8 "’" :html "&rsquo;"))
4220 ("es"
4221 (opening-double-quote :utf-8 "«" :html "&laquo;" :latex "\\guillemotleft{}"
4222 :texinfo "@guillemetleft{}")
4223 (closing-double-quote :utf-8 "»" :html "&raquo;" :latex "\\guillemotright{}"
4224 :texinfo "@guillemetright{}")
4225 (opening-single-quote :utf-8 "“" :html "&ldquo;" :latex "``" :texinfo "``")
4226 (closing-single-quote :utf-8 "”" :html "&rdquo;" :latex "''" :texinfo "''")
4227 (apostrophe :utf-8 "’" :html "&rsquo;"))
4228 ("fr"
4229 (opening-double-quote :utf-8 "« " :html "&laquo;&nbsp;" :latex "\\og "
4230 :texinfo "@guillemetleft{}@tie{}")
4231 (closing-double-quote :utf-8 " »" :html "&nbsp;&raquo;" :latex "\\fg{}"
4232 :texinfo "@tie{}@guillemetright{}")
4233 (opening-single-quote :utf-8 "« " :html "&laquo;&nbsp;" :latex "\\og "
4234 :texinfo "@guillemetleft{}@tie{}")
4235 (closing-single-quote :utf-8 " »" :html "&nbsp;&raquo;" :latex "\\fg{}"
4236 :texinfo "@tie{}@guillemetright{}")
4237 (apostrophe :utf-8 "’" :html "&rsquo;")))
4238 "Smart quotes translations.
4240 Alist whose CAR is a language string and CDR is an alist with
4241 quote type as key and a plist associating various encodings to
4242 their translation as value.
4244 A quote type can be any symbol among `opening-double-quote',
4245 `closing-double-quote', `opening-single-quote',
4246 `closing-single-quote' and `apostrophe'.
4248 Valid encodings include `:utf-8', `:html', `:latex' and
4249 `:texinfo'.
4251 If no translation is found, the quote character is left as-is.")
4253 (defconst org-export-smart-quotes-regexps
4254 (list
4255 ;; Possible opening quote at beginning of string.
4256 "\\`\\([\"']\\)\\(\\w\\|\\s.\\|\\s_\\)"
4257 ;; Possible closing quote at beginning of string.
4258 "\\`\\([\"']\\)\\(\\s-\\|\\s)\\|\\s.\\)"
4259 ;; Possible apostrophe at beginning of string.
4260 "\\`\\('\\)\\S-"
4261 ;; Opening single and double quotes.
4262 "\\(?:\\s-\\|\\s(\\)\\([\"']\\)\\(?:\\w\\|\\s.\\|\\s_\\)"
4263 ;; Closing single and double quotes.
4264 "\\(?:\\w\\|\\s.\\|\\s_\\)\\([\"']\\)\\(?:\\s-\\|\\s)\\|\\s.\\)"
4265 ;; Apostrophe.
4266 "\\S-\\('\\)\\S-"
4267 ;; Possible opening quote at end of string.
4268 "\\(?:\\s-\\|\\s(\\)\\([\"']\\)\\'"
4269 ;; Possible closing quote at end of string.
4270 "\\(?:\\w\\|\\s.\\|\\s_\\)\\([\"']\\)\\'"
4271 ;; Possible apostrophe at end of string.
4272 "\\S-\\('\\)\\'")
4273 "List of regexps matching a quote or an apostrophe.
4274 In every regexp, quote or apostrophe matched is put in group 1.")
4276 (defun org-export-activate-smart-quotes (s encoding info &optional original)
4277 "Replace regular quotes with \"smart\" quotes in string S.
4279 ENCODING is a symbol among `:html', `:latex' and `:utf-8'. INFO
4280 is a plist used as a communication channel.
4282 The function has to retrieve information about string
4283 surroundings in parse tree. It can only happen with an
4284 unmodified string. Thus, if S has already been through another
4285 process, a non-nil ORIGINAL optional argument will provide that
4286 original string.
4288 Return the new string."
4289 (if (equal s "") ""
4290 (let ((quotes-alist (cdr (assoc (plist-get info :language)
4291 org-export-smart-quotes-alist))))
4292 ;; 1. Replace quote character at the beginning of S.
4293 (let* ((prev (org-export-get-previous-element (or original s) info))
4294 (pre-blank (and prev (org-element-property :post-blank prev))))
4295 (cond
4296 ;; Apostrophe?
4297 ((and prev (zerop pre-blank)
4298 (string-match (nth 2 org-export-smart-quotes-regexps) s))
4299 (let ((smart-quote
4300 (plist-get (cdr (assq 'apostrophe quotes-alist)) encoding)))
4301 (when smart-quote
4302 (setq s (replace-match smart-quote nil t s 1)))))
4303 ;; Closing quote?
4304 ((and prev (zerop pre-blank)
4305 (string-match (nth 1 org-export-smart-quotes-regexps) s))
4306 (let ((smart-quote
4307 (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
4308 'closing-single-quote
4309 'closing-double-quote)
4310 quotes-alist))
4311 encoding)))
4312 (when smart-quote
4313 (setq s (replace-match smart-quote nil t s 1)))))
4314 ;; Opening quote?
4315 ((and (or (not prev) (> pre-blank 0))
4316 (string-match (nth 0 org-export-smart-quotes-regexps) s))
4317 (let ((smart-quote
4318 (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
4319 'opening-single-quote
4320 'opening-double-quote)
4321 quotes-alist))
4322 encoding)))
4323 (when smart-quote
4324 (setq s (replace-match smart-quote nil t s 1)))))))
4325 ;; 2. Replace quotes in the middle of the string.
4326 (setq s
4327 ;; Opening quotes.
4328 (replace-regexp-in-string
4329 (nth 3 org-export-smart-quotes-regexps)
4330 (lambda (text)
4331 (or (plist-get
4332 (cdr (assq (if (equal (match-string 1 text) "'")
4333 'opening-single-quote
4334 'opening-double-quote)
4335 quotes-alist))
4336 encoding)
4337 (match-string 1 text)))
4338 s nil t 1))
4339 (setq s
4340 (replace-regexp-in-string
4341 ;; Closing quotes.
4342 (nth 4 org-export-smart-quotes-regexps)
4343 (lambda (text)
4344 (or (plist-get
4345 (cdr (assq (if (equal (match-string 1 text) "'")
4346 'closing-single-quote
4347 'closing-double-quote)
4348 quotes-alist))
4349 encoding)
4350 (match-string 1 text)))
4351 s nil t 1))
4352 (setq s
4353 (replace-regexp-in-string
4354 ;; Apostrophes.
4355 (nth 5 org-export-smart-quotes-regexps)
4356 (lambda (text)
4357 (or (plist-get (cdr (assq 'apostrophe quotes-alist)) encoding)
4358 (match-string 1 text)))
4359 s nil t 1))
4360 ;; 3. Replace quote character at the end of S.
4361 (let ((next (org-export-get-next-element (or original s) info)))
4362 (cond
4363 ;; Apostrophe?
4364 ((and next (string-match (nth 8 org-export-smart-quotes-regexps) s))
4365 (let ((smart-quote
4366 (plist-get (cdr (assq 'apostrophe quotes-alist)) encoding)))
4367 (when smart-quote (setq s (replace-match smart-quote nil t s 1)))))
4368 ;; Closing quote?
4369 ((and (not next)
4370 (string-match (nth 7 org-export-smart-quotes-regexps) s))
4371 (let ((smart-quote
4372 (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
4373 'closing-single-quote
4374 'closing-double-quote)
4375 quotes-alist))
4376 encoding)))
4377 (when smart-quote (setq s (replace-match smart-quote nil t s 1)))))
4378 ;; Opening quote?
4379 ((and next (string-match (nth 6 org-export-smart-quotes-regexps) s))
4380 (let ((smart-quote
4381 (plist-get (cdr (assq (if (equal (match-string 1 s) "'")
4382 'opening-single-quote
4383 'opening-double-quote)
4384 quotes-alist))
4385 encoding)))
4386 (when smart-quote
4387 (setq s (replace-match smart-quote nil t s 1)))))))
4388 ;; Return string with smart quotes.
4389 s)))
4392 ;;;; Topology
4394 ;; Here are various functions to retrieve information about the
4395 ;; neighbourhood of a given element or object. Neighbours of interest
4396 ;; are direct parent (`org-export-get-parent'), parent headline
4397 ;; (`org-export-get-parent-headline'), first element containing an
4398 ;; object, (`org-export-get-parent-element'), parent table
4399 ;; (`org-export-get-parent-table'), previous element or object
4400 ;; (`org-export-get-previous-element') and next element or object
4401 ;; (`org-export-get-next-element').
4403 ;; `org-export-get-genealogy' returns the full genealogy of a given
4404 ;; element or object, from closest parent to full parse tree.
4406 (defun org-export-get-parent (blob)
4407 "Return BLOB parent or nil.
4408 BLOB is the element or object considered."
4409 (org-element-property :parent blob))
4411 (defun org-export-get-genealogy (blob)
4412 "Return full genealogy relative to a given element or object.
4414 BLOB is the element or object being considered.
4416 Ancestors are returned from closest to farthest, the last one
4417 being the full parse tree."
4418 (let (genealogy (parent blob))
4419 (while (setq parent (org-element-property :parent parent))
4420 (push parent genealogy))
4421 (nreverse genealogy)))
4423 (defun org-export-get-parent-headline (blob)
4424 "Return BLOB parent headline or nil.
4425 BLOB is the element or object being considered."
4426 (let ((parent blob))
4427 (while (and (setq parent (org-element-property :parent parent))
4428 (not (eq (org-element-type parent) 'headline))))
4429 parent))
4431 (defun org-export-get-parent-element (object)
4432 "Return first element containing OBJECT or nil.
4433 OBJECT is the object to consider."
4434 (let ((parent object))
4435 (while (and (setq parent (org-element-property :parent parent))
4436 (memq (org-element-type parent) org-element-all-objects)))
4437 parent))
4439 (defun org-export-get-parent-table (object)
4440 "Return OBJECT parent table or nil.
4441 OBJECT is either a `table-cell' or `table-element' type object."
4442 (let ((parent object))
4443 (while (and (setq parent (org-element-property :parent parent))
4444 (not (eq (org-element-type parent) 'table))))
4445 parent))
4447 (defun org-export-get-previous-element (blob info)
4448 "Return previous element or object.
4449 BLOB is an element or object. INFO is a plist used as
4450 a communication channel. Return previous exportable element or
4451 object, a string, or nil."
4452 (let (prev)
4453 (catch 'exit
4454 (mapc (lambda (obj)
4455 (cond ((eq obj blob) (throw 'exit prev))
4456 ((memq obj (plist-get info :ignore-list)))
4457 (t (setq prev obj))))
4458 (org-element-contents (org-export-get-parent blob))))))
4460 (defun org-export-get-next-element (blob info)
4461 "Return next element or object.
4462 BLOB is an element or object. INFO is a plist used as
4463 a communication channel. Return next exportable element or
4464 object, a string, or nil."
4465 (catch 'found
4466 (mapc (lambda (obj)
4467 (unless (memq obj (plist-get info :ignore-list))
4468 (throw 'found obj)))
4469 (cdr (memq blob (org-element-contents (org-export-get-parent blob)))))
4470 nil))
4473 ;;;; Translation
4475 ;; `org-export-translate' translates a string according to language
4476 ;; specified by LANGUAGE keyword or `org-export-language-setup'
4477 ;; variable and a specified charset. `org-export-dictionary' contains
4478 ;; the dictionary used for the translation.
4480 (defconst org-export-dictionary
4481 '(("Author"
4482 ("ca" :default "Autor")
4483 ("cs" :default "Autor")
4484 ("da" :default "Ophavsmand")
4485 ("de" :default "Autor")
4486 ("eo" :html "A&#365;toro")
4487 ("es" :default "Autor")
4488 ("fi" :html "Tekij&auml;")
4489 ("fr" :default "Auteur")
4490 ("hu" :default "Szerz&otilde;")
4491 ("is" :html "H&ouml;fundur")
4492 ("it" :default "Autore")
4493 ("ja" :html "&#33879;&#32773;" :utf-8 "著者")
4494 ("nl" :default "Auteur")
4495 ("no" :default "Forfatter")
4496 ("nb" :default "Forfatter")
4497 ("nn" :default "Forfattar")
4498 ("pl" :default "Autor")
4499 ("ru" :html "&#1040;&#1074;&#1090;&#1086;&#1088;" :utf-8 "Автор")
4500 ("sv" :html "F&ouml;rfattare")
4501 ("uk" :html "&#1040;&#1074;&#1090;&#1086;&#1088;" :utf-8 "Автор")
4502 ("zh-CN" :html "&#20316;&#32773;" :utf-8 "作者")
4503 ("zh-TW" :html "&#20316;&#32773;" :utf-8 "作者"))
4504 ("Date"
4505 ("ca" :default "Data")
4506 ("cs" :default "Datum")
4507 ("da" :default "Dato")
4508 ("de" :default "Datum")
4509 ("eo" :default "Dato")
4510 ("es" :default "Fecha")
4511 ("fi" :html "P&auml;iv&auml;m&auml;&auml;r&auml;")
4512 ("hu" :html "D&aacute;tum")
4513 ("is" :default "Dagsetning")
4514 ("it" :default "Data")
4515 ("ja" :html "&#26085;&#20184;" :utf-8 "日付")
4516 ("nl" :default "Datum")
4517 ("no" :default "Dato")
4518 ("nb" :default "Dato")
4519 ("nn" :default "Dato")
4520 ("pl" :default "Data")
4521 ("ru" :html "&#1044;&#1072;&#1090;&#1072;" :utf-8 "Дата")
4522 ("sv" :default "Datum")
4523 ("uk" :html "&#1044;&#1072;&#1090;&#1072;" :utf-8 "Дата")
4524 ("zh-CN" :html "&#26085;&#26399;" :utf-8 "日期")
4525 ("zh-TW" :html "&#26085;&#26399;" :utf-8 "日期"))
4526 ("Equation"
4527 ("fr" :ascii "Equation" :default "Équation"))
4528 ("Figure")
4529 ("Footnotes"
4530 ("ca" :html "Peus de p&agrave;gina")
4531 ("cs" :default "Pozn\xe1mky pod carou")
4532 ("da" :default "Fodnoter")
4533 ("de" :html "Fu&szlig;noten")
4534 ("eo" :default "Piednotoj")
4535 ("es" :html "Pies de p&aacute;gina")
4536 ("fi" :default "Alaviitteet")
4537 ("fr" :default "Notes de bas de page")
4538 ("hu" :html "L&aacute;bjegyzet")
4539 ("is" :html "Aftanm&aacute;lsgreinar")
4540 ("it" :html "Note a pi&egrave; di pagina")
4541 ("ja" :html "&#33050;&#27880;" :utf-8 "脚注")
4542 ("nl" :default "Voetnoten")
4543 ("no" :default "Fotnoter")
4544 ("nb" :default "Fotnoter")
4545 ("nn" :default "Fotnotar")
4546 ("pl" :default "Przypis")
4547 ("ru" :html "&#1057;&#1085;&#1086;&#1089;&#1082;&#1080;" :utf-8 "Сноски")
4548 ("sv" :default "Fotnoter")
4549 ("uk" :html "&#1055;&#1088;&#1080;&#1084;&#1110;&#1090;&#1082;&#1080;"
4550 :utf-8 "Примітки")
4551 ("zh-CN" :html "&#33050;&#27880;" :utf-8 "脚注")
4552 ("zh-TW" :html "&#33139;&#35387;" :utf-8 "腳註"))
4553 ("List of Listings"
4554 ("fr" :default "Liste des programmes"))
4555 ("List of Tables"
4556 ("fr" :default "Liste des tableaux"))
4557 ("Listing %d:"
4558 ("fr"
4559 :ascii "Programme %d :" :default "Programme nº %d :"
4560 :latin1 "Programme %d :"))
4561 ("Listing %d: %s"
4562 ("fr"
4563 :ascii "Programme %d : %s" :default "Programme nº %d : %s"
4564 :latin1 "Programme %d : %s"))
4565 ("See section %s"
4566 ("fr" :default "cf. section %s"))
4567 ("Table %d:"
4568 ("fr"
4569 :ascii "Tableau %d :" :default "Tableau nº %d :" :latin1 "Tableau %d :"))
4570 ("Table %d: %s"
4571 ("fr"
4572 :ascii "Tableau %d : %s" :default "Tableau nº %d : %s"
4573 :latin1 "Tableau %d : %s"))
4574 ("Table of Contents"
4575 ("ca" :html "&Iacute;ndex")
4576 ("cs" :default "Obsah")
4577 ("da" :default "Indhold")
4578 ("de" :default "Inhaltsverzeichnis")
4579 ("eo" :default "Enhavo")
4580 ("es" :html "&Iacute;ndice")
4581 ("fi" :html "Sis&auml;llysluettelo")
4582 ("fr" :ascii "Sommaire" :default "Table des matières")
4583 ("hu" :html "Tartalomjegyz&eacute;k")
4584 ("is" :default "Efnisyfirlit")
4585 ("it" :default "Indice")
4586 ("ja" :html "&#30446;&#27425;" :utf-8 "目次")
4587 ("nl" :default "Inhoudsopgave")
4588 ("no" :default "Innhold")
4589 ("nb" :default "Innhold")
4590 ("nn" :default "Innhald")
4591 ("pl" :html "Spis tre&#x015b;ci")
4592 ("ru" :html "&#1057;&#1086;&#1076;&#1077;&#1088;&#1078;&#1072;&#1085;&#1080;&#1077;"
4593 :utf-8 "Содержание")
4594 ("sv" :html "Inneh&aring;ll")
4595 ("uk" :html "&#1047;&#1084;&#1110;&#1089;&#1090;" :utf-8 "Зміст")
4596 ("zh-CN" :html "&#30446;&#24405;" :utf-8 "目录")
4597 ("zh-TW" :html "&#30446;&#37636;" :utf-8 "目錄"))
4598 ("Unknown reference"
4599 ("fr" :ascii "Destination inconnue" :default "Référence inconnue")))
4600 "Dictionary for export engine.
4602 Alist whose CAR is the string to translate and CDR is an alist
4603 whose CAR is the language string and CDR is a plist whose
4604 properties are possible charsets and values translated terms.
4606 It is used as a database for `org-export-translate'. Since this
4607 function returns the string as-is if no translation was found,
4608 the variable only needs to record values different from the
4609 entry.")
4611 (defun org-export-translate (s encoding info)
4612 "Translate string S according to language specification.
4614 ENCODING is a symbol among `:ascii', `:html', `:latex', `:latin1'
4615 and `:utf-8'. INFO is a plist used as a communication channel.
4617 Translation depends on `:language' property. Return the
4618 translated string. If no translation is found, try to fall back
4619 to `:default' encoding. If it fails, return S."
4620 (let* ((lang (plist-get info :language))
4621 (translations (cdr (assoc lang
4622 (cdr (assoc s org-export-dictionary))))))
4623 (or (plist-get translations encoding)
4624 (plist-get translations :default)
4625 s)))
4629 ;;; The Dispatcher
4631 ;; `org-export-dispatch' is the standard interactive way to start an
4632 ;; export process. It uses `org-export-dispatch-ui' as a subroutine
4633 ;; for its interface, which, in turn, delegates response to key
4634 ;; pressed to `org-export-dispatch-action'.
4636 (defvar org-export-dispatch-menu-entries nil
4637 "List of menu entries available for `org-export-dispatch'.
4638 This variable shouldn't be set directly. Set-up :menu-entry
4639 keyword in either `org-export-define-backend' or
4640 `org-export-define-derived-backend' instead.")
4642 ;;;###autoload
4643 (defun org-export-dispatch ()
4644 "Export dispatcher for Org mode.
4646 It provides an access to common export related tasks in a buffer.
4647 Its interface comes in two flavours: standard and expert. While
4648 both share the same set of bindings, only the former displays the
4649 valid keys associations. Set `org-export-dispatch-use-expert-ui'
4650 to switch to one or the other."
4651 (interactive)
4652 (let* ((input (save-window-excursion
4653 (unwind-protect
4654 (org-export-dispatch-ui (list org-export-initial-scope)
4656 org-export-dispatch-use-expert-ui)
4657 (and (get-buffer "*Org Export Dispatcher*")
4658 (kill-buffer "*Org Export Dispatcher*")))))
4659 (action (car input))
4660 (optns (cdr input)))
4661 (case action
4662 ;; First handle special hard-coded actions.
4663 (publish-current-file (org-e-publish-current-file (memq 'force optns)))
4664 (publish-current-project
4665 (org-e-publish-current-project (memq 'force optns)))
4666 (publish-choose-project
4667 (org-e-publish (assoc (org-icompleting-read
4668 "Publish project: "
4669 org-e-publish-project-alist nil t)
4670 org-e-publish-project-alist)
4671 (memq 'force optns)))
4672 (publish-all (org-e-publish-all (memq 'force optns)))
4673 (otherwise
4674 (funcall action
4675 (memq 'subtree optns)
4676 (memq 'visible optns)
4677 (memq 'body optns))))))
4679 (defun org-export-dispatch-ui (options first-key expertp)
4680 "Handle interface for `org-export-dispatch'.
4682 OPTIONS is a list containing current interactive options set for
4683 export. It can contain any of the following symbols:
4684 `body' toggles a body-only export
4685 `subtree' restricts export to current subtree
4686 `visible' restricts export to visible part of buffer.
4687 `force' force publishing files.
4689 FIRST-KEY is the key pressed to select the first level menu. It
4690 is nil when this menu hasn't been selected yet.
4692 EXPERTP, when non-nil, triggers expert UI. In that case, no help
4693 buffer is provided, but indications about currently active
4694 options are given in the prompt. Moreover, \[?] allows to switch
4695 back to standard interface."
4696 (let* ((fontify-key
4697 (lambda (key &optional access-key)
4698 ;; Fontify KEY string. Optional argument ACCESS-KEY, when
4699 ;; non-nil is the required first-level key to activate
4700 ;; KEY. When its value is t, activate KEY independently
4701 ;; on the first key, if any. A nil value means KEY will
4702 ;; only be activated at first level.
4703 (if (or (eq access-key t) (eq access-key first-key))
4704 (org-add-props key nil 'face 'org-warning)
4705 (org-no-properties key))))
4706 ;; Make sure order of menu doesn't depend on the order in
4707 ;; which back-ends are loaded.
4708 (backends (sort (copy-sequence org-export-dispatch-menu-entries)
4709 (lambda (a b) (< (car a) (car b)))))
4710 ;; Compute a list of allowed keys based on the first key
4711 ;; pressed, if any. Some keys (?1, ?2, ?3, ?4 and ?q) are
4712 ;; always available.
4713 (allowed-keys
4714 (nconc (list ?1 ?2 ?3 ?4)
4715 (mapcar 'car
4716 (if (not first-key) backends
4717 (nth 2 (assq first-key backends))))
4718 (cond ((eq first-key ?P) (list ?f ?p ?x ?a))
4719 ((not first-key) (list ?P)))
4720 (when expertp (list ??))
4721 (list ?q)))
4722 ;; Build the help menu for standard UI.
4723 (help
4724 (unless expertp
4725 (concat
4726 ;; Options are hard-coded.
4727 (format "Options
4728 [%s] Body only: %s [%s] Visible only: %s
4729 [%s] Export scope: %s [%s] Force publishing: %s\n\n"
4730 (funcall fontify-key "1" t)
4731 (if (memq 'body options) "On " "Off")
4732 (funcall fontify-key "2" t)
4733 (if (memq 'visible options) "On " "Off")
4734 (funcall fontify-key "3" t)
4735 (if (memq 'subtree options) "Subtree" "Buffer ")
4736 (funcall fontify-key "4" t)
4737 (if (memq 'force options) "On " "Off"))
4738 ;; Display registered back-end entries.
4739 (mapconcat
4740 (lambda (entry)
4741 (let ((top-key (car entry)))
4742 (concat
4743 (format "[%s] %s\n"
4744 (funcall fontify-key (char-to-string top-key))
4745 (nth 1 entry))
4746 (let ((sub-menu (nth 2 entry)))
4747 (unless (functionp sub-menu)
4748 ;; Split sub-menu into two columns.
4749 (let ((index -1))
4750 (concat
4751 (mapconcat
4752 (lambda (sub-entry)
4753 (incf index)
4754 (format (if (zerop (mod index 2)) " [%s] %-24s"
4755 "[%s] %s\n")
4756 (funcall fontify-key
4757 (char-to-string (car sub-entry))
4758 top-key)
4759 (nth 1 sub-entry)))
4760 sub-menu "")
4761 (when (zerop (mod index 2)) "\n"))))))))
4762 backends "\n")
4763 ;; Publishing menu is hard-coded.
4764 (format "\n[%s] Publish
4765 [%s] Current file [%s] Current project
4766 [%s] Choose project [%s] All projects\n\n"
4767 (funcall fontify-key "P")
4768 (funcall fontify-key "f" ?P)
4769 (funcall fontify-key "p" ?P)
4770 (funcall fontify-key "x" ?P)
4771 (funcall fontify-key "a" ?P))
4772 (format "\[%s] %s"
4773 (funcall fontify-key "q" t)
4774 (if first-key "Main menu" "Exit")))))
4775 ;; Build prompts for both standard and expert UI.
4776 (standard-prompt (unless expertp "Export command: "))
4777 (expert-prompt
4778 (when expertp
4779 (format
4780 "Export command (Options: %s%s%s%s) [%s]: "
4781 (if (memq 'body options) (funcall fontify-key "b" t) "-")
4782 (if (memq 'visible options) (funcall fontify-key "v" t) "-")
4783 (if (memq 'subtree options) (funcall fontify-key "s" t) "-")
4784 (if (memq 'force options) (funcall fontify-key "f" t) "-")
4785 (concat allowed-keys)))))
4786 ;; With expert UI, just read key with a fancy prompt. In standard
4787 ;; UI, display an intrusive help buffer.
4788 (if expertp
4789 (org-export-dispatch-action
4790 expert-prompt allowed-keys backends options first-key expertp)
4791 ;; At first call, create frame layout in order to display menu.
4792 (unless (get-buffer "*Org Export Dispatcher*")
4793 (delete-other-windows)
4794 (org-switch-to-buffer-other-window
4795 (get-buffer-create "*Org Export Dispatcher*"))
4796 (setq cursor-type nil))
4797 ;; At this point, the buffer containing the menu exists and is
4798 ;; visible in the current window. So, refresh it.
4799 (with-current-buffer "*Org Export Dispatcher*"
4800 (erase-buffer)
4801 (insert help))
4802 (org-fit-window-to-buffer)
4803 (org-export-dispatch-action
4804 standard-prompt allowed-keys backends options first-key expertp))))
4806 (defun org-export-dispatch-action
4807 (prompt allowed-keys backends options first-key expertp)
4808 "Read a character from command input and act accordingly.
4810 PROMPT is the displayed prompt, as a string. ALLOWED-KEYS is
4811 a list of characters available at a given step in the process.
4812 BACKENDS is a list of menu entries. OPTIONS, FIRST-KEY and
4813 EXPERTP are the same as defined in `org-export-dispatch-ui',
4814 which see.
4816 Toggle export options when required. Otherwise, return value is
4817 a list with action as CAR and a list of interactive export
4818 options as CDR."
4819 (let ((key (let ((k (read-char-exclusive prompt)))
4820 ;; Translate "C-a", "C-b"... into "a", "b"... Then take action
4821 ;; depending on user's key pressed.
4822 (if (< k 27) (+ k 96) k))))
4823 (cond
4824 ;; Ignore non-standard characters (i.e. "M-a") and
4825 ;; undefined associations.
4826 ((not (memq key allowed-keys))
4827 (ding)
4828 (unless expertp (message "Invalid key") (sit-for 1))
4829 (org-export-dispatch-ui options first-key expertp))
4830 ;; q key at first level aborts export. At second
4831 ;; level, cancel first key instead.
4832 ((eq key ?q) (if (not first-key) (error "Export aborted")
4833 (org-export-dispatch-ui options nil expertp)))
4834 ;; Help key: Switch back to standard interface if
4835 ;; expert UI was active.
4836 ((eq key ??) (org-export-dispatch-ui options first-key nil))
4837 ;; Toggle export options.
4838 ((memq key '(?1 ?2 ?3 ?4))
4839 (org-export-dispatch-ui
4840 (let ((option (case key (?1 'body) (?2 'visible) (?3 'subtree)
4841 (?4 'force))))
4842 (if (memq option options) (remq option options)
4843 (cons option options)))
4844 first-key expertp))
4845 ;; Action selected: Send key and options back to
4846 ;; `org-export-dispatch'.
4847 ((or first-key
4848 (and (eq first-key ?P) (memq key '(?f ?p ?x ?a)))
4849 (functionp (nth 2 (assq key backends))))
4850 (cons (cond
4851 ((not first-key) (nth 2 (assq key backends)))
4852 ;; Publishing actions are hard-coded. Send a special
4853 ;; signal to `org-export-dispatch'.
4854 ((eq first-key ?P)
4855 (case key
4856 (?f 'publish-current-file)
4857 (?p 'publish-current-project)
4858 (?x 'publish-choose-project)
4859 (?a 'publish-all)))
4860 (t (nth 2 (assq key (nth 2 (assq first-key backends))))))
4861 options))
4862 ;; Otherwise, enter sub-menu.
4863 (t (org-export-dispatch-ui options key expertp)))))
4866 (provide 'org-export)
4867 ;;; org-export.el ends here