Selaa lähdekoodia

ox: Implement `inner-template' transcoder

* lisp/ox.el (org-export-as): Call `inner-template' function, if
  available.
* lisp/ox-html.el (org-html-inner-template): New function.
(org-html-template): Move all parts that should be inserted even in
a body-only export into `org-html-inner-template'.
* testing/lisp/test-ox.el: Add tests.
Nicolas Goaziou 13 vuotta sitten
vanhempi
commit
1f8c8dc6d6
3 muutettua tiedostoa jossa 87 lisäystä ja 28 poistoa
  1. 21 14
      lisp/ox-html.el
  2. 22 14
      lisp/ox.el
  3. 44 0
      testing/lisp/test-ox.el

+ 21 - 14
lisp/ox-html.el

@@ -68,6 +68,7 @@
    (horizontal-rule . org-html-horizontal-rule)
    (horizontal-rule . org-html-horizontal-rule)
    (inline-src-block . org-html-inline-src-block)
    (inline-src-block . org-html-inline-src-block)
    (inlinetask . org-html-inlinetask)
    (inlinetask . org-html-inlinetask)
+   (inner-template . org-html-inner-template)
    (italic . org-html-italic)
    (italic . org-html-italic)
    (item . org-html-item)
    (item . org-html-item)
    (keyword . org-html-keyword)
    (keyword . org-html-keyword)
@@ -1369,6 +1370,26 @@ INFO is a plist used as a communication channel."
 	   (org-element-normalize-string postamble-contents)
 	   (org-element-normalize-string postamble-contents)
 	   "</div>\n"))))))
 	   "</div>\n"))))))
 
 
+(defun org-html-inner-template (contents info)
+  "Return body of document string after HTML conversion.
+CONTENTS is the transcoded contents string.  INFO is a plist
+holding export options."
+  (concat
+   (format "<div id=\"%s\">\n" (nth 1 org-html-divs))
+   ;; Document title.
+   (format "<h1 class=\"title\">%s</h1>\n"
+	   (org-export-data (plist-get info :title) info))
+   ;; Table of contents.
+   (let ((depth (plist-get info :with-toc)))
+     (when depth (org-html-toc depth info)))
+   ;; Document contents.
+   contents
+   ;; Footnotes section.
+   (org-html-footnote-section info)
+   ;; Bibliography.
+   (org-html-bibliography)
+   "\n</div>"))
+
 (defun org-html-template (contents info)
 (defun org-html-template (contents info)
   "Return complete document string after HTML conversion.
   "Return complete document string after HTML conversion.
 CONTENTS is the transcoded contents string.  INFO is a plist
 CONTENTS is the transcoded contents string.  INFO is a plist
@@ -1405,22 +1426,8 @@ holding export options."
 	       (or link-home link-up))))
 	       (or link-home link-up))))
    ;; Preamble.
    ;; Preamble.
    (org-html--build-preamble info)
    (org-html--build-preamble info)
-   ;; Begin content.
-   (format "<div id=\"%s\">\n" (nth 1 org-html-divs))
-   ;; Document title.
-   (format "<h1 class=\"title\">%s</h1>\n"
-	   (org-export-data (plist-get info :title) info))
-   ;; Table of contents.
-   (let ((depth (plist-get info :with-toc)))
-     (when depth (org-html-toc depth info)))
    ;; Document contents.
    ;; Document contents.
    contents
    contents
-   ;; Footnotes section.
-   (org-html-footnote-section info)
-   ;; Bibliography.
-   (org-html-bibliography)
-   ;; End content.
-   "\n</div>"
    ;; Postamble.
    ;; Postamble.
    (org-html--build-postamble info)
    (org-html--build-postamble info)
    ;; Closing document.
    ;; Closing document.

+ 22 - 14
lisp/ox.el

@@ -830,13 +830,15 @@ string, the type will be ignored, but the blank lines or white
 spaces will be kept.
 spaces will be kept.
 
 
 In addition to element and object types, one function can be
 In addition to element and object types, one function can be
-associated to the `template' symbol and another one to the
-`plain-text' symbol.
+associated to the `template' (or `inner-template') symbol and
+another one to the `plain-text' symbol.
 
 
 The former returns the final transcoded string, and can be used
 The former returns the final transcoded string, and can be used
 to add a preamble and a postamble to document's body.  It must
 to add a preamble and a postamble to document's body.  It must
 accept two arguments: the transcoded string and the property list
 accept two arguments: the transcoded string and the property list
-containing export options.
+containing export options.  A function associated to `template'
+will not be applied if export has option \"body-only\".
+A function associated to `inner-template' is always applied.
 
 
 The latter, when defined, is to be called on every text not
 The latter, when defined, is to be called on every text not
 recognized as an element or an object.  It must accept two
 recognized as an element or an object.  It must accept two
@@ -1227,7 +1229,8 @@ The back-end could then be called with, for example:
 ;;
 ;;
 ;; + `:translate-alist' :: Alist between element and object types and
 ;; + `:translate-alist' :: Alist between element and object types and
 ;;      transcoding functions relative to the current back-end.
 ;;      transcoding functions relative to the current back-end.
-;;      Special keys `template' and `plain-text' are also possible.
+;;      Special keys `inner-template', `template' and `plain-text' are
+;;      also possible.
 ;;   - category :: option
 ;;   - category :: option
 ;;   - type :: alist (SYMBOL . FUNCTION)
 ;;   - type :: alist (SYMBOL . FUNCTION)
 ;;
 ;;
