Browse Source

Revert "Merge export and special blocks within back-ends"

This reverts commit fbc7097ffa30225ace2b80e9f7466ee387491c44.

Conflicts:
	lisp/ox-texinfo.el
Nicolas Goaziou 10 years ago
parent
commit
e3369c07f0

+ 13 - 4
contrib/lisp/ox-groff.el

@@ -56,6 +56,7 @@
     (dynamic-block . org-groff-dynamic-block)
     (dynamic-block . org-groff-dynamic-block)
     (entity . org-groff-entity)
     (entity . org-groff-entity)
     (example-block . org-groff-example-block)
     (example-block . org-groff-example-block)
+    (export-block . org-groff-export-block)
     (export-snippet . org-groff-export-snippet)
     (export-snippet . org-groff-export-snippet)
     (fixed-width . org-groff-fixed-width)
     (fixed-width . org-groff-fixed-width)
     (footnote-definition . org-groff-footnote-definition)
     (footnote-definition . org-groff-footnote-definition)
@@ -882,6 +883,14 @@ information."
    (format ".DS L\n%s\n.DE"
    (format ".DS L\n%s\n.DE"
            (org-export-format-code-default example-block info))))
            (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
 ;;; Export Snippet
 
 
 (defun org-groff-export-snippet (export-snippet contents info)
 (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.
   "Transcode a SPECIAL-BLOCK element from Org to Groff.
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 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
 ;;; Src Block
 
 

+ 9 - 0
contrib/lisp/ox-koma-letter.el

@@ -518,6 +518,15 @@ are present return the preferred one as determined by
 
 
 ;;; Transcode Functions
 ;;; 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
 ;;;; Export Snippet
 
 
 (defun org-koma-letter-export-snippet (export-snippet contents info)
 (defun org-koma-letter-export-snippet (export-snippet contents info)

+ 67 - 18
lisp/org-element.el

@@ -45,11 +45,11 @@
 ;; and `special-block'.
 ;; and `special-block'.
 ;;
 ;;
 ;; Other element types are: `babel-call', `clock', `comment',
 ;; 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
 ;; Objects are related to document's contents.  Some of them are
 ;; recursive.  Associated types are of the following: `bold', `code',
 ;; 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
 (defconst org-element-all-elements
   '(babel-call center-block clock comment comment-block diary-sexp drawer
   '(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.")
   "Complete list of element types.")
 
 
 (defconst org-element-greater-elements
 (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)
 	 superscript table-cell underline)
   "List of recursive object types.")
   "List of recursive object types.")
 
 
-(defconst org-element-block-name-alist
+(defvar org-element-block-name-alist
   '(("CENTER" . org-element-center-block-parser)
   '(("CENTER" . org-element-center-block-parser)
     ("COMMENT" . org-element-comment-block-parser)
     ("COMMENT" . org-element-comment-block-parser)
     ("EXAMPLE" . org-element-example-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.
 their value.
 
 
 Return a list whose CAR is `special-block' and CDR is a plist
 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."
 Assume point is at the beginning of the block."
   (let* ((case-fold-search t)
   (let* ((case-fold-search t)
@@ -1551,10 +1550,6 @@ Assume point is at the beginning of the block."
 	    (list 'special-block
 	    (list 'special-block
 		  (nconc
 		  (nconc
 		   (list :type type
 		   (list :type type
-			 :raw-value
-			 (and contents-begin
-			      (buffer-substring-no-properties
-			       contents-begin contents-end))
 			 :begin begin
 			 :begin begin
 			 :end end
 			 :end end
 			 :contents-begin contents-begin
 			 :contents-begin contents-begin
@@ -1905,6 +1900,60 @@ CONTENTS is nil."
 	    "#+END_EXAMPLE")))
 	    "#+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
 ;;;; Fixed-width
 
 
 (defun org-element-fixed-width-parser (limit affiliated)
 (defun org-element-fixed-width-parser (limit affiliated)

+ 15 - 7
lisp/ox-ascii.el

@@ -55,6 +55,7 @@
     (dynamic-block . org-ascii-dynamic-block)
     (dynamic-block . org-ascii-dynamic-block)
     (entity . org-ascii-entity)
     (entity . org-ascii-entity)
     (example-block . org-ascii-example-block)
     (example-block . org-ascii-example-block)
+    (export-block . org-ascii-export-block)
     (export-snippet . org-ascii-export-snippet)
     (export-snippet . org-ascii-export-snippet)
     (fixed-width . org-ascii-fixed-width)
     (fixed-width . org-ascii-fixed-width)
     (footnote-reference . org-ascii-footnote-reference)
     (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)))
     (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
 ;;;; Fixed Width
 
 
 (defun org-ascii-fixed-width (fixed-width contents info)
 (defun org-ascii-fixed-width (fixed-width contents info)
@@ -1654,13 +1665,10 @@ contextual information."
   "Transcode a SPECIAL-BLOCK element from Org to ASCII.
   "Transcode a SPECIAL-BLOCK element from Org to ASCII.
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 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
 ;;;; Src Block

+ 11 - 0
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-options nil nil org-beamer-outline-frame-options)
     (:beamer-outline-frame-title nil nil org-beamer-outline-frame-title))
     (:beamer-outline-frame-title nil nil org-beamer-outline-frame-title))
   :translate-alist '((bold . org-beamer-bold)
   :translate-alist '((bold . org-beamer-bold)
+		     (export-block . org-beamer-export-block)
 		     (export-snippet . org-beamer-export-snippet)
 		     (export-snippet . org-beamer-export-snippet)
 		     (headline . org-beamer-headline)
 		     (headline . org-beamer-headline)
 		     (item . org-beamer-item)
 		     (item . org-beamer-item)
@@ -270,6 +271,16 @@ a communication channel."
 	  contents))
 	  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
 ;;;; Export Snippet
 
 
 (defun org-beamer-export-snippet (export-snippet contents info)
 (defun org-beamer-export-snippet (export-snippet contents info)

+ 28 - 19
lisp/ox-html.el

@@ -55,6 +55,7 @@
     (dynamic-block . org-html-dynamic-block)
     (dynamic-block . org-html-dynamic-block)
     (entity . org-html-entity)
     (entity . org-html-entity)
     (example-block . org-html-example-block)
     (example-block . org-html-example-block)
+    (export-block . org-html-export-block)
     (export-snippet . org-html-export-snippet)
     (export-snippet . org-html-export-snippet)
     (fixed-width . org-html-fixed-width)
     (fixed-width . org-html-fixed-width)
     (footnote-definition . org-html-footnote-definition)
     (footnote-definition . org-html-footnote-definition)
@@ -2271,6 +2272,14 @@ information."
   (when (eq (org-export-snippet-backend export-snippet) 'html)
   (when (eq (org-export-snippet-backend export-snippet) 'html)
     (org-element-property :value export-snippet)))
     (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
 ;;;; Fixed Width
 
 
 (defun org-html-fixed-width (fixed-width contents info)
 (defun org-html-fixed-width (fixed-width contents info)
@@ -3090,25 +3099,25 @@ contextual information."
   "Transcode a SPECIAL-BLOCK element from Org to HTML.
   "Transcode a SPECIAL-BLOCK element from Org to HTML.
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 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</%s>" block-type attributes contents block-type)
-	(format "<div%s>\n%s\n</div>" 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</%s>" block-type attributes
+		contents block-type)
+      (format "<div%s>\n%s\n</div>" attributes contents))))
 
 
 ;;;; Src Block
 ;;;; Src Block
 
 

+ 19 - 11
lisp/ox-latex.el

@@ -49,6 +49,7 @@
     (dynamic-block . org-latex-dynamic-block)
     (dynamic-block . org-latex-dynamic-block)
     (entity . org-latex-entity)
     (entity . org-latex-entity)
     (example-block . org-latex-example-block)
     (example-block . org-latex-example-block)
+    (export-block . org-latex-export-block)
     (export-snippet . org-latex-export-snippet)
     (export-snippet . org-latex-export-snippet)
     (fixed-width . org-latex-fixed-width)
     (fixed-width . org-latex-fixed-width)
     (footnote-definition . org-latex-footnote-definition)
     (footnote-definition . org-latex-footnote-definition)
@@ -1355,6 +1356,15 @@ information."
 	     (org-export-format-code-default example-block info)))))
 	     (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
 ;;;; Export Snippet
 
 
 (defun org-latex-export-snippet (export-snippet contents info)
 (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.
   "Transcode a SPECIAL-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 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
 ;;;; Src Block

+ 14 - 4
lisp/ox-man.el

@@ -61,6 +61,7 @@
     (dynamic-block . org-man-dynamic-block)
     (dynamic-block . org-man-dynamic-block)
     (entity . org-man-entity)
     (entity . org-man-entity)
     (example-block . org-man-example-block)
     (example-block . org-man-example-block)
+    (export-block . org-man-export-block)
     (export-snippet . org-man-export-snippet)
     (export-snippet . org-man-export-snippet)
     (fixed-width . org-man-fixed-width)
     (fixed-width . org-man-fixed-width)
     (footnote-definition . org-man-footnote-definition)
     (footnote-definition . org-man-footnote-definition)
@@ -431,6 +432,15 @@ information."
            (org-export-format-code-default example-block info))))
            (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
 ;;; Export Snippet
 
 
 (defun org-man-export-snippet (export-snippet contents info)
 (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.
   "Transcode a SPECIAL-BLOCK element from Org to Man.
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 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
 ;;; Src Block

+ 10 - 1
lisp/ox-md.el

@@ -71,6 +71,7 @@ This variable can be set to either `atx' or `setext'."
 		     (comment . (lambda (&rest args) ""))
 		     (comment . (lambda (&rest args) ""))
 		     (comment-block . (lambda (&rest args) ""))
 		     (comment-block . (lambda (&rest args) ""))
 		     (example-block . org-md-example-block)
 		     (example-block . org-md-example-block)
+		     (export-block . org-md-export-block)
 		     (fixed-width . org-md-example-block)
 		     (fixed-width . org-md-example-block)
 		     (footnote-definition . ignore)
 		     (footnote-definition . ignore)
 		     (footnote-reference . ignore)
 		     (footnote-reference . ignore)
@@ -157,7 +158,7 @@ channel."
 	    value)))
 	    value)))
 
 
 
 
