summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2012-05-18 10:18:42 +0200
committerNicolas Goaziou <n.goaziou@gmail.com>2012-05-18 11:42:15 +0200
commit7421e96536c6cdb14836d9dc553a6e8e80440585 (patch)
tree0ab608d790a3d625ac1514597c7aed45d6a8afb8
parent1c2aaca83710fddecf5eccb1ef55ecd08d718e02 (diff)
downloadorg-mode-7421e96536c6cdb14836d9dc553a6e8e80440585.tar.gz
org-export: Remove naming convening for back-ends
* contrib/lisp/org-e-ascii.el (org-e-ascii-translate-alist): New variable. * contrib/lisp/org-e-html.el (org-e-html-translate-alist): New variable. (org-e-html-filters-alist): Move variable into an appropriate section. * contrib/lisp/org-e-latex.el (org-e-latex-translate-alist): New variable. * contrib/lisp/org-e-odt.el (org-e-odt-translate-alist): New variable. (org-e-odt-option-alist): Move variable into an appropriate section. * contrib/lisp/org-export.el (org-export-transcoder): Retrieve translators from `org-BACKEND-translate-alist' instead of applying a naming convention to each of them. * testing/lisp/test-org-export.el: Update tests.
-rw-r--r--contrib/lisp/org-e-ascii.el69
-rw-r--r--contrib/lisp/org-e-html.el107
-rw-r--r--contrib/lisp/org-e-latex.el60
-rw-r--r--contrib/lisp/org-e-odt.el133
-rw-r--r--contrib/lisp/org-export.el94
-rw-r--r--testing/lisp/test-org-export.el121
6 files changed, 393 insertions, 191 deletions
diff --git a/contrib/lisp/org-e-ascii.el b/contrib/lisp/org-e-ascii.el
index 5c3a9c6..0a48a71 100644
--- a/contrib/lisp/org-e-ascii.el
+++ b/contrib/lisp/org-e-ascii.el
@@ -67,23 +67,78 @@
(backend file &optional subtreep visible-only body-only ext-plist))
-
-;;; Internal Variables
-
+;;; Define Back-End
+;;
;; The following setting won't allow to modify preferred charset
;; through a buffer keyword or an option item, but, since the property
;; will appear in communication channel nonetheless, it allows to
;; override `org-e-ascii-charset' variable on the fly by the ext-plist
;; mechanism.
-
+;;
;; We also install a filter for headlines and sections, in order to
;; control blank lines separating them in output string.
+(defvar org-e-ascii-translate-alist
+ '((babel-call . org-e-ascii-babel-call)
+ (bold . org-e-ascii-bold)
+ (center-block . org-e-ascii-center-block)
+ (clock . org-e-ascii-clock)
+ (code . org-e-ascii-code)
+ (comment . org-e-ascii-comment)
+ (comment-block . org-e-ascii-comment-block)
+ (drawer . org-e-ascii-drawer)
+ (dynamic-block . org-e-ascii-dynamic-block)
+ (entity . org-e-ascii-entity)
+ (example-block . org-e-ascii-example-block)
+ (export-block . org-e-ascii-export-block)
+ (export-snippet . org-e-ascii-export-snippet)
+ (fixed-width . org-e-ascii-fixed-width)
+ (footnote-definition . org-e-ascii-footnote-definition)
+ (footnote-reference . org-e-ascii-footnote-reference)
+ (headline . org-e-ascii-headline)
+ (horizontal-rule . org-e-ascii-horizontal-rule)
+ (inline-babel-call . org-e-ascii-inline-babel-call)
+ (inline-src-block . org-e-ascii-inline-src-block)
+ (inlinetask . org-e-ascii-inlinetask)
+ (italic . org-e-ascii-italic)
+ (item . org-e-ascii-item)
+ (keyword . org-e-ascii-keyword)
+ (latex-environment . org-e-ascii-latex-environment)
+ (latex-fragment . org-e-ascii-latex-fragment)
+ (line-break . org-e-ascii-line-break)
+ (link . org-e-ascii-link)
+ (macro . org-e-ascii-macro)
+ (paragraph . org-e-ascii-paragraph)
+ (plain-list . org-e-ascii-plain-list)
+ (plain-text . org-e-ascii-plain-text)
+ (planning . org-e-ascii-planning)
+ (property-drawer . org-e-ascii-property-drawer)
+ (quote-block . org-e-ascii-quote-block)
+ (quote-section . org-e-ascii-quote-section)
+ (radio-target . org-e-ascii-radio-target)
+ (section . org-e-ascii-section)
+ (special-block . org-e-ascii-special-block)
+ (src-block . org-e-ascii-src-block)
+ (statistics-cookie . org-e-ascii-statistics-cookie)
+ (strike-through . org-e-ascii-strike-through)
+ (subscript . org-e-ascii-subscript)
+ (superscript . org-e-ascii-superscript)
+ (table . org-e-ascii-table)
+ (table-cell . org-e-ascii-table-cell)
+ (table-row . org-e-ascii-table-row)
+ (target . org-e-ascii-target)
+ (template . org-e-ascii-template)
+ (timestamp . org-e-ascii-timestamp)
+ (underline . org-e-ascii-underline)
+ (verbatim . org-e-ascii-verbatim)
+ (verse-block . org-e-ascii-verse-block))
+ "Alist between element or object types and translators.")
+
(defconst org-e-ascii-option-alist
'((:ascii-charset nil nil org-e-ascii-charset))
"Alist between ASCII export properties and ways to set them.
See `org-export-option-alist' for more information on the
-structure or the values.")
+structure of the values.")
(defconst org-e-ascii-filters-alist
'((:filter-headline . org-e-ascii-filter-headline-blank-lines)
@@ -91,6 +146,10 @@ structure or the values.")
"Alist between filters keywords and back-end specific filters.
See `org-export-filters-alist' for more information.")
+
+
+;;; Internal Variables
+
(defconst org-e-ascii-dictionary
'(("Footnotes\n"
("en"
diff --git a/contrib/lisp/org-e-html.el b/contrib/lisp/org-e-html.el
index 41f1608..3478fbd 100644
--- a/contrib/lisp/org-e-html.el
+++ b/contrib/lisp/org-e-html.el
@@ -85,9 +85,63 @@
"org-compat" (&optional buffer-or-name norecord label))
-
-
-;;; Internal Variables
+;;; Define Back-End
+
+(defvar org-e-html-translate-alist
+ '((babel-call . org-e-html-babel-call)
+ (bold . org-e-html-bold)
+ (center-block . org-e-html-center-block)
+ (clock . org-e-html-clock)
+ (code . org-e-html-code)
+ (comment . org-e-html-comment)
+ (comment-block . org-e-html-comment-block)
+ (drawer . org-e-html-drawer)
+ (dynamic-block . org-e-html-dynamic-block)
+ (entity . org-e-html-entity)
+ (example-block . org-e-html-example-block)
+ (export-block . org-e-html-export-block)
+ (export-snippet . org-e-html-export-snippet)
+ (fixed-width . org-e-html-fixed-width)
+ (footnote-definition . org-e-html-footnote-definition)
+ (footnote-reference . org-e-html-footnote-reference)
+ (headline . org-e-html-headline)
+ (horizontal-rule . org-e-html-horizontal-rule)
+ (inline-babel-call . org-e-html-inline-babel-call)
+ (inline-src-block . org-e-html-inline-src-block)
+ (inlinetask . org-e-html-inlinetask)
+ (italic . org-e-html-italic)
+ (item . org-e-html-item)
+ (keyword . org-e-html-keyword)
+ (latex-environment . org-e-html-latex-environment)
+ (latex-fragment . org-e-html-latex-fragment)
+ (line-break . org-e-html-line-break)
+ (link . org-e-html-link)
+ (macro . org-e-html-macro)
+ (paragraph . org-e-html-paragraph)
+ (plain-list . org-e-html-plain-list)
+ (plain-text . org-e-html-plain-text)
+ (planning . org-e-html-planning)
+ (property-drawer . org-e-html-property-drawer)
+ (quote-block . org-e-html-quote-block)
+ (quote-section . org-e-html-quote-section)
+ (radio-target . org-e-html-radio-target)
+ (section . org-e-html-section)
+ (special-block . org-e-html-special-block)
+ (src-block . org-e-html-src-block)
+ (statistics-cookie . org-e-html-statistics-cookie)
+ (strike-through . org-e-html-strike-through)
+ (subscript . org-e-html-subscript)
+ (superscript . org-e-html-superscript)
+ (table . org-e-html-table)
+ (table-cell . org-e-html-table-cell)
+ (table-row . org-e-html-table-row)
+ (target . org-e-html-target)
+ (template . org-e-html-template)
+ (timestamp . org-e-html-timestamp)
+ (underline . org-e-html-underline)
+ (verbatim . org-e-html-verbatim)
+ (verse-block . org-e-html-verse-block))
+ "Alist between element or object types and translators.")
(defconst org-e-html-option-alist
'((:agenda-style nil nil org-agenda-export-html-style)
@@ -109,31 +163,18 @@
(:xml-declaration nil nil org-e-html-xml-declaration)
(:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments)
(:mathjax "MATHJAX" nil "" space))
- "Alist between export properties and ways to set them.
-
-The car of the alist is the property name, and the cdr is a list
-like \(KEYWORD OPTION DEFAULT BEHAVIOUR\) where:
-
-KEYWORD is a string representing a buffer keyword, or nil.
-OPTION is a string that could be found in an #+OPTIONS: line.
-DEFAULT is the default value for the property.
-BEHAVIOUR determine how Org should handle multiple keywords for
-the same property. It is a symbol among:
- nil Keep old value and discard the new one.
- t Replace old value with the new one.
- `space' Concatenate the values, separating them with a space.
- `newline' Concatenate the values, separating them with
- a newline.
- `split' Split values at white spaces, and cons them to the
- previous list.
-
-KEYWORD and OPTION have precedence over DEFAULT.
-
-All these properties should be back-end agnostic. For back-end
-specific properties, define a similar variable named
-`org-BACKEND-option-alist', replacing BACKEND with the name of
-the appropriate back-end. You can also redefine properties
-there, as they have precedence over these.")
+ "Alist between HTML export properties and ways to set them.
+See `org-export-option-alist' for more information on the
+structure of the values.")
+
+(defconst org-e-html-filters-alist
+ '((:filter-final-output . org-e-html-final-function))
+ "Alist between filters keywords and back-end specific filters.
+See `org-export-filters-alist' for more information.")
+
+
+
+;;; Internal Variables
;; FIXME: it already exists in org-e-html.el
(defconst org-e-html-cvt-link-fn
@@ -3023,16 +3064,6 @@ contextual information."
;;; Filter Functions
-;;;; Filter Settings
-
-(defconst org-e-html-filters-alist
- '((:filter-final-output . org-e-html-final-function))
- "Alist between filters keywords and back-end specific filters.
-See `org-export-filters-alist' for more information.")
-
-
-;;;; Filters
-
(defun org-e-html-final-function (contents backend info)
(if (not org-e-html-pretty-output) contents
(with-temp-buffer
diff --git a/contrib/lisp/org-e-latex.el b/contrib/lisp/org-e-latex.el
index 9d33e27..974b6b3 100644
--- a/contrib/lisp/org-e-latex.el
+++ b/contrib/lisp/org-e-latex.el
@@ -81,7 +81,63 @@
-;;; Internal Variables
+;;; Define Back-End
+
+(defvar org-e-latex-translate-alist
+ '((babel-call . org-e-latex-babel-call)
+ (bold . org-e-latex-bold)
+ (center-block . org-e-latex-center-block)
+ (clock . org-e-latex-clock)
+ (code . org-e-latex-code)
+ (comment . org-e-latex-comment)
+ (comment-block . org-e-latex-comment-block)
+ (drawer . org-e-latex-drawer)
+ (dynamic-block . org-e-latex-dynamic-block)
+ (entity . org-e-latex-entity)
+ (example-block . org-e-latex-example-block)
+ (export-block . org-e-latex-export-block)
+ (export-snippet . org-e-latex-export-snippet)
+ (fixed-width . org-e-latex-fixed-width)
+ (footnote-definition . org-e-latex-footnote-definition)
+ (footnote-reference . org-e-latex-footnote-reference)
+ (headline . org-e-latex-headline)
+ (horizontal-rule . org-e-latex-horizontal-rule)
+ (inline-babel-call . org-e-latex-inline-babel-call)
+ (inline-src-block . org-e-latex-inline-src-block)
+ (inlinetask . org-e-latex-inlinetask)
+ (italic . org-e-latex-italic)
+ (item . org-e-latex-item)
+ (keyword . org-e-latex-keyword)
+ (latex-environment . org-e-latex-latex-environment)
+ (latex-fragment . org-e-latex-latex-fragment)
+ (line-break . org-e-latex-line-break)
+ (link . org-e-latex-link)
+ (macro . org-e-latex-macro)
+ (paragraph . org-e-latex-paragraph)
+ (plain-list . org-e-latex-plain-list)
+ (plain-text . org-e-latex-plain-text)
+ (planning . org-e-latex-planning)
+ (property-drawer . org-e-latex-property-drawer)
+ (quote-block . org-e-latex-quote-block)
+ (quote-section . org-e-latex-quote-section)
+ (radio-target . org-e-latex-radio-target)
+ (section . org-e-latex-section)
+ (special-block . org-e-latex-special-block)
+ (src-block . org-e-latex-src-block)
+ (statistics-cookie . org-e-latex-statistics-cookie)
+ (strike-through . org-e-latex-strike-through)
+ (subscript . org-e-latex-subscript)
+ (superscript . org-e-latex-superscript)
+ (table . org-e-latex-table)
+ (table-cell . org-e-latex-table-cell)
+ (table-row . org-e-latex-table-row)
+ (target . org-e-latex-target)
+ (template . org-e-latex-template)
+ (timestamp . org-e-latex-timestamp)
+ (underline . org-e-latex-underline)
+ (verbatim . org-e-latex-verbatim)
+ (verse-block . org-e-latex-verse-block))
+ "Alist between element or object types and translators.")
(defconst org-e-latex-option-alist
'((:date "DATE" nil org-e-latex-date-format t)
@@ -90,7 +146,7 @@
(:latex-header-extra "LATEX_HEADER" nil nil newline))
"Alist between LaTeX export properties and ways to set them.
See `org-export-option-alist' for more information on the
-structure of the value.")
+structure of the values.")
diff --git a/contrib/lisp/org-e-odt.el b/contrib/lisp/org-e-odt.el
index fe1b148..b713b05 100644
--- a/contrib/lisp/org-e-odt.el
+++ b/contrib/lisp/org-e-odt.el
@@ -24,9 +24,95 @@
;;; Commentary:
;;; Code:
+
(eval-when-compile
(require 'cl))
+
+;;; Define Back-End
+
+(defvar org-e-odt-translate-alist
+ '((babel-call . org-e-odt-babel-call)
+ (bold . org-e-odt-bold)
+ (center-block . org-e-odt-center-block)
+ (clock . org-e-odt-clock)
+ (code . org-e-odt-code)
+ (comment . org-e-odt-comment)
+ (comment-block . org-e-odt-comment-block)
+ (drawer . org-e-odt-drawer)
+ (dynamic-block . org-e-odt-dynamic-block)
+ (entity . org-e-odt-entity)
+ (example-block . org-e-odt-example-block)
+ (export-block . org-e-odt-export-block)
+ (export-snippet . org-e-odt-export-snippet)
+ (fixed-width . org-e-odt-fixed-width)
+ (footnote-definition . org-e-odt-footnote-definition)
+ (footnote-reference . org-e-odt-footnote-reference)
+ (headline . org-e-odt-headline)
+ (horizontal-rule . org-e-odt-horizontal-rule)
+ (inline-babel-call . org-e-odt-inline-babel-call)
+ (inline-src-block . org-e-odt-inline-src-block)
+ (inlinetask . org-e-odt-inlinetask)
+ (italic . org-e-odt-italic)
+ (item . org-e-odt-item)
+ (keyword . org-e-odt-keyword)
+ (latex-environment . org-e-odt-latex-environment)
+ (latex-fragment . org-e-odt-latex-fragment)
+ (line-break . org-e-odt-line-break)
+ (link . org-e-odt-link)
+ (macro . org-e-odt-macro)
+ (paragraph . org-e-odt-paragraph)
+ (plain-list . org-e-odt-plain-list)
+ (plain-text . org-e-odt-plain-text)
+ (planning . org-e-odt-planning)
+ (property-drawer . org-e-odt-property-drawer)
+ (quote-block . org-e-odt-quote-block)
+ (quote-section . org-e-odt-quote-section)
+ (radio-target . org-e-odt-radio-target)
+ (section . org-e-odt-section)
+ (special-block . org-e-odt-special-block)
+ (src-block . org-e-odt-src-block)
+ (statistics-cookie . org-e-odt-statistics-cookie)
+ (strike-through . org-e-odt-strike-through)
+ (subscript . org-e-odt-subscript)
+ (superscript . org-e-odt-superscript)
+ (table . org-e-odt-table)
+ (table-cell . org-e-odt-table-cell)
+ (table-row . org-e-odt-table-row)
+ (target . org-e-odt-target)
+ (template . org-e-odt-template)
+ (timestamp . org-e-odt-timestamp)
+ (underline . org-e-odt-underline)
+ (verbatim . org-e-odt-verbatim)
+ (verse-block . org-e-odt-verse-block))
+ "Alist between element or object types and translators.")
+
+(defvar org-e-odt-option-alist
+ '(
+ ;; (:agenda-style nil nil org-agenda-export-html-style)
+ ;; (:convert-org-links nil nil org-e-odt-link-org-files-as-html)
+ ;; ;; FIXME Use (org-xml-encode-org-text-skip-links s) ??
+ ;; ;; (:expand-quoted-html nil "@" org-e-odt-expand)
+ ;; (:inline-images nil nil org-e-odt-inline-images)
+ ;; ;; (:link-home nil nil org-e-odt-link-home) FIXME
+ ;; ;; (:link-up nil nil org-e-odt-link-up) FIXME
+ ;; (:style nil nil org-e-odt-style)
+ ;; (:style-extra nil nil org-e-odt-style-extra)
+ ;; (:style-include-default nil nil org-e-odt-style-include-default)
+ ;; (:style-include-scripts nil nil org-e-odt-style-include-scripts)
+ ;; ;; (:timestamp nil nil org-e-odt-with-timestamp)
+ ;; (:html-extension nil nil org-e-odt-extension)
+ ;; (:html-postamble nil nil org-e-odt-postamble)
+ ;; (:html-preamble nil nil org-e-odt-preamble)
+ ;; (:html-table-tag nil nil org-e-odt-table-tag)
+ ;; (:xml-declaration nil nil org-e-odt-xml-declaration)
+ (:odt-styles-file "ODT_STYLES_FILE" nil nil t)
+ (:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments))
+ "Alist between ODT export properties and ways to set them.
+See `org-export-option-alist' for more information on the
+structure of the values.")
+
+
;; FIXMES
;; org-e-odt-preprocess-latex-fragments
;; org-export-as-e-odt-and-open
@@ -1762,53 +1848,6 @@ captions on export.")
;;;; HTML Internal Variables
-(defvar org-e-odt-option-alist
- '(
- ;; (:agenda-style nil nil org-agenda-export-html-style)
- ;; (:convert-org-links nil nil org-e-odt-link-org-files-as-html)
- ;; ;; FIXME Use (org-xml-encode-org-text-skip-links s) ??
- ;; ;; (:expand-quoted-html nil "@" org-e-odt-expand)
- ;; (:inline-images nil nil org-e-odt-inline-images)
- ;; ;; (:link-home nil nil org-e-odt-link-home) FIXME
- ;; ;; (:link-up nil nil org-e-odt-link-up) FIXME
- ;; (:style nil nil org-e-odt-style)
- ;; (:style-extra nil nil org-e-odt-style-extra)
- ;; (:style-include-default nil nil org-e-odt-style-include-default)
- ;; (:style-include-scripts nil nil org-e-odt-style-include-scripts)
- ;; ;; (:timestamp nil nil org-e-odt-with-timestamp)
- ;; (:html-extension nil nil org-e-odt-extension)
- ;; (:html-postamble nil nil org-e-odt-postamble)
- ;; (:html-preamble nil nil org-e-odt-preamble)
- ;; (:html-table-tag nil nil org-e-odt-table-tag)
- ;; (:xml-declaration nil nil org-e-odt-xml-declaration)
- (:odt-styles-file "ODT_STYLES_FILE" nil nil t)
- (:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments))
- "Alist between export properties and ways to set them.
-
-The car of the alist is the property name, and the cdr is a list
-like \(KEYWORD OPTION DEFAULT BEHAVIOUR\) where:
-
-KEYWORD is a string representing a buffer keyword, or nil.
-OPTION is a string that could be found in an #+OPTIONS: line.
-DEFAULT is the default value for the property.
-BEHAVIOUR determine how Org should handle multiple keywords for
-the same property. It is a symbol among:
- nil Keep old value and discard the new one.
- t Replace old value with the new one.
- `space' Concatenate the values, separating them with a space.
- `newline' Concatenate the values, separating them with
- a newline.
- `split' Split values at white spaces, and cons them to the
- previous list.
-
-KEYWORD and OPTION have precedence over DEFAULT.
-
-All these properties should be back-end agnostic. For back-end
-specific properties, define a similar variable named
-`org-BACKEND-option-alist', replacing BACKEND with the name of
-the appropriate back-end. You can also redefine properties
-there, as they have precedence over these.")
-
(defvar html-table-tag nil) ; dynamically scoped into this.
;; FIXME: it already exists in org-e-odt.el
diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
index 2027fd4..a568d13 100644
--- a/contrib/lisp/org-export.el
+++ b/contrib/lisp/org-export.el
@@ -46,50 +46,60 @@
;; The core function is `org-export-as'. It returns the transcoded
;; buffer as a string.
;;
-;; In order to derive an exporter out of this generic implementation,
-;; one can define a transcode function for each element or object.
-;; Such function should return a string for the corresponding element,
-;; without any trailing space, or nil. It must accept three
-;; arguments:
-;; 1. the element or object itself,
-;; 2. its contents, or nil when it isn't recursive,
-;; 3. the property list used as a communication channel.
-;;
-;; If no such function is found, that element or object type will
-;; simply be ignored, along with any separating blank line. The same
-;; will happen if the function returns the nil value. If that
-;; function returns the empty string, the type will be ignored, but
-;; the blank lines will be kept.
-;;
-;; Contents, when not nil, are stripped from any global indentation
-;; (although the relative one is preserved). They also always end
-;; with a single newline character.
-;;
-;; These functions must follow a strict naming convention:
-;; `org-BACKEND-TYPE' where, obviously, BACKEND is the name of the
-;; export back-end and TYPE the type of the element or object handled.
-;;
-;; Moreover, two additional functions can be defined. On the one
-;; hand, `org-BACKEND-template' returns the final transcoded string,
-;; and can be used to add a preamble and a postamble to document's
-;; body. It must accept two arguments: the transcoded string and the
-;; property list containing export options. On the other hand,
-;; `org-BACKEND-plain-text', when defined, is to be called on every
-;; text not recognized as an element or an object. It must accept two
-;; arguments: the text string and the information channel.
+;; In order to implement a back-end for this generic exporter, up to
+;; three steps may be needed:
+;;
+;; 1. Define a variable, `org-BACKEND-translate-alist' where elements
+;; and objects types are associated to translator functions.
+;;
+;; These functions should return a string without any trailing
+;; space, or nil. They must accept three arguments: the object or
+;; element itself, its contents or nil when it isn't recursive and
+;; the property list used as a communication channel.
+;;
+;; Contents, when not nil, are stripped from any global indentation
+;; (although the relative one is preserved). They also always end
+;; with a single newline character.
+;;
+;; If, for a given type, no function is found, that element or
+;; object type will simply be ignored, along with any blank line or
+;; white space at its end. The same will happen if the function
+;; returns the nil value. If that function returns the empty
+;; string, the type will be ignored, but the blank lines or white
+;; spaces will be kept.
+;;
+;; In addition to element and object types, one function can be
+;; associated to the `template' symbol and another one to the
+;; `plain-list' symbol. The former returns the final transcoded
+;; string, and can be used to add a preamble and a postamble to
+;; document's body. It must accept two arguments: the transcoded
+;; string and the property list containing export options. The
+;; latter, when defined, is to be called on every text not
+;; recognized as an element or an object. It must accept two
+;; arguments: the text string and the information channel.
+;;
+;; 2. Optionally define a variable, `org-BACKEND-option-alist', in
+;; order to support new export options, buffer keywords or
+;; "#+OPTIONS:" items specific to the back-end. See
+;; `org-export-option-alist' for supported defaults and syntax.
+;;
+;; 3. Optionally define a variable, `org-BACKEND-filters-alist', in
+;; order to apply developer filters. See "The Filter System"
+;; section in this file for more information.
+;;
+;; If the new back-end shares most properties with another one,
+;; `org-export-define-derived-backend' can be used to simplify the
+;; process.
;;
;; Any back-end can define its own variables. Among them, those
;; customizables should belong to the `org-export-BACKEND' group.
-;; Also, a special variable, `org-BACKEND-option-alist', allows to
-;; define buffer keywords and "#+options:" items specific to that
-;; back-end. See `org-export-option-alist' for supported defaults and
-;; syntax.
;;
;; Tools for common tasks across back-ends are implemented in the
;; penultimate part of this file. A dispatcher for standard back-ends
;; is provided in the last one.
;;; Code:
+
(eval-when-compile (require 'cl))
(require 'org-element)
;; Require major back-ends and publishing tools
@@ -1542,7 +1552,10 @@ non-nil, is a list of tags marking a subtree as exportable."
;; parse tree traversals skip it, `org-export-interpret-p' tells which
;; elements or objects should be seen as real Org syntax and
;; `org-export-expand' transforms the others back into their original
-;; shape.
+;; shape
+;;
+;; `org-export-transcoder' is an accessor returning appropriate
+;; translator function for a given element or object.
(defun org-export-transcoder (blob info)
"Return appropriate transcoder for BLOB.
@@ -1550,9 +1563,12 @@ INFO is a plist containing export directives."
(let ((type (org-element-type blob)))
;; Return contents only for complete parse trees.
(if (eq type 'org-data) (lambda (blob contents info) contents)
- (let ((transcoder
- (intern (format "org-%s-%s" (plist-get info :back-end) type))))
- (and (fboundp transcoder) transcoder)))))
+ (let ((translate-alist
+ (intern (format "org-%s-translate-alist"
+ (plist-get info :back-end)))))
+ (when (boundp translate-alist)
+ (let ((transcoder (cdr (assq type (symbol-value translate-alist)))))
+ (and (fboundp transcoder) transcoder)))))))
(defun org-export-data (data info)
"Convert DATA into current back-end format.
diff --git a/testing/lisp/test-org-export.el b/testing/lisp/test-org-export.el
index 82002e2..910eadd 100644
--- a/testing/lisp/test-org-export.el
+++ b/testing/lisp/test-org-export.el
@@ -23,20 +23,27 @@
(defmacro org-test-with-backend (backend &rest body)
"Execute body with an export back-end defined.
-BACKEND is the name, as a string, of the back-end. BODY is the
-body to execute. The defined back-end simply returns parsed data
-as Org syntax."
+BACKEND is the name of the back-end. BODY is the body to
+execute. The defined back-end simply returns parsed data as Org
+syntax."
(declare (debug (form body)) (indent 1))
- `(flet ,(let (transcoders)
- (dolist (type (append org-element-all-elements
- org-element-all-objects)
- transcoders)
- (push `(,(intern (format "org-%s-%s" backend type))
- (obj contents info)
- (,(intern (format "org-element-%s-interpreter" type))
- obj contents))
- transcoders)))
- ,@body))
+ `(let ((,(intern (format "org-%s-translate-alist" backend))
+ ',(let (transcode-table)
+ (dolist (type (append org-element-all-elements
+ org-element-all-objects)
+ transcode-table)
+ (push (cons type (intern (format "org-%s-%s" backend type)))
+ transcode-table)))))
+ (flet ,(let (transcoders)
+ (dolist (type (append org-element-all-elements
+ org-element-all-objects)
+ transcoders)
+ (push `(,(intern (format "org-%s-%s" backend type))
+ (obj contents info)
+ (,(intern (format "org-element-%s-interpreter" type))
+ obj contents))
+ transcoders)))
+ ,@body)))
(defmacro org-test-with-parsed-data (data &rest body)
"Execute body with parsed data available.
@@ -140,7 +147,7 @@ already filled in `info'."
"Test if export options have an impact on output."
;; Test exclude tags.
(org-test-with-temp-text "* Head1 :noexport:"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(equal (org-export-as 'test nil nil nil '(:exclude-tags ("noexport")))
""))))
@@ -150,7 +157,7 @@ already filled in `info'."
** Sub-Head1.1 :export:
*** Sub-Head1.1.1
* Head2"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(string-match
"\\* Head1\n\\*\\* Sub-Head1.1[ \t]+:export:\n\\*\\*\\* Sub-Head1.1.1\n"
@@ -162,7 +169,7 @@ already filled in `info'."
** Sub-Head2
* Head2 :noexport:
** Sub-Head1 :export:"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(string-match
"\\* Head1[ \t]+:export:\n\\*\\* Sub-Head2\n"
@@ -172,24 +179,24 @@ already filled in `info'."
;; Ignore tasks.
(let ((org-todo-keywords '((sequence "TODO" "DONE"))))
(org-test-with-temp-text "* TODO Head1"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should (equal (org-export-as 'test nil nil nil '(:with-tasks nil))
"")))))
(let ((org-todo-keywords '((sequence "TODO" "DONE"))))
(org-test-with-temp-text "* TODO Head1"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should (equal (org-export-as 'test nil nil nil '(:with-tasks t))
"* TODO Head1\n")))))
;; Archived tree.
(org-test-with-temp-text "* Head1 :archive:"
(let ((org-archive-tag "archive"))
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(equal (org-export-as 'test nil nil nil '(:with-archived-trees nil))
"")))))
(org-test-with-temp-text "* Head1 :archive:\nbody\n** Sub-head 2"
(let ((org-archive-tag "archive"))
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(string-match
"\\* Head1[ \t]+:archive:"
@@ -197,7 +204,7 @@ already filled in `info'."
'(:with-archived-trees headline)))))))
(org-test-with-temp-text "* Head1 :archive:"
(let ((org-archive-tag "archive"))
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(string-match
"\\`\\* Head1[ \t]+:archive:\n\\'"
@@ -205,20 +212,20 @@ already filled in `info'."
;; Drawers.
(let ((org-drawers '("TEST")))
(org-test-with-temp-text ":TEST:\ncontents\n:END:"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should (equal (org-export-as 'test nil nil nil '(:with-drawers nil))
""))
(should (equal (org-export-as 'test nil nil nil '(:with-drawers t))
":TEST:\ncontents\n:END:\n")))))
(let ((org-drawers '("FOO" "BAR")))
(org-test-with-temp-text ":FOO:\nkeep\n:END:\n:BAR:\nremove\n:END:"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(equal (org-export-as 'test nil nil nil '(:with-drawers ("FOO")))
":FOO:\nkeep\n:END:\n")))))
;; Timestamps.
(org-test-with-temp-text "[2012-04-29 sun. 10:45]<2012-04-29 sun. 10:45>"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(equal (org-export-as 'test nil nil nil '(:with-timestamps t))
"[2012-04-29 sun. 10:45]<2012-04-29 sun. 10:45>\n"))
@@ -233,7 +240,7 @@ already filled in `info'."
;; Clocks.
(let ((org-clock-string "CLOCK:"))
(org-test-with-temp-text "CLOCK: [2012-04-29 sun. 10:45]"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(equal (org-export-as 'test nil nil nil '(:with-clocks t))
"CLOCK: [2012-04-29 sun. 10:45]\n"))
@@ -242,7 +249,7 @@ already filled in `info'."
;; Plannings.
(let ((org-closed-string "CLOSED:"))
(org-test-with-temp-text "CLOSED: [2012-04-29 sun. 10:45]"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should
(equal (org-export-as 'test nil nil nil '(:with-plannings t))
"CLOSED: [2012-04-29 sun. 10:45]\n"))
@@ -254,7 +261,7 @@ already filled in `info'."
"Test if export process ignores commented trees."
(let ((org-comment-string "COMMENT"))
(org-test-with-temp-text "* COMMENT Head1"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(should (equal (org-export-as 'test) ""))))))
(ert-deftest test-org-export/export-scope ()
@@ -264,7 +271,7 @@ already filled in `info'."
** Head2
text
*** Head3"
- (org-test-with-backend "test"
+ (org-test-with-backend test
;; Subtree.
(forward-line 3)
(should (equal (org-export-as 'test 'subtree) "text\n*** Head3\n"))
@@ -297,14 +304,14 @@ text
#+BEGIN_SRC emacs-lisp
\(+ 1 2)
#+END_SRC"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(forward-line 1)
(should (equal (org-export-as 'test 'subtree) ": 3\n")))))
(ert-deftest test-org-export/export-snippet ()
"Test export snippets transcoding."
(org-test-with-temp-text "<test@A><t@B>"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(flet ((org-test-export-snippet
(snippet contents info)
(when (eq (org-export-snippet-backend snippet) 'test)
@@ -363,7 +370,7 @@ body\n")))
(ert-deftest test-org-export/user-ignore-list ()
"Test if `:ignore-list' accepts user input."
- (org-test-with-backend "test"
+ (org-test-with-backend test
(flet ((skip-note-head
(data backend info)
;; Ignore headlines with the word "note" in their title.
@@ -382,7 +389,7 @@ body\n")))
(ert-deftest test-org-export/before-parsing-hook ()
"Test `org-export-before-parsing-hook'."
- (org-test-with-backend "test"
+ (org-test-with-backend test
(org-test-with-temp-text "* Headline 1\nBody 1\n* Headline 2\nBody 2"
(let ((org-export-before-parsing-hook
'((lambda ()
@@ -457,7 +464,7 @@ body\n")))
(org-test-with-temp-text "[fn:1] Out of scope
* Title
Paragraph[fn:1]"
- (org-test-with-backend "test"
+ (org-test-with-backend test
(flet ((org-test-footnote-reference
(fn-ref contents info)
(org-element-interpret-data
@@ -864,45 +871,39 @@ Another text. (ref:text)
(mapcar (lambda (cell) (org-export-table-cell-alignment cell info))
(org-element-map tree 'table-cell 'identity))))))
;; 2. The last alignment cookie has precedence.
- (org-test-with-temp-text "
+ (org-test-with-parsed-data "
| <l8> |
| cell |
| <r9> |"
- (let* ((tree (org-element-parse-buffer))
- (info `(:parse-tree ,tree)))
- (should
- (equal
- '(right right right)
- (mapcar (lambda (cell) (org-export-table-cell-alignment cell info))
- (org-element-map tree 'table-cell 'identity))))))
+ (should
+ (equal
+ '(right right right)
+ (mapcar (lambda (cell) (org-export-table-cell-alignment cell info))
+ (org-element-map tree 'table-cell 'identity)))))
;; 3. If there's no cookie, cell's contents determine alignment.
;; A column mostly made of cells containing numbers will align
;; its cells to the right.
- (org-test-with-temp-text "
+ (org-test-with-parsed-data "
| 123 |
| some text |
| 12345 |"
- (let* ((tree (org-element-parse-buffer))
- (info `(:parse-tree ,tree)))
- (should
- (equal
- '(right right right)
- (mapcar (lambda (cell)
- (org-export-table-cell-alignment cell info))
- (org-element-map tree 'table-cell 'identity))))))
- ;; 5. Otherwise, they will be aligned to the left.
- (org-test-with-temp-text "
+ (should
+ (equal
+ '(right right right)
+ (mapcar (lambda (cell)
+ (org-export-table-cell-alignment cell info))
+ (org-element-map tree 'table-cell 'identity)))))
+ ;; 4. Otherwise, they will be aligned to the left.
+ (org-test-with-parsed-data "
| text |
| some text |
| \alpha |"
- (let* ((tree (org-element-parse-buffer))
- (info `(:parse-tree ,tree)))
- (should
- (equal
- '(left left left)
- (mapcar (lambda (cell)
- (org-export-table-cell-alignment cell info))
- (org-element-map tree 'table-cell 'identity))))))))
+ (should
+ (equal
+ '(left left left)
+ (mapcar (lambda (cell)
+ (org-export-table-cell-alignment cell info))
+ (org-element-map tree 'table-cell 'identity)))))))
(ert-deftest test-org-export/table-cell-borders ()
"Test `org-export-table-cell-borders' specifications."