Due to automatic counter step behavior when placing any heading, I’d recommend using a separate counter which you manually control, like below.
Note that I’ve taken the additional step of updating the heading counter to ensure it is consistent with the separate counter, ensuring we don’t have to rebuild headings entirely to start using the new counter, but rather keep headings as they are, using counter(heading)
like they always do. This also ensures they show up correctly in the outline without having to take any additional steps.
#let third-heading-counter = counter("third-heading-level")
#show selector.or(heading.where(level: 1), heading.where(level: 2)): it => {
it
// Revert level 3+ resets
context {
let new-numbers = third-heading-counter.get()
counter(heading).update(if it.level == 1 {
(one, ..n) => (one, 0, ..new-numbers)
} else {
(one, two, ..n) => (one, two, ..new-numbers)
})
}
}
#show heading: it => {
if it.level >= 3 {
third-heading-counter.step(level: it.level - 2)
}
it
}
// Sample:
#set page(width: 200pt, height: auto, margin: 0.5cm)
#set heading(numbering: "1.")
= A
== B
=== C
==== CC
== D
==== DD
=== E
==== EE
=== F
If you’d like to not display the first two numbers for level 3+ headings, you can selectively change their numbering by adding the following statements at the start, before all the headings:
#show heading.where(level: 1): set heading(numbering: "1.")
#show heading.where(level: 2): set heading(numbering: "1.")
// For level 3+: ignore first two numbers
#set heading(numbering: (first, second, ..n) => numbering("1.", ..n))
If you do this, I recommend using indent: auto
or indent: 2em
in your outline
to avoid ambiguity between 2.1. (level 2 heading) and 2.1. (level 4 heading), for example.