It’s not “the major part of the heading counter”, it’s the number of the top-/1st level heading. It’s not a versioning schema, it sounds confusing. Also y doesn’t restart after each heading, only after the top-level heading. Which is indeed a common per-section numbering, like in subpar – Typst Universe and i-figured – Typst Universe.
Here is a simple solution:
#let all-problems = state("all-problems", ())
#let problem-counter = counter("problem")
#let problem(statement: [], solution: none) = {
problem-counter.step()
context {
let h1-num = counter(heading).get().first()
let problem-number = numbering("1.1", h1-num, ..problem-counter.get())
let name = [Exercise #problem-number]
let problem = (solution: solution, location: here(), name: name)
all-problems.update(problems => problems + (problem,))
block[_#name:_ #statement]
}
}
#let display-solutions() = context for p in all-problems.get() {
if p.solution == none { continue }
let exercise-link = link(p.location, emph(p.name))
block[_Solution:_ #exercise-link#h(1em)#p.solution]
}
#set heading(numbering: "1.1")
#show heading.where(level: 1): it => it + problem-counter.update(0)
= First Chapter
#problem(statement: [What is $1 + 1$ ?], solution: [The answer is $2$])
#problem(statement: [What is $1 + 2$ ?], solution: [The answer is $3$])
== Sub
#problem(statement: [What is $1 + 3$ ?], solution: [The answer is $4$])
= Second Chapter
#problem(statement: [Then what is $1 + 4$ ?], solution: [The answer is $5$])
= The Solutions
#display-solutions()
