In this post, I present why I switched from Word Processors to text with Asciidoctor. Asciidoctor & Ascidoc help authors to focus on the content they are writing and they provide a complete ecosystem for producing nice documents in many different formats. Finally, I share some of my best practices and some useful tips for dealing with these less user-friendly tools.

Introduction

A long time ago, I was a researcher and part of my job was to write scientific materials. As a computer scientist, the common writing tool was LaTeX. With LaTeX, the writer uses plain text within markup tagging conventions to produce documents, as opposition as word processors (such as Microsoft Word or LibreOffice) which use formatted text, “What You See Is What You Get” – WYSIWYG.

The main advantage of LaTeX is the writer only focus on the text to produce. Then, the writer can simply use tools for producing a formatted document within different templates (articles, books, …).

Since I work in the “private” industry, my only tool for producing documents is Microsoft Word. Now, I spend a lot of time on how the text would look like formatted more than on the meaning. Microsoft Word does a great job for producing document and more recently it is even better for collaborative writing.

Unfortunately, I still miss some plan text features, such as:

  • Versioning and modification history
  • Powerful collaborative mode
  • Different formats of output (HTML, PDF, …)
  • Ease of text refactoring and reusability of text snippets

That is why I have started looking for alternatives to the “corporate” processor.

A Path Finding the Great Tool

As programmer, I daily use Markdown a lightweight markup language for writing text. It is like a simplified version of LaTeX, based on a few markups for formatting text. The real advantage of Markdown is its ubiquitousness in programming world (IDE, Code Editor, command lines, GitHub, GitLab, …). You can write some Markdown everywhere and display it formatted easily.

Markdown is great and simple; I use it for writing my blog posts. But it is limited in the possibilities of formatting and writing large documents (such as books) without coding / scripting some extensions.

LaTeX is great and I used it a lot in research. In research sector, LaTeX is ubiquitous for producing publications. Editors, journals, conferences, … provide directly LaTeX template to authors.

In my opinion, LaTeX is fantastic for research publications and for integrating many references. BibTeX is a great companion for managing the bibliography. However, LaTeX seems to be in a mature state and does not really evolve. You need some efforts to install it in recent OS and modern tools do not integrate it anymore.

Listening to a podcast Les Cast Codeurs (French), I heard Emmanuel Bernard talking about Asciidoc. First, it looked like a clone of LaTeX to me. Then, it was more a merge between Markdown and LaTex.

Thus, I decided to try Asciidoc, a tool recommended by a vi lover.

Asciidoctor in Short

First of all, Asciidoctor is the Ruby implementation released in 2013 of Asciidoc written in Python in 2002. In short, Asciidoc is the original and Asciidoctor is a more recent version. I use Asciidoc as syntax for my text files and Asciidoctor’s tools for parsing and converting.

From the Asciidoctor web site:

Asciidoctor is a fast, open source, Ruby-based text processor for parsing AsciiDoc® into a document model and converting it to output formats such as HTML 5, DocBook 5, manual pages, PDF, EPUB 3, and other formats.

An maybe the best definition:

Use AsciiDoc for document markup. Really. It’s actually readable by humans, easier to parse and way more flexible than XML. — Linus Torvalds

It is not a coincidence that Linus Torvalds used it for the Git documentation.

For a programmer, Asciidoctor is like writing code. Asciidoctor provides the same philosophy: focus on contents (instructions), several output formats (compilation), highly extensible (tooling), and can separate content in multiple files (managing code).

