Skip to content

Commit e54bb27

Browse files
padding shorthand for typst logo
and individual control of each side's padding
1 parent a25bd71 commit e54bb27

File tree

11 files changed

+154
-51
lines changed

11 files changed

+154
-51
lines changed

src/resources/filters/modules/typst.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,26 @@ local function _main()
7575
return result
7676
end
7777
end
78+
79+
local function as_typst_dictionary(tab)
80+
local entries = {}
81+
for k, v in _quarto.utils.table.sortedPairs(tab) do
82+
if type(v) == 'table' then
83+
v = as_typst_dictionary(v)
84+
end
85+
if k and v then
86+
table.insert(entries, k .. ': ' .. v)
87+
end
88+
end
89+
if #entries == 0 then return nil end
90+
return '(' .. table.concat(entries, ', ') .. ')'
91+
end
7892

7993
return {
8094
function_call = typst_function_call,
95+
sortedPairs = sortedPairs,
8196
as_typst_content = as_typst_content,
97+
as_typst_dictionary = as_typst_dictionary,
8298
css = require("modules/typst_css")
8399
}
84100
end

src/resources/filters/modules/typst_css.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ local typst_named_colors = {
175175
green = '#2ecc40',
176176
lime = '#01ff70',
177177
}
178+
178179
-- css can have fraction or percent
179180
-- typst can have int or percent
180181
-- what goes for opacity also goes for alpha

src/resources/filters/quarto-post/typst-brand-yaml.lua

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,12 @@ function render_typst_brand_yaml()
33
return {}
44
end
55

6-
local function sortedPairs(t, f)
7-
local a = {}
8-
for n in pairs(t) do table.insert(a, n) end
9-
table.sort(a, f)
10-
local i = 0 -- iterator variable
11-
local iter = function() -- iterator function
12-
i = i + 1
13-
if a[i] == nil then return nil
14-
else return a[i], t[a[i]]
15-
end
16-
end
17-
return iter
18-
end
19-
206
local function to_typst_dict_indent(tab, curr, indent)
217
curr = curr or ''
228
indent = indent or ' '
239
local entries = {}
2410
local inside = curr .. indent
25-
for k, v in sortedPairs(tab) do
11+
for k, v in _quarto.utils.table.sortedPairs(tab) do
2612
if type(v) == 'table' then
2713
v = to_typst_dict_indent(v, inside, indent)
2814
end
@@ -243,16 +229,63 @@ function render_typst_brand_yaml()
243229
logoOptions.path = foundLogo.dark.path
244230
logoOptions.alt = foundLogo.dark.alt
245231
end
246-
-- todo: path relative to brand.yaml
247-
logoOptions.padding = _quarto.modules.typst.css.translate_length(logoOptions.padding or '0.5in')
232+
233+
local pads = {}
234+
for k, v in _quarto.utils.table.sortedPairs(logoOptions) do
235+
if k == 'padding' then
236+
quarto.log.output('foo', k)
237+
local widths = {}
238+
_quarto.modules.typst.css.parse_multiple(v, 5, function(s, start)
239+
local width, newstart = _quarto.modules.typst.css.consume_width(s, start)
240+
table.insert(widths, width)
241+
return newstart
242+
end)
243+
local sides = _quarto.modules.typst.css.expand_side_shorthand(
244+
widths,
245+
'widths in padding list: ' .. v)
246+
pads.top = sides.top
247+
pads.right = sides.right
248+
pads.bottom = sides.bottom
249+
pads.left = sides.left
250+
elseif k:find '^padding-' then
251+
quarto.log.output('foo', k)
252+
local _, ndash = k:gsub('-', '')
253+
if ndash == 1 then
254+
local side = k:match('^padding--(%a+)')
255+
local padding_sides = {'left', 'top', 'right', 'bottom'}
256+
if tcontains(padding_sides, side) then
257+
pads[side] = _quarto.modules.typst.css.translate_length(v)
258+
else
259+
quarto.log.warning('invalid padding key ' .. k)
260+
end
261+
else
262+
quarto.log.warning('invalid padding key ' .. k)
263+
end
264+
end
265+
end
266+
local inset = nil
267+
if next(pads) then
268+
if pads.top == pads.right and
269+
pads.right == pads.bottom and
270+
pads.bottom == pads.left
271+
then
272+
inset = pads.top
273+
elseif pads.top == pads.bottom and pads.left == pads.right then
274+
inset = _quarto.modules.typst.as_typst_dictionary({x = pads.left, y = pads.top})
275+
else
276+
inset = _quarto.modules.typst.as_typst_dictionary(pads)
277+
end
278+
else
279+
inset = '0.5in'
280+
end
248281
logoOptions.width = _quarto.modules.typst.css.translate_length(logoOptions.width or '2in')
249282
logoOptions.location = logoOptions.location and
250283
location_to_typst_align(logoOptions.location) or 'left+top'
251284
quarto.log.debug('logo options', logoOptions)
252285
local altProp = logoOptions.alt and (', alt: "' .. logoOptions.alt .. '"') or ''
253286
local dblbackslash = string.gsub(logoOptions.path, '\\', '\\\\') -- double backslash?
254287
quarto.doc.include_text('in-header',
255-
'#set page(background: align(' .. logoOptions.location .. ', box(inset: ' .. logoOptions.padding .. ', image("' .. dblbackslash .. '", width: ' .. logoOptions.width .. altProp .. '))))')
288+
'#set page(background: align(' .. logoOptions.location .. ', box(inset: ' .. inset .. ', image("' .. dblbackslash .. '", width: ' .. logoOptions.width .. altProp .. '))))')
256289
end
257290
end
258291
end,

