Browse Source

Change export block syntax

* lisp/org-element.el (org-element-export-block-parser):
(org-element--current-element): Use new syntax for export blocks.
(org-element-block-name-alist): Remove.

* lisp/ox.el (org-export-register-backend):
(org-export-define-derived-backend): Remove :export-block keyword from
back-end's definition.
(org-export-expand-include-keyword): Use new syntax for include
keywords.

* lisp/ox-ascii.el (ascii):
* lisp/ox-beamer.el (beamer):
* lisp/ox-html.el (html):
* lisp/ox-latex.el (latex):
(org-latex-prefer-user-labels):
* lisp/ox-man.el (man):
* lisp/ox-md.el (md):
* lisp/ox-odt.el (odt):
* lisp/ox-texinfo.el (texinfo): Propagate changes to "ox.el".

* lisp/ob-core.el (org-babel-insert-result):
* lisp/ob-haskell.el (org-babel-haskell-export-to-lhs): Use new syntax.

* lisp/org.el (org-structure-template-alist): Use new syntax.
(org-protecting-blocks): Add "export" to protected blocks.  Remove
  back-ends blocks, which are now special blocks.
(org-fontify-meta-lines-and-blocks-1): Fontify correctly new blocks.

* lisp/org-footnote.el (org-footnote-forbidden-blocks):
* lisp/org-list.el (org-list-forbidden-blocks): Add "export" to
  forbidden blocks.  Remove back-ends blocks, which are now special
  blocks.

* contrib/lisp/ox-extra.el: Update comments.

* testing/lisp/test-org-element.el (test-org-element/export-block-parser):
(test-org-element/export-block-interpreter):
* testing/lisp/test-ob.el (test-ob/org-babel-remove-result--results-html):
(test-ob/org-babel-remove-result--results-latex):
* testing/lisp/test-ox.el (test-org-export/expand-include): Update tests.

Export blocks are explicitly marked as such at the syntax level to
disambiguate their parsing from special blocks.  The new syntax is

  #+BEGIN_EXPORT backend
  ...
  #+END_EXPORT

instead of

  #+BEGIN_backend
  ...
  #+END_backend

As a consequence, =INCLUDE= keywords syntax is modified, e.g.,

  #+INCLUDE: "file.org" HTML

becomes

  #+INCLUDE: "file.org" export html
Nicolas Goaziou 5 years ago
parent
commit
54318add34

+ 2 - 2
contrib/lisp/ox-extra.el

@@ -37,9 +37,9 @@
 ;; for export.  These blocks should be tagged with #+header: :header
 ;; yes.  For example:
 ;; #+header: :header yes
-;; #+begin_latex
+;; #+begin_export latex
 ;;   ...
