Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://m.canouil.dev/quarto-code-window/>, 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.
Expand Down
44 changes: 43 additions & 1 deletion _extensions/code-window/_modules/metadata.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
-- ============================================================================
Expand Down
5 changes: 1 addition & 4 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 3 additions & 3 deletions docs/examples.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The site sets:
extensions:
code-window:
style: macos
auto-filename: "false"
auto-filename: false
```

## Naming the window
Expand All @@ -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

Expand Down
12 changes: 6 additions & 6 deletions docs/reference.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.