Stephen Masters logo
  1. Home
  2. Projects
  3. Hugo with Asciidoctor

Hugo with Asciidoctor

Posted on September 27, 2021 • 4 min read • 667 words
Share via
Stephen Masters
Link copied to clipboard

An introduction to Asciidoctor as a means of adding richer content to Hugo pages.

Hugo supports a variety of content formats through its external helpers. One of these formats is Asciidoctor: a text processor which uses a syntax similar in style to Markdown, but provides much richer formatting capabilities and extensibility.

To demonstrate the capabilities, this page has been generated using Asciidoctor.

Global configuration

To get the best out of it you will want to create some basic configuration first.

First, create a Gemfile and configure some useful gems:

gem 'asciidoctor', '~> 2.0', '>= 2.0.16'
gem 'asciidoctor-diagram', '~> 2.2', '>= 2.2.1'

You should also set some global configuration for Asciidoctor in your config.toml.

[markup]
  [markup.asciidocExt]
    extensions = ["asciidoctor-diagram"]
    backend = 'html5'
    failureLevel = 'fatal'
    noHeaderOrFooter = true
    preserveTOC = false
    safeMode = 'unsafe'
    sectionNumbers = false
    trace = false
    verbose = false
    # Ensure that diagrams are generated into the same folder as the `.adoc`
    # so relative references can be used for including them.
    workingFolderCurrent = true

Syntax coloring

To get syntax coloring, add a syntax coloring gem such as Rouge to your Gemfile.

gem 'rouge', '~> 3.26', '>= 3.26.1'

In your Hugo config.toml, add some global configuration for syntax coloring.

[markup]
  [markup.asciidocExt]
    # ... config as before
    [markup.asciidocExt.attributes]
      icons = 'font'
      source-highlighter = 'rouge'
      rouge-css = 'style'
      rouge-style = 'github'

Then in any of your .adoc pages, you will be able to write code blocks where you can indicate the language used for syntax coloring.

[source,python]
----
for i in range(5):
    print('Hello: ' + i)
----

Which should produce something like this:

for i in range(5):
    print('Hello: ' + i)

The Asciidoctor Syntax Highlighting documentation provides more detail on what you can do. There are also various other supported highlighters such as Pygments, CodeRay and highlight.js.

Embed a CSV as a table

You can inline the contents of a CSV to draw a table:

.Mountain heights
[%header,format=csv]
|===
name,height(m)
Everest,8848
K2,8611
|===

Gives:

Table 1. Mountain heights
nameheight(m)

Everest

8848

K2

8611

One thing to note with this: at time of writing, changes to the CSV don’t take effect until you restart the Hugo dev server.

Diagrams as code with Asciidoctor Diagram

Asciidoctor Diagram is a set of Asciidoctor extensions that enable you to generate diagrams from plain text.

It is as Ruby Gem, so you can add it to your Gemfile.

gem 'asciidoctor-diagram', '~> 2.2', '>= 2.2.1'

Your Hugo config.toml can then be updated to enable it as an extension.

  [markup.asciidocExt]
    extensions = ["asciidoctor-diagram"]
    # Ensure that diagrams are generated into the same folder as the `.adoc`
    # so relative references can be used for including them.
    workingFolderCurrent = true

To generate some diagrams, you will need Graphviz installed wherever you run your build. This site is running on GitHub Pages, so I use a GitHub Action to build and deploy it. I added the following to my gh-pages.yml to ensure that Graphviz is installed on the build agent.

  - name: Setup Graphviz
    uses: ts-graphviz/setup-graphviz@v1

C4-PlantUML diagrams

C4-PlantUML provides a simple DSL to generate C4 diagrams. You can write PlantUML in-line, or include a .puml file. The PlantUML code itself looks like this:

@startuml Basic Sample
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

Person(customer, "Customer", "A customer of the bank")

System(web, "International Payments Web Application")
System(pricer, "FX Pricing Service", "Calculates quotes for international payments based on current foreign exchange rates.")
System(db, "Payments Database", "Storage for transactions and other data needed by the web application.")
System(swift, "SWIFT Gateway", "System used to send transactions out on to the SWIFT network.")

Rel(customer, web, "Requests quotes and sends international payments using", "HTTPS")
Rel(web, pricer, "Requests prices and quotes from", "HTTPS")
Rel(web, db, "Stores transactions in", "JDBC")
Rel(web, swift, "Sends international payments using", "MQ")

@enduml

Embed that using the following:

[plantuml, c4-context, svg]
----
include::./content/projects/hugo-with-asciidoctor/c4-context.puml[]
----

The .puml above generates this diagram:

c4 context

When running the local Hugo server the C4 diagrams are regenerated when you save a change to the .puml and the page is reloaded. It becomes very quick to make small tweaks and see the updated diagram on the page within a couple of seconds.

Copyright © 2024 Stephen Masters All rights reserved. Powered by Hinode.
Stephen Masters
Code copied to clipboard