注意 / Info
本站经 Typst GmbH 许可,提供 Typst v0.10.0+后期随缘更新 官方文档的翻译,由中文社区维护。建议与官方文档一同阅读,因为可能存在错译、漏译或过时信息。如有意改进翻译内容或网站本身,可在GitHub上提出 Issue、发起 Pull Requests。此外,也欢迎加入「Typst 非官方中文交流群」(QQ 793548390)
This site provides a Chinese translation of the Typst v0.10.0+后期随缘更新 documentation maintained by the “Typst Chinese Community” with permission from Typst GmbH. We recommend using this alongside the official documentation. We welcome contributions through Issues and Pull Requests on our GitHub repository for both translation improvements and website enhancements. Feel free to join our QQ chat group “Typst 非官方中文交流群” (793548390).
Typst文档简体中文版
v0.10.0+后期随缘更新

counter

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.

Displaying a counter

To display the current value of the heading counter, you call the counter function with the key set to heading and then call the display method on the counter. To see any output, you also have to enable heading numbering.

The display method optionally takes an argument telling it how to format the counter. This can be a numbering pattern or a function.

#set heading(numbering: "1.")

= Introduction
Some text here.

= Background
The current value is:
#counter(heading).display()

Or in roman numerals:
#counter(heading).display("I")
Preview

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 (in the case of headings for sections, subsections, and so on), the step method 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 multiple for multiple levels). For more flexibility, you can instead also give it a function that gets 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.

#set heading(numbering: "1.")

= Introduction
#counter(heading).step()

= Background
#counter(heading).update(3)
#counter(heading).update(n => n * 2)

= Analysis
Let's skip 7.1.
#counter(heading).step(level: 2)

== Analysis
Still at #counter(heading).display().
Preview

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

#let mine = counter("mycounter")
#mine.display() \
#mine.step()
#mine.display() \
#mine.update(c => c * 3)
#mine.display() \
Preview

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.

#let c = counter("theorem")
#let theorem(it) = block[
  #c.step()
  *Theorem #c.display():* #it
]

#theorem[$1 = 1$]
#theorem[$2 < 3$]
Preview

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).

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.

#set page(numbering: "(i)")

= Preface
The preface is numbered with
roman numerals.

#set page(numbering: "1 / 1")
#counter(page).update(1)

= Main text
Here, the counter is reset to one.
We also display both the current
page and total number of pages in
Arabic numbers.
Preview

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.

#let mine = counter("mycounter")

= Values
#locate(loc => {
  let start-val = mine.at(loc)
  let elements = query(<intro>, loc)
  let intro-val = mine.at(
    elements.first().location()
  )
  let final-val = mine.final(loc)
  [Starts as: #start-val \
   Value at intro is: #intro-val \
   Final value is: #final-val \ ]
})

#mine.update(n => n + 3)

= Introduction <intro>
#lorem(10)

#mine.step()
#mine.step()
Preview

Let's dissect what happens in the example above:

  • We call locate to get access to the current location in the document. We then pass this location to our counter's at method to get its value at the current location. The at method always returns an array because counters can have multiple levels. As the counter starts at zero, the first value is thus (0,).

  • We now query the document for all elements with the <intro> label. The result is an array from which we extract the first (and only) element's location. We then look up the value of the counter at that location. The first update to the counter sets it to 0 + 3 = 3. At the introduction heading, the value is thus (3,).

  • Last but not least, we call the final method on the counter. It tells us what the counter's value will be at the end of the document. We also need to give it a location to prove that we are inside of a locate call, but which one doesn't matter. After the heading follow two calls to step(), so the final value is (5,).

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.

构造函数
参数
参数是传给函数的输入,写在函数名后的括号中。

Create a new counter identified by a key.

key
必需参数
必需参数
必需参数在调用函数时必须传入。
位置参数
位置参数
位置参数按顺序传入,不带参数名。

The key that identifies this counter.

  • If it is a string, creates a custom counter that is only affected by manual updates,
  • If this is a <label>, counts through all elements with that label,
  • If this is an element function or selector, counts through its elements,
  • If this is the page function, counts through pages.

定义
定义
这些函数和类型带有附属定义。要访问这种定义,请先写上函数或类型的名称,再加上定义的名称,并用句点在中间分隔。

display

Displays the current value of the counter.

numbering
位置参数
位置参数
位置参数按顺序传入,不带参数名。

A numbering pattern or a function, which specifies how to display the counter. If given a function, that function receives each number of the counter as a separate argument. If the amount of numbers varies, e.g. for the heading argument, you can use an argument sink.

If this is omitted, displays the counter with the numbering style for the counted element or with the pattern "1.1" if no such style exists.

默认值:

none

both

If enabled, displays the current and final top-level count together. Both can be styled through a single numbering pattern. This is used by the page numbering property to display the current and total number of pages when a pattern like "1 / 1" is given.

默认值:

false

step

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.

self.step()->

level

The depth at which to step the counter. Defaults to 1.

默认值:

1

update

Updates the value of the counter.

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

self.update(
intarrayfunctioncounter-update
)->

update
intarrayfunctioncounter-update
必需参数
必需参数
必需参数在调用函数时必须传入。
位置参数
位置参数
位置参数按顺序传入,不带参数名。

If given an integer or array of integers, sets the counter to that value. If given a function, that function receives the previous counter value (with each number as a separate argument) and has to return the new value (integer or array).

at

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

self.at()->

location
必需参数
必需参数
必需参数在调用函数时必须传入。
位置参数
位置参数
位置参数按顺序传入,不带参数名。

The location at which the counter value should be retrieved. A suitable location can be retrieved from locate or query.

final

Gets 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.

self.final()->

location
必需参数
必需参数
必需参数在调用函数时必须传入。
位置参数
位置参数
位置参数按顺序传入,不带参数名。

Can be an arbitrary location, as its value is irrelevant for the method's return value. Why is it required then? Typst has to evaluate parts of your code multiple times to determine all counter values. By only allowing this method within locate calls, the amount of code that can depend on the method's result is reduced. If you could call final directly at the top level of a module, the evaluation of the whole module and its exports could depend on the counter's value.

转到官方文档(英文)

搜索