Vai al contenuto

Modulo:Infobox/sandbox

Da Wikipedia, l'enciclopedia libera.
-- Modulo per implementare le funzionalità di infobox
local p = {} -- per l'esportazione delle funzioni del modulo
require('Modulo:No globals')
local immagine_sinottico = require('Module:Immagine sinottico')._main

local args = {}-- variabile che contiene gli argomenti passati al template


local function is_defined(s)
	if s == nil or s == '' then
		return false
	end
	return true
end

-------------------------------------------------------------------------------
--                           classe Infobox
-------------------------------------------------------------------------------

p.Infobox = {}

function Infobox:new(args)
	local self = {}

	setmetatable(self, { __index = Infobox })
	-- Crea l'albero html che rappresenta la tabella del sinottico
	self.stile_gruppi = args.stile_gruppi or ''
	self.stile_etichette = args.stile_etichette or ''
	self.stile_valori = args.stile_valori or ''
	if args.CreaTable == 'no' then
		self.root = mw.html.create('')
	else
		self.root = mw.html.create('table')
		self.root
			:addClass(args.classe or 'sinottico')
			:cssText(args.stile)
			:attr('summary', args.sommario or 'Tabella sinottica che riassume i principali dati del soggetto' )
	end
	self:_setupTableNode()
	return self
end

function Infobox:tostring()
	return tostring(self.root)
end

function Infobox:sopratitolo(text, options)
	if is_defined(text) then 
		self.subtitle = mw.html.create('')
			:tag('span')
				:addClass('sinottico_sottotitolo')
				:cssText(options.stile_sopratitolo)
				:wikitext(text)
				:done()
			:tag('br')
	end
	return self
end

function Infobox:sottotitolo(text, options)
	if is_defined(text) then 
		self.subtitle = mw.html.create('')
			:tag('br')
				:done()
			:tag('span')
				:addClass('sinottico_sottotitolo')
				:cssText(options.stile_sottotitolo)
				:wikitext(text)
	end
	return self
end


function Infobox:titolo(title, options)
	self.root = nil
	if self.options.TitoloEst then
		self.root
			:tag('caption')	
			:addClass('sinottico_testata' )
			:css("font-weight", "bold")
			:cssText(options.stile)
			:node(options.sopratitolo, options)
			:wikitext(title)
			:node(options.sottotitolo, options)
	else 
		self.root
			:tag('tr')
			:addClass('sinottico_testata')
			:tag('th')
				:attr('colspan', '2')
				:node(options.sopratitolo, options)
				:cssText(options.stile)
				:wikitext(title)
				:node(options.sottotitolo, options)
	end
	return self
end

function infobox:gruppo(label, options)
	if not is_defined(label) then return self end
	if options.is_opzionale ~= nil then
		self.opzionale_label = label 
		self.opzionale_options = options
		return self
	end
	if self.opzionale_label ~= nil then
		infobox:voidGroup()
	end
	self.root
		:tag('tr')
		:addClass("sinottico_divisione")
		:tag('th')
		:attr('colspan', 2)
		:cssText(options.stile or self.stile_gruppi or '')
		:wikitext(label)
	return self

end

function infobox:annulla_gruppo()
	self.opzionale_label = ''
	self.opzionale_options = nil
	return self
end

function infobox:valore(value, label, options)
	if not is_defined(value) then return self end
	if self.opzionale_label then
		self:gruppo(self.opzionale_label, self.opzionale_options)
		self:annulla_gruppo()
	end
	local row = self.root:tag('tr')
	local dataCell
	if label ~= nil then
		row
			:tag('th')
				:cssText(options.stile_etichetta or self.stile_etichette or '')
				:wikitext(label)
		dataCell = row:tag('td')
	else
		dataCell = row:tag('td')
			:attr('colspan', 2)
			:css('text-align', 'center')
	end
	dataCell
		:addClass(options.classe or '')
		:cssText(args.stile_valore or self.stile_valori or '')
		:wikitext(value)			
	return self
end

-------------------------------------------------------------------------------
--                           fine classe Infobox
-------------------------------------------------------------------------------

local function getArgNums(...)
	-- Restituisce una lista che contiene il suffisso numerico  di tutti gli argomenti
	-- che iniziano con il prefisso "prefix"
	-- Per esempio se nella lista argomenti sono valorizzati "Valore1, Valore2 e Valore4"
	-- retistuirà la lista [1, 2, 4]
	local prefixs = {...}
	local nums = {}
	for k, _ in pairs(args) do
		local num = nil
		for _, candidate in ipairs(prefixs) do
			num = ('' .. k):match('^' .. candidate .. '(%d+)$')
			if num ~= nil then break end
		end
		if num then table.insert(nums, tonumber(num)) end
	end
	table.sort(nums)
	return nums
end

local function renderRows()
	local rownums = getArgNums('Valore', 'GruppoOpzionale',  'Gruppo')
	for k, num in ipairs(rownums) do
		if args['GruppoOpzionale' .. num] ~= nil then
			if args['GruppoOpzionale' .. num] ~= '$fine' then
				Infobox:gruppo(args['GruppoOpzionale' .. num], {opzionale='s',
							   classe = args['Classe' .. num], stile = args['GruppoStile' .. num]})
			else
				Infobox:annulla_gruppo()
			end
		else
			Infobox:valore(args['Valore' .. num], args['Nome' .. num])
		end
	end
end


local function _infobox()
	-- Crea l'albero html che rappresenta la tabella del sinottico e restituisce il markup
	Infobox = infobox.create({sommario = args.summary, stile_gruppi = args.StileGruppo, 
								stile_valori = args.StileValore, stile_etichette = args.StileEtichetta })
	local titolo, stile_titolo
	if args.TitoloEst then 
		titolo = args.TitoloEst
		stile = args.StileTitoloEst
	else
		titolo = args.TitoloInt
		stile = args.StileTitoloInt
	end
	Infobox:titolo( titolo, nil , { stile = stile, sottotitolo=args.SottoTitolo, stile_sottotitolo=args.StileSottoTitolo,
							  sopratitolo = args.SopraTitolo, stile_sopratitolo = args.SopraTitolo })
	if args.Immagine then
		local args_immagine = 
		Infobox:Valore(immagine_sinottico({ args.Immagine, args.Didascalia, stile_valore = args.StileImmagine, 
					   compatibile = 's'}))
	end
	renderRows(Infobox)
	Infobox:valore(args.Ultima, nil , {classe_valore='sinottico_piede', stile_valore = args.StileUltima })
	if args.NomeTemplate then
		local txt_nav =  mw.getCurrentFrame():expandTemplate({
					title = 'Link sinottico',
					args = args.LinkWikidata and
							{ args.NomeTemplate } or
							{ args.NomeTemplate, nowd = 1 }
				})
		Infobox:valore(txt_nav, nil , {classe_valore='sinottico_piede2 noprint metadata'})
	end
	return tostring(root)
end

local function preprocessSingleArg(argName)
	-- Se l'argomento esiste e non è una stringa vuota lo aggiunge alla tabella degli argomenti
	-- Argomenti uguali a stringa vuota sono trattati come nulli come da comportamento
	-- precedente del template {{Infobox}}
	if origArgs[argName] and origArgs[argName] ~= '' then
		args[argName] = origArgs[argName]
	end
end

