The Asciidoctor Gradle Plugin Suite is the official means of using Asciidoctor to convert all your AsciiDoc documentation using Gradle.

This started as a port of the Asciidoctor Maven Plugin project founded by Jason Porter and relies on AsciidoctorJ which was founded by Alex Soto. In fact the 1.5.x series of the Asciidoctor Gradle plugin can still be considered a port. However, with 2.x series came a complete departure with functionality far exceeding any lightweight markup plugins for any other build tool. With the 3.x serious allows for even more flexibility and options for the creation of a true DocuOps pipeline by bringing together Gradle as a powerful and generic build tool, and Asciidoctor as an agile and lightweight document generator.

Compatibility

This collection of plugins requires at least Gradle 4.9, JDK 11.0 and AsciidoctorJ 2.0.0 to run. If you need prior Gradle, JDK or AsciidoctorJ support please use a plugin from the 1.5.x or 1.6.x release series.

Quick Start

To start you need to use one of the plugins from the following Gradle snippet

build.gradle
plugins {
    id 'org.asciidoctor.jvm.convert' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.convert") version "4.0.2"
}

Task Configuration

All Asciidoctor tasks will have the following methods and properties:

Properties and methods common all AsciidoctorJ tasks
asciidoctorj

a task extension which allows a task to extend of override global configuration for Asciidoctor tasks. This allow extensive flexibility. Any thing that can be configured in the global asciidoctorj extension can also be configured here.

attributes

A shortcut for asciidoctorj.attributes and asciidoctorjs.attributes.

baseDir

Base directory for asciidoctor document conversion and root document inclusion. The base directory will be the project directory by default, but can be set to any other directory.

baseDirFollowsSourceDir

The base directory should be the same as the source directory even if the source directory is located within an intermediate working directory.

baseDirFollowsSourceFile

The base directory should be the same as the directory of each individual source file.

baseDirIsProjectDir

The base directory is always the current project directory.

baseDirIsRootProjectDir

The base directory is always the root project directory.

configurations

Specify additional configurations These configurations will be added to the classpath when the task is executed.

copyAllResources

Copy all resources to the output directory

copyNoResources

Do not copy any resources to the output directory

copyResourcesOnlyIf

Only copy resources if the backend matches the listed backend.

executionMode

Specifies whether Asciidoctor conversions should be run in-process or out-of-process. Default: JAVA_EXEC. In version 3.x this was called inProcess

languages

Invoke source language support but specifying one or more languages.

logDocuments

Specifies if documents being processed should be logged on console. Type: boolean. Default: false.

options

A shortcut to asciidoctorj.options.

outputDir

where generated docs go. Use either outputDir path, setOutputDir path or outputDir=path Type: File, but any object convertible with project.file can be passed. Default: $buildDir/asciidoc.

parallelMode

Specifies whether each backend or other variant of a converting tasks should be run in parallel or sequential. Sequential conversions might have less initialisation overhead, but may suffer from gemPath and extension pollution. Default: true (parallel).

resources

specify which additional files (image etc.) must be copied to output directory using a CopySpec. secondarySources: Specify which source files should be monitor for change. These are typically files which are included by top-level files as well as doctype files. Default: All files in sourceDir which matches getDefaultSourceDocumentPattern() as well as doctype files.

sourceDir

where the asciidoc sources are. Use either sourceDir path, setSourceDir path or sourceDir=path Type: File, but any object convertible with project.file can be passed. Default: src/docs/asciidoc.

sources

Specify which Asciidoctor source files to include as toplevel documents. It uses an Ant-style PatternSet.

useIntermediateWorkDir

Use an intermediate work directory for sources ances. Some extensions such as ditaa will write content into the source directory. In order to keep the project source directory pristine an intermediate work directory can be used. All sources and resources will be copied there prior the executing Asciidoctor.

withIntermediateArtifacts

Add intermediate artifacts to output directory. If the document conversion process creates intermediate artifacts which needs to be added to the output directory, then the pattern set with a closure or Action. This implies useIntermediateWorkDir. An example of such a case is the use of ditaa.

You will have to configure the properties for each plugin as they are not inherited from one to another. For example you will have to configure languages for both org.asciidoctor.jvm.convert and org.asciidoctor.jvm.pdf plugins if you want multi language pdf and html. Otherwise it wil not work properly. See This issue for more details.

The org.asciidoctor.jvm.convert plugin has a conversion task type of org.asciidoctor.gradle.jvm.AsciidoctorTask which, in addition the aforementioned will also have the following properties and methods which are configured via an outputOptions closure or action:

Properties & methods for configuring generic AsciidoctorTask
backends

the backends to use. Use backends to append. Use setBackends or backends=[] to overwrite Type: Set<String>, but any type can be converted to String can be used. Default: [html5].

separateOutputDirs

specifies whether each backend should use a separate subfolder under outputDir. Default: true

Defining Sources

