Módulo:Fmtn
Aspeto
Este módulo pode ter sua documentação deficiente. Por favor, documente-o ou melhore suas explicações caso o saiba usar ou tenha conhecimentos para tal. |
Este módulo é usado em 95 000 páginas. (Ver Wikipedia:Predefinições em alto risco) Para evitar sobrecargas desnecessárias ao servidor e outros transtornos, quaisquer mudanças devem ser previamente testadas, seja na subpágina de testes deste módulo, na subpágina de testes de módulos (ou ainda em sua subpágina de testes). Por favor, sempre considere expor eventuais mudanças na página de discussão, antes de implementá-las. |
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