diff --git a/packages/bibtex/csl/engine.lua b/packages/bibtex/csl/engine.lua
index 5c4824441..650a2a385 100644
--- a/packages/bibtex/csl/engine.lua
+++ b/packages/bibtex/csl/engine.lua
@@ -421,49 +421,73 @@ end
function CslEngine:_layout (options, content, entries)
local output = {}
+ if self.mode == "citation" then
+ for _, entry in ipairs(entries) do
+ self:_prerender()
+ local elem = self:_render_children(content, entry)
+ elem = self:_postrender(elem)
+ if elem then
+ table.insert(output, elem)
+ end
+ end
+ -- The CSL 1.0.2 specification is not very clear on this point, but on
+ -- citations, affixes and formatting apply on the whole layout.
+ -- Affixes are arround the delimited list, e.g. "(Smith, 2000; Jones, 2001)"
+ -- Rendering is done after, so vertical-align, etc. apply to the whole list,
+ -- e.g. 1,2
+ local cites = self:_render_delimiter(output, options.delimiter or "; ")
+ cites = self:_render_affixes(cites, options)
+ cites = self:_render_formatting(cites, options)
+ return cites
+ end
+ -- On bibliographies, affixes (usually just a period suffix) apply on each entry.
+ -- Formatting is not forbidden in the specification, and occurs in a few styles.
+ -- But it doesn't seem to be very useful (mostly font-variant="normal" and
+ -- vertical-align="baseline"). Anyhow, if set, it probably applies to the
+ -- entry including the affixes.
+ -- CSL 1.0.2 only mentions a delimiter for citations, so it's not used here,
+ -- quite logically as we force a paragraph break between entries.
for _, entry in ipairs(entries) do
self:_prerender()
local elem = self:_render_children(content, entry)
- -- affixes and formatting likely apply on elementary entries
- -- (The CSL 1.0.2 specification is not very clear on this point.)
- elem = self:_render_formatting(elem, options)
elem = self:_render_affixes(elem, options)
+ elem = self:_render_formatting(elem, options)
elem = self:_postrender(elem)
if elem then
table.insert(output, elem)
end
end
- if options.delimiter then
- return self:_render_delimiter(output, options.delimiter)
- end
- -- (Normally citations have a delimiter options, so we should only reach
- -- this point for the bibliography)
- local delim = self.mode == "citation" and "; " or ""
- -- references all belong to a different paragraph
- -- FIXME: should account for attributes on the toplevel bibliography element:
- -- line-spacing
- -- hanging-indent
- return table.concat(output, delim)
+ return table.concat(output, "")
end
function CslEngine:_text (options, content, entry)
local t
- local link
+ local variable
if options.macro then
if self.macros[options.macro] then
+ -- This is not explicit in the CSL 1.0.2 specification, which mention conditional
+ -- rendering for groups only. However, macro should behave as it own group, and
+ -- be suppressed on the same conditions. This is used in a variety of styles, for
+ -- instance UFES-ABNT, UNEAL-ABNT or ABNT-IPEA have definitions like:
+ --
+ --
+ -- (...)
+ --
+ self:_enterGroup()
t = self:_render_children(self.macros[options.macro], entry)
+ t = self:_leaveGroup(t)
else
SU.error("CSL macro " .. options.macro .. " not found")
end
elseif options.term then
t = self:_render_term(options.term, options.form, options.plural)
elseif options.variable then
- local variable = options.variable
+ variable = options.variable
t = entry[variable]
self:_addGroupVariable(variable, t)
if variable == "locator" then
+ variable = t and t.label
t = t and t.value
- variable = entry.locator.label
end
if variable == "page" and t then
-- Replace any dash in page ranges
@@ -476,26 +500,51 @@ function CslEngine:_text (options, content, entry)
-- title). If the “short” form is selected but unavailable, the
-- “long” form is rendered instead."
-- But CSL-JSON etc. do not seem to have standard provision for it.
-
- if t and (variable == "URL" or variable == "DOI" or variable == "PMID" or variable == "PMCID") then
- link = variable
- end
elseif options.value then
t = options.value
else
SU.error("CSL text without macro, term, variable or value")
end
+ -- Some styles have strip-periods even on DOI, etc.
t = self:_render_stripPeriods(t, options)
- t = self:_render_textCase(t, options)
- t = self:_render_formatting(t, options)
- t = self:_render_quotes(t, options)
- t = self:_render_affixes(t, options)
- if link then
- t = self:_render_link(t, link)
- elseif t and options.variable then
- t = self:_render_text_specials(t)
+ if t then
+ if variable and (variable == "DOI" or variable == "PMID" or variable == "PMCID") then
+ -- Some styles have a "http..." as prefix for DOIs, etc.
+ -- Other add raw text such as "DOI: "
+ -- Call that a totally ill-defined feature of CSL, with unclear semantics
+ -- and conflating affixes for styling/presentation and the link itself.
+ local isURLPrefix = options.prefix and options.prefix:find("^http")
+ if isURLPrefix then
+ -- Make the prefix part of the link, we'll want it part of an hyperlink
+ t = options.prefix .. t
+ end
+ t = self:_render_link(t, variable)
+ t = self:_render_textCase(t, options)
+ t = self:_render_formatting(t, options)
+ t = self:_render_quotes(t, options)
+ t = self:_render_affixes(t, {
+ prefix = not isURLPrefix and options.prefix or nil,
+ suffix = options.suffix,
+ })
+ -- (No "text specials" in DOIs, etc. by nature)
+ elseif variable == "URL" then
+ t = self:_render_link(t, variable)
+ t = self:_render_textCase(t, options)
+ t = self:_render_formatting(t, options)
+ t = self:_render_quotes(t, options)
+ t = self:_render_affixes(t, options)
+ -- (No "text specials" in URLs by nature)
+ else
+ t = self:_render_textCase(t, options)
+ t = self:_render_formatting(t, options)
+ t = self:_render_quotes(t, options)
+ t = self:_render_affixes(t, options)
+ if t and options.variable then
+ t = self:_render_text_specials(t)
+ end
+ end
+ t = self:_render_display(t, options)
end
- t = self:_render_display(t, options)
return t
end
@@ -697,6 +746,7 @@ function CslEngine:_number (options, content, entry)
local value = entry[variable]
self:_addGroupVariable(variable, value)
if variable == "locator" then -- special case
+ variable = value and value.label
value = value and value.value
end
if value then