Skip to content

typst brand yml: handle font families as possible lists #12542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 15, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ $endif$
$if(mainfont)$
font: ("$mainfont$",),
$elseif(brand.typography.base.family)$
font: ("$brand.typography.base.family$",),
font: $brand.typography.base.family$,
$endif$
$if(fontsize)$
fontsize: $fontsize$,
Expand All @@ -61,7 +61,7 @@ $elseif(brand.typography.base.size)$
$endif$
$if(title)$
$if(brand.typography.headings.family)$
heading-family: ("$brand.typography.headings.family$",),
heading-family: $brand.typography.headings.family$,
$endif$
$if(brand.typography.headings.weight)$
heading-weight: $brand.typography.headings.weight$,
Expand Down
23 changes: 23 additions & 0 deletions src/resources/filters/modules/typst_css.lua
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,28 @@ local function translate_font_weight(w, warnings)
end
end

local function dequote(s)
return s:gsub('^["\']', ''):gsub('["\']$', '')
end

local function quote(s)
return '"' .. s .. '"'
end

local function translate_font_family_list(sl)
if sl == nil then
return '()'
end
local strings = {}
for s in sl:gmatch('([^,]+)') do
s = s:gsub('^%s+', '')
table.insert(strings, quote(dequote(s)))
end
local trailcomma = #strings == 1 and ',' or ''
return '(' .. table.concat(strings, ', ') .. trailcomma .. ')'
end


