Files
curriculum-project-hub/crates/cph-typst/tests/fixtures/render-stub/lib.typ
T
sjfhsjfh 7e76482a31 feat(checker): cph-typst — embed typst 0.15, driver-gen, compile, PDF (WU-4)
The heart of the pipeline. Embeds the typst 0.15 compiler as a library to
compile-check a lesson and export a PDF, with diagnostics mapped back to source
spans (the product's value).

- LessonWorld: a typst World over the engineering-file directory tree. vpath =
  real relative path (ADR-0007); the per-target driver is mounted in-memory as
  `main` (.cph/driver-<target>.typ, never written to disk); @local/cph-render is
  resolved from render_dir (CPH_RENDER_DIR / with_render_dir), no package install
  or network. Fonts via typst-kit FontStore (system CJK).
- Driver generation: from the manifest, per target — static root-relative
  `include` of each content file (⇒ module body content, ADR-0006), assembled
  into the frozen `display(info, target, parts)` call; optional lemma proof
  emitted only if proof.typ exists; example `source` scalar threaded through.
- Diagnostics: typst SourceDiagnostic (errors + warnings) → cph_diag::Diagnostic.
  0.15 DiagSpan handled via span.id() + WorldExt::range → file-relative
  SourceSpan with 1-based line/col; driver-internal spans re-pointed with a
  "generated driver" hint, never dropped. typst hints/trace carried through.
- Engine API: new / with_render_dir / compile_check / build_pdf.
- 6 tests incl. build_pdf_with_real_render — full World→driver→cph-render→PDF
  producing real PDF-1.7 output (student 42KB / teacher 54KB). clippy/fmt clean.

Also fixes render/typst.toml `compiler = ">=0.15.0"` → `"0.15.0"`: typst 0.15's
manifest parser rejects a `>=` comparator on the compiler field (the 0.14 CLU
WU-2 tested against was lenient). This unblocks loading the real render package.

Pinned: typst/typst-pdf/typst-syntax/typst-library/typst-layout/typst-kit =0.15.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 01:49:15 +08:00

30 lines
1000 B
Typst

// Minimal stand-in for the real `cph-render` package, used so cph-typst's
// World / compile / PDF path can be proven independently of WU-2.
//
// It exercises the same call shape as the real entry: it reads `info`, walks
// `parts` IN ORDER, and renders each part's content fields by `kind`. Content
// values are already-evaluated content (the driver produced them via include).
#let display(info: (:), target: "student", parts: ()) = {
set document(title: info.at("title", default: ""))
[= #info.at("title", default: "")]
[target: #target]
for p in parts {
let kind = p.at("kind", default: none)
[== #kind]
if kind == "segment" {
p.textbook
} else if kind == "lemma" {
p.stmt
let proof = p.at("proof", default: none)
if proof != none { proof }
} else if kind == "example" {
p.problem
p.solution
let src = p.at("source", default: none)
if src != none [来源:#src]
} else if kind == "sop" {
p.sop
}
}
}