arkadianriver

AsciiDoc and Asciidoctor

Some feature highlights

01 Mar 2020

I discovered the AsciiDoc markup language last year and have decided to start using it regularly. I love the simplicity and elegance of markdown, but am frustrated by its lack of ability to meet the demands of technical documentation. AsciiDoc might be the markup language that fits the bill.

In this video and article, I show some features of AsciiDoc and Asciidoctor that stand out and that I really like. It’s not meant to show all the features; for that, I recommend checking out the Asciidoctor documentation.

00:00 - Compared to markdown

I see authoring in AsciiDoc compared to markdown as being similar to programming in Perl compared to Python, at least so far as the syntax is concerned. The Python language seems to read more easily compared reading the mess of symbols that is Perl.

However, if you were to add the same amount of functionality to markdown as is currently available in AsciiDoc (as is done with SSGs, extensions, and varying flavors, such as kramdown), you end up with the same mess of symbols in the end. Worse, there is no standard just yet to keep the syntax consistent. Standards are emerging organically, such as the use of mustache tagging ({...}), but it’s still the Wild West.

AsciiDoc is one language. There is the AsciiDoc project, home of the asciidoc processor, and the Asciidoctor project that now is home to the standard syntax definition and the faster asciidoctor processor.1

And because AsciiDoc is made for documentation, Asciidoctor comes with default styles that produce great looking HTML and PDF output straight out of the box.

08:30 - Includes and attributes

You can include documents into other documents. You can also include portions of documents in others, such as in the following example.

Referring document:

include::my-included-doc.adoc[tag=mysection,leveloffset=+1]

Included document:

// tag::mysection[]
== My section

Lorem ipsum
...
// end::mysection[]

In addition, you can include CSV data into tables or code examples directly from testable source files.

AsciiDoc has variables that it calls attributes. There are attributes that define behavior of the program, and there are user-defined attributes, which allow you to substitute text, such as URLs, throughout your document.

13:45 - Inline and block formatting

You can pass through HTML just like in markdown. You can also add styles and IDs to blocks and phrases, which you can only do in some flavors of markdown.

[#thispara1]
[.myparastyle]
This paragraph has an ID and a class assigned to it.
Here I have a [.specialstyle #specialid]#specially styled# span
inside of a sentence.

There are various article and documentation specific blocks you can specify in addition to code blocks and tables, such as notices (admonitions), sidebar comments, blockquotes, and math blocks.

A feature offered with many SSGs and publishing toolchains, Asciidoctor also has a gem for text-based graphic languages, such as graphviz, plantuml, and mermaid.

Each block comment is similarly structured, but they use different characters as their block delimiters (such as ****, ----, and ++++). Therefore, especially as folks are learning, I’d encourage the use of an advanced code editor. (Good free options are VS Code, Atom, Emacs, and Vim.) It’s nice to have an editor that offers code snippets and tab-completion as reminders to what the correct characters are.

19:35 - Conditional-coding

I mention the use of the ifdef macros in the video, which can key off of various attributes or environment variables to handle differing output for different builds. You can also specify multiple attributes:

ifdef::[backend-pdf+env-production]
...
endif::[]

And, there is the ifeval macro for cases that require further evaluation to determine if a condition is met:

ifeval::[{release} > 2]
...
endif::[]

21:35 - More cool stuff and conclusion

You can create and use a bibliography with the asciidoctor-bibtex gem.

In tables, you can add block markup within a cell. And, row-spanning tables are a thing. Yes!

Like Pandoc, you can use LaTeX to produce PDF (or you can export to LaTeX), or you can use the asciidoctor-pdf gem to produce a PDF natively with Prawn.

All-in-all, I’m very pleased with Asciidoctor. I think I might stick with it for a while. Although it requires some learning, maybe as much as if I were to take up LaTeX, at least it requires much less typing. And the look of its default output is much more modern, too.


  1. Asciidoctor provides a modern, compliant, and substantially faster implementation of the AsciiDoc processor written in Ruby. This implementation can also be run on the JVM (with AsciidoctorJ) or using JavaScript (with Asciidoctor.js). The Asciidoctor project now maintains the official definition of the AsciiDoc syntax. —AsciiDoc.org ↩︎