Combining packages

Each of palimpsest, checkitoff, and colophon is documented on its own, and none of them needs this page: every example in their own manuals compiles alone, with only that one package installed. This page is for the moment you want more than one of them on the same manuscript, in the same compile — a tracked-changes revision letter, a completed CONSORT grid, and a word-count audit, all citing the same real page numbers.

Because contexture.bundle — not any one package — owns documents:, adding a second (or third) package’s own document alongside another’s is just one more entry in the same array, not a second engine to reconcile:

#import "@preview/contexture:0.1.0": bundle
#import "@preview/palimpsest:0.1.0" as palimpsest
#import "@preview/checkitoff:0.1.0" as checkitoff
#import "@preview/colophon:0.1.0" as colophon

#show: bundle.with(
  template: colophon.instrument(template: my-journal-template),
  documents: (
    palimpsest.letter(exchanges: include "responses.typ"),
    checkitoff.checklist(checklist: checkitoff.checklists.consort),
    colophon.report(),
  ),
)

#include "manuscript.typ"

One compile, one manuscript: a tracked-changes version, a reviewer response letter, a completed CONSORT grid, and a word-count audit — all citing each other’s real page numbers, none of the three packages aware the other two exist.

What works

What doesn’t work

Not palimpsest/checkitoff-specific: both rules apply to any two contexture-based packages whose marking functions each render content over the same span, present or future — the fix is the same shape every time, one call renders, any other call that needs to know about that same span registers via its own package’s bare, non-rendering form instead of its normal marking call.

A full worked example

All three packages together, on the same manuscript, in one compile — a tracked-changes revision, a reviewer response letter, a completed CONSORT grid, and a word-count audit:

// Phase 4, part 2: colophon combined with BOTH palimpsest and checkitoff
// in the same bundle -- reuses the exact manuscript/responses already
// exercised by ../../combo-test-consort-palimpsest/, so this adds a
// third satellite (colophon's report()) to an already-proven
// combination rather than inventing a new one. Specifically checks
// whether colophon's word count sees text rendered by palimpsest's
// add()/del() -- which, unlike checkitoff's check(), always wraps its
// rendering in `context`, even in plain/clean mode (see CLAUDE.md).

#import "../../lib.typ" as colophon
#import "/typst-palimpsest/lib.typ" as palimpsest
#import "/typst-checkitoff/lib.typ" as checkitoff
#import "../../../typst-contexture/lib.typ" as contexture

#let simple-template(title: none, body) = {
  set page(paper: "a4", margin: 2.5cm)
  set text(size: 11pt)
  set heading(numbering: "1.")
  align(center, text(size: 1.4em, weight: "bold")[#title])
  v(1em)
  body
}

#show: contexture.bundle.with(
  template: colophon.instrument(
    template: simple-template.with(title: [Combined test -- palimpsest + checkitoff + colophon]),
  ),
  documents: (
    palimpsest.letter(exchanges: include "/combo-test-consort-palimpsest/responses.typ", round: 1),
    checkitoff.checklist(checklist: checkitoff.checklists.consort),
    colophon.report(),
  ),
)

#include "/combo-test-consort-palimpsest/manuscript.typ"

manuscript.pdf, compiled plain — the real, submitted text, with nothing of the reviewer exchange or the checklist visible:

The same compile again with --input variant=tracked shows exactly what changed, colored by reviewer:

response.pdf, from the very same compile, citing the manuscript’s real pages:

checklist.pdf, checkitoff’s own CONSORT grid, citing the same manuscript pages — unrelated to palimpsest’s passage() here (see “What works” above for the one case where they’d need to coordinate):

And audit.pdf, reading straight through palimpsest’s own marks — the word count matches the clean, submitted manuscript, not the tracked one:

See also

contexture’s own manual walks through the same mechanism from the other side — the anchor primitive and shared compile pilot that make this possible in the first place, with a two-package worked example of its own — in Composing independent packages.