Intertwingling AsciiDoc and Hugo 🎀
Updated 2021-September-8

Page contents


2020-December-21  Published this evolving⁠[1] article.

1. My journey with AsciiDoc and Hugo

For a long time I’ve wanted to modernize the Infinite Ink website and in 2017,⁠[2] I tentatively decided to use AsciiDoc and Hugo to do that. I chose the AsciiDoc markup language because I wanted to use a lightweight markup language that is richer and more standardized than Markdown. I chose the Hugo static site generator because I wanted a generator that supports AsciiDoc and has no dependencies (other than an implementation of AsciiDoc such as Asciidoctor).

For more than two years, this decision was tentative and I wrote my articles in pure AsciiDoc. This involved…

In 2020, I decided to no longer be tentative about this and to no longer write in pure AsciiDoc. Instead, I now promiscuously use Hugo shortcodes throughout my writing. This means that for Infinite Ink’s website, AsciiDoc and Hugo are intertwingled and if I ever decide to change either my markup language or my site generator, it will be a PITA. In other words, I’m committed to this AsciiDoc+Hugo marriage and I hope it works out!🤞


2. Using Hugo’s markup.asciidocExt site variable to configure AsciiDoc

Starting with Hugo v0.74.0, which was released 2020-July-13, you can configure AsciiDoc in your Hugo config file. Here is an excerpt of Infinite Ink’s config.yaml:

  preserveTOC: true
  workingFolderCurrent: false  # default is false
   toc: macro
   hide-uri-scheme: true@  # trailing @ means ok to override
   sectlinks: true



  • The hide-uri-scheme attribute hides the scheme part, such as https://, of a raw URI. For example, if is in a source file, it will be displayed as in the rendered destination file. An article where I turned off this attribute (via :!hide-uri-scheme:)⁠[4] is Infinite Ink’s AsciiDoc Kitchen Sink.

  • The highlighted workingFolderCurrent and sectlinks settings are discussed in section 5 below.

  • In the last four attributes, “huri” is my abbreviation for “Hugo URI.”


3. Highlighting code blocks

Asciidoctor supports code-block syntax highlighting, but it involves installing and maintaining a Ruby gem. Instead of messing around with Ruby, I prefer to use Hugo’s built-in highlight shortcode.

Here is how I highlighted the YAML fragment that is rendered in the previous section (section 2):

{{< highlight yaml "hl_lines=4 8" >}}
  preserveTOC: true
  workingFolderCurrent: false  # default is false
   toc: macro
   hide-uri-scheme: true@  # trailing @ means ok to override
   sectlinks: true
{{< /highlight >}}

The first and last lines of this source code (just above here) calls Hugo’s built-in highlight shortcode. To learn about this Hugo shortcode, see the highlight section of Infinite Ink’s Hugo Tips, Shortcodes, and Fragments.


4. Using Hugo shortcodes for reusable snippets

Before my decision to commit to AsciiDoc+Hugo, all my reusable content snippets were in AsciiDoc attributes and AsciiDoc includes. I now use Hugo shortcodes for some AsciiDoc content snippets. Below is an example of one of Infinite Ink’s snippets.


Example of a Hugo shortcode written in AsciiDoc markup

The following Hugo shortcode comprises pure AsciiDoc markup at the top and a Go Template comment block at the bottom.

Source of a shortcode named hugo-home-v-index.adoc
The home page layout file can be named either `home.html` or `index.html`.
I prefer to name it `home.html` because the word `index` is[semantically overloaded,title="'Semantic overload' at Wikipedia"]
in Hugo.

{{- /*

USAGE: {{% snippets/hugo-home-v-index %}}
PATH: layouts/shortcodes/snippets/hugo-home-v-index.adoc

N2S: This entire file is *published* in intertwingling-asciidoc-hugo

*/ -}}

This shortcode is rendered…


  • This shortcode uses AsciiDoc syntax and is meant to be used in an AsciiDoc (.ad, .adoc, or .asciidoc) content source file and called with the {{% and %}} shortcode delimiters (not the {{< and >}} shortcode delimiters).

  • To use this snippet as a footnote, the following syntax works:
    footnote:[{{% snippets/hugo-home-v-index %}}]

  • To avoid whitespace problems, the snippet begins on the first line of the shortcode file and the comment, which is below the snippet, uses the Go Template trim-whitespace comment style.

  • This shortcode is named hugo-home-v-index.adoc but, as far as I can tell, Hugo ignores its file extension (.adoc). The file extension is basically just a note to self in this particular situation.⁠[5]


