diff --git a/_extensions/code-window/code-window.lua b/_extensions/code-window/code-window.lua index 350cfd9..55586c0 100644 --- a/_extensions/code-window/code-window.lua +++ b/_extensions/code-window/code-window.lua @@ -40,7 +40,23 @@ local VALID_STYLES = { ['default'] = true, ['macos'] = true, ['windows'] = true --- schema declares and the internal label the language module writes alike. local ATTRIBUTE_PREFIX = 'code-window-' -local DEFAULTS = { +--- Defaults for the two cases where the schema cannot answer: a format the +--- extension does not act on, where the check never runs, and a schema that +--- could not be read, which is a state this extension renders through rather +--- than stopping for. Everywhere else _schema.yml decides these seven, so the +--- values below are a fallback and not a second place to change one of them. +--- The hotfix defaults are a different story, and are still kept by hand in +--- HOTFIX_DEFAULTS: they are nested in the schema and read on their own path, +--- so changing one in _schema.yml alone still changes nothing. +--- All seven stay listed, because the second case has nothing else to read +--- from, and an option added to the schema needs an entry here as well or it +--- has no default at all on a format the extension does not act on. +--- Where the two disagree, the schema wins on html and typst, and a format +--- the extension does not act on reads "enabled" alone, which is the one that +--- chooses whether a block's attributes are checked. So keep that one in step +--- with the schema, and treat a difference in the other six as a thing to +--- correct rather than a thing that shows. +local FALLBACK_DEFAULTS = { ['enabled'] = 'true', ['auto-filename'] = 'true', ['style'] = 'macos', @@ -782,8 +798,32 @@ function Meta(meta) -- read below, because the report says what the extension cannot use and the -- document renders either way. Only a format the extension acts on reports, -- because nothing it could say applies anywhere else. + -- The check also answers what the schema declares each option defaults to, + -- so those values are kept rather than dropped and rebuilt by hand here. + -- They arrive typed, and every comparison below reads a string, so each one + -- goes through stringify_bool on the way into the table. + local schema_defaults = {} if acts_on_format() then - checker:options(meta) + schema_defaults = checker:options(meta) + end + + -- The schema is read first and the fallback fills only what it leaves + -- unanswered, so on html and typst an option added to _schema.yml and to the + -- key list below needs nothing more. Anywhere else the check above never + -- runs, so the same option also needs an entry in FALLBACK_DEFAULTS or it + -- has no default there. Reading the fallback first would have made it the + -- list of options allowed to have a default at all, on every format, which + -- is the coupling this change exists to remove. What arrives is one entry + -- per option that declares a default of its own, and get_options reads only + -- the keys named below. + local defaults = {} + for key, declared in pairs(schema_defaults) do + defaults[key] = stringify_bool(declared) + end + for key, fallback in pairs(FALLBACK_DEFAULTS) do + if defaults[key] == nil then + defaults[key] = fallback + end end local opts = meta_mod.get_options({ @@ -792,7 +832,7 @@ function Meta(meta) 'enabled', 'auto-filename', 'style', 'cell-output', 'wrapper', 'collapse', 'lines-label', }, meta = meta, - defaults = DEFAULTS, + defaults = defaults, }) -- checker:options (above) already reports an unrecognised "style" value in diff --git a/tests/fixtures/wrapper-default.qmd b/tests/fixtures/wrapper-default.qmd new file mode 100644 index 0000000..9598b66 --- /dev/null +++ b/tests/fixtures/wrapper-default.qmd @@ -0,0 +1,16 @@ +--- +title: "The Typst wrapper name" +filters: + - code-window +format: + typst: + keep-typ: true +--- + +The block below is framed, so the document calls the wrapper function by the +name the configuration gives it. Nothing here sets that name, so the default +decides, and the schema is where the default is written down. + +```{.python filename="a.py"} +x = 1 +``` diff --git a/tests/run.sh b/tests/run.sh index 31e0e19..cae2fc8 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -235,6 +235,51 @@ else "a default class, a cw-auto class, and data-filename=\"foo\" on the block" fi +# ============================================================================ +# The schema is where an option's default is written down +# ============================================================================ + +# The schema declares a default for every option, and so did a table in the +# Lua. Changing the schema alone has to change the render, or the two can +# disagree with nothing to say so. The wrapper name is the option under test +# because it reaches the Typst output word for word. +render wrapper-default typst +if grep -q '^#code-window(' "${work_dir}/wrapper-default.typ"; then + report pass "wrapper-default: the schema default names the wrapper" +else + report fail "wrapper-default: the schema default names the wrapper" \ + "a #code-window( call in wrapper-default.typ" +fi + +sed -i.aside 's/default: "code-window"/default: "my-window"/' \ + "${work_dir}/_extensions/code-window/_schema.yml" +render wrapper-default typst +mv "${work_dir}/_extensions/code-window/_schema.yml.aside" \ + "${work_dir}/_extensions/code-window/_schema.yml" + +# The old name has to be gone as well as the new one present, because a rename +# that missed a call site would leave both in the document. +if grep -q '^#my-window(' "${work_dir}/wrapper-default.typ" && + ! grep -q '^#code-window(' "${work_dir}/wrapper-default.typ"; then + report pass "wrapper-default: a default changed in the schema alone is followed" +else + report fail "wrapper-default: a default changed in the schema alone is followed" \ + "a #my-window( call and no #code-window( call in wrapper-default.typ" +fi + +# With no schema to read, the fallback in the Lua answers instead, and the +# document still renders rather than stopping. +mv "${work_dir}/_extensions/code-window/_schema.yml" "${work_dir}/schema.yml.aside" +render wrapper-default typst +mv "${work_dir}/schema.yml.aside" "${work_dir}/_extensions/code-window/_schema.yml" + +if grep -q '^#code-window(' "${work_dir}/wrapper-default.typ"; then + report pass "wrapper-default: the fallback answers when the schema cannot be read" +else + report fail "wrapper-default: the fallback answers when the schema cannot be read" \ + "a #code-window( call in wrapper-default.typ" +fi + # ============================================================================ printf '\n%s passed, %s failed\n' "${passed}" "${failed}"