From 61c81493f52717d503f9a63199463fd4db1ae865 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Thu, 3 Sep 2026 15:46:29 +0200 Subject: [PATCH 1/3] Fix dead toc_title auto-fallback in typst outline template The toc block computed a title fallback (auto when toc_title is none) but passed toc_title directly to outline() instead of the computed local, so the fallback never applied. Harmless today since quarto always fills toc-title before pandoc runs, but restores the safety net for a none toc_title. --- src/resources/formats/typst/pandoc/quarto/typst-template.typ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources/formats/typst/pandoc/quarto/typst-template.typ b/src/resources/formats/typst/pandoc/quarto/typst-template.typ index 219ac27a8d4..cf1f8dd669c 100644 --- a/src/resources/formats/typst/pandoc/quarto/typst-template.typ +++ b/src/resources/formats/typst/pandoc/quarto/typst-template.typ @@ -128,7 +128,7 @@ } block(above: 0em, below: 2em)[ #outline( - title: toc_title, + title: title, depth: toc_depth, indent: toc_indent ); From 6caff52e28ab5b9848b6fa95439d6fe97eaf8d61 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Thu, 3 Sep 2026 16:42:47 +0200 Subject: [PATCH 2/3] Add regression test for typst toc_title auto fallback A user Lua Meta filter that removes toc-title reaches the toc_title == none path in typst-template.typ's article() function (the case the previous commit fixed) even though quarto always fills toc-title before pandoc runs for a normal render. Asserts on the compiled PDF text rather than the generated .typ source, since a .typ-text assertion would just re-check the source line changed by the fix rather than the outline's actual rendered title. --- .../smoke-all/typst/toc/strip-toc-title.lua | 6 ++++ .../typst/toc/toc-title-auto-fallback.qmd | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/docs/smoke-all/typst/toc/strip-toc-title.lua create mode 100644 tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd diff --git a/tests/docs/smoke-all/typst/toc/strip-toc-title.lua b/tests/docs/smoke-all/typst/toc/strip-toc-title.lua new file mode 100644 index 00000000000..893ea4fdc92 --- /dev/null +++ b/tests/docs/smoke-all/typst/toc/strip-toc-title.lua @@ -0,0 +1,6 @@ +-- Removes the toc-title metadata that Quarto fills in before Pandoc runs, +-- so the Typst template receives its own `toc_title: none` default. +function Meta(meta) + meta["toc-title"] = nil + return meta +end diff --git a/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd b/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd new file mode 100644 index 00000000000..4a5278108cf --- /dev/null +++ b/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd @@ -0,0 +1,30 @@ +--- +title: "TOC title auto fallback" +lang: en +toc: true +format: + typst: + keep-typ: true + filters: + - strip-toc-title.lua +_quarto: + tests: + typst: + ensureTypstFileRegexMatches: + - # Patterns that MUST be found + # The outline is emitted, so the `if toc` branch of article() ran + - '#outline\(' + - # Patterns that must NOT be found + # No toc_title argument in the article() call: the filter removed the + # metadata, so article() falls back to its own `toc_title: none` default + - 'toc_title: \[' + ensurePdfRegexMatches: + - # Typst's `auto` outline title for lang: en + - 'Contents' +--- + +Quarto fills `toc-title` with a localized default before Pandoc runs, so the +Typst `article()` function normally always receives a `toc_title` argument. +A user Lua `Meta` filter that removes the key is the one path that reaches the +function's own `toc_title: none` default, which is where `outline(title: auto)` +has to take over so the table of contents still gets a heading. From 1e7c3eb92307522864936d9b4807b2386cb37260 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Thu, 3 Sep 2026 17:54:00 +0200 Subject: [PATCH 3/3] Polish typst TOC fallback test wording --- tests/docs/smoke-all/typst/toc/strip-toc-title.lua | 4 ++-- .../docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/docs/smoke-all/typst/toc/strip-toc-title.lua b/tests/docs/smoke-all/typst/toc/strip-toc-title.lua index 893ea4fdc92..f86da508541 100644 --- a/tests/docs/smoke-all/typst/toc/strip-toc-title.lua +++ b/tests/docs/smoke-all/typst/toc/strip-toc-title.lua @@ -1,5 +1,5 @@ --- Removes the toc-title metadata that Quarto fills in before Pandoc runs, --- so the Typst template receives its own `toc_title: none` default. +-- Removes the toc-title metadata that Quarto adds before Pandoc runs, +-- causing article() to use its `toc_title: none` default. function Meta(meta) meta["toc-title"] = nil return meta diff --git a/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd b/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd index 4a5278108cf..5d2c6c6becf 100644 --- a/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd +++ b/tests/docs/smoke-all/typst/toc/toc-title-auto-fallback.qmd @@ -24,7 +24,7 @@ _quarto: --- Quarto fills `toc-title` with a localized default before Pandoc runs, so the -Typst `article()` function normally always receives a `toc_title` argument. -A user Lua `Meta` filter that removes the key is the one path that reaches the -function's own `toc_title: none` default, which is where `outline(title: auto)` -has to take over so the table of contents still gets a heading. +Typst `article()` function normally receives a `toc_title` argument. This test +uses a Lua `Meta` filter to remove the key and reach the function's own +`toc_title: none` default. In that case, `outline(title: auto)` provides the +table of contents heading.