org-export: Implement access to filters through communication channel

* contrib/lisp/org-export.el (org-export-option-alist): Add filters as
  properties in the communication channel.  This allows back-end
  developers to install their own filters at run time instead of
  making them reside in a global variable.
(org-export-data, org-export-as): Read filters from communication
  channel instead of global variables.
(org-export-filter-apply-functions): Only accept list of functions.
  Also change order of calling: it is now LIFO.
This commit is contained in:
Nicolas Goaziou 2012-01-21 14:57:27 +01:00
parent e760c0c1f2
commit 5f81b563e0
1 changed files with 66 additions and 21 deletions

View File

@ -110,6 +110,52 @@
(:description "DESCRIPTION" nil nil newline) (:description "DESCRIPTION" nil nil newline)
(:email "EMAIL" nil user-mail-address t) (:email "EMAIL" nil user-mail-address t)
(:exclude-tags "EXPORT_EXCLUDE_TAGS" nil org-export-exclude-tags split) (:exclude-tags "EXPORT_EXCLUDE_TAGS" nil org-export-exclude-tags split)
(:filter-babel-call nil nil org-export-filter-babel-call-functions)
(:filter-center-block nil nil org-export-filter-center-block-functions)
(:filter-comment nil nil org-export-filter-comment-functions)
(:filter-comment-block nil nil org-export-filter-comment-block-functions)
(:filter-drawer nil nil org-export-filter-drawer-functions)
(:filter-dynamic-block nil nil org-export-filter-dynamic-block-functions)
(:filter-emphasis nil nil org-export-filter-emphasis-functions)
(:filter-entity nil nil org-export-filter-entity-functions)
(:filter-example-block nil nil org-export-filter-example-block-functions)
(:filter-export-block nil nil org-export-filter-export-block-functions)
(:filter-export-snippet nil nil org-export-filter-export-snippet-functions)
(:filter-final-output nil nil org-export-filter-final-output-functions)
(:filter-fixed-width nil nil org-export-filter-fixed-width-functions)
(:filter-footnote-definition nil nil org-export-filter-footnote-definition-functions)
(:filter-footnote-reference nil nil org-export-filter-footnote-reference-functions)
(:filter-headline nil nil org-export-filter-headline-functions)
(:filter-horizontal-rule nil nil org-export-filter-horizontal-rule-functions)
(:filter-inline-babel-call nil nil org-export-filter-inline-babel-call-functions)
(:filter-inline-src-block nil nil org-export-filter-inline-src-block-functions)
(:filter-inlinetask nil nil org-export-filter-inlinetask-functions)
(:filter-item nil nil org-export-filter-item-functions)
(:filter-keyword nil nil org-export-filter-keyword-functions)
(:filter-latex-environment nil nil org-export-filter-latex-environment-functions)
(:filter-latex-fragment nil nil org-export-filter-latex-fragment-functions)
(:filter-line-break nil nil org-export-filter-line-break-functions)
(:filter-link nil nil org-export-filter-link-functions)
(:filter-macro nil nil org-export-filter-macro-functions)
(:filter-paragraph nil nil org-export-filter-paragraph-functions)
(:filter-parse-tree nil nil org-export-filter-parse-tree-functions)
(:filter-plain-list nil nil org-export-filter-plain-list-functions)
(:filter-plain-text nil nil org-export-filter-plain-text-functions)
(:filter-property-drawer nil nil org-export-filter-property-drawer-functions)
(:filter-quote-block nil nil org-export-filter-quote-block-functions)
(:filter-quote-section nil nil org-export-filter-quote-section-functions)
(:filter-radio-target nil nil org-export-filter-radio-target-functions)
(:filter-section nil nil org-export-filter-section-functions)
(:filter-special-block nil nil org-export-filter-special-block-functions)
(:filter-src-block nil nil org-export-filter-src-block-functions)
(:filter-statistics-cookie nil nil org-export-filter-statistics-cookie-functions)
(:filter-subscript nil nil org-export-filter-subscript-functions)
(:filter-superscript nil nil org-export-filter-superscript-functions)
(:filter-table nil nil org-export-filter-table-functions)
(:filter-target nil nil org-export-filter-target-functions)
(:filter-time-stamp nil nil org-export-filter-time-stamp-functions)
(:filter-verbatim nil nil org-export-filter-verbatim-functions)
(:filter-verse-block nil nil org-export-filter-verse-block-functions)
(:headline-levels nil "H" org-export-headline-levels) (:headline-levels nil "H" org-export-headline-levels)
(:keywords "KEYWORDS" nil nil space) (:keywords "KEYWORDS" nil nil space)
(:language "LANGUAGE" nil org-export-default-language t) (:language "LANGUAGE" nil org-export-default-language t)
@ -1237,7 +1283,7 @@ Return transcoded string."
((stringp blob) ((stringp blob)
(let ((transcoder (intern (format "org-%s-plain-text" backend)))) (let ((transcoder (intern (format "org-%s-plain-text" backend))))
(org-export-filter-apply-functions (org-export-filter-apply-functions
org-export-filter-plain-text-functions (plist-get info :filter-plain-text)
(if (fboundp transcoder) (funcall transcoder blob info) blob) (if (fboundp transcoder) (funcall transcoder blob info) blob)
backend))) backend)))
;; BLOB is an element or an object. ;; BLOB is an element or an object.
@ -1318,7 +1364,7 @@ Return transcoded string."
;; No filter for a full document. ;; No filter for a full document.
(if (eq type 'org-data) results (if (eq type 'org-data) results
(org-export-filter-apply-functions (org-export-filter-apply-functions
(eval (intern (format "org-export-filter-%s-functions" type))) (plist-get info (intern (format ":filter-%s" type)))
(let ((post-blank (org-element-get-property :post-blank blob))) (let ((post-blank (org-element-get-property :post-blank blob)))
(if (memq type org-element-all-elements) (if (memq type org-element-all-elements)
(concat (org-element-normalize-string results) (concat (org-element-normalize-string results)
@ -1739,13 +1785,12 @@ return a string or nil.")
(defun org-export-filter-apply-functions (filters value backend) (defun org-export-filter-apply-functions (filters value backend)
"Call every function in FILTERS with arguments VALUE and BACKEND. "Call every function in FILTERS with arguments VALUE and BACKEND.
Functions are called in reverse order, to be reasonably sure that Functions are called in a LIFO fashion, to be sure that developer
developer-specified filters, if any, are called first." specified filters, if any, are called first."
;; Ensure FILTERS is a list. ;; Ensure FILTERS is a list.
(let ((filters (if (listp filters) (reverse filters) (list filters)))) (loop for filter in filters
(loop for filter in filters if (not value) return nil else
if (not value) return nil else do (setq value (funcall filter value backend)))
do (setq value (funcall filter value backend))))
value) value)
@ -1803,18 +1848,18 @@ Return code as a string."
;; created, where all code blocks are evaluated. RAW-DATA is ;; created, where all code blocks are evaluated. RAW-DATA is
;; the parsed tree of the buffer resulting from that process. ;; the parsed tree of the buffer resulting from that process.
;; Eventually call `org-export-filter-parse-tree-functions'. ;; Eventually call `org-export-filter-parse-tree-functions'.
(let ((info (org-export-collect-options backend subtreep ext-plist)) (let* ((info (org-export-collect-options backend subtreep ext-plist))
(raw-data (progn (raw-data (progn
(when subtreep ; Only parse subtree contents. (when subtreep ; Only parse subtree contents.
(let ((end (save-excursion (org-end-of-subtree t)))) (let ((end (save-excursion (org-end-of-subtree t))))
(narrow-to-region (narrow-to-region
(progn (forward-line) (point)) end))) (progn (forward-line) (point)) end)))
(org-export-filter-apply-functions (org-export-filter-apply-functions
org-export-filter-parse-tree-functions (plist-get info :filter-parse-tree)
(org-export-with-current-buffer-copy (org-export-with-current-buffer-copy
(org-export-blocks-preprocess) (org-export-blocks-preprocess)
(org-element-parse-buffer nil visible-only)) (org-element-parse-buffer nil visible-only))
backend)))) backend))))
;; Initialize the communication system and combine it to INFO. ;; Initialize the communication system and combine it to INFO.
(setq info (setq info
(org-combine-plists (org-combine-plists
@ -1825,7 +1870,7 @@ Return code as a string."
(org-export-data raw-data backend info))) (org-export-data raw-data backend info)))
(template (intern (format "org-%s-template" backend))) (template (intern (format "org-%s-template" backend)))
(output (org-export-filter-apply-functions (output (org-export-filter-apply-functions
org-export-filter-final-output-functions (plist-get info :filter-final-output)
(if (or (not (fboundp template)) body-only) body (if (or (not (fboundp template)) body-only) body
(funcall template body info)) (funcall template body info))
backend))) backend)))