How to keep exercise and solution together in source, but render them separately?

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()

image

1 Like