I am born in 1973 and live in Tilburg, the Netherlands, with my beautiful wife and three gorgeous children. I am also known as mrhaki, which is simply the initials of his name prepended by mr. The following Groovy snippets shows how the alias comes together:

(How cool is Groovy that we can express this in a simple code sample ;-) )

I studied Information Systems and Management at the Tilburg University. After finishing my studies I started to work at a company which specialized in knowledge-based software. There I started writing my first Java software (yes, an applet!) in 1996. Over the years my focus switched from applets, to servlets, to Java Enterprise Edition applications, to Spring-based software.

In 2008 I wanted to have fun again when writing software. The larger projects I was working on were more about writing configuration XML files, tuning performance and less about real development. So I started to look around and noticed Groovy as a good language to learn about. I could still use existing Java code, libraries, and my Groovy classes in Java. The learning curve isn’t steep and to support my learning phase I wrote down interesting Groovy facts in my blog with the title Groovy Goodness. I post small articles with a lot of code samples to understand how to use Groovy. Since November 2011 I am also a DZone Most Valuable Blogger (MVB); DZone also posts my blog items on their site.

I have spoken at the Gr8Conf Europe and US editions about Groovy, Gradle, Grails and Asciidoctor topics. Other conferences where I talked are Greach in Madrid, Spain, JavaLand in Germany and JFall in The Netherlands.

I work for a company called JDriven in the Netherlands. JDriven focuses on technologies that simplify and improve development of enterprise applications. Employees of JDriven have years of experience with Java and related technologies and are all eager to learn about new technologies.

## Introduction

When I started to learn about Asciidoctor I wrote done little code snippets with features of Asciidoctor I found interesting. To access my notes from different locations I wrote the snippets with a short explanation in a blog: Messages from mrhaki. I labeled the post as Awesome Asciidoctor, because I thought this is awesome stuff, and that is how the Awesome Asciidoctor series began.

A while ago I bundled all my blog Groovy Goodness blog posts in a book published at Leanpub. Leanpub is very easy to use and I could use Markdown to write the content, which I really liked as a developer. So it felt natural to also bundle the Grails Goodness blog posts and Gradle Goodness blog posts at Leanpub.

In this book the blog posts are bundled and categorized into sections. Within each section blog posts that cover similar features are grouped. The book is intended to browse through the subjects. You should be able to just open the book at a random page and learn more about Asciidoctor. Maybe pick it up once in a while and learn a bit more about known and lesser known features of Asciidoctor.

## Tables

### Changing Table and Column Width

When we define a table in Asciidoctor the columns all have the same width and the table will the whole width of the page. Of course we can change this when we define the table. We can change the table width with the width attribute. We specify the column width with the cols attribute.

First we will change the width of the columns. We can specify proportional integer values or a percentage to specify the width of a column. In the following sample Asciidoctor file we use proportional values in the first table. The first column has value 1 and the second column value 3. This means the second column should be 3 times as wide as the first column. In the second table the column width is defined with percentage values. The first column should occupy 60% of the table width and the last column the rest.

When we transform the Asciidoctor source to HTML we get the following result:

We see in the examples that the width of the table is the same as the width of the page. To make a smaller table we set the width attribute for a table. The value must be a percentage. Let's create a sample Asciidoctor file and define a table with a width of 50%:

And if we look at the generated HTML for example we can see the second table is half the width of the first:

Written with Asciidoctor 1.5.1.

Original post written on November 7, 2014

### Table Column and Cell Alignment

Creating a table with Asciidoctor is a breeze. The syntax is very clear and the HTML output shows a very nice looking table. But there is also a lot of configuration we can do when we define a table. For example by default all columns are left aligned, but we can change this to have values centered or right aligned in columns. We can even set the vertical alignment for columns. And if this is not enough we can change the horizontal and vertical alignment per cell.

Let's start with a simple table with three columns. We want the first column to be centered, the middle column to be left aligned and the last column should be right aligned. To achieve this we must configure the cols attribute for our table definition. We use the following symbols to define the alignment:\

• <: left align values (default)
• >: right align values
• ^: center values

We create a new Asciidoctor file with the following contents:

When we create HTML output from this source we get the following output:

We have now defined the horizontal alignment. To include vertical alignment we must add dot (.) to the horizontal alignment value and then the vertical alignment value. The following vertical alignment values can be used:\

• <: top align values (default)
• >: bottom align values
• ^: center values

In the following sample Asciidoctor file we add vertical alignment configuration to our previous table:

We get the following HTML table when we process that source file:

Finally we can alter the horizontal and vertical alignment per cell. We use the alignment configuration symbols before the pipe symbol (|) of a cell definition. This overrules any alignment configuration set in the cols definition. In the next Asciidoctor file we combine all these settings for a table:

And when we look at the output we see all alignment configuration applied to our table:

Written with Asciidoctor 1.5.0.

Original post written on November 6, 2014

### Changing Table and Column Width

When we define a table in Asciidoctor the columns all have the same width and the table will the whole width of the page. Of course we can change this when we define the table. We can change the table width with the width attribute. We specify the column width with the cols attribute.

First we will change the width of the columns. We can specify proportional integer values or a percentage to specify the width of a column. In the following sample Asciidoctor file we use proportional values in the first table. The first column has value 1 and the second column value 3. This means the second column should be 3 times as wide as the first column. In the second table the column width is defined with percentage values. The first column should occupy 60% of the table width and the last column the rest.

When we transform the Asciidoctor source to HTML we get the following result:

We see in the examples that the width of the table is the same as the width of the page. To make a smaller table we set the width attribute for a table. The value must be a percentage. Let's create a sample Asciidoctor file and define a table with a width of 50%:

And if we look at the generated HTML for example we can see the second table is half the width of the first:

Written with Asciidoctor 1.5.1.

Original post written on November 7, 2014

### Span Cell over Rows and Columns

When we define a table in Asciidoctor we might want to span a cell over multiple columns or rows, instead of just a single column or row. We can do this using a cell specifier with the following format: column-span.row-span+. The values for column-span and row-span define the number of columns and rows the cell must span. We put the cell specifier before the pipe symbol (|) in our table definition.

In the following example Asciidoctor markup we have three tables. In the first table we span a cell over 2 columns, the second table spans a cell over 2 rows and in the final table we span a cell over both 2 columns and rows.

If we transform our source to HTML we get the following tables:

Written with Asciidoctor 1.5.1.

Original post written on December 4, 2014

### Repeating Cell Contents

With Asciidoctor we can repeat cell contents if we prefix the cell separator pipe symbol (|) with the number of times we want to repeat the cell followed by an asterisk (*).

In the following example Asciidoctor source file we define two tables and add 2* to cells that we want to repeat two times:

When we generate a HTML document from this source we see the following result:

Written with Asciidoctor 1.5.1.

Original post written on December 2, 2014

### Using Asciidoc in Tables

When we define a table in Asciidoctor and want to use Asciidoc in a table cell it is not interpreted as Asciidoc by default. The text is literally shown and this might not be what we expect. But we can force Asciidoctor to interpret the cell contents as Asciidoctor.

Let's start with a very simple table. The last cell of the first row contains some Asciidoc markup:

When we transform this Asciidoctor source to HTML we see the following output:

Notice that we don't get a nice image for our NOTE is not shown as image when it used in a table cell.