The plugin will search for sources under sourceDir. Sources may have any of the following extensions in order to be discovered:

  • .adoc (preferred)

  • .asciidoc

  • .ad

  • .asc

To select only certain files, use the sources method. This method takes a closure or an Action as an argument, which in turn configures an org.asciidoctor.gradle.jvm.epub.internal PatternSet.

To specify a custom output folder, use the outputDir method.

build.gradle
asciidoctor {
  sourceDir  file('docs')
  sources {
    include 'toplevel.adoc', 'another.adoc', 'third.adoc'
  }
  outputDir  file('build/docs')
}
build.gradle.kts
tasks {
  "asciidoctor"(AsciidoctorTask::class) {
    sourceDir = file("docs")
    sources(delegateClosureOf<PatternSet> {
      include("toplevel.adoc", "another.adoc", "third.adoc")
    })
    outputDir = file("build/docs")
  }
}

Paths defined in this PatternSet are resolved relative to the sourceDir.

Processing Auxiliary Files

Some backends require that additional files be copied across. The most common example are images for HTML backends. For this the resources method is used. It is provided with a closure that configures an org.asciidoctor.gradle.jvm.epub.internal CopySpec

build.gradle
resources {
  from('src/resources/images') {
    include 'images/**/*.png'
    exclude 'images/**/notThisOne.png'
  }

  from( "${buildDir}/downloads" ) {
    include 'deck.js/**'
  }

  into './images'
}
build.gradle.kts
resources(delegateClosureOf<CopySpec> {
  from("src/resources/images") {
    include("images/**/*.png")
    exclude("images/**/notThisOne.png")
  }

  from("$buildDir/downloads") {
    include("deck.js/**")
  }

  into("./images")
})

Files will be copied to below ${outputDir}/${backend} (or just ${outputDir} if separateOutputDirs=false)

Unlike sourceDir files can be copied from anywhere in the filesystem.

If resources is never set, the default behaviour is as if the following was called

build.gradle
resources {
  from(sourceDir) {
    include 'images/**'
  }
}

In case of languages the default behaviour is

build.gradle
resources {
  from(new File(sourceDir,"${langName}")) {
    include 'images/**'
  }
}

If you do not want this behaviour, then it can be turned off by doing

build.gradle
copyNoResources()

If you are using multiple languages and you have identical resource patterns for each languages within sourceDir/$ you need to explicitly declare those on a per-language basis:

build.gradle
resources 'en', {
  from("${sourceDir}/en") {
    include 'images/**'
  }
}

resources 'es', {
  from("${sourceDir}/es") {
    include 'images/**'
  }
}

Include directives and base directory

These plugins do not change the way include:: directive works, but it is important to note how setting baseDir will affect top level includes. It is recommended that you always use {includedir} as a prefix for the file path. This attribute is always set to the correct top-level folder where the sources will be located.

However it is not practical for everyone to use {includedir} and as from 2.2.0 it is possible to add a strategy for controlling the base directory:

build.gradle
asciidoctor {
    baseDirIsRootProjectDir() (1)
    baseDirIsProjectDir() (2)
    baseDirFollowsSourceDir() (3)
    baseDirFollowsSourceFile() (4)
}
1 The base directory is the root project directory.
2 The base directory is the current subproject directory.
3 The base directory will always the the same as the source directory. If an intermediate working directory is being used, the base directory will automatically point to that.
4 The base directory will be the same as the directory of each individual source file.

Docinfo processing

When using the docinfo attribute with html and docbook backends, it is recommended that baseDirFollowsSourceDir() is always set. This will ensure that the docinfo files are picked up correctly from the same directory that is the source directory.

Source language support

Some scenarios work on a source set of documents in a primary language and then translations of those sources into other languages. The Gradle plugin simplifies this scenario by allowing a structure such as

│   └── src
│       ├── asciidoc
│       │   └── en
│       │       └── index.adoc
│       │   └── es
│       │       └── index.adoc

This can be enabled in the DSL by doing

asciidoctor {
    languages 'en', 'es'
}

Gradle will then process both the en and the es source set and output to the output directory using the same languages names. Intermediate working directories and multiple backends are also covered. In this case the lang attribute will be injected with the specific language as the value.

It is also possible to specify additional attributes that will only be added when a specific language is processed

asciidoctorj { (1)
    attributesForLang 'en', langName : 'English'
    attributesForLang 'ca', langName : 'Catala'
}

asciidoctorjs { (2)
    attributesForLang 'en', langName : 'English'
    attributesForLang 'ca', langName : 'Catala'
}
1 Configuration when using AsciidoctorJ
2 Configuration when using Asciidoctor.js

Choosing a Process Mode for AsciidoctorJ

