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.
configurations {
asciidoctorExt
}
dependencies {
asciidoctorExt 'com.acme:asciidoctor-extensions:x.y.z'
}
asciidoctor {
configurations 'asciidoctorExt'
}
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:
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
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.
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, [:])
}
}
}
github.com/asciidoctor/asciidoctorj-groovy-dsl contains a description of the DSL itself.
Groovy extensions can also be included as files.
asciidoctorj {
docExtensions file('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, [:])
}