To change this behavior we can configure the table. We can configure a column to have Asciidoc content that needs to be interpreted or we can configure at cell level we want the contents to be interpreted as Asciidoc. We use the character a in the cols attribute when we define the table. Or we use the character a before the table cell separator (|). In the next sample Asciidoctor file we use both ways to make sure the cell contents is Asciidoc markup that needs to be transformed as well:

Once we have defined the table we get the following generated HTML:

And this time the cell contents is transformed as well.

Written with Asciidoctor 1.5.1.

Original post written on November 10, 2014

### Styling Columns and Cells in Tables

In a previous post we learned how to use Asciidoc markup in a table. The a character is just one of many styles we can define in our table. In this blog post we see which style options we have. We can either use the cols attribute to define a style for a whole column or specify per cell the style.

We can use the following styles:\

• e: emphasized
• a: Asciidoc markup
• m: monospace
• h: header style, all column values are styled as header
• s: strong
• l: literal, text is shown in monospace font and line breaks are kept
• d: default
• v: verse, keeps line breaks

The following Asciidoctor source uses the different styles as cols attribute values:

When we transform this into HTML using the Asciidoctor HTML backend we get the following result:

We can also override a column styling per cell. We must put the correct styling character before the pipe symbol (|), so the contents of the cell is styled differently:

And the following HTML is generated when we process this Asciidoctor source:

Written with Asciidoctor 1.5.1.

Original post written on November 10, 2014

### Nested Tables

Defining tables in Asciidoctor is very easy. The start and end of the table are defined by |===. But if we want to add a new table to a table cell we cannot use the same syntax. To define a nested table we must replace the | separator with !. So instead of |=== to indicate the table boundaries we use !===. Also the cell separators are now ! instead of |. Finally we must make sure the table cell or column supports Asciidoc markup, so the table is properly created. We must configure the cell or column with a so the nested table is created.

In the following example Asciidoctor markup we have a simple table with a nested table in the second column and row. Notice we can still apply all table configuration to the nested table as well:

When we run Asciidoctor to create HTML for this markup we get the following result:

Written with Asciidoctor 1.5.5.

Original post written on April 26, 2017

### Escaping Pipe Symbol in Tables

To define a table in Asciidoc is easy. Table cells are separated basically by pipe symbols (|). But if we want to use a pipe-symbol as cell content we need to escape the pipe-symbol with a backslash (\)

The following Asciidoc code is transformed to a correct HTML table output:

The generated HTML table looks like this for example:

Generated with Asciidoctor 0.1.4.

Original post written on June 4, 2014

### CSV and DSV Tables

With Asciidoctor we can create tables where the header and rows are in CSV (Comma Separated Values) and DSV (Delimiter Separated Values) format. Normally we use a pipe-symbol (|) to separate cell values. This is actually PSV (Prefix Separated Values) :-).

In the following Asciidoctor markup we create a very simple table with a header and two rows using CSV:

We generate this into HTML and we get the following result:

Asciidoctor provides also another way to define the above table:

The previous samples used a comma to separate values, but we can also use colon (:). The next sample contains tables defined with DSV:

With the include directive we can also include data from an external CSV of DSV file to create a table (of course also the traditional pipe-symbol separated format can be in an external file):

The file tools.cv has the following contents:

Code written with Asciidoctor 1.5.0.

Original post written on November 5, 2014

### Using Tab Separated Data In A Table

In a previous post we learned how to use data in CSV and DSV format. Recently we can also include tab separated values (TSV) in a Asciidoctor table. We must set the table attribute format to the value tsv. The data can be inside the document, but also defined in an external file which we add with the include macro.

In the following example markup we have a table with inline tab separated values. A second table includes an external file with tab delimited values:

When we convert our Asciidoctor markup to HTML we get the following result:

Written with Asciidoctor 1.5.6.1.

Original post written on October 5, 2017

## Blocks

### Using Filename Starting With Dot As Block Title

Adding a block title in Asciidoctor is easily done by adding a line at the top of the block that starts with a dot (.). The text following the dot is then used as the title of the block. But if the text of the title itself starts with a dot (.) Asciidoctor get's confused. For example if we want to use a filename that starts with a dot (.filename) we must use different syntax to set the block title with the filename.

In the next Ascciidoc markup sample we use different ways to set the block title for a code block with a filename that starts with a dot. First we use the title attribute for the block. Another solution is to use the Unicode value for the dot. Next we enclose the filename in back ticks () which also formats the filename with a monotype font. We can also separate the first dot with the dotted filename with the document attribute {blank}. Also we can define the dot as document attribute and use it in the title. And finally we can define the filename via a document attribute and reference the document attribute in the block title:

When we generate a HTML version of this markup we get the following result:

Written with Asciidoctor 1.5.4

Original post written on January 2, 2017

### Nested Delimited Blocks

In our Asciidoc markup we can include delimited blocks, like sidebars, examples, listings and admonitions. A delimited block is indicated by a balanced pair of delimiter characters. For example a sidebar starts and ends with four asterisk characters (****). If we want to nest another delimited block of the same type we must add an extra delimiter character at the start and end of the nested block. So when we want to nest another sidebar block inside an existing sidebar block we must use five asterisk characters (*****).

In the following example Asciidoc source we have several blocks with nested blocks:

If we transform this to HTML we get the following result:

Written with Asciidoctor 1.5.2.

Original post written on December 11, 2014

### Use Captions For Listing Blocks

Asciidoctor has some built-in attributes to work with captions for certain content blocks. For example the table-section attribute defines the caption label (by default Table) that is prefixed to a counter for all tables in the document. When we transform our markup Asciidoctor will insert the text Table followed by the table number. By default the caption for listing blocks is disabled, but we can easily enable it with the listing-caption attribute.

In the following markup we enable the caption for listing blocks and set the value to Listing. This will add the text Listing followed by the listing section counter to the output.

When we generate the HTML for this markup we see the caption for the two listing blocks:

To disable the listing captions we must negate the document attribute: :!listing-caption:.

Written with Asciidoctor 1.5.4.

Original post written on September 26, 2016

### Do Not Wrap Lines in Listing or Literal Blocks

When we use listing or literal blocks in our Asciidoc markup long lines will be wrapped if needed in the generated output. We can use the options attribute with a nowrap value to have horizontal scrolling instead of wrapped lines. This applies for the HTML backend when we generate the documentation.

In the following markup we first use the default wrapping of lines:

If we generate HTML we get the following output:

If we set the options attribute with the value nowrap the long lines are no longer wrapped and we get a horizontal scrollbar to see the complete code listing:

The following screenshot shows a horizontal scrollbar when we want to see the rest of the line:

Written with Asciidoctor 0.1.4.

Original post written on June 11, 2014

### Don't Wrap Lines in All Listing or Literal Blocks of Document

In a previous post we learned about setting the value of options attribute to nowrap on listing and literal blocks, so the lines in the block are not wrapped. In the comments a user suggested another option to disable line wrapping for all listing and literal blocks in the document by using the document attribute prewrap. We must negate the document attribute, :prewrap!:, to disable all wrapping. If we place this document attribute at the top of our Asciidoctor document it is applied for the whole document. We can also place it at other places in the document to change the setting for all listing and literal blocks following the prewrap document attribute. To enable wrapping again we set :prewrap: (leaving out the exclamation mark).

In the following example we have markup with a listing, literal and example block and we use the document attribute :prewrap!: to disable the wrapping for the listing and literal blocks:

When we create HTML from this markup we get the following output:

The code in the listing and literal blocks is now not wrapped, but continues on the same line.

Written with Asciidoctor 2.0.2.

Original post written on May 22, 2019

### Include Asciidoc Markup With Listing or Literal Blocks Inside Listing or Literal Block

If we want to include Asciidoc markup as source language and show the markup without transforming it we can use a listing or literal block. For example we are using Asciidoc markup to write a document about Asciidoctor and want to include some Asciidoc markup examples. If the markup contains sections like a listing or literal block and it is enclosed in a listing or literal block, the tranformation goes wrong. Because the beginning of the included listing or literal block is seen as the ending of the enclosing listing or literal block. Let's see what goes wrong with an example where we have the following Asciidoc markup:

When we transform this to HTML we get the following output:

We can use nested listing or literal blocks where we have to add an extra hyphen or dot to the nested block, but then the Asciidoc markup we want to show as an example is not correct anymore. It turns out we can also add an extra hyphen or dot to the enclosing listing or literal block to transform our markup correctly. So in our example we add an extra hyphen to the outer listing block:

The transformed HTML looks like this:

If our sample markup we want to show only contains a listing block we could have enclosed it in a literal block to get the same result or sample markup of a literal block could be in a listing block.\ But in our example we have both a listing and literal block so we needed another solution to get the desired result.

Written with Asciidoctor 2.0.9.

Original post written on May 24, 2019

### Collapsible Content

Since Asciidoctor 2.0.0 we can add the collapsible option to an example block. When the markup is generated to HTML we get a HTML details and summary section. The content of the example block is collapsed (default behaviour because it is in a details section) and a clickable text is available to open the collapsed block (the summary section), so we can see the actual content. The text we can click on is by default Details, but we can change that by setting the title of the example block. Then the title is used as the text to click on to open the collapsed content.

The following example markup has two collapsible blocks with and without a title:

When we generate this markup to HTML we get the following result:

And when we expand the collapsible content we see:

Written with Asciidoctor 2.0.2.

Original post written on March 28, 2019

## Lists

### Change Number Style For Ordered Lists

To write a (nested) ordered lists in Asciidoctor is easy. We need to start the line with a dot (.) followed by a space and the list item text. The number of dots reflects the levels of nesting. So with two dots (..) we have a nested list item. By default each nested level has a separate numbering style. The first level has arabic numbering, the second lower case alphanumeric, the third upper case alphanumeric, the fourth lower case roman and the fifth (which is maximum depth of nested levels in Asciidoctor) has style upper case roman. But we can change this by setting a block style for each nested level block. The name of the block style is arabic, loweralpha, upperalpha, lowerromann or upperroman. With the HTML5 backend we can also use decimal and lowergreek.

In the following example we have an ordered list where we set different block styles for the nested level:

When we create the HTML output we have the following result:

Written with Asciidoctor 1.5.4.

Original post written on December 13, 2016

### Creating a Checklist

Creating a list with Asciidoctor markup is easy. To create an unordered we need to start a line with an asterisk (*) or hypen (-). We can add some extra markup to create a checked list. If we add two square brackets ([]) to the list item we have a checklist. To have an unchecked item we use a space, for a checked item we can use a lowercase x (x) or an asterisk (*).

In the next example we define a shopping cart list with Asciidoctor markup:

When we create the HTML file we get the following output:

If we use font-based icons with the document attribute :icons: font the checkboxes are rendered using fonts:

The checkboxes are now simply output in the HTML file. We can add an options attribute to our list to make the checkboxes interactive:

If we transform this markup to HTML we see the following in our web browser:

Written with Asciidoctor 1.5.2.

Original post written on March 2, 2015

### Change Start Number for Numbered List

With Asciidoctor we can create numbered lists easily. When we want to change the number the list starts with we use the start attribute when we define the list.

We get the following HTML output when we transform the document:

Written with Asciidoctor 1.5.2.

Original post written on February 26, 2015

### Using Paragraphs in Lists With List Item Continuation

When we write a list in Asciidoctor we can simply create a list item by starting the line with a dot (.). To create a another list item we simply start a new line with a dot (.). But what if we want to add a list item with multiple paragraphs, or text and a source code block element. We can use the list item continuation (+) to indicate to Asciidoctor we want to keep these together for a single list item.

In the following example we have a list in Asciidoctor markup. The second list item has multiple paragraphs , the third item has an extra admonition block and the fourth item contains a source code block:

Let's generate this Asciidoctor markup to HTML and we see the following result:

We see how the extra paragraph, admonition and source code are part of a single list item.

Written with Asciidoctor 1.5.6.1.

Original post written on October 3, 2017

### Use Only Block As List Item

When we define a list in Asciidoctor we usually have a list item that is a paragraph. But if we want to have a block as list item we need to add an extra {blank} element to make sure the block is parsed correctly as list item. Because a list item starts with a . or a * at the beginning of a line and a block also is defined on the beginning of the line, we must add the extra {blank} element. Together with the list item continuation (+) we can have a list with blocks.

In the following example we define a numbered list with three listing blocks:

When we generate a HTML version we get the following result:

Written with Asciidoctor 1.5.6.1.

Original post written on October 16, 2017

## Source code

### Change Source Code Indentation

Writing documentation and including source files is made very easy in Asciidoc and Asciidoctor. We can use the include macro to include a source file in our documentation. This way we can write source code, test the code (preferable automated) and the code in our documentation always works and will be up to date. We can use the indent attribute when we include source code to change the indentation. Tab characters are replaced with 4 spaces when we use the indent attribute. We can specify the number of spaces the code needs to be indented with a value of 0 or greater.

The following sample Asciidoc markup will remove all indentation of the original code block which is indented with 4 spaces, because we use the value 0:

If we generate HTML we get the following result:

The code still looks indented, but that is done via CSS styling. The padding is set to a value greater than 0, but we can change that of course with our own CSS stylesheet.

In the following sample we set the indent attribute with the value 8:

We get the following result:

In the final sample we use the include macro to include source code. We can still use the indent attribute like we did with the inline code samples:

Here is the resulting HTML:

Code written with Asciidoctor 0.1.4.

Original post written on June 10, 2014

### Adding Line Numbers to Source Code Listings

When we write technical documentation with Asciidoctor we can easily include source code listings. When we use the coderay or pygments source code highlighter we can also include line numbers. We must add the attribute linenums to the listing block in our markup. This attribute is used by the source highlighters to create and format the line numbers. We can specify that the line numbers must be generated in table mode or inline mode. When the line numbers are in table mode we can select the source code without the line numbers and copy it to the clipboard. If we use inline mode the line numbers are selectable and are copied together with the selected source code to the clipboard. To specify which mode we want to use for the line numbers we use the document attribute coderay-linenums-mode or pygments-linenums-mode depending on the source highlighter we use. We can use the values table (default) or inline.

Let's generate HTML output from this markup and use different values for the source-highlighter and ...-linenums-mode attributes. First we use the Coderay source highlighter in table mode:

If we use inline mode (:coderay-linenums-mode: inline), we can see the line numbers are selected as well when we select the source code:

The following screenshots use the Pygments source highlighter with first a table mode for the line numbers and then inline mode:

Written with Asciidoctor 1.5.0.

Original post written on August 13, 2014

### Include Partial Parts from Code Samples

