Adding Details/Summary to Hugo Org-Mode Posts

Apr 22, 2024 · 1110 words · 6 minute read

If you like writing your Hugo posts in Emacs with Org-Mode, and you want to use the HTML detail/summary tags, it wasn't obvious to me how to go about it, but here are a few related ways of using HTML quoting to achieve that layout.

The <details> disclosure element is very useful if you want to hide something, or put optional information inline with the point you're making. There are a lot of situations where this is a good replacement for an footnote, that even with a link, requires jumping around the page, separating related information.

If you're writing your Hugo posts in Org-Mode, and you should be1, then the text goes through an intermediate step via the go-org parser to turn it into markdown first. This can make threading your desired formatting through three layers of mark-down/up tricky.

Org-Mode doesn't have a native way of signalling that a heading is specifically collapsible; because all headings and blocks are interactive and collapsible within Emacs, so you can work at different outline levels.

Org-Mode does support quoting HTML tags, which is the solution to our problem, but there are a few ways to do it.

(This doesn't just apply to HTML generated via go-org in Hugo. You can use the same methods to use HTML tags in Org-mode files that are exported using Org's built in HTML export, usually triggered with C-c C-e h h.)

Example 1 - All HTML

#+begin_export html
<details>
<summary>Example 1 - All HTML</summary>
Write your text as raw HTML in the HTML export source block and use <i>HTML formatting</i>, if you <b>want</b> to.
</details>
#+end_export
Example 1 - All HTMLWrite your text as raw HTML in the HTML export source block and use HTML formatting, if you want to.

That's OK, but we want to write Org-Mode, and not raw HTML, otherwise why even bother with a site generator?

Example 2 - HTML Export Sandwich

To achieve this trick, you can open and then close your HTML is separate HTML export blocks, with normal Org-Mode written in between, as below:

#+begin_export html
<details>
<summary>Example 2 - HTML export sandwich</summary>
#+end_export

Then write ~Org-Mode~ to your heart's content, and it will be rendered as it /normally/ would.
That includes tables, lists etc.

| Tables   | Are   | Great   |
|----------+-------+---------|
| everyone | loves | tables! |

Nice list:
- Just
- to
- prove
- my
- point

#+begin_export html
</details>
#+end_export
Example 2 - HTML export sandwich

Then write Org-Mode to your heart's content, and it will be rendered as it normally would. That includes tables, lists etc.

TablesAreGreat
everyonelovestables!

Nice list:

  • Just
  • to
  • prove
  • my
  • point

But why stop there?

Example 3 - A Sandwich too far

If we can squeeze the content of the <details> tag between HTML Export blocks, is that also possible with the <summary> tag? Yes, as below:

#+begin_export html
<details>
<summary>
#+end_export
** Example 3 - A Sandwich too far
#+begin_export html
</summary>
#+end_export
Then you run into problems with the heading not lining up with the open/close triangle marker, and it floats confusingly above the summary.
#+begin_export html
</details>
#+end_export

Example 3 - A Sandwich too far

Then you run into problems with the heading not lining up with the open/close triangle marker, and it floats confusingly above the summary.

The contents of the <summary> tag can contain heading or paragraph content, but in practice using a heading tag in there doesn't work well without adding some specific styling to solve the issue that open/close triangle is misaligned. It's also a problem with screen readers, as it's treated like a button, and not a real heading.

Example 4 - Hugo Shortcodes

Normally using shortcodes in the Org-Mode text doesn't work, but again if you place them into an HTML export block it works, so you can use one like this one from Hugo Mods:

#+begin_export html
{​{% details "Example 4 - Hugo Shortcodes" %}}
Which is nice, but for this example, I don't think it saves much space or typing. It also requires you to have the shortcode as part of your theme, which makes it much less portable.
{​{% /details %}}
#+end_export

(Careful if copying and pasting the above example, there's a zero width space lurking between the two opening brackets so it is not rendered in the source code block.)

Example 4 - Hugo ShortcodesWhich is nice, but for this example, I don't think it saves much space or typing. It also requires you to have the shortcode as part of your theme, which makes it much less portable.

Example 5 - Inline Syntax

The eagle eyed will have noticed that the Org-Mode manual page on quoting HTML also referred to inline tags, which you can indeed also use directly in the document without a source code or HTML export block.

@@html:<details>@@
@@html:<summary>@@Example 5 - Inline Syntax@@html:</summary>@@
My opinion is this is much uglier and harder to deal with for multiple nested tags, and seems better suited for something simpler like @@html:<mark>@@marking@@html:</mark>@@ that's really done inline.
@@html:</details>@@

Example 5 - Inline SyntaxMy opinion is this is much uglier and harder to deal with for multiple nested tags, and seems better suited from something simpler like marking that's really done inline.

Conclusion

That's probably far too many ways of solving that simple, and something obvious to most others, but it was new to me, and maybe it'll be new to someone else too. Of the options above I think the second version is the best mix of clarity and not too much extra markup.

Update

So, after saying method 5, with the inline markup was the least appealing, that's actually the one I end up using the most. This is mainly because it was the easiest to set up as a skeleton template, and breaks up the text the least while looking at it in Org-Mode.

I found that the skeleton documentation isn't the easiest to understand, and this guide was much more helpful to me for creating a simple example2). I added the below to my configuration file, and now I can quickly insert the relevant boilerplate code by running M-x html-det-sum, and it even places the point in the summary section after insertion.

(define-skeleton html-det-sum
    "Insert the escaped HTML code to create a detail/summary field"
    nil
    >"@@html:<details>@@\n"
    >"@@html:<summary>@@"_"@@html:</summary>@@\n
@@html:</details>@@\n")

1

Seriously, the Org-Mode syntax is so much better that Markdown, and interactively usable. The only downside is you have to use Emacs…I'm joking, that's the best part.

2

Isn't it beautiful that some examples and code written in 1999 can still be useful, and available, today?