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.
This commit is contained in:
Nicolas Goaziou 2013-02-11 22:19:23 +01:00
parent cc683398d8
commit 1f8c8dc6d6
3 changed files with 87 additions and 28 deletions

View File

@ -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.

View File

@ -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

View File

@ -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