Writing technical documentation with Asciidoc and Asciidoctor is so much fun. Especially the include macro makes inserting changing content, like source files, a breeze. We only need to maintain the original source file and changes will automatically appear in the generated documentation. We can include only a part of source file using tags. In the source file we add a comment with the following format tag::tagName[] to start the section. We end the section with end::tagName[]. Now in our Asciidoc document we can indicatie the tags we want to include with include::sourceFile[tags=tagName].

Suppose we have the following Groovy source file Sample.groovy. We want to include the method hello() in our technical documentation:

In our Asciidoc document we use the following syntax to include only the hello() method:

This will result in the following HTML if we use Asciidoctor with the pretty-print syntax highlighter:

Written with Asciidoctor 0.1.4.

Original post written on April 30, 2014

### Include Only Certain Lines from Included Files

In a previous post we learned how to include partial content from included files. We needed to enclose the content we want to include between start and end tags and reference those tags in our documentation markup. But Andres Almiray already mentioned in a tweet we can use line numbers as well:

@marcovermeulen @rfletcherew @mrhaki you can also use -1 in the include range, like this https://t.co/J4tohY4cp3

— Andres Almiray (@aalmiray) June 6, 2014

\

Let's see this in action in our Asciidoc markup. We can use the include macro and specify the lines we want to include with the lines attribute. We can include multiple lines by specifying a range (1..10), or separate different line sections with a ;. To indicate we want to include lines from a starting line up until the end of the file we can use -1 to indicate the end of the file.

Here is the source of the file we want to include:

And when we generate an HTML version of our markup we see that only part of the original source file is included in the output:

Written with Asciidoctor 0.1.4.

Original post written on August 5, 2014

### Explain Code with Callouts

Writing documentation with Asciidoc is such a treat. We can add markers to our code where we want to explain something in our code. The markers have numbers and are enclosed in < and > brackets. The explanation for the markers follows a code listing in a callout list. Here we use the same marker and add extra text to explain the code. We can put the markers in comments in our code so we can use the markers in existing code.

Suppose we have the following piece of documentation where we add two markers (in comments) to some Groovy source code:

When we generate this into an HTML document with the prettify syntax highlighter and icon font we get the following output:

Original post written on May 5, 2014

### Highlight Lines In Source Code Listings

In Asciidoctor we can configure syntax highlighting for our source code listings. We can choose from the built-in support for Coderay, Pygments, highlight.js and prettify. The syntax highlighter libraries Coderay and Pygments support extra highlighting of lines, so we can add extra attention to those lines. In this post we see how to use the line highlighting feature in Asciidoctor.

First we must add the document attribute source-highlighter and use the value coderay or pygments. When we use Coderay we must also enable the line numbers for the source code listing, because Coderay will highlight the line numbers in the output. Pygments highlight the whole line, with or without line numbers in the output. Therefore we choose Pygments in our example. To highlight certain lines in the source code output we use the highlight attribute for the source code block. We can specify single line numbers separated by a comma (,) or semi colon (;). If we use a comma we must enclose the value of the highlight attribute in quotes. To define a range of line numbers we can define the start and end line numbers with a hyphen in between (eg. 5-10 to highlight lines 5 to 10). To unhighlight a line we must prefix it with a exclamation mark (!). For example the following value for the highlight attribute highlights the lines 2, 3 to 7 and not 5: [source,highlight=1;3-7;!5].

In the following example markup we have a source code block where we highlight the lines 7 to 9. We use Pygments as syntax highlighter:

If we look at the generated HTML we can see lines 7, 8 and 9 are differently styled:

Written with Asciidoctor 1.5.4.

Original post written on October 5, 2016

### Changing Highlight.js Theme

Asciidoctor is a great tool for writing technical documentation. If we have source code in the Asciidoc markup we can set the document attribute source-highlighter to pygments, coderay, prettify and highlightjs. When we use highlight.js we can also add an extra document attribute highlightjs-theme with the value of a highlight.js theme. If we do not specify the highlightjs-theme the default theme github is used.

We use the following Asciidoc markup to see how the HTML output is when we transform the markup using the HTML backend:

The following screenshots show the result of applying different themes:

For a complete list of all available themes checkout highlight.js on Github.\

If we use the Prettify source code highlighter we must use the prettify-theme document attribute.

Written with Asciidoctor 1.5.0.

Original post written on August 13, 2014

### Source Syntax Highlighting With Prism

Asciidoctor has built-in support for a couple of source syntax highlighting libraries like Coderay, Pygments, highlight.js and prettify. In this post we learn how to use the Javascript library Prism to do the syntax highlighting for our source blocks. Because Prism is a Javascript library we must remember this only works for the HTML backend of Asciidoctor.

In the following markup we have two source code listings in Java and Groovy:

Each source listing is transformed to HTML with the following structure:

This fits perfectly with Prism. Prism expects this format to apply the syntax highlighting. So we only have to add the Prism Javascript and CSS files to the generated HTML file. We download the Prism Javascript and CSS file from the Prism download site. We save the Javascript file as prism.js and the CSS file as prism.css. Next we create a docinfo.html to include a reference to the prism.css file:

We also create the file docinfo-footer.html to reference prism.js:

In our markup we have the document attribute docinfo1 set. This means the files docinfo.html and docinfo-footer.html are included in the generated HTML output. Let's see the result in a web browser:

Written with Asciidoctor 1.5.4.

Original post written on October 4, 2016

## Extensions

### Use Asciidoctor Diagram with Gradle

Since Asciidoctor 1.5.0 we can use extensions when we write AsciiDoc documents. These extensions can be written in Ruby or any JVM language. If we use Gradle and the Asciidoctor Gradle plugin to transform our documents we can use both extensions. Of course an extension written in for example Java or Groovy can be included as a regular dependency in our build configuration. As the extension is on the classpath of the asciidoctor task then it can be used. When the extension is a Ruby extension and available as a Ruby gem we need some more configuration in our build file. To use an Asciidoctor extension written in Ruby in our build we must first make sure that we can download the extension. Then we can configure the asciidoctor task from the Asciidoctor Gradle plugin to use the extension.

Let's start with a sample Asciidoctor document which uses the Asciidoctor Diagram extension. With this extension we can embed diagrams as text in our document and get graphical images as output.

Next we create our Gradle build file. We must apply the Asciidoctor Gradle plugin so we can transform our AsciiDoc documents. And we must apply the JRuby Gradle plugin so we can download Ruby gems and use them from the asciidoctor task. The JRuby plugin adds a gems dependency configuration, which we can use to define the Ruby gems we need. The task jrubyPrepareGems is also added by the plugin and this task will download the gems and extract them in our project build directory. In our asciidoctor task that is added by the Asciidoctor plugin we use the requires property to specify which gem is needed. We also set the gemPath property to the directory which contains the downloaded and extracted Ruby gems. The following build file defines the plugins and configures the tasks we need so we can use Asciidoctor Diagram:

