Hello AsciiDoc, Goodbye Word

Posted by | December 08, 2013 | blog | 2 Comments

I write technical documentation from time to time, and, until recently, had been doing it in MS Word and was less than enjoying it. I had a feeling there was a better tool out there, so I decided to look around. First, I put together a list of my MS Word grievances:

  • Doesn’t integrate with version control since not plain text
  • No support for code snippets (I put them in a one-column table, is that right?)
  • I only have LibreOffice on my Mac, results in formatting issues
  • Word docs designed for print. What about web and other formats?
  • Clunky UI – I don’t want to use my mouse
  • Would be nice to have separation of content from styling

With this list in hand, I went off to find a solution that solved my issues.

What about Markdown?

The first solution I considered was Markdown. Being a user of GitHub and StackOverflow, I am pretty proficient with Markdown and really enjoy and respect it as a lightweight markup language. It solves almost all of my grievances above. It’s plain text, so can be version controlled, it’s easy and readable, can do code blocks and there are many converters to render Markdown to HTML, PDF and even Word Doc (I use the PanDoc SublimeText plugin for this).

What’s wrong with Markdown, you ask? Well, it’s just a little too simple. Markdown doesn’t have support for many structural features for documents, books, articles, etc. I wanted something that could do everything MS Word could do, including generating a table of contents, footnotes and references within my document. Unfortunately, when I needed these advanced features, Markdown left me hanging. Don’t get me wrong – I think Markdown is an awesome tool (I am using it to write this blog post), but it isn’t robust enough for complex document editing.

Unfortunately, when I needed these advanced features, Markdown left me hanging.

Let’s Try Something Else

I finally stumbled onto AsciiDoc and quickly knew I had found what I was looking for. AsciiDoc has a very similar syntax to Markdown (is almost a superset), but it extends far beyond it. It can do table of contents, callout blocks for warnings and notes (they call these admonitions) and can export to HTML5, PDF and Docbook (for books), among other formats.

To give you a feel for the syntax, here is a sample document in Asciidoc:

= My Document
Steve Hanson <steve@shanson.co>
:toc:
:icons: font
:sectanchors:

Read http://shanson.co[my blog].

== First Section

* item 1
* item 2

NOTE: This is a note block!

[source,ruby]
puts "Hello, World!"

At the top of the file, you’ll see several lines with : before and after. These are parameters that AsciiDoc will use when it generates the document, and are not required. In the above file, :toc: generates a table of contents, :icons: font tells AsciiDoc to use Font Awesome for icons (instead of images) and :sectanchors: turns on hover anchor tags on sections to make them linkable. Most of the rest of the file looks similar to Markdown, with a few exceptions.

Links are, in my opinion, simpler than Markdown. Markdown’s link format: [my link](http://...) is always hard for me to remember. AsciiDoc: http://mysite.com[my site]. The code block above specifies the language for syntax highlighting. AsciiDoc can also do code blocks by indenting one space per line (as opposed to Markdown’s four spaces per line) or by using the backtick for inline blocks.

Let’s move on to my AsciiDoc workflow.

My Workflow

I have a workflow set up where I can save my .adoc file and immediately see the changes in my browser.

Installing AsciiDoc(tor)

AsciiDoc has a wonderful Ruby port, called Asciidoctor, that is great for getting up and running quickly. Just run:

> gem install asciidoctor

Then you can compile .adoc files to HTML5 by running:

> asciidoctor <my-file.adoc>

Auto-Compile & LiveReload

Now that we can compile our files, we are off to a good start, but editing a document still looks like:

  1. save file
  2. compile file
  3. refresh browser window

Let’s see if we can cut out those last two steps by using Guard and LiveReload. Run:

> gem install guard-livereload guard-shell yajl-ruby

Now, create a file, called Guardfile, in the same directory as your adoc file and paste the following contents:

# Guardfile

require 'asciidoctor'
require 'erb'

guard 'shell' do
watch(/^*\.adoc$/) {|m|
  Asciidoctor.render_file(m[0], :in_place => true)
}
end

guard 'livereload' do
  watch(%r{^.+\.(css|js|html)$})
end

The shell guard task watches our directory and automatically renders adoc files to HTML when they change. The livereload task watches html, css, js files and automatically sends a LiveReload signal when they change (e.g. when the adoc file is rendered). Start the guard tasks by running guard start from your terminal in the directory of your adoc and guardfile files.

Now, the only step left is to set up our browser to catch the LiveReload signal. Just install the LiveReload extension for Firefox or Chrome.

Now, open your browser to doc HTML file and turn on LiveReload using your extension. Any saves will be auto-updated in the browser without refresh!

The full details of how this works are outlined here.

Wrap this up

In summary, I’m very excited to have found a markup language that is robust enough for my needs and still satisfying and productive to write in. I have now converted the documentation on my current project to AsciiDoc, checked it in with our source code and added a task in our build system to compile the documentation to HTML using Asciidoctor.

I am excited to see where this language goes in the coming months, as it seems to have picked up a lot of momentum in the last year with the Asciidoctor Ruby port. If you’re interested in learning more, I suggest you check out the What is AsciiDoc Article and this Syntax Guide.

How do you write technical (or non-technical) documents? Have a better workflow? I’m interested to hear your comments!