Module:Romaniser

From Feed The Beast Wiki
Jump to: navigation, search

Documentation for this module may be created at Module:Romaniser/doc

--Big roman numberals have lines over them
local function overline(s)
	return mw.ustring.format("<span style=\"text-decoration:overline;\">%s</span>", s)
end

-- Gets the Roman numerals for a given numeral table.
local function getLetters(num, t)
	local ret = {}
	for _, v in ipairs(t) do
		local val, letter = unpack(v)
		while num >= val do
			num = num - val
			table.insert(ret, letter)
		end
	end
	return table.concat(ret), num
end

local function main(f)
	local args = f.args or f
	if f == mw.getCurrentFrame() and args[1] == nil then
		args = f:getParent().args
	else
		f = mw.getCurrentFrame()
	end
	
	if args == nil or args == {} then 
		return
	else
		if type(args[1]) == "string" then
			args[1] = mw.ext.ParserFunctions.expr(args[1])
		end
	end
	
	if args[1] == nil then return end
	
	local num = tonumber(args[1])
	if not num or num < 0 or num == math.huge then
		error('Invalid number ' .. args[1], 2)
	elseif num == 0 then
		return 'N'
	end
	
	-- Return a message for numbers too big to be expressed in Roman numerals.
	if num >= 5000000 then
		return args[2] or 'N/A'
	end
	
	local ret = ""
	
	if num >= 4000 then
		local bigLetters
		bigLetters, num = getLetters(num, {{1000000, 'M'},
											{900000, 'CM'}, {500000, 'D'}, {400000, 'CD'}, {100000, 'C'},
											{90000, 'XC'}, {50000, 'L'}, {40000, 'XL'}, {10000, 'X'},
											{9000, 'IX'}, {5000, 'V'}, {4000, 'IV'}})
		ret = overline(bigLetters)
	end
	
	-- Find the Roman numerals for numbers less than the big Roman threshold.
	local smallLetters = getLetters(num, {{1000, 'M'},
										{900, 'CM'}, {500, 'D'}, {400, 'CD'}, {100, 'C'},
										{90, 'XC'}, {50, 'L'}, {40, 'XL'}, {10, 'X'},
										{9, 'IX'}, {5, 'V'}, {4, 'IV'}, {1, 'I'}})
	
	return ret .. smallLetters
end

return {convert=main}