How to correctly customize equation numbering & referencing simultaneously?

Suppose I have custom equation numbering & referencing as follows.

#set math.equation(numbering: it => numbering("(1.1)", counter(heading).get().at(0), it)) 

#set heading(numbering: "1.1")

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

#show ref: it => {
    let el = it.element
    if (el != none and el.func() == math.equation) {
      let loc = el.location()
      return link(loc,numbering(
        el.numbering,
        ..counter(math.equation).at(loc)
      ))
    }
    return it
  }


= 

$ a^2 + b^2 = c^2 $ <eq>

= 

$ a^2 + b^2 = c^2 $

Now look at this reference: @eq.
It should say (1.1) but it says (2.1)

Notice that the equation referencing is wrong.
How would one go about fixing this?

I think the following solution is quite nice: Wrong numbering for the equation - #2 by Eric. Basically you don’t change the ref, but just reset the equation counter after each heading.

From what I can tell, the goal of the show rule on ref is to change the appearance of a reference from Equation 2.1 to just (2.1). The unfortunate thing is that you have to explicitly call numbering(..) in the show rule, so the numbering function set in the rule for equations is always called with the context of the reference (instead of the context of the equation itself). The only possible workaround I could think of right now, is using a regex show rule to remove the supplement like this:

#show ref: it => {
  let el = it.element
  if (el != none and el.func() == math.equation) {
    // May need to adjust this when using letters in numbering
    show regex("\p{letter}+\s+"): none
    it
  } else {
    it
  }
}

Other than that, there are some potentially related issues you could follow:

1 Like

Sad to hear this.

I’ve accepted your answer as the solution, however, I do hope that somebody comes up with something better.

This works for me. But it’s probably fragile.
Notice that where you had el.numbering, I have hardcoded “(1,1)”. So it’s not very flexible. Either the concept of “element” is not well documented, or I missed it. I wonder what el.numbering is and if it has structure that would be useful here.

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

    // Format equation references.
    // Uses the top-level heading number first
    #set math.equation(numbering: n => {
        numbering("(1.1)", counter(heading).get().first(), n)})

    // References to equations are modified from "Equation (x.y)"
    // to "(x.y)".
    // This is hacky because "(1.1)" is hardcoded.
    #show ref: it => {
        let eq = math.equation
        let el = it.element
        if el != none and el.func() == eq {
            link(el.location(),
                numbering(
                    "(1.1)",
                    counter(heading).at(el.location()).first(),
                    counter(eq).at(el.location()).first()
                )
            )
        } else {
            // Other references as usual.
            it
        }
    }

If I use el.numbering rather than “(1.1)”, then I get an error:

error: unexpected argument
   ┌─ lib/gjl_template.typ:33:34
   │
33 │     #set math.equation(numbering: n => {
   │                                   ^

I am not sure if I understand completely, but if you want to reference only the number you can use empty brackets after the reference.
E.g.
@eq:derivative \\ this yields Equation 4.2
@eq:derivative[] \\ this yields 4.2

1 Like

I confirm this works.

I missed this before, but it is documented in the subheading “Syntax” on the documentation page for ref

I should note that if you have asked for parentheses, for example with numbering("(1.1)",..., then you get, following your example (4.2) rather than Equation (4.2).

It would be cleaner are more flexible to change the behavior with a bit of code in one place. But appending [] does work.