To generate our sample document we only have to run $gradle from the command line. After the documents are generated we can the result in the build/asciidoc directory of our project. The following screenshot shows the generated HTML: Written with Asciidoctor 1.5.1 and Gradle 2.1. Original post written on November 12, 2014 ### Use Diagram Block Macro To Include Diagrams With the Asciidoctor diagram extension we can include diagrams that are written in plain text. For example PlantUML or Ditaa diagrams. The extension offers a block processor where we include the diagram definitions in our Asciidoctor document. But there is also a block macro processor. With the block macro processor we can refer to an external file. The file is processed and the resulting image is in our output document. In the following example we see how to use the block macro for a Ditaa diagram: The contents of sample.ditaa: When we create a HTML document from this Asciidoctor markup we get the following output: Written with Asciidoctor 1.5.6.1. Original post written on October 30, 2017 ### Write Extensions Using Groovy (or Java) We can write extension for Asciidoctor using the extension API in Groovy (or any other JVM language) if we run Asciidoctor on the Java platform using AsciidoctorJ. Extensions could also be written in Ruby of course, but in this post we see how to write a simple inline macro with Groovy. The extension API has several extension points (Source):\ • Preprocessor: Processes the raw source lines before they are passed to the parser\ • Treeprocessor: Processes the Document (AST) once parsing is complete\ • Postprocessor: Processes the output after the Document has been rendered, before it's gets written to file\ • Block processor: Processes a block of content marked with a custom style (i.e., name) (equivalent to filters in AsciiDoc)\ • Block macro processor: Registers a custom block macro and process it (e.g., gist::12345[])\ • Inline macro processor: Registers a custom inline macro and process it (e.g., btn:[Save])\ • Include processor: Processes the include::[] macro\ To write an extension in Groovy (or Java) we must write our implementation class for a specific extension point and we must register the class so AsciidoctorJ knows the class can be used. Registering the implementation is very simple, because it is using the Java Service Provider. This means we have to place a file in the META-INF/services directory on the classpath. The contents of the file is the class name of the implementation class. Let's start with the Asciidoc markup and then write an implementation to process the inline macro twitter that is used: To implement an inline macro we create a new class and extend InlineMacroProcessor. We override the process method to return the value that needs to replace the inline macro in our Asciidoc markup. We have the implementation class so now we can register the class with Asciidoctor. To register our custom extensions we need to implement the ExtensionRegistry interface. We implement the register method where we can couple our extension class to Asciidoctor. The class that registers our extension must be available via the Java Service Provider so it is automatically registered within the JVM used to run Asciidoctor. Therefore we need to create the file META-INF/services/org.asciidoctor.extension.spi.ExtensionRegistry with the following contents: We have taken all steps necessary to have our inline macro implementation. We must compile the Groovy classes and add those with the Java Service Provider file to the classpath. We can package the files in a JAR file and define a dependency on the JAR file in our project. If we use Gradle and the Gradle Asciidoctor plugin we can also add the source files to the buildSrc directory of our project. The files will be compiled and added to the classpath of the Gradle project. With the following Gradle build file we can process Asciidoc markup and execute the twitter inline macro. We store the source files in the buildSrc directory. The build file in the buildSrc directory has a dependency on AsciidoctorJ. This module makes it possible to run Asciidoctor on the JVM. Let's see part of the HTML that is generated if we transform the Asciidoc markup that is shown at the beginning of this blog post. The twitter inline macro is transformed into a link to the Twitter page of the user: Andres Almiray also wrote about writing extensions with Gradle. Written with Asciidoctor 1.5.0 and Gradle 2.0. Original post written on August 28, 2014 ### Use Inline Extension DSL with Gradle One of the great features of Asciidoctor is the support for extensions. If we want to have some special feature we want to use, but is not supported by Asciidoctor, we can add our own extension. On the Java platform we can write those extensions in for example Java and Groovy. When we use Gradle as the build tool with the Asciidoctor plugin we can write the code for the extension in our Gradle build file with the Groovy extension DSL. Suppose we want to write a new inline macro that will transform the following markup issue:PRJ-100[] into a link that points to the web page for issue PRJ-100. First we create our Asciidoctor source document: Now we write the following Gradle build file. First we include the Gradle Asciidoctor plugin. Then we can use the extensions configuration method to add our code for the inline macro. If we would write another type of extension we could still use the same place to add it, but then we don't use inlinemacro. Let's transform our sample Asciidoctor markup to HTML. We see the following result: The link that is generated is http://issue-server/browse/PRJ-100. Written with Gradle 2.3 and Asciidoctor 1.5.2. Original post written on March 4, 2015 ### Using Ruby Extensions With Asciidoctor Gradle Plugin Asciidoctor is a Ruby tool, but luckily we can use AsciidoctorJ to use Asciidoctor in Java code. The Asciidoctor Gradle plugin relies on AsciidoctorJ to run. AsciidoctorJ allows us to write custom extensions in Java (or Groovy), but we can still use Asciidoctor extensions written in Ruby with the Gradle plugin. In the following example we use the emoji-inline-macro from Asciidoctor extensions lab. This is an extension written in Ruby. We create a new directory for our sample and create a lib folder. Inside the lib directory we copy the file emoji-inline-macro.rb and the supporting directory emoji-inline-macro. These files are all in the Asciidoctor extensions lab repository. After we have copied the files we should have the following structure: In our build file we configure the asciidoctor task and use the requires method to define a dependency on the Ruby emoji-inline-macro.rb file: We are done. Next we create a sample Asciidoc markup document with the following content: We get the following HTML5 output when we run the asciidoctor task: Written with Asciidoctor Gradle plugin 1.5.3. Original post written on November 8, 2016 ## Miscellaneous ### Using Comments We can add comments to our Asciidoc markup. The comments will not be added to generated output. We can add both single and multiline comments in the markup. Single line comments start with a double slash (//). Multiline comments are enclosed in a block of four forward slashes (////). The following sample markup defines Asciidoc markup with comments: When we generate HTML output we don't see any of the comments, not even in the HTML source: Written with Asciidoctor 1.5.0. Original post written on August 12, 2014 ### Which Asciidoctor Version is Used? When we create documentation using Asciidoc and Asciidoctor we can access the built-in attribute asciidoctor-version to see which version of Asciidoctor is used to generate the documentation. We can reference built-in attributes like any other attributes, so we enclose the name of the attributes with curly braces ({attributeName}). In the following sample we simply print out the Asciidoctor version that was used to generate the content: And we get the following HTML content once we have generated HTML from our Asciidoc source code: Code written Asciidoctor 0.1.4. Original post written on June 4, 2014 ### Disable Last Updated Text in Footer When we transform our Asciidoc source files to HTML Asciidoctor will print the date and time the document was last updated in the footer. If we want to disable the Last updated text we disable the document attribute last-update-label. In the following example Asciidoc file we disable the Last update label in the footer:\ When we transform this to HTML we get the following output: Written with Asciidoctor 1.5.1. Original post written on November 26, 2014 ### Adding Custom Content to Head and Footer When we convert our Asciidoctor markup to HTML we automatically get a head and footer element. We can add custom content to the HTML head element and to the HTML div with id footer. We must set a document attribute and create the files that contain the HTML that needs to be added to the head or footer. We have three different document attributes we can set to include the custom content files: • :docinfo: include document specific content. Files to be included must be named <docname>-docinfo.html for head element and <docname>-docinfo-footer.html for footer content.\ • :docinfo1: include general custom content. Files to be included must be named docinfo.html for head element and docinfo-footer.html for footer content.\ • :docinfo2: include document specific and general custom content. Files to be included must be named <docname>-docinfo.html and docinfo.html for head element and <docname>-docinfo-footer.html and docinfo-footer.html for footer content.\ In this sample we create the files docinfo.html and docinfo-footer.html we want to include in the generated output from the following Asciidoctor source file: Our docinfo.html looks like this: For the custom footer we create the file docinfo-footer.html: The following screenshot shows the generated HTML page: And here is part of the generated head element: Written with Asciidoctor 1.5.2. Original post written on April 20, 2015 ### Include Raw HTML If we use the HTML backend with Asciidoc we can use a passthrough block to include raw HTML in the output. The contents of a passthrough block is untouched and will be put literally in the generated output. A passthrough block is enclosed in four plus signs (++++). In the following sample Asciidoc markup we include some Javascript: The generated HTML will execute the Javascript and we get the following output: We can also add raw HTML inline in our Asciidoc markup. We can enclose the HTML in triple plus signs (+++) or use the pass:[] macro. The following sample shows the markup where both methods are used: The generated HTML looks like this: Code written with Asciidoctor 0.1.4. Original post written on June 11, 2014 ### Use Inline Icons Asciidoctor adds the icon: macro to the Asciidoc markup. With the macro we can insert an icon in our text. We specify the name of the icon after the macro name. If we use an HTML backend together with the document attribute icons set to the value font we can use Font Awesome Icons. If we want to use icon images the icon is looked up in the directory specified by the attribute iconsdir. For example the Docbook backend will use this to insert an icon. In the following markup we use the icon macro to insert a comment and file icon: We get the following result: And the following HTML is generated: We can specify CSS classes using the role attribute for the macro. But together with the HTML backend and font-based icons we can also use other attributes: size, rotate and flip. The size attribute can specified without the attribute name if we use it as the first attribute: When we generate HTML we get the following result: When we want to use an inline icon as a link we can use the attributes link and window: Image based icons have the following attributes, like an image: alt, width, height, title, role. Code written and generated with Asciidoctor 0.1.4. Original post written on June 19, 2014 ### Changing the FontAwesome CSS Location To use font icons from FontAwesome we set the document attribute icons with the value font. The default link to the CSS location is https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css. We can change the location for the FontAwesome CSS with document attributes. If we want to use a different CDN to serve the CSS we can set the document attribute iconfont-cdn and set the URI as a value: To reference the FontAwesome CSS from a relative location from our generated HTML page we can first unset the attribute iconfont-remote and set the attribute iconfont-name: In the generated HTML source we see the following link element: Written with Asciidoctor 1.5.0. Original post written on August 15, 2014 ### Change URI Scheme for Assets When we define the document attribute icons with the value font the FontAwesome fonts are loaded in the generated HTML page. In the head section of the HTML document a link element to the FontAwesome CSS on https://cdnjs.cloudflare.com/ajax/libs is added. Also when we use the highlight.js or Prettify source highlighter a link to the Javascript files on the cdnjs.cloudflare.com server is generated. We can change the value of the scheme from https to http by setting the attribute asset-uri-scheme to http. Or we can leave out the scheme so a scheme-less URI is generated for the links. A scheme-less URI provides the benefit that the same protocol of the origin HTML page is used to get the CSS or Javascript files from the cdnjs.cloudflare.com server. Remember this might provide a problem if the HTML page is opened locally. In the next sample Asciidoc markup we change the scheme to http: In the generated HTML we see the new scheme value: Now we leave the value of the asset-uri-scheme attribute empty: The generated HTML now contains a link to the FontAwesome CSS with a scheme-less URI: Written with Asciidoctor 1.5.0. Original post written on August 15, 2014 ### Replacements For Text To Symbols With Asciidoctor we can use text to describe a symbol in our markup. The text is automatically transformed to a Unicode replacement. For example if we use the text (C) it is converted to &#169; which is the copyright symbol: ©. In the following sample we see all the symbol replacements: Written with Asciidoctor 1.5.2. Original post written on September 15, 2016 ### Turn Section Titles Into Links When we use Asciidoctor to write and generate our documentation we can use the document attributes sectanchors or sectlinks to turn section titles into link references. This can be useful if we want for example to bookmark a section. The sectanchors attribute will show a section icon in front of the section title when we hover over the title. The icon itself is the link to the section. Section title in generated HTML output. Hover over section title and icon is shown. Section icon is link reference. With the sectlinks attribute the section title itself is the link. So we don't get an icon if we hover of the title, but the title text itself is now the link. The section title is now a link. Original post written on May 23, 2014 ### Leave Section Titles Out of Table Of Contents Section titles in our document (titles start with two or more equals signs) are part of the document hierarchy and therefore can be used in a generated table of contents. If we don't want to include a section title in the table of contents we must make the title discrete. The title is styled like a normal section title, but it is no longer part of the document structure as title. Therefore the section title will not be generated in the table of contents. To make a title discrete we must use the attribute discrete for the title. In the following document we first have a simple document with two section titles. When we generate the HTML for this document we see both titles in the table of contents. Now we make the first section title discrete by applying the discrete attribute: We generate the document again as HTML and this time we see the section title is no longer in the table of contents: Written with Asciidoctor 1.5.2. Original post written on September 10, 2015 ### Change Level Offset For Included Documents When we use the include directive to include another document we can must make sure the included document fits the levels of our main document. For example the included document shouldn't have level 0 headings if the main document already contains a level 0 heading. We can change the level offset in the main document before including another document. This will change the heading levels for the included document so all heading rules are okay. To change the level offset we use the document attribute leveloffset. It is best to use a relative value, so if the included document also contains included document the output will still be okay and the heading rules still apply. Alternatively we can use the leveloffset attribute for the include directive. In the following sample document we include other files with a level 0 heading: Here is the source for the included files: When we transform book.adoc to HTML with Asciidoctor we get the following result: \ Written with Asciidoctor 1.5.4. Original post written on September 20, 2016 ### Use Counters in Markup In Asciidoctor we can create a document attribute as a counter attribute. The attribute is automatically incremented each time we use it in our markup. We can choose to use numbers or characters. Only latin characters from 'a' to 'z' or 'A' to 'Z' are allowed. By default the counter will start at 1, but we can define another start value when we use the counter attribute for the first time. To define a counter attribute we must prefix the attribute name with counter:. Each time we use this syntax with the counter: prefix the value is incremented and displayed. To only display the current value, without incrementing, we simply refer to the document attribute without the counter: prefix. For example if we want to add a counter attribute with the name steps we would use the following markup in Asciidoctor: {counter:steps}. To increment the counter without display it we must replace counter: with counter2:. The value of the attribute is incremented but not displayed. So to increment our steps attribute we would use the syntax: {counter2:steps}. To get the current value without incrementing we simply use {steps}. To start with a different value than 1 we can suffix the attribute name with :<:start-value>. Let's look at how we would create the steps counter attribute starting from 100: {counter:steps:100}. To have a counter with letters we define the start value as a letter from which we want to count: {counter:steps:A}. In the following example markup we see different usages of the counter support in Asciidoctor: When we transform this to HTML with Asciidoctor we get the following result: \ Written with Asciidoctor 1.5.4. Original post written on September 16, 2016 To make an image linkable in Asciidoctor when formatted to HTML we must use the link attribute when we use the image macro. The value of the link attribute is the address where the user goes when clicking on the image. We can also specify extra link attributes like window to specify the target window for the link to open in. In the following example we use the link attribute for a block and inline image, with and without an extra window attribute: When we transform this markup to HTML we get the following HTML for the images: Written with Asciidoctor 2.0.9. Original post written on April 23, 2020 Since Asciidoctor 1.5.0 we can use the document attribute hide-uri-scheme to turn URLs into links, where the link text is displayed without the URI scheme. This can save typing when we simply want to add a URL without any special description. In the next Asciidoc syntax we first define URLs without the hide-uri-scheme attribute, followed by URLs after the attribute is set: When we generate output using the HTML backend we see the following output: Written with Asciidoctor 1.5.0. Original post written on August 12, 2014 To define a link in Asciidoc markup we only have to type the URL followed by an optional text for the link in square brackets ([text link]). With Asciidoctor we can add extra attributes that can be used when the content is generated. We have to set the document attribute :linkattrs: to make sure Asciidoctor will process the attributes. In the following sample Asciidoc markup we define links with attributes like window and role: The following HTML is generated when we use Asciidoctor with the HTML backend: Code written with Asciidoctor 0.1.4. Original post written on June 13, 2014 ### Prevent Transformation of URL to Hyperlink Normally if we type an URL in Asciidoctor that starts with a scheme Asciidoctor knows about, the URL is turned into a hyperlink. The following schemes are recognized by Asciidoctor: • http • https • ftp • irc • mailto • email@email.com If we want to keep our URL as text and not a link we must prepend our URL with a backslash (\). This way Asciidoctor will not transform the URL to a hyperlink in our output. In the following example we have URL that is transformed to a link, followed by the same URL but with a backslash (\) before it, that is not transformed: If we transform our document to HTML with Asciidoctor we get the following result: Written with Asciidoctor 1.5.6.1. Original post written on October 12, 2017 ### Customize How Missing Attributes Are Handled Document attributes are like variables for your Asciidoctor document. Normally when we reference an attribute that is not set in our Asciidoctor markup the reference is still in the output. This is very handy, because we immediately see that a document attribute is not set. But we can customize this behavior with the document attribute attribute-missing. We can use the default value skip, which leaves the reference in the output. Another option is drop, which means the reference is dropped from the output. Finally we can set the value to drop-line, where the complete line with the attribute reference is dropped from the output. In the following sample Asciidoctor markup we set the three values for the attribute attribute-missing: When we transform this to HTML5 we get the following output: Written with Asciidoctor 1.5.2. Original post written on February 25, 2015 ### Substitute Attribute in Listing Block To write a listing block where the contents of the block is generated in a monospace font and line breaks are preserved is easy with Asciidoc. We can use ---- or [listing] or indent the paragraph with one space to define a listing block. All content in a listing block is processed as is, but special characters and callouts are processed. This means if we have an attribute in our block the attribute is not substituted with the actual value. To enable the replacement of the attribute with the attribute value we must set the subs attribute for our listing block. Suppose we have the following listing block in our documentation with the attribute grailsVersion in the content: When we generate HTML output we get the following result: We add now the subs attribute to our listing and use the value attributes+ to instruct Asciidoctor to replace attributes with their values: The generated HTML now shows that the attribute value is used: Alternative ways to define the listing block with the subs attribute. These will render the same result: Written with Asciidoctor 0.1.4. Original post written on May 23, 2014 ### Escape Attribute References One of the many cool features of Asciidoc is attribute substitution. We can define attributes with values and in our Asciidoc markup we reference those attributes between curly braces. For example we could include the value of the attribute customAttr like this in Asciidoc: {customAttr}. But sometimes we simply want to include some text between curly braces without any attribute value substitution. We need to put an escape character (\) before the first brace and Asciidoc will not replace the attribute with a value. Suppose we have the following Asciidoc, where we want to explain some Groovy syntax ("${sampleValue}"). Asciidoc will try to substitute the attribute sampleValue with a value if set.

