Adding a custom header argument to Org Mode source blocks and using that argument during export
| org, emacs
I sometimes want to put long source blocks in a
<details><summary>...</summary>...</details>
block when I export to
HTML, so that they're tucked away in a collapsible block. I tried
using https://github.com/alhassy/org-special-block-extras
to define
my own #+begin_my_details "summary text" ... #+end_my_details
block,
but source blocks inside my_details
doesn't get fontlocked properly
while in the Org file. I wanted to add a :summary
attribute to the
regular src blocks, and to change the HTML export to wrap the code in
details
if the summary was specified.
Code for adding a :summary argument and using it during export
(setq org-babel-exp-code-template "#+begin_src %lang%switches%flags :summary %summary\n%body\n#+end_src") (defun my-org-html-src-block (src-block _contents info) (let* ((result (org-html-src-block src-block _contents info)) (block-info (org-with-point-at (org-element-property :begin src-block) (org-babel-get-src-block-info))) (summary (assoc-default :summary (elt block-info 2)))) (if (member summary '("%summary" "")) result (format "<details><summary>%s</summary>%s</details>" summary result)))) (with-eval-after-load 'ox-html (map-put! (org-export-backend-transcoders (org-export-get-backend 'html)) 'src-block 'my-org-html-src-block))
So now I can use it by specifying blocks like this:
#+begin_src emacs-lisp :summary "Code for adding a :summary argument and using it during export" ;; code goes here #+end_src
It took me a bit of digging around to figure this out. When I added
the :summary
attribute, org-babel-get-src-block-info
found it when
I was in the Org file, but by the time my-org-html-src-block
was
called, the block had been replaced with a copy that didn't have the
header argument. I dug around using edebug's d
command for
displaying the backtrace, stepping through various functions. I found
out that in the process for exporting source code blocks,
org-babel-exp-code
replaces the source block with the value of
org-babel-exp-code-template
, substituting certain values. Adding the
summary
flag to that and retrieving the summary information using
org-babel-get-src-block-info
worked. I originally used advice-add
to override org-html-src-block
, but I think I'll try replacing the
transcoder.
Adding custom header arguments could be useful for different export-related tweaks (someone wanted to create an argument for highlighting certain lines but hadn't figured it out in that thread). If there's a more elegant way to do this, I'd love to find out!