I want to create a dynamic list of solutions to exercises such that when I add a new section and move some problems into it, the new section in solutions list is created with a solution to new problem. In other words I want to:
create a function problem(id: "", body: [...], solution: [...]) which will print out the body of the problem, put solution into solutions_bank and create a label so that in other parts of the text the problem could be referenced.
create a solutions() function, which will group all solutions from solutions_bank by their chapter.
At first I tried to expand this forum post: How to keep exercise and solution together in source, but render them separately?
I tried to query all chapters in document and create a list of empty states (one per each chapter) and update them inside problem(...) function call. After failing to compare string and context or string and content I tried to use repr but left that idea after similar tries.
Next i found the exercise-bank package. It almost solved the issue (now I can group solutions by exo-filter() function) but when I tried to automatically assign the topic field value
#let current-chapter-title() = context {
// Query all level 1 headings that appear before the current location.
let headings = query(heading.where(level: 1).before(here()))
// Ensure at least one heading exists.
if headings == () {
panic("At least one heading must be defined before the current location.")
}
// Return the body (title text) of the last heading found.
headings.last().body
}
#let problem(title: "", body: [], solution: []) = context {
exo(
exercise: body,
solution: solution,
topic: repr(current-chapter-title()),
// topic: "Геометрична алгебра",
)
}
The topic value is context() instead of the name of current chapter. So, are there any way to create such behaviour? I’m still new to typst, so juggling states and contexts is hard.
in this case, you are wrapping the return value of current-chapter-title() in context, which means it can’t be read externally anymore. you should get rid of the context keyword for that function and just expect all callers (like problem) to have their own contexts instead. that way, everything is part of a single context block and the callers can read the value
#let current-chapter-title() = {
you should be able to apply this idea to your original custom implementation, in case you’re still interested in doing that (though i would simply use queries, not state). for example: