org-export: Run a hook before parsing

* contrib/lisp/org-export.el (org-export-before-parsing-hook): New
  variable.
(org-export-as): Run `org-export-before-parsing-hook'.
* testing/lisp/test-org-export.el: Add test.
This commit is contained in:
Nicolas Goaziou 2012-04-28 00:57:38 +02:00
parent 21e24f8f24
commit b3e8a8d437
2 changed files with 52 additions and 27 deletions

View File

@ -145,8 +145,8 @@
(:with-todo-keywords nil "todo" org-export-with-todo-keywords)) (:with-todo-keywords nil "todo" org-export-with-todo-keywords))
"Alist between export properties and ways to set them. "Alist between export properties and ways to set them.
The car of the alist is the property name, and the cdr is a list The CAR of the alist is the property name, and the CDR is a list
like \(KEYWORD OPTION DEFAULT BEHAVIOUR\) where: like (KEYWORD OPTION DEFAULT BEHAVIOUR) where:
KEYWORD is a string representing a buffer keyword, or nil. KEYWORD is a string representing a buffer keyword, or nil.
OPTION is a string that could be found in an #+OPTIONS: line. OPTION is a string that could be found in an #+OPTIONS: line.
@ -630,9 +630,10 @@ This variable can be either set to `buffer' or `subtree'."
(defcustom org-export-show-temporary-export-buffer t (defcustom org-export-show-temporary-export-buffer t
"Non-nil means show buffer after exporting to temp buffer. "Non-nil means show buffer after exporting to temp buffer.
When Org exports to a file, the buffer visiting that file is ever When Org exports to a file, the buffer visiting that file is ever
shown, but remains buried. However, when exporting to a temporary shown, but remains buried. However, when exporting to
buffer, that buffer is popped up in a second window. When this variable a temporary buffer, that buffer is popped up in a second window.
is nil, the buffer remains buried also in these cases." When this variable is nil, the buffer remains buried also in
these cases."
:group 'org-export-general :group 'org-export-general
:type 'boolean) :type 'boolean)
@ -1663,15 +1664,15 @@ Any element in `:ignore-list' will be skipped when using
;; Filters allow end-users to tweak easily the transcoded output. ;; Filters allow end-users to tweak easily the transcoded output.
;; They are the functional counterpart of hooks, as every filter in ;; They are the functional counterpart of hooks, as every filter in
;; a set is applied to the return value of the previous one. ;; a set is applied to the return value of the previous one.
;;
;; Every set is back-end agnostic. Although, a filter is always ;; Every set is back-end agnostic. Although, a filter is always
;; called, in addition to the string it applies to, with the back-end ;; called, in addition to the string it applies to, with the back-end
;; used as argument, so it's easy enough for the end-user to add ;; used as argument, so it's easy enough for the end-user to add
;; back-end specific filters in the set. The communication channel, ;; back-end specific filters in the set. The communication channel,
;; as a plist, is required as the third argument. ;; as a plist, is required as the third argument.
;;
;; Filters sets are defined below. There are of four types: ;; Filters sets are defined below. There are of four types:
;;
;; - `org-export-filter-parse-tree-functions' applies directly on the ;; - `org-export-filter-parse-tree-functions' applies directly on the
;; complete parsed tree. It's the only filters set that doesn't ;; complete parsed tree. It's the only filters set that doesn't
;; apply to a string. ;; apply to a string.
@ -1681,32 +1682,46 @@ Any element in `:ignore-list' will be skipped when using
;; not recognized as Org syntax. ;; not recognized as Org syntax.
;; - `org-export-filter-TYPE-functions' applies on the string returned ;; - `org-export-filter-TYPE-functions' applies on the string returned
;; after an element or object of type TYPE has been transcoded. ;; after an element or object of type TYPE has been transcoded.
;;
;; All filters sets are applied through ;; All filters sets are applied through
;; `org-export-filter-apply-functions' function. Filters in a set are ;; `org-export-filter-apply-functions' function. Filters in a set are
;; applied in a LIFO fashion. It allows developers to be sure that ;; applied in a LIFO fashion. It allows developers to be sure that
;; their filters will be applied first. ;; their filters will be applied first.
;;
;; Filters properties are installed in communication channel with
;; `org-export-install-filters' function.
;;
;; Eventually, a hook (`org-export-before-parsing-hook') is run just
;; before parsing to allow for heavy structure modifications.
;; Filters properties are installed in communication channel just
;; before parsing, with `org-export-install-filters' function. ;;;; Before Parsing Hook
(defvar org-export-before-parsing-hook nil
"Hook run before parsing an export buffer.
This is run after include keywords have been expanded and Babel
code executed, on a copy of original buffer's area being
exported. Visibility is the same as in the original one. Point
is left at the beginning of the new one.")
;;;; Special Filters ;;;; Special Filters
(defvar org-export-filter-parse-tree-functions nil (defvar org-export-filter-parse-tree-functions nil
"Filter, or list of filters, applied to the parsed tree. "List of functions applied to the parsed tree.
Each filter is called with three arguments: the parse tree, as Each filter is called with three arguments: the parse tree, as
returned by `org-element-parse-buffer', the back-end, as returned by `org-element-parse-buffer', the back-end, as
a symbol, and the communication channel, as a plist. It must a symbol, and the communication channel, as a plist. It must
return the modified parse tree to transcode.") return the modified parse tree to transcode.")
(defvar org-export-filter-final-output-functions nil (defvar org-export-filter-final-output-functions nil
"Filter, or list of filters, applied to the transcoded string. "List of functions applied to the transcoded string.
Each filter is called with three arguments: the full transcoded Each filter is called with three arguments: the full transcoded
string, the back-end, as a symbol, and the communication channel, string, the back-end, as a symbol, and the communication channel,
as a plist. It must return a string that will be used as the as a plist. It must return a string that will be used as the
final export output.") final export output.")
(defvar org-export-filter-plain-text-functions nil (defvar org-export-filter-plain-text-functions nil
"Filter, or list of filters, applied to plain text. "List of functions applied to plain text.
Each filter is called with three arguments: a string which Each filter is called with three arguments: a string which
contains no Org syntax, the back-end, as a symbol, and the contains no Org syntax, the back-end, as a symbol, and the
communication channel, as a plist. It must return a string or communication channel, as a plist. It must return a string or
@ -2141,23 +2156,22 @@ Return code as a string."
backend backend
(org-export-store-footnote-definitions (org-export-store-footnote-definitions
(org-export-get-environment backend subtreep ext-plist)))) (org-export-get-environment backend subtreep ext-plist))))
;; 2. Get parse tree. If NOEXPAND is non-nil, simply ;; 2. Get parse tree. Buffer isn't parsed directly.
;; parse current visible part of buffer. ;; Instead, a temporary copy is created, where include
(tree (if noexpand (org-element-parse-buffer nil visible-only) ;; keywords are expanded and code blocks are evaluated.
;; Otherwise, buffer isn't parsed directly. (tree (let ((buf (or (buffer-file-name (buffer-base-buffer))
;; Instead, a temporary copy is created, where (current-buffer))))
;; include keywords are expanded and code blocks (org-export-with-current-buffer-copy
;; are evaluated. (unless noexpand
(let ((buf (or (buffer-file-name (buffer-base-buffer))
(current-buffer))))
(org-export-with-current-buffer-copy
(org-export-expand-include-keyword) (org-export-expand-include-keyword)
;; Setting `org-current-export-file' is ;; Setting `org-current-export-file' is
;; required by Org Babel to properly resolve ;; required by Org Babel to properly resolve
;; noweb references. ;; noweb references.
(let ((org-current-export-file buf)) (let ((org-current-export-file buf))
(org-export-blocks-preprocess)) (org-export-blocks-preprocess)))
(org-element-parse-buffer nil visible-only)))))) (goto-char (point-min))
(run-hooks 'org-export-before-parsing-hook)
(org-element-parse-buffer nil visible-only)))))
;; 3. Call parse-tree filters to get the final tree. ;; 3. Call parse-tree filters to get the final tree.
(setq tree (setq tree
(org-export-filter-apply-functions (org-export-filter-apply-functions

View File

@ -344,9 +344,20 @@ body\n")))
(org-test-with-temp-text "* Head1\n* Head2 (note)\n" (org-test-with-temp-text "* Head1\n* Head2 (note)\n"
(should (equal (org-export-as 'test) "* Head1\n"))))))) (should (equal (org-export-as 'test) "* Head1\n")))))))
(ert-deftest test-org-export/before-parsing-hook ()
"Test `org-export-before-parsing-hook'."
(org-test-with-backend "test"
(org-test-with-temp-text "* Headline 1\nBody 1\n* Headline 2\nBody 2"
(let ((org-export-before-parsing-hook
((lambda ()
(org-map-entries
(lambda ()
(delete-region (point) (progn (forward-line) (point)))))))))
(should (equal (org-export-as 'test) "Body 1\nBody 2\n"))))))
;; Footnotes ;;; Footnotes
(ert-deftest test-org-export/footnotes () (ert-deftest test-org-export/footnotes ()
"Test footnotes specifications." "Test footnotes specifications."