Configuration
Global config options can be set either directly on an exam, using #show: exam.with(..) or using elembic’s #show: e.set_(config, ..) mechanism.
// Instead of using exam.with(..), you could uncomment the following lines
//
// #show: e.set_(config,
// numbering: ("Problem 1.", "(a)"),
// points-position: "end",
// points-format: p => [[#p pts]],
// solution-color: maroon,
// )
#show: exam.with(
numbering: ("Problem 1.", "(a)"),
points-position: "end",
points-format: p => [[#p pts]],
solution-color: maroon,
)
#question(points: 3)[
Find the derivative of $x^3$.
#answer-box(width: 100%)[#solution[$3x^2$]]
]
#question[
#part(points: 1)[Is $91$ prime? #solution[No.]]
#part(points: 2)[Factor $91$. #solution[$7 dot 13$]]
]#import "@preview/examy:1.1.0": *
// Instead of using exam.with(..), you could uncomment the following lines
//
// #show: e.set_(config,
// numbering: ("Problem 1.", "(a)"),
// points-position: "end",
// points-format: p => [[#p pts]],
// solution-color: maroon,
// )
#show: exam.with(
show-solutions: false, // true for the answer key
numbering: ("Problem 1.", "(a)"),
points-position: "end",
points-format: p => [[#p pts]],
solution-color: maroon,
)
#question(points: 3)[
Find the derivative of $x^3$.
#answer-box(width: 100%)[#solution[$3x^2$]]
]
#question[
#part(points: 1)[Is $91$ prime? #solution[No.]]
#part(points: 2)[Factor $91$. #solution[$7 dot 13$]]
]Inside of an exam, values can be set with elembic’s #show: e.set_(..) mechanism. Such values will affect the exam from that point onwards.
#show: exam.with(
solution-color: maroon,
)
#question(points: 3)[
Find the derivative of $x^3$.
#answer-box(width: 100%)[#solution[$3x^2$]]
]
// Solution color will change from now onward
#show: e.set_(config, solution-color: orange.darken(20%))
#question[
#part(points: 1)[Is $91$ prime? #solution[No.]]
#part(points: 2)[Factor $91$. #solution[$7 dot 13$]]
]#import "@preview/examy:1.1.0": *
#show: exam.with(
show-solutions: false, // true for the answer key
solution-color: maroon,
)
#question(points: 3)[
Find the derivative of $x^3$.
#answer-box(width: 100%)[#solution[$3x^2$]]
]
// Solution color will change from now onward
#show: e.set_(config, solution-color: orange.darken(20%))
#question[
#part(points: 1)[Is $91$ prime? #solution[No.]]
#part(points: 2)[Factor $91$. #solution[$7 dot 13$]]
]Reading config values
The global config can be read with elembic’s e.get(get => ..) mechanism. The following example shows how you might create a fully custom cover page with the exam’s name and term.
#show: exam.with(
exam-name: [MAT 101 Quiz 3],
term: [Fall 2026],
)
#e.get(get => [
*#text(fill: blue)[#get(config).exam-name]*, #get(config).term
])#import "@preview/examy:1.1.0": *
#show: exam.with(
exam-name: [MAT 101 Quiz 3],
term: [Fall 2026],
)
#e.get(get => [
*#text(fill: blue)[#get(config).exam-name]*, #get(config).term
])All config options
Solutions
--input show-solutions=.. command-line option overrides this setting.auto derives it from solution-background-color.auto derives it from solution-color by lightening.Cover pages
#maketitle().#maketitle().#maketitle().#maketitle(). Durations are shown in minutes (e.g. duration(hours: 1, minutes: 50) shows as "110 Minutes"). Pass content for complete control over what is shown (e.g., pass [1 h 50 min]).Numbering and indentation
Determines how questions, parts, and subparts are numbered. This option behaves like enum's numbering, taking a numbering pattern (e.g. "1.a.i.") or a function that generates a label. In addition, numbering also accepts an array of numbering patterns (e.g. ("Problem 1.", "(a)", "i.")), with the left-most pattern applying to the highest level (almost always the #question[..]).
A config rule inside an exam (e.g. #show: e.set_(config, numbering: ("Bonus 1.", "(i)"))) sets the numbering of the questions/parts/subparts after it in its scope. Its left-most pattern still applies to questions, even when the rule is inside a question.
enum's full, if set, ensures that questions/parts/subparts get globally unique identifiers (e.g., part (a) of question 1 is labelled "1 (a)" by default, or "1.a." with numbering: "1.a.i."). This also affects @name references to questions.Points
(points) => [content] that determines how points are visibly displayed. Defaults to a function that renders (X points). Other examples include p => [[#p]] or p => [(#p Punkte)].(bonus-points) => [content] that determines how bonus points are visibly displayed. Defaults to a function that renders (X bonus points).stringsdictionary(content)default(
question: [Question],
page: [Page],
points: [Points],
bonus: [Bonus],
score: [Score],
total: [Total],
)Words that can be localized to different languages. These include question, page, points, bonus, score, and total. Any subset of these may be set.
Note: the words in points badges are set by points-format and bonus-points-format.
Determines where the points are visibly displayed.
"start": before the question text.
"margin-left" or "margin-right": in the page margin. Those of every column go in that margin, stacked.
"end": right-aligned, after the question text.
When set to true, a question/part/subpart whose parts/subparts have points shows a total even when it is not given points itself: the sum of the points of its parts/subparts. One with no points of its own and none in its parts/subparts still shows none.
For example, #question[#part(points: 2)[]] shows 1. (2 points), with (a) (2 points) on the line below.
When set, a question that is assigned points while its parts/subparts are too shows a warning in red in place of its points.
#points-table(): "horizontal" (a column per question) or "vertical" (a row per question).#points-table(): one cell per "question" (the default), "part", "subpart", or "page".#points-table() includes an empty row for a grader to fill in.#points-table() includes a row for the bonus points (only visible if the exam has bonus points).#points-table(). A wider table wraps to multiple rows. Use none for no limit.Answer boxes
#answer-box[..]. Setting to auto sizes a non-empty box to fit its contents, excluding #solution[..]s, and gives an empty box answer-box-default-height.#answer-box[..]. Setting to auto makes a box answer-box-default-width wide, or full width if its height is fractional (e.g. 1fr).#answer-box[..], specified like a box's stroke (e.g. (bottom: .5pt) for a single line to write on).#answer-box[..] with an otherwise unspecified height.#answer-box[..] with a width of auto, unless its height is a fractional unit (e.g. 2fr).Multiple choice
#choice[..], #bubble(), #square-bubble(), and #choices[..]. Setting to auto uses 1em (which scales with the surrounding text).#choice[..], #bubble(), #square-bubble(), and #choices[..], specified like a circle's stroke: a thickness (e.g. .15em), a color (e.g. blue), or both (e.g. .15em + blue). A thickness left out is .1em, and a color left out is black. On the answer key, a correct bubble's outline takes the solution color.#choice[..]'s outset: a length (the gap after the bubble) or a dictionary of sides (left, right, top, bottom, x, y, rest).choices-enumerate).#choices[..] labels its bubbles. Setting to false results in no labels; true results in A, B, C, …. A numbering pattern, function, or array of labels can be used (e.g., "a" or ("x", "y", "z")).#choices[..] inline in a paragraph. If you would like a grid of choices, consider using choices-columns instead.#choices[..] into the specified number of columns. Setting to none results in a single column (i.e., each choice on its own line). Cannot be combined with choices-inline.#choices[..] block. Setting to auto uses the usual line spacing for choices on separate lines, and 1.5em for choices side by side. A fraction (e.g. 1fr) spreads side-by-side choices across the line.Rubrics
#rubric[..]). Setting to auto shows rubrics whenever solutions are shown. The --input show-rubrics=.. command-line option overrides this setting.Determines where rubrics are displayed.
"margin-left" or "margin-right": in the page margin, next to the question/part/subpart they belong to (see rubric-width). Those of every column go in that margin, stacked.
"end": after the question/part/subpart, taking up space on the page, so an exam with visible rubrics is laid out differently from one without.
auto draws lines only for rubrics in the margin. A rubric item's own trace overrides this.auto fills the margin.Exam metadata
Whether to embed extra metadata into the PDF (as attached JSON files). The --input embed-metadata=.. command-line option overrides this setting.
true: Embed all metadata.
false: Don't embed metadata.
auto: Embed the question regions, and the rubric data only when solutions are shown.
"rubric": Embed rubric data as examy-rubric.json (the same data as <examy-rubric>).
"question-regions": Embed rectangles indicating where each question/part/subpart starts and ends, where its answer boxes are, where the lines of a #name-block() are, and the size and margins of each page, as examy-regions.json.