All AsciidoctorJ-based tasks can control how Asciidoctor conversions are being run via the inProcess property. This is early days, and a choice for your build will depend very much on your context, but the following has already become clear:

  • IN_PROCESS and OUT_OF_PROCESS should theoretically run faster, especially if you continuously rebuild the same documentation. Gradle workers are the underlying implementation for these two options

  • The safe option is always JAVA_EXEC. For lower memory consumption this is by far the safer option. (It is also the only way we can get the Windows-based tests for this plugin to complete on Appveyor & Travis CI). It you run a lot of builds the penalty start-up time might become an issue for you.

In certain cases the plugin will overrule your choice as it has some built-in rules for special cases. In such cases it will log a warning that it has done that.

AsciidoctorJ Base Plugin

This plugin is automatically applied by all AsciidoctorJ-based plugins.

Adds an extension for configuring which version of AsciidoctorJ and various other AsciidoctorJ backends.

This is very much similar to the one used in older versions of the Asciidoctor Gradle plugin, but now it also offers the ability to add the same functionality to a task thus allowing a task to override the default versions that has been set.

asciidoctorj {
  version = '1.5.6' (1)
  groovyDslVersion = '1.0.0.Alpha2' (2)

  options doctype: 'book', ruby: 'erubis' (3)

  attributes toclevel : 2 (4)
}
1 Set the default version of AsciidoctorJ for all Asciidoctor tasks in a project.
2 Set the default version of the Groovy extensions DSL for all Asciidoctor tasks in a project.
3 Add options for all Asciidoctor tasks
4 Add attributes for all Asciidoctor tasks

You can also override or extend select settings within a task using the same extension i.e.

asciidoctor {
  asciidoctorj {
      setOptions = [ doctype: 'article' ] (1)

      attributes toc : left (2)
  }
}
1 Override any global options
2 Use these attributes in addition to the globally specified ones.

The AsciidoctorJ-specific entities that can be set are:

docExtensions

Groovy DSL and project-based extensions. Use docExtensions to add one or more extensions. Use setDocExtensions to replace the current set of extensions with a new set. Extensions can be any kind of object that is serialisable, although in most cases they will be strings or files. If extensions are detached dependencies, they will not be serialised, but rather will be placed on the classpath in order that AsciidoctorJ can pick them up automatically. See <asciidoctorj-extensions>> for more details.

fatalWarnings

Patterns for AsciidoctorJ log messages that should be treated as fatal errors. The list is empty be default. Use setFatalWarnings to clear any existing patterns or to decouple a task’s configuration from the global configuration. Use fatalWarnings to add more patterns. Pass missingIncludes() to add the common use-case of missing include files.

jrubyVersion

Minimum version of JRuby to be used. The exact version that will be used could be higher due to AsciidoctorJ having a transitive dependency that is newer.

logLevel

The log level at which AsciidoctorJ will log. This is specified as a Gradle logging level. The plugin will translate it to the appropriate AsciidoctorJ logging level. Default is whatever project.logger.level is at the time of execution.

modules

Configuration for version of specific components and converters that can be used. See AsciidoctorJ Modules for which modules are supported.

options

AsciidoctorJ options. Use options to append and setOptions to replace any current options with a new set. Options are evaluated as late as possible. See Setting Options for more details.

requires

The set of Ruby modules to be included. Use requires to append. Use setRequires or requires=['name'] to overwrite. Default: empty.

resolutionStrategy

Strategies for resolving Asciidoctorj-related dependencies. AsciidoctorJ dependencies are held in a detached configuration. If for some special reason, you need to modify the way the dependency set is resolved, you can modify the behaviour by adding one or more strategies.

version

AsciidoctorJ version. If not specified a sane default version will be used.

The following common entities can also be set:

attributes

Asciidoctor attributes. Use attributes to append and setAttributes to replace any current attributes with a new set. Attribute values are lazy-evaluated to strings. See [attributes] for more detail.

attributeProviders

Additional sources where attributes can be obtained from. Attribute providers are useful for where changes should not cause a rebuild of the docs.

attributesForLang

Language-specific attributes. Specify additional attributes which will only be added if a source set for the specified language is being processed.

safeMode

Asciidoctor safe mode. Set the Safe mode as either UNSAFE, SAFE, SERVER, SECURE. Can be a number (0, 1, 10, 20), a string, or the entity name

Options & Attributes

The following options may be set using the extension’s options property

  • header_footer - boolean

  • template_dirs - List<String>

  • template_engine - String

  • doctype - String

Any key/values set on attributes is sent as is to Asciidoctor. You may use this Map to specify a stylesheet for example. The following snippet shows a sample configuration defining attributes.

build.gradle
asciidoctorj { (1)
    options doctype: 'book', ruby: 'erubis'

    attributes 'source-highlighter': 'coderay',
                toc                 : '',
                idprefix            : '',
                idseparator         : '-'
}
1 This can be globally on the project extension or locally on the task’s extension.

Or in the Gradle Kotlin DSL:

