Módulo:Info

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

-- Tabela para funções especiais chamadas colocando # no começo do rótulo ou dados
local especial = {}
-- Tabela para tabelas de debug
debug = {}
debug.erros = {}
-- Cores padrões --
local cores = { -- tons das linhas: {'escuro', 'mediano', 'claro', 'bem claro'}
				{'#B60000', '#FFAFAF', '#FFD7D7', '#FFEBEB'}, -- vermelho
				{'#B00058', '#FFABD5', '#FFD5EA', '#FFEAF5'}, -- bordô
				{'#840084', '#FFA4FF', '#FFD2FF', '#FFE9FF'}, -- púrpura
				{'#5800B1', '#DAB5FF', '#EDDAFF', '#F6EDFF'}, -- roxo
				{'#2020C9', '#BFBFFF', '#DFDFFF', '#EFEFFF'}, -- azul
				{'#0057AF', '#93C9FF', '#C9E4FF', '#E4F2FF'}, -- azul~ciano
				{'#00626F', '#11E4FF', '#88F2FF', '#C4F9FF'}, -- ciano
				{'#00654E', '#27FFCF', '#93FFE7', '#C9FFF3'}, -- verde~ciano
				{'#006800', '#7BFF7B', '#BDFFBD', '#DEFFDE'}, -- verde
				{'#4A6000', '#CFFF27', '#E7FF93', '#F3FFC9'}, -- verde~amarelo
				{'#655900', '#FFE411', '#FFF288', '#FFF9C4'}, -- amarelo
				{'#8C4600', '#FFB56B', '#FFDAB5', '#FFEDDA'}, -- laranja
				{'#585858', '#C7C7C7', '#E3E3E3', '#F1F1F1'}  -- cinza
}
-- Função para montar a infobox depois que os parâmetros foram pré-processados
local montarinfo = function(extra)
				local partes = {}
				-- Cabeçalho --
				if params['cabeçalho'] then
								partes['cabeçalho'] = '<caption>' .. params['cabeçalho'] .. '</caption>'
				end
				-- Pictograma --
				if params['pictograma'] and string.match(params['pictograma'], '^[^%]%[:]+%.%a%a%a%a?$') then
								partes['pictograma'] = '<div style="position:absolute; top:0; right:0;' ..
										'">[[Ficheiro:' .. params['pictograma'] .. '|' .. 'x45px]]</div>'
				end
				-- Título --
				partes['cor'] = cor1
				partes['título'] = params['título']
				if partes['pictograma'] then
								-- é preciso colocar o título dentro de um elemento com position para ficar acima do pictograma
								partes['título'] = '<div style="position:relative">' .. partes['título'] .. '</div>'
				end
				-- Campos --
				local c = {}
				local vazio = params['debug'] == 'vazio'
				local i = 1
				while i <= #campos do
								local campo = campos[i]
								if campo['tópico'] then
												local n = i + 1
												while campos[n] do
																if campos[n][1] and campos[n][1] ~= '' then
																				table.insert(c, '|-\n|colspan=2 style="text-align:center; font-weight:bold;' .. cor2 .. '"|' ..
																						campo['tópico'])
																				break
																elseif campos[n]['tópico'] then
																				break
																end
																n = n + 1
												end
								elseif campo['rótulo'] and (campo[1] or vazio) then
												table.insert(c, '|-\n|scope="row" ' .. 'style="vertical-align:top; text-align:left; font-weight:bold;' ..
														cor3 .. '"|' .. campo['rótulo'] .. '\n|' .. (campo['wikidata'] and 'class="dadoswd" ' or '') ..
														'style="vertical-align:top; text-align:left;"|' .. (campo[1] or '(vazio)'))
								elseif campo[1] or vazio then
												table.insert(c, '|-\n|colspan=2 ' .. (campo['wikidata'] and 'class="dadoswd" ' or '') ..
														'style="vertical-align: top; text-align: center' .. (campo['peq'] and '; font-size: 90%' or '') ..
														'"|' .. (campo[1] or '(vazio)'))
								elseif campo['info'] then -- infobox incluída em um campo
												table.insert(c, campo['info'])
								end
								i = i + 1
				end
				partes['campos'] = table.concat(c, '\n')
				-- Rodapé --
				if params['rodapé'] then
								partes['rodapé'] = '|-\n|colspan=2 style="text-align:center;' .. cor2 .. '"|' .. params['rodapé']
				end
				if params['nome'] and string.match(params['nome'], '^Predefinição:') then
								partes['ver-editar'] = '|-\n|colspan=2 class="plainlinks" style="text-align:right"|[[' ..
								params['nome'] .. '|ver]]'
				end
				-- Extra (geralmente categorias) --
								partes['extra'] = extra
				-- Debug --
				if params['debug'] and type(debug[params['debug']]) == 'table' then
								local lista = table.concat(debug[params['debug']], '\n')
								if lista == '' then
												lista = '(debug vazio)'
								end
								partes['rodapé'] = '|-\n|colspan=2|<pre>' .. lista .. '</pre>'
				end
				-- Categorias de número de campos --
				if ncampos then
								local num = ncampos == 0 and 'nenhum campo' or ncampos == 1 and '1 campo' or ncampos < 10 and
										tostring(ncampos) .. ' campos' or '10 ou mais campos'
								partes['catcampos'] = '[[Categoria:!Infoboxes com ' .. num .. ']]'
				end
				if ncamposwd then
								local num = ncamposwd == 0 and 'nenhum campo' or ncamposwd == 1 and '1 campo' or ncamposwd < 10 and
										tostring(ncamposwd) .. ' campos' or '10 ou mais campos'
								partes['catcampos'] = (partes['catcampos'] or '') .. '[[Categoria:!Infoboxes com ' .. num .. ' do Wikidata]]'
				end
				if todoscamposwd then
								partes['catcampos'] = (partes['catcampos'] or '') ..
										'[[Categoria:!Infoboxes em que todos campos são do Wikidata]]'
				end
				-- Montar a partes --
				local template = [=[{|class="infobox" style="font-size:90%; line-height:1.2em; float:right; clear:right; margin:0 0 .5em 1em; width:20em; border:1px solid #C7C7C7; padding:2px; background-color:#FAFAFA; border-spacing:3px"
{ cabeçalho }
|-
!colspan=2 style="height:45px; vertical-align:middle; text-align:center; font-size:120%; font-weight:bolder; line-height:1.3em; position:relative;{ cor }"|{ pictograma }{ título }
{ campos }
{ rodapé }
{ ver-editar }
|}
{ extra }
{ catcampos }]=]
			local infobox = string.gsub(template, '(\n?){ ([^}]+) }',
						function(nl, parte)
										if partes[parte] and partes[parte] ~= "" then
														return nl .. partes[parte] else return ''
										end
						end)
			return infobox
end
-- Campos com rótulo '#imagem' adicionam imagens com 200px de largura
especial.imagem = function(campo)
				if not campo[1] then
								return nil
				end
				local dominio, img = string.match(campo[1], '^%[%[(%w+):([^%]%|%.\n]+%.%w%w%w%w?)[%]%|]')
				if dominio then
								for _, d in pairs({'Ficheiro', 'Imagem', 'File', 'Image', 'ficheiro', 'imagem', 'file', 'image'}) do
												if dominio == d then
																dominio = nil
																break
												end
								end
								if dominio then img = nil end
				elseif string.match(campo[1], '^[^%]%|%.\n]+%.%w%w%w%w?$') then
								img = campo[1]
				end
				if img then
								campo['rótulo'] = nil
								campo[1] = '[[Ficheiro:' .. img .. '|200px]]'
								return campo
				else
								table.insert(debug.erros, 'nome de imagem não encontrado em "' .. campo[1] .. '"')
								return nil
				end
end
-- Campos com rótulo '#legenda' adicionam texto sem rótulo com letra menor quando existe dados no campo acima
especial.legenda = function(campo, i)
				if campo[1] and campos[i - 1] and campos[i - 1][1] and campos[i - 1][1] ~= '' then
								local small = string.match(campo[1], '^<small>(.*)</small>$')
								return {small or campo[1], ['peq'] = true, ['wikidata'] = campo[1]['wikidata']}
				else
								return nil
				end
end
-- Separa uma infobox incluída dentro de um campo
local subInfo = function(str)
				local pos = str:find('\n{|class="infobox')
				local campo = str:sub(1, pos - 1)
				local infos = {}
				while pos do
								local inicio = pos
								pos = str:find('\n{|class="infobox', pos + 1)
								local info = str:sub(inicio, pos)
								inicio = info:find'\n|%-\n|'
								local p, fim = inicio
								while p do
												fim = p - 1
												p = info:find('\n|}', p + 1)
								end
								if inicio then
												table.insert(infos, info:sub(inicio + 1, fim))
								end
				end
				return campo, table.concat(infos, '\n')
end
-- Função principal
local base = function(args, nomebase, estender)
				local title = mw.title.getCurrentTitle()
				local namespace = title.namespace
				local vazio = args['debug'] == 'vazio'
				local extra
				params = {}
				-- Para ordenar as chaves de uma tabela em Lua é necessário separar a tabela em duas:
				local camposn = {} -- tabela para guardar os números dos campos
				local camposv = {} -- tabela para guardar os valores dos campos
				for k, v in pairs(args) do
								if v == '' then
												-- pass
								elseif string.match(k, '^%d+$') then
												local n = tonumber(k)
												local rotulo, dados = string.match(v, '^([^:]-):(.*)$')
												if rotulo then
																rotulo = string.gsub(rotulo, '^%s*(.-)%s*$', '%1')
																dados = string.gsub(dados, '^%s*(.-)%s*$', '%1')
																if rotulo == '#tópico' and dados ~= '' then
																				camposv[n] = {['tópico']=dados}
																				table.insert(camposn, n)
																elseif rotulo ~= '' then
																				camposv[n] = {['rótulo']=rotulo, dados}
																				table.insert(camposn, n)
																elseif dados ~= '' then
																				camposv[n] = {dados}
																				table.insert(camposn, n)
																elseif vazio and rotulo ~= '' then
																				camposv[n] = {['rótulo']=rotulo, '(vazio)'}
																				table.insert(camposn, n)
																end
												elseif v ~= '' then
																camposv[n] = {v}
																table.insert(camposn, n)
												end
								elseif string.match(k, '^tópico%d+%.?%d?$') or string.match(k, '^rótulo%d+%.?%d?$') or
										string.match(k, '^dados%d+%.?%d?$') then
												local tipo, n = string.match(k, '^([^%d]+)(%d+%.?%d?)$')
												if tipo == 'dados' then
																tipo = 1
												end
												n = tonumber(n)
												if v == '' then
																-- pass
												elseif camposv[n] then
																camposv[n][tipo] = v
												else
																camposv[n] = {[tipo]=v}
																table.insert(camposn, n)
												end
								else
												params[k] = v
								end
				end
				local estender = estender or params['estender']
				params['título'] = params['título'] or title.text
				params['nome'] = params['nome'] or nomebase
				-- Cor --
				if params['cor'] then
								local matiz, tom = string.match(params['cor'], '(%d%d?)%.(%d)')
								local cor
								if matiz and tonumber(tom) <= 4 then
												cor = cores[tonumber(matiz)][tonumber(tom)]
								else
												cor = string.upper(params['cor'])
								end
								for _, matiz in ipairs(cores) do
												for i, c in ipairs(matiz) do
																if cor == c then
																				if i == 1 then
																								cor1 = ' background-color:' .. c .. '; color:#FFFFFF'
																								i = 2
																				else
																								cor1 = ' background-color:' .. c
																				end
																				if i < 4 then
																								cor2 = ' background-color:' .. matiz[i + 1]
																								if i < 3 then
																												cor3 = ' background-color:' .. matiz[i + 2]
																								else
																												cor3 = ''
																								end
																				else
																								cor2 = ''
																								cor3 = ''
																				end
																				break
																end
												end
								end
				end
				if not cor1 then
								cor1 = ''
								cor2 = ''
								cor3 = ''
				end
				-- Ordenar os campos e agrupar dados de rótulos iguais --
				table.sort(camposn)
				campos = {}
				if params['debug'] == 'campos' then
								debug.campos = {}
				end
				local i = 0
				if params['subtítulo'] then
							i = 1
							campos[1] = {params['subtítulo']}
				end
				for _, n in ipairs(camposn) do
								-- Como no preenchimento antigo existem tópicos e rótulos/dados com o mesmo número,
								-- é necessário ordenar desta forma para colocar os dados um número a frente do tópico
								if camposv[n]['tópico'] then
												i = i + 1
												campos[i] = {['tópico']=camposv[n]['tópico']}
												camposv[n]['tópico'] = nil
								end
								if camposv[n]['rótulo'] then
												-- junta campos de mesmo rótulo
												if #campos > 0 and camposv[n]['rótulo'] == campos[i]['rótulo'] then
																table.insert(campos[i], camposv[n][1])
												else
																i = i + 1
																campos[i] = camposv[n]
												end
								elseif camposv[n][1] then
												i = i + 1
												campos[i] = camposv[n]
								end
								if campos[i][1] and string.match(campos[i][1], '\n{|class="infobox') then
												local info
												campos[i][1], info = subInfo(campos[i][1])
												if info and info ~= '' then
																i = i + 1
																campos[i] = {['info'] = info}
												end
								end
								-- para debug
								if debug.campos then
												local t = {}
												for k, v in pairs(campos[i]) do
																table.insert(t, tostring(k) .. '=' .. tostring(v))
												end
												table.insert(debug.campos, i .. ' => {' .. table.concat(t, ', ') .. '}')
								end
				end
				camposn, camposv = nil, nil
				-- Imagens e legendas no formato antigo --
				for i, n in ipairs({'', '1', '2', '3'}) do
								if params['imagem' .. n] then
					table.insert(campos, 1, {['rótulo']='#imagem', params['imagem' .. n]})
					if params['legenda' .. n] or params['imagem_legenda' .. n] then
									table.insert(campos, 2, {params['legenda' .. n] or params['imagem_legenda' .. n]})
					end
								end
				end
				-- Chamar extenção
				local ext
				local especial = especial
				if estender then
								local title = mw.title.new('Módulo:Info/' .. estender)
								if title.exists then
												ext = require('Módulo:Info/' .. estender)
												if ext.especial then
																for k, v in pairs(ext.especial) do
																				especial[k] = v
																end
												end
												if ext.campos then
																ext.campos(campos)
												end
								end
				end
				-- Processar campos que pedem dados do Wikidata, funções especiais e remove dados vazios --
				wdEntity = mw.wikibase.getEntity(params['item'] and params['item']:match('^Q%d+$'))
				local importar = params['wikidata'] ~= 'não'
				for i, campo in ipairs(campos) do
								while campo[1] do
												local arg = string.match(campo[1], '^#[Ww][Dd]: *(.*)')
												if arg and importar then
																if not wd or not debug.wikidata then
																				-- Só importa o módulo do Wikidata quando tiver campos do Wikidata
																				require('Módulo:Info/' .. (params['wd'] or 'wd'))
																				debug.wikidata = {}
																end
																local dados = wd.expandir(arg)
																if dados then
																				campo[1] = dados
																				campo['wikidata'] = true
																				break
																else
																				table.remove(campo, 1)
																end
																if wd.temp.debug then
																				table.insert(debug.wikidata, wd.temp.debug)
																				wd.temp = {}
																end
												elseif arg or campo[1] == '' then
																table.remove(campo, 1)
												else
																break
												end
								end
								local esp = campo['rótulo'] and string.match(campo['rótulo'], '^#(.*)') or nil
								if esp and especial[esp] then
												campos[i] = especial[esp](campo, i) or {}
								end
				end
				if ext and ext.extra then
								extra = ext.extra()
				end
				-- Contar número de campos e campos do Wikidata --
				local contarmin, contarmax = 0, 2
				local contarwdmin, contarwdmax
				local contarwdtodos = true
				if namespace ~= 0 then  -- só categoriza por padrão em artigos
								contarmin, contarmax, contarwdtodos = nil, nil, nil
				end
				if params['contar campos'] then
								contarmin, contarmax = string.match(params['contar campos'], '(%d%d?)[^%d]*(%d%d?)')
								if contarmin then
												contarmin, contarmax = tonumber(contarmin), math.min(10, tonumber(contarmax))
								elseif params['contar campos'] == 'sim' then
												contarmin, contarmax = 0, 10
								elseif params['contar campos'] == 'não' then
												contarmin, contarmax = nil, nil
								end
				end
				if params['contar wikidata'] then
								contarwdmin, contarwdmax = string.match(params['contar wikidata'], '(%d%d?)[^%d]*(%d%d?)')
								if contarwdmin then
												contarwdmin, contarwdmax = tonumber(contarwdmin), math.min(10, tonumber(contarwdmax))
								elseif params['contar wikidata'] == 'sim' then
												contarwdmin, contarwdmax = 0, 10
								elseif params['contar wikidata'] == 'não' then
												contarwdtodos = false
								end
				end
				if contarmin or contarwdmin or contarwdtodos then
								ncampos, ncamposwd = 0, 0
								for k, v in pairs(campos) do
												if v[1] then
																ncampos = ncampos + 1
												end
												if v[1] and v['wikidata'] then
																ncamposwd = ncamposwd + 1
												end
								end
								if contarwdtodos then
												todoscamposwd = ncampos >= 1 and ncampos == ncamposwd -- se todos os campos são do Wikidata
								end
								if not contarmin or (ncampos < tonumber(contarmin) or ncampos > contarmax) then
												ncampos = false
								end
								if not contarwdmin or (ncamposwd < tonumber(contarwdmin) or ncamposwd > contarwdmax) then
												ncamposwd = false
								end
				end
				-- Categoria de artigos bons e destacados em Wikipédias de outras línguas
				if namespace == 0 and wdEntity and wdEntity['sitelinks'] then
								local cats = {}
								local badges = {['Q17437796'] = '!Artigos destacados', ['Q17437798'] = '!Artigos bons',
										['Q17506997'] = '!Listas destacadas'}
								for wiki, sitelink in pairs(wdEntity['sitelinks']) do
												for _, badge in ipairs(sitelink['badges']) do
																if badges[badge] and wiki:match('wiki$') then
																				table.insert(cats, {badges[badge], wiki:match('^(.+)wiki$')})
																end
												end
								end
								if #cats > 0 then -- só carrega a lista de prefixos se for usar
												prefixos = mw.loadData('Módulo:Prefixos de língua')
												for i, cat in ipairs(cats) do
																local lingua = prefixos[cat[2]]
																cats[i] = lingua and '[[Categoria:' .. cat[1] .. ' na Wikipédia em ' .. lingua .. ']]' or ''
												end
												extra = (extra or '') .. table.concat(cats)
								end
				end
				return montarinfo(extra, debug)
end
local m, mt = {}, {}
m.base = function(frame)
				local parent = frame:getParent()
				return base(frame.args, parent and parent:getTitle())
end
mt.__index = function(t, k)
				return function(frame)
								local parent = frame:getParent()
								return base(frame.args, parent and parent:getTitle(), k)
				end
end
return setmetatable(m, mt)