Modulo:Sandbox/ppong

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
require("strict")

-- Tabella di configurazione
--------------------------------------------------------------------------------

local config = {
	-- Inserire solo le occorrenze più insolite: il modulo già rende maiuscolo il nome del progetto
	progetti = { 
		["Acquariofilia"] = "Forme di vita/Pesci/Acquariofilia",
		["anime"] = "Anime e manga",
		["animanga"] = "Anime e manga",
		["Anno"] = "Cronologia/Anno",
		["areeprotette"] = "Aree protette",
		["Armi da fuoco"] = "Guerra/Armi da fuoco",
		["Atletica leggera"] = "Sport/Atletica leggera",
		["Atletica"] = "Sport/Atletica leggera",

		["biologia"] = "Bio",
		["biochimica"] = "Bio",
		["Burma"] = "Birmania",

		["Calcio"] = "Sport/Calcio",
		["cartoni animati"] = "Cartoons",
		["Comuni"] = "Geografia/Antropica/Comuni",

		["Decade"] = "Cronologia/Decade",
		["Dialetti"] = "Dialetti d'Italia",
		["Wikilex"] = "Diritto",
		["minori"] = "Diritti dei minori",
		["disturbipsichici"] = "Disturbi psichici",
		["Documenta ecclesiae"] = "Documenta Ecclesiae",

		["aziende"] = "Economia",
		["Elicotteri"] = "Aviazione/Elicotteri",
		["Emilia"] = "Emilia e Romagna",
		["Romagna"] = "Emilia e Romagna",
		["emilia romagna"] = "Emilia e Romagna",
		["Emilia Romagna"] = "Emilia e Romagna",
		["Emilia-Romagna"] = "Emilia e Romagna",
		["ER"] = "Emilia e Romagna",
		["emilia-romagna"] = "Emilia e Romagna",

		["Fiction tv"] = "Fiction TV",
		["Film Horror"] = "Film horror",
		["horror"] = "Film horror",
		["formedivita"] = "Forme di vita",
		["Formula uno"] = "F1",
		["Formula 1"] = "F1",

		["Guerra elettronica"] = "Guerra/Guerra elettronica",
		["guerrestellari"] = "Guerre stellari",
		["GuerreStellari"] = "Guerre stellari",

		["Controlli automatici"] = "Ingegneria/Controlli automatici",

		["Musica classica"] = "Musica/Classica",
		["classica"] = "Musica/Classica",
		["metal"] = "Musica/Heavy metal",
		["Heavy Metal"] = "Musica/Heavy metal",
		["Heavy metal"] = "Musica/Heavy metal",
		["Hip Hop"] = "Musica/Hip hop",
		["hip hop"] = "Musica/Hip hop",
		["hiphop"] = "Musica/Hip hop",
		["Jazz"] = "Musica/Jazz",
		["Punk"] = "Musica/Punk",
		["Rock"] = "Musica/Rock",

		["Nobel"] = "Premi Nobel",
		["Premi nobel"] = "Premi Nobel",

		["Pallacanestro"] = "Sport/Pallacanestro",
		["Basket"] = "Sport/Pallacanestro",
		["Pk"] = "Fumetti/PK",
		["PK"] = "Fumetti/PK",
		["pokèmon"] = "Pokémon",
		["Pokemon"] = "Pokémon",
		["portorico"] = "Porto Rico",

		["Reggio calabria"] = "Reggio Calabria",
		["Rugby"] = "Sport/Rugby",

		["San marino"] = "San Marino",
		["Scienze della terra"] = "Scienze della Terra",
		["stati africa"] = "Stati",
		["stati america"] = "Stati",
		["stati asia"] = "Stati",
		["stati europa"] = "Stati",
		["stati oceania"] = "Stati",

		["tao"] = "Taoismo",
		["tv"] = "Televisione",
		["TV"] = "Televisione",

		["Venezia"] = "Venezia e Laguna",
		["venezia e laguna"] = "Venezia e Laguna",
		["Vibo valentia"] = "Vibo Valentia",
		["vibo"] = "Vibo Valentia",
		["videogames"] = "Videogiochi",

		["Disney"] = "Walt Disney",

		["q"] = "Qualità",
		["Qualita"] = "Qualità"
	},
	campi = {
		'accuratezza',
		'scrittura',
		'fonti',
		'immagini'
	},
	altri_parametri = {
		"note",
		"utente",
		"data",
		"modello di voce"
	},
	importanza = {
		fondamentale = 1,
		primario = 2,
		secondario = 3,
		medio = 3,
		minimo = 4,
		imprecisato = 5 -- valore predefinito
	},
	importanza_definizione = {
		'<span style="color: red">interesse fondamentale</span>',
		'<span style="color: orange">interesse primario</span>',
		'<span style="color: green">interesse secondario</span>',
		'<span style="color: gray">interesse minimo</span>',
		'<i>interesse imprecisato</i>'
	},
	voti = {
		A = 5,
		["A+"] = 5,
		VETRINA = 5,
		B = 4,
		C = 3,
		D = 2,
		E = 1,
		X = 1,
		STUB = 1
	},
	livelli = {
		"livello bozza",
		"livello iniziale",
		"livello medio",
		"livello buono",
		"livello completo",
		[0] = "nessun livello",
--		["livello completo"] = 5,
--		["livello buono"] = 4,
--		["livello sufficiente"] = 3,
--		["livello minimo"] = 2,
--		["livello bozza"] = 1,
--		["nessun livello"] = "NC",
--		["non compilate"] = "NC"
	},
	descrizione_stato = {
--[=[		livello = {
			["livello completo"] = "La voce ha ottenuto il massimo livello di valutazione in base a quanto raccomandato nel '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello buono"] = "La voce ha raggiunto un buon livello di valutazione in base a quanto raccomandato nel '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello sufficiente"] = "La voce è stata considerata di livello sufficiente in base a quanto raccomandato nel '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello minimo"] = "La voce è stata considerata di livello minimo in base a quanto raccomandato nel '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.",
			["livello bozza"] = "La voce è da considerarsi una bozza in base a quanto indicato dal '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]''' e da [[Aiuto:abbozzo]].", -- da chiarire meglio come funziona
			["nessun livello"] = "Alla voce non può ancora essere assegnato un livello per il '''[[Progetto:Qualità/Monitoraggio voci|monitoraggio della qualità]]'''.", -- da chiarire meglio come funziona
			["non compilate"] = "La voce non è stata ancora monitorata, <span class=\"plainlinks\">[http://it.wikipedia.org/w/title=" .. mw.title.getCurrentTitle().fullText .. "&action=edit&section=0 fallo ora]!</span>"
		}, -- ]=]
		accuratezza = {
			"La voce contiene un contenuto utile molto basso. Informazioni limitate o da controllare.",
			"La voce possiede un'accuratezza che richiede un maggiore sviluppo. Molti aspetti del tema non sono trattati o solo superficialmente.",
			"La voce ha dimensioni e accuratezza di medio livello. Potrebbe essere ancora ampliata notevolmente, stante l'argomento trattato.",
			"I contenuti della voce sono buoni e accurati, ma possono essere migliorati. Sarebbero utili approfondimenti o aggiornamenti.",
			"Voce adeguatamente accurata. Tutti gli aspetti principali del tema sono affrontati con la dovuta profondità e le informazioni sono aggiornate."
		},
		scrittura = {
			"La voce è scritta con un italiano pessimo e [[:categoria:correggere|da correggere]] oppure deve essere [[aiuto:wikificare|wikificata]].",
			"La scrittura della voce dovrebbe essere rivista in funzione del [[aiuto:manuale di stile|manuale di stile]].",
			"La voce è adeguatamente leggibile, ma lo [[aiuto:manuale di stile|stile]] potrebbe essere più scorrevole e le informazioni potrebbero essere presentate meglio.",			
			"La voce è ben scritta, fatto salvo qualche inciampo nello [[aiuto:manuale di stile|stile]]. Il linguaggio o la strutturazione in paragrafi sono ancora migliorabili sotto alcuni aspetti.",
			"Voce scritta in buon italiano e con buono [[aiuto:manuale di stile|stile]]. Sintassi e lessico adeguati, linguaggio chiaro e scorrevole, con uso attento di termini specifici. Strutturazione in paragrafi soddisfacente."
		},
		fonti = {
			"La voce [[:categoria:senza fonti|non ha nessuna fonte o ne ha pochissime]].",
			"La voce meriterebbe un maggior supporto di fonti [[Wikipedia:Fonti attendibili|attendibili]] e ne è ancora per lo più scoperta.",
			"La voce è provvista di fonti [[Wikipedia:Fonti attendibili|attendibili]], ma non è ancora completamente [[wp:verificabilità|verificabile]]. Sarebbe necessario trovare delle fonti per i diversi aspetti della voce che ne sono scoperti.",
			"La voce è ben coperta da fonti. Per migliorare l'attendibilità della voce si potrebbe comunque arricchirla con altri supporti maggiormente autorevoli.",
			"I contenuti della voce sono interamente verificabili tramite fonti [[Wikipedia:Fonti attendibili|autorevoli attendibili]]."
		},
		immagini = {
			"La voce necessiterebbe di immagini o file essenziali per la comprensione del tema, ma ne è assolutamente priva.",
			"La voce ha neccessità di file importanti per la comprensione del tema, alcuni essenziali.",
			"Per migliorare la comprensibilità della voce, dovrebbero esssere inserite delle immagini o file importanti per la comprensione del tema.",
			"Leggendo la voce non si avverte la mancanza di adeguati supporti grafici o multimediali, potrebbero tuttavia essere migliorati.",
			"La voce è corredata da un adeguato numero di immagini e/o supporti multimediali di qualità e in tema con il contenuto, oppure non ne necessita alcuno."
		}
	},
	icona = {
		'Monitoraggio 2015 !.svg',
		'Monitoraggio 2015 25.svg',
		'Monitoraggio 2015 50.svg',
		'Monitoraggio 2015 75.svg',
		'Monitoraggio 2015 100.svg',
		[0] = 'Symbol stub class.svg'
	}
}

