Mudanças entre as edições de "Módulo:Fmtn"

Origem: IRChelp Brasil - Wiki
Ir para navegação Ir para pesquisar
(Criação do Módulo Fmtn.)
 
(Sem diferença)

Edição atual tal como às 21h05min de 15 de dezembro de 2019

Este módulo contem código da predefinição {{Fmtn}}. Consulte a sua documentação para mais informações.

Categorias de manutênção

Este módulo atualmente implementa as seguintes categorias de manutênção:


local p = {}

-- Padrões de construção conhecidos, com uma transformação para que se torne
-- um padrão válido.
-- O padrão não precisa ser perfeito, pois ele é validado como número
-- após a transformação.  Então não há problemas se ele eventualmente puder
-- produzir números inválidos.  Há apenas de tomar o cuidado para que não
-- produza números incorretos.
-- Obs.: Observar que muitos REGEXes não são válidos em Lua.
--       Veja a documentação em:
--       https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
local padroes_conhecidos = {
    {   "^[%d,]*%.%d*$",     -- formato 1,123,123.123
        false,                 -- não necessita de revisão
        {
        	{ ",", "" },           -- remove vírgulas
        }
    },
    {   "^[%d.]*,%d*$",      -- formato 1.123.123,123 ou 1123123,123
        false,                 -- não marcar para revisão
        {
        	{ "%.", "" },          -- remove pontos
        	{ ",", "."},           -- substitui vírgula por ponto
        }
    },
    {	"^[%d%s]*[,.]%d*$",  -- formato 1 123 123,123 ou 1 123 123.123
        false,                 -- não marcar para revisão
        {
        	{ "%s", "" },          -- remove espaços
        	{ ",", "."},           -- substitui vírgula por ponto, se houver
        }
    },
    {   "^[%d,]*,%d%d%d$",   -- formato 1,123,123
        false,                 -- não marcar para revisão
        {
        	{ ",", "" },           -- remove vírgulas
        }
    },
	{   "^[%d.]*%.%d%d%d$",   -- formato 1.123.123 (três dígitos no último bloco)
        false,                  -- não marcar para revisão
        {
        	{ ",", "" },            -- remove pontos
        }
    },
    {   "^[%d,]*,%d%d%d$",   -- formato 1,123,123 (três dígitos no último bloco)
        false,                 -- não marcar para revisão
        {
        	{ ",", "" },           -- remove vírgulas
        }
    },
	{   "^[%d%s]*%s%d%d%d$", -- formato 1 123 123 (três dígitos no último bloco)
        false,                -- não marcar para revisão
        {
        	{ "%s", "" },         -- remove espaços
        }
    },
    {   "^[%d.]*%.%d%d$",   -- formato 1.123.12 (dois dígitos no último bloco)
        true,                 -- marcar para revisão
        {
        	{ ".", "" },          -- remove pontos
        	{ "(%d%d)$", ".%1" }, -- insere um ponto antes dos dois últimos dígitos
        }
    },
    {   "^[%d,]*,%d%d$",    -- formato 1,123,12 (dois dígitos no último bloco)
        true,                 -- marcar para revisão
        {
        	{ ",", "" },          -- remove vírgulas
        	{ "(%d%d)$", ".%1" }, -- insere um ponto antes dos dois últimos dígitos
        }
    },
    {   "^[%d%s]%s%d%d$",    -- formato 1 123 12 (dois dígitos no último bloco)
        true,                 -- marcar para revisão
        {
        	{ "%s", "" },          -- remove espaços
        	{ "(%d%d)$", ".%1" }, -- insere um ponto antes dos dois últimos dígitos
        }
    },
}

function p.fmtn(frame)
	local param1 = frame.args[1] or ""
	local param2 = frame.args[2] or ""
	local param3 = frame.args[3] or ""
	
	num1, isnumber1, needcheck1 = reconhece_numero(param1)
	num2, isnumber2, needcheck2 = reconhece_numero(param2)
	num3, isnumber3, needcheck3 = reconhece_numero(param3)
	
	isarticle = mw.title.getCurrentTitle().namespace == 0
	
	prefixo = ''
	sufixo = ''
	if isnumber1 and not isnumber2 and not isnumber3 then
		-- somente o primeiro número é válido
		mynum = num1
		needcheck = needcheck1
		if param2 ~= '' then sufixo = sufixo .. ' ' .. param2 end
		if param3 ~= '' then sufixo = sufixo .. ' ' .. param3 end
	elseif not isnumber1 and isnumber2 and not isnumber3 then
		-- somente o segundo número é válido
		mynum = num2
		needcheck = needcheck2
		if param1 ~= '' then prefixo = prefixo .. param1 .. ' ' end
		if param3 ~= '' then sufixo = sufixo .. ' ' .. param3 end
	elseif not isnumber1 and not isnumber2 and isnumber3 then
		-- somente o terceiro número é válido
		mynum = num3
		needcheck = needcheck3
		if param1 ~= '' then prefixo = prefixo .. param1 .. ' ' end
		if param2 ~= '' then prefixo = prefixo .. param2 .. ' ' end
	else
		-- ERRO: existem mais de dois números válidos, ou nenhum é válido
		-- Nesse caso, faz o que já era feito antes, tenta formatar da forma
		-- que for possível e retorna os parâmetros na ordem que foram
		-- apresentados
		
		-- Aqui usa-se o "callParserFunction" para copiar o comportamento que já
		-- era presenciado antes desse módulo existir e evitar que erros sejam
		-- impressos nos artigos
		res = ''
		if param1 ~= '' then
			res = res .. formatnum(param1)
		end
		if param2 ~= '' then
			if res ~= '' then res = res .. ' ' end
			res = res .. formatnum(param2)
		end
		if param3 ~= '' then
			if res ~= '' then res = res .. ' ' end
			res = res .. formatnum(param3)
		end
		if isarticle then
			res = res .. '[[Categoria:!Páginas com erro de uso da predefinição Fmtn]]'
		end
		return res
	end
	
  	res = prefixo .. formatnum(mynum) .. sufixo
  	if needcheck and isarticle then
  		res = res .. '[[Categoria:!Páginas cujo uso da predefinição Fmtn deve ser revisado]]'
  	end
  	return res
end

function formatnum(num)
	frame = mw.getCurrentFrame()
	return frame:callParserFunction{ name = 'formatnum', args = { num } }
	
	-- Não é utilizado pois não preserva o número de dígitos após a casa decimal
	-- lang = mw.language.getContentLanguage()
	-- return lang:formatNum(mynum)
end

function reconhece_numero(num)
	if tonumber(num) then
		-- já é um número válido, não precisa fazer nada
		isnumber = true
		needcheck = false
	else
		isnumber = false
		needcheck = true
		-- não é um número válido, observa os padrões para ver
		-- se pode ser convertido em um padrão válido
		for _, rule in pairs(padroes_conhecidos) do
			checkpattern = rule[1]
			if string.find(num, checkpattern) then
				newneedcheck = rule[2]
				substitutions = rule[3]
				
				newstr = num
				for _, subs in pairs(substitutions) do
					-- aplica a substituição na string
					newstr = string.gsub(newstr, subs[1], subs[2])
				end
				
				if tonumber(newstr) then
					-- verifica se a transformação produziu um número válido
					-- caso positivo, encerra o loop
					num = newstr
					isnumber = true
					needcheck = newneedcheck
					break
				end
			end
		end
		-- se nenhum padrão bateu, então deve ser inválido
		-- deixa o código retornar o mesmo número passado e deixa que
		-- o chamador faça o seu trabalho
	end
	return num, isnumber, needcheck
end

return p