Process AsciiDoc Using the API

Asciidoctor provides a Ruby API named Asciidoctor for parsing, analyzing, and converting AsciiDoc content. This API is intended for use in applications, scripts, integrations with other Ruby software, such as Rails, GitHub, and GitLab, and by other languages, such as Java (via AsciidoctorJ) and JavaScript (via Asciidoctor.js).

This page examines the purpose of the API and how it can be used, shows how to get started with it, introduces its primary entry points, and links to where you can find more information to start putting it into practice.

When to use the API

If all you need to do is convert an AsciiDoc file to a publishable format such as HTML, then the asciidoctor CLI should suit your needs. Here’s an example showing how to convert an AsciiDoc document to HTML using the CLI:

$ asciidoctor -d book -n -a toc=left -a source-highlighter=highlight.js document.adoc

Here’s the same example showing how to convert the document to HTML using the API:

require 'asciidoctor'

Asciidoctor.convert_file 'document.adoc', doctype: :book, safe: :unsafe,
  attributes: { 'toc' => 'left', 'sectnums' => '', 'source-highlighter' => 'highlight.js' }
When passing attributes using the Hash format, the attribute name must be specified as a String, not a Symbol. In other words, toc: 'left' is not recognized as an attribute entry (since toc: creates a Symbol key). It must be specified as 'toc' => 'left', as shown in the previous example.

This API call can be abbreviated by declaring the document attributes using shorthand form:

require 'asciidoctor'

Asciidoctor.convert_file 'document.adoc', doctype: :book, safe: :unsafe,
  attributes: 'toc=left sectnums source-highlighter=highlight.js'

In contrast to the CLI, the API enables you to break down the processing into smaller steps. By doing so, you can capture the result of a single step, analyze the parsed document, interface with the document model in an extension, or just gain more control over the processing in general.

When using the API, we talk about two main steps:

load

In this step, the AsciiDoc content is parsed into a document object model. This model represents an in-memory hierarchy of the AsciiDoc content as a tree of Ruby objects. These objects represent the elements in the AsciiDoc document, down to the block level, along with any metadata, such as document and block attributes.

convert

In this step, the previously prepared document object model is converted into the specified output format using a converter. In coordination with the converter, the processor passes each node in the document object model to the converter to be converted. The result is then combined and either returned or written to a file, depending on the options passed to the API.

You can use the API to perform these two steps together (like the CLI) using convert and convert_file, or separately using load and load_file followed by calling #convert on the document object. The API can load and convert AsciiDoc files (load_file and convert_file) or strings (load and convert). The API entrypoints section introduces these methods in more detail.

The API is the main way to interface with Asciidoctor in an application or integration library. By using the API, you avoid having to invoke Asciidoctor using a subprocess. You’ll find that it also gives you a lot more control over the processing than what the CLI affords. The API is also a useful tool in scripts, where you may need to dive deeper into the document model beyond where extensions allow you to go. It is also instrumental in the development of extensions.

Let’s learn how to get started with the API by requiring the Asciidoctor library.

Start with require

To get started with the Asciidoctor API, you first need to install the gem. The gem provides both the CLI and the API. In fact, the CLI uses the API to handle AsciiDoc conversion.

Whereas with the CLI, you interact with Asciidoctor using the asciidoctor command, when using the API, you interact with Asciidoctor using methods on the Asciidoctor module.

In order to make the Asciidoctor module available in a Ruby script or application, you must require the asciidoctor gem using Ruby’s require function:

require 'asciidoctor'

This one statement makes all of the public APIs in Asciidoctor available to your Ruby code. For example, we can check which version of Asciidoctor was required by Ruby using the following statement:

puts Asciidoctor::VERSION
# => 2.0.23

If the require statement fails, check to make sure that you have the gem installed (and available on the GEM_PATH).

API entrypoints

The CLI is primarily intended for converting AsciiDoc. While the API can do that as well, it can do so much more. Instead of just converting AsciiDoc, the API allows you to load the AsciiDoc into a document model. From there, you can either convert the document model to an output format, or you can pause to analyze or modify its structure.

There are four main entrypoints in the Asciidoctor API:

Asciidoctor.load

parses the AsciiDoc source (down to the block level) into an Asciidoctor::Document object

Asciidoctor.load_file

parses the contents of the AsciiDoc source file (down to the block level) into an Asciidoctor::Document object

Asciidoctor.convert

parses and converts the AsciiDoc source to the output format determined by the specified backend

Asciidoctor.convert_file

parses and converts the contents of the AsciiDoc source file to the output format determined by the specified backend

If you’re processing a file, you’d typically use a method that ends with _file. Otherwise, you’d use its complement, which accepts a String, an array of Strings, or an IO object.

By default, the output of the convert methods follows the input. If you convert a String, the method will output a String. If you convert a file, the method will output to a file. However, these defaults can be changed using the options (e.g., :to_file).

When calling Asciidoctor using the API, you can access additional options that control processing which are not available when using the CLI. For example, you can pass in extensions, parse only the header, enable the sourcemap, or catalog assets.

In addition to the main entrypoints, the API also provides a mechanism to register and develop extensions. To learn more about extensions, see Extensions.