build.gradle.kts
tasks {
  "asciidoctor"(AsciidoctorTask::class) { (1)
    options(mapOf("doctype" to "book", "ruby" to "erubis"))

    attributes(
      mapOf(
        "source-highlighter" to "coderay",
        "toc"                to "",
        "idprefix"           to "",
        "idseparator"        to "-"
      )
    )
  }
}
1 This is an example of setting it on the task extension in Kotlin.

The following attributes are automatically set by the asciidoctorj extension:

  • gradle-project-name : matches $project.name

  • gradle-project-version: matches $project.version (if defined). Empty String value if undefined

  • gradle-project-group: matches $project.group (if defined). Empty String value if undefined

These attributes may be overridden by explicit user input.

Refer to the Asciidoctor documentation to learn more about these options and attributes.

Attribute values defined on the build file will win over values defined on the documents themselves. You can change this behavior by appending an @ at the end of the value when defined in the build file. Please refer to Attribute assignment precedence for more information.

Versions of modules

The modules block currently supports four elements

build.gradle
asciidoctorj {
  modules {
    pdf { (1)
      version '1.2.3'
    }
    epub { (2)
      version '1.2.3'
    }
    diagram { (3)
      version '1.2.3'
    }
    groovyDsl { (4)
      version '1.2.3'
    }
    leanpub { (5)
      version '1.2.3'
    }
  }
}
1 Asciidoctorj-EPUB version. If not specified asciidoctorj-epub will not be on the classpath. If you plan to use the EPUB backend and not using the EPUB plugin, then you need to set a version here.
2 Asciidoctorj-PDF version. If not specified asciidoctorj-pdf will not be on the classpath. If you plan to use the PDF backend and not using the PDF plugin, then you need to set a version here.
3 See AsciidoctorJ Diagram,
4 Version of Groovy Extensions DSL. If not specified and no extensions are specified, Groovy DSL will not be used. However, if any extensions are added without setting an explicit version and default version will be used.
5 {asciidoctorj-leanpub-name} version. If not specified asciidoctorj-leanpub will not be on the classpath. If you plan to use the Leanpub backend and not using the Leanpub plugin, then you need to set a version here.

When using the {kotlin-dsl} the same settings can be achieved use something similar getModules().getPdf().version("1.2.3"). In a similar fashion shortcuts can be achieved in the {groovy-dsl}:

build.gradle
asciidoctorj {
  modules {
    pdf.version '1.2.3'
  }

  modules.pdf.version '1.2.3'
}
build.gradle.kts
asciidoctorj {
  getModules().getPdf().version("1.2.3") (1)
  getModules().getPdf().use() (2)
}
1 Set the Asciidoctorj-PDF version to 1.2.3.
2 Use the default version of Asciidoctorj-PDF.

Applying the AsciidoctorJ Base plugin on its own

If none of the default conventions work for you, the base plugin can be applied on its own.

build.gradle
plugins {
    id 'org.asciidoctor.jvm.base' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.base") version "4.0.2"
}

The New AsciidoctorJ Plugin

build.gradle
plugins {
    id 'org.asciidoctor.jvm.convert' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.convert") version "4.0.2"
}

When applying org.asciidoctor.jvm.convert it creates a single task of type org.asciidoctor.gradle.jvm.AsciidoctorTask called asciidoctor.

By convention it sets the * sourceDir to src/docs/asciidoc * outputDir to ${buildDir}/docs/asciidoc

The AsciidoctorPdf Plugin

build.gradle
plugins {
    id 'org.asciidoctor.jvm.pdf' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.pdf") version "4.0.2"
}

When applying org.asciidoctor.jvm.pdf it creates a single task of type org.asciidoctor.gradle.jvm.pdf.AsciidoctorPdfTask an extension called pdfThemes.

The default task is named asciidoctorPdf and is configured to:

  • Output source to "${buildDir}/docs/asciidocPdf"

  • Not to copy any resources to the output directory

  • It will set also a default version for asciidoctorj-pdf artifact. To override set asciidoctorj.pdfVersion or asciidoctorPdf.asciidoctorj.pdfVersion.

The AsciidoctorPdfTask task type has the following additional methods:

fontsDirs

Directories for custom PDF fonts. Specify a directory in any form acceptable to project.file. Using this instead of directly setting the pdf-fontsdir attribute means that Gradle will be able to check out of date status dependent on the content of this folder.

theme

Name of the theme to use. Optional. When specifying a theme name it must match one registered via pdfThemes.

The pdfThemes extension allows for themes to be registered from local copies or downloaded from GitHub or GitLab and has been inspired by earlier work of Florian Wilhelm (@fwilhe).