-;;;; Example Block and Src Block
+;;;; Example Block, Src Block and export Block
 
 
 (defun org-md-example-block (example-block contents info)
 (defun org-md-example-block (example-block contents info)
   "Transcode EXAMPLE-BLOCK element into Markdown format.
   "Transcode EXAMPLE-BLOCK element into Markdown format.
@@ -168,6 +169,14 @@ channel."
    (org-remove-indentation
    (org-remove-indentation
     (org-export-format-code-default example-block info))))
     (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
 ;;;; Headline
 
 

+ 40 - 33
lisp/ox-odt.el

@@ -43,6 +43,7 @@
     (dynamic-block . org-odt-dynamic-block)
     (dynamic-block . org-odt-dynamic-block)
     (entity . org-odt-entity)
     (entity . org-odt-entity)
     (example-block . org-odt-example-block)
     (example-block . org-odt-example-block)
+    (export-block . org-odt-export-block)
     (export-snippet . org-odt-export-snippet)
     (export-snippet . org-odt-export-snippet)
     (fixed-width . org-odt-fixed-width)
     (fixed-width . org-odt-fixed-width)
     (footnote-definition . org-odt-footnote-definition)
     (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)))
     (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
 ;;;; Fixed Width
 
 
 (defun org-odt-fixed-width (fixed-width contents info)
 (defun org-odt-fixed-width (fixed-width contents info)
@@ -3049,40 +3059,37 @@ contextual information."
   "Transcode a SPECIAL-BLOCK element from Org to ODT.
   "Transcode a SPECIAL-BLOCK element from Org to ODT.
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 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<text:p>%s</text:p>"
-		  (format "<office:annotation>\n%s\n</office:annotation>"
-			  (concat
-			   (and author
-				(format "<dc:creator>%s</dc:creator>" author))
-			   (and date
-				(format "<dc:date>%s</dc:date>"
-					(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<text:p text:style-name=\"%s\">%s</text:p>"
-		  "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<text:p>%s</text:p>"
+		(format "<office:annotation>\n%s\n</office:annotation>"
+			(concat
+			 (and author
+			      (format "<dc:creator>%s</dc:creator>" author))
+			 (and date
+			      (format "<dc:date>%s</dc:date>"
+				      (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<text:p text:style-name=\"%s\">%s</text:p>"
+		"Text_20_body" (org-odt--textbox contents width height
 						   style extra anchor))))
 						   style extra anchor))))
-       (t contents)))))
+     (t contents))))
 
 
 
 
 ;;;; Src Block
 ;;;; Src Block

