From e23f506d987b0eb66702514498dcc36b9793695f Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Fri, 8 Jun 2012 23:57:45 +0200 Subject: [PATCH] org-export: Add function to change elements in parse tree * contrib/lisp/org-export.el (org-export-get-buffer-attributes): Ensure initial accumulator in non-nil. (org-export-set-element): New function. * testing/lisp/test-org-export.el: Add test. --- contrib/lisp/org-export.el | 38 +++++++++++++++++++++++++++++---- testing/lisp/test-org-export.el | 18 +++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el index a3868c9e7..76f587b92 100644 --- a/contrib/lisp/org-export.el +++ b/contrib/lisp/org-export.el @@ -1282,10 +1282,9 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored." ;; Like `org-element-parse-buffer', but ;; makes sure the definition doesn't start ;; with a section element. - (nconc - (list 'org-data nil) - (org-element-parse-elements - (point-min) (point-max) nil nil nil nil nil)))) + (org-element-parse-elements + (point-min) (point-max) nil nil nil nil + (list 'org-data nil)))) alist)))) alist)) :id-alist @@ -2153,6 +2152,21 @@ Each filter is called with three arguments: the transcoded data, as a string, the back-end, as a symbol, and the communication channel, as a plist. It must return a string or nil.") + +;;;; Filters Tools +;; +;; Internal function `org-export-install-filters' installs filters +;; hard-coded in back-ends (developer filters) and filters from global +;; variables (user filters) in the communication channel. +;; +;; Internal function `org-export-filter-apply-functions' takes care +;; about applying each filter in order to a given data. It stops +;; whenever a filter returns a nil value. +;; +;; User-oriented function `org-export-set-element' replaces one +;; element or object in the parse tree with another one. It is meant +;; to be used as a tool for parse tree filters. + (defun org-export-filter-apply-functions (filters value info) "Call every function in FILTERS. Functions are called with arguments VALUE, current export @@ -2191,6 +2205,22 @@ Return the updated communication channel." ;; Return new communication channel. (org-combine-plists info plist))) +(defun org-export-set-element (old new) + "Replace element or object OLD with element or object NEW. +The function takes care of setting `:parent' property for NEW." + ;; OLD can belong to the contents of PARENT or to its secondary + ;; string. + (let* ((parent (org-element-property :parent old)) + (sec-loc (cdr (assq (org-element-type parent) + org-element-secondary-value-alist))) + (sec-value (and sec-loc (org-element-property sec-loc parent))) + (place (or (member old sec-value) (member old parent)))) + ;; Ensure NEW has correct parent. Then replace OLD with NEW. + (let ((props (nth 1 new))) + (if props (plist-put props :parent parent) + (setcar (cdr new) `(:parent ,parent)))) + (setcar place new))) + ;;; Core functions diff --git a/testing/lisp/test-org-export.el b/testing/lisp/test-org-export.el index 86453d751..bfbb3041a 100644 --- a/testing/lisp/test-org-export.el +++ b/testing/lisp/test-org-export.el @@ -369,6 +369,22 @@ body\n"))) (delete-region (point) (progn (forward-line) (point))))))))) (should (equal (org-export-as 'test) "Body 1\nBody 2\n")))))) +(ert-deftest test-org-export/set-element () + "Test `org-export-set-element' property." + (org-test-with-parsed-data "* Headline\n*a*" + (org-export-set-element + (org-element-map tree 'bold 'identity nil t) + '(italic nil "b")) + ;; Check if object is correctly replaced. + (should (org-element-map tree 'italic 'identity)) + (should-not (org-element-map tree 'bold 'identity)) + ;; Check if new object's parent is correctly set. + (should + (equal + (org-element-property :parent + (org-element-map tree 'italic 'identity nil t)) + (org-element-map tree 'paragraph 'identity nil t))))) + ;;; Footnotes @@ -758,7 +774,7 @@ Another text. (ref:text) ("6") :macro-seven ("1 + " (macro (:key "six" :value "{{{six}}}" :args nil :begin 5 :end 14 - :post-blank 0)))))))) + :post-blank 0 :parent nil)))))))) (ert-deftest test-org-export/expand-macro () "Test `org-export-expand-macro' specifications."