Skip to content

Commit 64eaba4

Browse files
OmikhleiaDidier Willis
authored andcommitted
fix(packages): CSL choose must inherit delimiter from nearest ancestor
1 parent c9c373f commit 64eaba4

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

packages/bibtex/csl/engine.lua

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
--- A rendering engine for CSL 1.0.2
22
--
3-
-- @copyright License: MIT (c) 2024 Omikhleia
3+
-- @copyright License: MIT (c) 2024, 2025 Omikhleia
44
--
55
-- Public API:
66
-- - (constructor) CslEngine(style, locale) -> CslEngine
@@ -450,7 +450,7 @@ function CslEngine:_layout (options, content, entries)
450450
for _, entry in ipairs(entries) do
451451
self:_prerender()
452452
local elem = self:_render_children(content, entry, {
453-
secondFieldAlign = self.inheritable.bibliography["second-field-align"] and true or false,
453+
secondFieldAlign = self.inheritable.bibliography["second-field-align"] and true or false
454454
})
455455
elem = self:_render_affixes(elem, options)
456456
elem = self:_render_formatting(elem, options)
@@ -1279,27 +1279,30 @@ function CslEngine:_if (options, content, entry)
12791279
end
12801280
end
12811281
end
1282-
if matching then
1283-
return self:_render_children(content, entry), true
1284-
-- FIXME:
1285-
-- The CSL specification says: "Delimiters from the nearest delimiters
1286-
-- from the nearest ancestor delimiting element are applied within the
1287-
-- output of cs:choose (i.e., the output of the matching cs:if,
1288-
-- cs:else-if, or cs:else; see delimiter).""
1289-
-- Ugh. This is rather obscure and not implemented yet (?)
1290-
end
1291-
return nil, false
1282+
-- We return the content if the condition is met
1283+
-- (Not the formatted content as in other methods)
1284+
return matching and content or nil
12921285
end
12931286

1294-
function CslEngine:_choose (options, content, entry)
1287+
function CslEngine:_choose (options, content, entry, context)
1288+
-- The CSL specification says: "Delimiters from the nearest delimiters
1289+
-- from the nearest ancestor delimiting element are applied within the
1290+
-- output of cs:choose (i.e., the output of the matching cs:if,
1291+
-- cs:else-if, or cs:else; see delimiters)."
1292+
-- NOTE: I am not sure if the current context is always sufficient here.
1293+
local delimiter = context.delimiter
12951294
for _, child in ipairs(content) do
12961295
if child.command == "cs:if" or child.command == "cs:else-if" then
1297-
local t, match = self:_if(child.options, child, entry)
1296+
local match = self:_if(child.options, child, entry)
12981297
if match then
1299-
return t
1298+
return self:_render_children(child, entry, {
1299+
delimiter = delimiter
1300+
})
13001301
end
13011302
elseif child.command == "cs:else" then
1302-
return self:_render_children(child, entry)
1303+
return self:_render_children(child, entry, {
1304+
delimiter = delimiter
1305+
})
13031306
end
13041307
end
13051308
end
@@ -1436,10 +1439,11 @@ end
14361439

14371440
-- PROCESSING
14381441

1439-
function CslEngine:_render_node (node, entry)
1442+
function CslEngine:_render_node (node, entry, context)
14401443
local callback = node.command:gsub("cs:", "_")
1444+
context = context or {}
14411445
if self[callback] then
1442-
return self[callback](self, node.options, node, entry)
1446+
return self[callback](self, node.options, node, entry, context)
14431447
else
14441448
SU.warn("Unknown CSL element " .. node.command .. " (" .. callback .. ")")
14451449
end
@@ -1453,7 +1457,7 @@ function CslEngine:_render_children (ast, entry, context)
14531457
context = context or {}
14541458
for _, content in ipairs(ast) do
14551459
if type(content) == "table" and content.command then
1456-
local r = self:_render_node(content, entry)
1460+
local r = self:_render_node(content, entry, context)
14571461
if r then
14581462
table.insert(ret, r)
14591463
end

0 commit comments

Comments
 (0)