This package allows you to have counters which can inherit from other counters.
Concretely, it implements rich-counter
, which is a counter that can inherit one or more levels from another counter.
The interface is pretty much the same as the usual counter. It provides a display()
, get()
, final()
, at()
, and a step()
method. An update()
method will be implemented soon.
Simple typical Showcase
In the following example, mycounter
inherits the first level from heading
(but not deeper levels).
#import "@preview/rich-counters:0.2.2": *
#set heading(numbering: "1.1")
#let mycounter = rich-counter(identifier: "mycounter", inherited_levels: 1)
// DOCUMENT
Displaying `mycounter` here: #context (mycounter.display)()
= First level heading
Displaying `mycounter` here: #context (mycounter.display)()
Stepping `mycounter` here. #(mycounter.step)()
Displaying `mycounter` here: #context (mycounter.display)()
= Another first level heading
Displaying `mycounter` here: #context (mycounter.display)()
Stepping `mycounter` here. #(mycounter.step)()
Displaying `mycounter` here: #context (mycounter.display)()
== Second level heading
Displaying `mycounter` here: #context (mycounter.display)()
Stepping `mycounter` here. #(mycounter.step)()
Displaying `mycounter` here: #context (mycounter.display)()
= Aaand another first level heading
Displaying `mycounter` here: #context (mycounter.display)()
Stepping `mycounter` here. #(mycounter.step)()
Displaying `mycounter` here: #context (mycounter.display)()
Construction of a rich-counter
To create a rich-counter
, you have to call the rich-counter(...)
function. It accepts three arguments:
-
identifier
(required)Must be a unique
string
which identifies the counter. -
inherited_levels
Specifies how many levels should be inherited from the parent counter.
-
inherited_from
(Default:heading
)Specifies the parent counter. Can be a
rich-counter
or any key that is accepted by thecounter(...)
constructor, such as alabel
, aselector
, alocation
, or afunction
likeheading
. If not specified, defaults toheading
(and hence it will inherit from the counter of the headings).If it’s a
rich-counter
andinherited_levels
is not specified, theninherited_levels
will default to one level higher than the givenrich-counter
.
For example, the following creates a rich-counter
foo
which inherits one level from the headings, and then another rich-counter
bar
which inherits two levels (implicitly) from foo
.
#import "@preview/rich-counters:0.2.2": *
#let foo = rich-counter(identifier: "foo", inherited_levels: 1)
#let bar = rich-counter(identifier: "bar", inherited_from: foo)
Usage of a rich-counter
-
display(numbering)
(needscontext
)Displays the current value of the counter with the given numbering style. Giving the numbering style is optional, with default value
"1.1"
. -
get()
(needscontext
)Returns the current value of the counter (as an
array
). -
final()
(needscontext
)Returns the value of the counter at the end of the document.
-
at(loc)
(needscontext
)Returns the value of the counter at
loc
, whereloc
can be alabel
,selector
,location
, orfunction
. -
step(depth: 1)
Steps the counter at the specified
depth
(default:1
). That is, it steps therich-counter
at levelinherited_levels + depth
.
Due to a Typst limitation, you have to put parentheses before you put the arguments. (See below.)
For example, the following steps mycounter
(at depth 1) and then displays it.
#import "@preview/rich-counters:0.2.2": *
#let mycounter = rich-counter(...)
#(mycounter.step)()
#context (mycounter.display)("1.1")
Limitations
Due to current Typst limitations, there is no way to detect manual updates or steps of Typst-native counters, like counter(heading).update(...)
or counter(heading).step(...)
. Only occurrences of actual heading
s can be detected. So make sure that after you call e.g. counter(heading).update(...)
, you place a heading directly after it, before you call any rich-counter
s.
Roadmap
- implement
update()
- use Typst custom types as soon as they become available
- adopt native Typst implementation of dependent counters as soon it becomes available