How can I only number labeled equation blocks?

I want the following:

  1. Only number labeled/referenced equations.
  2. Only number equation blocks, not individual equation lines.

How can I accomplish this?

After much coaxing I got the bot to spit out:

#set math.equation(numbering: "(1)")
#show math.equation: it => {
    if it.block and not it.has("label") [
        #counter(math.equation).update(v => v - 1)
        #math.equation(
            it.body,
            block: true,
            numbering: none,
        )#label("p")
    ] else {
        it
    }
}

But this seems like a hack for what should be a builtin feature of Typst. Is there a better way?

Well, here’s a better workaround, at least:

#set math.equation(numbering: none)
#show: body => context {
  let labels = query(math.equation.where(block: true))
    .filter(eq => eq.has("label"))
    .map(eq => eq.label)
    .dedup()
  if labels.len() > 0 {
    show selector.or(..labels): set math.equation(numbering: "(1)")
    body
  } else {
    body
  }
}

$ A $<l1>
$ a + b $<l2>
$ c + d $

Which is based on something that @Eric has shared before I think. Idea: find all relevant labels, then let the style system apply numbering to just them. It’s a better workaround because creating new math.equation elements has various unwanted side effects, including causing problems for references.

1 Like

There’s an open issue about better equation numbering: Fine grained equation numbering control · Issue #380 · typst/typst · GitHub

The team prioritises issues with more likes, so if this is something that you feel is missing from the language I’d encourage you to upvote the issue :slight_smile:

To add to @bluss’s answer, I personally find it nicer if the numbering is enabled only if the equation is referenced in the document. You can acheive this by slightly tweaking the conditional:

if labels.len() == 0 {
  return body
}
let referenced-labels = query(
  selector.or(..labels.map(
    label => ref.where(target: label)
  ))
).map(it => it.target)
if referenced-labels.len() == 0 {
  return body
}

show selector.or(..referenced-labels): set math.equation(numbering: "(1.1)")
body
1 Like