-;; #+end_latex
+;; #+end_export
 
 ;; - `ignore-headlines' -- allow a headline (but not its children) to
 ;; be ignored.  Any headline tagged with the 'ignore' tag will be

+ 66 - 0
etc/ORG-NEWS

@@ -9,6 +9,72 @@ See the end of the file for license conditions.
 Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
 
 * Version 9.0
+** Incompatible changes
+*** New syntax for export blocks
+Export blocks are explicetly marked as such at the syntax level to
+disambiguate their parsing from special blocks.  The new syntax is
+
+#+BEGIN_SRC org
+,#+BEGIN_EXPORT backend
+...
+,#+END_EXPORT
+#+END_SRC
+
+instead of
+
+#+BEGIN_SRC org
+,#+BEGIN_backend
+...
+,#+END_backend
+#+END_SRC
+
+As a consequence, =INCLUDE= keywords syntax is modified, e.g.,
+
+#+BEGIN_SRC org
+,#+INCLUDE: "file.org" HTML
+#+END_SRC
+
+becomes
+
+#+BEGIN_SRC org
+,#+INCLUDE: "file.org" export html
+#+END_SRC
+
+
+The following function repairs export blocks and =INCLUDE= keywords
+using previous syntax:
+
+#+BEGIN_SRC emacs-lisp
+(defun org-repair-export-blocks ()
+  "Repair export blocks and INCLUDE keywords in current buffer."
+  (when (eq major-mode 'org-mode)
+    (let ((case-fold-search t)
+          (back-end-re (regexp-opt
+                        '("HTML" "ASCII" "LATEX" "ODT" "MARKDOWN" "MD" "ORG"
+                          "MAN" "BEAMER" "TEXINFO" "GROFF" "KOMA-LETTER")
+                        t)))
+      (org-with-wide-buffer
+       (goto-char (point-min))
+       (let ((block-re (concat "^[ \t]*#\\+BEGIN_" back-end-re)))
+         (save-excursion
+           (while (re-search-forward block-re nil t)
+             (let ((element (save-match-data (org-element-at-point))))
+               (when (eq (org-element-type element) 'special-block)
+                 (save-excursion
+                   (goto-char (org-element-property :end element))
+                   (save-match-data (search-backward "_"))
+                   (forward-char)
+                   (insert "EXPORT")
+                   (delete-region (point) (line-end-position)))
+                 (replace-match "EXPORT \\1" nil nil nil 1))))))
+       (let ((include-re
+              (format "^[ \t]*#\\+INCLUDE: .*?%s[ \t]*$" back-end-re)))
+         (while (re-search-forward include-re nil t)
+           (let ((element (save-match-data (org-element-at-point))))
+             (when (and (eq (org-element-type element) 'keyword)
+                        (string= (org-element-property :key element) "INCLUDE"))
+               (replace-match "EXPORT \\1" nil nil nil 1)))))))))
+#+END_SRC
 
 ** New features
 *** Org linter

+ 9 - 8
lisp/ob-core.el

@@ -2131,15 +2131,16 @@ org ----- results are added inside of a \"src_org{}\" or \"#+BEGIN_SRC
           but Org syntax here will be discarded when exporting the
           file.
 
-html ---- results are added inside of a #+BEGIN_HTML block or
-          html export snippet depending on whether the current
+html ---- results are added inside of a #+BEGIN_EXPORT HTML block
+          or html export snippet depending on whether the current
           source block is inline or not.  This is a good option
           if your code block will output html formatted text.
 
-latex --- results are added inside of a #+BEGIN_LATEX block or
-          latex export snippet depending on whether the current
-          source block is inline or not.  This is a good option
-          if your code block will output latex formatted text.
+latex --- results are added inside of a #+BEGIN_EXPORT LATEX
+          block or latex export snippet depending on whether the
+          current source block is inline or not.  This is a good
+          option if your code block will output latex formatted
+          text.
 
 code ---- the results are extracted in the syntax of the source
           code of the language being evaluated and are added
@@ -2316,10 +2317,10 @@ INFO may provide the values of these header arguments (in the
 			     (concat "#+END_" (car (org-split-string name)))
 			     nil nil (concat "{{{results(@@" name ":") "@@)}}}")))
 		 ((member "html" result-params)
-		  (funcall wrap "#+BEGIN_HTML" "#+END_HTML" nil nil
+		  (funcall wrap "#+BEGIN_EXPORT html" "#+END_EXPORT" nil nil
 			   "{{{results(@@html:" "@@)}}}"))
 		 ((member "latex" result-params)
-		  (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX" nil nil
+		  (funcall wrap "#+BEGIN_EXPORT latex" "#+END_EXPORT" nil nil
 			   "{{{results(@@latex:" "@@)}}}"))
 		 ((member "org" result-params)
 		  (goto-char beg) (if (org-at-table-p) (org-cycle))

+ 2 - 2
lisp/ob-haskell.el

@@ -177,12 +177,12 @@ constructs (header arguments, no-web syntax etc...) are ignored."
         (save-match-data (setq indentation (length (match-string 1))))
         (replace-match (save-match-data
                          (concat
-                          "#+begin_latex\n\\begin{code}\n"
+                          "#+begin_export latex\n\\begin{code}\n"
                           (if (or preserve-indentp
                                   (string-match "-i" (match-string 2)))
                               (match-string 3)
                             (org-remove-indentation (match-string 3)))
-                          "\n\\end{code}\n#+end_latex\n"))
+                          "\n\\end{code}\n#+end_export\n"))
                        t t)
         (indent-code-rigidly (match-beginning 0) (match-end 0) indentation)))
     (save-excursion

+ 60 - 65
lisp/org-element.el

@@ -258,17 +258,6 @@ specially in `org-element--object-lex'.")
   (append org-element-recursive-objects '(paragraph table-row verse-block))
   "List of object or element types that can directly contain objects.")
 
