How can I prevent level 1 headings from being numbered?

Can I exclude level 1 headings from numbering while numbering all subsequent headings (level 2 and below) as “1.1”?

#show heading.where(
  level: 1
): it => block(width: 100%)[
  #set align(center)
  #set text(
    size: 20pt,
    weight: "bold",
    font: ("Poppins","Noto Serif CJK SC"),
  )
  #counter(heading).display(it.numbering)
  #smallcaps(it.body)
]

#show heading.where(
  level: 2
): it => block(width: 100%, below: 1.0em)[
  #set align(left)
  #set text(
    size: 18pt,
    weight: "bold",
    font: ("Poppins","Noto Serif CJK SC"),
    fill: rgb("#045bac")
  )
  #counter(heading).display(it.numbering)
  #smallcaps(it.body)
]

#show heading.where(
  level: 3
): it => block(width: 100%, below: 1.2em)[
  #set align(left)
  #set text(
    size: 14pt,
    weight: "regular",
    font: ("Poppins","Noto Serif CJK SC"),
    fill: rgb("#062f56")
  )
  #counter(heading).display(it.numbering)
  #smallcaps(it.body)
]

 
#set heading(numbering: "1.1")

I want to achieve:

Level 2 heading numbering: 1 2 3…
Level 3 heading numbering: 1.1, 1.2, 1.3…
And so on.

In the code above, if I remove the #counter(heading).display(it.numbering) from the first-level heading, the second-level headings become 1.1, 1.2…, which doesn’t match my desired outcome.

I’d be very grateful if you could tell me how to achieve this.

Hi there @ozzyc,

Two suggestions:

  1. You could use a numbering function:
#show heading.where(level: 1): set heading(numbering: none)
#set heading(numbering: (first, ..nums) => numbering("1.", ..nums))

  1. Or use the package numbly – Typst Universe with:
#import "@preview/numbly:0.1.0": numbly
#set heading(numbering: numbly(
  "",
  "{1}",
  "{1}.{2}",
  "{1}.{2}.{3}", // as needed
))

EDIT:

If we apply to your code (I have commented the font lines to be able to compile),

Your code
#show heading.where(level: 1): set heading(numbering: none)
#set heading(numbering: (chapter, ..n) => numbering("1.", ..n))

#show heading.where(
  level: 1
): it => block(width: 100%)[
  #set align(center)
  #set text(
    size: 20pt,
    weight: "bold",
  //  font: ("Poppins","Noto Serif CJK SC"),
  )
  //#counter(heading).display(it.numbering)
  #smallcaps(it.body)
]

#show heading.where(
  level: 2
): it => block(width: 100%, below: 1.0em)[
  #set align(left)
  #set text(
    size: 18pt,
    weight: "bold",
  //  font: ("Poppins","Noto Serif CJK SC"),
    fill: rgb("#045bac")
  )
  #counter(heading).display(it.numbering)
  #smallcaps(it.body)
]

#show heading.where(
  level: 3
): it => block(width: 100%, below: 1.2em)[
  #set align(left)
  #set text(
    size: 14pt,
    weight: "regular",
//    font: ("Poppins","Noto Serif CJK SC"),
    fill: rgb("#062f56")
  )
  #counter(heading).display(it.numbering)
  #smallcaps(it.body)
]
 
= Test
== Test
=== Test
==== Test
= Test
== Test
=== Test
==== Test

Edit2:
Following:

and with a bit of cleanup to reduce the usage of show rules (your should prioritize show-set rules):

#set heading(numbering: (first, ..nums) => numbering("1.", ..nums))
#show heading: smallcaps
#show heading: set align(left)
#show heading: set block(width: 100%)

#show heading.where(level: 1): set heading(numbering: none)
#show heading.where(level: 1): set align(center)
#show heading.where(level: 1): set text(
  size: 20pt,
  weight: "bold",
  //  font: ("Poppins","Noto Serif CJK SC"),
)

#show heading.where(level: 2): set block(below: 1.0em)
#show heading.where(level: 2): set text(
  size: 18pt,
  weight: "bold",
  //  font: ("Poppins","Noto Serif CJK SC"),
  fill: rgb("#045bac"),
)

#show heading.where(level: 3): set block(below: 1.2em)
#show heading.where(level: 3): set text(
  size: 14pt,
  weight: "regular",
  //  font: ("Poppins", "Noto Serif CJK SC"),
  fill: rgb("#062f56"),
)
3 Likes

Hello.

#set heading(numbering: (..n) => numbering("1.1", ..n.pos().slice(1)))
#show heading.where(level: 1): set heading(numbering: none)
= First level
== Second level
=== Third level
==== Fourth level

Though, to address the rest of the code:

// #show heading: set text(font: ("Poppins", "Noto Serif CJK SC"))
#set text(font: ("Poppins", "Noto Serif CJK SC"))
#set heading(numbering: (..n) => numbering("1.1", ..n.pos().slice(1)))

#show heading.where(level: 1): set align(center)
#show heading.where(level: 1): set text(20pt)
#show heading.where(level: 1): set heading(numbering: none)
// #show heading.where(level: 1): smallcaps

#show heading.where(level: 2): set text(18pt, rgb("#045bac"))
// #show heading.where(level: 2): smallcaps

#show heading.where(level: 3): set text(14pt, rgb("#062f56"), weight: "regular")
// #show heading.where(level: 3): smallcaps

#show heading: smallcaps

= First level
== Second level
=== Third level
==== Fourth level

Nice, I already forgot about this neat (_, ..n) trick.