Repository navigation
citeproc: warn with Q-23-2 at an unknown citation key instead of failing (#1111) - #1163
Merged
Merged
Conversation
…ion (bd-s1kn2w1r) Reproduced on main @ 250e2ed for HTML and Typst. Pandoc warns instead of failing; per user decision the fix makes a missing key a coded, located warning in both formats. Triage record and fixtures under claude-notes/issue-reports/1111/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A citation key no reference defines used to fail the HTML render with an uncoded "Citation processing error: Reference 'X' not found" and no location, stopping at the first such key. On Typst, Typst's own bibliography failed the compile and pointed at the generated .typ. Match Pandoc's citeproc instead: warn and render the item as bold `X?`. - quarto-citeproc: an unknown item renders as its prefix plus bold `id?` inside the citation's usual affixes and delimiters, drops its suffix, takes no citation number, and sorts last. - pampa citeproc filter: one Q-23-2 warning per unknown key, at the key's span in the source (its first citation). - Typst (citeproc off): a new check_citation_keys runs before Pandoc, warns the same way, and replaces only the unknown items, so the known keys stay native Typst citations. It skips the check when it can't read a bibliography (e.g. Hayagriva YAML) and leaves Typst to report. - New catalog code Q-23-2 in the citeproc subsystem, with a docs page, avoiding the Q-10-* collision with the template subsystem (bd-be2f7). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
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.
Fixes #1111. Braid: bd-s1kn2w1r.
Problem
Citing a key that isn't in the bibliography failed the render:
Error: Citation processing error: Reference 'missing2020' not found, with no Q-code and no location. Only the first missing key was reported.Q-21-3, pointing at a line in the generated.typfile.Pandoc (and Quarto 1) don't fail here. They warn
citation X not foundand render the citation as bold X?. This PR matches that for both formats and gives the warning a code and the key's location in the.qmd.What changes
Output. A missing key renders as bold
key?inside the citation's normal parentheses and delimiters, as Pandoc does:(Doe 2020; **missing2020?**),(see **missing2020?**). The item keeps its prefix and drops its suffix and locator. It takes no citation number in numeric styles, so the numbers of later references don't shift, and it sorts last within its citation. I checked each of these against Pandoc 3.12.1; the fixtures and observed output are inclaude-notes/issue-reports/1111/from the triage commit.Warning. One
Q-23-2warning per missing key, at the key's span (just after the@) in its first citation:Code.
Q-23-2is new, in the existingciteprocsubsystem (Q-23), with a catalog entry, a docs page, and a sidebar entry. The issue noted that citeproc'sQ-10-2collides with the template subsystem (bd-be2f7); this PR doesn't use the Q-10 codes, so the collision isn't made worse. bd-be2f7 still tracks fixing the remaining Q-10 codes inquarto-citeproc/src/error.rs.Where
quarto-citeproc/src/eval.rs: an unknown item goes throughunknown_item_outputinstead of returningReferenceNotFound. Unknown ids are skipped when assigning citation numbers and sort last.pampa/src/citeproc_filter.rs:apply_citeproc_filtercollects unknown ids. Only when there are some does it walk the document again for the key spans (Citation.id_source), so renders without missing keys pay nothing extra.check_citation_keysfor the Typst path: it loads the bibliographies, warns, and replaces only the unknown items with**key?**. Known items stay aCite, so Typst still resolves them (@doe2020 #strong[missing2020?])..yml, which Typst reads but Q2 doesn't), it leaves the document alone and Typst reports as before.quarto-core/src/stage/stages/user_filters.rs: runscheck_citation_keysin the post pass for Typst when Q2's citeproc isn't in the filter list and margin citations aren't in use (the Lua margin handler needs the originalCitenodes). This runs afterAstTransformsStage, so cross-reference@fig-xcites are already resolved and can't be mistaken for missing keys. The HTML citeproc filter already relies on the same ordering.Not changed
CiteprocFilterError::ProcessingErrorstill turns any remaining citeproc error into a string (thee.to_string()the issue pointed at). A missing key no longer reaches it. Carrying structured diagnostics throughFilterError→PipelineError::stage_erroris wider plumbing than this fix needs.ReferenceNotFoundsites intypes.rs(format_bibliography_entry*) still uselocation: None. They take a bare id from callers that have no source span, and the render path no longer hits them for a missing key.Tests
pampa(citeproc_filter::tests,unknown_key_*/key_check_*). They cover the bold marker and warning location, prefix kept and suffix dropped, one warning per key at its first citation, no citation number in a numeric style, and for the Typst check: partial replacement, a cite where every key is missing, separators between markers, and an unreadable bibliography. Written first; the citeproc ones failed with the old "must not fail the render" error.quarto-core(unknown_citation_keys.rs) that render a.qmdto HTML and to Typst. They assert theQ-23-2warnings, theirindex.qmdrow and column, and the output markers.Local run:
cargo nextest run --workspacepassed 19,220 of 19,221 tests. The one failure isengine::knitr::capture_tests::capture_classifies_pieces: the local R install reports the error class asrlang_errorinstead ofsimpleError. It's unrelated to this change, andmainat the merge base is green in CI. Lint, fmt, the warnings-denied build, tree-sitter, and ts-packages steps ofcargo xtask verifypass. The hub-client tests weren't run locally because the WASM package isn't built in this fresh worktree (--skip-hub-build); CI covers them.Cross-platform:
quarto-citeprocpassesclippy --all-targets --target x86_64-pc-windows-msvc -D warnings.pampaandquarto-corecan't be cross-checked from macOS because their C build scripts (tree-sitter, aws-lc-sys, wasmtime) need Windows headers. The change adds no platform-specific code; the tests compare paths by file name and use the same/memruntime pattern as the existing tests.🤖 Generated with Claude Code