Reference
Formatting rules
adocfmt applies the rules on this page and leaves the rest of the document as it is.
Guarantees
A byte that no rule covers is written back unchanged.
Line endings keep their form: a file with Windows line endings keeps them. A line that a rule writes ends the same way as the rest of the file.
Front matter, the block of YAML that some static site generators put at the top of a file, is left alone.
Lines whose meaning depends on an include or a conditional lose only their trailing whitespace. No other rule changes them, because their content is known only after Asciidoctor resolves the directive.
adocfmt refuses a document that it cannot read reliably. It reports what it found and writes nothing.
Formatting a formatted document changes nothing.
No rule changes what the rendered document shows. The rendering that counts is Asciidoctor’s, the reference implementation of AsciiDoc. The testing strategy describes how every rule is checked against Asciidoctor.
How adocfmt keeps your document safe gives the reasons.
Trailing whitespace
Spaces and tabs at the end of a line are removed, including inside code and literal blocks. So are the rarer characters that Asciidoctor strips there too, such as a form feed. A line that holds nothing but whitespace becomes empty.
· marks a space.
| Before | After |
|---|---|
Text.·· Line +·· | Text. Line + |
AsciiDoc forces a line break by ending a line with a space and a +.
That space is part of the break and stays.
Only the whitespace after the + is removed.
Left alone:
Front matter. It is YAML, where trailing whitespace can be part of a value.
Heading markers
A one-line section title is written with = signs followed by a single space.
A closing marker at the end of the line is removed.
| Before | After |
|---|---|
## Section ## == Other | == Section == Other |
The document title is written the same way. The author, revision and attribute lines below it keep their content.
Left alone:
A document title written on two lines. It turns on compat-mode. With a one-line title, the same document would render its inline markup differently.
A title that the rewrite would change. A closing marker counts only when it matches the opening marker. So
## Title ==has the titleTitle ==, but== Title ==would have the titleTitle.A document header that an include or a conditional reaches, including its title. Which lines are the author and revision lines is known only after Asciidoctor resolves the directive.
A title right below an include, a conditional or front matter, with no blank line between. Asciidoctor may read it as part of a paragraph above it. That paragraph can come from the lines that the directive brings in. Without the
skip-front-matterattribute, Asciidoctor reads front matter and the lines below it, down to the first blank line, as one paragraph.
Setext headings
A section title written as a line of text with an underline below it moves onto one line.
| Before | After |
|---|---|
Section ------- | == Section |
The underline character sets the level: = is level 0, - is level 1, ~ is level 2, ^ is level 3, and + is level 4.
Left alone:
An indented title. A one-line title cannot keep the indentation, because Asciidoctor skips the whitespace between the marker and the title.
A two-line title at the very top of a document. That title is the document title, not a section title. It stays on two lines; see Heading markers.
A title right below an include, a conditional or front matter, with no blank line between; see Heading markers.
A two-line title whose first line reads as a list item, such as
<1> Title. Block attribute lines between a description list and such a line stay in the list, because Asciidoctor keeps them only above a list item. On one line, the title would take them over.
Blank lines
One blank line separates two blocks, and two terms of a description list. No blank line stands between a metadata line and its block, or between the items of any other list. The file starts with no blank line and ends with a single line ending.
| Before | After |
|---|---|
= Title :toc: == Section .Listing ---- code ---- term:: one other:: two text * one * two | = Title :toc: == Section .Listing ---- code ---- term:: one other:: two text * one * two |
Two terms on consecutive lines share one description, so no blank line goes between them.
Example
Asciidoctor renders colour and color above the one description.
With a blank line between them, colour would look as if it had no description.
| Before | After |
|---|---|
colour:: color:: The wavelength. next:: Text. | colour:: color:: The wavelength. next:: Text. |
Asciidoctor renders a block, or a description list term, the same with or without a blank line in front of it. That is why adocfmt can insert the separating line safely. In a few places, a blank line is syntax, not spacing. There, adocfmt keeps the blank lines it finds.
Left alone:
Blank lines between a list item and the blocks attached to it. A blank line there decides what still belongs to the item, so adocfmt neither adds nor removes one.
Example
A callout list, the
<1>line, directly under a listing in an item belongs to that item. After a blank line, it becomes a list of its own below the item list.Part of the item A list of its own * An item + ---- code (1) ---- <1> a note
* An item + ---- code (1) ---- <1> a note
The blank line after an item that ends in indented text. Indented text in an item is a literal paragraph. The item takes every line from there down to the next blank line, even a block right under the paragraph. Without that blank line, the next item becomes part of the item above. For the same reason, adocfmt adds no blank line among those lines.
Example
On the left,
* twoshows as text inside the literal paragraph. On the right, the blank line ends the paragraph, and* twois a second item.Part of the indented text An item of its own * one indented text * two
* one indented text * two
The blank lines around a
+on a line of its own. In a list, such a+is a list continuation: it attaches the block below it to a list item. The blank lines above it decide which item the block attaches to, and the blank lines below it decide whether the block attaches at all. Outside a list, the+attaches nothing, and a blank line below it splits one paragraph into two.Example
Outside a list, Asciidoctor reads the
+and the text below it as one paragraph. With a blank line below the+, they are two paragraphs.One paragraph Two paragraphs Text. + More text.
Text. + More text.
Two or more blank lines in a row under a term with nothing after its
::. Asciidoctor reads the line after them as the start of the term’s description, even a delimiter or a block attribute line. After one blank line, such a line ends the description list instead.Two or more blank lines in a row between a term’s description and a list with a block attribute line above it. After one blank line, the list belongs to the description. After two, it is a list of its own below the description list.
Example
With one blank line, the list belongs to the description of
term. With two, it is a list of its own below the description list.Part of the description A list of its own term:: text [.role] * item
term:: text [.role] * item
The blank line under a comment. Asciidoctor drops comments before it renders, so nothing ties a comment to the block beneath it. Removing that blank line would make a comment that stands on its own read as a comment about the block below it.
The blank line under an attribute entry whose last line still ends in
\or+. The value runs on to the next blank line. Removing that blank line would make the block below part of the attribute value instead of rendering it.The lines below front matter, down to the first blank line: adocfmt adds no blank line between them. Asciidoctor skips front matter only when it is told to. Otherwise, it reads everything from the opening fence to that blank line as one paragraph. So a blank line there changes what the document title below the front matter becomes.
Example
Read as text A section title --- layout: post --- = Title
--- layout: post --- = Title
A blank line at the top of a file whose first line of content is a
---. Front matter counts only when its fence is the very first line. Removing that blank line would turn lines that are not front matter into front matter.Blank lines inside a listing, a literal block or a table. Each of these counts as one block.
Block delimiters
A delimited block opens and closes with a delimiter line, its fence. Both fences are written as short as the block allows: four characters, unless a line inside the block needs a longer fence.
| Before | After |
|---|---|
-------- code -------- | ---- code ---- |
A table fence is shortened the same way.
Its first character picks how the rows are read, so that character stays: |======= becomes |===, and ,======= becomes ,===.
A block ends at the first line that matches its opening fence. So the new fence is the shortest one that matches no line inside the formatted block.
| Before | After |
|---|---|
-------- ---- code -------- | ----- ---- code ----- |
This includes lines inside nested blocks, because a line that matches the outer fence closes the outer block even there.
Example
The ==== sits inside a listing, but it would still close an example block fenced with ====.
So the fence of the example block shrinks only to five characters, not four.
| Before | After |
|---|---|
====== ---- ==== ---- ====== | ===== ---- ==== ---- ===== |
Left alone:
An open block and a Markdown fence. Each has only one valid length: two dashes for an open block and three backticks for a Markdown fence. So there is nothing to shorten.
A comment block, which
////opens. A comment block is a block of its own only where it stands alone. Otherwise, it is part of the metadata of the block below it. So a rewrite would depend on where the comment block sits rather than on what it holds. A[comment]makes a comment block only out of an open block. Above any other fence, Asciidoctor drops the style and reads the block that the delimiter names.A block that an include or a conditional reaches, inside its body or on the line above it. The directive may bring in exactly the line that a shorter fence would close on.
List markers
A list is written with one marker per kind: * for a bullet and . for a number.
One space separates the marker from the text.
| Before | After |
|---|---|
1. first 2. second - one - two | . first . second * one * two |
The numbers themselves carry no meaning.
Asciidoctor counts the items and only warns where the numbers differ from that count.
So 3. 4. 5. renders like . . ..
To start at another number, set the start attribute, which this rule leaves alone.
Left alone:
A list whose new marker is already used by a list around it or a list inside it. AsciiDoc tells nested lists apart by their markers, so the two lists would become one.
Example
The
*list is nested inside the-list because the marker changes. Once both lists use the same marker,nestedbecomes a second item of the outer list. Lists on the other side of a delimited block’s fence do not count, because a list that is open outside the block is not open inside it.Two levels One level - one * nested
* one * nested
a.,A.,i),I), the•bullet, description terms and callouts. Each of them expresses something that a*or a.cannot.Example
Before After a. alpha term:: text
a. alpha term:: text
A list that an include or a conditional reaches, next to the list or inside one of its items. Nothing marks the end of a list, so the items that a directive brings in may still belong to it. Their markers are known only after Asciidoctor resolves the directive.
The first line of a list, where a shorter line would read as a section title. The rest of the list keeps that line’s marker.
Example
A section title can be written over two lines. Asciidoctor takes the second line as the underline when its length is within one character of the first line.
A list A section title - item ~~~~~~
* item ~~~~~~
One sentence per line
The lines of a paragraph are joined and split again, so that every sentence starts on a line of its own.
| Before | After |
|---|---|
First sentence continues here. Second one. | First sentence continues here. Second one. |
A sentence ends at a ., ! or ? followed by whitespace and a word that starts with an uppercase letter.
Closing quotes, brackets and formatting marks after it belong to the sentence.
A period does not end a sentence after a digit, a single letter or a common English or German abbreviation such as Dr., e.g., z. B. or Nr..
An ellipsis does not end a sentence either.
A line that ends in a ., !, ? or : keeps its line break, even after a number, an abbreviation or ….
So a sentence may start with a lowercase word, code or a macro such as link:.
A hard line break stays where it is.
So does a line break inside code, a passthrough or a macro.
Left alone:
The text of a list item, including a description list entry. A paragraph attached to an item with a
+is reflowed like any other.Example
Before After * This item has two lines. They stay. + This paragraph is attached. It is reflowed.
* This item has two lines. They stay. + This paragraph is attached. It is reflowed.
A paragraph in a list, when one of its lines starts like a list item. Asciidoctor takes that line for the start of a nested list and leaves a
+below it to that list, so the page shows the+as text. Joined into the line above, the+would attach the next paragraph again.Example
The
- orline keeps the+below it on the page. Reflowed, the+would disappear from the page.Left alone Reflowed * Install the tool. + Pass the path as an argument - or set it in the config file. + Then run it.
* Install the tool. + Pass the path as an argument - or set it in the config file. + Then run it.
A paragraph whose line breaks show on the page. Verse and literal paragraphs show every line break. So does a paragraph with the
hardbreaksoption, set on the paragraph or for the whole document. A paragraph with its ownsubscan pass raw HTML through, and raw HTML can show a line break.Example
A verse paragraph keeps its line breaks on the page, so joining its lines would change what the page shows.
[verse] Roses are red. Violets are blue.
A paragraph below
:attribute-missing: drop-line, which sets how Asciidoctor treats missing attributes. Asciidoctor then drops every line that refers to a missing attribute, so the line breaks decide which sentences the page shows.A paragraph that holds a comment line. Joining its lines would pull the comment into the text, where it shows.
A paragraph right below an include, a conditional or front matter, with no blank line between. Asciidoctor may read it as part of a paragraph above it; see Heading markers. When the directive brings in a literal paragraph, the line breaks show.
A block that an extension may read in its own way. That is a block with a style Asciidoctor does not know, such as
[mermaid], and a paragraph that starts with a block macro it does not know, such asplantuml::diagram.puml[]. Which extensions are loaded depends on the build, which adocfmt cannot see.A paragraph that a joined or a split line would turn into something else. A line that starts like a list item, an attribute line or an admonition label is syntax, not text.
Example
A paragraph An admonition NOTE: the label stands alone.
NOTE: the label stands alone.