Title property of headlines and secondary-strings
I'm a bit confused about the title property of headlines. It is a secondary-string:
(setq title (org-ml-get-property :title (org-ml-build-headline! :title-text "This is my headline")))
(#("This is my headline" 0 19
(:parent
(paragraph
(:standard-properties
[1 1 1 21 21 0 nil top-comment nil nil nil nil nil nil #<killed
buffer> nil nil
(section
(:standard-properties
[1 1 1 21 21 0 nil first-section nil nil nil 1 21 nil
#<killed buffer> nil nil
(org-data
(:standard-properties
[1 1 1 21 21 0 nil org-data nil nil nil 3 21 nil
#<killed buffer> nil nil nil]
:path nil :CATEGORY nil)
#9)])
#4)])
#(" This is my headline" 0 20 (:parent #4))))))
But I can't convert that back to a string. (I know about :raw-value but it is nil in the above case, and anyway I like to do things "properly".)
(org-ml-get-type title)
nil
(org-ml-to-string title)
Eval error Argument type error: "Can only stringify node or nil, got (This is my headline)"
Is there even a way to tell if something is a secondary-string? Is there a way to properly stringify it, especially when it's actually a list or tree of nodes? The above case is simple, with no formatting, no TODO -- so how to get the proper string value in the general case?
But I can't convert that back to a string.
There's no built-in function but all you need is (-mapcat #'org-ml-to-string <nodes>)
Is there even a way to tell if something is a secondary-string?
Depends on how strict you want to be. The strictest is secondary string = list of org-element objects (plain-text, timestamp, etc) which you can get by testing each node with (org-ml-is-any-type org-ml-objects <x>).
If you want to test the list directly rather than mapping over it with a predicate, org-element itself has org-element-type which will return 'anonymous' for secondary strings with an optional argument (see docstring). This only tests if a) the thing being tested is a list and b) if the first member of said list has a car corresponding to an org-element type.
I tried that but it fails, looks like it interprets some strings as sequences:
(-mapcat #'org-ml-to-string (org-ml-get-property :title (org-ml-build-headline! :title-text "This is *my* headline")))
;; => (84 104 105 115 32 105 115 32 42 109 121 42 32 . "headline")
I didn't realize -mapcat only works on lists, use mapconcat instead:
(mapconcat #'org-ml-to-string (org-ml-get-property :title (org-ml-build-headline! :title-text "This is *my* headline")))