I'm working on implementing a custom Org mode backend and trying to understand how the exported contents of an element/object are combined together by the export system. It seems like everything is done in a bottom-up manner, with the transcoder function corresponding to an element's type being called with the element, its already-encoded contents, and the plist containing the export environment. It's this second argument I'm interested in: it seems like each element/object in the parent's contents is encoded separately, then all the resulting strings are joined together somehow to make a single string that's then passed to the parent's transcoder function. Is there any way to control how this joining process happens? The backend is for exporting to JSON so it's crucial that everything is joined correctly with commas, and I'd like to be able to control the whitespace too.
1 Answer
Went through the source code and it does not look like this is something you can change. However, I did find a way around it by just ignoring the contents
argument and re-creating it myself by calling org-export-data
on each of the AST node's contents, then joining them together. The backend machinery memoizes the results of exporting each node so this doesn't create a lot of extra work.
The resulting function looks like this:
(defun export-contents (node info)
(format "[\n%s\n]"
(s-join ",\n"
(cl-loop
with encoded-items = nil
for item in (org-element-contents node)
do (let ((encoded (org-export-data item info)))
(unless (s-blank? encoded)
(push encoded encoded-items)))
finally return (nreverse encoded-items)))))
(defun transcode-some-element(node contents info)
(setq contents (export-contents node info)
...