-- Funzioni di utilità
--------------------------------------------------------------------------------

local getArgs = require("Modulo:Arguments").getArgs

local iconaArgomento = require("Modulo:Sandbox/ppong/Icona").iconaArgomento

local italiano = mw.language.new("it")

-- per complicarsi la vita inutilmente
local function riordinaTabella(t) 
	local n = 0
	for _, _ in pairs(t) do
		n = n + 1
	end
	local i = 0
	for ii = 1, n do
		while true do
			i = i + 1
			if t[i] then
				break
			end
		end
		t[ii] = t[i]
	end
end

-- Classe Monitoraggio
--------------------------------------------------------------------------------

local Monitoraggio = {}

function Monitoraggio:new(o)
	o = o or {}
	setmetatable(o, self)
	self.__index = self
	return o
end

function Monitoraggio:newError(err) -- funzione di utilità per gli errori
	if not self.errori then
		self.errori = {}
	end
	self.errori[#self.errori + 1] = err
end

function Monitoraggio:organizzaArgomenti(args)
	-- minuscolizza tutti i parametri
	for k, v in pairs(args) do
		if type(k) == "string" then
			local k_min = mw.ustring.lower(k)
			if k_min ~= k and args[k_min] then
				self:newError("Parametro <kbd>" .. k_min .. "</kbd> inserito più volte con un diverso uso della maiuscola.")
				args[k] = nil
			elseif k_min ~= k then
				args[k_min] = v
				args[k] = nil
			end
		end
	end
	self.voti = {}
	for _, s in ipairs(config.campi) do
		local voto = args[s] or 'NC'
		voto = string.upper(voto)
		if config.voti[voto] then
			self.voti[s] = config.voti[voto]
		elseif voto ~= 'NC' then
			self:newError("Valore \"" .. voto .. "\" non riconosciuto per il campo <kbd>" .. s .. "</kbd>.")
		end
		args[s] = nil
	end
	for _, s in ipairs(config.altri_parametri) do
		self[s] = args[s]
		args[s] = nil
	end
	if args.progetto and args.progetto1 then
		self:newError("<kbd>progetto</kbd> e <kbd>progetto1</kbd> entrambi specificati, sono due donominazioni alternative per il primo progetto, i seguenti vanno numerati a partire da 2")
		args.progetto = nil
	elseif args.progetto then
		args.progetto1 = args.progetto
		args.progetto = nil
	end
	self.progetti = {}
	for k, v in pairs(args) do
		if string.find(k, "^progetto%d+$") then
			local i = tonumber(k:match("^progetto(%d+)$"))
			self.progetti[i] = {nome = v}
			-- attinge alla tabella di configurazione per ottenere il nome completo del progetto
			local v_maius = italiano:ucfirst(v)
			self.progetti[i]['link'] = config.progetti[v] or config.progetti[v_maius] or v_maius
			args[k] = nil
			local imp = args['importanza'..i]
			if imp and not config.importanza[imp] then
				self:newError("Valore <kbd>".. imp .."</kbd> non riconosciuto per il parametro <kbd>importanza".. i .."</kbd>.")
			end
			self.progetti[i]['importanza'] = config.importanza[imp] or 5
			args['importanza'..i] = nil
		elseif not string.find(k, "^importanza%d+$") then
			self:newError("Parametro <kbd>" .. k .. "</kbd> non riconosciuto.")
		end
	end
	riordinaTabella(self.progetti)
	if #self.progetti == 0 then
		self:newError("nessun progetto specificato")
--[[	elseif #self.progetti > 4 then
		self:newError("più di quattro progetti specificati")
		for i = 5, #self.progetti do
			self.progetti[i] = nil
		end -- ]]
	end
end

-- crea una firma a partire dal solo nome utente. se invece c'è una firma con data, estrapola la data
function Monitoraggio:trovaUtente()
	if mw.ustring.find(self.utente, '%[%[[Uu]tente:') then
		local n, _, data = mw.ustring.find(self.utente, ' %d%d:%d%d, %d?%d (%a+ %d%d%d%d)')
		if n then
			self.data = self.data or data
			-- toglie ora e data e i trattini iniziali dalla firma
			self.utente = mw.ustring.gsub(mw.ustring.sub(self.utente, 1, n-1), '$--', '')
		end
	else
		self.utente = '[[utente:'.. self.utente ..'|'.. self.utente ..']] ([[discussioni utente:'.. self.utente ..'|msg]])'
	end
end

-- funzione di supporto: trova i campi vuoti relativi alla valutazione (accuratezza, scrittura...)
function Monitoraggio:trovaCampiVuoti()
	local out = {}
	for _, v in ipairs(config.campi) do
		if not self.voti[v] then
			out[#out+1] = v
		end
	end
	if #out > 0 then
		return out
	end
end

function Monitoraggio:assegnaLivello()
	local t = self.voti
	if next(t) == nil then
		self.livello = -1
	else
		-- prima si calcola la media dei valori
		local tot, n_tot = 0, 0
		for _, n in pairs(t) do
			n_tot = n_tot+1
			tot = tot+n
		end
		local media = tot/n_tot
		-- arrotondata:
		if media-math.floor(media) > 0.5 then
			media = math.ceil(media)
		else
			media = math.floor(media)
		end
		-- poi si controlla se alcuni valori forzano il risultato verso il basso
		local tetto
		local function impostaTetto(n, t, v)
			if media > n and (not tetto or tetto >= n) then
				tetto = n
				t[#t+1] = v
			end
		end
		self.migliora, self.compila = {}, {}
		if not t.accuratezza then
			impostaTetto(0, self.compila, 'accuratezza')
		else
			impostaTetto(t.accuratezza, self.migliora, 'accuratezza')
		end
		if not t.fonti then
			impostaTetto(2, self.compila, 'fonti')
		else
			impostaTetto(t.fonti+1, self.migliora, 'copertura di fonti')
		end
		if not t.scrittura then
			impostaTetto(3, self.compila, 'scrittura')
		end
		if not t.immagini then
			impostaTetto(4, self.compila, 'immagini')
		end
		self.livello = tetto or media
	end
end

function Monitoraggio:creaCategorie()
	local out = self.categorie or {}
	--[=[
	out[#out + 1] = "[[Categoria:Voci monitorate - " .. self.livello .. "]]"
	for _, prg in ipairs(self.link_progetti) do
		local indirizzo = "Voci monitorate Progetto " .. prg .. " - " .. self.livello
		if mw.title.makeTitle(Categoria, indirizzo):esist() then
			out[#out + 1] = "[[Categoria:" .. indirizzo .. "]]"
		end
		end
	for k, v in pairs(self.voti) do
		out[#out + 1] = "[[Categoria:Voci monitorate - " .. k .. " " .. v .. "]]"
		for _, prg in ipairs(self.link_progetti) do
			local indirizzo = "Progetto:" .. prg .. "/Tabella monitoraggio automatico - " .. self.livello
			if mw.title.makeTitle(Categoria, indirizzo):esist() then
				out[#out + 1] = "[[Categoria:" .. indirizzo .. "]]"
			end
		end
	end
	if not self.data then
		self:newError("data non specificata")
	else
		local indirizzo = "Voci monitorate - " .. self.data
		if mw.title.makeTitle(Categoria, indirizzo):esist() then
			out[#out + 1] = "[[Categoria:" .. indirizzo .. "]]"
		else
			self:newError("data non riconosciuta, inserire: <code>data = " .. italiano:formatDate("F Y") .. "</code>")
		end
	end
	-- ]=]
	self.categorie = out
end

-- funzione che crea il primo box del template, cioè quello relativo ai progetti
function Monitoraggio:creaPrimoContenitore()
	local out = mw.html.create('table'):cssText("margin: 0 10% 0.2em 10%; border: thin solid #a7d7f9; background-color: #f0eeff;")
	if #self.progetti == 1 then
		local prg = self.progetti[1]
		local intestazione = 'La voce <b>'..mw.title.getCurrentTitle().text..'</b> è di '.. config.importanza_definizione[prg.importanza] ..' per il [[progetto:'.. prg.link .. '|progetto '.. prg.nome ..
		                     ']] di Wikipedia ([[Progetto:'.. prg.link ..'/Monitoraggio voci|tabella di monitoraggio]]), un\'iniziativa di coordinamento e collaborazione rivolta a migliorare le voci riguardanti lo stesso tema. Puoi segnalare nuove discussioni riguardo a questa voce nel [[discussioni progetto:'..
		                     prg.link ..'|bar tematico del progetto]].'
		if self['modello di voce'] then
			intestazione = intestazione..' Per questo genere di voci è presente un [['.. self['modello di voce'] ..'|modello da seguire]].'
		end
		out:tag('tr')
			:tag('td')
				:addClass("avviso-immagine")
				:wikitext('[[File:'.. iconaArgomento{prg.nome, 'Crystal Clear action viewmag.png'} ..'|40x40px]]')
				:done()
			:tag('td')
				:addClass("avviso-testo")
				:wikitext(intestazione)
	elseif #self.progetti > 1 then
		local intestazione = 'La voce <b>'..mw.title.getCurrentTitle().text..'</b> è monitorata da '..#self.progetti..
			' [[wikipedia:progetto|progetti]] di Wikipedia, iniziative di coordinamento e collaborazione rivolte a migliorare le voci riguardanti i temi interessati. Puoi segnalare nuove discussioni riguardo a questa voce nei [[wp:bar tematico|bar tematici]] relativi a ciascun progetto.'
		if self['modello di voce'] then
			intestazione = intestazione..' Per questo genere di voci è presente un [['.. self['modello di voce'] ..'|modello da seguire]].'
		end
		out:addClass("mw-collapsible")
			:tag('tr')
				:tag('td')
					:addClass("avviso-immagine")
					:wikitext('[[File:Crystal Clear action viewmag.png|40px]]')
					:done()
				:tag('td')
					:addClass("avviso-testo")
					:wikitext(intestazione)
					:done()
				:tag('td')
					:cssText("vertical-align: top")
					:tag('div')
						:cssText("width: 5em;")
		local elenco = out:tag('tr'):tag('td'):attr('colspan', "3"):tag('table')
		elenco:cssText("clear: both; width: 100% !important; border-collapse: collapse;")
		-- creo una tabella che contenga l'indice dei progetti per grado di importanza
		local gradi_interesse = {{}, {}, {}, {}, {}}
		for _, prg in ipairs(self.progetti) do
			table.insert(gradi_interesse[prg.importanza], prg)
		end
		for importanza, grado in ipairs(gradi_interesse) do
			for i, prg in ipairs(grado) do
				-- procedo per ogni progetto, in ordine di importanza, a creare una riga con icona e collegamenti
				local riga = elenco:tag('tr')
				riga:cssText("background-color: white; border: thin solid #D8D8D8;")
				riga:tag('td')
					:cssText("width: 20px; text-align: center;")
					:wikitext('[[File:'.. iconaArgomento{prg.nome, 'Crystal Clear app ksirtet.png'} ..'|20x20px]]')
				local inizio_frase = 'La voce è di '.. config.importanza_definizione[importanza] ..' per'
				local fine_frase = 'il [[Progetto:'.. prg.link .. '|progetto '.. prg.nome ..']] ([[Progetto:'.. prg.link ..
				                   '/Monitoraggio voci|monitoraggio]]&nbsp;<b>·</b> [[Discussioni progetto:'.. prg.link ..'|bar tematico]])'
				if #grado == 1 then
					riga:tag('td')
						:cssText("padding-left: 0.4em;")
						:wikitext(inizio_frase ..' '.. fine_frase)
				elseif i == 1 then
					riga:tag('td')
						:attr('rowspan', #grado)
						:cssText("width: 17em; text-align: right; padding-right: 0.3em; vertical-align:top;")
						:wikitext(inizio_frase ..':')
					riga:tag('td')
						:wikitext(fine_frase)
				else
					riga:tag('td')
						:wikitext(fine_frase)
				end
			end
		end
	end
	return out
end

-- funzione che crea il secondo box del template, cioè quello relativo al monitoraggio
function Monitoraggio:creaSecondoContenitore()
	local modifica = mw.title.getCurrentTitle():fullUrl{action = 'edit', section = 0}
	local out = mw.html.create('table')
		:cssText("margin: 0 10% 0.2em 10%; border: thin solid #a7d7f9; background-color: white;")
	-- nel caso la voce debba essere ancora monitorata
	if self.livello == -1 then
		out:tag('tr')
			:tag('td')
				:addClass("avviso-immagine")
				:wikitext('[[file:'.. config.icona[0] ..'|40px]]')
				:done()
			:tag('td')
				:addClass("avviso-testo")
				:wikitext('Questa voce non è stata ancora [[aiuto:monitoraggio|monitorata]]. ['.. modifica ..' Fallo] adesso!')
	-- nel caso il monitoraggio sia stato compilato
	else
		local intestazione = {'La voce <b>'.. mw.title.getCurrentTitle().text ..'</b> è stata monitorata nel mese di '}
		intestazione[2] = self.data or '<b class="error" style="font-size:smaller">data mancante</b>[[categoria:Voci monitorate - non datate]]'
		intestazione[3] = ' da '.. (self.utente or '<b class="error" style="font-size:smaller">valutatore mancante</b>[[categoria:Voci monitorate - non firmate]]')
		if self.livello == 0 then
			intestazione[4] = ', ma non può ancora ricevere una valutazione. È necessaria una valutazione riguardo l\'accuratezza della voce per assegnargli un livello qualitativo.'
		else
			intestazione[4] = ' ed è classificata di <b>'.. config.livelli[self.livello] ..'</b>.'
			local serve = {}
			serve[1] = #self.migliora > 0 and ' una migliore '.. table.concat(self.migliora, ' e una migliore ') or nil
			serve[#serve+1] = #self.compila > 0 and ' una valutazione per il parametro <code>|'.. self.compila[1] ..'=</code>' or nil
			intestazione[5] = #serve > 0 and ' È necessaria'.. table.concat(serve, ' nonché') ..' per assegnare alla voce un livello maggiore.' or nil
		end
		out:addClass("mw-collapsible")
			:tag('tr')
				:tag('td')
					:addClass("avviso-immagine")
					:wikitext('[[file:'.. config.icona[self.livello] ..'|40px]]')
					:done()
				:tag('td')
					:addClass("avviso-testo")
					:wikitext(table.concat(intestazione))
					:done()
				:tag('td')
					:cssText("vertical-align: top")
					:tag('div')
						:cssText("width: 5em;")
		local elenco = out:tag('tr'):tag('td'):attr('colspan', "3"):tag('table')
		elenco:cssText("clear: both; width: 100% !important; border-collapse: collapse;")
		for _, parametro in ipairs(config.campi) do
			local voto = self.voti[parametro]
			if voto then
				elenco:tag('tr')
					:cssText("background-color: white; border: thin solid #D8D8D8;")
					:tag('td')
						:cssText("width: 20px;")
						:wikitext('[[file:'.. config.icona[voto] ..'|20px]]')
						:done()
					:tag('td')
						:wikitext(config.descrizione_stato[parametro][voto])
			end
		end
		local vuoti = self:trovaCampiVuoti()
		if vuoti then
			local testo = 'Per questa tabella '.. (#vuoti == 1 and 'deve essere ancora compilato il campo' or 'devono essere ancora compilati i campi') ..' <code>|'.. mw.text.listToText(vuoti, '=</code>, <code>|', '=</code> e <code>|') ..'</code>.'
			elenco:tag('tr')
				:cssText("background-color: white; border: thin solid #D8D8D8;")
				:tag('td')
					:cssText("width: 20px;")
					:wikitext('[[file:'.. config.icona[0] ..'|20px]]')
					:done()
				:tag('td')
					:wikitext(testo)
		end
	end
	if self.note then
		out:tag('tr')
			:tag('td')
				:attr('colspan', "3")
				:cssText("padding-left: 4px;")
				:wikitext('<b>Note</b>: '.. self.note)
	end
	return out
end
	
function Monitoraggio:__tostring()
	local out = tostring(self:creaPrimoContenitore()) .. tostring(self:creaSecondoContenitore())
	local err, cat = self.errori, self.categorie
	if err then
		out = out .. '<li class="error"><ul style="display: block;">' .. table.concat(err, '</ul><ul style="display: block;">') .. '</ul></li>'
	end
	if cat then
		if err then
			cat[#cat + 1] = "[[Categoria:Errori di compilazione del template Monitoraggio]]"
		end
		out = out .. table.concat(cat, "\n")
	end
	return out
end

-- Funzione di invoke
--------------------------------------------------------------------------------

local p = {}

-- per il debug
function p.create(t)
	return Monitoraggio:new(t)
end

function p.main(frame)
	local args = getArgs(frame)
	local out = Monitoraggio:new()
	out:organizzaArgomenti(args)
	if out.utente then
		out:trovaUtente()
	end
	out:assegnaLivello()
	if mw.title.getCurrentTitle().namespace == 1 then
		out:creaCategorie()
	end
	return tostring(out)
end

return p