robinm
October 24, 2025, 1:27am
1
I am trying to count how many sub-heading there is in the current section and display them in the heading.
= a
== 1
== 2
== 3
== 4
= b
== I
== II
== III
In the first heading (a), it should display a (sub-headers: 4), and for the second it should display b (sub-headers: 3).
#let sub-heading-counter = counter("sub-heading");
#show heading.where(level: 2): it => [
#sub-heading-counter.step()
#it
]
#show heading.where(level: 1): it => [
#sub-heading-counter.update(0)
#let sub-heading = {
let next-headings = query(heading.where(level: 1).after(here()))
if next-headings.len() > 1 {
sub-heading-counter.at(next-headings.at(1).location())
} else {
sub-heading-counter.final()
}.at(0)
}
#[#box[#it] (sub-headers: #sub-heading)]
]
The above does work, but:
It seems more complicated than needed
Is there a way to more the code inside the #show into a #let function? I was not able to understand what I had to do with context since it seems to be needed to use here() if I extract the code in a function.
Y.D.X
October 24, 2025, 3:17am
2
This might be simpler?
#let n-sections() = {
let later-chapters = query(heading.where(level: 1).after(here()))
// Select sections after here…
let target = heading.where(level: 2).after(here())
// …and before the next chapter (if exists)
if later-chapters.len() > 0 {
let next-chapter = later-chapters.first()
target = target.before(next-chapter.location())
}
query(target).len()
}
= a (sub-headers: #context n-sections())
== 1
== 2
== 3
== 4
= b (sub-headers: #context n-sections())
== I
== II
== III
here() needs context. You can define a function that retrieves information from the context, and provide the context to the function when calling it, like #context n-sections() above.
robinm
October 24, 2025, 7:48am
3
That’s perfect.
And if someone needs it, I did end up calling n-sections() like this:
#show heading.where(level: 1): it => block[
#[#box[#it] (sub-headers: #context n-sections())]
]
Y.D.X
October 24, 2025, 7:59am
4
Oh, well, you can use {…} to switch from markup mode to code mode to get rid of so many # and put newlines freely.
#show heading.where(level: 1): it => block({
box(it)
[ ]
[(sub-headers: #context n-sections())]
})
2 Likes