How to referencing custom numbering for appendicies

I am trying to create appendices for a report and would like to reference them in earlier sections, I have managed to make the headings having numbering like this

== content

And it displays like this

Appendix A: content

using this

#let unary(.., last) = "Appendix " + context str.from-unicode(last+64) + ":"  
#set heading(numbering: unary)

Referencing it in the text creates a reference like this

Section Appendix A:

I would like it to only have Appendix A in the text.
Any help with this would be fantastic.
Thanks

Unfortunately, it is a bit complicated, at least I wasn’t able to come up with something simpler :/. You have to modify the element in ref to replace the last colon with nothing (you could also rebuild the entire reference):

#show ref: it => {
  if it.element != none and it.element.func() == heading {
    show regex(":$"): none
    it
  } else {
    it
  }
}

To remove the prefix “Section” you have to set the supplement to none.

#set heading(numbering: unary, supplement: none)

In your numbering function context isn’t needed for from-unicode and instead of from-unicode Typst has a dedicated numbering function.
In addition, I modified your function to make it more robust (support multiple appendix levels).

#let unary(_, ..last) = "Appendix " + numbering("A.1", ..last) + ":"
1 Like

In several cases, it has proven to be better not to use the numbering for displaying other text along with the number because of the numerous side effects.

A solution which might be more idiomatic and that does not require hacking into ref would be the following.

#set heading(numbering: "A", supplement: [Appendix])
#show heading: it => block({
  [#it.supplement ]
  counter(heading).display(it.numbering)
  [: #it.body]
})

This is using the supplement for exactly what it is supposed to be used and there will be no interference with headings. The appearance of the heading is styled through a corresponding show rule.

Both solutions are valid and produce different effects. This includes

  • whether the word “Appendix” shows up in the outline.
  • whether the word “Appendix” is included in the PDF outline when exporting the document
3 Likes

Thank you, I now understand how supplement works, but as you said, the key difference is how they show in the outline. With your solution, I have tried but I can not figure out how to have Appendix A show in the outline.

Additionally, I am using a level 2 heading so with numbering:"A" it shows as Appendix AA:.

If you are able to provide any help, that would be great.
Thanks heaps

1 Like

Thanks for sharing, I agree this is a lot less hacky.

Additionally, I am using a level 2 heading so with numbering:"A" it shows as Appendix AA:.

For this just refine the show rule to show heading.where(level: 1): ...

Thank you, I now understand how supplement works, but as you said, the key difference is how they show in the outline. With your solution, I have tried but I can not figure out how to have Appendix A show in the outline.

This is of course a valid argument. It is still possible to solve it via something like this:

#show outline.entry: it => {
  if it.element.supplement != [Appendix] { return it }
  it.indented(
    [#it.element.supplement #it.prefix():],
    it.inner()
  )
}

All in all:

#show outline.entry: it => {
  if it.element.supplement != [Appendix] { return it }
  it.indented(
    [#it.element.supplement #it.prefix():],
    it.inner()
  )
}

#let appendix(body) = {
  set heading(numbering: "A", supplement: [Appendix])

  show heading.where(level: 1): it => block({
    [#it.supplement ]
    counter(heading).display(it.numbering)
    [: #it.body]
  })
  counter(heading).update(0)
  body
}

// Main text

#show: appendix

= Content // Appendix A

But now one could argue that it’s getting quite complicated. Anyway, this is just for demonstration/learning of how Typst works and what is possible!

2 Likes

Thank you for all your help. I understand this better now.

1 Like