5. Using AsciiDoc includes for reusable snippets

An AsciiDoc include is better than a Hugo shortcode…

  • if the snippet resides somewhere other than a project’s layouts/shortcodes/ directory, which is where Hugo reusable shortcodes must reside,

  • or if you want to use an AsciiDoc include feature, such as including only specific lines of a file,

  • or if you do not want the safety features that Hugo shortcodes, and Go Templates in general, enforce.


Example of an AsciiDoc include

In the source of section 3 of Infinite Ink’s Linkified Section Headings in Hugo-⁠Generated Web Pages, I use the following AsciiDoc include to display lines 1, 2, and 3 of Infinite Ink’s layouts/_default/_markup/render-heading.html.


To display all lines of an AsciiDoc include file, use the following syntax.


This second AsciiDoc include line is used in the source of this section of this page and is rendered right here:

<h{{ .Level }} id="{{ .Anchor | safeURL }}">
         <a href="#{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}</a>
</h{{ .Level }}>

{{- /* 

PATH: layouts/_default/_markup/render-heading.html

* Lines 1-3 of this file are *published* in linkified-section-headings-in-hugo-generated-web-pages
* This entire file is *published* in intertwingling-asciidoc-hugo

*/ -}}

Note that this included file is a Hugo Markdown render hook and it does for Markdown what the sectlinks: true config setting (from section 2 above) does for AsciiDoc, i.e., linkify section headings. You can see it in action in Infinite Ink’s Ordinary and Extraordinary Markdown, which is one of the rare Infinite Ink pages written in Markdown rather than AsciiDoc or raw HTML.⁠[6]


  • In Asciidoctor and Hugo, forward slash (/) works as a directory path delimiter on any platform (including Windows).

  • In the above two AsciiDoc include directives, the relative path layouts/_default/_markup/ works…

    1. because of the workingFolderCurrent: false config setting (from section 2 above). This makes a path in an AsciiDoc include relative to the project’s root directory.

    2. And because I cd to the project’s root directory before running the hugo command (as opposed to using hugo --source …).

  • In an AsciiDoc include file, Hugo shortcodes and Hugo emoji codes do not work.


Another example of an AsciiDoc include

In the source of Infinite Ink’s AsciiDoc Kitchen Sink, I use an include like this:


To learn about this, see:


6. Using get-leaf-text custom shortcode to get a snippet in the current leaf bundle

If a snippet is used in only one page, you can turn the page into a Hugo bundle and put the snippet inside the bundle directory. This is what I did with the markup.asciidocExt snippet that is used in sections 2 and 3 above. The source files of this page, which is a leaf bundle, are structured like this:

├── index.adoc
└── markupdotasciidocext.yaml

In index.adoc, the source of section 2 includes this fragment…

{{< highlight yaml "hl_lines=4 8" >}}
{{< get-leaf-text "markupdotasciidocext.yaml" >}}
{{< /highlight >}}

…and the source of section 3 includes this fragment:

{{</* highlight yaml "hl_lines=4 8" */>}}
{{< get-leaf-text "markupdotasciidocext.yaml" >}}
{{</* /highlight */>}}

To learn about Infinite Ink’s get-leaf-text custom shortcode, see the get-leaf-text section of Infinite Ink’s Hugo Tips, Shortcodes, and Fragments.


See also


1. Many Infinite Ink articles, including this one, are evergreen and regularly updated.
2. You can see the evolution of my thoughts about the modernization of the Infinite Ink website on Infinite Ink’s To-⁠Do, Doing, and Done Lists⁠👷‍♀ starting in the section ~2013–2016 and scrolling up.
3. An example of an AsciiDoc Document Header is in the AsciiDoc section of Infinite Ink’s Linkified Section Headings in Hugo-⁠Generated Web Pages.
4. :!hide-uri-scheme: is equivalent to :hide-uri-scheme!:.
5. In Hugo, a file extension is usually meaningful and affects how Hugo processes a file, but that does not seem to be the case in this situation.
6. All Infinite Ink pages that were published in the 1990s were written in raw HTML. Most Infinite Ink pages that were published in 2019, 2020, and 2021 were written in AsciiDoc. (If you’re wondering what happened in between, I was publishing via Blogger, Tumblr, Twitter, GitHub, GitBook, etc.)

Comments 👍 👎 📝

Please comment so I know I'm not speaking into the void. Also, your public comment might improve this page or help me to improve this page.