How can I number equations within sections?

I want a command similar to LaTeXs \numberwithin{equation}{section}.

So e.g. the 5th equation in chapter 2 should have the number (2.5). How can I achieve this? Is there a package that does this?

On Discord, I found some old code that works, but the compiler gives the warning that this uses the deprecated locate function so I would assume that this is not the canonical way to do this. What is?

(I feel like the most user friendly would be a package that does this under the hood and gets updated every time a new version of typst deprecates some of the used code. Has anyone written or seen this?)

The code on Discord as a reference:

#set heading(numbering: "1.")
#let chaptercounter=counter("chapter")
#let equationcounter=counter(math.equation)

#show heading.where(level:1): it => {
  chaptercounter.step()
  equationcounter.update(0)
  it
}

#set math.equation(numbering: it => {
locate(loc => {
let count = chaptercounter.at(loc).first()
numbering("(1.1)", count, it)
})})

= Section

$ 5 + 3 = 8 $
$ 5 + 3 = 8 $

= New Section
== Test

$ 5 + 3 = 8 $ <thiseq>
== Test 2
$ 5 + 3 = 8 $

Try replacing the set rule for math.equation with this:

#set math.equation(numbering: it => {
  let count = chaptercounter.get().first()
  numbering("(1.1)", count, it)
})

From the docs for locate:

In Typst 0.10 and lower, the locate function took a closure that made the current location in the document available (like here does now).

… and .get() is the same as .at(here()) (see documentation for .get())

I get what you’re saying about this being dropped into a package to be user-friendly, and there very well may be a package that might manage this. However, I find one of the great features of Typst is using set and show rules to precisely style your document. This has the added benefit of having only minimal package dependencies (in contrast to LaTeX).

1 Like

There are counting packages. Both headcount and rich-counters might be useful for your usecase.

I used what you suggested and changed it a bit to be:

#set heading(numbering: "1.")
#show heading.where(level:1): it => {
  counter(math.equation).update(0)
  it
}

#set math.equation(
  numbering: it => {
    let count = counter(heading.where(level: 1)).at(here()).first()
    if count >0 {
      numbering("(1.1)", count, it)
    } else {
      numbering("(1)",it)
    }
  }
)

What can be a good way to implement it also for a minimal theorem that is defined in the template like this:

#show figure.where(kind: "thm"): it => [
  / #it.supplement #context(it.counter.display(it.numbering)).: #it.body
]
#let thm(it) = figure(
  kind: "thm",
  supplement: "Theorem",
  caption: none,
  placement: none, 
  it
) 

More suggestions are welcomed :slight_smile:

1 Like

I tried to use both packages but failed to get a correct numbering given the fact, that I start my section numbering at 0, because they assume, that it starts at 1 and therefore give me one too high section counter.

Thank you! I changed it a bit to work for my usecase where I start my section numbering at 0 and it works!

The full code I use is:

#show heading.where(level:1): it => {
  counter(math.equation).update(0)
  it
}


 #set math.equation(numbering: it => {
    let count = counter(heading.where(level: 1)).at(here()).first()
    if count > 0 and start_section_numbering_at_0 {
      numbering("(1.1)", count - 1, it)
    }
    else {
      numbering("(1.1)", count, it)
    }
})
1 Like