Módulo:Categorizar
Módulo usado para fazer categorizações.
Uso
editarVeja a descrição das funções principais na {{categorizar}}.
- Funções para serem invocadas
{{#invoke:categorizar|principal|<argumentos>}}
mesmas funções da {{categorizar}}{{#invoke:categorizar|link|<argumentos>}}
mesmas funções, porém retorna o link[[:Categoria:...]]
em vez de categorizar a página.
- Funções para serem usadas dentro de outros módulos
categorizar = require'Módulo:Categorizar'
cat = categorizar.categorizar{'assunto em', ano='1942'} -- igual à {{categorizar|assunto em|ano=1942}}
cat = categorizar.ano_decada{'assunto em', ano='1942'} -- retorna 'assunto na década de 1940'
cat = categorizar.ano_seculo{'assunto em', ano='1942'} -- retorna 'assunto no século XX'
local m = {}
-- remove "Categoria:" do inicio se tiver
local rmcat = function(cat)
if not cat then return end
local a, b = string.find(cat, '[Cc]ategoria:')
if a == 1 then
return string.sub(cat, b + 1)
end
return cat
end
-- verifica se a categoria existe
local existe = function(cat)
if not cat then return end
local page = mw.title.new(cat, 14)
if page.exists then
return '[[Categoria:' .. cat .. ']]'
end
end
-- verifica se é um ano válido e converte a.C. para número negativo
local num_ano = function(ano)
local a, b = string.find(ano, '^%-?%d+')
-- retorna nil se ano não for válido
if a == nil then return end
local ac = string.find(string.sub(ano, b + 1), '^ ?a%.?[Cc]%.?$')
ano = tonumber(string.sub(ano, a, b))
if ac and ano > 0 then
ano = -ano
end
return ano
end
-- transforma um número em número romano
local romano = function(num)
if num > 3999 or num < 1 then return end
local nr = {[1]='I', [5]='V', [10]='X', [50]='L', [100]='C', [500]='D', [1000]='M'}
local resp = {}
while num > 0 do
local base = math.pow(10, math.floor(math.log10(num)))
local mult = math.floor(num / base)
if mult == 9 then
table.insert(resp, nr[base] .. nr[base * 10])
num = num - 9 * base
elseif mult > 5 then
table.insert(resp, nr[base * 5])
num = num - 5 * base
elseif mult == 4 then
table.insert(resp, nr[base] .. nr[base * 5])
num = num - 4 * base
else
table.insert(resp, nr[base])
num = num - base
end
end
return table.concat(resp)
end
-- verifica se o ano é válido e padroniza a indicação a.C.
local valida_ano = function(ano)
if string.find(ano, '^%d+$') then
return ano
elseif string.find(ano, '^%-%d+$') then
return math.abs(ano) .. ' a.C.'
end
local ano, ac = string.match(ano, '^(%d+) ?(a%.?[Cc]%.?)$')
if ano then
return ano .. ' a.C.'
end
end
-- retorna a categoria da década
m.ano_decada = function(cat, ano)
ano = num_ano(ano)
if ano == nil then return end
local decada = math.floor(ano / 10) * 10
if ano < 0 then
decada = decada + 10 .. ' a.C.'
end
if string.find(cat, ' de$') then
return string.sub(cat, 1, -3) .. 'da década de ' .. decada
elseif string.find(cat, ' em$') then
return string.sub(cat, 1, -3) .. 'na década de ' .. decada
else
return cat .. ' década de ' .. decada
end
end
-- retorna a categoria do século
m.ano_seculo = function(cat, ano)
ano = num_ano(ano)
if ano == nil then return end
-- ano fora dos limites de tempo
if ano > 3000 or ano < -3000 then
if string.find(cat, ' em$') then
cat = string.sub(cat, 1, -3)
end
return cat .. (ano > 0 and 'após o século XXX' or 'antes do século XXX a.C.')
end
local num = (math.floor(math.abs(ano) / 100) + 1)
local seculo = romano(num)
if ano < 0 then
seculo = seculo .. ' a.C.'
end
if string.find(cat, ' de$') then
return string.sub(cat, 1, -3) .. 'do século ' .. seculo
elseif string.find(cat, ' em$') then
return string.sub(cat, 1, -3) .. 'no século ' .. seculo
else
return cat .. ' século ' .. seculo
end
end
------ função principal ------
m.categorizar = function(args)
local prefixo = args['prefixo']
local sufixo = args['sufixo'] or ''
local ano = args['ano']
local cat_erro = args['erro'] and rmcat(args['erro'])
local cats = {}
-- tratamento de erros
cat_erro = cat_erro and '[[Categoria:' .. cat_erro .. ']]'
or '[[Categoria:!Páginas com erro nos parâmetros de categorização]]'
if ano then
local valido = valida_ano(ano)
if valido then
ano = valido
else
return cat_erro
end
end
-- verifica parâmetros de ano mínimo e ano máximo
for k, v in pairs(args) do
local antes = string.match(k, '^antes de (%-?%d+ ?a?%.?[Cc]?%.?)$')
local apos = string.match(k, '^após (%-?%d+ ?a?%.?[Cc]?%.?)$')
if (antes or apos) and ano then
local limite = num_ano(antes or apos)
local num = num_ano(ano)
if not limite or not num then break end
if antes and num < limite or apos and num > limite then
return '[[Categoria:' .. v .. ']]'
end
end
end
-- primeira passagem pelas opções de categorias
for _, cat in ipairs(args) do
cat = rmcat(cat)
if prefixo then
cat = rmcat(prefixo) .. ' ' .. cat
end
if (cat == '' and sufixo == '') or string.find(cat, '[{}%[%]]') then
return cat_erro
elseif ano then
table.insert(cats, cat)
else
if sufixo ~= '' then
cat = cat .. ' ' .. sufixo
end
local encontrada = existe(cat)
if encontrada then
return encontrada
end
end
end
-- categorias com ano, década e século
if ano then
-- para poder usar somente ano e sufixo
if not cats[1] and sufixo ~= '' then
cats[1] = ''
end
-- ano
for _, cat in ipairs(cats) do
cat = cat .. ' ' .. ano
if sufixo ~= '' then
cat = cat .. ' ' .. sufixo
end
local encontrada = existe(cat)
if encontrada then
return encontrada
end
end
-- década do ano
for _, cat in ipairs(cats) do
cat = m.ano_decada(cat, ano)
if sufixo ~= '' then
cat = cat .. ' ' .. sufixo
end
local encontrada = existe(cat)
if encontrada then
return encontrada
end
end
-- século do ano
for _, cat in ipairs(cats) do
cat = m.ano_seculo(cat, ano)
if sufixo ~= '' then
cat = cat .. ' ' .. sufixo
end
local encontrada = existe(cat)
if encontrada then
return encontrada
end
end
end
-- nenhuma categoria encontrada, usa o parâmetro 'nenhuma' se estiver preenchido
if args['nenhuma'] then
cat = rmcat(args['nenhuma'])
-- não testa se a categoria existe desta vez
return '[[Categoria:' .. cat .. ']]'
end
end
-- funções para serem usadas com #invoke
-- função principal para ser usada na {{categorizar}}
m.principal = function(frame)
local args = next(frame.args) ~= nil and frame.args or frame:getParent().args or {}
return m.categorizar(args)
end
-- como a m.predef, só que retorna o link [[:Categoria:...]]
m.link = function(frame)
local cat = m.categorizar(frame.args)
if cat then
cat = string.gsub(cat, '^%[%[C', '[[:C')
return cat
end
end
return m