-(defvar org-element-block-name-alist
-  '(("CENTER" . org-element-center-block-parser)
-    ("COMMENT" . org-element-comment-block-parser)
-    ("EXAMPLE" . org-element-example-block-parser)
-    ("QUOTE" . org-element-quote-block-parser)
-    ("SRC" . org-element-src-block-parser)
-    ("VERSE" . org-element-verse-block-parser))
-  "Alist between block names and the associated parsing function.
-Names must be uppercase.  Any block whose name has no association
-is parsed with `org-element-special-block-parser'.")
-
 (defconst org-element-affiliated-keywords
   '("CAPTION" "DATA" "HEADER" "HEADERS" "LABEL" "NAME" "PLOT" "RESNAME" "RESULT"
     "RESULTS" "SOURCE" "SRCNAME" "TBLNAME")
@@ -1600,9 +1589,6 @@ CONTENTS is the contents of the element."
 ;; through the following steps: implement a parser and an interpreter,
 ;; tweak `org-element--current-element' so that it recognizes the new
 ;; type and add that new type to `org-element-all-elements'.
-;;
-;; As a special case, when the newly defined type is a block type,
-;; `org-element-block-name-alist' has to be modified accordingly.
 
 
 ;;;; Babel Call
@@ -1953,42 +1939,43 @@ 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)))))
+  (let* ((case-fold-search t))
     (if (not (save-excursion
-	       (re-search-forward
-		(format "^[ \t]*#\\+END_%s[ \t]*$" type) limit t)))
+	       (re-search-forward "^[ \t]*#\\+END_EXPORT[ \t]*$" 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)))))))))
+      (save-excursion
+	(let* ((contents-end (match-beginning 0))
+	       (backend
+		(progn
+		  (looking-at
+		   "[ \t]*#\\+BEGIN_EXPORT\\(?:[ \t]+\\(\\S-+\\)\\)?[ \t]*$")
+		  (match-string-no-properties 1)))
+	       (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 :type backend
+		       :begin begin
+		       :end end
+		       :value value
+		       :post-blank (count-lines pos-before-blank end)
+		       :post-affiliated post-affiliated)
+		 (cdr affiliated))))))))
 
 (defun org-element-export-block-interpreter (export-block _)
   "Interpret EXPORT-BLOCK element as Org syntax."
-  (let ((type (org-element-property :type export-block)))
-    (concat (format "#+BEGIN_%s\n" type)
-	    (org-element-property :value export-block)
-	    (format "#+END_%s" type))))
+  (format "#+BEGIN_EXPORT %s\n%s#+END_EXPORT"
+	  (org-element-property :type export-block)
+	  (org-element-property :value export-block)))
 
 
 ;;;; Fixed-width
