org-ml icon indicating copy to clipboard operation
org-ml copied to clipboard

how to keep properties of org-element or org-ql headlines

Open titaniumbones opened this issue 3 years ago • 1 comments

I think I'm asking a well-formed questions, but I do feel a little unsure, os apologies if this is inaccurate.

From what I can tell, org-element and org-ql store headline properties as simple plist properties in the headline's definition. org-ml seems to separate them out into a property drawer. I'd like to, for instance, grab a headline with properties from one buffer and reproduce it in a different buffer with a couple of property changes and a large number of child headlines. My thought was to do something like:

(let* ((assignment (car (org-ql-select "./Assignments.org"
                         '(and (heading "Fake Assignment for Testing")(tags "assignment")))))
       (students '("Jimmy" "Mary" "Sunit" "Jasmine"))
       (children  (--map (org-ml-build-headline :level 2 :title `(,it)) students)))
  (->> (org-ml-set-children children assignment)
       (org-ml-to-trimmed-string)))

but the resultant string eliminates the parent's property drawer. I guess I need to manually recreate the property drawer and add it a a child? Yet this seems unnecessarily complex. Is there some trick for extracting the property drawer from a headline object returned by org-element?

titaniumbones avatar Nov 08 '21 16:11 titaniumbones

Short answer:

you need to recreate the property drawer manually or parse it with the headline initially

Long answer:

To distinguish several things, the 'property-list' (plist) you are referring to has 'properties' for the headline node (:raw-value, :title, :todo-keyword, etc) as well as any of the 'properties' in a drawer underneath the headline node. Just to be clear I'll call the former 'headline-properties' and the latter 'drawer-properties'. The only distinguishing feature I can see between 'headline-properties' and 'drawer-properties' is that the latter are in always uppercase.

The purpose of the 'drawer-properties' as far as I can tell is to provide a shortcut for reading the property drawer directly. That being said, org-element itself doesn't do anything with them when converting to a string (see org-element-interpret-data) which by extension means org-ml will behave the same way because it uses org-element internally for string conversion.

As far as actually recreating the properties, you would somehow need to get the 'drawer-property' keys from the plist, which you could do by searching for those that are uppercase. This should work but any properties that are not entirely uppercase would be converted to uppercase in the new headline. Then is is just a matter of using org-ml-set-node-property (or -properties) before converting to a string.

Alternatively, you could parse the entire headline directly by supplying org-ml-parse-this-headline to org-ql (if I'm understanding it correctly) and that would give you the headline and all its contents, including the property drawer. The tradeoff would be performance since the entire headline's contents would need to be parsed.

ndwarshuis avatar Nov 08 '21 18:11 ndwarshuis