0

As the title says, parsing the output of org-element-parse-buffer replaces each node's :parent value with modified copy of parent node.

Steps to Reproduce

Here is my Org file:

* Milk - 2% :food:
:PROPERTIES:
:QUANTITY_CACHE: 1
:END:
* Milk - 1% :food:
* Chicken :food:
* Broccoli :food:

When I run (org-element-parse-buffer 'headline) on this file (in Org Mode, I get a reasonable AST result (comments added after):

(org-data
 (:standard-properties
  [1 1 1 75 75 0 nil org-data headline nil nil 3 75 nil #<buffer Foods.org> nil nil nil]
  :path "/file/path/Foods.org" :CATEGORY "Foods")
;; Headline 1: Milk - 2%
 (headline
  (;; Headline 1 standard properties
   :standard-properties 
   [1 1 20 58 58 0 (:title) first-section headline nil nil nil nil 1 #<buffer Foods.org> nil nil #0] ;; NOTE: #0
   ;; Headline 1 properties
   :pre-blank 0 :raw-value "Milk - 2%" :title "Milk - 2%" :level 1 :priority nil :tags ("food")
   :todo-keyword nil :todo-type nil :footnote-section-p nil :archivedp nil :commentedp nil :QUANTITY_CACHE "1"))
;; Headline 1: Chicken
 (headline
  (;; Headline 2 standard properties
   :standard-properties
   [58 58 nil nil 75 0 (:title) nil headline nil nil nil nil 1 #<buffer Foods.org> nil nil #0] ;; NOTE: #0
   ;; Headline 2 properties
   :pre-blank 0 :raw-value "Chicken" :title "Chicken" :level 1 :priority nil :tags ("food")
   :todo-keyword nil :todo-type nil :footnote-section-p nil :archivedp nil :commentedp nil)))

Goal: I eventually would like to extract, for a given (unique) title, the (headline ...) with that title. At the moment, I am trying to get the headline nodes into their own list so I can loop through them and search each title.

Parsing output: I figured I could just do (cddr (org-element-parse-buffer 'headline) to get a list of the headline nodes (i.e. pop the org-data and (:standard-properties [...] :path "..." :CATEGORY "...") nodes).

However, when I eval (cddr (org-element-parse-buffer 'headline), I get the following:

((headline
  ;; Standard properties of Headline 1
  (:standard-properties
   [ 1 1 20 58 58 0 (:title) first-section headline nil nil nil nil 1 #<buffer Foods.org> nil nil
       ;; NOTE: #0 replaced by the following list:
       (org-data
        (:standard-properties ;; NOTE: Standard properties of org-data (i.e. parent node)
         [1 1 1 75 75 0 nil org-data headline nil nil 3 75 nil #<buffer Foods.org> nil nil nil]
         :path "/file/path/Foods.org" :CATEGORY "Foods")
        #1
        (headline
         (:standard-properties ;; NOTE: Standard properties of Headline 2
          [58 58 nil nil 75 0 (:title) nil headline nil nil nil nil 1 #<buffer Foods.org> nil nil #4]
          :pre-blank 0 :raw-value "Chicken" :title "Chicken" :level 1 :priority nil :tags ("food")
          :todo-keyword nil :todo-type nil :footnote-section-p nil :archivedp nil :commentedp nil)))
   ]
   ;; Properties of Headline 1
   :pre-blank 0 :raw-value "Milk - 2%" :title "Milk - 2%" :level 1 :priority nil :tags ("food")
   :todo-keyword nil :todo-type nil :footnote-section-p nil :archivedp nil :commentedp nil :QUANTITY_CACHE "1"))
 (headline
  ;; Standard properties of Headline 2
  (:standard-properties
   [58 58 nil nil 75 0 (:title) nil headline nil nil nil nil 1 #<buffer Foods.org> nil nil
       ;; NOTE: #0 replaced by the following list:
       (org-data
        (:standard-properties ;; NOTE: Standard properties of org-data (i.e. parent node)
         [1 1 1 75 75 0 nil org-data headline nil nil 3 75 nil #<buffer Foods.org> nil nil nil]
         :path "/home/user/nextcloud-sync.bak/projects/degOrge/Foods.org" :CATEGORY "Foods")
        (headline
         (:standard-properties ;; NOTE: Standard properties of Headline 1
          [1 1 20 58 58 0 (:title) first-section headline nil nil nil nil 1 #<buffer Foods.org> nil nil #4]
          :pre-blank 0 :raw-value "Milk - 2%" :title "Milk - 2%" :level 1 :priority nil :tags ("food")
          :todo-keyword nil :todo-type nil :footnote-section-p nil :archivedp nil :commentedp nil :QUANTITY_CACHE "1"))
        #1)
   ]
   ;; Properties of Headline 2
   :pre-blank 0 :raw-value "Chicken" :title "Chicken" :level 1 :priority nil :tags ("food")
   :todo-keyword nil :todo-type nil :footnote-section-p nil :archivedp nil :commentedp nil)))

The "Replacement" Problem

As indicated by the comments, running (cddr ...) seems to have resulted in a replacement the #0 value of the :parent property of :standard-properties by the org-data node, i.e. the parent node, i.e. the entire AST. In the inserted copy of the AST, however, the node of the current headline is replaced by #1.

Obviously, cddr is not causing this replacement. So what is causing this replacement?

Org Version 9.7 has new AST parser?

Running the command in emacs -Q results in an expected AST, though its structure is different; running cddr on that AST results in the expected output. Indeed, emacs -Q uses Org version 9.6.6, while my private Org version is 9.7 (9.7-??-e90a8a69a @ /home/user/.emacs.d/.local/straight/build-29.1/org/) (Doom Emacs).

Checking the Org Mode News at https://elpa.gnu.org/devel/org.html reveals that

**** Internal structure of Org parse tree has been changed

The code relying upon the previously used =(TYPE PROPERTIES-PLIST CONTENTS-LIST)= structure may no longer work. Please use ~org-element-create~, ~org-element-property~, and other Org element API functions to work with Org syntax trees.

Some syntax node properties are no longer stored as property list elements. Instead, they are kept in a special vector value of a new =:standard-properties= property. This is done to improve performance.

If there is a need to traverse all the node properties, a new API function ~org-element-properties-map~ can be used.

Logical question: how could a change to the AST structure cause the replacement problem described above? Shouldn't the output of (org-element-parse-buffer) be static data? Shouldn't cddr operate on it without causing some changing in the underlying data structure?

The Org Mode News snippet quoted above states that "code relying upon the previously used =(TYPE PROPERTIES-PLIST CONTENTS-LIST)= structure may no longer work". However, I'm not aware that org-element-parse-buffer in any way depends on this structure. Also, there is no new parser, e.g. org-element-parse-buffer-with-standard-properties, included in the Org Mode 9.7 version of org-element-ast.el.

1

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.