Module:number list: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 1: Line 1:
local export = {}
-- TODO: support <id:...>. currently it does nothing.


local m_links = require("Module:links")
local m_links = require("Module:links")
local m_str_utils = require("Module:string utilities")
local char = string.char
local concat = table.concat
local gsub = m_str_utils.gsub
local insert = table.insert
local list_to_set = require("Module:table").listToSet
local sort = table.sort
local u = m_str_utils.char
local upper = string.upper
local export = {}


--[=[
--[=[
Line 20: Line 32:
]=]
]=]


local form_types = {
local default_form_types = {
{key = "cardinal", display = "[[wikt:cardinal number|Cardinal]]"},
{key = "cardinal", display = "[[cardinal number|Cardinal]]"},
{key = "ordinal", display = "[[wikt:ordinal number|Ordinal]]"},
{key = "ordinal", display = "[[ordinal number|Ordinal]]"},
{key = "ordinal_abbr", display = "[[wikt:ordinal number|Ordinal]] [[wikt:abbreviation]]"},
{key = "ordinal_abbr", display = "[[ordinal number|Ordinal]] [[abbreviation]]"},
{key = "adverbial", display = "[[wikt:adverbial number|Adverbial]]"},
{key = "adverbial", display = "[[adverbial number|Adverbial]]"},
{key = "multiplier", display = "[[wikt:multiplier|Multiplier]]"},
{key = "multiplier", display = "[[multiplier|Multiplier]]"},
{key = "distributive", display = "[[wikt:distributive number|Distributive]]"},
{key = "distributive", display = "[[distributive number|Distributive]]"},
{key = "collective", display = "[[wikt:collective number|Collective]]"},
{key = "collective", display = "[[collective number|Collective]]"},
{key = "fractional", display = "[[wikt:fractional|Fractional]]"},
{key = "fractional", display = "[[fractional|Fractional]]"},
{key = "formal", display = "[[wikt:formal|Formal]]"},
}
}


Line 43: Line 54:
lower = true,
lower = true,
}
}
local function track(page)
require("Module:debug/track")("number list/" .. page)
return true
end


