How to do figure numbering across different kinds of figures

Hello,

I have two different kinds of figures, and I want to count them the same way. In the code below, you can see that even though I am trying to reset the counters for both “raw” and “raw2” figures, it doesn’t work exactly as it should, because “Fig 2.4” is being listed as Listing 2.3 and “Fig 2.3” as Listing 2.2. Is there any way to make this numbering work using two different kinds of figures?

Test output can also be seen here: Test



#set figure(numbering: it => { 
      let count = counter(heading).get()

      numbering("1.1.", count.at(0), it)
      
})
#set heading(numbering: "1.1.1")
#show heading.where(level: 1): it => {
    counter(figure.where(kind: image)).update(0)
    counter(figure.where(kind: table)).update(0)
    counter(figure.where(kind: raw).or(figure.where(kind: "raw2"))).update(0)
      counter(math.equation).update(0)
    it
  }



= Heading1

#figure(
  raw("Fig 1.1"),
  caption: [What]
)

= Heading2
#figure(
  raw("Fig 2.1"),

  caption: [What],
  kind: "raw2",
  supplement: "Listing",
)

#figure(
  raw("Fig 2.2"),

  caption: [What],
  kind: "raw2",
    supplement: "Listing",

)

#figure(
  raw("Fig 2.3"),

  caption: [What],
  supplement: "Listing",

)

#figure(
  raw("Fig 2.4"),

  caption: [What],
  supplement: "Listing",
  kind: "raw2",

)
= Heading3

#figure(
  raw("Fig 3.1"),

  caption: [What]
)

#figure(
  raw("Fig 3.2"),

  caption: [What],
  supplement: "Listing",
  kind: "raw2",

)

#outline(title: [List of listings], target: figure.where(kind: raw).or(figure.where(kind: "raw2")))

Thank you for your time and help in advance.

Hello. The automatic counters are only for simple figure selectors, not for complex ones:

#show heading.where(level: 1): it => {
  counter(figure.where(kind: image)).update(0)
  counter(figure.where(kind: table)).update(0)
  counter(figure.where(kind: raw)).update(0)
  counter(figure.where(kind: "raw2")).update(0)
  // counter(figure.where(kind: raw).or(figure.where(kind: "raw2"))).update(0)
  counter(math.equation).update(0)
  it
}

If you are fine with no period in the outline, then this is the simplest way:

#let raw-figure-numbering(n) = {
  let heading = counter(heading).get().first()
  let raw = counter(figure.where(kind: raw)).get().first()
  let raw2 = counter(figure.where(kind: "raw2")).get().first()
  numbering("1.1", heading, raw + raw2)
}

#show figure.where(kind: raw): set figure(numbering: raw-figure-numbering)
#show figure.where(kind: "raw2"): set figure(numbering: raw-figure-numbering)

#set heading(numbering: "1.1.1")
#show heading.where(level: 1): it => {
  counter(figure.where(kind: raw)).update(0)
  counter(figure.where(kind: "raw2")).update(0)
  it
}

= Heading1
#figure(raw("Fig 1.1"), caption: [raw])

= Heading2
#figure(raw("Fig 2.1"), caption: [raw2], kind: "raw2", supplement: "Listing")
#figure(raw("Fig 2.2"), caption: [raw2], kind: "raw2", supplement: "Listing")
#figure(raw("Fig 2.3"), caption: [raw])
#figure(raw("Fig 2.4"), caption: [raw2], kind: "raw2", supplement: "Listing")

= Heading3
#figure(raw("Fig 3.1"), caption: [raw])
#figure(raw("Fig 3.2"), caption: [raw2], kind: "raw2", supplement: "Listing")

#outline(
  title: [List of listings],
  target: figure.where(kind: raw).or(figure.where(kind: "raw2")),
)

Otherwise you would have to conditionally add the period:

#let _in-outline = state("in-outline", false)
#let in-outline() = _in-outline.get()

#let raw-figure-numbering(n) = {
  let heading = counter(heading).get().first()
  let raw = counter(figure.where(kind: raw)).get().first()
  let raw2 = counter(figure.where(kind: "raw2")).get().first()
  context {
    let period = if in-outline() { "." } else { none }
    numbering("1.1" + period, heading, raw + raw2)
  }
}

#set heading(numbering: "1.1.1")
#show heading.where(level: 1): it => {
  counter(figure.where(kind: raw)).update(0)
  counter(figure.where(kind: "raw2")).update(0)
  it
}

#show figure.where(kind: raw): set figure(numbering: raw-figure-numbering)
#show figure.where(kind: "raw2"): set figure(numbering: raw-figure-numbering)

#show outline: it => _in-outline.update(true) + it + _in-outline.update(false)

= Heading1
#figure(raw("Fig 1.1"), caption: [raw])

= Heading2
#figure(raw("Fig 2.1"), caption: [raw2], kind: "raw2", supplement: "Listing")
#figure(raw("Fig 2.2"), caption: [raw2], kind: "raw2", supplement: "Listing")
#figure(raw("Fig 2.3"), caption: [raw])
#figure(raw("Fig 2.4"), caption: [raw2], kind: "raw2", supplement: "Listing")

= Heading3
#figure(raw("Fig 3.1"), caption: [raw])
#figure(raw("Fig 3.2"), caption: [raw2], kind: "raw2", supplement: "Listing")

#outline(
  title: [List of listings],
  target: figure.where(kind: raw).or(figure.where(kind: "raw2")),
)

Wow, that’s very cool. Could you maybe also explain to me, why the period is harder to implement in this case?

Ah nvm, you can just replace numbering("1.1", heading, raw + raw2) with numbering("1.1.", heading, raw + raw2).

Thank you very much for your help and quick response!

I updated the post.

The numbering has some implicit behavior and is overdue for a rewrite. But it’s low in priority, so we have to use some hacks to do things. Though there is Numbering implementation refactor by samuelireson · Pull Request #6122 · typst/typst · GitHub and Disambiguate numbering pattern names by samuelireson · Pull Request #6379 · typst/typst · GitHub.

That will generate “Listing 2.3.: raw”.