diff options
Diffstat (limited to 'biblio/citation-style-language/citeproc-node-label.lua')
-rw-r--r-- | biblio/citation-style-language/citeproc-node-label.lua | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/biblio/citation-style-language/citeproc-node-label.lua b/biblio/citation-style-language/citeproc-node-label.lua new file mode 100644 index 0000000000..d8bfe2ba3d --- /dev/null +++ b/biblio/citation-style-language/citeproc-node-label.lua @@ -0,0 +1,106 @@ +local label = {} + +local element = require("citeproc-element") +local util = require("citeproc-util") + + +local Label = element.Element:new() + +function Label:render (item, context) + self:debug_info(context) + context = self:process_context(context) + + local variable_name + if context.names_element then + -- The `variable` attribute of names may hold multiple roles. + -- Each of them may call `Label:render()` to render the term. + -- When used in `names` element, the role name is the first argument + -- and the item is accessed via `context.item`. + -- Bad design + -- TODO: Redesign the arguments of render() + variable_name = item + else + variable_name = context.options["variable"] + end + + local form = context.options["form"] + local plural = context.options["plural"] or "contextual" + + if not context.names_element then + local variable_type = util.variable_types[variable_name] + -- variable must be or one of the number variables. + if variable_type ~= "number" then + return nil + end + -- The term is only rendered if the selected variable is non-empty + local variable = item[variable_name] + if not variable then + return nil + end + if type(variable) == "string" then + if not (string.match(variable, "^%d") or util.is_numeric(variable)) then + return nil + end + end + end + + local term + if variable_name == "locator" then + local locator_type = item.label or "page" + term = self:get_term(locator_type, form) + else + term = self:get_term(variable_name, form) + end + + local res = nil + if term then + if plural == "contextual" and self:_is_plural(variable_name, context) or plural == "always" then + res = term:render(context, true) + else + res = term:render(context, false) + end + + res = self:strip_periods(res, context) + res = self:case(res, context) + res = self:format(res, context) + res = self:wrap(res, context) + end + return res +end + +function Label:_is_plural (variable_name, context) + local variable_type = util.variable_types[variable_name] + -- Don't use self:get_variable here + local variable = context.item[variable_name] + local res = false + if variable_type == "name" then + -- Label inside `names` + res = #variable > 1 + + elseif variable_type == "number" then + if util.startswith(variable_name, "number-of-") then + res = tonumber(variable) > 1 + else + variable = tostring(variable) + variable = string.gsub(variable, "\\%-", "") + if #util.split(variable, "%s*[,&-]%s*") > 1 then + -- check if contains multiple numbers + -- "i–ix": true + -- res = string.match(tostring(variable), "%d+%D+%d+") ~= nil + res = true + elseif string.match(variable, "%Aand%A") or string.match(variable, "%Aet%A") then + res = true + else + res = false + end + end + else + util.warning("Invalid attribute \"variable\".") + end + return res +end + + +label.Label = Label + +return label |