If we generate HTML with Asciidoctor we get the following output and notice that attrValue is changed to attrvalue (lower case v):

If we add the escape character no attribute substitution will take place, even if we assign a value to the attribute attrValue:

Now we get the output we expect:

Written with Asciidoctor 0.1.4.

Original post written on July 3, 2014

### Document Attributes With Styling

Document attributes in Asciidoctor are very powerful. We can assign values to a document attributes and reference the attribute name in our document enclosed between curly braces. Asciidoctor will fill in the value when the document is transformed. Instead of a plain value we can also use styling markup in the document attribute definition. We must use the passthrough macro and allow for quote substitution.

In the following example document we define three document attributes: cl-added, cl-updated and cl-changed. We use the passthrough macro, quotes substation to assign CSS classes:

Notice we need a file docinfo.html with the CSS style definitions:

When run Asciidoctor to get HTML output we see the following:

Written with Aciidoctor 1.5.7.1.

Original post written on September 2, 2018

### Using Conditional Directives

In Asciidoc markup we can include or exclude text based on the existence of document attributes or based on the value of a document attribute. Therefore we use the macros ifdef, ifndef and ifeval. If we want to include some content if the document attribute sample is set we can use the following syntax:

If we want to include some content if the attribute is not set we use ifndef:

We can even use multiple attributes for these macros. If the attribute names are , separated only one of the attributes need to be set to include the content. If we use the + separator all attributes must be set to include the content.

