Turning an Org Mode outline into an HTML table with a column for more notes
| emacs, orgThe last time A- had a babysitter, I quickly scribbled down some ideas for activities that A- might enjoy. The babysitter found the list very helpful, so I figured I’d make a list that I could easily update as A-‘s interests change. I wanted a two-column table with space for notes, but I didn’t want to fiddle with LibreOffice or manually writing HTML. Org Mode to the rescue! To turn something like this:
* Activity ideas :noexport: ** Gross motor *** Balance on one leg *** Coast on the balance bike ** Fine motor *** Cut along a curve or shape ...
into a table like this:
I wrote this bit of code inside a #+begin_src emacs-lisp :exports results :results value html
… #+end_src
block:
(let* ((elements (org-element-parse-buffer)) (activity-ideas (org-element-contents (org-export-resolve-link "Activity ideas" `(:parse-tree ,elements))))) (format "<table><tr><th width=\"50%%\">Activity ideas</th><th width=\"50%%\">Notes</th></tr>%s</table>" (mapconcat (lambda (section) (format "<tr><td><h2>%s</h2><ul>%s</ul></td><td></td></tr>" (org-element-property :raw-value section) (mapconcat (lambda (idea) (format "<li>%s</li>" (org-element-property :raw-value idea))) (org-element-contents section) ""))) (org-element-contents activity-ideas) "")))
I can then export the buffer to HTML and get my nice neat table by itself, since the data comes from a subtree with the :noexport: tag. The code parses the elements in the buffer, looks at the children under the “Activity ideas” header, turns each child into a table row, and turns the children of those nodes into list items.
The code coincidentally takes advantage of the org-export-resolve-link
I wrote to help someone with an Org feature request. Yay for multipurpose code!
For the next step, I’ll probably put TODO state filtering in so that I can keep a long list of activities and then select a few for each category. It’s nice to have an outline I can easily update!