Questions and numbering
A document is built out of an #exam[..] (alternatively #show: exam). Inside are questions created with the commands #question[..], #part[..], and #subpart[..], used to create a question hierarchy. Questions/parts/subparts can be assigned points, heights, etc.
#show: exam
#question[
Let $f(x) = x^2 sin(1/x)$ for $x != 0$ and let $f(0) = 0$.
#part(points: 2)[
Show that $f$ is continuous at $x = 0$.
#answer-box(height: 1fr)[]
]
#part(points: 3)[
Is $f$ differentiable at $x = 0$? Justify your answer.
#subpart[Compute the difference quotient.]
#subpart[Take its limit.]
#answer-box(height: 1fr)[]
]
]#import "@preview/examy:1.1.0": *
#show: exam
#question[
Let $f(x) = x^2 sin(1/x)$ for $x != 0$ and let $f(0) = 0$.
#part(points: 2)[
Show that $f$ is continuous at $x = 0$.
#answer-box(height: 1fr)[]
]
#part(points: 3)[
Is $f$ differentiable at $x = 0$? Justify your answer.
#subpart[Compute the difference quotient.]
#subpart[Take its limit.]
#answer-box(height: 1fr)[]
]
]A part’s numbering is determined only by how deeply it is nested, so #question[#question[..]] and #question[#part[..]] are numbered the same. The aliases question/part/subpart are provided for convenience.
Numbering a question
By default, questions automatically increment their number. Providing a number: .. argument to a question/part/subpart overrides this behaviour. A numerical value will cause numbering to skip to that value; a non-numerical value or general content will pause the counter and show that content. To omit a number completely, you can set number: none.
#question[An automatically numbered question.]
#question[Another one.]
#question(number: 10)[An integer sets the number.]
#question[…and numbering continues from it.]
#question(number: "★")[Content is shown verbatim.]
#question(number: none)[An unnumbered question.]
#question[The automatic counter ignores the previous two.]#import "@preview/examy:1.1.0": *
#show: exam
#question[An automatically numbered question.]
#question[Another one.]
#question(number: 10)[An integer sets the number.]
#question[…and numbering continues from it.]
#question(number: "★")[Content is shown verbatim.]
#question(number: none)[An unnumbered question.]
#question[The automatic counter ignores the previous two.]Numbering styles
The numbering style of each level is set for the document via the global config’s numbering option. It takes an array of numbering patterns (e.g., ("1.", "(a)", "(i)")) or numbering strings following the same format as an enum’s numbering argument (e.g., "1.a.i."). Questions/parts/subparts are labelled hierarchically with the left-most numbering pattern being assigned to the outer-most question/part/subpart.
#show: exam.with(
numbering: ("Problem 1.", "(A)", "i."),
)
#question[
The first problem.
#part[A part.]
#part[Translate the question statement of @later to German.]
]
#question[
#part(label: <later>)[Where is the nearest grocery store?]
#part[Relative to your answer in part @later, where is the nearest train station?]
]#import "@preview/examy:1.1.0": *
#show: exam.with(
numbering: ("Problem 1.", "(A)", "i."),
)
#question[
The first problem.
#part[A part.]
#part[Translate the question statement of @later to German.]
]
#question[
#part(label: <later>)[Where is the nearest grocery store?]
#part[Relative to your answer in part @later, where is the nearest train station?]
]To force each question/part/subpart to be labelled with a globally unique identifier, use numbering-full: true. This is similar to setting the full argument on an enum.
#show: exam.with(numbering: "1.a.i.", numbering-full: true)
#question[
#part[A part.]
#part(label: <second>)[Another, with #subpart[a subpart.]]
]
#question[See @second.]#import "@preview/examy:1.1.0": *
#show: exam.with(numbering: "1.a.i.", numbering-full: true)
#question[
#part[A part.]
#part(label: <second>)[Another, with #subpart[a subpart.]]
]
#question[See @second.]To number some questions/parts/subparts differently, set numbering with a config rule inside the exam. It takes the same values as the global numbering option and applies to the questions/parts/subparts after the rule, up to the end of its scope.
#question[What is $3 + 4$?]
#[
#show: e.set_(config, numbering: ("Bonus 1.", "(i)"))
#question(number: 1)[
#part[Name a prime number larger than 100.]
#part(label: <largest>)[Name the largest prime number you know.]
]
]
#question[Is your answer to @largest really prime?]#import "@preview/examy:1.1.0": *
#show: exam
#question[What is $3 + 4$?]
#[
#show: e.set_(config, numbering: ("Bonus 1.", "(i)"))
#question(number: 1)[
#part[Name a prime number larger than 100.]
#part(label: <largest>)[Name the largest prime number you know.]
]
]
#question[Is your answer to @largest really prime?]The indent option sets how far each part and subpart is indented from the question/part it is in (by default, 1.5em). A question/part/subpart given indent itself uses its own.
Height and writing space
To allow students a space to write, use #answer-box(height: ..)[]. However, if you need a question and all its part/subparts to cumulatively take up a fixed amount of space, you can provide a height: .. argument directly on a question.
#question(height: 4.5cm, points: 4)[
Sketch the graph of $f(x) = x^3 - x$.
#part[
Mark its zeros.
#answer-box(height: 1fr)[]
]
#part[
Mark its turning points.
#answer-box(height: 1fr)[]
]
]
#question[The next question starts below the first one's 4.5cm.]#import "@preview/examy:1.1.0": *
#show: exam
#question(height: 4.5cm, points: 4)[
Sketch the graph of $f(x) = x^3 - x$.
#part[
Mark its zeros.
#answer-box(height: 1fr)[]
]
#part[
Mark its turning points.
#answer-box(height: 1fr)[]
]
]
#question[The next question starts below the first one's 4.5cm.]Pagebreaks
#pagebreak() works inside questions, parts, and subparts. The question/part/subpart continues on the next page with the same indentation.
#question(points: 2)[
Explain why every differentiable function is continuous.
#answer-box(width: 100%, height: 1.5cm)[
#solution[If $f'(a)$ exists,
$f(a + h) - f(a) = h dot (f(a + h) - f(a)) / h
-> 0 dot f'(a) = 0$.]
]
#pagebreak()
#answer-box(width: 100%, height: 1.5cm)[
#text(fill:gray)[_Scratch area_]
]
]
#question[The next question.]#import "@preview/examy:1.1.0": *
#show: exam.with(show-solutions: false) // true for the answer key
#question(points: 2)[
Explain why every differentiable function is continuous.
#answer-box(width: 100%, height: 1.5cm)[
#solution[If $f'(a)$ exists,
$f(a + h) - f(a) = h dot (f(a + h) - f(a)) / h
-> 0 dot f'(a) = 0$.]
]
#pagebreak()
#answer-box(width: 100%, height: 1.5cm)[
#text(fill:gray)[_Scratch area_]
]
]
#question[The next question.]Columns
Questions, parts, and subparts can go inside #columns. They are numbered and given their points as usual, and a question’s text outside the columns stays across the page.
#question[
Find the derivative of each function.
#columns(2)[
#part(points: 1)[
$f(x) = x^3$
#answer-box(width: 100%, height: 1cm)[]
]
#part(points: 1)[
$g(x) = sin(x)$
#answer-box(width: 100%, height: 1cm)[]
]
#colbreak()
#part(points: 1)[
$h(x) = e^(2x)$
#answer-box(width: 100%, height: 1cm)[]
]
#part(points: 1)[
$k(x) = ln(x)$
#answer-box(width: 100%, height: 1cm)[]
]
]
]
#question(points: 2)[State the chain rule.]#import "@preview/examy:1.1.0": *
#show: exam
#question[
Find the derivative of each function.
#columns(2)[
#part(points: 1)[
$f(x) = x^3$
#answer-box(width: 100%, height: 1cm)[]
]
#part(points: 1)[
$g(x) = sin(x)$
#answer-box(width: 100%, height: 1cm)[]
]
#colbreak()
#part(points: 1)[
$h(x) = e^(2x)$
#answer-box(width: 100%, height: 1cm)[]
]
#part(points: 1)[
$k(x) = ln(x)$
#answer-box(width: 100%, height: 1cm)[]
]
]
]
#question(points: 2)[State the chain rule.]Typst fills the first column before it starts the next, so use #colbreak() where the next column should start. Columns continue onto the next page by themselves. A #pagebreak() inside them moves what comes after it to the next page, where the same columns start again from the first column.
An answer box with a fractional height, such as height: 1fr, shares what is left of its own column down to the bottom of the page. Whatever follows the columns then starts on the next page. A question or part given a height has no next page to move to, so inside one, the columns must come last, and no other box with a fractional height can come before them.
Points and rubrics in a margin go in the margin of the page, whichever column they come from. Each stays level with its question if it can, and otherwise moves down until it is clear of the others. Those from different columns can then mix, out of the order of the questions, so points-position: "start" is usually clearer inside columns.