Jump to content
Toggle menu
  • 8 articles
  • 75 files
  • 7 users
  • 37.8K edits
Neodyland Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Ordinal: Difference between revisions

From Neodyland Wiki
m fix debug reporting
eliminate need for Module:Roman
 
(31 intermediate revisions by 6 users not shown)
Line 10: Line 10:
   
   
]]
]]
local p = {}
   
   
-- =======================================
-- =======================================
-- === Dependencies ======================
-- === Dependencies ======================
-- =======================================
-- =======================================
local i18n = require('Module:I18n/ordinal') -- get localized translations of ordinals
local i18n       = require('Module:I18n/ordinal')       -- get localized translations of ordinals
local fallback = require('Module:Fallback') -- get fallback functions
local yesno     = require('Module:Yesno')               -- boolean value interpretation
local yesno = require('Module:Yesno') -- boolean value interpretation
local formatnum = require('Module:Formatnum')           -- number formatting
local formatnum = require('Module:Formatnum') -- number formatting
 
local roman = require('Module:Roman') -- roman numeral conversion (primarily for French)
-- =======================================
-- === Private Functions =================
-- =======================================
 
------------------------------------------------------------------------------
-- code equivalent to https://commons.wikimedia.org/wiki/Template:LangSwitch
 
local function langSwitch(list,lang)
local langList = mw.language.getFallbacksFor(lang)
table.insert(langList,1,lang)
table.insert(langList,math.max(#langList,2),'default')
for i,language in ipairs(langList) do
if list[language] then
return list[language]
end
end
return nil
end


--[[
--[[
Ordinal
Helper function to generate superscripted content
This function converts an integer value into a numeral followed by ordinal indicator.  The output string might
contain HTML tags unless you set nosup=y.
Usage:
{{#invoke:Ordinal|Ordinal|1=|style=|gender=|lang=|nosup=|debug=
Parameters
    1: Positive integer number.
    style: Presentation style. Different options for different languages. In English there is "style=d" adding -d suffixes to all numbers.
    gender: Gender is used in French and Polish language versions. Genders: m for male, f for female and n for neuter.
    lang: language
    nosup: Set nosup=y to display the ordinals without superscript.
    debug: Set debug=y to output error messages.
   
Error Handling:
  Unless debug=y, any error results in parameter 1 being echoed to the output.  This reproduces the behavior of the original Ordinal template.
]]
]]
function p.Ordinal( frame )
local function Superscript( str, superscript, nosup, period )
-- if no argument provided than check parent template/module args
if superscript and (not nosup) and (str ~= '') then
local args = frame.args
return period .. '<sup>' .. str .. '</sup>'
if args[1]==nil then
else
args = frame:getParent().args
return str
end
end
end
--[[
This function returns a string containing the input value formatted as a Roman numeral. 
It works for values between 0 and 3999.
]]
local function Roman(value)
local d0, d1, d2, d3, i0, i1, i2, i3
d0 = { [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' }
    d1 = { [0] = '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC' }
    d2 = { [0] = '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM' }
    d3 = { [0] = '', 'M', 'MM', 'MMM'}
local result = ''
--  if we don't have a specified language, attempt to use the user's language
if ((value >= 0) and (value < 4000)) then
local lang = args.lang
i3 = math.floor(value / 1e3) 
if not lang or lang == '' or not mw.language.isValidCode( lang ) then
i2 = math.floor(value / 1e2) % 10
lang = frame:preprocess('{{int:lang}}')
i1 = math.floor(value / 1e1) % 10
i0 = math.floor(value / 1e0) % 10
result = d3[i3] .. d2[i2] .. d1[i1] .. d0[i0]
end
end
 
-- set debug, defaulting to false
return result
local debug = yesno(args["debug"], false)
end
local input = args[1]
local output = input
--[[
if input then
Helper function to call Formatnum.
local value = tonumber(input)
]]
if value and (value > 0) then
local function FormatNum( value, lang )
output = p._Ordinal(
if lang == 'roman' then
value,  -- positive integer number
return Roman(value)
args["style"] or '', -- allows to set presentation style
args["gender"] or '', -- allows to specify gender (m, f, or n)
args["lang"], -- language
yesno(args["nosup"], false) -- set nosup to "y" to suppress superscripts
)
else
if debug then
output = p._error( "not a number", input )
end
end
else
else
if debug then
return formatnum.formatNum(value, lang)
output = p._error( "not a number", '' )
end
end
end
end
return output
--[[
Helper function to add append a category to a message.
]]
local function output_cat( message, category )
    return message .. '[[Category:' .. category .. ']]'
end
end


--[[
Helper function to handle error messages.
]]
local function output_error( error_str, value )
error_str = '<strong class="error"><span title="Error: ' .. error_str .. '">' .. value .. '</span></strong>'
    return output_cat(error_str, 'Errors reported by Module Ordinal');
end


--[[
--[[
This function will add the appropriate ordinal suffix to a given integer.
This function is the core functionality for adding the appropriate ordinal suffix to a given integer.
]]
]]
function p._Ordinal( value, style, gender, lang, nosup )
local function OrdinalCore( value, lang, style, gender, nosup )
 
-- Normalize style & gender; 'roman year' is an alias for 'roman'
style = string.lower(style)
if style == 'roman year' then
style = 'roman'
end
gender = string.lower(gender)
-- if no language is specified, default to english (caller might want to get user's language)
if not lang or lang == '' then
lang = 'en';
end
 
-- Just in case someone breaks the internationalization code, fix the english scheme
-- Just in case someone breaks the internationalization code, fix the english scheme
if i18n.SchemeFromLang['en'] == nil then
if i18n.SchemeFromLang['en'] == nil then
Line 116: Line 116:
i18n.Scheme['period-scheme'] = {rules = 'suffix', suffix = '.'}
i18n.Scheme['period-scheme'] = {rules = 'suffix', suffix = '.'}
end
end
-- which scheme should we use to format the ordinal value?  
-- which scheme should we use to format the ordinal value?  
-- Use Fallback module to handle languages groups that map to a supported language
-- Use Fallback module to handle languages groups that map to a supported language
local schemeSpecifier = fallback._langSwitch(i18n.SchemeFromLang, lang)
local schemeSpecifier = langSwitch(i18n.SchemeFromLang, lang)
-- Look up scheme based on scheme specifier (and possibly style)
-- Look up scheme based on scheme specifier (and possibly style)
Line 137: Line 137:
suffix = scheme['suffix_'..mod10] or scheme.suffix or ''
suffix = scheme['suffix_'..mod10] or scheme.suffix or ''
end
end
output = p._FormatNum(value, scheme.formatlang or lang) .. p._Superscript( suffix, scheme.superscript, nosup, period)
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'suffix' then
elseif rules == 'suffix' then
output = p._FormatNum(value, scheme.formatlang or lang) .. p._Superscript( scheme.suffix or '', scheme.superscript, nosup, period)
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( scheme.suffix or '', scheme.superscript, nosup, period)
elseif rules == 'prefix' then
elseif rules == 'prefix' then
output = (scheme.prefix or '') .. p._FormatNum(value, scheme.formatlang or lang)
output = (scheme.prefix or '') .. FormatNum(value, scheme.formatlang or lang)
elseif rules == 'mod10-suffix' then
elseif rules == 'mod10-suffix' then
local index = math.floor(math.abs(value)) % 10
local index = math.floor(math.abs(value)) % 10
local suffix = scheme['suffix_'..index] or scheme.suffix or ''
local suffix = scheme['suffix_'..index] or scheme.suffix or ''
output = p._FormatNum(value, scheme.formatlang or lang) .. p._Superscript( suffix, scheme.superscript, nosup, period)
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'gendered-suffix' then
elseif rules == 'gendered-suffix' then
local suffix = scheme['suffix_'..gender] or scheme.suffix or ''
local suffix = scheme['suffix_'..gender] or scheme.suffix or ''
output = p._FormatNum(value, scheme.formatlang or lang) .. p._Superscript( suffix, scheme.superscript, nosup, period)
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'gendered-suffix-one' then
elseif rules == 'gendered-suffix-one' then
local suffix
local suffix
Line 156: Line 156:
suffix = scheme['suffix_'..gender] or scheme.suffix or ''
suffix = scheme['suffix_'..gender] or scheme.suffix or ''
end
end
output = p._FormatNum(value, scheme.formatlang or lang) .. p._Superscript( suffix, scheme.superscript, nosup, period)
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'pl' then
elseif rules == 'gendered-suffix-n' then
output = p._PolishOrdinal(value, gender)
local suffix
if value <= 9 then
suffix = scheme['suffix_'..value..'_'..gender] or scheme['suffix_'..value] or scheme['suffix_'..gender] or scheme.suffix or ''
else
suffix = scheme['suffix_'..gender] or scheme.suffix or ''
end
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'suffix-one' then
local prefix, suffix
if value == 1 then
prefix = scheme['prefix_1'] or scheme.prefix or ''
suffix = scheme['suffix_1'] or scheme.suffix or ''
else
prefix = scheme.prefix or ''
suffix = scheme.suffix or ''
end
output = prefix .. FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'mod10-gendered-suffix-skip-tens' then
local suffix
local mod100 = math.floor(math.abs(value)) % 100
if (mod100 >= 10) and (mod100 <= 19) then
suffix = scheme['suffix_'..gender] or scheme.suffix or ''
else
local mod10 = math.floor(math.abs(value)) % 10
suffix = scheme['suffix_'..mod10..'_'..gender] or scheme['suffix_'..mod10] or scheme['suffix_'..gender] or scheme.suffix or ''
end
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
elseif rules == 'uk-rules' then
local suffix
local mod100 = math.floor(math.abs(value)) % 100
local mod1000 = math.floor(math.abs(value)) % 1000
if (mod1000 == 0) then
suffix = scheme['suffix_1000_'..gender] or scheme.suffix or ''
elseif (mod100 == 40) then
suffix = scheme['suffix_40_'..gender] or scheme.suffix or ''
elseif (mod100 >= 10) and (mod100 <= 19) then
suffix = scheme['suffix_'..gender] or scheme.suffix or ''
else
local mod10 = math.floor(math.abs(value)) % 10
suffix = scheme['suffix_'..mod10..'_'..gender] or scheme['suffix_'..mod10] or scheme['suffix_'..gender] or scheme.suffix or ''
end
output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
else
else
output = p._FormatNum(value, lang)
output = FormatNum(value, lang)
end  
end  
Line 166: Line 207:
end
end


-- =======================================
-- === Public Functions ==================
-- =======================================


local p = {}
--[[
--[[
Helper function to generate Polish ordinals. Polish rules are more complex than most, so we
Ordinal
resort to a custom function for Polish ordinals rather than the centralized localization table.
This function converts an integer value into a numeral followed by ordinal indicator.  The output string might
contain HTML tags unless you set nosup=y.
Usage:
{{#invoke:Ordinal|Ordinal|1=|lang=|style=|gender=|nosup=|debug=}}
{{#invoke:Ordinal|Ordinal}} - uses the caller's parameters
Parameters
    1: Positive integer number.
    lang: language
    style: Presentation style. Different options for different languages. In English there is "style=d" adding -d suffixes to all numbers.
    gender: Gender is used in French and Polish language versions. Genders: m for male, f for female and n for neuter.
    nosup: Set nosup=y to display the ordinals without superscript.
    debug: Set debug=y to output error messages.
   
Error Handling:
  Unless debug=y, any error results in parameter 1 being echoed to the output.  This reproduces the behavior of the original Ordinal template.
]]
]]
function p._PolishOrdinal( value, gender )
function p.Ordinal( frame )
local suffix = ''
-- if no argument provided than check parent template/module args
local mod100 = math.floor(math.abs(value)) % 100
local args = frame.args
if (mod100 >= 10) and (mod100 <= 19) then
if args[1]==nil then
if gender == 'f' then
args = frame:getParent().args
suffix = 'ta'
end
elseif gender == 'n' then
suffix = 'te'
--  if we don't have a specified language, attempt to use the user's language
else
local lang = args.lang
suffix = 'ty'
if not lang or lang == '' or not mw.language.isValidCode( lang ) then
end
lang = frame:preprocess('{{int:lang}}')
else
end
local mod10 = math.floor(math.abs(value)) % 10
if (mod10 == 1) then
local nosup = yesno(args["nosup"] or '', false) -- nosup can be true or false
if gender == 'f' then
local debugging = yesno(args["debug"], false) -- debugging can be nil, true, or false
suffix = 'sza'
 
elseif gender == 'n' then
-- also enable debugging if debug is unspecified, and "nosup" is false
suffix = 'sze'
debugging = debugging or ((debugging == nil) and not nosup)
else
suffix = 'szy'
local output = p._Ordinal(
end
args[1],  -- positive integer number
elseif (mod10 == 2) then
lang, -- language
if gender == 'f' then
args["style"], -- allows to set presentation style
suffix = 'ga'
args["gender"], -- allows to specify gender (m, f, or n)
elseif gender == 'n' then
nosup, -- set nosup to "y" to suppress superscripts
suffix = 'gie'
debugging -- Set debug=y to output error messages
else
)
suffix = 'gi'
end
-- Add maintenance category
elseif (mod10 == 3) then
if (i18n.SchemeFromLang[lang] == nil) and debugging then  
if gender == 'f' then
output = output_cat(output, 'Pages with calls to Module Ordinal using an unsupported language')
suffix = 'cia'
elseif gender == 'n' then
suffix = 'cie'
else
suffix = 'ci'
end
elseif (mod10 == 7) or (mod10 == 8) then
if gender == 'f' then
suffix = 'ma'
elseif gender == 'n' then
suffix = 'me'
else
suffix = 'my'
end
else
if gender == 'f' then
suffix = 'ta'
elseif gender == 'n' then
suffix = 'te'
else
suffix = 'ty'
end
end
end
end
return p._FormatNum(value, 'pl') .. '-' .. suffix
return output
end
end




--[[
--[[
Helper function to generate superscripted content
This function will add the appropriate ordinal suffix to a given integer.
 
Parameters
input: Numeral as a positive integer or string.
lang: Language code as a string (e.g. 'en', 'de', etc.).
style: Presentation style as a string (e.g. 'd', 'roman', etc.).
gender: Gender as a string ('m', 'f', 'n').  Use empty string '' to leave gender unspecified.
nosup: Boolean, set to true to force the ordinals to display without superscript.
debug: Boolean, set to true to output error messages.
 
Error Handling:
  Unless debug is true, any error results in value being echoed to the output.
]]
]]
function p._Superscript( str, superscript, nosup, period )
function p._Ordinal( input, lang, style, gender, nosup, debugging )
if superscript and (not nosup) then
local output = input
return period .. '<sup>' .. str .. '</sup>'
else
if input then
return str
local value = tonumber(input)
end
if value and (value > 0) then
end
 
-- Normalize style, the style 'roman year' is an alias for 'roman'
style = string.lower(style or '')
if style == 'roman year' then
style = 'roman'
end
-- Normalize gender parameter
gender = string.lower(gender or '')
if (gender ~= 'm') and (gender ~= 'f') and (gender ~= 'n') then
gender = ''
end
--[[
-- if no language is specified, default to english (caller might want to get user's language)
Helper function to call Formatnum.  This really should be invoking Formatnum via the module directly, but
if not lang or lang == '' then
the Formatnum module doesn't currently have a Lua-friendly method, just a template method.
lang = 'en';
]]
end
function p._FormatNum( value, lang )
if lang == 'roman' then
output = OrdinalCore( value, lang, style, gender, nosup )
return roman._HTMLNumeral (value )
else
if debugging then
output = output_error( "not a number", input )
end
end
else
else
return mw.getCurrentFrame():expandTemplate({title = 'Template:Formatnum', args = {value, lang}})
if debugging then
output = output_error( "not a number", '' )
end
end
end
end
return output
 
--[[
Helper function to handle error messages.
]]
function p._error( error_str, value )
    return '<strong class="error"><span title="Error: ' .. error_str .. '">' .. value .. '</span></strong>';
end
end


return p
return p

Latest revision as of 02:40, 13 May 2022

Module documentation[ create · purge ]
This documentation is transcluded from Module:Ordinal/doc.
--[[  
 
This template will add the appropriate ordinal suffix to a given integer.
 
Please do not modify this code without applying the changes first at Module:Ordinal/sandbox and testing 
at Module:Ordinal/sandbox/testcases and Module talk:Ordinal/sandbox/testcases.
 
Authors and maintainers:
* User:RP88
 
]]
 
-- =======================================
-- === Dependencies ======================
-- =======================================
local i18n       = require('Module:I18n/ordinal')        -- get localized translations of ordinals
local yesno      = require('Module:Yesno')               -- boolean value interpretation
local formatnum  = require('Module:Formatnum')           -- number formatting

-- =======================================
-- === Private Functions =================
-- =======================================

------------------------------------------------------------------------------
-- code equivalent to https://commons.wikimedia.org/wiki/Template:LangSwitch

local function langSwitch(list,lang)
	local langList = mw.language.getFallbacksFor(lang)
	table.insert(langList,1,lang)
	table.insert(langList,math.max(#langList,2),'default')
	for i,language in ipairs(langList) do
		if list[language] then
			return list[language]
		end
	end
	return nil
end

--[[
Helper function to generate superscripted content
]]
local function Superscript( str, superscript, nosup, period )
	if superscript and (not nosup) and (str ~= '') then
		return period .. '<sup>' .. str .. '</sup>'
	else
		return str
	end
end

--[[
This function returns a string containing the input value formatted as a Roman numeral.  
It works for values between 0 and 3999. 
]]
local function Roman(value)
	local d0, d1, d2, d3, i0, i1, i2, i3
	d0 = { [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' }
    d1 = { [0] = '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC' }
    d2 = { [0] = '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM' }
    d3 = { [0] = '', 'M', 'MM', 'MMM'}
	local result = ''
	
	if ((value >= 0) and (value < 4000)) then
		i3 = math.floor(value / 1e3)  
		i2 = math.floor(value / 1e2) % 10
		i1 = math.floor(value / 1e1) % 10
		i0 = math.floor(value / 1e0) % 10 
		result = d3[i3] .. d2[i2] .. d1[i1] .. d0[i0]
	end
	
	return result
end
	
--[[
Helper function to call Formatnum.
]]
local function FormatNum( value, lang )
	if lang == 'roman' then
		return Roman(value)
	else
		return formatnum.formatNum(value, lang)
	end
end
	
--[[
Helper function to add append a category to a message.
]]
local function output_cat( message, category )
    return message .. '[[Category:' .. category .. ']]'
end

--[[
Helper function to handle error messages.
]]
local function output_error( error_str, value )
	error_str = '<strong class="error"><span title="Error: ' .. error_str .. '">' .. value .. '</span></strong>'
    return output_cat(error_str, 'Errors reported by Module Ordinal');
end

--[[
This function is the core functionality for adding the appropriate ordinal suffix to a given integer.
]]
local function OrdinalCore( value, lang, style, gender, nosup )	
	-- Just in case someone breaks the internationalization code, fix the english scheme
	if i18n.SchemeFromLang['en'] == nil then
		i18n.SchemeFromLang['en'] = 'en-scheme'
	end	
	if i18n.Scheme['en-scheme'] == nil then
		i18n.Scheme['en-scheme'] = {rules = 'skip-tens', superscript = true, suffix = 'th', suffix_1 = 'st', suffix_2 = 'nd', suffix_3 = 'rd'}
	end
	
	-- Add the default scheme (i.e. "<value>.")
	if i18n.SchemeFromLang['default'] == nil then
		i18n.SchemeFromLang['default'] = 'period-scheme'
	end	
	if i18n.Scheme['period-scheme'] == nil then
		i18n.Scheme['period-scheme'] = {rules = 'suffix', suffix = '.'}
	end
		
	-- which scheme should we use to format the ordinal value? 
	-- Use Fallback module to handle languages groups that map to a supported language
	local schemeSpecifier = langSwitch(i18n.SchemeFromLang, lang)
	
	-- Look up scheme based on scheme specifier (and possibly style)
	local scheme = i18n.Scheme[schemeSpecifier .. '/' .. style] or i18n.Scheme[schemeSpecifier]
	
	-- process scheme by applying rules identified by Scheme
	local output = ''
	local period = (scheme.period and '.') or ''
	local rules = scheme.rules
	if rules == 'skip-tens' then
		local suffix
		local mod100 = math.floor(math.abs(value)) % 100
		if (mod100 >= 10) and (mod100 <= 19) then
			suffix = scheme.suffix or ''
		else
			local mod10 = math.floor(math.abs(value)) % 10
			suffix = scheme['suffix_'..mod10] or scheme.suffix or ''
		end
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'suffix' then
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( scheme.suffix or '', scheme.superscript, nosup, period)
	elseif rules == 'prefix' then
		output = (scheme.prefix or '') .. FormatNum(value, scheme.formatlang or lang)
	elseif rules == 'mod10-suffix' then
		local index = math.floor(math.abs(value)) % 10
		local suffix = scheme['suffix_'..index] or scheme.suffix or ''
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'gendered-suffix' then
		local suffix = scheme['suffix_'..gender] or scheme.suffix or ''
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'gendered-suffix-one' then
		local suffix
		if value == 1 then
			suffix = scheme['suffix_1_'..gender] or scheme['suffix_1'] or scheme.suffix or ''
		else
			suffix = scheme['suffix_'..gender] or scheme.suffix or ''
		end
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'gendered-suffix-n' then
		local suffix
		if value <= 9 then
			suffix = scheme['suffix_'..value..'_'..gender] or scheme['suffix_'..value] or scheme['suffix_'..gender] or scheme.suffix or ''
		else
			suffix = scheme['suffix_'..gender] or scheme.suffix or ''
		end
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'suffix-one' then
		local prefix, suffix
		if value == 1 then
			prefix = scheme['prefix_1'] or scheme.prefix or ''
			suffix = scheme['suffix_1'] or scheme.suffix or ''
		else
			prefix = scheme.prefix or ''
			suffix = scheme.suffix or ''
		end
		output = prefix .. FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'mod10-gendered-suffix-skip-tens' then
		local suffix
		local mod100 = math.floor(math.abs(value)) % 100
		if (mod100 >= 10) and (mod100 <= 19) then
			suffix = scheme['suffix_'..gender] or scheme.suffix or ''
		else
			local mod10 = math.floor(math.abs(value)) % 10
			suffix = scheme['suffix_'..mod10..'_'..gender] or scheme['suffix_'..mod10] or scheme['suffix_'..gender] or scheme.suffix or ''
		end
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	elseif rules == 'uk-rules' then
		local suffix
		local mod100 = math.floor(math.abs(value)) % 100
		local mod1000 = math.floor(math.abs(value)) % 1000
		if (mod1000 == 0) then
			suffix = scheme['suffix_1000_'..gender] or scheme.suffix or ''
		elseif (mod100 == 40) then
			suffix = scheme['suffix_40_'..gender] or scheme.suffix or ''
		elseif (mod100 >= 10) and (mod100 <= 19) then
			suffix = scheme['suffix_'..gender] or scheme.suffix or ''
		else
			local mod10 = math.floor(math.abs(value)) % 10
			suffix = scheme['suffix_'..mod10..'_'..gender] or scheme['suffix_'..mod10] or scheme['suffix_'..gender] or scheme.suffix or ''
		end
		output = FormatNum(value, scheme.formatlang or lang) .. Superscript( suffix, scheme.superscript, nosup, period)
	else
		output = FormatNum(value, lang)
	end 
	
	return output
end

-- =======================================
-- === Public Functions ==================
-- =======================================

local p = {}
--[[
Ordinal
 
This function converts an integer value into a numeral followed by ordinal indicator.  The output string might 
contain HTML tags unless you set nosup=y.
 
Usage:
{{#invoke:Ordinal|Ordinal|1=|lang=|style=|gender=|nosup=|debug=}}
{{#invoke:Ordinal|Ordinal}} - uses the caller's parameters
 
Parameters
    1: Positive integer number. 
    lang: language
    style: Presentation style. Different options for different languages. In English there is "style=d" adding -d suffixes to all numbers.
    gender: Gender is used in French and Polish language versions. Genders: m for male, f for female and n for neuter.	
    nosup: Set nosup=y to display the ordinals without superscript.
    debug: Set debug=y to output error messages.
    
Error Handling:
   Unless debug=y, any error results in parameter 1 being echoed to the output.  This reproduces the behavior of the original Ordinal template.
]]
function p.Ordinal( frame )
	-- if no argument provided than check parent template/module args
	local args = frame.args
	if args[1]==nil then
		args = frame:getParent().args 
	end
	
	--  if we don't have a specified language, attempt to use the user's language
	local lang = args.lang
	if not lang or lang == '' or not mw.language.isValidCode( lang ) then
		lang = frame:preprocess('{{int:lang}}')
	end
	
	local nosup = yesno(args["nosup"] or '', false) -- nosup can be true or false
	local debugging = yesno(args["debug"], false) -- debugging can be nil, true, or false

	-- also enable debugging if debug is unspecified, and "nosup" is false
	debugging = debugging or ((debugging == nil) and not nosup)
		
	local output = p._Ordinal( 
		args[1],  					-- positive integer number
		lang,						-- language
		args["style"],				-- allows to set presentation style
		args["gender"], 			-- allows to specify gender (m, f, or n)
		nosup,						-- set nosup to "y" to suppress superscripts
		debugging					-- Set debug=y to output error messages
	)
	
	-- Add maintenance category
	if (i18n.SchemeFromLang[lang] == nil) and debugging then 
		output = output_cat(output, 'Pages with calls to Module Ordinal using an unsupported language')
	end
	
	return output
end


--[[
This function will add the appropriate ordinal suffix to a given integer. 

Parameters
	input: Numeral as a positive integer or string.
	lang: Language code as a string (e.g. 'en', 'de', etc.).
	style: Presentation style as a string (e.g. 'd', 'roman', etc.).
	gender: Gender as a string ('m', 'f', 'n').  Use empty string '' to leave gender unspecified.
	nosup: Boolean, set to true to force the ordinals to display without superscript.
	debug: Boolean, set to true to output error messages.

Error Handling:
   Unless debug is true, any error results in value being echoed to the output.
]]
function p._Ordinal( input, lang, style, gender, nosup, debugging )	
	local output = input
	
	if input then
		local value = tonumber(input)
		if value and (value > 0) then
		
			-- Normalize style, the style 'roman year' is an alias for 'roman'
			style = string.lower(style or '')
			if style == 'roman year' then
				style = 'roman'
			end
			
			-- Normalize gender parameter
			gender = string.lower(gender or '')
			if (gender ~= 'm') and (gender ~= 'f') and (gender ~= 'n') then
				gender = ''
			end
	
			-- if no language is specified, default to english (caller might want to get user's language)
			if not lang or lang == '' then
				lang = 'en';
			end
			
			output = OrdinalCore( value, lang, style, gender, nosup )
		else
			if debugging then
				output = output_error( "not a number", input )
			end
		end
	else
		if debugging then
			output = output_error( "not a number", '' )
		end
	end
		
	return output
end

return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.