In the following sample Asciidoc markup we see several usages of the ifdef and ifndef macros:

If we generate HTML output and set and unset the intermediate and advanced document attributes we see that content is included or not:

\

Finally with Asciidoctor we can use the ifeval macro to evaluate the value of attributes. If the expression evaluates to true the content is included otherwise it is skipped. The following sample evaluate the version document attribute and shows different content based on the value:

Let's generate HTML with different values for the version attribute:

Written with Asciidoctor 0.1.4.

Original post written on August 5, 2014

### Conditional Directive to Check If Document is On GitHub

In a previous blog post we learned about the conditional directives in Asciidoctor. Dan Allen mentioned a conditional directive that we can use to see if the document is used on GitHub. The conditional directive is called env-github.

We have the following Asciidoc markup for a document stored on GitHub:

To see what is rendered we can view the document on GitHub.

Written with Asciidoctor 1.5.0.

Original post written on August 26, 2014

### Using Document Fragments

Normally all Asciidoc files are processed and transformed to output files by Asciidoctor. But if we start the file name with an underscore (_) the file is not transformed to an output file. This is very useful, because we can define some Asciidoc document fragments and include them in other Asciidoc files, but in the output directory the document fragment is not generated.

Let's create two Asciidoc files. One is _attrs.adoc which is a document fragment file that is used in sample.doc:

From the command line we can invoke the asciidoctor command. We also check the directory and see there is only the file sample.html:

The following screenshot shows how the sample.html looks like in a web browser:

Written with Asciidoctor 1.5.1.

Original post written on November 25, 2014

### Keep Line Breaks in Paragraphs

Normally when we write a paragraph in Asciidoc markup the line breaks are not preserved. Multiple lines are combined into a paragraph until an empty line is found to separate paragraphs. If we want to keep line breaks we must add the plus sign (+) at the end of the line. If we generate HTML from the Asciidoc markup a line break is inserted with a <br> tag. We can also use the hardbreaks document attribute to enable or disable line breaks in paragraphs without the addition of the + symbols.

In the following Asciidoc sample we use the + sign to keep line breaks in a paragraph:

We get the following result if we use the HTML backend:

We can also use the hardbreaks attribute:

If we generate HTML we get the following result:

Samples written with Asciidoctor 0.1.4.

Original post written on June 25, 2014

### Auto Number Callouts

In a previous post we learned about callouts in Asciidoctor to add explanation to source code. While surfing the Internet I came upon the following blog post by Alex Soto: Auto-numbered Callouts in Asciidoctor. I turns out that since Asciidoctor 1.5.8 we can use a dot (.) instead of explicit numbers to have automatic increasing numbering for the callouts.

