fix: evaluate theorem title strings as Typst markup#13
Merged
Conversation
Quarto wraps theorem/example titles in __quarto_custom_scaffold Divs with inline-only content. Both the code-window box wrapping and Pandoc's Skylighting generate Typst function calls (#box(...), #NormalTok(...)) that get stringified as literal text when Quarto renders the title parameter as a string. Replace the global Code filter with a selective document walk that converts Code to plain Typst backtick code inside title scaffolds and applies the full box styling everywhere else.
Quarto renders custom type titles as title: "..." (string mode) which stringifies any Typst markup. Inline code in titles produces Skylighting tokens with inner quotes that break the Typst string syntax. Two-part fix: - Pre-quarto: convert Code in title scaffolds to plain Typst backtick code, avoiding Skylighting tokens that contain unescaped quotes. - Post-quarto: inject a Typst override of simple-theorem-render that evaluates string titles with eval(mode: "markup"), giving title: [...] semantics even though Quarto emits title: "...".
The previous approach redefined simple-theorem-render, but make-frame captures the render function by value at definition time, so the override had no effect. Instead, scan the Typst preamble for make-frame definitions, extract the generated function names (e.g., example, theorem), and inject wrapper functions that evaluate string title parameters with eval(mode: "markup") before delegating to the original function.
header-includes is placed before template definitions in the Typst preamble, so the theorem functions are not yet defined. RawBlocks inserted into doc.blocks appear after the template preamble, where make-frame has already created the theorem functions. Also scan the source file for cross-reference div IDs (e.g., #exm-, #thm-) to determine which theorem functions to wrap, since this information is not available in the AST at filter time.
Each hotfix can now have its own quarto-version threshold for
auto-disable, since upstream fixes are unlikely to land in the same
Quarto release. The hotfix value can be a boolean or a map with
enabled and quarto-version keys:
hotfix:
code-annotations:
quarto-version: "1.10.0"
skylighting:
quarto-version: "1.11.0"
typst-title:
quarto-version: "1.10.0"
The global quarto-version key is still supported as a fallback.
Add typst-title as a new hotfix key for the theorem title fix.
Remove the global hotfix.quarto-version fallback in favour of per-hotfix thresholds only. Update _schema.yml to use type: [boolean, object] instead of anyOf (unsupported by quarto-wizard schema). Document the new typst-title hotfix and per-hotfix map form in README. Add fragility comments for internal Quarto dependencies.
Use pandoc.MetaMap() instead of a plain Lua table when storing hotfix state in document metadata, ensuring correct serialisation across filter boundaries. Wrap f:read in pcall so the file handle is always closed even if the read fails.
Guard the hotfix metadata bridge with CONFIG.enabled so the post-quarto typst-title-fix filter does not inject wrappers when the extension is turned off.
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.
Inline code and other markup in theorem/example titles was being stringified in Typst output because Quarto renders custom type titles as string parameters. This adds a post-quarto filter (
typst-title-fix) that wraps Typst theorem functions to evaluate string titles as markup viaeval(mode: "markup").The Skylighting inline code filter now distinguishes title scaffolds from normal blocks, emitting plain backtick code in scaffolds to avoid breaking the string parameter that Quarto generates.
Hotfix configuration is reworked: the global
hotfix.quarto-versionkey is replaced with per-hotfixquarto-versionthresholds, since upstream fixes are unlikely to land in the same Quarto release. Each hotfix value can be a boolean or a map withenabledandquarto-versionkeys.