AsciiDoc Recommended Practices

This document catalogs a set of recommended practices for composing documents in AsciiDoc.

DRAFT

This document is only a rough draft. These recommendations are not doctrine and are subject to change.

AsciiDoc offers multiple ways to accomplish the same thing, and is often very lenient with the syntax. This guide helps bring consistency to your documents that will maximize efficiency, improve readability and minimize maintainence.

Document extension

AsciiDoc doesn’t care which extension you use. GitHub supports the extensions .asciidoc, .adoc and .asc.

.adoc seems to be the most often used extension and the one we prefer. It does not conflict with other well known applications, is distinct, and not excessively long (like .asciidoc). It also reads as “a doc”. Our recommendation, therefore, is to use .adoc.

We strongly recommend against using the .asc extension. The connection to AsciiDoc isn’t immediately obvious and it gets falsely identified as a PGP file on Linux.

One Sentence Per Line

Don’t wrap text at a fixed column width. Instead, put each sentence on its own line, a technique called sentence per line. This technique is similar to how you write and organize source code. The result can be spectacular.

Here are some of the advantages of using the sentence per line style:

  • It prevents reflows (meaning a change early in the paragraph won’t cause the remaining lines in the paragraph to reposition).

  • You can easily swap sentences.

  • You can easily separate or join paragraphs.

  • You can comment out sentences or add commentary to them.

  • You can spot sentences which are too long or sentences that vary widely in length.

  • You can spot redundant (and thus mundane) patterns in your writing.

We picked up this idea from the writing guide in the Neo4j documentation. However, it seems like the idea dates back a discovery by Buckminster Fuller in the 1930s, who called it ventilated prose. The technique was also recommended in 2009 by Brandon Rhodes in a blog post about Semantic Linefeeds.

It’s important to note that this technique works because AsciiDoc doesn’t treat wrapped lines in prose as hard line breaks. At least, it doesn’t show up that way to the reader. The line breaks between contiguous lines of prose will not be visible in the rendered document (i.e., as the reader sees it).

While a single line break doesn’t appear in the output, two consecutive line breaks starts a new paragraph (or other block).

Section Titles

There are three ways to define a section title. These variants can be classified into two types of styles, atx and setext (historical names).

Atx-style

In the Atx-style, the section title is defined on a single line. The section title begins with one or more equal characters (i.e., =) followed by a space and the section title. The number of leading characters representing the depth. The top-level section is reserved for the document title, so the first section in the document will have two leading characters.

== First Section

This example uses the asymmetric Atx-style. The asymmetric Atx-style is the style we recommend to define your section titles. It requires the least number of characters and it’s intuitive since the number of leading characters represents the heading level.

When using the HTML backend, this section title will be transformed into an h2 heading (likely wrapped in a section block for styling):

<h2>First Section</h2>

The symmetric Atx-style bookends the section title between a matching pair of delimiters.

== First Section ==

While this syntax may look nicer to some, it requires twice the number of delimiters without adding any additional semantics. Therefore, I consider it a waste of keystrokes and don’t recommend using it. However, either of the Atx-style section titles are better than the Setext style.

Setext

In the Setext-style, the section title is defined on two lines. The second line is a string of characters that form an underline below the section title. Here’s an example of a section title from above defined in the Setext-style.

First Section
-------------

Since the length of the line is determined by the number of characters in the section title, another dimension must be introduced to determine the level. That dimension is the character used for the underline. The characters used are (sorted from document title to level 5 section) =, -, ~, ^, and +.

I strongly recommend against using the Setext style for section titles. Keeping the length of the underline in sync with the title length is an unnecessary task and time waster. A more substantial reason is that the mapping between character and heading level is very difficult to remember and not obvious to new AsciiDoc adopters. All in all, using Setext section titles is a bad practice. Don’t use them!

The recommendation is to use the asymmetric Atx-style for section titles. It’s the most simple and intuitive method for writing, as well as for reading in the plain text (source) file.

Document title

Since the document title occurs only once in a document, I consider it acceptable to use the Setext style in this instance.

Document Title
==============
Author Name <author@example.org>
:compat-mode!:
You must explicitly disable compatibility mode (i.e., compat-mode!) in this case if you don’t want it enabled. Compatibility mode is automatically enabled when using the Setext style document title. See the migration guide for details.

Be sure to include your name immediately following the document title.

