From 1f8c8dc6d6b0f6c9900be44519c00497f8ed89ff Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Mon, 11 Feb 2013 22:19:23 +0100 Subject: [PATCH] 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. --- lisp/ox-html.el | 35 +++++++++++++++++++++-------------- lisp/ox.el | 36 ++++++++++++++++++++++-------------- testing/lisp/test-ox.el | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 28 deletions(-) diff --git a/lisp/ox-html.el b/lisp/ox-html.el index e1b9cf07b..3f67c5c50 100644 --- a/lisp/ox-html.el +++ b/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) "\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 "
\n" (nth 1 org-html-divs)) + ;; Document title. + (format "

%s

\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
")) + (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 "
\n" (nth 1 org-html-divs)) - ;; Document title. - (format "

%s

\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
" ;; Postamble. (org-html--build-postamble info) ;; Closing document. diff --git a/lisp/ox.el b/lisp/ox.el index d83c11bd6..0b32842e6 100644 --- a/lisp/ox.el +++ b/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 diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index b27ded0dd..c67db4f7c 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -2093,6 +2093,50 @@ Another text. (ref:text) +;;; 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 (ert-deftest test-org-export/get-next-element () -- 2.11.4.GIT