local function preprocessArgs(prefixTable, step)
	-- Assegna i parametri con i dati prefissi alla tabella args, in ordine e secondo lotti di
	-- dimensione specificata. La prefixTable dovrebbe essere un  array contenente tabelle, ognuna
	-- delle quali con due possibili campi, una stringa "prefisso" e una tabella di "dipendenze". La
	-- funsione esamina tutti i parametri contenenti la stringa prefisso, ma esamina quelli della
	-- tabella dipendenti solo se il prefisso da cui dipendono è presente e non nullo.
	if type(prefixTable) ~= 'table' then
		error("Valore non tabella trovato nella tabella prefissi", 2)
	end
	if type(step) ~= 'number' then
		error("Passo di tipo non valido", 2)
	end

	-- Ottiene gli argmenti senza un suffisso numerico e controlla per input errati.
	for i,v in ipairs(prefixTable) do
		if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
			error('Valori non validi riscontrati per la tabella di prefissi preprocessArgs', 2)
		end
		preprocessSingleArg(v.prefix)
		-- Esamina i parametri dipendenti solo se il parametro prefisso è presente e non nullo.
		if args[v.prefix] and v.depend then
			for j, dependValue in ipairs(v.depend) do
				if type(dependValue) ~= 'string' then
					error('Parametro "dipendente"  non valido riscontrato in preprocessArgs')
				end
				preprocessSingleArg(dependValue)
			end
		end
	end
	if step == 0 then return end
	-- Estrae gli argomenti con un suffisso numerico
	local a = 1 -- Counter variable.
	local moreArgumentsExist = true
	while moreArgumentsExist == true do
		moreArgumentsExist = false
		for i = a, a + step - 1 do
			for j,v in ipairs(prefixTable) do
				local prefixArgName = v.prefix .. tostring(i)
				if origArgs[prefixArgName] then
					moreArgumentsExist = true -- Aggiunge una passata se un parametro è stato trovato, anche se nullo.
					preprocessSingleArg(prefixArgName)
				end
				-- Processa la tavola dei dipendenti  se il parametro da cui dipendono esiste e non è nullo
				if v.depend and args[prefixArgName] then
					for j,dependValue in ipairs(v.depend) do
						local dependArgName = dependValue .. tostring(i)
						preprocessSingleArg(dependArgName)
					end
				end
			end
		end
		a = a + step
	end
end

function p.infobox(frame)
	-- Se chiamata mediante  #invoke, usa gli argomenti passati al template invocante.
	-- Altrimenti a scopo di test assume che gli argomenti siano passati direttamente
	if frame == mw.getCurrentFrame() then
		origArgs = frame:getParent().args
	else
		origArgs = frame.args
	end

	-- Le funzioni Parser considerano la stringa vuota come falsa, così per preservare il
	-- comportamento di {{infobox}} tutti gli argomenti vuoti non vengono memorizzati
	-- nella tabella globale args, così da essere considerati falsi
	-- Nota: args è una variabile globale per il modulo dichiarata al suo inizio
	-- Scandisce i parametri nello stesso ordine in cui lo faceva il vecchio {{infobox}}
	-- così che eventuali istruzioni ref compariranno in posizione e ordine corretto. Parametri che dipendono da
	-- altri parametri sono processati solo se il parametro è presente, così da evitare
	-- la comparsa di riferimenti fantasma in posti inattesi.
	preprocessSingleArg('StileTabella')
	preprocessArgs({
		{prefix='SopraTitolo', depend={'StileSopraTitolo'}}
		}, 0)
	preprocessArgs({
		{prefix='TitoloEst', depend={'StileTitoloEst'}}
		 }, 0)
	preprocessArgs({
		{prefix='TitoloInt', depend={'StileTitoloInt'}}
		}, 0)
	preprocessArgs({
		{prefix='SottoTitolo', depend={'StileSottoTitolo'}}
		}, 0)
	preprocessArgs({
		{prefix='Immagine', depend={'ClasseImmagine', 'StileImmagine',
						'Didascalia', 'StileDidascalia'}}
		}, 0)
	preprocessSingleArg('StileGruppo')
	preprocessSingleArg('StileNome')
	preprocessSingleArg('StileValore')
	preprocessArgs({
		{prefix = 'Gruppo', depend={'GruppoStile'}},
		{prefix = 'GruppoOpzionale', depend={'GruppoStile'}},
		{prefix = 'Valore', depend={'Nome', 'Classe'}},
	}, 50)
	preprocessSingleArg('Ultima')
	preprocessSingleArg('StileUltima')
	preprocessSingleArg('NomeTemplate')
	preprocessSingleArg('LinkWikidata')
	preprocessSingleArg('CreaTable')
	preprocessSingleArg('Summary')
	return _infobox()
end

return p