1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
--
-- Copyright (c) 2021-2022 Zeping Lee
-- Released under the MIT license.
-- Repository: https://github.com/zepinglee/citeproc-lua
--
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
|