While migrating my blog from Jekyll to Hugo I went down quite a rabbit hole.
While setup and migration to Hugo was a breeze, I spent a lot of time making my .adoc formatted post work with the new blog.
After working through several GitHub issues I ended up manipulating the DOM with Javascript to get admonitions working.
It still doesn’t feel right - but hey it works! 🤷‍♂️
This post will cover the steps I took in case I myself or anyone out there ever needs to do this again.

The following tool versions were used:

hugo v0.54.0

Asciidoctor 1.5.8

Firefox 65.0

Fontawesome 4.7.0

Warning:

This post contains a lot of hacks that might be obsolete by the time you read this; please check for alternatives before you hurt yourself for no reason

Getting Hugo to parse Asciidoc

Initial support for Asciidoc is already provided by the latest Hugo versions due to the concept of External Helpers.
A really neat trick that allows compatibility with any markup language that ships a binary for compilation.

Hugo has a new concept called external helpers. It means that you can write your content using Asciidoc, reStructuredText, or pandoc.
If you have files with associated extensions, Hugo will call external commands to generate the content. (See the Hugo source code for external helpers.)
For example, for Asciidoc files, Hugo will try to call the Asciidoctor or asciidoc command.
This means that you will have to install the associated tool on your machine to be able to use these formats. ⸺ the Hugo docs

So all there is to do, is to install the Asciidoctor toolchain on the machine you are running hugo - or CI server respectively.
But because Hugo calls the Asciidoctor binary using the --safe parameter lists get rendered with additional paragraphs resulting in weird layout.
The line break after each list number is something that really breaks the reading flow.

The Asciidoctor binary hack

Since Hugo does not allow you to modify the arguments passed to the Asciidoctor toolchain it also does not support using Asciidoctor with extensions.
However since Hugo only performs a system call we can use PATH trickery to mix in our wishlist before the execution.

The first step is to create a shadow executable that Hugo will use instead of the installed Asciidoctor binary.
This is an executable bash script calling the real Asciidoctor binary with additional arguments.
To find the position of your Asciidoctor binary use which asciidoctor in your terminal.

Note that this does not change the arguments specified by Hugo itself it merely adds additional modules.
It should be possible with more bash code to actually remove the --safe flag from the list of arguments that is passed on by [email protected].

To make Hugo use this executable name it asciidoctor and place it in the root directory of your Hugo project.
When calling Hugo just append the current directory to the PATH variable with highest priority, this will make Hugo our bash script which in turn calls the real Asciidoctor binary.

<ol class="arabic">
<li>Antora expects all documentation to be part of a <em>component</em>
<ol class="loweralpha" type="a">
<li>any asciidoc file can reference or include files from other components within the same Antora project</li>
</ol>
</li>
<li>the playbook can define multiple content sources
<ol class="loweralpha" type="a">
<li>each content source needs to point to a root directory of a git repo (local or remote)</li>
<li>the repo must have at least one commit</li>
</ol>
</li>
</ol>

Styling the HTML output

The next issue I had was that AsciiDoc admonitions looked pretty lame.
This is caused by the use of asciidoctor-html5s and expected behavior by the author.

Figure 2. Semantic HTML5 Asciidoctor admonitions with HTML source

The author of the semantic HTML5 Asciidoctor extension suggests hiding the text label and adding a background color with the admonition icon.
I tried it and it works fine but I did not want to add icons for the admonitions to my list of assets.
Instead I applied the DOM layout and CSS style that the Antora UI project uses for admonitions.

Manipulating the DOM for custom CSS

The Hugo theme I am using allows for custom Javascript and CSS to be injected which makes this hack quite easy to implement.
I wrote a piece of Javascript that looks for admonition-block elements and extracts the admonition type and admonition text from the DOM element.
By constructing a new DOM element using a <table> structure and replacing the original block I can style the table cells using adoc.css.

In addition to generic table styling with padding, border and background colors the following lines are necessary to get admonitions with icons.
As the Javascript snippet assigns the class="icon-${type}" to each icon cell we can add specify their respective icon using Fontawesome unicodes.