summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2012-08-18 10:13:35 +0200
committerNicolas Goaziou <n.goaziou@gmail.com>2012-08-18 10:13:35 +0200
commit3f57803fb4cbbcc5b7f1c38d6c6c7a287f847753 (patch)
tree90be6eb4bb2260ca3a8c5abacab9a9f9685ceea5
parent445a90ceeb30b0edf57dc79564cd3fa5fb4e0087 (diff)
downloadorg-mode-3f57803fb4cbbcc5b7f1c38d6c6c7a287f847753.tar.gz
org-element: Generalize `org-element-adopt-element' into `org-element-adopt-elements'
* lisp/org-element.el (org-element-set-element): Rewrite function. (org-element-adopt-elements): New function. (org-element-adopt-element): Removed function. (org-element--parse-elements, org-element--parse-objects): Use new function. * testing/lisp/test-org-element.el: Update tests.
-rw-r--r--lisp/org-element.el73
-rw-r--r--testing/lisp/test-org-element.el21
2 files changed, 43 insertions, 51 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el
index b7cdc44..3109186 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -346,7 +346,7 @@ still has an entry since one of its properties (`:title') does.")
;; Setter functions allow to modify elements by side effect. There is
;; `org-element-put-property', `org-element-set-contents',
;; `org-element-set-element' and `org-element-adopt-element'. Note
-;; that `org-element-set-element' and `org-element-adopt-element' are
+;; that `org-element-set-element' and `org-element-adopt-elements' are
;; higher level functions since also update `:parent' property.
(defsubst org-element-type (element)
@@ -393,38 +393,39 @@ Return modified element."
(defsubst org-element-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 (memq old sec-value) (memq old parent))))
- ;; Make sure NEW has correct `:parent' property.
- (org-element-put-property new :parent parent)
- ;; Replace OLD with NEW in PARENT.
- (setcar place new)))
-
-(defsubst org-element-adopt-element (parent child &optional append)
- "Add an element to the contents of another element.
-
-PARENT is an element or object. CHILD is an element, an object,
-or a string.
-
-CHILD is added at the beginning of PARENT contents, unless the
-optional argument APPEND is non-nil, in which case CHILD is added
-at the end.
+ ;; Since OLD is going to be changed into NEW by side-effect, first
+ ;; make sure that every element or object within NEW has OLD as
+ ;; parent.
+ (mapc (lambda (blob) (org-element-put-property blob :parent old))
+ (org-element-contents new))
+ ;; Transfer contents.
+ (apply 'org-element-set-contents old (org-element-contents new))
+ ;; Ensure NEW has same parent as OLD, then overwrite OLD properties
+ ;; with NEW's.
+ (org-element-put-property new :parent (org-element-property :parent old))
+ (setcar (cdr old) (nth 1 new))
+ ;; Transfer type.
+ (setcar old (car new)))
+
+(defsubst org-element-adopt-elements (parent &rest children)
+ "Append elements to the contents of another element.
+
+PARENT is an element or object. CHILDREN can be elements,
+objects, or a strings.
The function takes care of setting `:parent' property for CHILD.
Return parent element."
- (if (not parent) (list child)
- (let ((contents (org-element-contents parent)))
- (apply 'org-element-set-contents
- parent
- (if append (append contents (list child)) (cons child contents))))
- ;; Link the CHILD element with PARENT.
- (when (consp child) (org-element-put-property child :parent parent))
- ;; Return the parent element.
+ (if (not parent) children
+ ;; Link every child to PARENT.
+ (mapc (lambda (child)
+ (unless (stringp child)
+ (org-element-put-property child :parent parent)))
+ children)
+ ;; Add CHILDREN at the end of PARENT contents.
+ (apply 'org-element-set-contents
+ parent
+ (nconc (org-element-contents parent) children))
+ ;; Return modified PARENT element.
parent))
@@ -3738,7 +3739,7 @@ Elements are accumulated into ACC."
(org-element--parse-objects
cbeg (org-element-property :contents-end element) element
(org-element-restriction type))))
- (org-element-adopt-element acc element t)))
+ (org-element-adopt-elements acc element)))
;; Return result.
acc))
@@ -3765,11 +3766,11 @@ current object."
(let ((obj-beg (org-element-property :begin next-object)))
(unless (= (point) obj-beg)
(setq acc
- (org-element-adopt-element
+ (org-element-adopt-elements
acc
(replace-regexp-in-string
"\t" (make-string tab-width ? )
- (buffer-substring-no-properties (point) obj-beg)) t))))
+ (buffer-substring-no-properties (point) obj-beg))))))
;; 2. Object...
(let ((obj-end (org-element-property :end next-object))
(cont-beg (org-element-property :contents-begin next-object)))
@@ -3784,16 +3785,16 @@ current object."
(org-element--parse-objects
(point-min) (point-max) next-object
(org-element-restriction next-object))))
- (setq acc (org-element-adopt-element acc next-object t))
+ (setq acc (org-element-adopt-elements acc next-object))
(goto-char obj-end))))
;; 3. Text after last object. Untabify it.
(unless (= (point) end)
(setq acc
- (org-element-adopt-element
+ (org-element-adopt-elements
acc
(replace-regexp-in-string
"\t" (make-string tab-width ? )
- (buffer-substring-no-properties (point) end)) t)))
+ (buffer-substring-no-properties (point) end)))))
;; Result.
acc)))
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index df719b7..feeee6b 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -128,34 +128,25 @@ Some other text
(org-element-map tree 'italic 'identity nil t))
(org-element-map tree 'paragraph 'identity nil t))))))
-(ert-deftest test-org-element/adopt-element ()
- "Test `org-element-adopt-element' specifications."
+(ert-deftest test-org-element/adopt-elements ()
+ "Test `org-element-adopt-elements' specifications."
;; Adopt an element.
(should
- (equal '(italic plain-text)
+ (equal '(plain-text italic)
(org-test-with-temp-text "* Headline\n *a*"
(let ((tree (org-element-parse-buffer)))
- (org-element-adopt-element
+ (org-element-adopt-elements
(org-element-map tree 'bold 'identity nil t) '(italic nil "a"))
(mapcar (lambda (blob) (org-element-type blob))
(org-element-contents
(org-element-map tree 'bold 'identity nil t)))))))
;; Adopt a string.
(should
- (equal '("b" "a")
- (org-test-with-temp-text "* Headline\n *a*"
- (let ((tree (org-element-parse-buffer)))
- (org-element-adopt-element
- (org-element-map tree 'bold 'identity nil t) "b")
- (org-element-contents
- (org-element-map tree 'bold 'identity nil t))))))
- ;; Test APPEND optional argument.
- (should
(equal '("a" "b")
(org-test-with-temp-text "* Headline\n *a*"
(let ((tree (org-element-parse-buffer)))
- (org-element-adopt-element
- (org-element-map tree 'bold 'identity nil t) "b" t)
+ (org-element-adopt-elements
+ (org-element-map tree 'bold 'identity nil t) "b")
(org-element-contents
(org-element-map tree 'bold 'identity nil t)))))))