Prechádzať zdrojové kódy

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 12 rokov pred
rodič
commit
1f8c8dc6d6
3 zmenil súbory, kde vykonal 87 pridanie a 28 odobranie
  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)
    (inline-src-block . org-html-inline-src-block)
    (inlinetask . org-html-inlinetask)
+   (inner-template . org-html-inner-template)
    (italic . org-html-italic)
    (item . org-html-item)
    (keyword . org-html-keyword)
@@ -1369,6 +1370,26 @@ INFO is a plist used as a communication channel."
 	   (org-element-normalize-string postamble-contents)
 	   "</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)
   "Return complete document string after HTML conversion.
 CONTENTS is the transcoded contents string.  INFO is a plist
@@ -1405,22 +1426,8 @@ holding export options."
 	       (or link-home link-up))))
    ;; Preamble.
    (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.
    contents
-   ;; Footnotes section.
-   (org-html-footnote-section info)
-   ;; Bibliography.
-   (org-html-bibliography)
-   ;; End content.
-   "\n</div>"
    ;; Postamble.
    (org-html--build-postamble info)
    ;; 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.
 
 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
 to add a preamble and a postamble to document's body.  It must
 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
 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
 ;;      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
 ;;   - 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
 ;;    `latex-fragment' objects should appear in export output.  When
 ;;    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
 ;;      planning info.
@@ -2848,18 +2851,23 @@ Return code as a string."
 	       (org-combine-plists
 		info (org-export-collect-tree-properties tree info)))
 	 ;; 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
-	   ;; 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-export-filter-apply-functions
 	     (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))))))))
 
 ;;;###autoload

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

@@ -2092,6 +2092,50 @@ Another text. (ref:text)
       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