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)]
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),
)