Módulo:Categorizar

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:Categorizar/doc

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