Registering a local theme
pdfThemes {
    local 'basic', { (1)
        themeDir = file('themes/basic') (2)
        themeName = 'very-basic' (3)
    }
}
1 Local themes are registered using the local keyword and must be provided with a name
2 Directory for finding the theme. Specify a directory in any form acceptable to project.file.
3 Optional setting of the style name. If this is not set, the theme name provided previously will be used.
Registering a GitHub or GitLab theme
pdfThemes {
    github 'basic', { (1)
        organisation = 'fwilhe2' (2)
        repository = 'corporate-theme' (3)
        relativePath = 'resources/themes' (4)

        branch = 'master' (5)
        tag = '1.0.1' (6)
        commit = '4910271e8c3964b60e186a62f3e4339ed0752714' (7)
    }
}
1 Specify a GitHub repository which contains one or more themes. (For GitLab replace github with gitlab).
2 GitHub/GitLab Organisation (or user).
3 Name of repository containing the theme(s).
4 Relative path inside the repository to where the theme is located. If not specified the theme is assumed to be in the root of the repository.
5 Specify the branch
6 Instead of a branch a tag can be used.
7 Instead of a branch or a tag, a very specific commit can be used.

If a repository contains more than one theme, then the block will need to be repeated for each theme and the name and relativePath adjusted accordingly. Gradle will however, only download the repository once.

Kotlin users can use equivalent Action-based configurations.

The AsciidoctorEpub Plugin

INFO: As from version 3.3 support for KindleGen is dropped as Amazon no longer has the binary available for download.

build.gradle
plugins {
    id 'org.asciidoctor.jvm.epub' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.epub") version "4.0.2"
}

When applying org.asciidoctor.jvm.epub it creates a single task of type org.asciidoctor.gradle.jvm.epub.AsciidoctorEpubTask which is then configured to:

  • Output source to "${buildDir}/docs/asciidocEpub"

  • Not to copy any resources to the output directory

  • It will set also a default version for asciidoctorj-epub artifact. To override set asciidoctorj.epubVersion or asciidoctorEpub.asciidoctorj.epubVersion.

The AsciidoctorEpubTask task type has the following additional methods:

ebookFormats

The epub formats to generate. Specify one of more strings. Anything that is supported by the Asciidoctor EPUB backend can be used. Constant EPUB3 is available for convenience. To override any previous set formats use setEbookFormats. To add to the existing list use eBookFormats.

The AsciidoctorJ Reveal.js Plugin

build.gradle
plugins {
    id 'org.asciidoctor.jvm.revealjs' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.revealjs") version "4.0.2"
}

When applying org.asciidoctor.jvm.revealjs support is added for creating slides using Asciidoctor & Reveal.js. The plugin configures:

  • Create a task called asciidoctorRevealJs.

  • Create an extension called revealjs which is used for configuring the version of Reveal.js as well as a template.

  • Create an extension called revealjsPlugins which will allow for downloading additional Reveal.js plugins.

  • Output source to "${buildDir}/docs/asciidocRevealJs"

  • Copy all resources to the output directory including Reveal.js templates.

  • Apply the org.asciidoctor.jvm.gems plugin as GEM support is required.

The AsciidoctorRevealJSTask task type has the following additional methods:

revealjsOptions

Configure special Reveal.js options. Can be configured via Closure or Action. See [RevealJSOptions] for more details.

templateDir

Location where the template directory will be located on disk before Asciidoctor processing starts.

theme

The Reveal.js theme to use. The theme must match one from the template.

The version of the Reveal.js GEM and the Reveal.js template is configured via the revealjs extension:

revealjs {
  version = '1.1.3' (1)

  templateGitHub {  (2)
    organisation = 'hakimel'
    repository = 'reveal.js'
    tag = '3.7.0'
  }
}
1 Reveal.js GEM version
2 Obtain the Reveal.js template from GitHub.

If not specified, sensible defaults are provided.

Reveal.js Options

Various options can be configured for Reveal.js. Although these can be set as attributes directly, it is far better to set them on the task as advantage can be taken of Gradle task caching and file resolving.

asciidoctorRevealJs {
  revealjsOptions { (1)
    controls = true
  }
}
1 Use revealjsOptions block for configuration with any of the below options.
autoslideInterval

Delay in milliseconds between automatically proceeding to the next slide. Disabled when set to 0 (the default). This value can still be overwritten on a per-slide basis by setting a data-autoslide attribute on a slide. Type is integer.

autoSlideStoppable

Stop auto-sliding after user input Type is boolean.

backgroundTransition

Transition style for full page slide backgrounds.. Can be a RevealJSOptions.Transition or string value.

controls

Display controls in the bottom right corner. Type is boolean.

customThemeLocation

A custom theme that is not in the template. Can be anything convertible to a file or URI.

hideAddressBarOnMobile

Hides the address bar on mobile devices. Type is boolean.

flagEmbedded

Flags if the presentation is running in an embedded mode ( contained within a limited portion of the screen ). Type is boolean.

fragments

Use fragments globally. Type is boolean.

highlightJsThemeLocation

Highlight.js theme location. Can be anything convertible to a file or URI.

keyboardShortcuts

Enable keyboard shortcuts for navigation. Type is boolean.

loop

Loop the presentation.. Type is boolean.