It is probably because of this similitude that some big tech uses it: Zalando, [Spring](https://spring.io/projects , …

A great feature is the source code highlighting and the ease to link code block to project’s sources for having up-to-date code snippets in the document.

GitLab and GitHub provide direct rendering.

In Short

Pro

  • Focus on content
  • Reuse of contents
  • Combining to Git (even better with GitLab) for great collaboration, history, versioning, …
  • Exporting to different formats (HTML, Word, PDF, …)
  • Easy integration with tooling for automatization (exporting to Web site)
  • Dynamic integration of CSV, code files, …

Cons

  • Learning syntax
  • Need to be interpreted to get “nice” output
  • Output tuning can be hard

Conclusion but not the End

This post is about my thoughts on a tool that I use every day for sharing knowledge and information. Since I used it, I have gained in productivity by reusing and organising the knowledge.

Asciidoctor combined to solution such GitLab becomes a great content management platform for collaborative editing, history, versioning, review, search, …

I have even automated with some CI/CD the production of some documentations for seamless publishing.

While writing this post I read a very good and similar post: How I wrote my book by Kevin W. McConnell.

In the rest of this post, I share my best practices and tips for having a great use of Asccidoctor.

Writing Project Practices

My basic project structure follows this:

your_project
|__assets
|__chapters
|__styles
|  .gitignore
|  index.adoc
|  Makefile		
  • assets: all images
  • chapters: typically, one adoc file by chapter for better organisation
  • styles: custom styles
  • .gitignore: the git ignore file
  • index.adoc: the main file
  • Makefile: building and exporting

My .gitignore file:

# AsciiDoctor
output/
*~

My Makefile:

DOCKER := asciidoctor/docker-asciidoctor:latest
DIRMOUNTS := /documents
DIRCONTENTS := chapters
DIRBUILDS := output
DIRWORK := $(shell pwd -P)
OPTIONS := -a docinfo=shared

.PHONY: all clean pull assets
.PHONY: html pdf epub force

all: clean html pdf epub
clean:
	rm -rf $(DIRBUILDS);

pull:
	docker pull $(DOCKER);

assets:
	mkdir -p $(DIRBUILDS)/assets;
	cp -r assets/*.png $(DIRBUILDS)/assets;

html: assets pull
	docker run -v $(DIRWORK):$(DIRMOUNTS)/ ${DOCKER} asciidoctor \
	  -D $(DIRMOUNTS)/$(DIRBUILDS) $(OPTIONS) index.adoc;

pdf: pull
	docker run -v $(DIRWORK):$(DIRMOUNTS)/ ${DOCKER} asciidoctor-pdf \
	  -D $(DIRMOUNTS)/$(DIRBUILDS) $(OPTIONS)  index.adoc;
	mv -f $(DIRBUILDS)/index.pdf $(DIRBUILDS)/my-doc.pdf;

epub: pull
	docker run -v $(DIRWORK):$(DIRMOUNTS)/ ${DOCKER} asciidoctor-epub3 \
	  -D $(DIRMOUNTS)/$(DIRBUILDS) index.adoc;
	mv -f $(DIRBUILDS)/index.epub $(DIRBUILDS)/my-doc.epub;

My typical index.adoc file used for organising my chapters:

= A Great Title
:author: Alexandre di Costanzo
:revnumber: v1.0
:revdate: 19.03.2021
:toc: left
:toclevels: 4
:source-highlighter: coderay
:numbered:
:doctype: book
:sectnums:
:partnums:
:docinfodir: styles
:docinfo1:
:title-logo-image: assets/logo.png

// For using specific chapter and toc labels (here French translation)
:toc-title: Table des Matières
:chapter-label: Chapitre

// Example of how to include a chapter with automatic level offset
include::chapters/my-first-chapter.adoc[leveloffset=+1]

Tools for Editing

Here is some tools I use for writing:

  • Asciidoctor.js Live Preview is a Firefox add-on for live previewing as HTML, AsciiDoc files.
  • Emacs adoc-mode is a great Emacs AsciiDoc integration, even with a WYSIWYG mode.
  • IntelliJ plugin provides a good IDE integration within auto-completion.
  • Of course plugins and modes exist for other best-editors such as Vim or Sublime Text

Useful Tips

Cheatsheet

A complete cheatsheet: AsciiDoc cheatsheet by POWERMAN

Exporting to Standalone HTML

$ asciidoctor --backend html5 -a data-uri my_file.adoc

-a data-uri embeds images as base64 inside the HTML, the single HTML file for sharing.

Swiss-Army Knife of Conversions: Pandoc

Pandoc as it describes itself is a Swiss-army knife for converting files from one markup format into another. It supports Markdown, Asciidoc, LaTeX, EPUB, Microsoft Word, …

I use it for exporting Markdown to Asciidoc or HTML ; and for converting Asciidoc to Microsoft Word, see bellow.

Converting to Markdown

Converting to Markdown relies on two operations:

$ asciidoctor -b docbook my_file.adoc

$ pandoc -f docbook -t markdown my_file.xml -o my_file.md

Converting to Microsoft Word

Asciidoctor cannot not be directly processed to Microsoft Word. You need to process it in Docbook then use Pandoc to convert it into Microsoft Word.

Prerequisites:

Command:

$ INPUT_ADOC=my_input_file.adoc 
$ asciidoctor --backend docbook --out-file - $INPUT_ADOC | pandoc --from \
 docbook --to docx --output $INPUT_ADOC.docx 

There are a few more options for customisation:

  1. Code block highlighting: using Pandoc --highlight-style, e.g.:
    $ INPUT_ADOC=my_input_file.adoc 
    $ asciidoctor --backend docbook --out-file - $INPUT_ADOC | pandoc --from \
     docbook --to docx --output $INPUT_ADOC.docx --highlight-style espresso
    
    • All available style by: $ pandoc --list-highlight-styles.
  2. Using a Microsoft Word template – customise all styles: using Pandoc --reference-doc ; it very useful for exporting within the corporate style, e.g.:
    $ INPUT_ADOC=my_input_file.adoc 
    $ asciidoctor --backend docbook --out-file - $INPUT_ADOC | pandoc --from \
     docbook --to docx --output $INPUT_ADOC.docx --highlight-style espresso \
     --reference-doc=corporate-styles.docx
    

Using CSV as Tables

Tables are painful to define with a markup language, especially large ones. Asciidoctor can create tables where the header and rows are in CSV (Comma Separated Values) and DSV (Delimiter Separated Values) format.

[format="csv", options="header"]
|===
Header Col 1, Header Col2
Val 1, Val2
|===

Better, including the CSV from an external file:

[format="csv", options="header"]
|===
include::your_csv_.csv[]
|===

Strikethrough / Cross Out Text

Strikethrough text is not a core syntax formatting option. AsciiDoc provides some build-in roles for using advanced formatting.

My test is [line-through]#stricken#.

Labels like Swagger-UI

This post describes how to customize the default style to add labels like swagger-ui.

An usage example for describing Restful API:

=== {http-post} SSO / Contexte

[horizontal]
HTTP Method:: `POST`
HTTP Path:: `/api/{target}/sso`
HTTP Content:: `application/json`

References