Módulo:Romano

A documentação para este módulo pode ser criada na página Módulo:Romano/doc

-- Este módulo implementa {{Romano}}.
local p = {}
-- barra horizontal {{sobrelinhado}} de nomes elevado.
local function sobrelinhado( s )
				return '<span style="text-decoration:overline">' .. s .. '</span>'
end
-- Obtem os números Romano de uma tabela númerica. Devolve ambos texto do
-- números e o valor do número depois dele ser processado.
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
function p.toRoman( num, default )
				num = tonumber( num )
				if not num or num < 1 or num == math.huge then
								return
				end
				num = math.floor( num )
		
				-- Return a message for numbers too big to be expressed in Roman numerals.
				if num >= 5000000 then
								return default or 'N/A'
				end
		
				local ret = ''
				-- Find the Roman numerals for the large part of numbers 5000 and bigger.
				-- The if statement is not strictly necessary, but makes the algorithm
				-- more efficient for smaller numbers.
				if num >= 5000 then
								local bigRomans = {
												{ 1000000, 'M' },
												{ 900000, 'CM' }, { 500000, 'D' }, { 400000, 'CD' }, { 100000, 'C' },
												{ 90000, 'XC' }, { 50000, 'L' }, { 40000, 'XL' }, { 10000, 'X' },
												{ 5000, 'V' }
								}
								local bigLetters
								bigLetters, num = getLetters( num, bigRomans )
								ret = sobrelinhado( bigLetters )
				end
		
				-- Find the Roman numerals for numbers 4999 or less.
				local smallRomans = {
								{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"}
				}
				local smallLetters = getLetters( num, smallRomans )
				ret = ret .. smallLetters
		
				return ret
end
function p.fromRoman( str, default )
				local strOrig = str
				str = str:upper()
				if not str:find( '^[MDCLXVI]+$' ) then
								return tonumber( str ) or default or strOrig
				end
				local smallRomans = { I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000 }
				local result = 0
				local old, n = 0
				for i = str:len(), 1, -1  do
								n = smallRomans[ str:sub( i, i ) ]
								if n < old then
												result = result - n
								else
												result = result + n
												old = n
								end
				end
				return result
end
-- compatibility with [[en:Module:Roman]]
function p._main(args)
				return p.toRoman( args[1] )
end
function p.main( frame )
				return p.nomeEmRomano( frame )
end
-- functions to call the module from a template (takes the #invoke first arg or the template first arg)
function p.nomeEmRomano( frame )
				local num
				if frame == mw.getCurrentFrame() then
								num = frame.args[1] or frame:getParent().args[1]
				else
								num = frame
				end
				return p.toRoman( mw.text.trim( num or '' ) )
end
function p.nomeDepoisRomano( frame )
				local str
				if frame == mw.getCurrentFrame() then
								str = frame.args[1] or frame:getParent().args[1]
				else
								str = frame
				end
				return p.fromRoman( mw.text.trim( str or '' ) )
end
		
return p