@@ -3763,27 +3750,35 @@ element it has to parse."
 	     ;; Keywords.
 	     ((looking-at "[ \t]*#")
 	      (goto-char (match-end 0))
-	      (cond ((looking-at "\\(?: \\|$\\)")
-		     (beginning-of-line)
-		     (org-element-comment-parser limit affiliated))
-		    ((looking-at "\\+BEGIN_\\(\\S-+\\)")
-		     (beginning-of-line)
-		     (let ((parser (assoc (upcase (match-string 1))
-					  org-element-block-name-alist)))
-		       (if parser (funcall (cdr parser) limit affiliated)
-			 (org-element-special-block-parser limit affiliated))))
-		    ((looking-at "\\+CALL:")
-		     (beginning-of-line)
-		     (org-element-babel-call-parser limit affiliated))
-		    ((looking-at "\\+BEGIN:? ")
-		     (beginning-of-line)
-		     (org-element-dynamic-block-parser limit affiliated))
-		    ((looking-at "\\+\\S-+:")
-		     (beginning-of-line)
-		     (org-element-keyword-parser limit affiliated))
-		    (t
-		     (beginning-of-line)
-		     (org-element-paragraph-parser limit affiliated))))
+	      (cond
+	       ((looking-at "\\(?: \\|$\\)")
+		(beginning-of-line)
+		(org-element-comment-parser limit affiliated))
+	       ((looking-at "\\+BEGIN_\\(\\S-+\\)")
+		(beginning-of-line)
+		(funcall (pcase (upcase (match-string 1))
+			   ("CENTER"  #'org-element-center-block-parser)
+			   ("COMMENT" #'org-element-comment-block-parser)
+			   ("EXAMPLE" #'org-element-example-block-parser)
+			   ("EXPORT"  #'org-element-export-block-parser)
+			   ("QUOTE"   #'org-element-quote-block-parser)
+			   ("SRC"     #'org-element-src-block-parser)
+			   ("VERSE"   #'org-element-verse-block-parser)
+			   (_         #'org-element-special-block-parser))
+			 limit
+			 affiliated))
+	       ((looking-at "\\+CALL:")
+		(beginning-of-line)
+		(org-element-babel-call-parser limit affiliated))
+	       ((looking-at "\\+BEGIN:? ")
+		(beginning-of-line)
+		(org-element-dynamic-block-parser limit affiliated))
+	       ((looking-at "\\+\\S-+:")
+		(beginning-of-line)
+		(org-element-keyword-parser limit affiliated))
+	       (t
+		(beginning-of-line)
+		(org-element-paragraph-parser limit affiliated))))
 	     ;; Footnote Definition.
 	     ((looking-at org-footnote-definition-re)
 	      (org-element-footnote-definition-parser limit affiliated))

+ 1 - 2
lisp/org-footnote.el

@@ -92,8 +92,7 @@
   (org-re "^\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]")
   "Regular expression matching the definition of a footnote.")
 
-(defconst org-footnote-forbidden-blocks
-  '("ascii" "beamer" "comment" "example" "html" "latex" "odt" "src")
+(defconst org-footnote-forbidden-blocks '("comment" "example" "export" "src")
   "Names of blocks where footnotes are not allowed.")
 
 (defgroup org-footnote nil

+ 1 - 2
lisp/org-list.el

@@ -377,8 +377,7 @@ list, obtained by prompting the user."
 	  (list (symbol :tag "Major mode")
 		(string :tag "Format"))))
 
-(defvar org-list-forbidden-blocks '("example" "verse" "src" "ascii" "beamer"
-				    "html" "latex" "odt")
+(defvar org-list-forbidden-blocks '("example" "verse" "src" "export")
   "Names of blocks where lists are not allowed.
 Names must be in lower case.")
 

+ 4 - 5
lisp/org.el

@@ -4383,8 +4383,7 @@ You need to reload Org or to restart Emacs after customizing this."
 	    (plist :tag "Face property list"))
 	   (option (const verbatim)))))
 
-(defvar org-protecting-blocks
-  '("src" "example" "latex" "ascii" "html" "ditaa" "dot" "r" "R")
+(defvar org-protecting-blocks '("src" "example" "export")
   "Blocks that contain text that is quoted, i.e. not processed as Org syntax.
 This is needed for font-lock setup.")
 
@@ -12296,11 +12295,11 @@ keywords relative to each registered export back-end."
     ("v" "#+BEGIN_VERSE\n?\n#+END_VERSE")
     ("V" "#+BEGIN_VERBATIM\n?\n#+END_VERBATIM")
     ("c" "#+BEGIN_CENTER\n?\n#+END_CENTER")
-    ("l" "#+BEGIN_LaTeX\n?\n#+END_LaTeX")
+    ("l" "#+BEGIN_EXPORT latex\n?\n#+END_EXPORT")
     ("L" "#+LaTeX: ")
-    ("h" "#+BEGIN_HTML\n?\n#+END_HTML")
+    ("h" "#+BEGIN_EXPORT html\n?\n#+END_EXPORT")
     ("H" "#+HTML: ")
-    ("a" "#+BEGIN_ASCII\n?\n#+END_ASCII")
+    ("a" "#+BEGIN_EXPORT ascii\n?\n#+END_EXPORT")
     ("A" "#+ASCII: ")
     ("i" "#+INDEX: ?")
     ("I" "#+INCLUDE: %file ?"))

+ 0 - 1
lisp/ox-ascii.el

@@ -93,7 +93,6 @@
     (underline . org-ascii-underline)
     (verbatim . org-ascii-verbatim)
     (verse-block . org-ascii-verse-block))
-  :export-block "ASCII"
   :menu-entry
   '(?t "Export to Plain Text"
        ((?A "As ASCII buffer"

+ 0 - 1
lisp/ox-beamer.el

@@ -232,7 +232,6 @@ Return overlay specification, as a string, or nil."
 ;;; Define Back-End
 
 (org-export-define-derived-backend 'beamer 'latex
-  :export-block "BEAMER"
   :menu-entry
   '(?l 1
        ((?B "As LaTeX buffer (Beamer)" org-beamer-export-as-latex)

+ 0 - 1
lisp/ox-html.el

@@ -102,7 +102,6 @@
     (underline . org-html-underline)
     (verbatim . org-html-verbatim)
     (verse-block . org-html-verse-block))
-  :export-block "HTML"
   :filters-alist '((:filter-options . org-html-infojs-install-script)
 		   (:filter-final-output . org-html-final-function))
   :menu-entry

+ 2 - 3
lisp/ox-latex.el

@@ -90,7 +90,6 @@
     ;; Pseudo objects and elements.
     (latex-math-block . org-latex-math-block)
     (latex-matrices . org-latex-matrices))
-  :export-block '("LATEX" "TEX")
   :menu-entry
   '(?l "Export to LaTeX"
        ((?L "As LaTeX buffer" org-latex-export-as-latex)
@@ -364,9 +363,9 @@ For example, when this variable is non-nil, a headline like this:
      :CUSTOM_ID: sec:foo
      :END:
   This is section [[#sec:foo]].
-  #+BEGIN_LATEX
+  #+BEGIN_EXPORT latex
   And this is still section \\ref{sec:foo}.
-  #+END_LATEX
+  #+END_EXPORT
 
 will be exported to LaTeX as:
 

+ 0 - 1
lisp/ox-man.el

@@ -97,7 +97,6 @@
     (underline . org-man-underline)
     (verbatim . org-man-verbatim)
     (verse-block . org-man-verse-block))
-  :export-block "MAN"
   :menu-entry
   '(?M "Export to MAN"
        ((?m "As MAN file" org-man-export-to-man)

+ 0 - 1
lisp/ox-md.el

@@ -55,7 +55,6 @@ This variable can be set to either `atx' or `setext'."
 ;;; Define Back-End
 
 (org-export-define-derived-backend 'md 'html
-  :export-block '("MD" "MARKDOWN")
   :filters-alist '((:filter-parse-tree . org-md-separate-elements))
   :menu-entry
   '(?m "Export to Markdown"

+ 0 - 1
lisp/ox-odt.el

@@ -83,7 +83,6 @@
     (underline . org-odt-underline)
     (verbatim . org-odt-verbatim)
     (verse-block . org-odt-verse-block))
-  :export-block "ODT"
   :filters-alist '((:filter-parse-tree
 		    . (org-odt--translate-latex-fragments
 		       org-odt--translate-description-lists

+ 0 - 1
lisp/ox-texinfo.el

@@ -78,7 +78,6 @@
     (timestamp . org-texinfo-timestamp)
     (verbatim . org-texinfo-verbatim)
     (verse-block . org-texinfo-verse-block))
-  :export-block "TEXINFO"
   :filters-alist
   '((:filter-headline . org-texinfo--filter-section-blank-lines)
     (:filter-parse-tree . org-texinfo--normalize-headlines)

+ 17 - 46
lisp/ox.el

@@ -1013,10 +1013,6 @@ 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.
@@ -1143,14 +1139,6 @@ back-end.
 BODY can start with pre-defined keyword arguments.  The following
 keywords are understood:
 
-  :export-block
-
-    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 relative `export-block' type
-    translator.
-
   :filters-alist
 
     Alist between filters and function, or list of functions,
@@ -1220,23 +1208,19 @@ keywords are understood:
     `org-export-options-alist' for more information about
     structure of the values."
   (declare (indent 1))
-  (let (blocks filters menu-entry options)
+  (let (filters menu-entry options)
     (while (keywordp (car body))
       (let ((keyword (pop body)))
-	(cl-case keyword
-	  (:export-block (let ((names (pop body)))
-			   (setq blocks (if (consp names) (mapcar 'upcase names)
-					  (list (upcase names))))))
+	(pcase keyword
 	  (:filters-alist (setq filters (pop body)))
 	  (:menu-entry (setq menu-entry (pop body)))
 	  (:options-alist (setq options (pop body)))
-	  (t (error "Unknown keyword: %s" keyword)))))
+	  (_ (error "Unknown keyword: %s" keyword)))))
     (org-export-register-backend
      (org-export-create-backend :name backend
 				:transcoders transcoders
 				:options options
 				:filters filters
-				:blocks blocks
 				:menu menu-entry))))
 
 (defun org-export-define-derived-backend (child parent &rest body)
@@ -1248,14 +1232,6 @@ the parent back-end.
 BODY can start with pre-defined keyword arguments.  The following
 keywords are understood:
 
-  :export-block
-
-    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 relative `export-block' type
-    translator.
-
   :filters-alist
 
     Alist of filters that will overwrite or complete filters
@@ -1292,25 +1268,21 @@ The back-end could then be called with, for example:
 
   (org-export-to-buffer \\='my-latex \"*Test my-latex*\")"
   (declare (indent 2))
-  (let (blocks filters menu-entry options transcoders)
+  (let (filters menu-entry options transcoders)
     (while (keywordp (car body))
       (let ((keyword (pop body)))
-	(cl-case keyword
-	  (:export-block (let ((names (pop body)))
-			   (setq blocks (if (consp names) (mapcar 'upcase names)
-					  (list (upcase names))))))
+	(pcase keyword
 	  (:filters-alist (setq filters (pop body)))
 	  (:menu-entry (setq menu-entry (pop body)))
 	  (:options-alist (setq options (pop body)))
 	  (:translate-alist (setq transcoders (pop body)))
-	  (t (error "Unknown keyword: %s" keyword)))))
+	  (_ (error "Unknown keyword: %s" keyword)))))
     (org-export-register-backend
      (org-export-create-backend :name child
 				:parent parent
 				:transcoders transcoders
 				:options options
 				:filters filters
-				:blocks blocks
 				:menu menu-entry))))
 
 
@@ -3304,10 +3276,12 @@ storing and resolving footnotes.  It is created automatically."
 			value)
 		       (prog1 (match-string 1 value)
 			 (setq value (replace-match "" nil nil value)))))
-		 (env (cond ((string-match "\\<example\\>" value)
-			     'literal)
-			    ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
-			     'literal)))
+		 (env (cond
+		       ((string-match "\\<example\\>" value) 'literal)
+		       ((string-match "\\<export\\(?: +\\(.*\\)\\)?" value)
+			'literal)
+		       ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
+			'literal)))
 		 ;; Minimal level of included file defaults to the child
 		 ;; level of the current headline, if any, or one.  It
 		 ;; only applies is the file is meant to be included as
@@ -3319,12 +3293,11 @@ storing and resolving footnotes.  It is created automatically."
 			     (setq value (replace-match "" nil nil value)))
 			 (get-text-property (point)
 					    :org-include-induced-level))))
-		 (src-args (and (eq env 'literal)
-				(match-string 1 value)))
+		 (args (and (eq env 'literal) (match-string 1 value)))
 		 (block (and (string-match "\\<\\(\\S-+\\)\\>" value)
 			     (match-string 1 value))))
 	    ;; Remove keyword.
-	    (delete-region (point) (progn (forward-line) (point)))
+	    (delete-region (point) (line-beginning-position 2))
 	    (cond
 	     ((not file) nil)
 	     ((not (file-readable-p file))
@@ -3338,10 +3311,8 @@ storing and resolving footnotes.  It is created automatically."
 	      (cond
 	       ((eq env 'literal)
 		(insert
-		 (let ((ind-str (make-string ind ? ))
-		       (arg-str (if (stringp src-args)
-				    (format " %s" src-args)
-				  ""))
+		 (let ((ind-str (make-string ind ?\s))
+		       (arg-str (if (stringp args) (format " %s" args) ""))
 		       (contents
 			(org-escape-code-in-string
 			 (org-export--prepare-file-contents file lines))))
@@ -3349,7 +3320,7 @@ storing and resolving footnotes.  It is created automatically."
 			   ind-str block arg-str contents ind-str block))))
 	       ((stringp block)
 		(insert
-		 (let ((ind-str (make-string ind ? ))
+		 (let ((ind-str (make-string ind ?\s))
 		       (contents
 			(org-export--prepare-file-contents file lines)))
 		   (format "%s#+BEGIN_%s\n%s%s#+END_%s\n"

+ 4 - 4
testing/lisp/test-ob.el

@@ -1036,9 +1036,9 @@ content\"
 (ert-deftest test-ob/org-babel-remove-result--results-html ()
   "Test `org-babel-remove-result' with :results html."
   (test-ob-verify-result-and-removed-result
-   "#+BEGIN_HTML
+   "#+BEGIN_EXPORT html
 <head><body></body></head>
-#+END_HTML"
+#+END_EXPORT"
 
    "* org-babel-remove-result
 #+begin_src emacs-lisp :results html
@@ -1050,11 +1050,11 @@ content\"
 (ert-deftest test-ob/org-babel-remove-result--results-latex ()
   "Test `org-babel-remove-result' with :results latex."
   (test-ob-verify-result-and-removed-result
-   "#+BEGIN_LaTeX
+   "#+BEGIN_EXPORT latex
 Line 1
 Line 2
 Line 3
-#+END_LaTeX"
+#+END_EXPORT"
 
    "* org-babel-remove-result
 #+begin_src emacs-lisp :results latex

+ 17 - 21
testing/lisp/test-org-element.el

@@ -829,31 +829,27 @@ Some other text
   "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)))
+   (eq 'export-block
+       (org-test-with-temp-text "#+BEGIN_EXPORT LATEX\nText\n#+END_EXPORT"
+	 (org-element-type (org-element-at-point)))))
+  (should
+   (equal "LATEX"
+	  (org-test-with-temp-text "#+BEGIN_EXPORT LATEX\nText\n#+END_EXPORT"
+	    (org-element-property :type (org-element-at-point)))))
   ;; 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))))
+   (eq 'export-block
+       (org-test-with-temp-text "#+begin_export latex\nText\n#+end_export"
+	 (org-element-type (org-element-at-point)))))
   ;; 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))))
+   (eq 'export-block
+       (org-test-with-temp-text "#+BEGIN_EXPORT"
+	 (org-element-type (org-element-at-point)))))
   ;; 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))))))