@@ -1286,8 +1289,8 @@ The back-end could then be called with, for example:
 ;; + `:with-latex' :: Non-nil means `latex-environment' elements and
 ;; + `:with-latex' :: Non-nil means `latex-environment' elements and
 ;;    `latex-fragment' objects should appear in export output.  When
 ;;    `latex-fragment' objects should appear in export output.  When
 ;;    this property is set to `verbatim', they will be left as-is.
 ;;    this property is set to `verbatim', they will be left as-is.
-;;    - category :: option
-;;    - symbol (`verbatim', nil, t)
+;;   - category :: option
+;;   - type :: symbol (`verbatim', nil, t)
 ;;
 ;;
 ;; + `:with-plannings' :: Non-nil means transcoding should include
 ;; + `:with-plannings' :: Non-nil means transcoding should include
 ;;      planning info.
 ;;      planning info.
@@ -2848,18 +2851,23 @@ Return code as a string."
 	       (org-combine-plists
 	       (org-combine-plists
 		info (org-export-collect-tree-properties tree info)))
 		info (org-export-collect-tree-properties tree info)))
 	 ;; Eventually transcode TREE.  Wrap the resulting string into
 	 ;; Eventually transcode TREE.  Wrap the resulting string into
-	 ;; a template, if needed.  Finally call final-output filter.
-	 (let ((body (org-element-normalize-string
-		      (or (org-export-data tree info) "")))
-	       (template (cdr (assq 'template
-				    (plist-get info :translate-alist)))))
+	 ;; a template.
+	 (let* ((body (org-element-normalize-string
+		       (or (org-export-data tree info) "")))
+		(inner-template (cdr (assq 'inner-template
+					   (plist-get info :translate-alist))))
+		(full-body (if (not (functionp inner-template)) body
+			     (funcall inner-template body info)))
+		(template (cdr (assq 'template
+				     (plist-get info :translate-alist)))))
 	   ;; Remove all text properties since they cannot be
 	   ;; Remove all text properties since they cannot be
-	   ;; retrieved from an external process, and return result.
+	   ;; retrieved from an external process.  Finally call
+	   ;; final-output filter and return result.
 	   (org-no-properties
 	   (org-no-properties
 	    (org-export-filter-apply-functions
 	    (org-export-filter-apply-functions
 	     (plist-get info :filter-final-output)
 	     (plist-get info :filter-final-output)
-	     (if (or (not (functionp template)) body-only) body
-	       (funcall template body info))
+	     (if (or (not (functionp template)) body-only) full-body
+	       (funcall template full-body info))
 	     info))))))))
 	     info))))))))
 
 
 ;;;###autoload
 ;;;###autoload

+ 44 - 0
testing/lisp/test-ox.el

@@ -2092,6 +2092,50 @@ Another text. (ref:text)
       info))))
       info))))
 
 
 
 
+
+;;; Templates
+
+(ert-deftest test-org-export/inner-template ()
+  "Test `inner-template' translator specifications."
+  (should
+   (equal "Success!"
+	  (let (org-export-registered-backends)
+	    (org-export-define-backend test
+	      ((inner-template . (lambda (contents info) "Success!"))
+	       (headline . (lambda (h c i) "Headline"))))
+	    (org-test-with-temp-text "* Headline"
+	      (org-export-as 'test)))))
+  ;; Inner template is applied even in a "body-only" export.
+  (should
+   (equal "Success!"
+	  (let (org-export-registered-backends)
+	    (org-export-define-backend test
+	      ((inner-template . (lambda (contents info) "Success!"))
+	       (headline . (lambda (h c i) "Headline"))))
+	    (org-test-with-temp-text "* Headline"
+	      (org-export-as 'test nil nil 'body-only))))))
+
+(ert-deftest test-org-export/template ()
+  "Test `template' translator specifications."
+  (should
+   (equal "Success!"
+	  (let (org-export-registered-backends)
+	    (org-export-define-backend test
+	      ((template . (lambda (contents info) "Success!"))
+	       (headline . (lambda (h c i) "Headline"))))
+	    (org-test-with-temp-text "* Headline"
+	      (org-export-as 'test)))))
+  ;; Template is not applied in a "body-only" export.
+  (should-not
+   (equal "Success!"
+	  (let (org-export-registered-backends)
+	    (org-export-define-backend test
+	      ((template . (lambda (contents info) "Success!"))
+	       (headline . (lambda (h c i) "Headline"))))
+	    (org-test-with-temp-text "* Headline"
+	      (org-export-as 'test nil nil 'body-only))))))
+
+
 
 
 ;;; Topology
 ;;; Topology