--[=[
--[=[
Line 81: Line 97:
end
end


local function list_to_set(list)
function export.get_data_module_name(langcode)
local set = {}
return "Module:number list/data/" .. langcode
for _, item in ipairs(list) do
set[item] = true
end
return set
end
 
function export.get_data_module_name(langcode, must_exist)
local module_name = "Module:number list/data/" .. langcode
if must_exist and not mw.title.new(module_name).exists then
error(("Data module [[%s]] for language code '%s' does not exist"):format(module_name, langcode))
end
return module_name
end
 
local function power_of(n)
return "1" .. string.rep("0", n)
end
end


Line 113: Line 113:
-- Parse a form with modifiers such as 'vuitanta-vuit<tag:Central>' or 'سیزده<tr:sizdah>'
-- Parse a form with modifiers such as 'vuitanta-vuit<tag:Central>' or 'سیزده<tr:sizdah>'
-- or 'سیزده<tr:sizdah><tag:Iranian>' into its component parts. Return a form object, i.e. an object with fields
-- or 'سیزده<tr:sizdah><tag:Iranian>' into its component parts. Return a form object, i.e. an object with fields
-- `form` for the form, and `alt`, `tr`, `tag`, `q`, `qq` or `link` for the modifiers. The `tag` field is a tag list
-- `form` for the form, and `tr`, `tag`, `q`, `qq` or `link` for the modifiers. The `tag` field is a tag list
-- (see above).
-- (see above).
function export.parse_form_and_modifiers(form_with_modifiers)
function export.parse_form_and_modifiers(form_with_modifiers)
Line 130: Line 130:
if prefix == "tag" then
if prefix == "tag" then
if retval.tag then
if retval.tag then
table.insert(retval.tag, content)
insert(retval.tag, content)
else
else
retval.tag = {content}
retval.tag = {content}
end
end
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "alt" then
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" then
if retval[prefix] then
if retval[prefix] then
error(("Duplicate modifier '%s' in data module form, already saw value '%s': %s"):format(prefix,
error(("Duplicate modifier '%s' in data module form, already saw value '%s': %s"):format(prefix,
Line 178: Line 178:
-- Given a number form, convert it to its independent (un-affixed) form. This only makes sense for certain languages
-- Given a number form, convert it to its independent (un-affixed) form. This only makes sense for certain languages
-- where there is a difference between independent and affixed forms of numerals. Currently the only such language
-- where there is a difference between independent and affixed forms of numerals. Currently the only such language
-- is Swahili, where e.g. the cardinal number form for 3 is affixed [[wikt:-tatu]], independent [[wikt:tatu]], and the ordinal
-- is Swahili, where e.g. the cardinal number form for 3 is affixed [[-tatu]], independent [[tatu]], and the ordinal
-- number form is [[wikt:-a tatu]], independent [[wikt:tatu]]. We rely on a set of Lua pattern substitutions to convert from
-- number form is [[-a tatu]], independent [[tatu]]. We rely on a set of Lua pattern substitutions to convert from
-- affixed to independent form.
-- affixed to independent form.
--
--
Line 189: Line 189:
for _, entry in ipairs(m_data.unaffix) do
for _, entry in ipairs(m_data.unaffix) do
local from, to = unpack(entry)
local from, to = unpack(entry)
form = mw.ustring.gsub(form, from, to)
form = gsub(form, from, to)
end
end
return form
return form
Line 231: Line 231:
end
end


table.sort(sorted_list, export.numbers_less_than)
sort(sorted_list, export.numbers_less_than)


-- We could binary search to save time, but given that we already sort, which is supra-linear, it won't
-- We could binary search to save time, but given that we already sort, which is supra-linear, it won't
Line 266: Line 266:
-- with different types, e.g. the ordinal and fractional forms for a given number are the same), but will
-- with different types, e.g. the ordinal and fractional forms for a given number are the same), but will
-- throw an error if different numbers are seen.
-- throw an error if different numbers are seen.
table.insert(retval, {num, typ})
insert(retval, {num, typ})
end
end
end
end
Line 285: Line 285:


return retval
return retval
end
local function index_of_number_type(t, type)
for i, subtable in ipairs(t) do
if subtable.key == type then
return i
end
end
end
end


Line 299: Line 291:
-- the numeral type that the form should appear before or after.
-- the numeral type that the form should appear before or after.
-- The transformations are applied in order.
-- The transformations are applied in order.
local function add_form_types(additional_types)
local function add_form_types(form_types, additional_types)
local types = require("Module:table").deepcopy(form_types)
local types = require("Module:table").deepCopy(form_types)
for _, type in ipairs(additional_types) do
for _, additional_type in ipairs(additional_types) do
type = require("Module:table").shallowcopy(type)
if not (additional_type.before or additional_type.after) then
local i
insert(types, additional_type)
if type.before or type.after then
else
i = index_of_number_type(types, type.before or type.after)
if additional_type.before and additional_type.after then
end
error("The form type '" .. additional_type.key .. "' is specifying both before and after, which is not allowed")
-- For now, simply log an error message
end
-- if the "before" or "after" number type was not found,
 
-- and insert the number type at the end.
local anchor, index = additional_type.before or additional_type.after
if i then
 
if type.before then
for i, another_type in ipairs(types) do
table.insert(types, i - 1, type)
if another_type.key == anchor then
else
index = i
table.insert(types, i + 1, type)
break
end
end
 
if index and additional_type.after then
index = index + 1
end
end
else
 
table.insert(types, type)
additional_type = require("Module:table").shallowCopy(additional_type)
if type.before or type.after then
additional_type.before, additional_type.after = nil, nil
if not index then
mw.log("Number type "
mw.log("Number type "
.. (type.before or type.after)
.. (additional_type.before or additional_type.after)
.. " was not found.")
.. " was not found.")
insert(types, additional_type)
else
insert(types, index, additional_type)
end
end
end
end
type.before, type.after = nil, nil
end
end
return types
return types
Line 331: Line 332:
-- Return all form types for the language in question, in order.
-- Return all form types for the language in question, in order.
function export.get_number_types(m_data)
function export.get_number_types(m_data)
local final_form_types = form_types
local form_types = default_form_types
if m_data.additional_number_types then
if m_data.additional_number_types then
final_form_types = add_form_types(m_data.additional_number_types)
return add_form_types(form_types, m_data.additional_number_types)
else
return form_types
end
end
return final_form_types
end
end


Line 343: Line 345:
return number_type.display
return number_type.display
else
else
return (number_type.key:gsub("^.", string.upper):gsub("_", " "))
return (number_type.key:gsub("^.", upper):gsub("_", " "))
end
end
end
end
Line 356: Line 358:
local parts = { numstr:sub(-start) }
local parts = { numstr:sub(-start) }
for i = start + 1, #numstr, group do
for i = start + 1, #numstr, group do
table.insert(parts, 1, numstr:sub(-(i + group - 1), -i))
insert(parts, 1, numstr:sub(-(i + group - 1), -i))
end
end


return table.concat(parts, separator)
return concat(parts, separator)
end
end


Line 399: Line 401:
end
end


return numstr:gsub("[0-9]", function (digit)
return numstr:gsub("%d", function (digit)
return mw.ustring.char(zero_codepoint + tonumber(digit))
return u(zero_codepoint + tonumber(digit))
end)
end)
end
end
Line 425: Line 427:
mantissa = ""
mantissa = ""
elseif #kstr == 1 then
elseif #kstr == 1 then
mantissa = kstr .. " x "
mantissa = kstr .. " × "
else
else
mantissa = kstr:gsub("^([0-9])", "%1.") .. " x "
mantissa = kstr:gsub("^([0-9])", "%1.") .. " × "
end
end
local scientific = mantissa .. exponent
local scientific = mantissa .. exponent
Line 440: Line 442:
-- keys of tables.
-- keys of tables.
local function tag_list_to_combined_tag(tag_list)
local function tag_list_to_combined_tag(tag_list)
return table.concat(tag_list, "|||")
return concat(tag_list, "|||")
end
end


Line 460: Line 462:
for _, form in ipairs(forms) do
for _, form in ipairs(forms) do
local formobj = export.parse_form_and_modifiers(form)
local formobj = export.parse_form_and_modifiers(form)
table.insert(seen_forms, formobj)
insert(seen_forms, formobj)
local combined_tag = formobj.tag and tag_list_to_combined_tag(formobj.tag) or ""
local combined_tag = formobj.tag and tag_list_to_combined_tag(formobj.tag) or ""
if not forms_by_tag[combined_tag] then
if not forms_by_tag[combined_tag] then
table.insert(seen_tags, combined_tag)
insert(seen_tags, combined_tag)
forms_by_tag[combined_tag] = {}
forms_by_tag[combined_tag] = {}
combined_tags_to_tag_lists[combined_tag] = formobj.tag or {}
combined_tags_to_tag_lists[combined_tag] = formobj.tag or {}
end
end
table.insert(forms_by_tag[combined_tag], formobj)
insert(forms_by_tag[combined_tag], formobj)
end
end


Line 477: Line 479:
local left_q = formobj.q and require("Module:qualifier").format_qualifier(formobj.q) .. " " or ""
local left_q = formobj.q and require("Module:qualifier").format_qualifier(formobj.q) .. " " or ""
local right_q = formobj.qq and " " .. require("Module:qualifier").format_qualifier(formobj.qq) or ""
local right_q = formobj.qq and " " .. require("Module:qualifier").format_qualifier(formobj.qq) or ""
return left_q .. m_links.full_link({
return left_q .. m_links.full_link{
lang = lang, term = maybe_unaffix(m_data, formobj.form), alt = formobj.alt or formobj.form, tr = formobj.tr,
lang = lang, term = maybe_unaffix(m_data, formobj.form), alt = formobj.form, tr = formobj.tr,
}) .. right_q
} .. right_q
end
end


Line 487: Line 489:


local params = {
local params = {
[1] = {required = true},
[1] = {required = true, type = "language", default = "und"},
[2] = {},
[2] = true,
["pagename"] = {},
["pagename"] = true,
["type"] = {},
["type"] = true,
}
}


local parent_args = frame:getParent().args
local parent_args = frame:getParent().args
if parent_args.pagename then
track("show-box-pagename")
end
local args = require("Module:parameters").process(parent_args, params, nil, "number list", "show_box")
local args = require("Module:parameters").process(parent_args, params, nil, "number list", "show_box")


local langcode = args[1] or "und"
local lang = args[1]
local lang = require("Module:languages").getByCode(langcode, "1")
local langcode = lang:getCode()


-- Get the data from the data module. Some modules (e.g. currently [[wikt:Module:number list/data/ka]]) have to be
-- Get the data from the data module. Some modules (e.g. currently [[Module:number list/data/ka]]) have to be
-- loaded with require() because the exported numbers table has a metatable.
-- loaded with require() because the exported numbers table has a metatable.
local module_name = export.get_data_module_name(langcode, "must exist")
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
local m_data = require(module_name)


Line 510: Line 515:


-- We represent all numbers as strings in this function to deal with the limited precision inherent in Lua numbers.
-- We represent all numbers as strings in this function to deal with the limited precision inherent in Lua numbers.
-- These large numbers do occur, such as 100 trillion ([[wikt:རབ་བཀྲམ་ཆེན་པོ]]), 1 sextillion, etc. Lua represents all
-- These large numbers do occur, such as 100 trillion ([[རབ་བཀྲམ་ཆེན་པོ]]), 1 sextillion, etc. Lua represents all
-- numbers as 64-bit floats, meaning that some numbers above 2^53 cannot be represented exactly. The first power of
-- numbers as 64-bit floats, meaning that some numbers above 2^53 cannot be represented exactly. The first power of
-- 10 that cannot be represented exactly is 10^22 (ten sextillion in short scale, ten thousand trillion in long
-- 10 that cannot be represented exactly is 10^22 (ten sextillion in short scale, ten thousand trillion in long
Line 530: Line 535:
end
end
for _, num_and_type in ipairs(nums_and_types) do
for _, num_and_type in ipairs(nums_and_types) do
local num, typ = unpack(num_and_type)
local num = num_and_type[1]
num = export.format_fixed(num)
num = export.format_fixed(num)
if cur_num and num ~= cur_num then
if cur_num and num ~= cur_num then
Line 536: Line 541:
for _, num_and_type in ipairs(nums_and_types) do
for _, num_and_type in ipairs(nums_and_types) do
local num, typ = unpack(num_and_type)
local num, typ = unpack(num_and_type)
table.insert(errparts, ("%s (%s)"):format(num, typ))
insert(errparts, ("%s (%s)"):format(num, typ))
end
end
error("The current page name '" .. pagename .. "' matches the spelling of multiple numbers in [[" ..
error("The current page name '" .. pagename .. "' matches the spelling of multiple numbers in [[" ..
module_name .. "]]: " .. table.concat(errparts, ",") .. ". Please specify the number explicitly.")
module_name .. "]]: " .. concat(errparts, ",") .. ". Please specify the number explicitly.")
else
else
cur_num = num
cur_num = num
Line 578: Line 583:


local form_types = export.get_number_types(m_data)
local form_types = export.get_number_types(m_data)
 
-- LONG COMMENT EXPLAINING TAG HANDLING:
-- LONG COMMENT EXPLAINING TAG HANDLING:
--
--
Line 626: Line 631:
local numeral = cur_data[form_type.key]
local numeral = cur_data[form_type.key]
if numeral then
if numeral then
local numerals
local seen_forms, forms_by_tag, seen_tags, combined_tags_to_tag_lists = export.group_numeral_forms_by_tag(
if type(numeral) == "string" then
type(numeral) == "table" and numeral or {numeral}
numerals = {numeral}
)
elseif type(numeral) == "table" then
numerals = numeral
end
 
local seen_forms, forms_by_tag, seen_tags, combined_tags_to_tag_lists = export.group_numeral_forms_by_tag(numerals)
forms_by_tag_per_form_type[form_type] = forms_by_tag
forms_by_tag_per_form_type[form_type] = forms_by_tag
seen_tags_per_form_type[form_type] = seen_tags
seen_tags_per_form_type[form_type] = seen_tags
Line 685: Line 685:
return index1 < index2
return index1 < index2
end
end
table.sort(combined_tags, compare_tags)
sort(combined_tags, compare_tags)
end
end


Line 698: Line 698:
local pagename_among_forms = false
local pagename_among_forms = false
for _, formobj in ipairs(forms_by_tag[tag]) do
for _, formobj in ipairs(forms_by_tag[tag]) do
table.insert(formatted_tag_forms, export.format_formobj(formobj, m_data, lang))
insert(formatted_tag_forms, export.format_formobj(formobj, m_data, lang))
if form_equals_pagename(formobj, pagename, m_data, lang) then
if form_equals_pagename(formobj, pagename, m_data, lang) then
pagename_among_forms = true
pagename_among_forms = true
Line 706: Line 706:
if tag ~= "" then
if tag ~= "" then
local tag_list = combined_tags_to_tag_lists[tag]
local tag_list = combined_tags_to_tag_lists[tag]
tag = table.concat(tag_list, " / ")
tag = concat(tag_list, " / ")
end
end
local displayed_number_type = export.display_number_type(form_type) .. (tag == "" and "" or (" (%s)"):format(tag))
local displayed_number_type = export.display_number_type(form_type) .. (tag == "" and "" or (" (%s)"):format(tag))
Line 713: Line 713:
end
end


table.insert(formatted_forms, " &nbsp;&nbsp;&nbsp; ''" .. displayed_number_type .. "'': " ..
insert(formatted_forms, " &nbsp;&nbsp;&nbsp; ''" .. displayed_number_type .. "'': " ..
table.concat(formatted_tag_forms, ", "))
concat(formatted_tag_forms, ", "))
end
end


Line 730: Line 730:
if m_data.numeral_config then
if m_data.numeral_config then
numeral = export.generate_non_arabic_numeral(m_data.numeral_config, cur_num)
numeral = export.generate_non_arabic_numeral(m_data.numeral_config, cur_num)
if langcode == "qay" then numeral = numeral:gsub("A","¹"):gsub("B","²") end
elseif cur_data["numeral"] then
elseif cur_data["numeral"] then
numeral = export.format_fixed(cur_data["numeral"])
numeral = export.format_fixed(cur_data["numeral"])
Line 736: Line 735:


if numeral then
if numeral then
cur_display = full_link({lang = lang, alt = numeral, tr = "-"}) .. "<br/><span style=\"font-size: smaller;\">" .. cur_display .. "</span>"
cur_display = full_link{lang = lang, alt = numeral, tr = "-"} .. "<br/><span style=\"font-size: smaller;\">" .. cur_display .. "</span>"
end
end


Line 777: Line 776:
-- and return it if it's available and the number passes any checks, otherwise nil.
-- and return it if it's available and the number passes any checks, otherwise nil.
local function make_greater_power_of_ten(power)
local function make_greater_power_of_ten(power)
return cur_num .. string.rep("0", power)
return cur_num .. ("0"):rep(power)
end
end


Line 787: Line 786:
return nil
return nil
end
end
return k .. string.rep("0", desired_zeros)
return k .. ("0"):rep(desired_zeros)
end
end


Line 825: Line 824:
return data
return data
end
end
if not try((k + 1) .. string.rep("0", m)) and k == 1 then
if not try((k + 1) .. ("0"):rep(m)) and k == 1 then
-- Try looking up a greater power of ten instead.
-- Try looking up a greater power of ten instead.
for _, power_of_10 in ipairs(power_of_10_sequence) do
for _, power_of_10 in ipairs(power_of_10_sequence) do
Line 852: Line 851:
local num_to_try
local num_to_try
if k == 1 then
if k == 1 then
num_to_try = "9" .. string.rep("0", m - 1)
num_to_try = "9" .. ("0"):rep(m - 1)
else
else
num_to_try = (k - 1) .. string.rep("0", m)
num_to_try = (k - 1) .. ("0"):rep(m)
end
end
if not try(num_to_try) and k == 1 then
if not try(num_to_try) and k == 1 then
Line 927: Line 926:
return nil
return nil
end
end
local num_type_data = num_data[cur_type]
local forms = num_data[cur_type]
if not num_type_data then
if not forms then
return nil
return nil
end
elseif type(forms) ~= "table" then
local forms = num_type_data
if type(forms) ~= "table" then
forms = {forms}
forms = {forms}
end
end
Line 938: Line 935:
local seen_forms, forms_by_tag = export.group_numeral_forms_by_tag(forms)
local seen_forms, forms_by_tag = export.group_numeral_forms_by_tag(forms)


-- FIXME: `cur_tag` is not defined. This seems to have been missed when multiple tag handling was added in [[Special:Diff/68978046]].
local forms_to_display
local forms_to_display
if cur_tag and forms_by_tag[cur_tag] then
if cur_tag and forms_by_tag[cur_tag] then
Line 954: Line 952:
for _, form in ipairs(forms_to_display) do
for _, form in ipairs(forms_to_display) do
if not seen_pagenames[form] then
if not seen_pagenames[form] then
table.insert(pagenames_to_display, form)
insert(pagenames_to_display, form)
seen_pagenames[form] = true
seen_pagenames[form] = true
end
end
end
if #pagenames_to_display == 0 then
return nil
end
end


Line 968: Line 970:
local links = {}
local links = {}
for i, term in ipairs(pagenames_to_display) do
for i, term in ipairs(pagenames_to_display) do
links[i] = m_links.language_link{lang = lang, term = term, alt = "[" .. string.char(a + i - 1) .. "]"}
links[i] = m_links.language_link{lang = lang, term = term, alt = "[" .. char(a + i - 1) .. "]"}
end
end
links = "<sup>" .. table.concat(links, ", ") .. "</sup>"
links = "<sup>" .. concat(links, ", ") .. "</sup>"
return arrow == "larrow" and links .. num_arrow or num_arrow .. links
return arrow == "larrow" and links .. num_arrow or num_arrow .. links
else
else
Line 994: Line 996:


local canonical_name = lang:getCanonicalName()
local canonical_name = lang:getCanonicalName()
local title = canonical_name .. " numbers"
local appendix1 = canonical_name .. " numerals"
local appendix2 = canonical_name .. " numbers"
local appendix
local title
if mw.title.new(appendix1, "Appendix"):getContent() then
appendix = appendix1
elseif mw.title.new(appendix2, "Appendix"):getContent() then
appendix = appendix2
end
 
if appendix then
title = "[[Appendix:" .. appendix .. "|" .. appendix2 .. "]]"
else
title = appendix2
end


local function format_cell(contents, font_size, background, colspan, bold)
local function format_cell(contents, class_name, colspan, bold)
font_size = font_size and (" font-size:%s;"):format(font_size) or ""
class_name = class_name and (" " .. class_name) or ""
background = background and (" background:%s;"):format(background) or ""
colspan = colspan and ('colspan="%s" '):format(colspan) or ""
colspan = colspan and ('colspan="%s" '):format(colspan) or ""
bold = bold and "!" or "|"
bold = bold and "!" or "|"
return ('%s %sstyle="min-width: 6em;%s%s | %s\n'):format(bold, colspan, font_size, background, contents)
return ('%s %sclass="table-cell %s | %s\n'):format(bold, colspan, class_name, contents)
end
end


Line 1,012: Line 1,027:
blank_cell = "|\n"
blank_cell = "|\n"
end
end
local parts = {'|- style="text-align: center; background:#dddddd;"\n'}
local parts = {'|- class="adjacent-panel"\n'}
table.insert(parts, blank_cell)
insert(parts, blank_cell)
table.insert(parts, format_cell(display, "smaller"))
insert(parts, format_cell(display, "adjacent-number"))
table.insert(parts, blank_cell)
insert(parts, blank_cell)
return table.concat(parts)
return concat(parts)
end
end


Line 1,023: Line 1,038:


local function format_display_cell(display)
local function format_display_cell(display)
return format_cell(display, "smaller", "#dddddd")
return format_cell(display, "adjacent-number")
end
end


Line 1,030: Line 1,045:
prev_outer_display = has_outer_display and format_display_cell(prev_outer_display or "") or ""
prev_outer_display = has_outer_display and format_display_cell(prev_outer_display or "") or ""
next_outer_display = has_outer_display and format_display_cell(next_outer_display or "") or ""
next_outer_display = has_outer_display and format_display_cell(next_outer_display or "") or ""
cur_display = format_cell(cur_display, "larger", nil, nil, "bold")
cur_display = format_cell(cur_display, "current-number", nil, "bold")


local forms_display = ('| colspan="%s" style="text-align: center;" | %s\n'):format(
local forms_display = ('| colspan="%s" style="text-align: center;" | %s\n'):format(
has_outer_display and 5 or 3, table.concat(formatted_forms, "<br/>"))
has_outer_display and 5 or 3, concat(formatted_forms, "<br/>"))


local footer_display
local footer_display
Line 1,039: Line 1,054:
local footer =
local footer =
"[[w:" .. lang:getCode() .. ":Main Page|" .. lang:getCanonicalName() .. " Wikipedia]] article on " ..
"[[w:" .. lang:getCode() .. ":Main Page|" .. lang:getCanonicalName() .. " Wikipedia]] article on " ..
m_links.full_link({lang = lang, term = "w:" .. lang:getCode() .. ":" .. cur_data.wplink,
m_links.full_link{lang = lang, term = "w:" .. lang:getCode() .. ":" .. cur_data.wplink,
alt = export.format_number_for_display(cur_num)})
alt = export.format_number_for_display(cur_num)}
footer_display = '|- style="text-align: center;"\n' .. format_cell(footer, nil, "#dddddd", has_outer_display and 5 or 3)
footer_display = '|- style="text-align: center;"\n' .. format_cell(footer, "footer-cell", has_outer_display and 5 or 3)
else
else
footer_display = ""
footer_display = ""
Line 1,050: Line 1,065:
" edit]</span>)</sup>"
" edit]</span>)</sup>"


return [=[{| class="floatright" cellpadding="5" cellspacing="0" style="background: #ffffff; border: 1px #aaa solid; border-collapse: collapse; margin-top: .5em;" rules="all"
return [=[{| class="floatright number-box" cellpadding="5" cellspacing="0" style="background: var(--wikt-palette-white, #ffffff); color: inherit; border: 1px #aaa solid; border-collapse: collapse; margin-top: .5em;" rules="all"
|+ ''']=] .. title .. edit_link .. "'''\n" ..
|+ ''']=] .. title .. edit_link .. "'''\n" ..
upper_display .. '|- style="text-align: center;"\n' ..
upper_display .. '|- style="text-align: center;"\n' ..
prev_outer_display .. prev_display .. cur_display .. next_display .. next_outer_display .. "|-\n" ..
prev_outer_display .. prev_display .. cur_display .. next_display .. next_outer_display .. "|-\n" ..
lower_display .. "|-\n" ..
lower_display .. "|-\n" ..
forms_display .. footer_display .. "|}"
forms_display .. footer_display .. "|}" ..
end
require("Module:TemplateStyles")("Template:number box/styles.css")
 
 
-- Assumes string or nil (or false), the types that can be found in an args table.
local function if_not_empty(val)
if val and mw.text.trim(val) == "" then
return nil
else
return val
end
end
end


Line 1,073: Line 1,079:
local num_type = frame.args["type"]
local num_type = frame.args["type"]


local args = {}
local args = require("Module:parameters").process(frame:getParent().args, {
--cloning parent's args while also assigning nil to empty strings
[1] = {required = true, type = "language", default = "und"},
for pname, param in pairs(frame:getParent().args) do
sc = {type = "script"},
args[pname] = if_not_empty(param)
headlink = true,
end
wplink = true,
alt = true,
tr = true,
[2] = true, -- prev_symbol
[3] = true, -- cur_symbol
[4] = true, -- next_symbol
[5] = true, -- prev_term
[6] = true, -- next_term
card = true, cardalt = true, cardtr = true,
ord = true, ordalt = true, ordtr = true,
adv = true, advalt = true, advtr = true,
mult = true, multalt = true, multtr = true,
dis = true, disalt = true, distr = true,
coll = true, collalt = true, colltr = true,
frac = true, fracalt = true, fractr = true,
opt = true, optx = true, optxalt = true, optxtr = true,
opt2 = true, opt2x = true, opt2xalt = true, opt2xtr = true,
})
 
local lang = args[1]
local sc = args.sc
local headlink = args.headlink
local wplink = args.wplink
local alt = args.alt
local tr = args.tr


local lang = args[1] or (mw.title.getCurrentTitle().nsText == "Template" and "und") or error("Language code has not been specified. Please pass parameter 1 to the template.")
local prev_symbol = args[2]
local sc = args["sc"];
local cur_symbol = args[3]
local headlink = args["headlink"]
local next_symbol = args[4]
local wplink = args["wplink"]
local alt = args["alt"]
local tr = args["tr"]


local prev_symbol = if_not_empty(args[2])
local prev_term = args[5]
local cur_symbol = if_not_empty(args[3]);
local next_term = args[6]
local next_symbol = if_not_empty(args[4])


local prev_term = if_not_empty(args[5])
local cardinal_term = args.card; local cardinal_alt = args.cardalt; local cardinal_tr = args.cardtr
local next_term = if_not_empty(args[6])


local cardinal_term = args["card"]; local cardinal_alt = args["cardalt"]; local cardinal_tr = args["cardtr"]
local ordinal_term = args.ord; local ordinal_alt = args.ordalt; local ordinal_tr = args.ordtr


local ordinal_term = args["ord"]; local ordinal_alt = args["ordalt"]; local ordinal_tr = args["ordtr"]
local adverbial_term = args.adv; local adverbial_alt = args.advalt; local adverbial_tr = args.advtr


local adverbial_term = args["adv"]; local adverbial_alt = args["advalt"]; local adverbial_tr = args["advtr"]
local multiplier_term = args.mult; local multiplier_alt = args.multalt; local multiplier_tr = args.multtr


local multiplier_term = args["mult"]; local multiplier_alt = args["multalt"]; local multiplier_tr = args["multtr"]
local distributive_term = args.dis; local distributive_alt = args.disalt; local distributive_tr = args.distr


local distributive_term = args["dis"]; local distributive_alt = args["disalt"]; local distributive_tr = args["distr"]
local collective_term = args.coll; local collective_alt = args.collalt; local collective_tr = args.colltr


local collective_term = args["coll"]; local collective_alt = args["collalt"]; local collective_tr = args["colltr"]
local fractional_term = args.frac; local fractional_alt = args.fracalt; local fractional_tr = args.fractr


local fractional_term = args["frac"]; local fractional_alt = args["fracalt"]; local fractional_tr = args["fractr"]
local optional1_title = args.opt
local optional1_term = args.optx; local optional1_alt = args.optxalt; local optional1_tr = args.optxtr


local optional1_title = args["opt"]
local optional2_title = args.opt2
local optional1_term = args["optx"]; local optional1_alt = args["optxalt"]; local optional1_tr = args["optxtr"]
local optional2_term = args.opt2x; local optional2_alt = args.opt2xalt; local optional2_tr = args.opt2xtr


local optional2_title = args["opt2"]
track(lang:getCode())
local optional2_term = args["opt2x"]; local optional2_alt = args["opt2xalt"]; local optional2_tr = args["opt2xtr"]


if sc then
track("sc")
end


lang = require("Module:languages").getByCode(lang) or error("The language code \"" .. lang .. "\" is not valid.")
if headlink then
sc = (sc and (require("Module:scripts").getByCode(sc) or error("The script code \"" .. sc .. "\" is not valid.")) or nil)
track("headlink")
end
 
if wplink then
track("wplink")
end
 
if alt then
track("alt")
end
 
if cardinal_alt or ordinal_alt or adverbial_alt or multiplier_alt or distributive_alt or collective_alt or fractional_alt or optional1_alt or optional2_alt then
track("xalt")
end


local subpage = mw.title.getCurrentTitle().subpageText
local subpage = mw.title.getCurrentTitle().subpageText
local is_reconstructed = lang:hasType("reconstructed") or mw.title.getCurrentTitle().nsText == "Reconstruction"
local is_reconstructed = lang:hasType("reconstructed") or mw.title.getCurrentTitle().nsText == "Reconstruction"
alt = alt or (is_reconstructed and "*" or "") .. subpage
-- Commenting out this line prevents passing redundant alts to full_link;
-- however, there may have been a purpose to it.
-- alt = alt or (is_reconstructed and "*" or "") .. subpage


if num_type == "cardinal" then
if num_type == "cardinal" then
cardinal_term = (is_reconstructed and "*" or "") .. subpage
cardinal_term = cardinal_term or (is_reconstructed and "*" or "") .. subpage
cardinal_alt = alt
cardinal_alt = cardinal_alt or alt
cardinal_tr = tr
cardinal_tr = cardinal_tr or tr
elseif num_type == "ordinal" then
elseif num_type == "ordinal" then
ordinal_term = (is_reconstructed and "*" or "") .. subpage
ordinal_term = ordinal_term or (is_reconstructed and "*" or "") .. subpage
ordinal_alt = alt
ordinal_alt = ordinal_alt or alt
ordinal_tr = tr
ordinal_tr = ordinal_tr or tr
end
end


Line 1,140: Line 1,184:


if prev_term or prev_symbol then
if prev_term or prev_symbol then
previous = m_links.full_link({lang = lang, sc = sc, term = prev_term, alt = "&nbsp;&lt;&nbsp;&nbsp;" .. prev_symbol, tr = "-"})
previous = m_links.full_link{lang = lang, sc = sc, term = prev_term, alt = "&nbsp;&lt;&nbsp;&nbsp;" .. prev_symbol, tr = "-", no_alt_ast = true}
end
end


local current = m_links.full_link({lang = lang, sc = sc, alt = cur_symbol, tr = "-"})
local current = m_links.full_link{lang = lang, sc = sc, alt = cur_symbol, tr = "-", no_alt_ast = true}


local next = ""
local next = ""


if next_term or next_symbol then
if next_term or next_symbol then
next = m_links.full_link({lang = lang, sc = sc, term = next_term, alt = next_symbol .. "&nbsp;&nbsp;&gt;&nbsp;", tr = "-"})
next = m_links.full_link{lang = lang, sc = sc, term = next_term, alt = next_symbol .. "&nbsp;&nbsp;&gt;&nbsp;", tr = "-", no_alt_ast = true}
end
end


Line 1,154: Line 1,198:


if cardinal_term then
if cardinal_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:cardinal number|Cardinal]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = cardinal_term, alt = cardinal_alt, tr = cardinal_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[cardinal number|Cardinal]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = cardinal_term, alt = cardinal_alt, tr = cardinal_tr})
end
end


if ordinal_term then
if ordinal_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:ordinal number|Ordinal]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = ordinal_term, alt = ordinal_alt, tr = ordinal_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[ordinal number|Ordinal]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = ordinal_term, alt = ordinal_alt, tr = ordinal_tr})
end
end


if adverbial_term then
if adverbial_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:adverbial number|Adverbial]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = adverbial_term, alt = adverbial_alt, tr = adverbial_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[adverbial number|Adverbial]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = adverbial_term, alt = adverbial_alt, tr = adverbial_tr})
end
end


if multiplier_term then
if multiplier_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:multiplier|Multiplier]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = multiplier_term, alt = multiplier_alt, tr = multiplier_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[multiplier|Multiplier]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = multiplier_term, alt = multiplier_alt, tr = multiplier_tr})
end
end


if distributive_term then
if distributive_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:distributive number|Distributive]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = distributive_term, alt = distributive_alt, tr = distributive_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[distributive number|Distributive]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = distributive_term, alt = distributive_alt, tr = distributive_tr})
end
end


