Browse Source

org-element: Implement `org-element-copy'

* lisp/org-element.el (org-element-copy): New function.
* testing/lisp/test-org-element.el (test-org-element/copy): New test.
Nicolas Goaziou 10 years ago
parent
commit
70933a3dd6
2 changed files with 51 additions and 1 deletions
  1. 19 1
      lisp/org-element.el
  2. 32 0
      testing/lisp/test-org-element.el

+ 19 - 1
lisp/org-element.el

@@ -412,7 +412,8 @@ still has an entry since one of its properties (`:title') does.")
 ;; high-level functions useful to modify a parse tree.
 ;;
 ;; `org-element-secondary-p' is a predicate used to know if a given
-;; object belongs to a secondary string.
+;; object belongs to a secondary string.  `org-element-copy' returns
+;; an element or object, stripping its parent property in the process.
 
 (defsubst org-element-type (element)
   "Return type of ELEMENT.
@@ -561,6 +562,23 @@ The function takes care of setting `:parent' property for NEW."
     ;; Transfer type.
     (setcar old (car new))))
 
+(defun org-element-copy (datum)
+  "Return a copy of DATUM.
+
+DATUM is an element, object or string.  `:parent' property is
+cleared and contents are removed in the process.  If you need to
+preserve contents, use `org-element-extract-element' instead.
+
+If DATUM is nil, return nil."
+  (when datum
+    (let ((type (org-element-type datum)))
+      (case type
+	(org-data (list 'org-data nil))
+	(plain-text (substring-no-properties datum))
+	((nil) (copy-sequence datum))
+	(otherwise
+	 (list type (plist-put (copy-sequence (nth 1 datum)) :parent nil)))))))
+
 
 
 ;;; Greater elements

+ 32 - 0
testing/lisp/test-org-element.el

@@ -285,6 +285,38 @@ Some other text
 	      (org-element-set-element text "b")
 	      (org-element-map tree 'plain-text 'identity nil t))))))
 
+(ert-deftest test-org-element/copy ()
+  "Test `org-element-copy' specifications."
+  ;; Preserve type.
+  (should (eq 'bold
+	      (org-test-with-temp-text "*bold*"
+		(org-element-type (org-element-copy (org-element-context))))))
+  (should (eq 'plain-text
+	      (org-test-with-temp-text "*bold*"
+		(org-element-type
+		 (org-element-map (org-element-parse-buffer) 'plain-text
+		   #'org-element-copy nil t)))))
+  ;; Preserve properties except `:parent'.
+  (should (= 7
+	     (org-test-with-temp-text "*bold*"
+	       (org-element-property
+		:end (org-element-copy (org-element-context))))))
+  (should-not
+   (org-test-with-temp-text "*bold*"
+     (org-element-property
+      :parent (org-element-copy (org-element-context)))))
+  (should-not
+   (org-test-with-temp-text "*bold*"
+     (org-element-property
+      :parent
+      (org-element-map (org-element-parse-buffer) 'plain-text
+	#'org-element-copy nil t))))
+  ;; Copying nil returns nil.
+  (should-not (org-element-copy nil))
+  ;; Return a copy secondary strings.
+  (should (equal '("text") (org-element-copy '("text"))))
+  (should-not (eq '("text") (org-element-copy '("text")))))
+
 
 
 ;;; Test Parsers