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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## Unreleased

### Breaking Changes

- 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)

### Bug Fixes

- fix: Style inline code in a Typst theorem title like inline code anywhere else. (#78)

## 1.6.0 (2026-10-05)

### New Features
Expand Down
4 changes: 1 addition & 3 deletions _extensions/code-window/_extension.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
title: Code Window
author: Mickaël Canouil
version: 1.6.0
quarto-required: ">=1.9.36"
quarto-required: ">=1.10.19"
contributes:
filters:
- at: pre-quarto
path: main.lua
- at: post-quarto
path: _modules/hotfix/typst-title-fix.lua
71 changes: 13 additions & 58 deletions _extensions/code-window/_modules/hotfix/skylighting-typst-fix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
--- @copyright 2026 Mickaël Canouil
--- @author Mickaël Canouil
--- @brief Typst skylighting styling override and inline code background.
--- Pandoc 3.8+ generates correct token colours and bgcolor from the theme,
--- but the generated Skylighting block lacks styling properties (width, inset,
--- radius, stroke) and ignores its own fill parameter. This module overrides
--- the Skylighting function with better block styling and adds inline code
--- background support for Typst output.
--- This module redefines the Skylighting function to draw code annotation
--- markers, and adds inline code background support for Typst output.
--- Quarto patches the block styling of its own Skylighting function since
--- 1.9.27 (https://github.com/quarto-dev/quarto-cli/issues/14126), but the
--- redefinition replaces that function, so it carries the block styling
--- (width, inset, radius, stroke) and honours its fill parameter itself.

local _wrapper_prefix = 'code-window'

Expand All @@ -18,10 +19,9 @@ local function set_wrapper(prefix)
_wrapper_prefix = prefix
end

--- Build a Skylighting override with improved block styling.
--- Pandoc 3.8+ generates correct bgcolor but the block call lacks width,
--- inset, radius, and stroke properties. The fill parameter is also ignored.
--- This override fixes both issues.
--- Build a Skylighting override that draws annotation markers.
--- It replaces Quarto's patched function, so it sets the block width, inset,
--- radius and stroke itself, and honours its fill parameter.
--- @return string|nil Typst #let Skylighting(...) definition, or nil
local function build_skylighting_override()
local hm = PANDOC_WRITER_OPTIONS and PANDOC_WRITER_OPTIONS.highlight_method
Expand Down Expand Up @@ -219,61 +219,16 @@ function Pandoc(doc)
return doc
end

--- Check if a Div is a Quarto title scaffold (inline-only content).
--- NOTE: relies on Quarto's internal `__quarto_custom_scaffold` attribute,
--- which is not part of the public API and may change without notice.
--- @param div pandoc.Div
--- @return boolean
local function is_title_scaffold(div)
if div.attributes['__quarto_custom_scaffold'] ~= 'true' then
return false
end
for _, child in ipairs(div.content) do
if child.t ~= 'Plain' and child.t ~= 'Para' then
return false
end
end
return true
end

--- Walk the document tree and box inline Code with background styling.
--- The extension contributes the pass once, so it sees each Code element
--- once and boxes it once.
--- Code in title scaffolds is converted to plain
--- Typst backtick code to avoid Skylighting tokens with inner quotes
--- that would break the string parameter Quarto generates.
--- The typst-title-fix post-quarto filter then evaluates the string
--- as markup so the backtick code renders with proper inline styling.
--- once and boxes it once, theorem titles included. Metadata such as the
--- document title is left alone: the template writes it before the
--- definitions the box relies on.
local function process_inline_code(doc)
if not quarto.doc.is_format('typst') then
return doc
end

local code_filter = { Code = function(el) return process_typst_inline(el) end }
local title_filter = {
Code = function(el)
return pandoc.RawInline('typst', '`' .. el.text .. '`')
end,
}

local function walk_blocks(blocks)
local new_blocks = {}
for _, blk in ipairs(blocks) do
if blk.t == 'Div' then
if is_title_scaffold(blk) then
table.insert(new_blocks, blk:walk(title_filter))
else
blk.content = walk_blocks(blk.content)
table.insert(new_blocks, blk)
end
else
table.insert(new_blocks, blk:walk(code_filter))
end
end
return pandoc.Blocks(new_blocks)
end

doc.blocks = walk_blocks(doc.blocks)
doc.blocks = doc.blocks:walk({ Code = process_typst_inline })
return doc
end

Expand Down
111 changes: 0 additions & 111 deletions _extensions/code-window/_modules/hotfix/typst-title-fix.lua

This file was deleted.

12 changes: 0 additions & 12 deletions _extensions/code-window/_schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,6 @@ options:
quarto-version:
type: string
description: "Quarto version at or above which this hot-fix is automatically disabled."
typst-title:
type: [boolean, object]
default: true
description: "Enable the Typst title hot-fix (evaluates theorem title strings as markup). Use a boolean or a map with 'enabled' and 'quarto-version' keys."
additionalProperties: false
properties:
enabled:
type: boolean
description: "Explicitly enable or disable this hot-fix."
quarto-version:
type: string
description: "Quarto version at or above which this hot-fix is automatically disabled."

attributes:
CodeBlock:
Expand Down
11 changes: 0 additions & 11 deletions _extensions/code-window/code-window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ local VALID_COLLAPSE = {
local HOTFIX_DEFAULTS = {
['code-annotations'] = true,
['skylighting'] = true,
['typst-title'] = true,
}

local CURRENT_FORMAT = nil
Expand Down Expand Up @@ -919,19 +918,9 @@ function Meta(meta)
lines_label = opts['lines-label'] == 'true',
hotfix_code_annotations = hotfix['code-annotations'],
hotfix_skylighting = hotfix['skylighting'],
hotfix_typst_title = hotfix['typst-title'],
code_annotations = annotations_enabled,
}

-- Store hotfix state in metadata so the post-quarto typst-title-fix filter
-- can read it (it runs as a separate filter and has no access to CONFIG).
if not meta['_code-window-hotfix'] then
meta['_code-window-hotfix'] = pandoc.MetaMap({})
end
meta['_code-window-hotfix']['typst-title'] = pandoc.MetaString(
CONFIG.enabled and hotfix['typst-title'] and 'true' or 'false'
)

-- Cache syntax highlighting background colour for Typst contrast-aware annotations.
if CURRENT_FORMAT == 'typst' then
local hm = PANDOC_WRITER_OPTIONS and PANDOC_WRITER_OPTIONS.highlight_method
Expand Down
5 changes: 2 additions & 3 deletions docs/examples.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ The option does nothing in HTML, which draws its chrome from the stylesheet and

## The Typst hot-fixes

The three hot-fixes act on Typst output only.
The two hot-fixes act on Typst output only.
Each one is on by default.
A boolean turns one off:

Expand All @@ -238,7 +238,6 @@ extensions:
hotfix:
code-annotations: true
skylighting: false
typst-title: true
```

A map adds a version at which the hot-fix switches itself off:
Expand All @@ -249,7 +248,7 @@ extensions:
hotfix:
skylighting:
enabled: true
quarto-version: "1.9.0"
quarto-version: "1.11.0"
```

The extension compares that string with the running Quarto.
Expand Down
3 changes: 1 addition & 2 deletions docs/reference.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ All of them follow `enabled`, so a document that turns the filter off takes no h
| --- | --- |
| `code-annotations` | Code annotations in Typst output. |
| `skylighting` | Block styling and inline code backgrounds in Typst output. |
| `typst-title` | Theorem title strings, evaluated as markup. |

: The Typst hot-fixes. {.striped .hover tbl-colwidths="[26,74]"}

Expand All @@ -129,7 +128,7 @@ extensions:
hotfix:
skylighting:
enabled: true
quarto-version: "1.9.0"
quarto-version: "1.11.0"
```

They exist for [quarto-dev/quarto-cli#14170](https://github.com/quarto-dev/quarto-cli/issues/14170) and will be removed once Quarto covers the same ground.
Expand Down
6 changes: 2 additions & 4 deletions example.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ extensions:
hotfix:
code-annotations: true
skylighting: true
typst-title: true
```

Each hotfix accepts either a boolean or a map with `enabled` and `quarto-version` keys for per-hotfix version thresholds:
Expand All @@ -284,11 +283,10 @@ Each hotfix accepts either a boolean or a map with `enabled` and `quarto-version
extensions:
code-window:
hotfix:
code-annotations: true
code-annotations:
quarto-version: "1.11.0"
skylighting:
enabled: false
typst-title:
quarto-version: "1.10.0"
```

Override per block with the `code-window-style` attribute:
Expand Down
17 changes: 17 additions & 0 deletions tests/fixtures/theorem-title.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: "Theorem title"
filters:
- code-window
format:
typst:
keep-typ: true
---

A theorem title holds markup and inline code.
Quarto renders the title as Typst content, so no hot-fix is needed.

::: {#thm-markup}
## A title with *emphasis* and `code`

Body.
:::
13 changes: 13 additions & 0 deletions tests/fixtures/title-inline-code.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: "A `code` title"
filters:
- code-window
format:
typst:
keep-typ: true
highlight-style: none
---

The document title holds inline code, and the theme gives no background.
The title is metadata, which the inline code pass leaves alone, so the render
compiles.
Loading
Loading