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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
--
-- Copyright (c) 2021-2022 Zeping Lee
-- Released under the MIT license.
-- Repository: https://github.com/zepinglee/citeproc-lua
--
local locale = {}
local element = require("citeproc-element")
local Locale = element.Element:new()
function Locale:get_option (key)
local query = string.format("style-options[%s]", key)
local option = self:query_selector(query)[1]
if option then
local value = option:get_attribute(key)
if self.option_type[key] == "integer" then
value = tonumber(value)
elseif self.option_type[key] == "boolean" then
value = (value == "true")
end
return value
else
return nil
end
end
function Locale:get_term (name, form, number, gender)
if form == "long" then
form = nil
end
local match_last
local match_last_two
local match_whole
if number then
assert(type(number) == "number")
match_last = string.format("%s-%02d", name, number % 10)
match_last_two = string.format("%s-%02d", name, number % 100)
match_whole = string.format("%s-%02s", name, number)
end
local res = nil
for _, term in ipairs(self:query_selector("term")) do
-- Use get_path?
local match_name = name
if number then
local term_match = term:get_attribute("last-two-digits")
if term_match == "whole-number" then
match_name = match_whole
elseif term_match == "last-two-digits" then
match_name = match_last_two
elseif number < 10 then
-- "13" can match only "ordinal-13" not "ordinal-03"
-- It is sliced to "3" in a later checking pass.
match_name = match_last_two
else
match_name = match_last
end
end
local term_name = term:get_attribute("name")
local term_form = term:get_attribute("form")
if term_form == "long" then
term_form = nil
end
local term_gender = term:get_attribute("gender-form")
if term_name == match_name and term_form == form and term_gender == gender then
return term
end
end
-- Fallback
if form == "verb-sort" then
return self:get_term(name, "verb")
elseif form == "symbol" then
return self:get_term(name, "short")
elseif form == "verb" then
return self:get_term(name, "long")
elseif form == "short" then
return self:get_term(name, "long")
end
if number and number > 10 then
return self:get_term(name, nil, number % 10, gender)
end
if gender then
return self:get_term(name, nil, number, nil)
end
if number then
return self:get_term(name, nil, nil, nil)
end
return nil
end
local Term = element.Element:new()
function Term:render (context, is_plural)
self:debug_info(context)
context = self:process_context(context)
local output = {
single = self:get_text(),
}
for _, child in ipairs(self:get_children()) do
if child:is_element() then
output[child:get_element_name()] = self:escape(child:get_text())
end
end
local res = output.single
if is_plural then
if output.multiple then
res = output.multiple
end
end
if res == "" then
return nil
end
return res
end
locale.Locale = Locale
locale.Term = Term
return locale
|