Module:Ordinal

From Xenharmonic Wiki
Jump to navigation Jump to search

Documentation transcluded from /doc
Note: Do not invoke this module directly; use the corresponding template instead: Template:Ordinal.
Icon-Todo.png Todo: Documentation

--[[
	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.
]]

local p = {}

--[[
	This function converts an integer value into a numeral followed by ordinal indicator.
	The output string might contain HTML tags.

	Usage:
	{{#invoke:Ordinal|ordinal|1=|2=}}
	{{#invoke:Ordinal|ordinal}} - uses the caller's parameters

	Parameters
	    1: Any number or string.
	    2: Set to "d" if the module should display "d" instead of "nd" and "rd".
]]
function p.ordinal(frame)
	local args = frame.args
	if args[1] == nil then
		args = frame:getParent().args
	end
	if args[1] == nil then
		args[1] = "{{{1}}}"
	end
	return p._ordinal(args[1], (args[2] == "d"))
end

function p._ordinal(n, d)
	local x = tonumber(mw.ustring.match(n, "(%d*)%W*$"))
	local suffix = "th"
	-- If tonumber(n) worked:
	if x then
		local mod10 = math.abs(x) % 10
		local mod100 = math.abs(x) % 100
		if mod10 == 1 and mod100 ~= 11 then
			suffix = "st"
		elseif mod10 == 2 and mod100 ~= 12 then
			if d then
				suffix = "d"
			else
				suffix = "nd"
			end
		elseif mod10 == 3 and mod100 ~= 13 then
			if d then
				suffix = "d"
			else
				suffix = "rd"
			end
		end
	end
	return n .. suffix
end

return p