How can I show the heading number after the heading itself?

I want to make it so

= Section
== Subsection

shows as
1 Section
Subsection 1.1

I tried doing that using

#show heading.where(level: 2): it => box(strong(it.body + " "))

but that just shows the heading format string

You can get the heading number from the built-in counter. The counter requires context to evaluate/display, and the block is used to get the default behavior of a heading.

#set heading(numbering: "1.1")
#show heading.where(level: 2): it => context block(
  it.body + [ ] + counter(heading).display()
)

= A Section
== A Subsection
== Another Subsection

Hello. For this, you would have to recreate the default heading show rule from scratch and change its behavior:

#import "@preview/text-dirr:1.0.0": text-dir

#set heading(numbering: "1.")

#show heading.where(level: 2): it => {
  let spacing = h(0.3em, weak: true)
  let numbering = counter(heading).display(it.numbering)
  let realized = it.body + spacing + numbering
  let indent = if it.hanging-indent == auto { 0pt } else { it.hanging-indent }
  if it.hanging-indent == auto { indent = measure(numbering).width + 0.3em }
  let start = if text-dir() == ltr { "left" } else { "right" }
  block(inset: ((start): indent), h(-indent) + realized)
}

= Section
== Subsection
#heading(depth: 2, hanging-indent: 5em, numbering: "I.")[#lorem(15)]

image

Now that the text-dirr package is out, so you can fully copy the default behavior that uses “start” alignment or side, which depends on text.dir.

For full heading implementation, see Add default typst implementation code where possible · Issue #5095 · typst/typst · GitHub. Since the numbering is now not at the start, I don’t know if you need auto hanging indent or hanging indent at all. If not, then you can simply do this:

#show heading.where(level: 2): it => block(
  it.body + h(0.3em, weak: true) + counter(heading).display(it.numbering),
)

Hi @Amasica, welcome to the forum! Don’t forget to tick :ballot_box_with_check: one of the responses if you got a satisfying answer. The answer you choose should usually be the response that you found most correct/helpful/comprehensive for the question you asked. Thanks!