Let's take our example from the earlier blog post and now use auto numbered callouts:

When we convert this markup to HTML we get the following result:

This makes it very easy to add new callouts without having to change all numbers we first typed by hand.

Written with Asciidoctor 2.0.9

Original post written on December 10, 2019

### Apply Custom Styling to Blocks

To define a listing block to display for example source code in Asciidoc is easy. We can use ---- delimiter or explicitly use [listing] and include the source code. If we use the HTML backend to generate HTML the result will be a pre block enclosed in some div sections with a couple CSS classes applied. If we want to add our own CSS classes to the generated output we can apply so-called roles to our block.

In the following Asciidoc markup we apply a role with the name console to a listing block. Remember we can use the same syntax for other types of blocks as well.

If we generate HTML we get the following HTML code. Notice the class attribute of the first div contains console:

We can use an alternate syntax which resembles CSS classes closely. We can use dot (.) followed by the role name.

If we want to apply multiple roles (CSS classes) we can specify the names separated by spaces in the role attribute or chain the names with .:

By specifying role values we can customize how the output looks with different implementation for the CSS classes that we want.

Code generated by Asciidoctor 0.1.4.

Original post written on June 16, 2014

### Customize the Figure Captions

With Asciidoctor we can use images in our documents with the image directive. When the document is converted each image gets a caption. By default the caption label is Figure followed a number for the position of the image in the document. So the first image has a caption Figure 1.. If we add a block title (text prefixed with a .) to the image then that text is used in the caption as well. We can customize the caption label, figure counter, caption text or disable the figure caption using a combination of document and image attributes.

We have the following Asciidoctor markup. We include several images and customize the figure caption settings. To change the caption label (Figure) we set a different value for the document attribute figure-caption. In our example we use the value Logo. Any captions following this definition will have the label Logo.

To use a separate counter we can use a counter attribute inside the caption attribute for our image. In our example we use this for the Gradle logo. If we want to use another caption text instead of the block title we can use the title attribute for an image.

Finally to disable all figure captions we negate the figure-caption document attribute.

When we transform this markup to HTML we get the following output:

\

Written with Asciidoctor 1.5.4.

Original post written on September 26, 2016

### Grouping Floating Images

With Asciidoctor markup we can position images in our document. We can even float images, so text can next to an image, inside only below or about the image. We can also define multiple images to float, so the images are displayed on the same line next to each other. Any text that follows these images is also displayed next to the images. If we want only to have floating images, but the text starting under the images we can place the images inside an open block and assign the block the role float-group.

In the next example we first define three images that all have roles to float left. In the second part we group these images using the role float-group, so the text will not be displayed next to the images, but under the images:

When we create a HTML document from the Asciidoctor markup we get the following result:

Written with Asciidoctor 1.5.6.1.

Original post written on October 4, 2017

### Trick To Use Caption Labels And Numbers In References

In Asciidoctor we can add an anchor with an ID to a section or title and then reference it in a link. The title of the section is used as link text. We can alter that when we define the link, but if we rely on the default behaviour we create a title for our section including the caption label and number. This way the created link points to the correct section and the text contains the caption text and number for that section.

In the following example markup we can see how we can use the caption label and section counter as attributes in the title. We do this with the title attribute of a section. By using the single quotes we tell Asciidoctor to interpret the attributes. We must also make sure we set the caption attribute to an empty string value. This disables the default caption creation of Asciidoctor for our section. Finally we need to provide an ID for the section using the #ID syntax:

When we generate a HTML version of this markup we get the following result:

Written with Asciidoctor 1.5.4.

Original post written on September 26, 2016

### Changing Values for Default Captions

Asciidoctor has several captions and labels that can be overridden with document attributes. We need to define a document attribute and assign a new value to override a default caption or label. We can use UTF-8 characters as the value. The following list shows captions and labels we can override:

• :appendix-caption:
• :caution-caption:
• :example-caption:
• :figure-caption:
• :important-caption:
• :last-update-label:
• :manname-title:
• :note-caption:
• :table-caption:
• :tip-caption:
• :toc-title:
• :untitled-label:
• :version-label:
• :warning-caption:

In the next example Asciidoctor document we override caution-caption and last-update-label:

We get the following HTML output:

This mechanism can be used to provide messages for other languages than English. The Asciidoctor Github repository contains a file with already translated values for a lot of languages. We include this document in our own Asciidoctor markup and we set the document attribute lang with the value we want, eg. nl. In the following example document we include the file https://raw.githubusercontent.com/asciidoctor/asciidoctor/v1.5.5/data/locale/attributes.adoc.

When we invoke Asciidoctor via the command line we must add the option -a allow-uri-read to the remote document is included. The following screenshot shows the output:

Written with Asciidoctor 1.5.5.

Original post written on October 11, 2016

### Display Keyboard Shortcuts

When we want to explain in our documentation which keys a user must press to get to a function we can use the keyboard macro in Asciidoctor. The macro will output the key nicely formatted as a real key on the keyboard. The syntax of the macro is kbd:[key]. To get the desired output we must set the document attribute experimental otherwise the macro is not used.

In the next Asciidoctor example file we use the keyboard macro:

When we transform this to HTML with the built-in HTML5 templates we get the following output:

Written with Asciidoctor 1.5.2.

Original post written on April 22, 2015

### Exclude Parts From Included Files

In a previous post we learned how to include parts of a document in the generated output. The included parts are defined using tags. The start of a tag is defined in a comment with the format tag::tagName[] and the end has the format end::tagName[]. Next we must use the tags attribute for the include macro followed by the tagName. If we don't want to include a tag we must prefix it with an exclamation mark (!).

Suppose we have an external Java source we want to include in our Asciidoctor document.

In the following sample Asciidoctor document we include Sample.java, but we don't want to include the text enclosed with the singletonAnnotation tag. So we use tags=!singletonAnnotaion with the include macro:

When we transform our Asciidoctor markup to HTML we get the following result:

Written with Asciidoctor 1.5.6.1.

Original post written on January 29, 2019

Asciidoctor is a great tool for writing technical documentation. The documentation to our Java source is what we write in Javadoc comments. Wouldn't it be nice if we could use Asciidoctor in our Javadoc comments? Of course! We can achieve this with the Asciidoclet Javadoc doclet. The doclet processes the Javadoc comments as Asciidoctor source and generates HTML in the final Javadoc documentation. We can use all of Asciidoc syntax like tables, lists, include directives, styling and more. We can even use Asciidoctor extensions like asciidoctor-diagram.

In the following Java source code we have Javadoc comments with Asciidoctor syntax. We have document attributes, list, styling, include macro, table and asciidoctor-diagram code in our Javadoc. Notice that we don't have the clutter of HTML tags we normally we would have if we write Javadoc.

Next we create a Gradle build file and configure the javadoc task to use the Asciidoclet Javadoc doclet. In our Java class we also used the asciidoctor-diagram support and therefore we also need to set up the Gradle jruby plugin.

When we run the javadoc task we get the generated output. For example part of the generated documentation for our Application class looks like this:

Documentation for the main` method:

Remember this only applies to Javadoc. If we write Groovy code and use Groovydoc to generate documentation we cannot use Asciidoclet.

Written with Asciidoclet 1.5.2 and Gradle 2.7.

Original post written on October 12, 2015