+   (org-test-with-temp-text "#+BEGIN_EXPORT latex\nC\n#+END_EXPORT\n "
+     (= (org-element-property :end (org-element-at-point)) (point-max)))))
 
 
 ;;;; Export Snippet
@@ -2638,8 +2634,8 @@ CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] =>  0:01"))))
 (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")))
+		  "#+BEGIN_EXPORT HTML\nTest\n#+END_EXPORT")
+		 "#+BEGIN_EXPORT HTML\nTest\n#+END_EXPORT\n")))
 
 (ert-deftest test-org-element/fixed-width-interpreter ()
   "Test fixed width interpreter."

+ 3 - 11
testing/lisp/test-ox.el

@@ -1031,10 +1031,10 @@ text
   ;; Inclusion within an html export-block.
   (should
    (equal
-    "#+BEGIN_HTML\n<p>HTML!</p>\n#+END_HTML\n"
+    "#+BEGIN_EXPORT html\n<p>HTML!</p>\n#+END_EXPORT\n"
     (org-test-with-temp-text
 	(format
-	 "#+INCLUDE: \"%s/examples/include.html\" HTML"
+	 "#+INCLUDE: \"%s/examples/include.html\" EXPORT html"
 	 org-test-dir)
       (org-export-expand-include-keyword)
       (buffer-string))))
@@ -1426,15 +1426,7 @@ Footnotes[fn:2], foot[fn:test], digit only[3], 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)))))
-  ;; 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))))
+	    (org-export-backend-menu (org-export-get-backend 'test))))))
 
 (ert-deftest test-org-export/define-derived-backend ()
   "Test `org-export-define-derived-backend' specifications."