src/resources/filters/quarto-post/typst-css-property-processing.lua

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,6 @@ function render_typst_css_property_processing()
3232
end
3333
end
3434

35-
local function sortedPairs(t, f)
36-
local a = {}
37-
for n in pairs(t) do table.insert(a, n) end
38-
table.sort(a, f)
39-
local i = 0 -- iterator variable
40-
local iter = function() -- iterator function
41-
i = i + 1
42-
if a[i] == nil then return nil
43-
else return a[i], t[a[i]]
44-
end
45-
end
46-
return iter
47-
end
48-
4935
local function dequote(s)
5036
return s:gsub('^["\']', ''):gsub('["\']$', '')
5137
end
@@ -84,20 +70,6 @@ function render_typst_css_property_processing()
8470
return nil
8571
end
8672

87-
local function to_typst_dict(tab)
88-
local entries = {}
89-
for k, v in sortedPairs(tab) do
90-
if type(v) == 'table' then
91-
v = to_typst_dict(v)
92-
end
93-
if k and v then
94-
table.insert(entries, k .. ': ' .. v)
95-
end
96-
end
97-
if #entries == 0 then return nil end
98-
return '(' .. table.concat(entries, ', ') .. ')'
99-
end
100-
10173
local border_sides = {'left', 'top', 'right', 'bottom'}
10274
local border_properties = {'width', 'style', 'color'}
10375
local function all_equal(seq)
@@ -228,7 +200,7 @@ function render_typst_css_property_processing()
228200
-- inset seems either buggy or hard to get right, see
229201
-- https://github.com/quarto-dev/quarto-cli/pull/9387#issuecomment-2076015962
230202
-- if next(paddings) ~= nil then
231-
-- cell.attributes['typst:inset'] = to_typst_dict(paddings)
203+
-- cell.attributes['typst:inset'] = _quarto.modules.typst.as_typst_dictionary(paddings)
232204
-- end
233205