mouseWheel

Enable slide navigation via mouse wheel. Type is boolean.

overviewMode

Enable the slide overview mode. Type is boolean.

parallaxBackgroundImageLocation

Parallax background image. Can be anything convertible to a file or URI.

parallaxBackgroundSize

Parallax background size. Accepts any CSS syntax. Can be anything convertible to a string.

previewLinks

Opens links in an iframe preview overlay. Type is boolean.

processBar

Display a presentation progress bar. Type is boolean.

pushToHistory

Push each slide change to the browser history. Type is boolean.

righttoLeft

Change the presentation direction to be RTL. Type is boolean.

slideNumber

Display the slide number of the current slide. Can be a RevealJSOptions.SlideNumber, a string value or a boolean.

touchMode

Enables touch navigation on devices with touch input. Type is boolean.

transition

Slide transition mode. Can be a RevealJSOptions.Transition or string value.

transitionSpeed

Slide transition speed. Can be a RevealJSOptions.TransitionSpeed or string value.

verticalCenter

Vertical centering of slides. Type is boolean.

viewDistance

Number of slides away from the current that are visible. Type is integer.

Using AsciidoctorJ Diagram

The new plugins have built-in support for asciidoctorj-diagram. Simply add the following to the project or task extension and diagramming will be available. If it is not set the asciidoctorj-diagram JAR will not be added to the classpath.

asciidoctorj {
    modules {
       diagram.use() (1)
       diagram.version '1.5.16' (2)
    }
}
1 Enables diagram usage with whatever the default version of asciidoctorj-diagram is.
2 Enables usages, but set a specific version rather than the default suggested by the plugin.

With this enhancement, there is also no longer a need to add requires 'asciidoctor-diagram'.

If you using OpenJDK 9/10 on MacOS you might find an error such as below
Caused by: java.lang.UnsatisfiedLinkError: /path/to/openjdk10/lib/libfontmanager.dylib: dlopen(/path/to/openjdk10/lib/libfontmanager.dylib, 1): Library not loaded: /Users/jenkins/workspace/openjdk10_build_x86-64_macos/openjdk/installedfreetype/lib/libfreetype.6.dylib
  Referenced from: /path/to/openjdk10/lib/libfontmanager.dylib
  Reason: image not found

The solution is to install freetype via HomeBrew or MacPorts. You might also need to do something (ridiculous) such as

$ sudo mkdir -p /Users/jenkins/workspace/openjdk10_build_x86-64_macos/openjdk/installedfreetype
$ sudo ln -s /opt/local/lib /Users/jenkins/workspace/openjdk10_build_x86-64_macos/openjdk/installedfreetype/lib (1)
1 opt/local/lib is the location for MacPorts. Change it accordingly for HomeBrew.

Ruby GEM support

GEM support is simplified via the org.asciidoctor.jvm.gems plugin.

build.gradle
plugins {
    id 'org.asciidoctor.jvm.gems' version '4.0.2'
}

repositories {
    ruby {
        gems() (1)
    }
}

dependencies {
    asciidoctorGems 'rubygems:asciidoctor-revealjs:1.1.3' (2)
}

asciidoctorj {
    requires 'asciidoctor-revealjs' (3)
}
1 Always specify a GEM proxy. In this case use the internal proxy to https://rubygems.org.
2 Specify GEMs as per usual.
3 Add the GEM to the project-wide (or task-specific) list of requires.
build.gradle.kts
plugins {
    id("org.asciidoctor.jvm.gems") version "4.0.2"
}

Adding Custom Extensions

Starting with version 1.5.0 you were able to write your own Asciidoctor extensions in Groovy, or any other JVM language for that matter. Now with the 2.0.0 you have even more flexibility in that extensions can be applied on a per task basis on globally. There are several options available to make it happen.

As External Library

This is the most versatile option, as it allows you to reuse the same extension in different projects. An external library is just like any other Java/Groovy project. You simply define a dependency using the asciidoctor configuration.

build.gradle
configurations {
    asciidoctorExt
}

dependencies {
    asciidoctorExt 'com.acme:asciidoctor-extensions:x.y.z'
}

asciidoctor {
    configurations 'asciidoctorExt'
}
build.gradle.kts
val asciidoctorExt by configurations.creating

dependencies {
    asciidoctorExt("com.acme:asciidoctor-extensions:x.y.z")
}

tasks.withType<AsciidoctorTask> {
   configurations("asciidoctorExt")
}

As Project Dependency

The next option is to host the extension project in a multi-project build. This allows for a much quicker development cycle as you don’t have to publish the jar to a repository every time you make adjustments to the code. Take for example the following setup:

.
├── build.gradle
├── core
│   ├── build.gradle
│   └── src
│       ├── asciidoc
│       │   └── index.adoc
│       └── main
│           └── java
├── extension
│   ├── build.gradle
│   └── src
│       └── main
│           ├── groovy
│           │   └── org
│           │       └── asciidoctor
│           │           └── example
│           │               ├── ExampleExtensionRegistry.groovy
│           │               └── YellBlock.groovy
│           └── resources
│               └── META-INF
│                   └── services
│                       └── org.asciidoctor.extension.spi.ExtensionRegistry
└── settings.gradle

The extension project is a sibling for core. The build file for the latter looks like this:

build.gradle
plugins {
   id 'org.asciidoctor.jvm.convert' version '4.0.2'
}

repositories {
    jcenter()
}

configurations {
    asciidoctorExtensions
}

dependencies {
    asciidoctorExtensions project(':extension')
}

asciidoctor {
    configurations 'asciidoctorExtensions'
}

Alternatively you can add the project to the extension directly

build.gradle
plugins {
   id 'org.asciidoctor.jvm.convert' version '4.0.2'
}

asciidoctorj {
    docExtensions project(':extension')
}

In the less-common case where extension is not supplied via the default configuration, the latter shortcut will not work, and you will need to use the longer method described above.

As Inline Script

The next option is to define extensions directly in the build script. This approach is based on the project asciidoctorj-groovy-dsl that allows to define Asciidoctor extensions in Groovy. An extension is registered via the docExtensions element.

build.gradle
asciidoctorj {
    docExtensions {
        block(name: "BIG", contexts: [":paragraph"]) {
            parent, reader, attributes ->
            def upperLines = reader.readLines()
                .collect {it.toUpperCase()}
                .inject("") {a, b -> a + '\n' + b}

            createBlock(parent, "paragraph", [upperLines], attributes, [:])
        }
    }
}

http://github.com/asciidoctor/asciidoctorj-groovy-dsl contains a description of the DSL itself.

Groovy extensions can also be included as files.

build.gradle
asciidoctorj {
    docExtensions file('big.groovy')
}
big.groovy
block(name: "BIG", contexts: [":paragraph"]) {
    parent, reader, attributes ->
    def upperLines = reader.readLines()
        .collect {it.toUpperCase()}
        .inject("") {a, b -> a + '\n' + b}

    createBlock(parent, "paragraph", [upperLines], attributes, [:])
}

Working with Asciidoctor.js instead

Instead of AsciidoctorJ, Asciidoctor.js can be used as a rendering engine as from 3.0.

The configuration follows much the same as for AsciidoctorJ, but will a couple of differences.

  • Only HTML is supported out of the box

  • The configurating extension is called asciidoctorjs and is available at both task and project level.

  • Docbook must be enabled via asciidoctorjs.modules.docbook.use().

  • The implementation runs node.js under the hood, but the user does not have to install anything. The plugin suite takes care of everything.

  • Additional NPM modules can be added via asciidoctorj.require.

The Asciidoctor Editor Config Plugin

build.gradle
plugins {
    id 'org.asciidoctor.editorconfig' version '4.0.2'
}
build.gradle.kts
plugins {
    id("org.asciidoctor.editorconfig") version "4.0.2"
}

Writes an .asciidoctorconfig file so that supporting IDEs can render Asciidoctor-based documentation correctly.

Adding attributes

asciidoctorEditorConfig {
  attributes foo1: 'bar1', foo2: 'bar2' (1)

  additionalAttributes asciidoctorj (2)

  additionalAttributes 'src/docs/asciidoc/attributes.adoc' (3)
}
1 Adds predefined attributes. These attributes are added first to the generated file.
2 Adds all attributes defined on the project extension to the generated file. These attributes are added after the predefined attributes.
3 Appends the context of the specified file to the generated file. Context such as this is added last. This method also allows you to define a number of attributes in your source directory and include them in your main Asciidoc file as well as send them to .asciidoctorconfig.

Changing the output directory

asciidoctorEditorConfig {
  destinationDir = 'docs'
}

Extra content for HTML & Docbook backends

You may need to include extra content into the head of the exported document. For example, you might want to include jQuery inside the <head> element of the HTML export. To do so, first create a docinfo file in your source directory i.e. src/docs/asciidoc/docinfo.html containing the content to include, in this case the <script> tag to load jQuery.

src/docs/asciidoc/docinfo.html
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.js"></script>

Then, add the docinfo1 attribute to the attributes list in the previous example:

build.gradle
asciidoctorj { (1)
    attribute 'docinfo1', ''
}
1 Substitute asciidoctorjs if you are using the Asciidoctor.js engine.

See Asciidoctor User Manual for more information on docinfo and friends.

Upgrading From Older Versions of Asciidoctor

If you are still on a 1.5/1.6 version of the plugin, upgrade to the latest 2.x version first.

If you are on 2.x version, upgrade to the latest 2.x first and ensure that you have corrected all of the deprecation warnings.

If you have AsciidoctorJ binary extensions you’ll need to recompile them against AsciidoctorJ v2.0+ in order to use them with the v.3x version of the plugins.

Old name

