Mudanças

Ir para navegação Ir para pesquisar

Módulo:Info

18 945 bytes adicionados, 10h44min de 21 de abril de 2021
Criação do Módulo Info
-- 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 wIRChelps 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 wIRChelp ' .. 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)

Menu de navegação