I think that’s a smart approach.
- A bug fix: we need to remove the label from fields, then references to labelled headings will work
- I explored a derived solution that creates parallel heading elements, visible ones and hidden bookmarked ones (idea from Andrew’s comment here: Different heading text for outline/bookmark and displaying · Issue #1889 · typst/typst · GitHub). Relying on a
show: none
heading to be part of the bookmarks maybe still feels like exploiting a quirk that is likely to be fixed sooner or later… I don’t know which way to prefer, it’s a matter of style or judgment.
Code, yours but lightly modified
// Remove original headings from bookmarks. We will add new ones later.
#set heading(bookmarked: false)
#outline()
#show heading: it => if it.numbering == none {
// This heading has been processed. Keep it untouched.
it
} else {
let (numbering, body, ..args) = it.fields()
let _ = args.remove("label", default: none)
// Render the numbering manually
let numbered-body = block({
counter(heading).display(numbering)
[ ] // space in the bookmark
body
})
// regular heading
it
// Add our bookmarked, hidden heading
show heading: none
heading(..args, outlined: false, bookmarked: true, numbering: none, numbered-body)
}
#set heading(numbering: "1.1")
= A
== B <section>
= C
See section @section
#pagebreak()
#counter(heading).update(0)
= D