if collective_term then
if collective_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:collective number|Collective]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = collective_term, alt = collective_alt, tr = collective_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[collective number|Collective]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = collective_term, alt = collective_alt, tr = collective_tr})
end
end


if fractional_term then
if fractional_term then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''[[wikt:fractional|Fractional]]'' : " .. m_links.full_link({lang = lang, sc = sc, term = fractional_term, alt = fractional_alt, tr = fractional_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''[[fractional|Fractional]]'' : " .. m_links.full_link{lang = lang, sc = sc, term = fractional_term, alt = fractional_alt, tr = fractional_tr})
end
end


if optional1_title then
if optional1_title then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''" .. optional1_title .. "'' : " .. m_links.full_link({lang = lang, sc = sc, term = optional1_term, alt = optional1_alt, tr = optional1_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''" .. optional1_title .. "'' : " .. m_links.full_link{lang = lang, sc = sc, term = optional1_term, alt = optional1_alt, tr = optional1_tr})
end
end


if optional2_title then
if optional2_title then
table.insert(forms, " &nbsp;&nbsp;&nbsp; ''" .. optional2_title .. "'' : " .. m_links.full_link({lang = lang, sc = sc, term = optional2_term, alt = optional2_alt, tr = optional2_tr}))
insert(forms, " &nbsp;&nbsp;&nbsp; ''" .. optional2_title .. "'' : " .. m_links.full_link{lang = lang, sc = sc, term = optional2_term, alt = optional2_alt, tr = optional2_tr})
end
end


