From e3369c07f01f6c604c9a835fe7ea6e27b017ce5f Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 8 Sep 2014 11:57:27 +0200 Subject: [PATCH 1/3] 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." From d4281e5f3fe3b738e66d794e934d97f1337aedd9 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 8 Sep 2014 12:01:35 +0200 Subject: [PATCH 2/3] Revert "ORG-NEWS: Document `export-block' type removal" This reverts commit 98b719fb597a9fd03febffe1779115510ef61399. Conflicts: etc/ORG-NEWS --- etc/ORG-NEWS | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index a17979895..0bae014d3 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -13,43 +13,6 @@ Please send Org bug reports to emacs-orgmode@gnu.org. *** No default title is provided when =TITLE= keyword is missing Skipping =TITLE= keyword no longer provides the current file name, or buffer name, as the title. Instead, simply ignore the title. -*** Remove ~export-block~ element type -For export back-end developers. - -So called "Export blocks" are now raw "Special blocks". As -a consequence ~export-block~ type doesn't exist anymore in parser, and -should not have a translator associated in an export back-end. - -In order to tell the difference between a special block and a former -export block, a new predicate, ~org-export-raw-special-block-p~ is -implemented. - -To put it simply, two steps may be needed to update a back-end -defining export blocks. - -1. Remove any ~org-BACKEND-export-block~ function, associated filter - and remove ~export-block~ entry from back-end definition. This - step can be omitted if you want to preserve backward-compatibility - with Org 8.2. In this case, the function and filter will be used - in Org 8.2 but ignored in Org 8.3. - -2. If there is a translator for special blocks, e.g., - ~org-BACKEND-special-block~, first check if the current block is an - export block using the predicate and, if that is true, simply - insert raw value, obtained through block's ~:raw-value~ - property. E.g., - - #+BEGIN_SRC emacs-lisp - (defun org-latex-special-block (special-block contents info) - (if (org-export-raw-special-block-p special-block info) - (org-element-property :raw-value special-block) - ;; Usual handling for special blocks goes here. - )) - #+END_SRC - - Note that If BACKEND is a derived back-end and doesn't implement - its own special block translator already, there is nothing to - change. The parent back-end will take care of such blocks. *** Signature changes The following functions require an additional argument. See their docstring for more information. From 7c48bdd7a803ae11970e367bfbf49dcf1ab2314e Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 8 Sep 2014 12:09:52 +0200 Subject: [PATCH 3/3] Revert "ox: Implement predicate for export blocks" This reverts commit 2160b3d2422fb877fbcc6283ae561a9c59b5621a. --- lisp/ox.el | 23 +-------------- testing/lisp/test-ox.el | 62 ----------------------------------------- 2 files changed, 1 insertion(+), 84 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index 21cf8fbb5..9ed84289c 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4138,29 +4138,8 @@ objects of the same type." ((funcall predicate el info) (incf counter) nil))) info 'first-match))))) -;;;; For Special Blocks -;; -;; `org-export-raw-special-block-p' check if current special block is -;; an "export block", i.e., a block whose contents should be inserted -;; as-is in the output. This should generally be the first check to -;; do when handling special blocks in the export back-end. -(defun org-export-raw-special-block-p (element info &optional no-inheritance) - "Non-nil if ELEMENT is an export block relatively to current back-end. -An export block is a special block whose contents should be -included as-is in the final output. Such blocks are defined -through :export-block property in `org-export-define-backend', -which see." - (and (eq (org-element-type element) 'special-block) - (let ((type (org-element-property :type element)) - (b (plist-get info :back-end))) - (if no-inheritance (member type (org-export-backend-blocks b)) - (while (and b (not (member type (org-export-backend-blocks b)))) - (setq b (org-export-get-backend (org-export-backend-parent b)))) - b)))) - - -;;;; For Src Blocks +;;;; For Src-Blocks ;; ;; `org-export-get-loc' counts number of code lines accumulated in ;; src-block or example-block elements with a "+n" switch until diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 42e1bbe71..759e7a1e0 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -1889,68 +1889,6 @@ Another text. (ref:text) (lambda (link) (org-export-resolve-radio-link link info)) info t))))) - -;;; Special blocks - -(ert-deftest test-org-export/raw-special-block-p () - "Test `org-export-raw-special-block-p' specifications." - ;; Standard test. - (should - (org-test-with-parsed-data "#+BEGIN_FOO\nContents\n#+END_FOO" - (let ((info (org-combine-plists - info (list :back-end - (org-export-create-backend :blocks '("FOO")))))) - (org-export-raw-special-block-p - (org-element-map tree 'special-block #'identity info t) info)))) - (should-not - (org-test-with-parsed-data "#+BEGIN_BAR\nContents\n#+END_BAR" - (let ((info (org-combine-plists - info (list :back-end - (org-export-create-backend :blocks '("FOO")))))) - (org-export-raw-special-block-p - (org-element-map tree 'special-block #'identity info t) info)))) - ;; Check is not case-sensitive. - (should - (org-test-with-parsed-data "#+begin_foo\nContents\n#+end_foo" - (let ((info (org-combine-plists - info (list :back-end - (org-export-create-backend :blocks '("FOO")))))) - (org-export-raw-special-block-p - (org-element-map tree 'special-block #'identity info t) info)))) - ;; Test inheritance. - (should - (org-test-with-parsed-data "#+BEGIN_FOO\nContents\n#+END_FOO" - (let* ((org-export--registered-backends - (list (org-export-create-backend :name 'b1 :blocks '("FOO")))) - (info (org-combine-plists - info (list :back-end - (org-export-create-backend :parent 'b1 - :blocks '("BAR")))))) - (org-export-raw-special-block-p - (org-element-map tree 'special-block #'identity info t) info)))) - (should-not - (org-test-with-parsed-data "#+BEGIN_BAZ\nContents\n#+END_BAZ" - (let* ((org-export--registered-backends - (list (org-export-create-backend :name 'b1 :blocks '("FOO")))) - (info (org-combine-plists - info (list :back-end - (org-export-create-backend :parent 'b1 - :blocks '("BAR")))))) - (org-export-raw-special-block-p - (org-element-map tree 'special-block #'identity info t) info)))) - ;; With optional argument, ignore inheritance. - (should-not - (org-test-with-parsed-data "#+BEGIN_FOO\nContents\n#+END_FOO" - (let* ((org-export--registered-backends - (list (org-export-create-backend :name 'b1 :blocks '("FOO")))) - (info (org-combine-plists - info (list :back-end - (org-export-create-backend :parent 'b1 - :blocks '("BAR")))))) - (org-export-raw-special-block-p - (org-element-map tree 'special-block #'identity info t) info t))))) - - ;;; Src-block and example-block