Syntax Highlighting

AsciiDoc defines a style of listing block known as a source block for adding source code snippets intended to be colorized by a syntax highlighter to a document. Here’s a simple example of a source block:

[source,ruby]
----
puts "Hello, World!"
----

Here’s how we expect it to appear:

puts "Hello, World!"

It’s up to an AsciiDoc processor such as Asciidoctor to apply the syntax highlighting to this source block, a process referred to as source highlighting. Asciidoctor provides adapters that integrate with several popular syntax highlighter libraries to perform this task. It also provides an interface for implementing a custom syntax highlighter adapter.

Syntax highlighter types

Asciidoctor supports two types of syntax highlighters: client-side and build-time. Let’s explore each type and how they work.

A client-side syntax highlighter performs syntax highlighting in the browser as the page is loading. Asciidoctor does not invoke the syntax highlighter itself. Instead, it focuses on adding the assets to the generated HTML so the browser can load the syntax highlighter and run it. For this type of syntax highlighter, Asciidoctor passes the contents of the source block through to the output as is. It also adds metadata to the element so that the syntax highlighter knows to highlight it and which language it is. Unfortunately, Asciidoctor does not process callout numbers in the source block in this case, so they may cause the syntax highlighter to get tripped up.

A build-time syntax highlighter performs syntax highlighting during AsciiDoc conversion. Asciidoctor does invoke the syntax highlighter in this case. It also takes care of hiding the callout numbers from the syntax highlighter, ensuring they are put back in the proper place afterwards. What Asciidoctor emits into the output is the result produced by the syntax highlighter, which are the tokens enclosed in <span> elements to apply color and other formatting (either inline or via CSS classes). These syntax highlighters tend to support more features because Asciidoctor has greater control over the process.

Client-side vs build-time

There are benefits and drawbacks of each type. The benefit of a client-side syntax highlighter is that does not require installing any additional libraries. It also makes conversion faster and makes it produce smaller output since the syntax highlighting is deferred until page load. The main drawback is that callouts in the source block can be mangled by the syntax highlighter or confuse it. The benefits of a build-time syntax highlighter is that you have more control over syntax highlighting and can enable additional features such as line numbers and line highlighting. The main drawback is that it requires installing an extra library, it slows down conversion, and causes the output to be larger.

You should try each syntax highlighter and find the one that works best for you.

Built-in syntax highlighter adapters

Type Syntax Highlighter Required RubyGem Compatible Converters

Client-side

Highlight.js

n/a

HTML, Reveal.js

Build-time

CodeRay

coderay (>= 1.1)

HTML, PDF, EPUB3, Reveal.js

Pygments

pygments.rb (>= 1.2)

HTML, PDF, EPUB3, Reveal.js

Rouge

rouge (>= 2)

HTML, PDF, EPUB3, Reveal.js

Asciidoctor does not apply syntax highlighting when generating DocBook. The assumption is that this is a task the DocBook toolchain can handle. The DocBook converter generates a <programlisting> element for the source block and passes through the source language as specified in the AsciiDoc. It’s then up to the DocBook toolchain to apply syntax highlighting to the contents of that tag.

You can explore these integrations in depth on the Highlight.js, Rouge, Pygments, and CodeRay pages.

You can also create your own integration by making a Custom Syntax Highlighter Adapter.