Source Highlighting

Source highlighting is applied to text that’s assigned the source block style (either explicitly or implicitly) and a source language. The source language is defined either on the block or inherited from the source-language document attribute.

source-highlighter attribute

Source highlighting isn’t enabled by default. To enable source highlighting, you must set the source-highlighter attribute in the document header using an attribute entry.

= Document Title
:source-highlighter: <value>

For example, here’s how to enable syntax highlighting using Rouge:

= Document Title
:source-highlighter: rouge

You can also declare this attribute using the CLI or API.

Available source highlighters

Table 1 lists the recognized values for the source-highlighter attribute and the toolchains that support the usage of the syntax highlighting libraries.

Table 1. Built-in source-highlighter values and the supporting toolchains
Library Value Toolchain

CodeRay

coderay

Asciidoctor, AsciidoctorJ, Asciidoctor PDF

highlight.js

highlight.js

Asciidoctor, AsciidoctorJ, Asciidoctor.js

Pygments

pygments

Asciidoctor, Asciidoctor PDF

Rouge

rouge

Asciidoctor, AsciidoctorJ, Asciidoctor PDF

To use Rouge, CodeRay, or Pygments, you must have the appropriate library installed on your system. See Rouge, CodeRay, or Pygments for installation instructions.

If you’re using the client-side library Highlight.js, there’s no need to install additional libraries. The generated HTML will load the required source files from a CDN, custom URL, or file path.

Source Highlighter vs. Syntax Highlighter

You might notice that the source-highlighter attribute uses the term “source highlighter”, whereas the library that performs the highlighting is referred to as a “syntax highlighter”. What’s the difference?

  • The generally accepted term for a syntax (aka code) highlighter is “syntax highlighter”.

  • The syntax highlighter is applied to source blocks in AsciiDoc, hence why we say “source highlighter”.

In other words, the source-highlighter attribute means “use this syntax highlighter to colorize source blocks”.

Apply source highlighting

To apply highlighting to a block of source code, you must specify a source language. If the block is a literal block or paragraph, you must also specify the source style.

The AsciiDoc language does not specify the list of valid source language values. Instead, the available source language values are defined by the syntax highlighter library.

You can find the list of available languages supported by Rouge in the Rouge documentation. You can print a list of available languages supported by Pygments by running pygmentize -L formatters. The available languages supported by highlight.js depends on which bundle of highlight.js you are using.

Typically, the source language value is the proper name of the language in lowercase (e.g., ruby, java). Most syntax highlighters also accept using the source file extension (e.g., js, rb), though it’s important to be consistent. If the syntax highlighter doesn’t recognize or support the source language, the block will not be highlighted.

Example 1. Source block with ID and source highlighting
[#hello,ruby] (1) (2) (3)
---- (4)
require 'sinatra'

get '/hi' do
  "Hello World!"
end
----
1 The block style source is implied since a source language is specified.
2 An optional ID can be added to the block by appending it to style using the shorthand syntax (#) for id.
3 Assign a source language to the second position.
4 An implicit source block uses the listing structural container.

The result of Example 1 is displayed below.

require 'sinatra'

get '/hi' do
  "Hello World!"
end
Example 2. Source paragraph
[source,xml] (1)
<meta name="viewport"
  content="width=device-width, initial-scale=1.0">
(2)
This is normal content.
1 Place the attribute list directly above the paragraph. In this case, the source style is always required.
2 Once an empty line is encountered the source block ends.

The result of Example 2 is displayed below.

<meta name="viewport"
  content="width=device-width, initial-scale=1.0">

This is normal content.

shell vs console

The source language for shell and console are often mixed up. The language shell is intended for the contents of a shell script, often indicated by a shebang for the generic shell. If the shell script is written for a particular shell, you might use that language instead (e.g., bash or zsh). The language console is intended to represent text that’s typed into a console (i.e., a terminal application).

Here’s an example of when you would use shell:

[,shell]
----
#!/bin/sh

fail () {
    echo
    echo "$*"
    echo
    exit 1
} >&2

JAVACMD=java
which java >/dev/null 2>&1 || fail "ERROR: no 'java' command could be found in your PATH.

exec "$JAVACMD" "$@"
----

Here’s an example of when you would use console:

[source,console]
$ asciidoctor -v

Typically, the syntax highlighter will parse the prompt (e.g., $) at the start of each line, then handle the remaining text using the shell language.

Often times, a basic console command is represented using a literal paragraph since there isn’t much to be gained from syntax highlighting in this case.

Enable line numbering

Provided the feature is supported by the source highlighter, you can enable line numbering on a source block by setting the linenums option on the block.

Line numbering is added by the syntax highlighter, not the AsciiDoc converter. Therefore, to get line numbering on a source block, you must have the source-highlighter attribute set and the library to which it refers must support line numbering. When using Asciidoctor, the only syntax highlighter that does not support line numbering is highlight.js.

The linenums option can either be specified as a normal block option named linenums, or as the third positional attribute on the block. The value of the positional attribute doesn’t matter, though it’s customary to use linenums.

Example 3. Enable line numbering using the linenums option
[%linenums,ruby]
----
puts 1
puts 2
puts 3
----
Example 4. Enable line numbering using the third positional attribute
[,ruby,linenums]
----
puts 1
puts 2
puts 3
----

Disable source highlighting

To disable source highlighting for a given source block, specify the language as text or remove the source style.

source-language attribute

If the majority of your source blocks use the same source language, you can set the source-language attribute in the document header and assign a language to it. Setting the source-language document attribute implicitly promotes listing blocks to source blocks.

Example 5. Set source-language attribute
= Document Title
:source-highlighter: pygments
:source-language: java

----
public void setAttributes(Attributes attributes) {
    this.options.put(ATTRIBUTES, attributes.map());
}
----

Notice that it’s not necessary to specify the source style or source language on the block. To make a listing block in this situation, you must set the listing style on the block.

You can override the global source language on an individual block by specifying a source language directly on the block.

Example 6. Override source-language attribute
= Document Title
:source-highlighter: pygments
:source-language: java

[,ruby]
require 'sinatra'