Repository navigation
CND as a typst compile output format - #4
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The example-suite parity test (added next) caught complex_multipage.typ producing textually different CND output across separate `typst compile` runs of the same document. Root cause: `NodeBase::state_metadata` was a `std::collections::HashMap<String, serde_json::Value>`, whose iteration order is randomized per process — confirmed by running the CLI three times on the same input and diffing the key order of one node's state_metadata each time. Switch it (and every construction site: metadata.rs, emit/convert.rs, emit/figure.rs, emit/table.rs) to `serde_json::Map<String, serde_json::Value>`. Without serde_json's `preserve_order` feature (deliberately not enabled anywhere in this workspace, since Cargo feature unification would change map ordering for every crate in the build, including upstream ones), `Map` is backed by a `BTreeMap`, so keys always serialize in the same alphabetical order regardless of process or machine. Nested dicts already went through `serde_json::Map` in `value_to_json`; this makes the top level consistent with them. Adds a regression unit test in metadata.rs asserting alphabetical key order from a dict inserted in non-alphabetical order. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…suite Adds CndWorld::new_with_options(input, inputs, system_fonts), with new_with_inputs now a thin wrapper over it (system_fonts: true). This lets a test build the same font set --ignore-system-fonts gives the CLI path, so both entry points are comparable with system fonts off — they otherwise discover fonts in a different order, which is a font-setup difference, not an exporter one. cnd_format_matches_the_standalone_exporter_on_every_example compiles every .typ file in typst-cnd/examples/ through both entry points (typst compile --format cnd, and CndWorld + cnd_from_document/ cnd_to_json directly) and asserts the two CNDs are identical after normalizing built_at and node UUIDs (order of first appearance). This caught the state_metadata ordering bug fixed in the previous commit; all 21 examples now agree byte-for-byte, verified stable across five repeated runs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Loads a JSON object of string values into sys.inputs, merged with --input pairs (--input wins on a key collision since it is applied last). Ports build_inputs/load_inputs_file/json_kind from typst-cnd's standalone binary, with errors as String instead of SourceResult so they compose with WorldCreationError. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A project file that does not exist is looked up by its file name alone in the fallback directory. A project file that exists always wins, a directory in the project stays an error, escaping paths fail before the lookup, and package files never fall back. Only regular files whose real path lies inside the fallback directory are served, so a symlink cannot lead out of it. `--deps` names the fallback file that was read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream's --deps only lists files read through the file store; fonts served by FontStore were not reported. SystemWorld now tracks which font indices World::font served since the last reset and exposes them as font_dependencies() — sorted, deduplicated file paths, embedded fonts (no file) omitted. Every --deps format (json, make, zero) includes them via relative_dependencies(); watch.rs is untouched, so typst watch still does not watch font files. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Font files were reported by the path the font search found them at, so a --font-path given through a symlink or as a relative path was reported differently from a file dependency in the same directory, and two spellings of one file were listed twice. They are now canonicalized like file dependencies, then made relative to the root when inside it. The integration tests of `typst compile --format cnd` also clear every environment variable the CLI reads as a flag default, so a TYPST_ROOT or TYPST_FONT_PATHS in the environment cannot change their outcome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drops stale planning notes, local paths and links to private notes; keeps the hook points, the pipeline and the contributor rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
typst compile --format cnd(or a.cndoutput path) runs the CND exporter through the standard CLI, so--root,--font-path,--ignore-system-fontsand--depsapply to CND.--inputs-file: a JSON object of string values merged intosys.inputs(--inputwins on a key collision), for every format.--fallback-dir: a missing project file is looked up by file name in that directory; project files win, packages never fall back, escaping paths still fail, symlinks cannot lead outside the directory, only regular files are served.--depsnow also lists the font files the compilation loaded, by canonical path (all deps formats; the watcher does not watch fonts).state_metadatais serialized in a stable key order (it followed a per-process random order before); the JSON shape is unchanged.typst-cndbinary is unchanged apart from its help text.Test plan
cargo test -p typst-cli(newtests/cnd.rs: format selection, stdout, CND semantics feature,--root, parity with the standalone exporter on every example,--inputs-file,--fallback-dirincl. escape and symlink cases, font deps; hermetic againstTYPST_*env vars)cargo test -p typst-cndcargo test --workspace --no-fail-fastlocally (Linux)🤖 Generated with Claude Code