Asciidoctor is a text processor and publishing toolchain that converts AsciiDoc files into HTML5, PDF, EPUB, and MOBI. It probably supports more formats, but these are the ones I use.

I really got into Asciidoctor a few years ago when I authored the first version of the JHipster Mini-Book for InfoQ. When I first suggested the idea, they thought it’d be the most expensive book they’d ever produced, but they were still willing to let me do it. They thought it’d require taking the PDF generated from Asciidoctor, putting it into their design program, then manipulating it to output EPUB, MOBI, and a printable version too. In the end, it turned out to be the cheapest book they’d ever produced! Asciidoctor supports all of the aforementioned outputs and I was able to match InfoQ’s mini-book design with code and CSS.

I enjoyed the process so much, I created a template project for InfoQ mini-books. Even if you’re not writing an InfoQ mini-book, this template can help you self-publish your own book.

When I started writing on this blog (which uses Jekyll, soon to be Hugo), I reluctantly used Markdown to author posts. Fast forward to today, and we’ve integrated AsiiDoc support! I have to thank Josh Long for motivating this integration. He started writing our Reactive Programming series with it. The code callouts were so cool, I had to make them work. Below is an example.

Example 1. Read data from a file synchronously package com.example.io ; import lombok.extern.log4j.Log4j2 ; import org.springframework.util.FileCopyUtils ; import java.io.File ; import java.io.FileInputStream ; import java.io.IOException ; import java.util.function.Consumer ; @Log4j2 class Synchronous implements Reader { @Override public void read ( File file , Consumer < BytesPayload > consumer ) throws IOException { try ( FileInputStream in = new FileInputStream ( file )) { (1) byte [] data = new byte [ FileCopyUtils . BUFFER_SIZE ]; int res ; while (( res = in . read ( data , 0 , data . length )) != - 1 ) { (2) consumer . accept ( BytesPayload . from ( data , res )); (3) } } } } 1 source the file using a regular java.io.File 2 pull the results out of the source one line at a time…​ 3 I’ve written this code to accept a Consumer<BytesPayload> that gets called when there’s new data

One downside to AsciiDoc is GitHub doesn’t support it as well as Markdown. You can fix that by viewing your *.adoc files through DocGist, as I’ve done with my Angular 7 Tutorial.