Skip to content

Commit 13e395c

Browse files
authored
Merge pull request #13777 from quarto-dev/fix/issue-13775
2 parents d433605 + 6043f1f commit 13e395c

File tree

10 files changed

+355
-41
lines changed

10 files changed

+355
-41
lines changed

news/changelog-1.9.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ All changes included in 1.9:
3939
- ([#13555](https://github.com/quarto-dev/quarto-cli/issues/13555)): Add support for `icon=false` in callouts when used in `format: typst`.
4040
- ([#13589](https://github.com/quarto-dev/quarto-cli/issues/13589)): Fix callouts with invalid ID prefixes crashing with "attempt to index a nil value". Callouts with unknown reference types now render as non-crossreferenceable callouts with a warning, ignoring the invalid ID.
4141
- ([#13602](https://github.com/quarto-dev/quarto-cli/issues/13602)): Fix support for multiple files set in `bibliography` field in `biblio.typ` template partial.
42+
- ([#13775](https://github.com/quarto-dev/quarto-cli/issues/13775)): Fix brand fonts not being applied when using `citeproc: true` with Typst format. Format detection now properly handles Pandoc format variants like `typst-citations`.
4243

4344
### `pdf`
4445

src/command/render/output-tex.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import { writeFileToStdout } from "../../core/console.ts";
1111
import { dirAndStem, expandPath } from "../../core/path.ts";
1212
import { texSafeFilename } from "../../core/tex.ts";
1313

14-
import { kKeepTex, kOutputExt, kOutputFile } from "../../config/constants.ts";
14+
import {
15+
kKeepTex,
16+
kOutputExt,
17+
kOutputFile,
18+
kTargetFormat,
19+
} from "../../config/constants.ts";
1520
import { Format } from "../../config/types.ts";
1621

1722
import { PandocOptions, RenderFlags, RenderOptions } from "./types.ts";
@@ -49,8 +54,8 @@ export function texToPdfOutputRecipe(
4954
// include variants in the tex stem if they are present to avoid
5055
// overwriting files
5156
let fixupInputName = "";
52-
if (format.identifier["target-format"]) {
53-
const formatDesc = parseFormatString(format.identifier["target-format"]);
57+
if (format.identifier[kTargetFormat]) {
58+
const formatDesc = parseFormatString(format.identifier[kTargetFormat]);
5459
fixupInputName = `${formatDesc.variants.join("")}${
5560
formatDesc.modifiers.join("")
5661
}`;

src/config/format.ts

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,51 +10,42 @@ import { Format, FormatPandoc } from "./types.ts";
1010
export function isPdfOutput(format: string): boolean;
1111
export function isPdfOutput(format: FormatPandoc): boolean;
1212
export function isPdfOutput(format: string | FormatPandoc): boolean {
13-
if (typeof (format) !== "string") {
14-
format = format?.to || "html";
15-
}
16-
return format === "pdf" || format === "beamer";
13+
return isFormatTo(format, "pdf") || isFormatTo(format, "beamer");
1714
}
1815

1916
export function isLatexOutput(format: FormatPandoc) {
20-
return ["pdf", "latex", "beamer"].includes(format.to || "");
17+
return ["pdf", "latex", "beamer"].some((fmt) => isFormatTo(format, fmt));
2118
}
2219

2320
export function isTypstOutput(format: string): boolean;
2421
export function isTypstOutput(format: FormatPandoc): boolean;
2522
export function isTypstOutput(format: string | FormatPandoc) {
26-
if (typeof (format) !== "string") {
27-
format = format?.to || "html";
28-
}
29-
return format === "typst";
23+
return isFormatTo(format, "typst");
3024
}
3125

3226
export function isBeamerOutput(format: FormatPandoc) {
33-
return ["beamer"].includes(format.to || "");
27+
return isFormatTo(format, "beamer");
3428
}
3529

3630
export function isEpubOutput(format: string): boolean;
3731
export function isEpubOutput(format: FormatPandoc): boolean;
3832
export function isEpubOutput(format: string | FormatPandoc): boolean {
39-
if (typeof (format) !== "string") {
33+
if (typeof format !== "string") {
4034
format = format?.to || "html";
4135
}
42-
return ["epub", "epub2", "epub3"].includes(format || "");
36+
return ["epub", "epub2", "epub3"].some((fmt) => isFormatTo(format, fmt));
4337
}
4438

4539
export function isDocxOutput(format: string): boolean;
4640
export function isDocxOutput(format: FormatPandoc): boolean;
4741
export function isDocxOutput(format: string | FormatPandoc): boolean {
48-
if (typeof (format) !== "string") {
49-
format = format?.to || "html";
50-
}
51-
return format === "docx";
42+
return isFormatTo(format, "docx");
5243
}
5344

5445
export function isHtmlFileOutput(format: string): boolean;
5546
export function isHtmlFileOutput(format: FormatPandoc): boolean;
5647
export function isHtmlFileOutput(format?: string | FormatPandoc): boolean {
57-
if (typeof (format) !== "string") {
48+
if (typeof format !== "string") {
5849
format = format?.to || "html";
5950
}
6051
return isHtmlDocOutput(format) || isHtmlSlideOutput(format);
@@ -66,7 +57,7 @@ export function isHtmlOutput(
6657
format?: string | FormatPandoc,
6758
strict?: boolean,
6859
): boolean {
69-
if (typeof (format) !== "string") {
60+
if (typeof format !== "string") {
7061
format = format?.to;
7162
}
7263
format = format || "html";
@@ -81,36 +72,26 @@ export function isHtmlOutput(
8172
}
8273
}
8374

84-
export function isHtmlDocOutput(format?: string | FormatPandoc) {
85-
if (typeof (format) !== "string") {
86-
format = format?.to || "html";
87-
}
88-
return [
89-
"html",
90-
"html4",
91-
"html5",
92-
].includes(format);
75+
export function isHtmlDocOutput(format: string | FormatPandoc) {
76+
return ["html", "html4", "html5"].some((fmt) => isFormatTo(format, fmt));
9377
}
9478

95-
export function isHtmlSlideOutput(format?: string | FormatPandoc) {
96-
if (typeof (format) !== "string") {
97-
format = format?.to || "html";
98-
}
79+
export function isHtmlSlideOutput(format: string | FormatPandoc) {
9980
return [
10081
"s5",
10182
"dzslides",
10283
"slidy",
10384
"slideous",
10485
"revealjs",
105-
].includes(format);
86+
].some((fmt) => isFormatTo(format, fmt));
10687
}
10788

10889
export function isHtmlDashboardOutput(format?: string) {
10990
return format === "dashboard" || format?.endsWith("-dashboard");
11091
}
11192

11293
export function isJatsOutput(format?: string | FormatPandoc) {
113-
if (typeof (format) !== "string") {
94+
if (typeof format !== "string") {
11495
format = format?.to || "html";
11596
}
11697

@@ -136,7 +117,7 @@ export function isPresentationOutput(format: FormatPandoc) {
136117
export function isRevealjsOutput(format: string): boolean;
137118
export function isRevealjsOutput(format: FormatPandoc): boolean;
138119
export function isRevealjsOutput(format?: string | FormatPandoc) {
139-
if (typeof (format) !== "string") {
120+
if (typeof format !== "string") {
140121
format = format?.to;
141122
}
142123
format = format || "html";
@@ -159,8 +140,11 @@ export function isIpynbOutput(format: FormatPandoc) {
159140
return isFormatTo(format, "ipynb");
160141
}
161142

162-
function isFormatTo(format: FormatPandoc, to: string) {
163-
return !!format.to && format.to.startsWith(to);
143+
function isFormatTo(format: string | FormatPandoc, to: string) {
144+
const formatStr = typeof format === "string"
145+
? format
146+
: (format?.to || "html");
147+
return formatStr.startsWith(to);
164148
}
165149

166150
export function isMarkdownOutput(
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.quarto/
2+
*_files/
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: "Test"
3+
format:
4+
beamer:
5+
variant: -smart
6+
# this is is needed to not triggered pdf recipe
7+
output-ext: tex
8+
beamer+without:
9+
# this is is needed to not triggered pdf recipe
10+
output-ext: tex
11+
beamer-smart:
12+
# this is is needed to not triggered pdf recipe
13+
output-ext: tex
14+
_quarto:
15+
tests:
16+
beamer:
17+
ensureFileRegexMatches:
18+
- []
19+
-
20+
# beamer should be detected and not trigger colorlinks by default
21+
- 'linkcolor=\{blue\}'
22+
- "``marks''"
23+
- "`here'"
24+
printsMessage:
25+
level: INFO
26+
regex: "to: beamer-smart\n"
27+
beamer-smart:
28+
ensureFileRegexMatches:
29+
- []
30+
-
31+
# beamer should be detected and not trigger colorlinks by default
32+
- 'linkcolor=\{blue\}'
33+
# setting extensions to format works
34+
- "``marks''"
35+
- "`here'"
36+
printsMessage:
37+
level: INFO
38+
regex: "to: beamer-smart\n"
39+
beamer+without:
40+
ensureFileRegexMatches:
41+
-
42+
- "``marks''"
43+
- "`here'"
44+
-
45+
- 'linkcolor=\{blue\}'
46+
printsMessage:
47+
level: INFO
48+
regex: "to: beamer\n"
49+
---
50+
51+
## Quarto
52+
53+
54+
Test the quotation "marks" here and 'here'.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
title: brand font not handled
3+
format: typst
4+
brand:
5+
typography:
6+
fonts:
7+
- family: Sarabun
8+
source: google
9+
base:
10+
family: Sarabun
11+
size: 12pt
12+
citeproc: true
13+
_quarto:
14+
tests:
15+
typst:
16+
printsMessage:
17+
level: INFO
18+
regex: 'warning: unknown font family: sarabun'
19+
negate: true
20+
---
21+
22+
Content using Sarabun font.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: "Test variants are detected for HTML specific feature"
3+
format:
4+
html:
5+
variant: +literate_haskell
6+
html+without:
7+
output-file: without
8+
html+literate_haskell:
9+
output-file: with_ext
10+
reference-location: margin
11+
_quarto:
12+
tests:
13+
html:
14+
ensureHtmlElements:
15+
-
16+
- 'div.column-margin div#fn1' # this prove `isHtmlDocOutput()` is working
17+
- []
18+
printsMessage:
19+
level: INFO
20+
regex: "to: html\\+literate\\_haskell\n"
21+
html+literate_haskell:
22+
ensureHtmlElements:
23+
-
24+
- 'div.column-margin div#fn1' # this prove `isHtmlDocOutput()` is working
25+
- []
26+
printsMessage:
27+
level: INFO
28+
regex: "to: html\\+literate\\_haskell\n"
29+
html+without:
30+
ensureHtmlElements:
31+
-
32+
- 'div.column-margin div#fn1' # this prove `isHtmlDocOutput()` is working
33+
- 'pre.sourceCode.haskell'
34+
- ['pre.sourceCode.literatehaskell']
35+
printsMessage:
36+
level: INFO
37+
regex: "to: html\n"
38+
---
39+
40+
This documents tests that `isHtmlDocOutput()` is correctly detecting HTML even if there is a variant by checking some basic article layout feature are correctly working.
41+
42+
## Ref in margin should work
43+
44+
This is a reference[^1]
45+
46+
[^1]: This is the footnote text.
47+
48+
## see if extension is working (literate_haskell)
49+
50+
This is just to see if setting variants works correctly in Quarto
51+
52+
````{.haskell .literate}
53+
unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d
54+
unsplit = arr . uncurry
55+
-- arr (\op (x,y) -> x `op` y)
56+
````
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
title: "Test"
3+
format:
4+
latex:
5+
variant: -smart
6+
latex+without: default
7+
latex-smart: default
8+
_quarto:
9+
tests:
10+
latex:
11+
ensureFileRegexMatches:
12+
-
13+
- 'linkcolor=\{blue\}'
14+
-
15+
# setting extensions to format works
16+
- "``marks''"
17+
- "`here'"
18+
printsMessage:
19+
level: INFO
20+
regex: "to: latex-smart\n"
21+
latex-smart:
22+
ensureFileRegexMatches:
23+
-
24+
- 'linkcolor=\{blue\}'
25+
-
26+
# setting extensions to format works
27+
- "``marks''"
28+
- "`here'"
29+
printsMessage:
30+
level: INFO
31+
regex: "to: latex-smart\n"
32+
latex+without:
33+
ensureFileRegexMatches:
34+
-
35+
- 'linkcolor=\{blue\}'
36+
- "``marks''"
37+
- "`here'"
38+
- []
39+
printsMessage:
40+
level: INFO
41+
regex: "to: latex\n"
42+
---
43+
44+
## Quarto
45+
46+
47+
Test the quotation "marks" here and 'here'.

0 commit comments

Comments
 (0)