From e3369c07f01f6c604c9a835fe7ea6e27b017ce5f Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 8 Sep 2014 11:57:27 +0200 Subject: [PATCH] Revert "Merge export and special blocks within back-ends" This reverts commit fbc7097ffa30225ace2b80e9f7466ee387491c44. Conflicts: lisp/ox-texinfo.el --- contrib/lisp/ox-groff.el | 17 ++++++-- contrib/lisp/ox-koma-letter.el | 9 +++++ lisp/org-element.el | 85 +++++++++++++++++++++++++++++++--------- lisp/ox-ascii.el | 22 +++++++---- lisp/ox-beamer.el | 11 ++++++ lisp/ox-html.el | 47 +++++++++++++--------- lisp/ox-latex.el | 30 ++++++++------ lisp/ox-man.el | 18 +++++++-- lisp/ox-md.el | 11 +++++- lisp/ox-odt.el | 73 ++++++++++++++++++---------------- lisp/ox-texinfo.el | 15 +++++-- lisp/ox.el | 15 ++++++- testing/lisp/test-org-element.el | 39 ++++++++++++++++++ testing/lisp/test-ox.el | 10 ++++- 14 files changed, 298 insertions(+), 104 deletions(-) diff --git a/contrib/lisp/ox-groff.el b/contrib/lisp/ox-groff.el index 9475a9fa8..7fbd16bb0 100644 --- a/contrib/lisp/ox-groff.el +++ b/contrib/lisp/ox-groff.el @@ -56,6 +56,7 @@ (dynamic-block . org-groff-dynamic-block) (entity . org-groff-entity) (example-block . org-groff-example-block) + (export-block . org-groff-export-block) (export-snippet . org-groff-export-snippet) (fixed-width . org-groff-fixed-width) (footnote-definition . org-groff-footnote-definition) @@ -882,6 +883,14 @@ information." (format ".DS L\n%s\n.DE" (org-export-format-code-default example-block info)))) +;;; Export Block + +(defun org-groff-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to Groff. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (string= (org-element-property :type export-block) "GROFF") + (org-remove-indentation (org-element-property :value export-block)))) + ;;; Export Snippet (defun org-groff-export-snippet (export-snippet contents info) @@ -1469,10 +1478,10 @@ holding contextual information." "Transcode a SPECIAL-BLOCK element from Org to Groff. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (if (org-export-raw-special-block-p special-block info) - (org-remove-indentation (org-element-property :raw-value special-block)) - (let ((type (downcase (org-element-property :type special-block)))) - (org-groff--wrap-label special-block (format "%s\n" contents))))) + (let ((type (downcase (org-element-property :type special-block)))) + (org-groff--wrap-label + special-block + (format "%s\n" contents)))) ;;; Src Block diff --git a/contrib/lisp/ox-koma-letter.el b/contrib/lisp/ox-koma-letter.el index d3aa335fb..32dd1999b 100644 --- a/contrib/lisp/ox-koma-letter.el +++ b/contrib/lisp/ox-koma-letter.el @@ -518,6 +518,15 @@ are present return the preferred one as determined by ;;; Transcode Functions +;;;; Export Block + +(defun org-koma-letter-export-block (export-block contents info) + "Transcode an EXPORT-BLOCK element into KOMA Scrlttr2 code. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (when (member (org-element-property :type export-block) '("KOMA-LETTER" "LATEX")) + (org-remove-indentation (org-element-property :value export-block)))) + ;;;; Export Snippet (defun org-koma-letter-export-snippet (export-snippet contents info) diff --git a/lisp/org-element.el b/lisp/org-element.el index 4b3df91d1..f175fbc50 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -45,11 +45,11 @@ ;; and `special-block'. ;; ;; Other element types are: `babel-call', `clock', `comment', -;; `comment-block', `diary-sexp', `example-block', `fixed-width', -;; `horizontal-rule', `keyword', `latex-environment', `node-property', -;; `paragraph', `planning', `src-block', `table', `table-row' and -;; `verse-block'. Among them, `paragraph' and `verse-block' types can -;; contain Org objects and plain text. +;; `comment-block', `diary-sexp', `example-block', `export-block', +;; `fixed-width', `horizontal-rule', `keyword', `latex-environment', +;; `node-property', `paragraph', `planning', `src-block', `table', +;; `table-row' and `verse-block'. Among them, `paragraph' and +;; `verse-block' types can contain Org objects and plain text. ;; ;; Objects are related to document's contents. Some of them are ;; recursive. Associated types are of the following: `bold', `code', @@ -169,11 +169,11 @@ is not sufficient to know if point is at a paragraph ending. See (defconst org-element-all-elements '(babel-call center-block clock comment comment-block diary-sexp drawer - dynamic-block example-block fixed-width footnote-definition - headline horizontal-rule inlinetask item keyword - latex-environment node-property paragraph plain-list - planning property-drawer quote-block section special-block - src-block table table-row verse-block) + dynamic-block example-block export-block fixed-width + footnote-definition headline horizontal-rule inlinetask item + keyword latex-environment node-property paragraph plain-list + planning property-drawer quote-block section + special-block src-block table table-row verse-block) "Complete list of element types.") (defconst org-element-greater-elements @@ -194,7 +194,7 @@ is not sufficient to know if point is at a paragraph ending. See superscript table-cell underline) "List of recursive object types.") -(defconst org-element-block-name-alist +(defvar org-element-block-name-alist '(("CENTER" . org-element-center-block-parser) ("COMMENT" . org-element-comment-block-parser) ("EXAMPLE" . org-element-example-block-parser) @@ -1520,9 +1520,8 @@ keyword and CDR is a plist of affiliated keywords along with their value. Return a list whose CAR is `special-block' and CDR is a plist -containing `:type', `:raw-value', `:begin', `:end', -`:contents-begin', `:contents-end', `:post-blank' and -`:post-affiliated' keywords. +containing `:type', `:begin', `:end', `:contents-begin', +`:contents-end', `:post-blank' and `:post-affiliated' keywords. Assume point is at the beginning of the block." (let* ((case-fold-search t) @@ -1551,10 +1550,6 @@ Assume point is at the beginning of the block." (list 'special-block (nconc (list :type type - :raw-value - (and contents-begin - (buffer-substring-no-properties - contents-begin contents-end)) :begin begin :end end :contents-begin contents-begin @@ -1905,6 +1900,60 @@ CONTENTS is nil." "#+END_EXAMPLE"))) +;;;; Export Block + +(defun org-element-export-block-parser (limit affiliated) + "Parse an export block. + +LIMIT bounds the search. AFFILIATED is a list of which CAR is +the buffer position at the beginning of the first affiliated +keyword and CDR is a plist of affiliated keywords along with +their value. + +Return a list whose CAR is `export-block' and CDR is a plist +containing `:begin', `:end', `:type', `:value', `:post-blank' and +`:post-affiliated' keywords. + +Assume point is at export-block beginning." + (let* ((case-fold-search t) + (type (progn (looking-at "[ \t]*#\\+BEGIN_\\(\\S-+\\)") + (upcase (org-match-string-no-properties 1))))) + (if (not (save-excursion + (re-search-forward + (format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t))) + ;; Incomplete block: parse it as a paragraph. + (org-element-paragraph-parser limit affiliated) + (let ((contents-end (match-beginning 0))) + (save-excursion + (let* ((begin (car affiliated)) + (post-affiliated (point)) + (contents-begin (progn (forward-line) (point))) + (pos-before-blank (progn (goto-char contents-end) + (forward-line) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (line-beginning-position)))) + (value (buffer-substring-no-properties contents-begin + contents-end))) + (list 'export-block + (nconc + (list :begin begin + :end end + :type type + :value value + :post-blank (count-lines pos-before-blank end) + :post-affiliated post-affiliated) + (cdr affiliated))))))))) + +(defun org-element-export-block-interpreter (export-block contents) + "Interpret EXPORT-BLOCK element as Org syntax. +CONTENTS is nil." + (let ((type (org-element-property :type export-block))) + (concat (format "#+BEGIN_%s\n" type) + (org-element-property :value export-block) + (format "#+END_%s" type)))) + + ;;;; Fixed-width (defun org-element-fixed-width-parser (limit affiliated) diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el index 60ec4ac14..feef86077 100644 --- a/lisp/ox-ascii.el +++ b/lisp/ox-ascii.el @@ -55,6 +55,7 @@ (dynamic-block . org-ascii-dynamic-block) (entity . org-ascii-entity) (example-block . org-ascii-example-block) + (export-block . org-ascii-export-block) (export-snippet . org-ascii-export-snippet) (fixed-width . org-ascii-fixed-width) (footnote-reference . org-ascii-footnote-reference) @@ -1197,6 +1198,16 @@ CONTENTS is nil. INFO is a plist holding contextual information." (org-element-property :value export-snippet))) +;;;; Export Block + +(defun org-ascii-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to ASCII. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (string= (org-element-property :type export-block) "ASCII") + (org-ascii--justify-element + (org-element-property :value export-block) export-block info))) + + ;;;; Fixed Width (defun org-ascii-fixed-width (fixed-width contents info) @@ -1654,13 +1665,10 @@ contextual information." "Transcode a SPECIAL-BLOCK element from Org to ASCII. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (if (org-export-raw-special-block-p special-block info) - (org-ascii--justify-element - (org-element-property :raw-value special-block) special-block info) - ;; "JUSTIFYLEFT" and "JUSTFYRIGHT" have already been taken care of - ;; at a lower level. There is no other special block type to - ;; handle. - contents)) + ;; "JUSTIFYLEFT" and "JUSTFYRIGHT" have already been taken care of + ;; at a lower level. There is no other special block type to + ;; handle. + contents) ;;;; Src Block diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el index 768e5bb1f..f2c001230 100644 --- a/lisp/ox-beamer.el +++ b/lisp/ox-beamer.el @@ -245,6 +245,7 @@ Return overlay specification, as a string, or nil." (:beamer-outline-frame-options nil nil org-beamer-outline-frame-options) (:beamer-outline-frame-title nil nil org-beamer-outline-frame-title)) :translate-alist '((bold . org-beamer-bold) + (export-block . org-beamer-export-block) (export-snippet . org-beamer-export-snippet) (headline . org-beamer-headline) (item . org-beamer-item) @@ -270,6 +271,16 @@ a communication channel." contents)) +;;;; Export Block + +(defun org-beamer-export-block (export-block contents info) + "Transcode an EXPORT-BLOCK element into Beamer code. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (when (member (org-element-property :type export-block) '("BEAMER" "LATEX")) + (org-remove-indentation (org-element-property :value export-block)))) + + ;;;; Export Snippet (defun org-beamer-export-snippet (export-snippet contents info) diff --git a/lisp/ox-html.el b/lisp/ox-html.el index 9e642055b..132c34f13 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -55,6 +55,7 @@ (dynamic-block . org-html-dynamic-block) (entity . org-html-entity) (example-block . org-html-example-block) + (export-block . org-html-export-block) (export-snippet . org-html-export-snippet) (fixed-width . org-html-fixed-width) (footnote-definition . org-html-footnote-definition) @@ -2271,6 +2272,14 @@ information." (when (eq (org-export-snippet-backend export-snippet) 'html) (org-element-property :value export-snippet))) +;;;; Export Block + +(defun org-html-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (string= (org-element-property :type export-block) "HTML") + (org-remove-indentation (org-element-property :value export-block)))) + ;;;; Fixed Width (defun org-html-fixed-width (fixed-width contents info) @@ -3090,25 +3099,25 @@ contextual information." "Transcode a SPECIAL-BLOCK element from Org to HTML. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (if (org-export-raw-special-block-p special-block info) - (org-remove-indentation (org-element-property :raw-value special-block)) - (let* ((block-type (downcase (org-element-property :type special-block))) - (contents (or contents "")) - (html5-fancy (and (org-html-html5-p info) - (plist-get info :html-html5-fancy) - (member block-type org-html-html5-elements))) - (attributes (org-export-read-attribute :attr_html special-block))) - (unless html5-fancy - (let ((class (plist-get attributes :class))) - (setq attributes (plist-put attributes :class - (if class (concat class " " block-type) - block-type))))) - (setq attributes (org-html--make-attribute-string attributes)) - (when (not (equal attributes "")) - (setq attributes (concat " " attributes))) - (if html5-fancy - (format "<%s%s>\n%s" block-type attributes contents block-type) - (format "\n%s\n" attributes contents))))) + (let* ((block-type (downcase + (org-element-property :type special-block))) + (contents (or contents "")) + (html5-fancy (and (org-html-html5-p info) + (plist-get info :html-html5-fancy) + (member block-type org-html-html5-elements))) + (attributes (org-export-read-attribute :attr_html special-block))) + (unless html5-fancy + (let ((class (plist-get attributes :class))) + (setq attributes (plist-put attributes :class + (if class (concat class " " block-type) + block-type))))) + (setq attributes (org-html--make-attribute-string attributes)) + (when (not (equal attributes "")) + (setq attributes (concat " " attributes))) + (if html5-fancy + (format "<%s%s>\n%s" block-type attributes + contents block-type) + (format "\n%s\n" attributes contents)))) ;;;; Src Block diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 478d5d405..b3f8f2c12 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -49,6 +49,7 @@ (dynamic-block . org-latex-dynamic-block) (entity . org-latex-entity) (example-block . org-latex-example-block) + (export-block . org-latex-export-block) (export-snippet . org-latex-export-snippet) (fixed-width . org-latex-fixed-width) (footnote-definition . org-latex-footnote-definition) @@ -1355,6 +1356,15 @@ information." (org-export-format-code-default example-block info))))) +;;;; Export Block + +(defun org-latex-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to LaTeX. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (member (org-element-property :type export-block) '("LATEX" "TEX")) + (org-remove-indentation (org-element-property :value export-block)))) + + ;;;; Export Snippet (defun org-latex-export-snippet (export-snippet contents info) @@ -2232,17 +2242,15 @@ holding contextual information." "Transcode a SPECIAL-BLOCK element from Org to LaTeX. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (if (org-export-raw-special-block-p special-block info) - (org-remove-indentation (org-element-property :raw-value special-block)) - (let ((type (downcase (org-element-property :type special-block))) - (opt (org-export-read-attribute :attr_latex special-block :options))) - (concat (format "\\begin{%s}%s\n" type (or opt "")) - ;; Insert any label or caption within the block - ;; (otherwise, a reference pointing to that element will - ;; count the section instead). - (org-latex--caption/label-string special-block info) - contents - (format "\\end{%s}" type))))) + (let ((type (downcase (org-element-property :type special-block))) + (opt (org-export-read-attribute :attr_latex special-block :options))) + (concat (format "\\begin{%s}%s\n" type (or opt "")) + ;; Insert any label or caption within the block + ;; (otherwise, a reference pointing to that element will + ;; count the section instead). + (org-latex--caption/label-string special-block info) + contents + (format "\\end{%s}" type)))) ;;;; Src Block diff --git a/lisp/ox-man.el b/lisp/ox-man.el index 4b27ab6c3..c8c999857 100644 --- a/lisp/ox-man.el +++ b/lisp/ox-man.el @@ -61,6 +61,7 @@ (dynamic-block . org-man-dynamic-block) (entity . org-man-entity) (example-block . org-man-example-block) + (export-block . org-man-export-block) (export-snippet . org-man-export-snippet) (fixed-width . org-man-fixed-width) (footnote-definition . org-man-footnote-definition) @@ -431,6 +432,15 @@ information." (org-export-format-code-default example-block info)))) +;;; Export Block + +(defun org-man-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to Man. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (string= (org-element-property :type export-block) "MAN") + (org-remove-indentation (org-element-property :value export-block)))) + + ;;; Export Snippet (defun org-man-export-snippet (export-snippet contents info) @@ -765,10 +775,10 @@ holding contextual information." "Transcode a SPECIAL-BLOCK element from Org to Man. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (if (org-export-raw-special-block-p special-block info) - (org-remove-indentation (org-element-property :raw-value special-block)) - (let ((type (downcase (org-element-property :type special-block)))) - (org-man--wrap-label special-block (format "%s\n" contents))))) + (let ((type (downcase (org-element-property :type special-block)))) + (org-man--wrap-label + special-block + (format "%s\n" contents)))) ;;; Src Block diff --git a/lisp/ox-md.el b/lisp/ox-md.el index 1a891dc01..695fb6106 100644 --- a/lisp/ox-md.el +++ b/lisp/ox-md.el @@ -71,6 +71,7 @@ This variable can be set to either `atx' or `setext'." (comment . (lambda (&rest args) "")) (comment-block . (lambda (&rest args) "")) (example-block . org-md-example-block) + (export-block . org-md-export-block) (fixed-width . org-md-example-block) (footnote-definition . ignore) (footnote-reference . ignore) @@ -157,7 +158,7 @@ channel." value))) -;;;; Example Block and Src Block +;;;; Example Block, Src Block and export Block (defun org-md-example-block (example-block contents info) "Transcode EXAMPLE-BLOCK element into Markdown format. @@ -168,6 +169,14 @@ channel." (org-remove-indentation (org-export-format-code-default example-block info)))) +(defun org-md-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to Markdown. +CONTENTS is nil. INFO is a plist holding contextual information." + (if (member (org-element-property :type export-block) '("MARKDOWN" "MD")) + (org-remove-indentation (org-element-property :value export-block)) + ;; Also include HTML export blocks. + (org-export-with-backend 'html export-block contents info))) + ;;;; Headline diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 26ed8725d..205712ace 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -43,6 +43,7 @@ (dynamic-block . org-odt-dynamic-block) (entity . org-odt-entity) (example-block . org-odt-example-block) + (export-block . org-odt-export-block) (export-snippet . org-odt-export-snippet) (fixed-width . org-odt-fixed-width) (footnote-definition . org-odt-footnote-definition) @@ -1676,6 +1677,15 @@ CONTENTS is nil. INFO is a plist holding contextual information." (org-element-property :value export-snippet))) +;;;; Export Block + +(defun org-odt-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to ODT. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (string= (org-element-property :type export-block) "ODT") + (org-remove-indentation (org-element-property :value export-block)))) + + ;;;; Fixed Width (defun org-odt-fixed-width (fixed-width contents info) @@ -3049,40 +3059,37 @@ contextual information." "Transcode a SPECIAL-BLOCK element from Org to ODT. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (if (org-export-raw-special-block-p special-block info) - (org-remove-indentation (org-element-property :raw-value special-block)) - (let ((type (downcase (org-element-property :type special-block))) - (attributes (org-export-read-attribute :attr_odt special-block))) - (cond - ;; Annotation. - ((string= type "annotation") - (let* ((author (or (plist-get attributes :author) - (let ((author (plist-get info :author))) - (and author (org-export-data author info))))) - (date (or (plist-get attributes :date) - ;; FIXME: Is `car' right thing to do below? - (car (plist-get info :date))))) - (format "\n%s" - (format "\n%s\n" - (concat - (and author - (format "%s" author)) - (and date - (format "%s" - (org-odt--format-timestamp - date nil 'iso-date))) - contents))))) - ;; Textbox. - ((string= type "textbox") - (let ((width (plist-get attributes :width)) - (height (plist-get attributes :height)) - (style (plist-get attributes :style)) - (extra (plist-get attributes :extra)) - (anchor (plist-get attributes :anchor))) - (format "\n%s" - "Text_20_body" (org-odt--textbox contents width height + (let ((type (downcase (org-element-property :type special-block))) + (attributes (org-export-read-attribute :attr_odt special-block))) + (cond + ;; Annotation. + ((string= type "annotation") + (let* ((author (or (plist-get attributes :author) + (let ((author (plist-get info :author))) + (and author (org-export-data author info))))) + (date (or (plist-get attributes :date) + ;; FIXME: Is `car' right thing to do below? + (car (plist-get info :date))))) + (format "\n%s" + (format "\n%s\n" + (concat + (and author + (format "%s" author)) + (and date + (format "%s" + (org-odt--format-timestamp date nil 'iso-date))) + contents))))) + ;; Textbox. + ((string= type "textbox") + (let ((width (plist-get attributes :width)) + (height (plist-get attributes :height)) + (style (plist-get attributes :style)) + (extra (plist-get attributes :extra)) + (anchor (plist-get attributes :anchor))) + (format "\n%s" + "Text_20_body" (org-odt--textbox contents width height style extra anchor)))) - (t contents))))) + (t contents)))) ;;;; Src Block diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el index 5927b3a04..fa0298816 100644 --- a/lisp/ox-texinfo.el +++ b/lisp/ox-texinfo.el @@ -45,6 +45,7 @@ (dynamic-block . org-texinfo-dynamic-block) (entity . org-texinfo-entity) (example-block . org-texinfo-example-block) + (export-block . org-texinfo-export-block) (export-snippet . org-texinfo-export-snippet) (fixed-width . org-texinfo-fixed-width) (footnote-definition . org-texinfo-footnote-definition) @@ -694,7 +695,15 @@ information." (format "@verbatim\n%s@end verbatim" (org-export-format-code-default example-block info))) -;;;; Export Snippet +;;; Export Block + +(defun org-texinfo-export-block (export-block contents info) + "Transcode a EXPORT-BLOCK element from Org to Texinfo. +CONTENTS is nil. INFO is a plist holding contextual information." + (when (string= (org-element-property :type export-block) "TEXINFO") + (org-remove-indentation (org-element-property :value export-block)))) + +;;; Export Snippet (defun org-texinfo-export-snippet (export-snippet contents info) "Transcode a EXPORT-SNIPPET object from Org to Texinfo. @@ -1226,9 +1235,7 @@ holding contextual information." "Transcode a SPECIAL-BLOCK element from Org to Texinfo. CONTENTS holds the contents of the block. INFO is a plist used as a communication channel." - (if (org-export-raw-special-block-p special-block info) - (org-remove-indentation (org-element-property :raw-value special-block)) - contents)) + contents) ;;;; Src Block diff --git a/lisp/ox.el b/lisp/ox.el index 235b0abac..050b05437 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -189,6 +189,7 @@ way they are handled must be hard-coded into (:filter-dynamic-block . org-export-filter-dynamic-block-functions) (:filter-entity . org-export-filter-entity-functions) (:filter-example-block . org-export-filter-example-block-functions) + (:filter-export-block . org-export-filter-export-block-functions) (:filter-export-snippet . org-export-filter-export-snippet-functions) (:filter-final-output . org-export-filter-final-output-functions) (:filter-fixed-width . org-export-filter-fixed-width-functions) @@ -935,6 +936,10 @@ BACKEND is a structure with `org-export-backend' type." (let ((parent (org-export-backend-parent backend))) (when (and parent (not (org-export-get-backend parent))) (error "Cannot use unknown \"%s\" back-end as a parent" parent))) + ;; Register dedicated export blocks in the parser. + (dolist (name (org-export-backend-blocks backend)) + (add-to-list 'org-element-block-name-alist + (cons name 'org-element-export-block-parser))) ;; If a back-end with the same name as BACKEND is already ;; registered, replace it with BACKEND. Otherwise, simply add ;; BACKEND to the list of registered back-ends. @@ -1066,7 +1071,7 @@ keywords are understood: String, or list of strings, representing block names that will not be parsed. This is used to specify blocks that will contain raw code specific to the back-end. These blocks - still have to be handled by the `special-block' type + still have to be handled by the relative `export-block' type translator. :filters-alist @@ -1171,7 +1176,7 @@ keywords are understood: String, or list of strings, representing block names that will not be parsed. This is used to specify blocks that will contain raw code specific to the back-end. These blocks - still have to be handled by the `special-block' type + still have to be handled by the relative `export-block' type translator. :filters-alist @@ -2596,6 +2601,12 @@ Each filter is called with three arguments: the transcoded data, as a string, the back-end, as a symbol, and the communication channel, as a plist. It must return a string or nil.") +(defvar org-export-filter-export-block-functions nil + "List of functions applied to a transcoded export-block. +Each filter is called with three arguments: the transcoded data, +as a string, the back-end, as a symbol, and the communication +channel, as a plist. It must return a string or nil.") + (defvar org-export-filter-fixed-width-functions nil "List of functions applied to a transcoded fixed-width. Each filter is called with three arguments: the transcoded data, diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index 9b1ca7711..f463b051c 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -777,6 +777,39 @@ Some other text (org-element-property :label-fmt (org-element-at-point))))))) +;;;; Export Block + +(ert-deftest test-org-element/export-block-parser () + "Test `export-block' parser." + ;; Standard test. + (should + (org-test-with-temp-text "#+BEGIN_LATEX\nText\n#+END_LATEX" + (org-element-map + (let ((org-element-block-name-alist + '(("LATEX" . org-element-export-block-parser)))) + (org-element-parse-buffer)) + 'export-block 'identity))) + ;; Ignore case. + (should + (let ((org-element-block-name-alist + '(("LATEX" . org-element-export-block-parser)))) + (org-test-with-temp-text "#+begin_latex\nText\n#+end_latex" + (org-element-map (org-element-parse-buffer) 'export-block 'identity)))) + ;; Ignore incomplete block. + (should-not + (let ((org-element-block-name-alist + '(("LATEX" . org-element-export-block-parser)))) + (org-test-with-temp-text "#+BEGIN_LATEX" + (org-element-map (org-element-parse-buffer) 'export-block + 'identity nil t)))) + ;; Handle non-empty blank line at the end of buffer. + (should + (let ((org-element-block-name-alist + '(("LATEX" . org-element-export-block-parser)))) + (org-test-with-temp-text "#+BEGIN_LATEX\nC\n#+END_LATEX\n " + (= (org-element-property :end (org-element-at-point)) (point-max)))))) + + ;;;; Export Snippet (ert-deftest test-org-element/export-snippet-parser () @@ -2443,6 +2476,12 @@ CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01")))) "#+BEGIN_EXAMPLE\nTest\n#+END_EXAMPLE\n" (org-element-interpret-data '(example-block (:value "Test")))))) +(ert-deftest test-org-element/export-block-interpreter () + "Test export block interpreter." + (should (equal (org-test-parse-and-interpret + "#+BEGIN_HTML\nTest\n#+END_HTML") + "#+BEGIN_HTML\nTest\n#+END_HTML\n"))) + (ert-deftest test-org-element/fixed-width-interpreter () "Test fixed width interpreter." ;; Standard test. diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 1e92afe5c..9cb5bb06c 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -1126,7 +1126,15 @@ Footnotes[fn:1], [fn:test] and [fn:inline:anonymous footnote]. (org-export-define-backend 'test '((headline . my-headline-test)) :menu-entry '(?k "Test Export" test)) - (org-export-backend-menu (org-export-get-backend 'test)))))) + (org-export-backend-menu (org-export-get-backend 'test))))) + ;; Export Blocks. + (should + (equal '(("TEST" . org-element-export-block-parser)) + (let (org-export--registered-backends org-element-block-name-alist) + (org-export-define-backend 'test + '((headline . my-headline-test)) + :export-block '("test")) + org-element-block-name-alist)))) (ert-deftest test-org-export/define-derived-backend () "Test `org-export-define-derived-backend' specifications." -- 2.11.4.GIT