Line 1,194: Line 1,238:
footer =
footer =
"[[w:" .. lang:getCode() .. ":Main Page|" .. lang:getCanonicalName() .. " Wikipedia]] article on " ..
"[[w:" .. lang:getCode() .. ":Main Page|" .. lang:getCanonicalName() .. " Wikipedia]] article on " ..
m_links.full_link({lang = lang, sc = sc, term = "w:" .. lang:getCode() .. ":" .. wplink, alt = alt, tr = tr})
m_links.full_link{lang = lang, sc = sc, term = "w:" .. lang:getCode() .. ":" .. wplink, alt = alt, tr = tr}
end
end


return [=[{| class="floatright" cellpadding="5" cellspacing="0" style="background: #ffffff; border: 1px #aaa solid; border-collapse: collapse; margin-top: .5em;" rules="all"
return [=[{| class="floatright number-box" cellpadding="5" cellspacing="0" rules="all"
|+ ''']=] .. header .. [=['''
|+ ''']=] .. header .. [=['''
|-
|-
| style="width: 64px; background:#dddddd; text-align: center; font-size:smaller;" | ]=] .. previous .. [=[
| class="adjacent-slot" | ]=] .. previous .. [=[


! style="width: 98px; text-align: center; font-size:larger;" | ]=] .. current .. [=[
! class="current-slot" | ]=] .. current .. [=[


| style="width: 64px; text-align: center; background:#dddddd; font-size:smaller;" | ]=] .. next .. [=[
| class="adjacent-slot" | ]=] .. next .. [=[


|-
|-
| colspan="3" style="text-align: center;" | ]=] .. table.concat(forms, "<br/>") .. [=[
| colspan="3" class="form-slot" | ]=] .. concat(forms, "<br/>") .. [=[


|-
|-
| colspan="3" style="text-align: center; background: #dddddd;" | ]=] .. footer .. [=[
| colspan="3" class="footer-slot" | ]=] .. footer .. [=[


|}]=]
|}]=] .. require("Module:TemplateStyles")("Template:number box/styles.css")
end
end


return export
return export