Módulo:Roman

Fonte: Enciclopédia de conhecimento da Igreja de Deus
Saltar para a navegação Saltar para a pesquisa

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

-- Este módulo implementa {{Roman}}.
require[[strict]]
local p = {}
-- Esta função implementa, internamente, a predefinição {{Sobrelinhado}}.
local function overline(s)
				return mw.ustring.format( '<span style="text-decoration:overline;">%s</span>', s )
end
-- Obtém os numerais romanos para uma determinada tabela numeral. Retorna tanto
-- a sequência ('string') de numerais e o valor do número depois que ele 
-- terminar de 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
-- O fluxo de controle principal do módulo.
local function _main(args)
				-- Obtém a entrada e sai sem exibir nada se a entrada estiver vazia.
				if args[1] == nil then return end
				local num = tonumber(args[1])
				if not num or num < 0 or num == math.huge then
					error('Número inválido ' .. args[1], 2)
				elseif num == 0 then
								return 'N'
				end
				-- Retorna uma mensagem para números muito grandes para serem expressos 
				-- em algarismos romanos.
				if num >= 5000000 then
								return args[2] or 'N/A'
				end
				local ret = ''
				-- Encontra os algarismos romanos para a maior parte dos números.
				-- 23 de abril de 2016 - ajustado para >= 4000 para aceitar o romano "IV" grande
				-- A instrução "if" não é estritamente necessária, mas torna o algoritmo 
				-- mais eficiente para números menores.
				if num >= 4000 then
								local bigRomans = {
												{ 1000000, 'M' },
												{ 900000, 'CM' }, { 500000, 'D' }, { 400000, 'CD' }, { 100000, 'C' },
												{  90000, 'XC' }, {  50000, 'L' }, {  40000, 'XL' }, {  10000, 'X' },
												{   9000, 'IX' }, {   5000, 'V' }, {   4000, 'IV' },
								}
								local bigLetters
								bigLetters, num = getLetters(num, bigRomans)
								ret = overline(bigLetters)
				end
				-- Encontra os numerais romanos para números menores que o limite romano grande.
				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
				if args.fraction == 'yes' then
								-- Encontra os numerais romanos para as partes fracionárias dos números.
								-- Se num não for um número inteiro, adiciona a metade de 1/1728 
								-- (a menor unidade) para igualar ao arredondamento.
								-- Certifica-se de que não somos menores que a menor unidade ou maiores 
								-- que 1 - a menor unidade para evitar obter dois símbolos "meio" 
								-- ou nenhum símbolo
								num = num - math.floor(num)
								if num ~= 0 then
												num = math.max(1.1/1728, math.min(1727.1/1728, num + 1/3456))
								end
								local fractionalRomans = {
												{ 1/2, 'S' }, { 5/12, "''':'''•''':'''" }, { 1/3, "'''::'''" },
												{ 1/4, "''':'''•" }, { 1/6, "''':'''" }, { 1/12, '•' },
												{ 1/24, 'Є' }, { 1/36, 'ƧƧ' }, { 1/48, 'Ɔ' }, { 1/72, 'Ƨ' }, { 1/144, '<s>Ƨ</s>' },
												{ 1/288, '℈' }, { 1/1728, '»' },
								}
								local fractionalLetters = getLetters(num, fractionalRomans)
								
								ret = ret .. fractionalLetters
				end
				return ret
end
function p.main(frame)
				-- Se chamado via "#invoke", usa os argumentos passados na chamada da
				-- predefinição, ou os argumentos passados para "#invoke" se existirem. 
				-- De outra forma assume que os argumentos estão sendo passados diretamente
				-- do console de depuração ou de outro módulo Lua.
				local origArgs
				if frame == mw.getCurrentFrame() then
								origArgs = frame:getParent().args
								for k, v in pairs(frame.args) do
												origArgs = frame.args
												break
								end
				else
								origArgs = frame
				end
				-- Corta os espaços em branco e remove os argumentos em branco.
				local args = {}
				for k, v in pairs(origArgs) do
								if type( v ) == 'string' then
												v = mw.text.trim(v)
								end
								if v ~= '' then
												args[k] = v
								end
				end
				
				-- Saída se não for dado nada.
				if args == nil or args == {} then return end
				-- Dada a expressão matemática, simplifica para um número.
				if type(args[1]) == 'string' then
								local success, result = pcall(mw.ext.ParserFunctions.expr, args[1])
								if success then
												args[1] = result
								end -- Caso não, passa para a rotina "_main" e tenta deixar a "tonumber"
												-- de Lua lidar com isso.
				end
				return _main(args)
end
return p