AsciiDoc only supports an e-mail following the author line. It does not support a personal URL. Asciidoctor supports a raw URL as well as an inline link macro.

It’s a good practice to also include a revision line following the author line.

Document Title
==============
Author Name <author@example.org>
v1.0, 2012-02-10
:compat-mode!:

The version number is optional. The revision line may consist of a date only.

Document Title
==============
Author Name <author@example.org>
2012-02-10
:compat-mode!:

Delimited Blocks

Delimited blocks contain special text such as code listings, quotes, sidebar text, tables and so on. As you may have guessed, they are bounded by a string of delimiters. The delimiters are defined on a line by themselves. The content goes in between the delimiter lines. Here’s an example of a listing:

----
$ asciidoctor -b html5 recommended-practices.adoc
----

Delimited blocks require four or more repeating characters on a line by themselves to mark the boundary of the block. The one exception is the open block, which only requires two - repeating characters.

You may be tempting to extend the line furthur, either to a predetermined length or to match the length of the content.

-------------------------------------------------
$ asciidoctor -b html5 recommended-practices.adoc
-------------------------------------------------

Don’t do this!

Maintaining long delimiter lines is a colossal waste of time, not to mention arbitrary and error prone. I strong urge you to use the minimum number of characters necessary to form a delimited block and move on to drafting the content. The reader will never see these long strings of delimiters anyway since they are not carried over to the output (HTML, DocBook, etc).

AsciiDoc does not enforce that the length of the line that opens the delimited block match the length of the line that closes the delimited block, but I think it should. Asciidoctor enforces this requirement, so make sure they match!

Attributes (i.e., Variables)

TODO

What they are, use them to stay DRY, such as URLs

Positional attributes

Save some typing

Numbering
{counter:counter-name}

Document settings

Document settings are configured using attribute entries immediately following the document title (without any blank lines in between). There are several options of interest.

Section numbering

You can enable numbering of sections using the sectnums attribute (off by default).

:sectnums:
Document description

You can set the description of the document using the description attribute. The description is included in the header of the document.

:description: This document catalogs a set of recommended practices for writing in AsciiDoc.

You can break any attribute value across several lines by ending the lines in a {plus} preceded by a space.

:description: This document catalogs a set of recommended practices +
              for composing documents in AsciiDoc.

You can use this text anywhere in the document by referencing it as an attribute.

{description}
Section title IDs and ID prefixes

IDs are generated for each section title by default. The ID is generated from the section title, prefixed with an underscore (i.e., _) by default. You can change the prefix using the idprefix attribute.

:idprefix: -

If you want to remove the prefix, assign it to an empty value:

:idprefix:

To disable the auto-generation of section IDs, unset the sectids attribute:

:sectids!:
Table of contents

Set the toc attribute to activate an auto-generated table of contents at the top of document:

:toc:

Images and Other Media

TODO

Paths

don’t include the images directory in each image reference

Block vs inline

…​

Conditional Inclusion

TODO

how to use, reason for using

Lists

Unordered list markers

AsciiDoc supports both * (one or more) and - (only one) as markers for a top-level list item.

* first
* second
* third

or

- first
- second
- third

However, the dash marker cannot be repeated when defining a list item. This can lead to confusion since AsciiDoc increases the nesting level each time it encounters a different marker. For instance, in the following case, the item that have an asterisk marker is nested inside the first item.

- first
* nested item
- second
- third

This nesting rule is true even when the number of asterisks seems to indicate the level:

*** first
* nested item
*** second
*** third

Yep, that’s right, the second list item is nested inside the first list item.

If you stick to convention, the number of asterisks can represent the nesting level:

* first
** nested item
* second
* third

Now that’s intuitive.

I strongly recommend using the asterisk marker if you are going to be using nested lists.

If you only have top-level list items, then using either marker is reasonable. I may even recommend using the dash marker for lists that are not intended to have nested items and the asterisk marker for lists that do have nested items. That way it’s easy to identify them as different types.

Definition lists

They exist!

Separating lists

Adjacent lists sometimes like to fuse. To force the start of a new list, offset the two lists by an empty line comment:

* apples
* oranges
* bananas

//

* carrots
* tomatoes
* celery

Literal Text

TODO

backticks vs plus and passthough stuffs

recommendation for inline code quote char

Tables

Stacked cells

Leverage them, makes it easy to read