local function translate_border_style(v, _warnings)
local dash
if v == 'none' then
Expand Down Expand Up @@ -763,6 +785,7 @@ return {
translate_border_style = translate_border_style,
translate_border_color = translate_border_color,
translate_font_weight = translate_font_weight,
translate_font_family_list = translate_font_family_list,
consume_width = consume_width,
consume_style = consume_style,
consume_color = consume_color
Expand Down
11 changes: 6 additions & 5 deletions src/resources/filters/quarto-post/typst-brand-yaml.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function render_typst_brand_yaml()
if headings and next(headings) then
quarto.doc.include_text('in-header', table.concat({
'#show heading: set text(',
conditional_entry('font', headings.family),
conditional_entry('font', headings.family and _quarto.modules.typst.css.translate_font_family_list(headings.family), false),
conditional_entry('weight', _quarto.modules.typst.css.translate_font_weight(headings.weight)),
conditional_entry('style', headings.style),
conditional_entry('fill', headings.color, false),
Expand All @@ -147,7 +147,7 @@ function render_typst_brand_yaml()
if monospaceInline and next(monospaceInline) then
quarto.doc.include_text('in-header', table.concat({
'#show raw.where(block: false): set text(',
conditional_entry('font', monospaceInline.family),
conditional_entry('font', monospaceInline.family and _quarto.modules.typst.css.translate_font_family_list(monospaceInline.family), false),
conditional_entry('weight', _quarto.modules.typst.css.translate_font_weight(monospaceInline.weight)),
conditional_entry('size', monospaceInline.size, false),
conditional_entry('fill', monospaceInline.color, false),
Expand All @@ -166,7 +166,7 @@ function render_typst_brand_yaml()
if monospaceBlock and next(monospaceBlock) then
quarto.doc.include_text('in-header', table.concat({
'#show raw.where(block: true): set text(',
conditional_entry('font', monospaceBlock.family),
conditional_entry('font', monospaceBlock.family and _quarto.modules.typst.css.translate_font_family_list(monospaceBlock.family), false),
conditional_entry('weight', _quarto.modules.typst.css.translate_font_weight(monospaceBlock.weight)),
conditional_entry('size', monospaceBlock.size, false),
conditional_entry('fill', monospaceBlock.color, false),
Expand Down Expand Up @@ -318,7 +318,7 @@ function render_typst_brand_yaml()
local base = _quarto.modules.brand.get_typography(brandMode, 'base')
if base and next(base) then
meta.brand.typography.base = {
family = base.family,
family = base.family and pandoc.RawInline('typst', _quarto.modules.typst.css.translate_font_family_list(base.family)),
size = base.size,
}
end
Expand All @@ -332,8 +332,9 @@ function render_typst_brand_yaml()
color = color and pandoc.RawInline('typst', color)
local weight = _quarto.modules.typst.css.translate_font_weight(headings.weight or base.weight)
weight = weight and pandoc.RawInline('typst', tostring(quote_string(weight)))
local family = headings.family or base.family
meta.brand.typography.headings = {
family = headings.family or base.family,
family = family and pandoc.RawInline('typst', _quarto.modules.typst.css.translate_font_family_list(family)),
weight = weight,
style = headings.style or base.style,
decoration = headings.decoration or base.decoration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ function render_typst_css_property_processing()
end
end

local function dequote(s)
return s:gsub('^["\']', ''):gsub('["\']$', '')
end

local function quote(s)
return '"' .. s .. '"'
end

local function translate_vertical_align(va)
if va == 'top' then
return 'top'
Expand Down Expand Up @@ -270,15 +262,6 @@ function render_typst_css_property_processing()
end
return span
end

local function translate_string_list(sl)
local strings = {}
for s in sl:gmatch('([^,]+)') do
s = s:gsub('^%s+', '')
table.insert(strings, quote(dequote(s)))
end
return '(' .. table.concat(strings, ', ') ..')'
end

return {
Table = function(tab)
Expand All @@ -288,7 +271,7 @@ function render_typst_css_property_processing()
for clause in tabstyle:gmatch('([^;]+)') do
local k, v = to_kv(clause)
if k == 'font-family' then
tab.attributes['typst:text:font'] = translate_string_list(v)
tab.attributes['typst:text:font'] = _quarto.format.typst.css.translate_font_family_list(v)
end
if k == 'font-size' then
tab.attributes['typst:text:size'] = _quarto.format.typst.css.translate_length(v, _warnings)
Expand Down Expand Up @@ -320,7 +303,7 @@ function render_typst_css_property_processing()
for clause in divstyle:gmatch('([^;]+)') do
local k, v = to_kv(clause)
if k == 'font-family' then
div.attributes['typst:text:font'] = translate_string_list(v)
div.attributes['typst:text:font'] = _quarto.format.typst.css.translate_font_family_list(v)
elseif k == 'font-size' then
div.attributes['typst:text:size'] = _quarto.format.typst.css.translate_length(v, _warnings)
elseif k == 'background-color' then
Expand Down
4 changes: 2 additions & 2 deletions src/resources/formats/typst/pandoc/quarto/typst-show.typ
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ $endif$
$if(mainfont)$
font: ("$mainfont$",),
$elseif(brand.typography.base.family)$
font: ("$brand.typography.base.family$",),
font: $brand.typography.base.family$,
$endif$
$if(fontsize)$
fontsize: $fontsize$,
Expand All @@ -47,7 +47,7 @@ $elseif(brand.typography.base.size)$
$endif$
$if(title)$
$if(brand.typography.headings.family)$
heading-family: ("$brand.typography.headings.family$",),
heading-family: $brand.typography.headings.family$,
$endif$
$if(brand.typography.headings.weight)$
heading-weight: $brand.typography.headings.weight$,
Expand Down
53 changes: 53 additions & 0 deletions tests/docs/smoke-all/typst/brand-yaml/typography/font-list.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
format:
typst:
keep-typ: true
brand:
typography:
fonts:
- family: Barrio
source: google
- family: Roboto
source: google
- family: Inconsolata
source: google
base: InvalidFont, Roboto,
headings: Barrio, Times New Roman
monospace: InvalidFont, Inconsolata
_quarto:
tests:
typst:
ensureTypstFileRegexMatches:
-
- 'font: \("InvalidFont", "Roboto"\),'
- '#show raw.where\(block: false\): set text\(font: \("InvalidFont", "Inconsolata"\), \)'
- '#show raw.where\(block: true\): set text\(font: \("InvalidFont", "Inconsolata"\), \)'
- []
ensurePdfRegexMatches:
-
- 'Base is \("invalidfont", "roboto"\)'
- 'Heading is \("barrio", "times new roman"\)'
- []
---

```{=typst}
#set text(fallback: false)
```

## Base font

Base is `#context text.font`{=typst}

{{< lipsum 1 >}}

## Heading is `#context text.font`{=typst}


::: {style="font-family: Barrio"}
{{< lipsum 1 >}}
:::

```js
const fib = num => num < 2 ? num : fib(num-1) + fib(num - 2);
console.log(fib(12))
```
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ _quarto:
- 'heading-style: "normal",$'
- 'heading-color: rgb\("#0b8005"\),$'
- 'heading-line-height: 0\.25em,$'
- '^#show heading: set text\(font: "Montserrat", weight: 800, style: "normal", fill: rgb\("#0b8005"\), \)$'
- '^#show heading: set text\(font: \("Montserrat",\), weight: 800, style: "normal", fill: rgb\("#0b8005"\), \)$'
- '^#show heading: set par\(leading: 0.25em\)$'

- '^#show raw.where\(block: false\): set text\(font: "Inconsolata", weight: 600, size: 0.57\*14pt, fill: rgb\(8, 111, 15\), \)$'
- '^#show raw.where\(block: false\): set text\(font: \("Inconsolata",\), weight: 600, size: 0.57\*14pt, fill: rgb\(8, 111, 15\), \)$'
- '^#show raw.where\(block: false\): content => highlight\(fill: rgb\(255, 250, 224\), content\)$'

- '^#show raw.where\(block: true\): set text\(font: "Inconsolata", size: 18pt, fill: rgb\(245, 255, 250\), \)$'
- '^#show raw.where\(block: true\): set text\(font: \("Inconsolata",\), size: 18pt, fill: rgb\(245, 255, 250\), \)$'
- '^#show raw.where\(block: true\): set block\(fill: rgb\("#77aae1"\)\)$'
- '^#show raw.where\(block: true\): set par\(leading: 1\.25em\)$'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ _quarto:
- 'heading-style: "normal",$'
- 'heading-color: rgb\("#042f02"\),$'
- 'heading-line-height: 0\.25em,$'
- '^#show heading: set text\(font: "Raleway", weight: 500, style: "normal", fill: rgb\("#042f02"\), \)$'
- '^#show heading: set text\(font: \("Raleway",\), weight: 500, style: "normal", fill: rgb\("#042f02"\), \)$'
- '^#show heading: set par\(leading: 0.25em\)$'

- '^#show raw.where\(block: false\): set text\(font: "Space Mono", weight: 400, size: 0.75\*12pt, fill: rgb\(8, 111, 15\), \)$'
- '^#show raw.where\(block: false\): set text\(font: \("Space Mono",\), weight: 400, size: 0.75\*12pt, fill: rgb\(8, 111, 15\), \)$'
- '^#show raw.where\(block: false\): content => highlight\(fill: rgb\(255, 250, 224\), content\)$'

- '^#show raw.where\(block: true\): set text\(font: "Space Mono", weight: 400, size: 0.75\*12pt, fill: rgb\("#eee"\), \)$'
- '^#show raw.where\(block: true\): set text\(font: \("Space Mono",\), weight: 400, size: 0.75\*12pt, fill: rgb\("#eee"\), \)$'
- '^#show raw.where\(block: true\): set block\(fill: rgb\("#0a3c07"\)\)$'

- '^#show link: set text\(weight: 200, fill: maroon, \)$'
Expand Down
Loading