Sidenotes using ox-hugo
— Kaushal ModiAdding sidenotes using a Hugo shortcode and ox-hugo.
This is a post in the “Sidenotes” series.
2022-02-05 | Sidenotes using ox-hugo |
2022-02-03 | Sidenotes using only CSS |
The main focus of my previous post was the CSS for sidenotes. I also showed the companion HTML wrapper needed for that CSS to work. Here it is again for convenience:
<span class="sidenote-number">
<small class="sidenote">
sidenote content
</small>
</span>
Hugo shortcode #
Now .. You might be thinking that it’s not too practical to type that
thing for each new sidenote. And you are right! That’s where we use
the Hugo Shortcode feature.
Hugo Shortcodes are like Org Macros that are typically used to
insert some HTML template around the user entered content.
If you look at the above snippet, the outer span
and small
tags
are just HTML boilerplate that the user will need to type mechanically
around each sidenote. So the shortcodes are perfect for solving this
annoyance.
If we design a paired shortcode for this, the above HTML example will change to below:
{{% sidenote %}}
sidenote content
{{% /sidenote %}}
As you can see, this shortcode
This is a markdown-rendering shortcode i.e. a shortcode with {{% .. %}}
instead of {{< .. >}}
. So the insides of this shortcode
will passed on to the Hugo Markdown renderer.
now enables the user to
focus on content writing than on writing boilerplate HTML. And the definition of that shortcode
is pretty simple as well:
<span class="sidenote-number"><small class="sidenote">{{ .Inner }}</small></span>
The only Hugo-templating syntax used here is {{ .Inner }}
. You can
read more about it here, but the tl;dr is that the .Inner
holds
whatever content the user entered inside the {{% sidenote %}}
and
{{% /sidenote %}}
tags.
Once you save that shortcode snippet to a layouts/sidenote.html
file
in your Hugo site’s directory, you are ready to use it.
🛑 But wait! 🛑
Org mode special block #
It would be a shame to populate the Org source of this blog with Hugo-specific shortcodes when I am using ox-hugo 😄.
So instead, we just use the plain-old Org special blocks and tell ox-hugo that this “sidenote” special block be exported as a markdown-rendering Hugo shortcode. I do that by just placing this at the top of my Org file See the Hugo Paired Shortcodes section in the ox-hugo manual to learn more about this. :
#+hugo_paired_shortcodes: %sidenote
.. and then writing a “sidenote” type Org special block:
abc
#+begin_sidenote
example sidenote content
#+end_sidenote
def
Normally, Org mode would insert a paragraph break where any Org block (like that sidenote special block) is used. So above would render as:
abc
example sidenote content
def
But I am pretty sure that nobody would render sidenote references in their main text as above—instead, below is more normal 😄.
abc example sidenote content def
In that normal example of the sidenote, ox-hugo trims the whitespace
around the sidenote block. That is configured by customizing the
org-hugo-special-block-type-properties
variable:
(with-eval-after-load 'ox-hugo
(add-to-list 'org-hugo-special-block-type-properties '("sidenote" . (:trim-pre t :trim-post t))))
You can read more about this whitespace trimming feature in the ox-hugo manual.
Summary #
One-time configuration #
- Create and save a “sidenote” Hugo shortcode as shown here.
- Configure ox-hugo to export “sidenote” special block as a markdown-rendering shortcode.
- Configure whitespace to be trimmed around those blocks using
org-hugo-special-block-type-properties
customization variable.
Org special block: sidenote
#
Now just use the #+begin_sidenote
.. #+end_sidenote
Org special
blocks wherever you need sidenotes.