AsciiDoc Configuration

On this page, you’ll learn:

  • How to define global (site-wide) AsciiDoc document attributes in a playbook.

  • How to override a global AsciiDoc document attribute from a page.

  • How to register an Asciidoctor extension globally.

  • How to register an Asciidoctor extension that’s scoped to each page.

  • How to preload modules into the Antora runtime.

Global document attributes

If you find yourself defining the same AsciiDoc document attributes over and over in every page, you can move these attributes to the playbook, where you only have to define them once. Antora then adds these attributes to every page it converts.

You can define global (i.e., site-wide) AsciiDoc document attributes using the attributes key under the asciidoc category in the playbook. This key accepts a map of name-value pairs. The attribute can be one of the following:

  • A built-in AsciiDoc attribute you want to override (e.g., sectnums, hide-uri-scheme, linkattrs)

  • A custom attribute specific to your content (e.g., product-name)

  • An attribute that configures the behavior of a custom extension (e.g., plantuml-server-url)

Defining global AsciiDoc document attributes
asciidoc:
  attributes:
    hide-uri-scheme: ''
    product-name: 'Instant Container Maker'
    toc: ~

These attributes will be applied and available to every page in your site. You can yield the value of these attributes using the attribute reference syntax (e.g., {product-name}).

Certain built-in attributes are not applicable in the Antora environment. These attributes include data-uri, allow-uri-read, docinfo, linkcss, noheader, nofooter, webfonts, and outfilesuffix. Assigning a value to these attributes either has no effect or may cause Antora to malfunction. Other attributes, such as imagesdir, are automatically set by Antora and cannot be overridden.

Attribute value types

There are three attribute value types in AsciiDoc: String, Number, and Boolean.

If the attribute value is a String, we recommend enclosing the value in quotes just to be safe (e.g., 'Listing'). (If you’re using YAML for your playbook, and you are comfortable with the rules of the syntax, you may choose to drop the quotes when they aren’t needed).

If the attribute value is a Number, no quotes should be used around the value (e.g., 3).

If the attribute value is a Boolean, use an empty string (i.e., '') to set the attribute and a null value (i.e., null or ~) to unset the value.

You can also use a null value to unset any type of attribute (e.g., table-caption: ~). This is a good way to disable attributes that authors may use for local preview but should never be set in Antora (e.g., toc: ~).

Default attribute values

Sometimes, you want to assign a default value to an attribute, but still allow a given page to override that value. By default, an attribute defined in the playbook overrides any assignment in the document (aka the page) itself. This behavior can be changed by appending the modifier @.

If you add the @ symbol at the end of an attribute value defined in the playbook, it lowers the precedence of the attribute assignment so the page may override the value. The @ modifier is then stripped from the value. We refer to this technique as soft setting an attribute.

Defining attributes that can be overridden by a page
asciidoc:
  attributes:
    product-name: 'Instant Container Maker@'

Now, any page can override this attribute as follows:

Overriding a default global attribute in a page
= Document Title
:product-name: Explosive Container Maker

Unfortunately, it’s not currently possible to soft unset an attribute.

Asciidoctor extensions

The asciidoc category can also used for registering Asciidoctor extensions. First, you need to install the extension code, which you can either do by installing it globally, declaring it as a dependency of the project, or adding the extension script to the playbook project. Then, you can register the extension using the extensions key. The extensions key accepts a list of node module names (i.e., npm package names) and/or paths.

Global Asciidoctor extensions

Global extensions are registered once, before any pages are converted. These extensions are shared by all documents Antora converts using Asciidoctor (including navigation files). A global extension is a node module or script that exports a function when required. Antora passes this function directly to the register method of Asciidoctor’s static extension registry.

To register a global extension, all you need to do is reference its name (if it’s a node module on the require path) or path (if it’s a local script) in the extensions key.

Register a global extension provided by a node module
asciidoc:
  extensions:
  - asciidoctor-emoji-macro

In this case, asciidoctor-emoji-macro is the name of an installed node module and is thus available on the require path (either in the node_modules directory in the playbook project or in the global node_modules directory).

Register a global extension from a local script
asciidoc:
  extensions:
  - ./lib/shout-block

In this case, the extension is a script located at the path lib/shout-block.js relative to the playbook file.

Here’s an example that shows how to register multiple global extensions:

Register multiple global extensions
asciidoc:
  extensions:
  - asciidoctor-emoji-macro
  - ./lib/shout-block

Scoped Asciidoctor extensions

Rather than requiring an extension globally, you may want to register an extension per instance of the AsciiDoc processor. The benefit of this approach is that it allows the extension to hook into the Antora lifecycle. The other difference is that scoped extensions are only registered and used for pages, not for navigation files.

In order to register a scoped extension, the extension must support this mode of usage. Specifically, the extension must export a register function that accepts an extension registry on which it self registers. The function is called with a scoped (per-processor) extension registry and a context object. The context object includes the current file, the content catalog, and the AsciiDoc configuration object from the playbook.

Here’s an example of a register function for a scoped extension:

Scoped Asciidoctor extension register function
module.exports.register = function (registry, context) {
  registry.block('shout', createShoutBlock(context))
}

A scoped extension is registered in the playbook in exactly the same way as a global extension.

Register a scoped extension from the require path
asciidoc:
  extensions:
  - asciidoctor-plantuml
Register a scoped extension from a local script
asciidoc:
  extensions:
  - ./lib/equation-macro

The main difference is that if the extension exports the register function, it gets scoped to the processor instance instead of being registered globally.

Preloading modules

Instead of registering extensions using the playbook, you can preload extensions using the -r (or --require) CLI option. The value of this option may be either a path to a file (relative to the current directory), or a node module name. The -r option may be specified multiple times.

This option gives site authors the ability to load additional code into the runtime before Antora begins executing. The option follows the module resolution rules of the require() function in Node. A common use case for this option is to register Asciidoctor extensions globally.

If the node module or script is an Asciidoctor extension, it must self-register with Asciidoctor’s static extension registry when required in order for the extension to be used. (Antora merely requires the script. It does not invoke its exported function).

Here’s an example showing how to use the Antora CLI to preload multiple Asciidoctor extensions:

$ antora -r ./lib/shout-block -r asciidoctor-emoji-macro antora-playbook.yml

The -r option can also be used for other purposes, such as to alter global state or override Antora components.

For more information about the CLI, see the CLI commands and options page.