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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- fix: The HTML dependency folder now uses the extension version, so browsers load the new files after an upgrade. (#88)
- fix: Leave alone the code block that Quarto adds for a chapter's front matter in a book rendered to one file, so no empty `quarto-title-block` window shows at the start of the chapter. (#89)

## 1.8.2 (2026-11-05)

Expand Down
17 changes: 17 additions & 0 deletions _extensions/code-window/code-window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ local function is_unnamed_cell_output(block)
return cell_output.is_marked(block) and str.is_empty(block.attributes['filename'])
end

--- Check whether a block holds a chapter's front matter, which Quarto writes
--- in a book rendered to one file and later replaces with the title block.
--- @param block pandoc.CodeBlock Code block element
--- @return boolean
local function is_quarto_block(block)
return block.classes:includes('quarto-title-block')
end

-- ============================================================================
-- BLOCK-LEVEL STYLE OVERRIDE
-- ============================================================================
Expand Down Expand Up @@ -970,6 +978,10 @@ end
--- that rather than skipping validation for the same kind of block, so the
--- same document reports the same finding in both formats.
function CodeBlock(block)
if is_quarto_block(block) then
return nil
end

-- The Typst path reads the marker in the Pandoc filter, which runs first, so
-- this pass is where it is removed for every format.
local is_plain_output = is_unnamed_cell_output(block)
Expand Down Expand Up @@ -1056,6 +1068,10 @@ end
--- @return boolean consumed_next Whether the next block was consumed
--- @return integer|nil annotation_block_id Block ID if annotations were found (for parent propagation)
local function process_typst_block(block, next_block)
if is_quarto_block(block) then
return { block }, false, nil
end

-- Check this block's own attributes against the CodeBlock group of the
-- schema before anything below reads or rewrites them, in either branch.
local resolved, auto_label = resolve_and_take(block)
Expand Down Expand Up @@ -1383,4 +1399,5 @@ return {
CodeBlock = CodeBlock,
CONFIG = function() return CONFIG end,
draws_chrome = draws_chrome,
is_quarto_block = is_quarto_block,
}
2 changes: 1 addition & 1 deletion _extensions/code-window/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ 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
if not code_window.draws_chrome() or code_window.is_quarto_block(block) then
return nil
end
if not code_window.CONFIG().auto_filename then
Expand Down
16 changes: 16 additions & 0 deletions tests/fixtures/book/_quarto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
project:
type: book

book:
title: "Book title block"
author: "Code Window"
chapters:
- index.qmd
- chapter.qmd

filters:
- code-window

format:
typst:
keep-typ: true
9 changes: 9 additions & 0 deletions tests/fixtures/book/chapter.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "Chapter with front matter"
---

Quarto puts this front matter into a code block of its own, which code-window must leave alone.

```r
x <- 1
```
3 changes: 3 additions & 0 deletions tests/fixtures/book/index.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Preface {.unnumbered}

A chapter with no front matter of its own.
27 changes: 25 additions & 2 deletions tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ report() {
fi
}

# Render a fixture, and stop the run when the render itself fails.
# Render a fixture, and stop the run when the render itself fails. A fixture
# is a file, or a directory that holds a project.
# $1 fixture base name. $2 target format.
render() {
if ! quarto render "${work_dir}/$1.qmd" --to "$2" --quiet >"${work_dir}/$1.log" 2>&1; then
local target="${work_dir}/$1.qmd"
if [ -d "${work_dir}/$1" ]; then
target="${work_dir}/$1"
fi
if ! quarto render "${target}" --to "$2" --quiet >"${work_dir}/$1.log" 2>&1; then
printf 'FAIL %s: the render failed\n' "$1"
tail -n 20 "${work_dir}/$1.log"
exit 1
Expand Down Expand Up @@ -538,6 +543,24 @@ else
"four windows, two of them named bash, in language-not-first.typ"
fi

# ============================================================================
# Quarto's own code blocks are left alone
# ============================================================================

# The front matter of a chapter becomes a quarto-title-block code block.
book_dir="${work_dir}/book"
cp -R "${tests_dir}/fixtures/book" "${book_dir}"
cp -R "${work_dir}/_extensions" "${book_dir}/_extensions"
render book typst
book_typ="${book_dir}/index.typ"
if [ "$(count_typst_windows "${book_typ}")" -eq 1 ] &&
! grep -q 'quarto-title-block' "${book_typ}"; then
report pass "book: the chapter title block gets no window"
else
report fail "book: the chapter title block gets no window" \
"one window, for the r block, and no quarto-title-block in index.typ"
fi

# ============================================================================

printf '\n%s passed, %s failed\n' "${passed}" "${failed}"
Expand Down