Skip to content
Draft
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
30 changes: 30 additions & 0 deletions .claude/rules/extension-subtrees.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
paths:
- src/resources/extension-subtrees/**
---

# Extension Subtrees

Files under `src/resources/extension-subtrees/<name>/` are git subtrees from external repos. **Do NOT edit directly here.**

Current subtrees (see [`src/command/dev-call/pull-git-subtree/cmd.ts`](../../src/command/dev-call/pull-git-subtree/cmd.ts) for the source of truth):

| Name | Upstream repo |
|---|---|
| `julia-engine` | `PumasAI/quarto-julia-engine` |
| `orange-book` | `quarto-ext/orange-book` |

## Workflow

1. Open a PR with the fix in the upstream repo
2. Wait for upstream merge
3. From quarto-cli, run:
```bash
quarto dev-call pull-git-subtree <name>
```
4. The command adds two commits (squash + merge) — **do not edit those commits**
5. **Do not rebase** a branch that contains the subtree-pull commits — they cannot be rebased cleanly. Merge to `main` without rebasing, or remove the two commits before rebasing and re-run the pull command.

## Reference

Full workflow: [`dev-docs/subtree-extensions.md`](../../dev-docs/subtree-extensions.md)
50 changes: 49 additions & 1 deletion dev-docs/subtree-extensions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Subtree extensions

Subtree extensions live in `src/resources/subtree-extensions`.
Subtree extensions live in `src/resources/extension-subtrees`.

Each is the complete git repository of a Quarto extension, e.g. the directory tree for the Julia engine looks like

Expand All @@ -14,6 +14,20 @@ src/resources/extension-subtrees/
...
```

The list of subtrees and their upstream repos lives in the `SUBTREES` table in [`src/command/dev-call/pull-git-subtree/cmd.ts`](../src/command/dev-call/pull-git-subtree/cmd.ts).

## Updating an extension

Fixes to extension files **must be authored upstream**, never edited directly inside `src/resources/extension-subtrees/<name>/`. The correct workflow:

1. Open a PR with the fix in the upstream repo (e.g. `quarto-ext/orange-book`, `PumasAI/quarto-julia-engine`)
2. Merge the PR upstream
3. From quarto-cli, run the pull command (see [Pulling subtree updates](#pulling-subtree-updates))

Editing directly inside the subtree prefix is wrong: the change will be overwritten the next time the subtree is pulled, and anyone who forked the upstream extension will not benefit from it.

## Pulling subtree updates

The command to add or update a subtree is

```
Expand All @@ -39,3 +53,37 @@ So you must either

- run the command when ready to merge to main, or
- remove the commits when rebasing, and run the `dev-call` command again

## Recovery: edits made in-tree by mistake

If a fix has already been committed directly inside the subtree prefix (wrong workflow), it needs to be re-authored upstream before resuming the normal flow. Two paths:

### Option A — re-author upstream manually (recommended)

Faster and more predictable, especially in repos with many commits where `git subtree split` walks the full history.

1. Clone the upstream repo locally (e.g. `git clone https://github.com/quarto-ext/orange-book.git`)
2. Create a feature branch from upstream `main`
3. Apply the same change at the upstream repo's path (the subtree's `_extensions/...` becomes the repo root)
4. Commit (preserve original author and message) and push to the upstream repo
5. Open a PR upstream and merge

### Option B — `git subtree push`

Extracts the prefix-scoped history into a synthetic branch and pushes it. Works but is slow on large repos (the split walks every commit) and untested in this codebase.

```
git fetch <upstream-url> <upstream-branch>
git subtree push --prefix=src/resources/extension-subtrees/<name> \
<upstream-url> <feature-branch>
```

Then open a PR upstream from `<feature-branch>`.

### After the upstream PR merges

Back in quarto-cli, on the branch holding the original in-tree commit:

1. Remove the in-tree edit from the local commit (amend or rebase out the lines under the subtree prefix) so `pull-git-subtree` does not conflict with itself
2. Run `quarto dev-call pull-git-subtree <name>` to bring the upstream change in via the normal two-commit pattern
3. Merge the branch to `main` without rebasing (the subtree-pull commits cannot be rebased — see [Pulling subtree updates](#pulling-subtree-updates))
222 changes: 222 additions & 0 deletions llm-docs/localization-architecture.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions news/changelog-1.10.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ All changes included in 1.10:
- ([#14261](https://github.com/quarto-dev/quarto-cli/issues/14261)): Fix theorem/example block titles containing inline code producing invalid Typst markup when syntax highlighting is applied.
- ([#14460](https://github.com/quarto-dev/quarto-cli/issues/14460)): Fix CSS `border` and `border-color` declarations losing tokens that precede an `rgb()`/`rgba()` color (e.g. `border: 0px solid rgb(255, 0, 0)` rendering as a 2.25pt border instead of being suppressed). Also fixes: `var(--brand-NAME)` references crashing the Typst CSS translator when `NAME` contained digits (e.g. `--brand-red-50`); a crash when an `rgba()` alpha is unparseable; the `dvmin` length unit being silently rejected (a stray space in the unit table); CSS keywords like `BOLD` not matching as `bold` (CSS keywords are case-insensitive); invalid hex colors like `#fffff` being silently accepted as 2-component colors.
- ([#14511](https://github.com/quarto-dev/quarto-cli/issues/14511)): Fix brand fonts downloaded for a Typst book project not being passed to `typst compile`, causing `unknown font family` warnings and fallback to Libertinus Serif.
- ([#14524](https://github.com/quarto-dev/quarto-cli/issues/14524), [quarto-ext/orange-book#3](https://github.com/quarto-ext/orange-book/pull/3)): Fix orange-book Typst book running header not honoring `lang:` — chapter heading band stayed `Chapter N.` instead of the locale's word (e.g. `Chapitre N.` for `lang: fr`). Also fixes the orange-book `list-of-figure-title` / `list-of-table-title` template pipes which were silently rendering as empty strings.

### `revealjs`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ $endif$
$if(lot)$
list-of-table-title: "$if(crossref.lot-title)$$crossref.lot-title$$else$$crossref-lot-title$$endif$",
$endif$
$if(crossref-ch-prefix)$
supplement-chapter: "$crossref-ch-prefix$",
$endif$
$if(margin-geometry)$
padded-heading-number: false,
$endif$
Expand Down
15 changes: 14 additions & 1 deletion src/resources/filters/common/meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,20 @@ function metaInjectHtml(meta, func)
end


function readMetaOptions(meta)
-- Copy a filter param into Pandoc metadata so it resolves as a $key$
-- variable in Pandoc templates. Skips when the user already set the key
-- (explicit metadata wins). See llm-docs/localization-architecture.md for
-- the broader pattern.
function surfaceParamToMeta(meta, key)
if meta[key] == nil then
local value = param(key, nil)
if value ~= nil then
meta[key] = value
end
end
end

function readMetaOptions(meta)
local options = {}
for key,value in pairs(meta) do
if type(value) == "table" and value.clone ~= nil then
Expand Down
12 changes: 12 additions & 0 deletions src/resources/filters/crossref/meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@
function crossrefMetaInject()
return {
Meta = function(meta)
-- surface localized crossref strings as Pandoc template variables
-- (consumed by Pandoc templates like orange-book typst-show.typ via
-- $crossref-ch-prefix$, $crossref-lof-title$, $crossref-lot-title$).
-- Filter params are Lua-only; templates need values in meta.
for _, key in ipairs({
"crossref-ch-prefix",
"crossref-lof-title",
"crossref-lot-title",
}) do
surfaceParamToMeta(meta, key)
end

local function as_latex(inlines)
return trim(pandoc.write(pandoc.Pandoc(quarto.utils.as_blocks(inlines)), "latex"))
end
Expand Down
5 changes: 5 additions & 0 deletions tests/docs/smoke-all/typst/orange-book-lang/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/.quarto/
/_book/
/index.typ
**/*.quarto_ipynb
*_files/
17 changes: 17 additions & 0 deletions tests/docs/smoke-all/typst/orange-book-lang/_quarto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
project:
type: book

book:
title: "Livre Test"
author: "Auteur Test"
chapters:
- index.qmd
- chapter1.qmd

lang: fr

format:
typst:
keep-typ: true
lof: true
lot: true
3 changes: 3 additions & 0 deletions tests/docs/smoke-all/typst/orange-book-lang/chapter1.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Premier chapitre

Voici le premier chapitre de ce livre de test.
16 changes: 16 additions & 0 deletions tests/docs/smoke-all/typst/orange-book-lang/index.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
keep-typ: true
_quarto:
render-project: true
tests:
typst:
ensureTypstFileRegexMatches:
-
- 'supplement-chapter: "Chapitre"'
- 'list-of-figure-title: "Liste des Figures"'
- 'list-of-table-title: "Liste des Tables"'
---

# Préface {.unnumbered}

Préface du livre de test.
Loading