+ 11 - 4
lisp/ox-texinfo.el

@@ -45,6 +45,7 @@
     (dynamic-block . org-texinfo-dynamic-block)
     (dynamic-block . org-texinfo-dynamic-block)
     (entity . org-texinfo-entity)
     (entity . org-texinfo-entity)
     (example-block . org-texinfo-example-block)
     (example-block . org-texinfo-example-block)
+    (export-block . org-texinfo-export-block)
     (export-snippet . org-texinfo-export-snippet)
     (export-snippet . org-texinfo-export-snippet)
     (fixed-width . org-texinfo-fixed-width)
     (fixed-width . org-texinfo-fixed-width)
     (footnote-definition . org-texinfo-footnote-definition)
     (footnote-definition . org-texinfo-footnote-definition)
@@ -694,7 +695,15 @@ information."
   (format "@verbatim\n%s@end verbatim"
   (format "@verbatim\n%s@end verbatim"
 	  (org-export-format-code-default example-block info)))
 	  (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)
 (defun org-texinfo-export-snippet (export-snippet contents info)
   "Transcode a EXPORT-SNIPPET object from Org to Texinfo.
   "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.
   "Transcode a SPECIAL-BLOCK element from Org to Texinfo.
 CONTENTS holds the contents of the block.  INFO is a plist used
 CONTENTS holds the contents of the block.  INFO is a plist used
 as a communication channel."
 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
 ;;;; Src Block
 
 

+ 13 - 2
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-dynamic-block . org-export-filter-dynamic-block-functions)
     (:filter-entity . org-export-filter-entity-functions)
     (:filter-entity . org-export-filter-entity-functions)
     (:filter-example-block . org-export-filter-example-block-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-export-snippet . org-export-filter-export-snippet-functions)
     (:filter-final-output . org-export-filter-final-output-functions)
     (:filter-final-output . org-export-filter-final-output-functions)
     (:filter-fixed-width . org-export-filter-fixed-width-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)))
   (let ((parent (org-export-backend-parent backend)))
     (when (and parent (not (org-export-get-backend parent)))
     (when (and parent (not (org-export-get-backend parent)))
       (error "Cannot use unknown \"%s\" back-end as a parent" 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
   ;; If a back-end with the same name as BACKEND is already
   ;; registered, replace it with BACKEND.  Otherwise, simply add
   ;; registered, replace it with BACKEND.  Otherwise, simply add
   ;; BACKEND to the list of registered back-ends.
   ;; BACKEND to the list of registered back-ends.
@@ -1066,7 +1071,7 @@ keywords are understood:
     String, or list of strings, representing block names that
     String, or list of strings, representing block names that
     will not be parsed.  This is used to specify blocks that will
     will not be parsed.  This is used to specify blocks that will
     contain raw code specific to the back-end.  These blocks
     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.
     translator.
 
 
   :filters-alist
   :filters-alist
@@ -1171,7 +1176,7 @@ keywords are understood:
     String, or list of strings, representing block names that
     String, or list of strings, representing block names that
     will not be parsed.  This is used to specify blocks that will
     will not be parsed.  This is used to specify blocks that will
     contain raw code specific to the back-end.  These blocks
     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.
     translator.
 
 
   :filters-alist
   :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
 as a string, the back-end, as a symbol, and the communication
 channel, as a plist.  It must return a string or nil.")
 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
 (defvar org-export-filter-fixed-width-functions nil
   "List of functions applied to a transcoded fixed-width.
   "List of functions applied to a transcoded fixed-width.
 Each filter is called with three arguments: the transcoded data,
 Each filter is called with three arguments: the transcoded data,

+ 39 - 0
testing/lisp/test-org-element.el

@@ -777,6 +777,39 @@ Some other text
 	(org-element-property :label-fmt (org-element-at-point)))))))
 	(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
 ;;;; Export Snippet
 
 
 (ert-deftest test-org-element/export-snippet-parser ()
 (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"
     "#+BEGIN_EXAMPLE\nTest\n#+END_EXAMPLE\n"
     (org-element-interpret-data '(example-block (:value "Test"))))))
     (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 ()
 (ert-deftest test-org-element/fixed-width-interpreter ()
   "Test fixed width interpreter."
   "Test fixed width interpreter."
   ;; Standard test.
   ;; Standard test.

+ 9 - 1
testing/lisp/test-ox.el

@@ -1126,7 +1126,15 @@ Footnotes[fn:1], [fn:test] and [fn:inline:anonymous footnote].
 	    (org-export-define-backend 'test
 	    (org-export-define-backend 'test
 	      '((headline . my-headline-test))
 	      '((headline . my-headline-test))
 	      :menu-entry '(?k "Test Export" 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 ()
 (ert-deftest test-org-export/define-derived-backend ()
   "Test `org-export-define-derived-backend' specifications."
   "Test `org-export-define-derived-backend' specifications."