summaryrefslogtreecommitdiff
path: root/biblio/citation-style-language/citeproc-node-label.lua
diff options
context:
space:
mode:
Diffstat (limited to 'biblio/citation-style-language/citeproc-node-label.lua')
-rw-r--r--biblio/citation-style-language/citeproc-node-label.lua106
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