summaryrefslogtreecommitdiff
path: root/biblio/citation-style-language/citeproc-node-number.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-01-22 03:01:16 +0000
committerNorbert Preining <norbert@preining.info>2022-01-22 03:01:16 +0000
commit26bfc07f2b7829213356de43cf5b81c3ba99e338 (patch)
treeefb3037df2c42c45c904ad131334e8fc626cea19 /biblio/citation-style-language/citeproc-node-number.lua
parent5d5f239204f5c0d1f7573c9ebc64b5ad1ae75b49 (diff)
CTAN sync 202201220301
Diffstat (limited to 'biblio/citation-style-language/citeproc-node-number.lua')
-rw-r--r--biblio/citation-style-language/citeproc-node-number.lua99
1 files changed, 99 insertions, 0 deletions
diff --git a/biblio/citation-style-language/citeproc-node-number.lua b/biblio/citation-style-language/citeproc-node-number.lua
new file mode 100644
index 0000000000..e4fe710fd0
--- /dev/null
+++ b/biblio/citation-style-language/citeproc-node-number.lua
@@ -0,0 +1,99 @@
+local number_module = {}
+
+local element = require("citeproc-element")
+local util = require("citeproc-util")
+
+
+local Number = element.Element:new()
+
+function Number:render (item, context)
+ self:debug_info(context)
+ context = self:process_context(context)
+ local variable = context.options["variable"]
+ local content = self:get_variable(item, variable, context)
+
+ table.insert(context.variable_attempt, content ~= nil)
+
+ if not content then
+ return nil
+ end
+
+ local numbers = {}
+ local punct_list = {}
+ local last_position = 1
+ for number, punct, pos in string.gmatch(content, "(.-)%s*([-,&])%s*()") do
+ table.insert(numbers, number)
+ table.insert(punct_list, punct)
+ last_position = pos
+ end
+ table.insert(numbers, string.sub(content, last_position))
+
+ local res = ""
+ for i, number in ipairs(numbers) do
+ local punct = punct_list[i]
+ number = self:_format_single_number(number, context)
+ res = res .. number
+
+ if punct == "-" then
+ res = res .. punct
+ elseif punct == "," then
+ res = res .. punct .. " "
+ elseif punct == "&" then
+ res = res .. " " .. punct .. " "
+ end
+ end
+
+ res = self:case(res, context)
+ res = self:wrap(res, context)
+ res = self:display(res, context)
+
+ return res
+end
+
+function Number:_format_single_number(number, context)
+ local form = context.options["form"] or "numeric"
+ if form == "numeric" or not string.match(number, "^%d+$") then
+ return number
+ end
+ number = tonumber(number)
+ if form == "ordinal" or form == "long-ordinal" then
+ return self:_format_oridinal(number, form, context)
+ elseif form == "roman" then
+ return util.convert_roman(number)
+ end
+end
+
+function Number:_format_oridinal(number, form, context)
+ assert(type(number) == "number")
+ local variable = context.options["variable"]
+
+ if form == "long-ordinal" then
+ if number < 1 or number > 10 then
+ form = "ordinal"
+ end
+ end
+
+ local gender = nil
+ local term = self:get_term(variable)
+ if term then
+ gender = term:get_attribute("gender")
+ end
+
+ term = self:get_term(form, nil, number, gender)
+ local res = term:render(context)
+ if form == "ordinal" then
+ if res then
+ return tostring(number) .. res
+ else
+ res = tostring(number)
+ end
+ else
+ return res
+ end
+ return res
+end
+
+
+number_module.Number = Number
+
+return number_module