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
13 changes: 9 additions & 4 deletions news/changelog-1.11.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ All changes included in 1.11:

- ([#14982](https://github.com/quarto-dev/quarto-cli/issues/14982)): Fix a footnote in document metadata, such as `title` or `author`, making PDF and Typst output shift heading levels, which turned the first level-1 heading into the document title.

### `revealjs`

- ([#14996](https://github.com/quarto-dev/quarto-cli/pull/14996)): Fix `controls: auto` and `previewLinks: auto` set at the top level of a revealjs document's front matter producing a presentation that fails to load, because `auto` was written unquoted into the generated JavaScript.

### `typst`

- ([#14847](https://github.com/quarto-dev/quarto-cli/pull/14847)): Fix `toc_title` auto-fallback in typst outline template that was ignoring the computed fallback value when `toc_title` is `none`.
Expand All @@ -57,6 +61,10 @@ All changes included in 1.11:

- ([#14974](https://github.com/quarto-dev/quarto-cli/issues/14974)): Fix math in `.llms.md` files from `llms-txt` coming out garbled with the default `mathjax` method, and with `katex` and `webtex`. Math is now written as `$...$` and `$$...$$` with the `mathjax`, `katex`, `webtex` and `mathml` methods.

## Lua API

- ([#14894](https://github.com/quarto-dev/quarto-cli/pull/14894)): Fix `quarto.version` and `quarto.config.version()` crashing filters with `table expected, got string` when the version string contains semver build metadata (such as a distro packager's revision suffix) or otherwise does not start with a digit.

## Commands

### `call`
Expand Down Expand Up @@ -90,12 +98,9 @@ All changes included in 1.11:

- ([#13966](https://github.com/quarto-dev/quarto-cli/issues/13966)): Fix doubled newlines in HTML output of stdout and stderr containing ANSI escape codes.

## Lua API

- ([#14894](https://github.com/quarto-dev/quarto-cli/pull/14894)): Fix `quarto.version` and `quarto.config.version()` crashing filters with `table expected, got string` when the version string contains semver build metadata (such as a distro packager's revision suffix) or otherwise does not start with a digit.

## Other fixes and improvements

- ([#9864](https://github.com/quarto-dev/quarto-cli/issues/9864), [#11139](https://github.com/quarto-dev/quarto-cli/issues/11139)): Fix metadata defined both in a document's front matter and in `_quarto.yml`, a directory `_metadata.yml` or `metadata-files` reaching Pandoc templates and Lua filters with only the document's values. The values are now merged, and the document's values still take precedence for single values. Lists are combined instead of replaced, so a document can no longer drop entries that the project, a directory `_metadata.yml` or `metadata-files` add to a list such as `keywords`. (author: @jkrumbiegel)
- ([#14775](https://github.com/quarto-dev/quarto-cli/issues/14775)): Fix a crash when the `QUARTO_R` environment variable is set to a malformed path. Quarto now warns and falls back to other R lookup methods.
- ([#14865](https://github.com/quarto-dev/quarto-cli/issues/14865)): Fix internal links in a preview being treated as external when the preview is reached through a proxy, such as on Posit Workbench. Links are now classified against the origin the browser sees.
- ([#14878](https://github.com/quarto-dev/quarto-cli/pull/14878)): Add `az` (Azerbaijani) language translation. (author: @abdanar)
23 changes: 21 additions & 2 deletions src/command/render/pandoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1177,12 +1177,31 @@ export async function runPandoc(
if (key === kTheme && isRevealjsOutput(options.format.pandoc)) {
continue;
}
// - controls and previewLinks are replaced for revealjs when not a boolean (e.g. 'auto'), which is not a valid reveal.js value
if (
(key === "controls" || key === "previewLinks") &&
typeof engineMetadata[key] !== "boolean" &&
isRevealjsOutput(options.format.pandoc)
) {
continue;
}
// - categories are handled specifically already for website projects with a metadata override and should not be overridden by user input
if (key === kFieldCategories && projectIsWebsite(options.project)) {
continue;
}
// perform the override
pandocMetadata[key] = engineMetadata[key];
// a key that execution left unchanged keeps what other sources merged
// into it, with the document's own values on top; a key holding inline
// expressions takes the executed value as a whole
if (ld.isEqual(options.unexecutedMetadata?.[key], engineMetadata[key])) {
// wrapped so that arrays and scalars are concatenated or replaced,
// not merged by index
pandocMetadata[key] = mergeConfigs(
{ value: pandocMetadata[key] },
{ value: options.unexecutedMetadata?.[key] },
).value;
} else {
pandocMetadata[key] = engineMetadata[key];
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/command/render/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export async function renderPandoc(
args: recipe.args,
services: context.options.services,
metadata: executeResult.metadata,
unexecutedMetadata: context.target.metadata,
quiet,
flags: context.options.flags,
};
Expand Down
3 changes: 3 additions & 0 deletions src/command/render/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ export interface PandocOptions {
// extra metadata to merge
metadata?: Metadata;

// the input's metadata as written, before execution resolved inline expressions
unexecutedMetadata?: Metadata;

// optional execution engine
executionEngine?: string;

Expand Down
25 changes: 25 additions & 0 deletions tests/docs/metadata-merge-cli/cli-metadata-file.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Front matter and --metadata-file
shared: document-value
custom:
shared: document-value
from-document: document-value
keywords:
- document-keyword
---

::: {#shared}
{{< meta shared >}}
:::

::: {#custom-shared}
{{< meta custom.shared >}}
:::

::: {#custom-from-document}
{{< meta custom.from-document >}}
:::

::: {#custom-from-metadata-file}
{{< meta custom.from-metadata-file >}}
:::
6 changes: 6 additions & 0 deletions tests/docs/metadata-merge-cli/cli-metadata-file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
shared: metadata-file-value
custom:
shared: metadata-file-value
from-metadata-file: metadata-file-value
keywords:
- metadata-file-keyword
2 changes: 2 additions & 0 deletions tests/docs/project/metadata-merge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.quarto/
**/*.quarto_ipynb
22 changes: 22 additions & 0 deletions tests/docs/project/metadata-merge/_quarto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
project:
type: default

format:
html:
template: template.html

keywords:
- project-keyword
- shared-keyword

tags:
- project-tag

params:
from-project: project-value

custom:
from-project: project-value
shared: project-value
list:
- project-item
26 changes: 26 additions & 0 deletions tests/docs/project/metadata-merge/knitr.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Knitr document
keywords:
- document-keyword
- shared-keyword
params:
from-document: document-value
custom:
from-document: document-value
shared: document-value
list:
- document-item
tags:
- '`{r} "project-tag"`'
- document-tag
evaluated: '`{r} paste0("evaluated", "-value")`'
---

```{r}
#| echo: false
invisible(1)
```

::: {#lua-params}
{{< meta params.from-project >}}
:::
17 changes: 17 additions & 0 deletions tests/docs/project/metadata-merge/markdown.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Markdown document
keywords:
- document-keyword
- shared-keyword
params:
from-document: document-value
custom:
from-document: document-value
shared: document-value
list:
- document-item
---

::: {#lua-params}
{{< meta params.from-project >}}
:::
9 changes: 9 additions & 0 deletions tests/docs/project/metadata-merge/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
KEYWORDS: [$for(keywords)$$it$$sep$, $endfor$]
TAGS: [$for(tags)$$it$$sep$, $endfor$]
PARAMS: [$params.from-project$] [$params.from-document$]
FROM-PROJECT: [$custom.from-project$]
SHARED: [$custom.shared$]
FROM-DOCUMENT: [$custom.from-document$]
CUSTOM-LIST: [$for(custom.list)$$it$$sep$, $endfor$]
EVALUATED: [$evaluated$]
$body$
2 changes: 2 additions & 0 deletions tests/docs/smoke-all/metadata-merge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.quarto/
**/*.quarto_ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/.quarto/
_book/

**/*.quarto_ipynb
12 changes: 12 additions & 0 deletions tests/docs/smoke-all/metadata-merge/book-chapter-title/_quarto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
project:
type: book

book:
title: "Metadata merge book"
chapters:
- index.qmd
- chapter.qmd

format:
html:
number-sections: true
14 changes: 14 additions & 0 deletions tests/docs/smoke-all/metadata-merge/book-chapter-title/chapter.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: Chapter from YAML
_quarto:
tests:
html:
ensureHtmlElements:
- ['h1.title span.chapter-number']
- []
ensureHtmlElementContents:
selectors: ['h1.title']
matches: ['^\s*1\s+Chapter from YAML\s*$']
---

A book chapter whose title comes from the YAML `title` key keeps the chapter number Quarto computes for it. The document's own `title` value must not replace the numbered title.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Preface {.unnumbered}

Home page of the fixture. The assertions live in `chapter.qmd`.
18 changes: 18 additions & 0 deletions tests/docs/smoke-all/metadata-merge/format-key-precedence.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Top-level title
subtitle: Top-level subtitle
format:
html:
title: Format title
subtitle: Format subtitle
_quarto:
tests:
html:
ensureFileRegexMatches:
-
- '<h1 class="title">Format title</h1>'
- '<p class="subtitle lead">Format subtitle</p>'
- []
---

A key set both at the top level and under `format: html:` in the same document takes the format-level value in the output. The document is not executed (markdown engine), so this checks the merge order of document metadata on its own: the executed-front-matter substitution done before calling pandoc must not bring the top-level value back.
26 changes: 26 additions & 0 deletions tests/docs/smoke-all/metadata-merge/knitr-inline-yaml.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: "Title `r 1 + 1`"
custom-key: "Custom `{r} 2 + 3`"
nested:
inner: "Nested `r 3 * 3`"
engine: knitr
_quarto:
tests:
html:
ensureFileRegexMatches:
-
- '<h1 class="title">Title 2</h1>'
- '<div id="custom-key">\s*<p>Custom 5</p>'
- '<div id="nested-inner">\s*<p>Nested 9</p>'
- []
---

Inline R expressions in YAML front matter are evaluated by knitr, and the evaluated values must reach pandoc: the standard `title`, a custom top-level key, and a nested key with no project-level counterpart.

::: {#custom-key}
{{< meta custom-key >}}
:::

::: {#nested-inner}
{{< meta nested.inner >}}
:::
6 changes: 6 additions & 0 deletions tests/docs/smoke-all/metadata-merge/metadata-files-extra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
shared: metadata-file-value
custom:
shared: metadata-file-value
from-metadata-file: metadata-file-value
keywords:
- metadata-file-keyword
40 changes: 40 additions & 0 deletions tests/docs/smoke-all/metadata-merge/metadata-files.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: Front matter and metadata-files
metadata-files:
- metadata-files-extra.yml
shared: document-value
custom:
shared: document-value
from-document: document-value
keywords:
- document-keyword
_quarto:
tests:
html:
ensureFileRegexMatches:
-
- '<meta name="keywords" content="document-keyword, metadata-file-keyword">'
- '<div id="shared">\s*<p>document-value</p>'
- '<div id="custom-shared">\s*<p>document-value</p>'
- '<div id="custom-from-document">\s*<p>document-value</p>'
- '<div id="custom-from-metadata-file">\s*<p>metadata-file-value</p>'
- []
---

The document's front matter wins over its `metadata-files` for a value both define, and what only the metadata file defines is kept, including entries of a list and keys of a mapping the front matter also defines.

::: {#shared}
{{< meta shared >}}
:::

::: {#custom-shared}
{{< meta custom.shared >}}
:::

::: {#custom-from-document}
{{< meta custom.from-document >}}
:::

::: {#custom-from-metadata-file}
{{< meta custom.from-metadata-file >}}
:::
22 changes: 22 additions & 0 deletions tests/docs/smoke-all/metadata-merge/revealjs-controls-auto.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Controls and preview links set to auto
format: revealjs
controls: auto
previewLinks: auto
_quarto:
tests:
revealjs:
ensureFileRegexMatches:
-
- 'controls: false,'
- "'controlsAuto': true,"
- 'previewLinks: false,'
- "'previewLinksAuto': true,"
-
- 'controls: auto,'
- 'previewLinks: auto,'
---

## Slide

`auto` is not a valid reveal.js value: Quarto passes `false` to reveal.js and enables its own automatic behavior instead.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
controls: true
previewLinks: true
22 changes: 22 additions & 0 deletions tests/docs/smoke-all/metadata-merge/revealjs-controls-boolean.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Controls and preview links set in front matter and metadata-files
format: revealjs
metadata-files:
- revealjs-controls-boolean-extra.yml
controls: false
previewLinks: false
_quarto:
tests:
revealjs:
ensureFileRegexMatches:
-
- 'controls: false,'
- 'previewLinks: false,'
-
- 'controls: true,'
- 'previewLinks: true,'
---

## Slide

A boolean `controls` or `previewLinks` in the front matter wins over its `metadata-files`, like any other key.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/.quarto/
_site/

**/*.quarto_ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
project:
type: website

website:
title: "metadata-merge categories"

categories:
- from-project
Loading
Loading