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)
(:email "EMAIL" nil user-mail-address t)
(: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)
(:keywords "KEYWORDS" nil nil space)
(:language "LANGUAGE" nil org-export-default-language t)
@ -1237,7 +1283,7 @@ Return transcoded string."
((stringp blob)
(let ((transcoder (intern (format "org-%s-plain-text" backend))))
(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)
backend)))
;; BLOB is an element or an object.
@ -1318,7 +1364,7 @@ Return transcoded string."
;; No filter for a full document.
(if (eq type 'org-data) results
(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)))
(if (memq type org-element-all-elements)
(concat (org-element-normalize-string results)
@ -1739,13 +1785,12 @@ return a string or nil.")
(defun org-export-filter-apply-functions (filters value backend)
"Call every function in FILTERS with arguments VALUE and BACKEND.
Functions are called in reverse order, to be reasonably sure that
developer-specified filters, if any, are called first."
Functions are called in a LIFO fashion, to be sure that developer
specified filters, if any, are called first."
;; Ensure FILTERS is a list.
(let ((filters (if (listp filters) (reverse filters) (list filters))))
(loop for filter in filters
if (not value) return nil else
do (setq value (funcall filter value backend))))
(loop for filter in filters
if (not value) return nil else
do (setq value (funcall filter value backend)))
value)
@ -1803,18 +1848,18 @@ Return code as a string."
;; created, where all code blocks are evaluated. RAW-DATA is
;; the parsed tree of the buffer resulting from that process.
;; Eventually call `org-export-filter-parse-tree-functions'.
(let ((info (org-export-collect-options backend subtreep ext-plist))
(raw-data (progn
(when subtreep ; Only parse subtree contents.
(let ((end (save-excursion (org-end-of-subtree t))))
(narrow-to-region
(progn (forward-line) (point)) end)))
(org-export-filter-apply-functions
org-export-filter-parse-tree-functions
(org-export-with-current-buffer-copy
(org-export-blocks-preprocess)
(org-element-parse-buffer nil visible-only))
backend))))
(let* ((info (org-export-collect-options backend subtreep ext-plist))
(raw-data (progn
(when subtreep ; Only parse subtree contents.
(let ((end (save-excursion (org-end-of-subtree t))))
(narrow-to-region
(progn (forward-line) (point)) end)))
(org-export-filter-apply-functions
(plist-get info :filter-parse-tree)
(org-export-with-current-buffer-copy
(org-export-blocks-preprocess)
(org-element-parse-buffer nil visible-only))
backend))))
;; Initialize the communication system and combine it to INFO.
(setq info
(org-combine-plists
@ -1825,7 +1870,7 @@ Return code as a string."
(org-export-data raw-data backend info)))
(template (intern (format "org-%s-template" backend)))
(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
(funcall template body info))
backend)))