From fb18d0e3a6e590c7f2a4aaed8bf33202a92dcfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 22:55:22 +0100 Subject: [PATCH 1/7] feat: add public code-window-auto-label attribute Another filter can now ask for a window on a block that has no filename, without copying the internal cw-auto marker. The label frames the block even when auto-filename is off, and an explicit filename or a per-block opt-out still wins. --- CHANGELOG.md | 4 ++ _extensions/code-window/_modules/language.lua | 22 +++++--- _extensions/code-window/_schema.yml | 3 ++ _extensions/code-window/code-window.lua | 20 ++++++-- _extensions/code-window/main.lua | 10 +++- docs/reference.qmd | 18 +++++++ tests/fixtures/auto-label-forced.qmd | 39 +++++++++++++++ tests/fixtures/auto-label-kept.qmd | 12 +++++ tests/run.sh | 50 +++++++++++++++++++ 9 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 tests/fixtures/auto-label-forced.qmd create mode 100644 tests/fixtures/auto-label-kept.qmd diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a926d5..66e1db1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ - refactor: Remove the `typst-title` hot-fix and its `hotfix.typst-title` option, as Quarto renders theorem titles as Typst markup since 1.10. (#78) - build: Require Quarto 1.10.19 or later. (#78) +### New Features + +- feat: Add the `code-window-auto-label` attribute, so another filter can ask for a window with its own label on a block that has no `filename`. The label works even when `auto-filename` is off. + ### Bug Fixes - fix: Style inline code in a Typst theorem title like inline code anywhere else. (#78) diff --git a/_extensions/code-window/_modules/language.lua b/_extensions/code-window/_modules/language.lua index 59bdeef..2494cf3 100644 --- a/_extensions/code-window/_modules/language.lua +++ b/_extensions/code-window/_modules/language.lua @@ -31,6 +31,20 @@ local function is_known_language(lang) return is_known end +--- Write the label on a block that has no name yet. +--- A filename or a label already on the block wins, because the author or +--- another filter set it to name the window. +--- @param block pandoc.CodeBlock +--- @param label string Label to write when the block has no name yet +local function set_label(block, label) + local attributes = block.attributes + local has_filename = attributes['filename'] and attributes['filename'] ~= '' + local has_label = attributes['code-window-auto-label'] and attributes['code-window-auto-label'] ~= '' + if not has_filename and not has_label then + attributes['code-window-auto-label'] = label + end +end + --- Normalise code blocks with no or unknown language class to "default". --- Both are framed like a highlighted code cell rather than left as a bare --- block: a no-language block is labelled "default", and an unknown language @@ -47,18 +61,14 @@ function M.CodeBlock(block) if not block.classes or #block.classes == 0 then block.classes:insert('default') - if not block.attributes['filename'] or block.attributes['filename'] == '' then - block.attributes['code-window-auto-label'] = 'default' - end + set_label(block, 'default') return block end local lang = block.classes[1] if not is_known_language(lang) then block.classes[1] = 'default' - if not block.attributes['filename'] or block.attributes['filename'] == '' then - block.attributes['code-window-auto-label'] = lang - end + set_label(block, lang) end return block diff --git a/_extensions/code-window/_schema.yml b/_extensions/code-window/_schema.yml index 2484de6..4ac81e1 100644 --- a/_extensions/code-window/_schema.yml +++ b/_extensions/code-window/_schema.yml @@ -71,6 +71,9 @@ attributes: type: boolean default: false description: "Suppress the auto-generated filename for this specific code block without changing the global setting." + code-window-auto-label: + type: string + description: "Frame this code block with this label, styled as an auto-generated filename, even when auto-filename is false. An explicit filename, code-window-enabled false, or code-window-no-auto-filename true wins over it." code-window-style: type: string enum: ["default", "macos", "windows"] diff --git a/_extensions/code-window/code-window.lua b/_extensions/code-window/code-window.lua index 287fb33..fc2dd8d 100644 --- a/_extensions/code-window/code-window.lua +++ b/_extensions/code-window/code-window.lua @@ -147,6 +147,9 @@ end --- @return string|nil auto_label Label written by the language module, if any local function take_block_attributes(block) local auto_label = block.attributes['code-window-auto-label'] + if auto_label == '' then + auto_label = nil + end local owned = {} for key, _ in pairs(block.attributes) do if key:sub(1, #ATTRIBUTE_PREFIX) == ATTRIBUTE_PREFIX and not cell_output.is_marker(key) then @@ -706,7 +709,9 @@ local function process_html(block, resolved, auto_label) return block end - if not CONFIG.auto_filename or overrides.no_auto_filename then + -- A label on the block asks for a window by itself, so it does not wait on + -- the document's auto-filename setting. + if overrides.no_auto_filename or not (auto_label or CONFIG.auto_filename) then return block end @@ -1036,10 +1041,15 @@ local function resolve_window_params(block, resolved, auto_label) local is_auto = false if (not filename or filename == '') and not overrides.no_auto_filename then - if CONFIG.auto_filename and block.classes and #block.classes > 0 then - -- Default/unknown/no-language blocks carry their label on - -- code-window-auto-label; everything else uses its language class. - filename = auto_label or block.classes[1] + -- A label on the block asks for a window by itself, whatever the + -- document's auto-filename setting. Default/unknown/no-language blocks + -- carry the label the language module wrote; everything else uses its + -- language class. + if auto_label then + filename = auto_label + is_auto = true + elseif CONFIG.auto_filename and block.classes and #block.classes > 0 then + filename = block.classes[1] is_auto = true end end diff --git a/_extensions/code-window/main.lua b/_extensions/code-window/main.lua index 59727d4..5af238e 100644 --- a/_extensions/code-window/main.lua +++ b/_extensions/code-window/main.lua @@ -79,10 +79,18 @@ end --- rewritten with no reader either. Answering that per block means relabelling --- where the name is built, which is a change to the two window paths rather --- than to this gate. +--- A block that carries "code-window-auto-label" asks for a window by itself, +--- so it takes the pass whatever "auto-filename" says. Without it, a block in +--- a language Pandoc cannot highlight would get no wrapper to frame. --- @param block pandoc.CodeBlock --- @return pandoc.CodeBlock|nil Relabelled block, or nil when the pass is skipped local function normalise_language(block) - if not code_window.draws_chrome() or not code_window.CONFIG().auto_filename then + if not code_window.draws_chrome() then + return nil + end + local label = block.attributes['code-window-auto-label'] + local has_label = label and label ~= '' + if not code_window.CONFIG().auto_filename and not has_label then return nil end return language.CodeBlock(block) diff --git a/docs/reference.qmd b/docs/reference.qmd index c560b9e..4e42542 100644 --- a/docs/reference.qmd +++ b/docs/reference.qmd @@ -47,6 +47,7 @@ extensions: | --- | --- | --- | | `code-window-enabled` | boolean | Whether this block gets chrome. Annotations still render when it does not. | | `code-window-no-auto-filename` | boolean | Suppress the derived filename for this block alone. | +| `code-window-auto-label` | string | Frame this block with this label, styled as a derived filename. Works when `auto-filename` is `false`. | | `code-window-style` | string | Override the style for this block: `macos`, `windows`, `default`. | | `code-window-collapse` | boolean or string | Fold this block: `open`, `closed`, `true`, or `false`. HTML only. | | `code-window-lines` | string | The line spec shown in the chip, such as `1,3-5`. Defaults to Quarto's `code-line-numbers`. | @@ -62,6 +63,23 @@ The result is the same window; it needs JavaScript, as the rest of the HTML chro Typst frames derived and author-set filenames alike, without a script. ::: +### Labels from another filter + +A filter that runs before Code Window can ask for a window on a block that has no `filename`. +Set `code-window-auto-label` on the block to the label that the title bar must show. + +```lua +block.attributes['code-window-auto-label'] = 'Terminal' +``` + +The label shows in the same style as a derived filename. +The block gets the window also when the document sets `auto-filename` to `false`. +These attributes win over the label: + +- A `filename` attribute names the window instead of the label. +- `code-window-enabled="false"` removes the window. +- `code-window-no-auto-filename="true"` removes the window. + ## Executed cells Quarto writes the output of an executed cell as a code block with no language. diff --git a/tests/fixtures/auto-label-forced.qmd b/tests/fixtures/auto-label-forced.qmd new file mode 100644 index 0000000..5eafa63 --- /dev/null +++ b/tests/fixtures/auto-label-forced.qmd @@ -0,0 +1,39 @@ +--- +title: "A label that asks for its own window" +filters: + - code-window +format: + html: default + typst: + keep-typ: true +extensions: + code-window: + auto-filename: false +--- + +The document derives no names, yet the first block names its own label, so it +gets a window with that label. Each block after it writes something that wins +over the label, so none of them gets the label in its title bar. + +```{.bash code-window-auto-label="Terminal"} +echo forced +``` + +```{.bash filename="run.sh" code-window-auto-label="Terminal"} +echo explicit +``` + +```{.bash code-window-enabled="false" code-window-auto-label="Terminal"} +echo disabled +``` + +```{.bash code-window-no-auto-filename="true" code-window-auto-label="Terminal"} +echo refused +``` + +A labelled block in a language Pandoc cannot highlight still goes through the +language pass, so it is framed like any other labelled block. + +```{.foo code-window-auto-label="Shell"} +x = 1 +``` diff --git a/tests/fixtures/auto-label-kept.qmd b/tests/fixtures/auto-label-kept.qmd new file mode 100644 index 0000000..494459a --- /dev/null +++ b/tests/fixtures/auto-label-kept.qmd @@ -0,0 +1,12 @@ +--- +title: "A label set before the language pass" +filters: + - code-window +--- + +The language pass labels a block whose language Pandoc cannot highlight. A +label another filter set first has to survive that pass. + +```{.foo code-window-auto-label="Terminal"} +x = 1 +``` diff --git a/tests/run.sh b/tests/run.sh index 05e1ebe..3ab341f 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -455,6 +455,56 @@ else "pdftotext on PATH (brew install poppler)" fi +# ============================================================================ +# A label set on a block asks for a window of its own +# ============================================================================ + +# Another filter sets code-window-auto-label to get a window with a derived +# style on a block that names no file. The label has to work when the document +# derives no names, and an explicit filename or a per-block opt-out still wins. +render auto-label-forced html +forced_html="${work_dir}/auto-label-forced.html" +forced_labels="$({ grep -o 'data-filename="Terminal"' "${forced_html}" || true; } | wc -l | tr -d ' ')" +forced_auto="$(block_classes "${forced_html}" | grep -c 'cw-auto' || true)" +if [ "${forced_labels}" -eq 1 ] && [ "${forced_auto}" -eq 2 ] && + grep -q 'data-filename="run.sh"' "${forced_html}"; then + report pass "auto-label-forced: only the labelled block takes the label in HTML" +else + report fail "auto-label-forced: only the labelled block takes the label in HTML" \ + "one data-filename=\"Terminal\", two cw-auto blocks, and data-filename=\"run.sh\", got ${forced_labels} and ${forced_auto}" +fi + +render auto-label-forced typst +forced_typst="${work_dir}/auto-label-forced.typ" +if [ "$(count_typst_windows "${forced_typst}")" -eq 3 ] && + grep -q '^#code-window(filename: "Terminal", is-auto: true' "${forced_typst}" && + grep -q '^#code-window(filename: "run.sh", is-auto: false' "${forced_typst}"; then + report pass "auto-label-forced: only the labelled block takes the label in Typst" +else + report fail "auto-label-forced: only the labelled block takes the label in Typst" \ + "three code-window calls, with one for Terminal with is-auto: true and one for run.sh" +fi + +# A labelled block takes the language pass even where the document derives no +# names, or Pandoc leaves it unhighlighted and the script has no wrapper to +# frame. +if block_wrappers "${forced_html}" | grep -q 'data-filename="Shell"'; then + report pass "auto-label-forced: a labelled block in an unknown language is framed" +else + report fail "auto-label-forced: a labelled block in an unknown language is framed" \ + "data-filename=\"Shell\" on a sourceCode wrapper in auto-label-forced.html" +fi + +# The language pass labels a block it cannot highlight, and a label that is +# already there is the one to keep. +render auto-label-kept html +if grep -q 'data-filename="Terminal"' "${work_dir}/auto-label-kept.html"; then + report pass "auto-label-kept: the language pass keeps a label set before it" +else + report fail "auto-label-kept: the language pass keeps a label set before it" \ + "data-filename=\"Terminal\" in auto-label-kept.html" +fi + # ============================================================================ printf '\n%s passed, %s failed\n' "${passed}" "${failed}" From 5cb7675a03fac807fa5a3140d1a7852daf983379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 22:59:26 +0100 Subject: [PATCH 2/7] refactor: read the auto label in one place --- _extensions/code-window/_modules/language.lua | 27 ++++++++++++------- _extensions/code-window/_schema.yml | 2 +- _extensions/code-window/code-window.lua | 13 +++------ _extensions/code-window/main.lua | 8 ++---- tests/fixtures/auto-label-kept.qmd | 12 --------- tests/run.sh | 17 +++--------- 6 files changed, 27 insertions(+), 52 deletions(-) delete mode 100644 tests/fixtures/auto-label-kept.qmd diff --git a/_extensions/code-window/_modules/language.lua b/_extensions/code-window/_modules/language.lua index 2494cf3..d4763a7 100644 --- a/_extensions/code-window/_modules/language.lua +++ b/_extensions/code-window/_modules/language.lua @@ -6,6 +6,8 @@ local cell_output = require( quarto.utils.resolve_path('_modules/cell-output.lua'):gsub('%.lua$', '')) +local str = require( + quarto.utils.resolve_path('_vendor/quarto-lua-modules/string.lua'):gsub('%.lua$', '')) local M = {} @@ -31,17 +33,24 @@ local function is_known_language(lang) return is_known end ---- Write the label on a block that has no name yet. ---- A filename or a label already on the block wins, because the author or ---- another filter set it to name the window. +--- Read the label that names a block's window, set by this module, by the +--- author, or by another filter. An empty value counts as no label. --- @param block pandoc.CodeBlock ---- @param label string Label to write when the block has no name yet +--- @return string|nil label +function M.auto_label(block) + local label = block.attributes['code-window-auto-label'] + if str.is_empty(label) then + return nil + end + return label +end + +--- Set the label unless the block already has a filename or a label. +--- @param block pandoc.CodeBlock +--- @param label string local function set_label(block, label) - local attributes = block.attributes - local has_filename = attributes['filename'] and attributes['filename'] ~= '' - local has_label = attributes['code-window-auto-label'] and attributes['code-window-auto-label'] ~= '' - if not has_filename and not has_label then - attributes['code-window-auto-label'] = label + if str.is_empty(block.attributes['filename']) and not M.auto_label(block) then + block.attributes['code-window-auto-label'] = label end end diff --git a/_extensions/code-window/_schema.yml b/_extensions/code-window/_schema.yml index 4ac81e1..34003e3 100644 --- a/_extensions/code-window/_schema.yml +++ b/_extensions/code-window/_schema.yml @@ -73,7 +73,7 @@ attributes: description: "Suppress the auto-generated filename for this specific code block without changing the global setting." code-window-auto-label: type: string - description: "Frame this code block with this label, styled as an auto-generated filename, even when auto-filename is false. An explicit filename, code-window-enabled false, or code-window-no-auto-filename true wins over it." + description: "Frame this code block with this label, styled as an auto-generated filename, even when auto-filename is false." code-window-style: type: string enum: ["default", "macos", "windows"] diff --git a/_extensions/code-window/code-window.lua b/_extensions/code-window/code-window.lua index fc2dd8d..b699279 100644 --- a/_extensions/code-window/code-window.lua +++ b/_extensions/code-window/code-window.lua @@ -18,6 +18,7 @@ local meta_mod = require(quarto.utils.resolve_path('_vendor/quarto-lua-modules/m local pdoc = require(quarto.utils.resolve_path('_vendor/quarto-lua-modules/pandoc-helpers.lua'):gsub('%.lua$', '')) local html_mod = require(quarto.utils.resolve_path('_vendor/quarto-lua-modules/html.lua'):gsub('%.lua$', '')) local cell_output = require(quarto.utils.resolve_path('_modules/cell-output.lua'):gsub('%.lua$', '')) +local language = require(quarto.utils.resolve_path('_modules/language.lua'):gsub('%.lua$', '')) local code_annotations = nil local checker = nil @@ -146,10 +147,7 @@ end --- @param block pandoc.CodeBlock Code block element --- @return string|nil auto_label Label written by the language module, if any local function take_block_attributes(block) - local auto_label = block.attributes['code-window-auto-label'] - if auto_label == '' then - auto_label = nil - end + local auto_label = language.auto_label(block) local owned = {} for key, _ in pairs(block.attributes) do if key:sub(1, #ATTRIBUTE_PREFIX) == ATTRIBUTE_PREFIX and not cell_output.is_marker(key) then @@ -709,8 +707,6 @@ local function process_html(block, resolved, auto_label) return block end - -- A label on the block asks for a window by itself, so it does not wait on - -- the document's auto-filename setting. if overrides.no_auto_filename or not (auto_label or CONFIG.auto_filename) then return block end @@ -1041,10 +1037,7 @@ local function resolve_window_params(block, resolved, auto_label) local is_auto = false if (not filename or filename == '') and not overrides.no_auto_filename then - -- A label on the block asks for a window by itself, whatever the - -- document's auto-filename setting. Default/unknown/no-language blocks - -- carry the label the language module wrote; everything else uses its - -- language class. + -- A label asks for a window whatever auto-filename says. if auto_label then filename = auto_label is_auto = true diff --git a/_extensions/code-window/main.lua b/_extensions/code-window/main.lua index 5af238e..38357fe 100644 --- a/_extensions/code-window/main.lua +++ b/_extensions/code-window/main.lua @@ -85,12 +85,8 @@ end --- @param block pandoc.CodeBlock --- @return pandoc.CodeBlock|nil Relabelled block, or nil when the pass is skipped local function normalise_language(block) - if not code_window.draws_chrome() then - return nil - end - local label = block.attributes['code-window-auto-label'] - local has_label = label and label ~= '' - if not code_window.CONFIG().auto_filename and not has_label then + if not code_window.draws_chrome() + or (not code_window.CONFIG().auto_filename and not language.auto_label(block)) then return nil end return language.CodeBlock(block) diff --git a/tests/fixtures/auto-label-kept.qmd b/tests/fixtures/auto-label-kept.qmd deleted file mode 100644 index 494459a..0000000 --- a/tests/fixtures/auto-label-kept.qmd +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "A label set before the language pass" -filters: - - code-window ---- - -The language pass labels a block whose language Pandoc cannot highlight. A -label another filter set first has to survive that pass. - -```{.foo code-window-auto-label="Terminal"} -x = 1 -``` diff --git a/tests/run.sh b/tests/run.sh index 3ab341f..9cf072c 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -464,7 +464,7 @@ fi # derives no names, and an explicit filename or a per-block opt-out still wins. render auto-label-forced html forced_html="${work_dir}/auto-label-forced.html" -forced_labels="$({ grep -o 'data-filename="Terminal"' "${forced_html}" || true; } | wc -l | tr -d ' ')" +forced_labels="$(block_wrappers "${forced_html}" | grep -c 'data-filename="Terminal"' || true)" forced_auto="$(block_classes "${forced_html}" | grep -c 'cw-auto' || true)" if [ "${forced_labels}" -eq 1 ] && [ "${forced_auto}" -eq 2 ] && grep -q 'data-filename="run.sh"' "${forced_html}"; then @@ -485,9 +485,8 @@ else "three code-window calls, with one for Terminal with is-auto: true and one for run.sh" fi -# A labelled block takes the language pass even where the document derives no -# names, or Pandoc leaves it unhighlighted and the script has no wrapper to -# frame. +# The language pass runs for a labelled block and keeps its label, or the +# label would read "foo". if block_wrappers "${forced_html}" | grep -q 'data-filename="Shell"'; then report pass "auto-label-forced: a labelled block in an unknown language is framed" else @@ -495,16 +494,6 @@ else "data-filename=\"Shell\" on a sourceCode wrapper in auto-label-forced.html" fi -# The language pass labels a block it cannot highlight, and a label that is -# already there is the one to keep. -render auto-label-kept html -if grep -q 'data-filename="Terminal"' "${work_dir}/auto-label-kept.html"; then - report pass "auto-label-kept: the language pass keeps a label set before it" -else - report fail "auto-label-kept: the language pass keeps a label set before it" \ - "data-filename=\"Terminal\" in auto-label-kept.html" -fi - # ============================================================================ printf '\n%s passed, %s failed\n' "${passed}" "${failed}" From 3fff1eedf63f08ea3a2fe95c3aac26ea9b2c1100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 23:05:09 +0100 Subject: [PATCH 3/7] fix: keep the language of a labelled block with no window --- _extensions/code-window/main.lua | 14 +++++++++++--- tests/fixtures/auto-label-forced.qmd | 11 +++++++++++ tests/run.sh | 10 ++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/_extensions/code-window/main.lua b/_extensions/code-window/main.lua index 38357fe..e4ec16b 100644 --- a/_extensions/code-window/main.lua +++ b/_extensions/code-window/main.lua @@ -81,14 +81,22 @@ end --- than to this gate. --- A block that carries "code-window-auto-label" asks for a window by itself, --- so it takes the pass whatever "auto-filename" says. Without it, a block in ---- a language Pandoc cannot highlight would get no wrapper to frame. +--- a language Pandoc cannot highlight would get no wrapper to frame. Such a +--- block that also refuses the window has no reader for the label, so it is +--- left alone here. --- @param block pandoc.CodeBlock --- @return pandoc.CodeBlock|nil Relabelled block, or nil when the pass is skipped local function normalise_language(block) - if not code_window.draws_chrome() - or (not code_window.CONFIG().auto_filename and not language.auto_label(block)) then + if not code_window.draws_chrome() then return nil end + if not code_window.CONFIG().auto_filename then + local refuses_window = block.attributes['code-window-enabled'] == 'false' + or block.attributes['code-window-no-auto-filename'] == 'true' + if not language.auto_label(block) or refuses_window then + return nil + end + end return language.CodeBlock(block) end diff --git a/tests/fixtures/auto-label-forced.qmd b/tests/fixtures/auto-label-forced.qmd index 5eafa63..a515453 100644 --- a/tests/fixtures/auto-label-forced.qmd +++ b/tests/fixtures/auto-label-forced.qmd @@ -37,3 +37,14 @@ language pass, so it is framed like any other labelled block. ```{.foo code-window-auto-label="Shell"} x = 1 ``` + +A labelled block that turns the window off keeps the language its author wrote, +because no window reads the label. + +```{.foo code-window-no-auto-filename="true" code-window-auto-label="Terminal"} +x = 2 +``` + +```{.foo code-window-enabled="false" code-window-auto-label="Terminal"} +x = 3 +``` diff --git a/tests/run.sh b/tests/run.sh index 9cf072c..15b07c4 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -494,6 +494,16 @@ else "data-filename=\"Shell\" on a sourceCode wrapper in auto-label-forced.html" fi +# A labelled block that refuses the window has no reader for the label, so the +# language pass leaves its language alone. +opted_out="$(block_classes "${forced_html}" | grep -c '"foo' || true)" +if [ "${opted_out}" -eq 2 ]; then + report pass "auto-label-forced: a labelled block that refuses the window keeps its language" +else + report fail "auto-label-forced: a labelled block that refuses the window keeps its language" \ + "two blocks with a foo class in auto-label-forced.html, got ${opted_out}" +fi + # ============================================================================ printf '\n%s passed, %s failed\n' "${passed}" "${failed}" From c6b5c4d2293874c8b673dbb76e79e300739ab695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 23:10:04 +0100 Subject: [PATCH 4/7] fix: read a block's opt-out in any letter case --- _extensions/code-window/main.lua | 5 +++-- tests/fixtures/auto-label-forced.qmd | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/_extensions/code-window/main.lua b/_extensions/code-window/main.lua index e4ec16b..478127f 100644 --- a/_extensions/code-window/main.lua +++ b/_extensions/code-window/main.lua @@ -91,8 +91,9 @@ local function normalise_language(block) return nil end if not code_window.CONFIG().auto_filename then - local refuses_window = block.attributes['code-window-enabled'] == 'false' - or block.attributes['code-window-no-auto-filename'] == 'true' + local enabled = (block.attributes['code-window-enabled'] or ''):lower() + local no_auto_filename = (block.attributes['code-window-no-auto-filename'] or ''):lower() + local refuses_window = enabled == 'false' or no_auto_filename == 'true' if not language.auto_label(block) or refuses_window then return nil end diff --git a/tests/fixtures/auto-label-forced.qmd b/tests/fixtures/auto-label-forced.qmd index a515453..48370eb 100644 --- a/tests/fixtures/auto-label-forced.qmd +++ b/tests/fixtures/auto-label-forced.qmd @@ -45,6 +45,6 @@ because no window reads the label. x = 2 ``` -```{.foo code-window-enabled="false" code-window-auto-label="Terminal"} +```{.foo code-window-enabled="False" code-window-auto-label="Terminal"} x = 3 ``` From 1b971ad4d49f20d356d0fbe3203215efcc7ad5ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 23:14:42 +0100 Subject: [PATCH 5/7] docs: note why the language gate reads raw opt-outs --- _extensions/code-window/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_extensions/code-window/main.lua b/_extensions/code-window/main.lua index 478127f..77cbe79 100644 --- a/_extensions/code-window/main.lua +++ b/_extensions/code-window/main.lua @@ -91,6 +91,8 @@ local function normalise_language(block) return nil end if not code_window.CONFIG().auto_filename then + -- Lowercased to match the schema's boolean coercion. Resolving through the + -- schema check here would report each of its warnings twice per block. local enabled = (block.attributes['code-window-enabled'] or ''):lower() local no_auto_filename = (block.attributes['code-window-no-auto-filename'] or ''):lower() local refuses_window = enabled == 'false' or no_auto_filename == 'true' From 9e252af815e2383669ab35cd24918cc8253208ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 23:16:06 +0100 Subject: [PATCH 6/7] docs: list the auto label under Unreleased --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66e1db1..a01d7bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Features + +- feat: Add the `code-window-auto-label` attribute, so another filter can ask for a window with its own label on a block that has no `filename`. The label works even when `auto-filename` is off. + ## 1.7.0 (2026-11-04) ### Breaking Changes @@ -9,10 +13,6 @@ - refactor: Remove the `typst-title` hot-fix and its `hotfix.typst-title` option, as Quarto renders theorem titles as Typst markup since 1.10. (#78) - build: Require Quarto 1.10.19 or later. (#78) -### New Features - -- feat: Add the `code-window-auto-label` attribute, so another filter can ask for a window with its own label on a block that has no `filename`. The label works even when `auto-filename` is off. - ### Bug Fixes - fix: Style inline code in a Typst theorem title like inline code anywhere else. (#78) From 856c7c85132f05644f758126701c64d685e35b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 4 Nov 2026 23:16:38 +0100 Subject: [PATCH 7/7] docs: add the pull request to the changelog [skip ci] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a01d7bd..165a998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### New Features -- feat: Add the `code-window-auto-label` attribute, so another filter can ask for a window with its own label on a block that has no `filename`. The label works even when `auto-filename` is off. +- feat: Add the `code-window-auto-label` attribute, so another filter can ask for a window with its own label on a block that has no `filename`. The label works even when `auto-filename` is off. (#82) ## 1.7.0 (2026-11-04)