Your first checklist
Installing and compiling
#import "@preview/checkitoff:0.1.0": *
#import "@preview/contexture:0.1.0": bundleA manuscript plus its completed checklist compiles with one command:
typst compile --features bundle --format bundle main.typ
This produces manuscript.pdf and checklist.pdf from the same compile. A second, optional compile is useful while drafting:
typst compile --features bundle --format bundle --input preview=true main.typ
This produces manuscript-preview.pdf only — no checklist.pdf in this compile, and Wiring a real project explains why — with every check()‘d span lightly highlighted and tagged with its item id, so you can see at a glance what’s covered so far and where. Nothing about it ever reaches the real submission.
About the examples in this manual
Every example here is a single, self-contained file, compiled directly — the simplest way to show what each function does on its own.
check() and na() even work in a plain typst compile, with no bundle at all: that’s the form used for the very next example. A real, multi-file project instead wires its manuscript and its checklist together explicitly — that pattern is covered once you’ve seen the pieces it’s built from, in Wiring a real project.A first, complete example
The smallest complete example: a four-item made-up checklist — a real project would pass checklists.consort or another built-in grid instead (see Built-in checklists), but a tiny one keeps the whole grid on one page here — a short manuscript, and two check() calls plus one na().
#import "../../lib.typ": *
#import "../../../typst-contexture/lib.typ" as contexture
// A tiny, made-up grid — not a real reporting guideline — kept small so
// checklist.pdf fits on one page for this illustration; a real project
// passes e.g. `checklists.consort` here instead (see the "Built-in
// checklists" chapter).
#let tiny = (
name: "TINY",
full-name: [Tiny reporting checklist],
items: (
(section: "Title and abstract", topic: "Title", group: none, id: "1a",
description: [Identification as a randomised trial.]),
(section: "Methods", topic: "Sequence generation", group: "Randomisation", id: "10",
description: [Method used to generate the random allocation sequence.]),
(section: "Methods", topic: "Allocation concealment", group: "Randomisation", id: "11",
description: [Mechanism used to conceal the allocation sequence.]),
(section: "Discussion", topic: "Interpretation", group: none, id: "14",
description: [Interpretation consistent with results, balancing benefits and harms.]),
),
)
#show: contexture.bundle.with(
template: body => {
set page(width: 16.6cm, height: auto, margin: 12pt)
set text(size: 10.5pt)
body
},
documents: (checklist(checklist: tiny),),
)
= Title and abstract
#check("1a")[Effect of Drug X on Outcome Y: a randomised controlled trial.]
= Methods
#check("10")[Participants were randomly assigned via a computer-generated
sequence.]
#check("11")[Allocation was concealed using sequentially numbered, opaque,
sealed envelopes.]
= Discussion
This short illustrative manuscript omits a full interpretation section.
#na("14", reason: [Omitted from this compact illustrative example.])
A few things to notice in that file, top to bottom:
tinyis nothing but a dictionary: aname, afull-name, and a list ofitems, each with asection, an optionaltopic/group, anid, and adescription. Nothing here is specific to checkitoff’s internals — it’s the same shape every built-in checklist uses, and the same shape a house checklist of your own would use.#show: contexture.bundle.with(...)is the one line of setup a real project needs: it tells Typst which checklist is active (checklist(checklist: tiny)) and applies a page template to the manuscript. Everything after it is your manuscript, written exactly as you’d write it without checkitoff at all.#check("1a")[...]wraps a passage of the manuscript and records “this is where item 1a is answered.”#na("14", reason: [...])instead declares, in one line, that item 14 doesn’t apply here — with a justification, not a silent omission.
Compiled plain, manuscript.pdf shows nothing but ordinary prose — no box, no id, no visible trace of check() at all:
Compiled again with --input preview=true — a drafting view only, never part of the real submission — each checked span is lightly highlighted with its item id superscripted, so you can see coverage at a glance while writing (checklist.pdf isn’t produced in this compile at all):
And here is checklist.pdf, from the first, plain compile — the actual deliverable:
Worth noticing in that grid: “Randomisation” (item 10/11′s shared group) renders as its own band nested inside the “Methods” section band — an item’s group, when it has one, always gets this treatment. Item 14 shows N/A in the Page column, with its justification printed verbatim underneath, in the “Not applicable” block — both come directly from the single na("14", reason: [...]) call above, with no check() anywhere for that id. If an item had been left neither check()‘d nor na()’d, its Page cell would instead show a small warning marker — covered in full in Reading the grid, once the individual marking functions have been introduced properly.
Recommended workflow
The example above is the whole mechanism; a real manuscript just repeats the same two calls, check() and na(), at every relevant spot. In practice:
- Pick a checklist — one of the built-in ones (Built-in checklists), or your own dictionary of the same shape.
- Write the manuscript as usual, wrapping each passage that answers an item in
check(id)[...], and grouping every genuinely inapplicable item underna(id, reason: [...]). - While drafting, compile with
--input preview=truefrom time to time — a quick visual check of what’s covered and what isn’t yet, with no effect on the real manuscript. - Once the draft feels complete, compile normally and read
checklist.pdf. Its Diagnostics block (below) lists anything unresolved: an item never covered, acheck()with nothing in it, an id that doesn’t match any item, or a genuine contradiction. - Fix each one — add the missing
check(), or anna()with a real reason — and recompile. - Before submission, compile once with
strict: true(below): every remaining diagnostic becomes a hard compile error instead of a soft marker, a clean pass-fail gate. - Submit
manuscript.pdfandchecklist.pdftogether — they came from the same compile, so the page numbers in one are guaranteed to match the other.
| ← checkitoff overview | Marking items: check and na → |