Counters

Counters are used to store and display ad-hoc sequences of numbers or Latin characters.

Counters are a poorly defined feature in AsciiDoc and should be avoided if possible. If you do use counters, you should only used them for the most rudimentary use cases, such as making a sequence in a list, table column, or prose. You should not use counters to build IDs (i.e., references) or reference text. Using counters across the boundaries of a reference will very likely result in unexpected behavior.

A counter is implemented as a specialized document attribute. You declare and display a counter using an attribute reference, where the attribute name is prefixed with counter: (e.g., {counter:name}). Since counters are attributes, counter names follow the same rules as attribute names. The most important rule to note is that letters in counter names must be lowercase.

The counter value is incremented and displayed every time the counter: attribute reference is resolved. The term increment means to advance the attribute value to the next value in the sequence. If the counter value is an integer, add 1. If the counter value is a character, move to the next letter in the Latin alphabet (e.g., a → b). The default start value of a counter is 1.

To create a sequence starting at 1, use the simple form {counter:name} as shown here:

The salad calls for {counter:seq1}) apples, {counter:seq1}) oranges and {counter:seq1}) pears.

Here’s the resulting output:

The salad calls for 1) apples, 2) oranges and 3) pears.

If you want to use a counter value in a section title, you should define it first using an attribute reference.

:seq1: {counter:seq1}
== Section {seq1}

The sequence in this section is {seq1}.

:seq1: {counter:seq1}
== Section {seq1}

The sequence in this section is {seq1}.

Here’s the resulting output:

Section 1

The sequence in this section is 1.

Section 2

The sequence in this section is 2.

To increment the counter without displaying it (i.e., to skip an item in the sequence), use the counter2 prefix instead:

{counter2:seq1}
A counter2 attribute reference on a line by itself will produce an empty paragraph. You’ll need to adjoin it to the nearest content to avoid this side effect.

To display the current value of the counter without incrementing it, reference the counter name as you would any other attribute:

{counter2:pnum}This is paragraph {pnum}.

To create a character sequence, or start a number sequence with a value other than 1, specify a start value by appending it to the first use of the counter:

Dessert calls for {counter:seq1:A}) mangoes, {counter:seq1}) grapes and {counter:seq1}) cherries.
Character sequences either run from a,b,c,…​x,y,z,{,|…​ or A,B,C,…​,X,Y,Z,[,…​ depending on the start value. Therefore, they aren’t really useful for more than 26 items.

The start value of a counter is only recognized if the counter is unset at that point in the document. Otherwise, the start value is ignored.

To reset a counter attribute, unset the corresponding attribute using an attribute entry. The attribute entry must be adjacent to a block or else it is ignored.

The salad calls for {counter:seq1:1}) apples, {counter:seq1}) oranges and {counter:seq1}) pears.

:!seq1:
Dessert calls for {counter:seq1:A}) mangoes, {counter:seq1}) grapes and {counter:seq1}) cherries.

This gives:

The salad calls for 1) apples, 2) oranges and 3) pears.

Dessert calls for A) mangoes, B) grapes and C) cherries.

Here’s a full example that shows how to use a counter for part numbers in a table.

.Parts{counter2:index:0}
|===
|Part Id |Description

|PX-{counter:index}
|Description of PX-{index}

|PX-{counter:index}
|Description of PX-{index}
|===

Here’s the output of that table:

Parts
Part Id Description

PX-1

Description of PX-1

PX-2

Description of PX-2