New name

Substituable

Usage

projectdir

gradle-projectdir

No

The Gradle project directory which is running the Asciidoctor task.

rootdir

gradle-rootdir

No

The rootproject directory in a multi-project build.

project-name

gradle-project-name

Yes

The name of the current Gradle subproject. (Or the root project in case of a single project).

project-group

gradle-project-group

Yes

The project/artifact group if it is defined.

project-version

revnumber

Yes

The project version if it is defined.

-

gradle-relative-srcdir

No

The relative path from the parent of the current document that is being processed to the source document root. It is calcluated as moving from the current document towards the root. For instance src/docs/asciidoc/subdir/sample.adoc will set this attribute to .. if sourceDir == src/docs/asciidoc.

Substitutable attributes means that the build script author can change those attributes by setting them explicitly.

Asciidoctor compatibility tasks

The Asciidoctor compatibility task has been removed. You need to use the Asciidoctor task from org.asciidoctor.jvm.convert instead.

GEMs

If you used external GEMs via the JRuby Gradle plugin, you should switch over to using org.asciidoctor.jvm.gems instead. You should also use the asciidoctorGems configuration rather than the gems configuration. Tasks should not depend on JRubyPrepare, but on AsciidoctorGemsPrepare instead.

If you have the following in your build

plugins {
    id 'org.asciidoctor.jvm.gems' version '2.4.1'
    id 'com.github.jruby-gradle.base' version '1.7.0'
}

repositories {
    rubygems('https://rubygems.org')
}

then change it to

plugins {
    id 'org.asciidoctor.jvm.gems' version '4.0.2'
}

repositories {
    ruby.gems()
}

Reveal.js

Follows the same guidelines as for GEMS above.

Configurations

The asciidoctor configuration is no longer available. If you used that before to make artifacts available on the classpath you should use the configurations method on the task to add them. If you used it to manipulate versions of AsciidoctorJ and JRuby then you should rather use the explicit versions settings on asciidoctorj.

Multiple Asciidoctor tasks

If you have more than one Asciidoctor task, decide which options, attributes and requires should go in the asciidoctorj global project extension block and which should be customised within the tasks asciidoctor extension block.

Importantly, you probably did import org.asciidoctor.gradle.AsciidoctorTask. You will need to change that to import org.asciidoctor.gradle.jvm.AsciidoctorTask.

Extensions

Extensions on the Gradle classpath are no longer detected. You need to declare them explicitly. This includes any extensions created in buildSrc.

Appendix A: Tips & Tricks

Issues with plugins that modify project.version

Plugins such as Nebula Release and Reckon modify project.version with a non-serialisable object. This breaks the build.

The safest workaround is to set the revnumber attribute to a delayed evaluation of project.version in your build:

asciidoctorj {
    attributes revnumber : { project.version.toString() }
}

Pre-process and post-process

To make your own custom actions before or after asciidoctor processing, use doFirst and doLast. Check out chapters 14 and 17 in the Gradle docs to learn about the various actions you can perform.

build.gradle
asciidoctor.doFirst {
  // pre-process
}
asciidoctor.doLast {
  // post-process
}

As an example, here’s how to copy the generated index.html file to the root of the project. This is useful in Windows systems where asciidoctor can’t output directly to the root.

build.gradle
asciidoctor.doLast {
    copy {
        from 'build/docs/html5'
        into "$projectDir"
        include 'index.html'
    }
}

Using Pygments source highlighter

You need to have Python 2.x installed on a system or in a container for Pygments to work.
plugins {
  id 'org.asciidoctor.jvm.pdf' version '4.0.2'
  id 'org.asciidoctor.jvm.gems' version '4.0.2'
}

repositories {
    jcenter()
    ruby.gems()
}

dependencies {
  asciidoctorGems 'rubygems:pygments:1.2.1'
}

asciidoctorPdf {
  dependsOn asciidoctorGemsPrepare
  sourceDir 'docs'

  asciidoctorj {
    requires 'pygments'
    attributes 'source-highlighter' : 'pygments'
  }
}

Appendix B: Known Issues

These are the main ones we know about:

  • EPUB3 + KF8 in one task. Both formats in one task is currently failing. The exact failure message depends on which order (KF8+EPUB3 or EPUB3+KF8) the conversion takes place in.

  • KF8 conversions fails under Windows. (Related to AsciidoctorJ #659 & JRuby #4943.

  • Does not work with JDK9 (but does with JDK10).

  • DeckTape export to JPG/PNG does not work on Windows (issues-asciidoctorj}[AsciidoctorJ #381] & Decktape #181).

Appendix C: Development

The master branch represents the code for the latest 2.x release of these plugins. Development for for 2.x is against the development-2.0 branch. PRs are preferably taking against that branch. The 1.5.x & 1.6.x series of the plugin is now in maintenance only mode. PRs for these should be raised against the maintenance-1.5 and maintenance-1.6branch.