Typst Fumadocs

Counter

Documentation for the Counter type.

Counts through pages, elements, and more.

With the counter function, you can access and modify counters for pages, headings, figures, and more. Moreover, you can define custom counters for other things you want to count.

Since counters change throughout the course of the document, their current value is contextual. It is recommended to read the chapter on context before continuing here.

Accessing a counter

To access the raw value of a counter, we can use the get function. This function returns an array: Counters can have multiple levels (in the case of headings for sections, subsections, and so on), and each item in the array corresponds to one level.

Loading compiler...

Displaying a counter

Often, we want to display the value of a counter in a more human-readable way. To do that, we can call the display function on the counter. This function retrieves the current counter value and formats it either with a provided or with an automatically inferred numbering.

Loading compiler...

Modifying a counter

To modify a counter, you can use the step and update methods:

  • The step method increases the value of the counter by one. Because counters can have multiple levels , it optionally takes a level argument. If given, the counter steps at the given depth.
  • The update method allows you to arbitrarily modify the counter. In its basic form, you give it an integer (or an array for multiple levels). For more flexibility, you can instead also give it a function that receives the current value and returns a new value.

The heading counter is stepped before the heading is displayed, so Analysis gets the number seven even though the counter is at six after the second update.

Loading compiler...

Page counter

The page counter is special. It is automatically stepped at each pagebreak. But like other counters, you can also step it manually. For example, you could have Roman page numbers for your preface, then switch to Arabic page numbers for your main content and reset the page counter to one.

Loading compiler...

Custom counters

To define your own counter, call the counter function with a string as a key. This key identifies the counter globally.

Loading compiler...

How to step

When you define and use a custom counter, in general, you should first step the counter and then display it. This way, the stepping behaviour of a counter can depend on the element it is stepped for. If you were writing a counter for, let's say, theorems, your theorem's definition would thus first include the counter step and only then display the counter and the theorem's contents.

Loading compiler...

The rationale behind this is best explained on the example of the heading counter: An update to the heading counter depends on the heading's level. By stepping directly before the heading, we can correctly step from 1 to 1.1 when encountering a level 2 heading. If we were to step after the heading, we wouldn't know what to step to.

Because counters should always be stepped before the elements they count, they always start at zero. This way, they are at one for the first display (which happens after the first step).

Time travel

Counters can travel through time! You can find out the final value of the counter before it is reached and even determine what the value was at any particular location in the document.

Loading compiler...

Other kinds of state

The counter type is closely related to state type. Read its documentation for more details on state management in Typst and why it doesn't just use normal variables for counters.

Constructor

Create a new counter identified by a key.

#counter(
  key
) -> counter

Parameters

Prop

Type

Methods

Retrieves the value of the counter at the current location. Always returns an array of integers, even if the counter has just one number.

This is equivalent to counter.at(here()).

Displays the value of the counter.

You can provide both a custom numbering and a custom location. Both default to auto, selecting sensible defaults (the numbering of the counted element and the current location, respectively).

Returns the formatted output.

#counter.display(
  numbering,
  at: auto | label | selector | location | function,
  both: bool
) -> any

Parameters

Prop

Type

Retrieves the value of the counter at the given location. Always returns an array of integers, even if the counter has just one number.

The selector must match exactly one element in the document. The most useful kinds of selectors for this are labels and locations.

#counter.at(
  selector
) -> int array

Parameters

Prop

Type

Retrieves the value of the counter at the end of the document. Always returns an array of integers, even if the counter has just one number.

Increases the value of the counter by one.

The update will be in effect at the position where the returned content is inserted into the document. If you don't put the output into the document, nothing happens! This would be the case, for example, if you write let _ = counter(page).step(). Counter updates are always applied in layout order and in that case, Typst wouldn't know when to step the counter.

#counter.step(
  level: int
) -> content

Parameters

Prop

Type

Updates the value of the counter.

Just like with step, the update only occurs if you put the resulting content into the document.

#counter.update(
  update
) -> content

Parameters

Prop

Type

On this page