234206
-- since e.g. the left side of one cell can override the right side of another
@@ -259,9 +231,9 @@ function render_typst_css_property_processing()
259231
quarto.log.debug('paints', table.unpack(paints))
260232
if all_equal(thicknesses) and all_equal(dashes) and all_equal(paints) then
261233
assert(borders.left)
262-
cell.attributes['typst:stroke'] = to_typst_dict(borders.left)
234+
cell.attributes['typst:stroke'] = _quarto.modules.typst.as_typst_dictionary(borders.left)
263235
else
264-
cell.attributes['typst:stroke'] = to_typst_dict(borders)
236+
cell.attributes['typst:stroke'] = _quarto.modules.typst.as_typst_dictionary(borders)
265237
end
266238
end
267239
end
@@ -291,7 +263,7 @@ function render_typst_css_property_processing()
291263
hlprops.fill = 'rgb(0,0,0,0)'
292264
end
293265
return pandoc.Inlines({
294-
pandoc.RawInline('typst', '#highlight' .. to_typst_dict(hlprops) .. '['),
266+
pandoc.RawInline('typst', '#highlight' .. _quarto.modules.typst.as_typst_dictionary(hlprops) .. '['),
295267
span,
296268
pandoc.RawInline('typst', ']')
297269
})

src/resources/pandoc/datadir/_utils.lua

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,22 @@ local function tcontains(t, value)
235235
return false
236236
end
237237

238+
239+
local function sortedPairs(t, f)
240+
local a = {}
241+
for n in pairs(t) do table.insert(a, n) end
242+
table.sort(a, f)
243+
local i = 0 -- iterator variable
244+
local iter = function() -- iterator function
245+
i = i + 1
246+
if a[i] == nil then return nil
247+
else return a[i], t[a[i]]
248+
end
249+
end
250+
return iter
251+
end
252+
253+
238254
local function get_type(v)
239255
local pandoc_type = pandoc.utils.type(v)
240256
if pandoc_type == "Inline" then
@@ -546,7 +562,8 @@ return {
546562
type = get_type,
547563
table = {
548564
isarray = tisarray,
549-
contains = tcontains
565+
contains = tcontains,
566+
sortedPairs = sortedPairs
550567
},
551568
as_inlines = as_inlines,
552569
as_blocks = as_blocks,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
logo:
2+
images:
3+
large-light: quarto.png
4+
large: large-light
5+
defaults:
6+
quarto:
7+
format:
8+
typst:
9+
logo:
10+
src: large
11+
location: center-top
12+
width: 300px
13+
padding: 1in
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
title: logo background
3+
format:
4+
typst:
5+
keep-typ: true
6+
logo:
7+
padding: 1in 2in
8+
_quarto:
9+
tests:
10+
typst:
11+
ensureTypstFileRegexMatches:
12+
-
13+
- '#set page\(background: align\(center\+top, box\(inset: \(x: 2in, y: 1\in\), image\("quarto.png", width: 225pt\)\)\)\)'
14+
- []
15+
---
16+
17+
{{< lipsum 4 >}}
18+
11.5 KB
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
logo:
2+
images:
3+
large-light: quarto.png
4+
large: large-light
5+
defaults:
6+
quarto:
7+
format:
8+
typst:
9+
logo:
10+
src: large
11+
location: center-top
12+
width: 300px
13+
padding: 1in
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: logo background
3+
format:
4+
typst:
5+
keep-typ: true
6+
logo:
7+
padding-left: 4pt
8+
padding: 9pt 2pt 3pt 17pt
9+
padding-top: 1pt
10+
_quarto:
11+
tests:
12+
typst:
13+
ensureTypstFileRegexMatches:
14+
-
15+
- '#set page\(background: align\(center\+top, box\(inset: \(bottom: 3pt, left: 4pt, right: 2pt, top: 1pt\), image\("quarto.png", width: 225pt\)\)\)\)'
16+
- []
17+
---
18+
19+
{{< lipsum 4 >}}
20+

0 commit comments

Comments
 (0)