diff --git a/CHANGELOG.md b/CHANGELOG.md index 75b80a7..caab051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,14 @@ ## Unreleased +### Bug Fixes + +- fix: Honour a boolean option written as a bare YAML `false`, such as `auto-filename: false`, `enabled: false`, or `lines-label: false`. The value was read as an absent option, so the default applied instead and only the quoted string worked. + ### Documentation +- docs: Correct the reference and the examples page, which said a derived filename frames nothing in HTML. It frames the block through the injected script, as the rest of the HTML chrome does. + - docs: Add a documentation website under `docs/`, built on the `atelier` project type and published to , framed by the extension itself. - docs: Record that the filter claims code blocks at `pre-quarto`, which prevents `typst-render` from seeing its own `{typst}` blocks and double-decorates alongside `language-cell-decorator`. - docs: Trim `README.md` to a landing page pointing at the website. diff --git a/_extensions/code-window/_modules/metadata.lua b/_extensions/code-window/_modules/metadata.lua index bab2087..2e1b6d5 100644 --- a/_extensions/code-window/_modules/metadata.lua +++ b/_extensions/code-window/_modules/metadata.lua @@ -42,8 +42,12 @@ end --- @param key string The metadata key to retrieve --- @return string|nil The metadata value as a string, or nil if not found --- @usage local repo = M.get_metadata_value(meta, "github", "repository-name") +--- @note A boolean `false` is a value, not an absence, so the test is against +--- `nil` rather than truthiness. Stringifying it yields "false", which is what +--- a caller comparing against the string form already expects. function M.get_metadata_value(meta, extension_name, key) - if meta['extensions'] and meta['extensions'][extension_name] and meta['extensions'][extension_name][key] then + if meta['extensions'] and meta['extensions'][extension_name] + and meta['extensions'][extension_name][key] ~= nil then return str.stringify(meta['extensions'][extension_name][key]) end return nil @@ -175,6 +179,44 @@ function M.get_options(spec) return result end +-- ============================================================================ +-- PROJECT METADATA UTILITIES +-- ============================================================================ + +--- Get repo-url from Quarto project metadata via QUARTO_EXECUTE_INFO. +--- Reads the JSON file pointed to by the QUARTO_EXECUTE_INFO environment variable +--- and extracts repo-url from website or book metadata. +--- @return string|nil The repo-url value, or nil if not available +function M.get_project_repo_url() + local path = os.getenv("QUARTO_EXECUTE_INFO") + if not path then return nil end + + local file = io.open(path, "r") + if not file then return nil end + + local content = file:read("*a") + file:close() + + if str.is_empty(content) then return nil end + + local ok, info = pcall(quarto.json.decode, content) + if not ok or not info then return nil end + + local format_meta = info["format"] and info["format"]["metadata"] + if not format_meta then return nil end + + -- Try website.repo-url first, then book.repo-url + local repo_url = nil + if format_meta["website"] and format_meta["website"]["repo-url"] then + repo_url = format_meta["website"]["repo-url"] + elseif format_meta["book"] and format_meta["book"]["repo-url"] then + repo_url = format_meta["book"]["repo-url"] + end + + if str.is_empty(repo_url) then return nil end + return repo_url +end + -- ============================================================================ -- MODULE EXPORT -- ============================================================================ diff --git a/docs/_quarto.yml b/docs/_quarto.yml index b586862..6068cbf 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -124,7 +124,4 @@ extensions: style: "macos" # Blocks here are configuration to copy rather than files to save, so a # filename derived from the language would only add noise. - # - # Quoted deliberately. A bare `false` is read as unset and reverts to the - # default, because the option lookup treats a Lua `false` as absent. - auto-filename: "false" + auto-filename: false diff --git a/docs/examples.qmd b/docs/examples.qmd index a6d4afb..06cba1a 100644 --- a/docs/examples.qmd +++ b/docs/examples.qmd @@ -11,7 +11,7 @@ The site sets: extensions: code-window: style: macos - auto-filename: "false" + auto-filename: false ``` ## Naming the window @@ -30,8 +30,8 @@ project: type: website ``` -A block with no `filename` is left alone in HTML, whatever `auto-filename` says. -Under Typst that same block is framed and labelled with its language. +A block with no `filename` is left alone here, because this site turns `auto-filename` off. +With it on, that same block is framed and labelled with its language, in HTML and under Typst alike. ## The three styles diff --git a/docs/reference.qmd b/docs/reference.qmd index 4223ee5..1214f61 100644 --- a/docs/reference.qmd +++ b/docs/reference.qmd @@ -54,10 +54,11 @@ extensions: Quarto's own `filename` attribute names the window. -::: {.callout-important} -In HTML output only a block with an author-set `filename` is framed. -Quarto builds the wrapper the chrome attaches to before this filter runs, so a filename derived by `auto-filename` arrives too late: the block keeps its language as a `data-filename` attribute and renders without a window. -Typst is unaffected, and frames derived and author-set filenames alike. +::: {.callout-note} +A derived filename is applied later than an author-set one. +Quarto builds its own wrapper before this filter runs, so a block with no `filename` leaves the filter carrying a `data-filename` attribute and a marker class instead, and the injected script builds the wrapper at page load. +The result is the same window; it needs JavaScript, as the rest of the HTML chrome does. +Typst frames derived and author-set filenames alike, without a script. ::: ## How the chrome is applied @@ -104,5 +105,4 @@ Two extensions in this family are affected: [`typst-render`](https://m.canouil.d - HTML formats and Typst. Elsewhere the code block is left as it is. - Folding is HTML only; Typst has no equivalent. - The HTML chrome is built by script at page load, so a reader with JavaScript off sees plain code blocks. -- `auto-filename` frames nothing in HTML; give a block an explicit `filename` there. -- A boolean option written as `false` under `extensions.code-window` is read as unset and reverts to its default. Write `"false"` in quotes until this is fixed. +- A block with a derived filename is framed by the script rather than by the wrapper Quarto builds, so it needs JavaScript in HTML like the rest of the chrome.