Pygments

Pygments is a popular syntax highlighter that supports a broad range of programming and template languages.

Install Pygments

In order to use Pygments with Asciidoctor, you need Python and the pygments.rb gem. The pygments.rb gem manages calls to Pygments, which is an external program that runs using Python.

You do not need to install Pygments itself. It comes bundled with the pygments.rb gem.
You must have Python installed to use pygments.rb.

The version of Python required depends on which pygments.rb release you’re using:

  • pygments.rb 1.x requires Python 2. Check that you have a python2 (Linux), python (macOS), or py -2 (Windows) executable on your PATH. (On macOS, verify that the python executable uses Python 2 by running python -V).

  • pygments.rb 2.x requires Python 3. Check that you have a python3 (Linux/macOS) or py -3 (Windows) executable on your PATH.

Example 1. Installing Python and the pygments.rb gem via the CLI (cross platform)
$ "`\which apt-get || \which dnf || \which yum || \which brew`" install python (1)
$ gem install pygments.rb (2)
1 Install Python using your package manager
2 Install the pygments.rb gem

Activate Pygments

Once you’ve installed these libraries, assign pygments to the source-highlighter attribute in your document’s header.

:source-highlighter: pygments

Pygments attributes

You can further customize the source block output with additional Pygments attributes.

pygments-style

Sets the name of the color theme Pygments uses. To see the list of available style names, see Available Pygments style names. Default: pastie.

pygments-css

Controls what method is used for applying CSS to the tokens. Can be class (CSS classes) or style (inline styles). See the Pygments stylesheet section to learn more about how the value class is handled. Default: class.

pygments-linenums-mode

Controls how line numbers are arranged when line numbers are enabled on the source block. Can be table or inline. If line wrapping is enabled on preformatted blocks (i.e., prewrap), and you want to use line numbering on source blocks, you must set the value of this attribute to inline in order for the numbers to line up properly with their target lines. Default: table.

Example 2. Customizing a source block with Pygments attributes
:source-highlighter: pygments
:pygments-style: manni
:pygments-linenums-mode: inline

[%linenums,ruby]
----
ORDERED_LIST_KEYWORDS = {
  'loweralpha' => 'a',
  'lowerroman' => 'i',
  'upperalpha' => 'A',
  'upperroman' => 'I'
   #'lowergreek' => 'a'
   #'arabic'     => '1'
   #'decimal'    => '1'
}
----

Available Pygments style names

To list the available Pygments styles, run the following command in a terminal:

$ $(dirname $(gem which pygments.rb))/../vendor/pygments-main/pygmentize -L styles

The pygments.rb gem uses a bundled version of Pygments (often ahead of the latest release). This command ensures that you are invoking the pygmentize command from the Pygments used by that gem.

Pygments timeout (pygments.rb 1.x only)

If you’re using pygments.rb 1.x, you may need to adjust the timeout. This configuration step is not necessary if you’re using pygments.rb 2.x with Python 3.

Since Pygments is an external program, the call to that command in pygments.rb 1.x is managed by a timeout to safeguard against a hanging process. By default, this timeout is 8 seconds. If you discover that the call is failing to complete within this timeout period, you can increase the timeout (in seconds) by setting the MENTOS_TIMEOUT environment variable.

export MENTOS_TIMEOUT=30

Now the call to Pygments (via pygments.rb 1.x) will be allocated up to 30 seconds to complete.

Use a custom Pygments installation

If you already have Pygments installed on your system, you want to use your own fork, or you want to customize how Pygments is configured, you can get Asciidoctor to use a custom version of Pygments instead of the one bundled with the pygments.rb gem.

First, install your own version of Pygments. You can do this, for instance, by cloning the upstream Pygments repository:

$ hg clone https://bitbucket.org/birkenfeld/pygments-main pygments

Find the directory that contains the file pygmentize or the Makefile. That’s your Pygments installation path. Make note of it.

Next, create a script to run before invoking Asciidoctor for the first time. Let’s call it pygments_init.rb. Populate the script with the following content:

Example 3. pygments_init.rb
require 'pygments'

# use a custom Pygments installation (directory that contains pygmentize)
Pygments.start '/path/to/pygments'

# example of registering a missing or additional lexer
#Pygments::Lexer.create name: 'Turtle', aliases: ['turtle'],
#    filenames: ['*.ttl'], mimetypes: ['text/turtle', 'application/x-turtle']
You could enhance this script to read the Pygments installation path from an environment variable (or configuration file).

Now just require this script before your invoke Asciidoctor the first time. When using the asciidoctor command, pass the script using the -r flag:

$ asciidoctor -r ./pygments_init.rb document.adoc

When using the Asciidoctor API, require the script using require or require_relative:

require 'asciidoctor'
require_relative './pygments_init.rb'

Asciidoctor.convert_file 'document.adoc', safe: :safe

Now Asciidoctor is using your custom installation of Pygments instead of the one bundled with the pygments.rb gem.

Alternately, you can extend the adapter for Pygments and put this logic inside that adapter.