From dea1be4ad3fcbff04c6ca17c7e9f8822b07bff10 Mon Sep 17 00:00:00 2001 From: Omikhleia Date: Sat, 14 Sep 2024 14:25:52 +0200 Subject: [PATCH] refactor(packages): Better handling of page ranges in bibliographies --- csl/core/engine.lua | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/csl/core/engine.lua b/csl/core/engine.lua index d3edf2e8e..48cf4f5d2 100644 --- a/csl/core/engine.lua +++ b/csl/core/engine.lua @@ -22,6 +22,7 @@ local CslLocale = require("csl.core.locale").CslLocale local superfolding = require("csl.core.utils.superfolding") local endash = luautf8.char(0x2013) +local emdash = luautf8.char(0x2014) local CslEngine = pl.class() @@ -61,12 +62,26 @@ function CslEngine:_init (style, locale, extras) close_quote = self:_render_term("close-quote") or luautf8.char(0x201D), -- 0x201D curly right quote open_inner_quote = self:_render_term("open-inner-quote") or luautf8.char(0x2018), -- 0x2018 curly left single quote close_inner_quote = self:_render_term("close-inner-quote") or luautf8.char(0x2019), -- 0x2019 curly right single quote - page_range_delimiter = self:_render_term("page-range-delimiter") or endash, -- FIXME: UNUSED AS OF NOW + page_range_delimiter = self:_render_term("page-range-delimiter") or endash, [","] = self:_render_term("comma") or ",", [";"] = self:_render_term("semicolon") or ";", [":"] = self:_render_term("colon") or ":", } + -- For page ranges, see text processing for + local sep = self.punctuation.page_range_delimiter + local dashes = "%-" .. endash .. emdash + if sep ~= "-" and sep ~= endash and sep ~= emdash then + local escape = function (str) + local escapeInLua = "[%.%+%*%[%?%-%%]" + return string.gsub(str, "([%.%+%*%[%?%-%%])", "%%%1") + end + dashes = dashes .. string.gsub(sep, "([%.%+%*%?%-%]%[%%])", "%%%1") + end + local textinrange = "[^" .. dashes .. "]+" + local dashinrange = "[" .. dashes .. "]+" + self.page_range_capture = "(" .. textinrange .. ")%s*" .. dashinrange .. "%s*(" .. textinrange .. ")" + -- Inheritable variables -- There's a long list of such variables, but let's be dumb and just merge everything. self.inheritable = { @@ -410,12 +425,19 @@ function CslEngine:_text (options, content, entry) elseif options.term then t = self:_render_term(options.term, options.form, options.plural) elseif options.variable then - local variable = SU.required(options, "variable", "CSL text") + local variable = options.variable t = entry[variable] self:_addGroupVariable(variable, t) if variable == "locator" then t = t and t.value + variable = entry.locator.label end + if variable == "page" and t then + -- Replace any dash in page ranges + local sep = self.punctuation.page_range_delimiter + t = luautf8.gsub(t, self.page_range_capture, "%1" .. sep .. "%2") + end + -- FIXME NOT IMPLEMENTED SPEC: -- "May be accompanied by the form attribute to select the “long” -- (default) or “short” form of a variable (e.g. the full or short