When a heading has letter numbering, the dot is included in the references

A reference to @characters[Appendix] produces “Appendix A.” (including the full stop). I’d like it to produce “Appendix A” (without the full stop). Is there a straightforward way to do this?

// This code for heading numbering taken from https://forum.typst.app/t/how-can-i-prevent-level-1-headings-from-being-numbered/5884
#show heading.where(level: 1): set heading(numbering: none)
#set heading(numbering: (first, ..nums) => numbering("A.", ..nums))
= Appendix
== Characters <characters>

From message by @Eric:

it’s intended that it strips prefixes and suffixes from numbering pattern strings, so that when you have e.g. numbering "1." for headings, it doesn’t show “Section 1.” but only “Section 1”. This can’t be automatically done for custom numbering functions as we can’t know what happens inside them

More flexible separators in numbering patterns · Issue #905 · typst/typst · GitHub seems like the issue, though not precisely. Also https://typst.app/docs/reference/model/numbering/#numbering-patterns-and-numbering-functions still doesn’t explain this, which is not good.

Hmm, similar to how you can change figure supplement for figure vs. reference using context, the same can be done with heading numbering:

#set heading(numbering: "A.")
= Heading
== Heading
== Heading <good>

@good

#show heading.where(level: 1): set heading(numbering: none)
#set heading(numbering: (_, ..n) => numbering("A.", ..n))
=== Heading <bad>
@bad

#let in-ref = state("in-ref", false)
#show ref: it => in-ref.update(true) + it + in-ref.update(false)

#set heading(numbering: (_, ..n) => context {
  if in-ref.get() { numbering("A.A", ..n) } else { numbering("A.", ..n) }
})
=== Heading <works>
@works

Not sure if there are any edge cases. I guess you can make it potentially more reliable by checking for heading instead of ref:

#let in-heading = state("in-heading", false)
#show heading: it => in-heading.update(true) + it + in-heading.update(false)

#set heading(numbering: (_, ..n) => context {
  if in-heading.get() { numbering("A.", ..n) } else { numbering("A.A", ..n) }
})

@Eric found one: Option to hide last dot in refs to heading that had custom numbering. · Issue #6032 · typst/typst · GitHub.

In this specific instance, I only have two such references in the document, and both by coincidence happen to be at the ends of sentences, so it’s fine and I’ll leave it untouched. It’s just good to know that this is a genuine problem and I’m not missing something obvious.