Questo modulo contiene funzioni utili alla declinazione dei sostantivi latini.


local p={}

function wikitabella(decl, variante, altri_casi, sing, pl)
	nome_caso = {"nominativo", "", "genitivo", "", "dativo", "", "accusativo", "", "vocativo", "", "ablativo"}
	nome_altro_caso = {"locativo", ""}
	
	if pl and (string.lower(pl) == "no"
		or string.lower(pl) == "n")
	then
							--SOLO SINGOLARE
		tab = ""
		tab = tab..[[{|border="1" cellpadding="2" style="float:right; margin:1em 1em 1em 0;background:#f0fff0;color:#000;border:1px #aaaaaa solid;border-collapse:collapse"]].."\n"
		tab = tab.."|-".."\n"
		tab = tab.."|+"..titolo().."\n"
		tab = tab..[[|- style="border: 1px solid #f0fff0"]].."\n"	
		tab = tab..[[|style="border: 1px solid #f0fff0"|  ]].."\n"
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0"|''singolare'']].."\n"
		tab = tab..[[|- style="border: 1px solid #f0fff0"]].."\n"
		for t=1, 12, 2
		do
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0"| '']]..nome_caso[t] ..[['']].."\n"
		if mancante(decl[t]) then tab = tab.."|—" --testo visualizzato nel caso in cui una forma flessa sia mancante
			else
		tab = tab..'|style="border: 1px solid #f0fff0"|[['..link(decl[t]).."|"..decl[t].."]]"
		end
		if variante[1][t] and variante[1][t]~= "" then 
			tab = tab.. ", [["..link(variante[1][t]).."|"..variante[1][t].."]]"  
			if variante[2][t] and variante[2][t]~= "" then 
			tab = tab.. ", [["..link(variante[2][t]).."|"..variante[2][t].."]]" 
			end
		end
		tab = tab.."\n"
		tab = tab.."|-".."\n"
		end
		for t = 1, #altri_casi, 2 do
		if altri_casi[t] then
			tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0"| '']]..nome_altro_caso[t]..[[]]..[['']].."\n"
			tab = tab..'|style="border: 1px solid #f0fff0"|[['..link(altri_casi[t]).."|"..altri_casi[t].."]]"
			tab = tab.."\n"
			tab = tab..[[|- style="border: 1px solid #f0fff0"]].."\n"
		end
		end
		tab = tab.."|}"
	elseif sing and (string.lower(sing) == "no"
		or string.lower(sing) == "n")
	then
							--SOLO PLURALE
		tab = ""
		tab = tab..[[{|border="1" cellpadding="2" style="float:right; margin:1em 1em 1em 0;background:#f0fff0;color:#000;border:1px #aaaaaa solid;border-collapse:collapse"]].."\n"
		tab = tab.."|-".."\n"
		tab = tab.."|+"..titolo().."\n"
		tab = tab..[[|- style="border: 1px solid #f0fff0"]].."\n"	
		tab = tab.."|  ".."\n"
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0"|''plurale'']].."\n"
		tab = tab..[[|- style="border: 1px solid #f0fff0"]].."\n"
		
		for t=2, 12, 2
		do
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0"| '']]..nome_caso[t-1] ..[['']].."\n"
		if mancante(decl[t]) then tab = tab.."|—" --testo visualizzato nel caso in cui una forma flessa sia mancante
			else
		tab = tab..'|style="border: 1px solid #f0fff0"|[['..link(decl[t]).."|"..decl[t].."]]"
		end
		if variante[1][t] and variante[1][t]~= "" then 
			tab = tab.. ", [["..link(variante[1][t]).."|"..variante[1][t].."]]"  
			if variante[2][t] and variante[2][t]~= "" then 
			tab = tab.. ", [["..link(variante[2][t]).."|"..variante[2][t].."]]" 
			end
		end
		tab = tab.."\n"
		tab = tab.."|-".."\n"
		end
		for t = 2, #altri_casi, 2 do
		if altri_casi[t] then
			tab = tab..[[!bgcolor="#87cefa style="border: 1px solid #f0fff0""| '']]..nome_altro_caso[t-1]..[[]]..[['']].."\n"
			tab = tab.."|[["..link(altri_casi[t]).."|"..altri_casi[t].."]]"
			tab = tab.."\n"
			tab = tab.."|-".."\n"
		end
		end
		tab = tab.."|}"
	else
							--SINGOLARE E PLURALE
		tab = ""
		tab = tab..[[{|border="1" cellpadding="2" style="float:right; margin:1em 1em 1em 0;background:#f0fff0;color:#000;border:1px #aaaaaa solid;border-collapse:collapse"]].."\n"
		tab = tab.."|-".."\n"
		tab = tab.."|+"..titolo().."\n"
		tab = tab..[[|- style="border: 1px solid #f0fff0"]].."\n"	
		tab = tab.."|  ".."\n"
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0""|''singolare'']].."\n"
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0""|''plurale'']].."\n"
		tab = tab.."|-".."\n"
		
		for t=1, 12, 2
		do
		tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0""| '']]..nome_caso[t] ..[['']].."\n"
		if mancante(decl[t]) then tab = tab.."|—" --testo visualizzato nel caso in cui una forma flessa sia mancante
			else
		tab = tab..'|style="border: 1px solid #f0fff0"|[['..link(decl[t])..'|'..decl[t]..']]'
		end
		if variante[1][t] and variante[1][t]~= "" then 
			tab = tab.. ", [["..link(variante[1][t]).."|"..variante[1][t].."]]"  
			if variante[2][t] and variante[2][t]~= "" then 
			tab = tab.. ", [["..link(variante[2][t]).."|"..variante[2][t].."]]" 
			end
		end
		tab = tab.."\n"
		if mancante(decl[t+1]) then tab = tab.."|—" --testo visualizzato nel caso in cui una forma flessa sia mancante
			else
		tab = tab..'|style="border: 1px solid #f0fff0"|[['..link(decl[t+1]).."|"..decl[t+1].."]]"
		end
		if variante[1][t+1] and variante[1][t+1]~= "" then 
			tab = tab.. ", [["..link(variante[1][t+1]).."|"..variante[1][t+1].."]]"  
			if variante[2][t+1] and variante[2][t+1]~= "" then 
			tab = tab.. ", [["..link(variante[2][t+1]).."|"..variante[2][t+1].."]]" 
			end
		end
		tab = tab.."\n"
		tab = tab.."|-".."\n"
	end
	for t = 1, #altri_casi, 2 do
		if altri_casi[t] or altri_casi[t+1] then
			tab = tab..[[!bgcolor="#87cefa" style="border: 1px solid #f0fff0"| '']]..nome_altro_caso[t]..[[]]..[['']].."\n"
			for m = t,t+1 do
				if altri_casi[m] then tab = tab..'|style="border: 1px solid #f0fff0"|[['..link(altri_casi[m]).."|"..altri_casi[m].."]]"
				else
				tab = tab.."|—" 
				end
			tab = tab.."\n"
			end
			tab = tab.."|-".."\n"
		end
	end
		tab = tab.."|}"
	end
	return tab
end

function titolo()  --genera il titolo della tabella e aggiunge la relativa categoria per la declinazione
	local testo = ""
	if string.sub(tipo, 1, 1) == "1" then
		testo = "Prima declinazione"
		cat = "[[Categoria:Sostantivi di prima declinazione in latino]]"
	elseif string.sub(tipo, 1, 1) == "2" then
		testo = "Seconda declinazione"
		cat = "[[Categoria:Sostantivi di seconda declinazione in latino]]"
			elseif string.sub(tipo, 1, 1) == "3" then
		testo = "Terza declinazione"
		cat = "[[Categoria:Sostantivi di terza declinazione in latino]]"
			elseif string.sub(tipo, 1, 1) == "4" then
		testo = "Quarta declinazione"
		cat = "[[Categoria:Sostantivi di quarta declinazione in latino]]"
			elseif string.sub(tipo, 1, 1) == "5" then
		testo = "Quinta declinazione"
		cat = "[[Categoria:Sostantivi di quinta declinazione in latino]]"
	end
	if string.sub(tipo, 2, 2) == "n" then
		testo = testo..", neutro [[Categoria:Sostantivi neutri in latino]]"
	end
	if irreg then
		testo = testo.." (irregolare)"
	end
	if altro_titolo and altro_titolo ~= "" then
		testo = altro_titolo
	end
	return testo.. cat
end

function irregolare(ns, np, gs, gp, ds, dp, acs, acp, vs, vp, as, ap)	--funzione che gestisce le forme flesse irregolari
	casoirreg = {ns, np, gs, gp, ds, dp, acs, acp, vs, vp, as, ap}		--inserite dall’utente
	for i = 1, 12
	do
		if casoirreg[i]
		and casoirreg[i] ~= "" then
			irreg = true
			decl[i] = casoirreg[i]
		end
	end
end

function mancante(argm)
	if argm == "-" or string.lower(argm) == "mancante" then --controlla se una forma flessa
		return true											--è stata indicata come mancante
	end
end

function link(parola)	--rimuove i segni diacritici dalle vocali della parola
	local lun = {"Ā", "ā", "Ē", "ē", "Ī", "ī", "Ō", "ō", "Ū", "ū", "ȳ", "Ȳ"}
	local bre = {"Ă", "ă", "Ĕ", "ĕ", "Ĭ", "ĭ", "Ŏ", "ŏ", "Ŭ", "ŭ", "y", "Y"}
	local voc = {"A", "a", "E", "e", "I", "i", "O", "o", "U", "u", "y", "Y"}
	for i= 1, 12
	do
		parola = mw.ustring.gsub(parola, lun[i], voc[i])
		parola = mw.ustring.gsub(parola, bre[i], voc[i])
	end
	return parola
end

function test_voc(lettera)		--restituisce ‘true’ se la lettera che riceve è una vocale
	local voc = {
					"Ā", "ā", "Ē", "ē", "Ī", "ī", "Ō", "ō", "Ū", "ū", "ȳ", "Ȳ",
					"Ă", "ă", "Ĕ", "ĕ", "Ĭ", "ĭ", "Ŏ", "ŏ", "Ŭ", "ŭ", "y", "Y",
					"A", "a", "E", "e", "I", "i", "O", "o", "U", "u", "y", "Y",
																		}
	test = false
	local i=0
	repeat
		i = i+1
		if lettera == voc[i] then test = true  end
	until voc[i] == nil
	return test
end

function test_cons(lettera)	--restituisce ‘true’ se la lettera che riceve non è una vocale
	return not test_voc(lettera)
end

-- La seguente funzione suddivide in sillabe la parola che riceve
-- principali limitazioni:
--  • non vengono sillabati i nomi composti

function sillabe(parola)
	if sillaba == nil	--inizializza la tabella ‘sillaba’, che conterrà le sillabe della parola
	then n = 1 i = 1
		sillaba={}
	end
	local lettera = mw.ustring.sub(parola, i, i)	--lettera da analizzare
	if sillaba[n]==nil then sillaba[n]="" end	--inizializza la nuova sillaba
	sillaba[n]=sillaba[n]..lettera
	if test_voc(lettera)	--se la lettera analizzata è una vocale, allora passa alla nuova sillaba
	then
		n=n+1
	end
	min = mw.ustring.lower	--rende il testo minuscolo, quando, in una condizione, non importano le maiuscole
	if mw.ustring.len(parola)>1 then
		if mw.ustring.sub(min(link(parola)), 1, 2) == "ae" or mw.ustring.sub(min(link(parola)), 1, 2) == "oe" then n=n-1 end	--mantiene uniti i dittonghi
		if min(link(lettera)) == "u" and (mw.ustring.sub(min(sillaba[n-1]), mw.ustring.len(sillaba[n-1])-1, mw.ustring.len(sillaba[n-1])-1) == "q"	--non divide la sillaba quando ‘q’ precede ‘u’
			or mw.ustring.sub(min(sillaba[n-1]), mw.ustring.len(sillaba[n-1])-1, mw.ustring.len(sillaba[n-1])-1) == "g")	--lo stesso fa anche quando ‘g’ precede ‘u’
		and test_voc(mw.ustring.sub(parola, 2, 2))
		then n=n-1 end
		if test_cons(lettera) and sillaba[n-1] ~= nil and test_cons(mw.ustring.sub(parola, 2, 2)) and test_voc(mw.ustring.sub(sillaba[n-1], mw.ustring.len(sillaba[n-1])))
		then						--quando si susseguono più consonanti, riporta la prima consonante alla sillaba precedente…
			m = {"b", "d", "c", "f", "g", "p", "t", "v"}
			for k = 1, #m
			do
				if mw.ustring.find(mw.ustring.lower(lettera), m[k]) ~= nil
				then contiene_m = true end
			end
			if not contiene_m or	-- …a meno di casi particolari
			mw.ustring.sub(min(parola), 2, 2) ~= "l" and mw.ustring.sub(min(parola), 2, 2) ~= "r"
			then
				sillaba[n-1] = sillaba[n-1]..lettera
				sillaba[n]=nil
			end
		end
		sillabe(mw.ustring.sub(parola, i+1))
	end
	ultimalettera = mw.ustring.sub(sillaba[#sillaba], mw.ustring.len(sillaba[#sillaba]))
	if test_cons(ultimalettera) and mw.ustring.len(parola) == 1 and sillaba[n-1] ~= nil	--evita che la sillaba finale sia priva di vocali
	then
		tuttec = true	--variabile che indica se l’ultima sillaba ha solo consonanti
		for j=1, mw.ustring.len(sillaba[n])
		do if not test_cons(mw.ustring.sub(mw.ustring.len(sillaba[n]), j, j)) then tuttec = false end
	end
	if tuttec then	--se l’ultima variabile del vettore ‘sillaba’ ha solo consonanti
		sillaba[n-1] = sillaba[n-1]..sillaba[n]	--allora viene concatenata alla variabile che la precede
		sillaba[n]=nil
	end
	end
	return sillaba
end

function radicepiusuffisso()
	for i = 1, 12
	do
		decl[i] = radice..suff[i]
	end
end

function test_plur(sing)
	solopl = false
	if sing and (string.lower(sing) == "no"
		or string.lower(sing) == "n")
	then solopl = true
		return solopl
	end
end

function locativo(radice, loc, loc2)
	if loc and loc ~= "" then
		if mw.ustring.lower(loc) == "sì"
		or mw.ustring.lower(loc) == "si"
		or mw.ustring.lower(loc) == "s"
		or mw.ustring.lower(loc) == "yes"
		then
			loc = radice..loc2
		end
		return loc
	end
	return false
end

function errore(radice, parola, num) --funzione che gestisce i messaggi di errore
	if link(mw.ustring.sub(parola, -#radice)) ~= radice --in caso di terminazione del nome non corretta
	then
		error("Terminazione della "..num.."ª declinazione non riconosciuta")
	end
end

function p.prima( frame ) --PRIMA DECLINAZIONE
	nom = frame.args[1]
	decl = {}	-- tabella atta a contenere la declinazione del nome
	altricasi = {}
	var = {}
	tipo = "1"
	suff = {"ă", "ae", "ae", "ārŭm", "ae", "īs", "ăm", "ās", "ă", "ae", "ā", "īs"}
	radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
			--Solo per i pluralia tantum
			solopl= test_plur(frame.args.sing)
			if solopl and link(mw.ustring.sub(nom, -2)) == "ae"
			then radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
				else errore("a", nom, 1)
			end
			--Fine
	radicepiusuffisso()
	f = frame.args
	altricasi[1] = locativo(radice, f.locs, "ae") 	altricasi[2] = locativo(radice, f.locp, "īs") --locativo
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	var[1] = {f.ns2, f.np2, f.gs2, f.gp2, f.ds2, f.dp2, f.acs2, f.acp2, f.vs2, f.vp2, f.as2, f.ap2}
	var[2] = {f.ns3, f.np3, f.gs3, f.gp3, f.ds3, f.dp3, f.acs3, f.acp3, f.vs3, f.vp3, f.as3, f.ap3}
	altro_titolo = frame.args["titolo"]
	return wikitabella(decl, var, altricasi, f.sing, f.pl)
end

function p.seconda( frame ) --SECONDA DECLINAZIONE
	nom = frame.args[1]
	gen = frame.args[2]
	decl = {}
	altricasi = {}
	var = {}
	tipo = "2"
	if link(mw.ustring.sub(nom, -2)) == "us"
	then
		radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
		suff = {"ŭs", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "ĕ", "ī", "ō", "īs"}
		radicepiusuffisso()
	elseif link(mw.ustring.sub(nom, -2)) == "um"
		then
			tipo = "2n"
			radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
			suff = {"ŭm", "ă", "ī", "ōrŭm", "ō", "īs", "ŭm", "ă", "ŭm", "ă", "ō", "īs"}
			radicepiusuffisso()
	elseif link(mw.ustring.sub(nom, -1)) == "r" and gen and gen ~= ""
		then
			tipo = "2-er"
			radice = mw.ustring.sub(gen, 1, mw.ustring.len(gen)-1)
			suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
			radicepiusuffisso()
			decl[1] = nom
			decl[9] = nom
	elseif link(mw.ustring.sub(nom, -1)) == "r"
		then
			if link(mw.ustring.sub(nom, -2)) == "er" then 
				eccz = {"b", "c", "d", "f", "g", "p", "t", "v"} ri = false
				for i=1, #eccz
				do
					if mw.ustring.sub(nom, mw.ustring.len(nom)-2, mw.ustring.len(nom)-2) == eccz[i]
					then
						ri = true
					end
				end
				if ri == false
				then
					tipo = "2-er"
					radice = nom
					suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
					radicepiusuffisso()
				else
					tipo = "2-er-ri"
					radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2).."r"
					suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
					radicepiusuffisso()
					decl[1] = nom
					decl[9] = nom
				end
			else
				tipo = "2-r"
				radice = nom
				suff = {"", "ī", "ī", "ōrŭm", "ō", "īs", "ŭm", "ōs", "", "ī", "ō", "īs"}
				radicepiusuffisso()
			end
						--Solo per i pluralia tantum
						else
						solopl= test_plur(frame.args.sing)
						if solopl and link(mw.ustring.sub(nom, -1)) == "i"
						then radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
							suff = {"", "ī", "", "ōrŭm", "", "īs", "", "ōs", "", "ī", "", "īs"}
							radicepiusuffisso()
						elseif solopl and link(mw.ustring.sub(nom, -1)) == "a"
						then tipo = "2n"
							radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
							suff = {"", "ă", "", "ōrŭm", "", "īs", "", "ă", "", "ă", "", "īs"}
							radicepiusuffisso()
							else errore("er", nom, 2)
						end
						--Fine
	end
						
	f = frame.args
	altricasi[1] = locativo(radice, f.locs, "ī") 	altricasi[2] = locativo(radice, f.locp, "īs") --locativo
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	var[1] = {f.ns2, f.np2, f.gs2, f.gp2, f.ds2, f.dp2, f.acs2, f.acp2, f.vs2, f.vp2, f.as2, f.ap2}
	var[2] = {f.ns3, f.np3, f.gs3, f.gp3, f.ds3, f.dp3, f.acs3, f.acp3, f.vs3, f.vp3, f.as3, f.ap3}
	altro_titolo = frame.args["titolo"]
	return wikitabella(decl, var, altricasi, f.sing, f.pl)
end

function p.terza( frame ) --TERZA DECLINAZIONE
	nom = frame.args[1]
	gen = frame.args[2]
	neut = frame.args.n
	decl = {}
	altricasi = {}
	var = {}
	tipo = "3"
	parisillabo = false			--inizializza la variabile che indica se un nome è parisillabo
	local numsillabe_nom= #sillabe(nom)						--la funzione ‘sillabe’ usa una variabile globale
	local numsillabe_gen= #sillabe(gen) - numsillabe_nom	--è quindi necessario fare la differenza tra la dimensione finale e quella iniziale
	if numsillabe_nom == numsillabe_gen
	then
		parisillabo = true
	end
	if neut ~= nil				--controlla se l’utente ha specificato che il nome è neutro
	then
		if mw.ustring.lower(neut) == "sì"
		or mw.ustring.lower(neut) == "si"
		or mw.ustring.lower(neut) == "s"
		or mw.ustring.lower(neut) == "yes"
		then
			neut = true
		end
	end
	radice = mw.ustring.sub(gen, 1, mw.ustring.len(gen)-2)
	if not parisillabo and test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)))		-- I gruppo
	and not test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)-1, mw.ustring.len(radice)-1))
	then
		if neut == true
		then
			tipo = "3n-I"
			suff = {"", "ă", "ĭs", "ŭm", "ī", "ĭbŭs", "", "ă", "", "ă", "ĕ", "ĭbŭs"}
		else
			tipo = "3-I"
			suff = {"", "ēs", "ĭs", "ŭm", "ī", "ĭbŭs", "ĕm", "ēs", "", "ēs", "ĕ", "ĭbŭs"}
		end
	end
	if parisillabo or																		-- II gruppo
	(not parisillabo and test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)))
		and test_cons(mw.ustring.sub(radice, mw.ustring.len(radice)-1, mw.ustring.len(radice)-1)))
	then
		if neut == true
		then
			tipo = "3n-II"
			suff = {"", "ă", "ĭs", "ĭŭm", "ī", "ĭbŭs", "", "ă", "", "ă", "ĕ", "ĭbŭs"}
		else
			tipo = "3-II"
			suff = {"", "ēs", "ĭs", "ĭŭm", "ī", "ĭbŭs", "ĕm", "ēs", "", "ēs", "ĕ", "ĭbŭs"}
		end
	end
	if neut == true and (link(mw.ustring.sub(nom, mw.ustring.len(nom)))== "e"				-- III gruppo
		or (link(mw.ustring.sub(nom, mw.ustring.len(nom)-1)) == "al" and link(mw.ustring.sub(gen, mw.ustring.len(gen)-3)) == "alis")
		or (link(mw.ustring.sub(nom, mw.ustring.len(nom)-1)) == "ar" and link(mw.ustring.sub(gen, mw.ustring.len(gen)-3)) == "aris"))
	then
		tipo = "3n-III"
		suff = {"", "ĭă", "ĭs", "ĭŭm", "ī", "ĭbŭs", "", "ĭă", "", "ĭă", "ī", "ĭbŭs"}
	end
	if suff ~= nil then
		radicepiusuffisso()
	end
	decl[1] = nom
	decl[9] = nom
	if neut == true
	then
		decl[7] = nom
	end
				--Solo per i pluralia tantum
				solopl= test_plur(frame.args.sing)
				if solopl
				then
					if neut == true and link(mw.ustring.sub(nom, -2)) == "ia" then
					tipo = "3n"
					radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
					suff = {"", "ĭă", "", "ĭŭm", "", "ĭbŭs", "", "ĭă", "", "ĭă", "", "ĭbŭs"}
					radicepiusuffisso()
				elseif neut == true and link(mw.ustring.sub(nom, -1)) == "a" then
					tipo = "3n"
					radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
					suff = {"", "ă", "", "ŭm", "", "ĭbŭs", "", "ă", "", "ă", "", "ĭbŭs"}
					if link(mw.ustring.sub(gen, -3)) == "ium" then
						suff[4] = "ĭŭm" end
						radicepiusuffisso()
					elseif link(mw.ustring.sub(gen, -2)) == "um" then
						radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
						suff = {"", "ēs", "", "ŭm", "", "ĭbŭs", "", "ēs", "", "ēs", "", "ĭbŭs"}
						if link(mw.ustring.sub(gen, -3)) == "ium" then
							suff[4] = "ĭŭm" end
						radicepiusuffisso()
					end
					else errore("is", gen, 3)
				end
				--Fine
	f = frame.args
	altricasi[1] = locativo(radice, f.locs, "ī") --locativo
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	var[1] = {f.ns2, f.np2, f.gs2, f.gp2, f.ds2, f.dp2, f.acs2, f.acp2, f.vs2, f.vp2, f.as2, f.ap2}
	var[2] = {f.ns3, f.np3, f.gs3, f.gp3, f.ds3, f.dp3, f.acs3, f.acp3, f.vs3, f.vp3, f.as3, f.ap3}
	altro_titolo = frame.args["titolo"]
	return wikitabella(decl, var, altricasi, f.sing, f.pl)
end

function p.quarta( frame ) --QUARTA DECLINAZIONE
	nom = frame.args[1]
	decl = {}
	altricasi = {}
	var = {}
	tipo = "4"
	if link(mw.ustring.sub(nom, -1)) == "u"
	then
		tipo = "4n"
		radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-1)
		suff = {"ū", "ŭă", "ūs", "ŭŭm", "ū", "ĭbŭs", "ū", "ŭă", "ū", "ŭă", "ū", "ĭbŭs"}
	else
		tipo = "4"
		radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
		suff = {"ŭs", "ūs", "ūs", "ŭŭm", "ŭī", "ĭbŭs", "ŭm", "ūs", "ŭs", "ūs", "ū", "ĭbŭs"}
			--Solo per i pluralia tantum
				solopl= test_plur(frame.args.sing)
				if solopl and link(mw.ustring.sub(nom, -2)) == "ua"
				then tipo = "4n"
				radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
				suff = {"", "ŭă", "", "ŭŭm", "", "ĭbŭs", "", "ŭă", "", "ŭă", "", "ĭbŭs"}
				else errore("us", nom, 4)
				end
				--Fine
	end
	radicepiusuffisso()
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	var[1] = {f.ns2, f.np2, f.gs2, f.gp2, f.ds2, f.dp2, f.acs2, f.acp2, f.vs2, f.vp2, f.as2, f.ap2}
	var[2] = {f.ns3, f.np3, f.gs3, f.gp3, f.ds3, f.dp3, f.acs3, f.acp3, f.vs3, f.vp3, f.as3, f.ap3}
	altro_titolo = frame.args["titolo"]
	return wikitabella(decl, var, altricasi, f.sing, f.pl)
end

function p.quinta( frame ) --QUINTA DECLINAZIONE
	nom = frame.args[1]
	decl = {}
	altricasi = {}
	var = {}
	tipo = "5"
	radice = mw.ustring.sub(nom, 1, mw.ustring.len(nom)-2)
	if test_voc(mw.ustring.sub(radice, -1))
	then
		tipo = "5-i"
		suff = {"ēs", "ēs", "ēī", "ērŭm", "ēī", "ēbŭs", "ĕm", "ēs", "ēs", "ēs", "ē", "ēbŭs"}
	else
		tipo = "5"
		suff = {"ēs", "ēs", "ĕī", "ērŭm", "ĕī", "ēbŭs", "ĕm", "ēs", "ēs", "ēs", "ē", "ēbŭs"}
	end
	errore("es", nom, 5)
	radicepiusuffisso()
	f = frame.args
	irregolare(f.ns, f.np, f.gs, f.gp, f.ds, f.dp, f.acs, f.acp, f.vs, f.vp, f.as, f.ap)
	var[1] = {f.ns2, f.np2, f.gs2, f.gp2, f.ds2, f.dp2, f.acs2, f.acp2, f.vs2, f.vp2, f.as2, f.ap2}
	var[2] = {f.ns3, f.np3, f.gs3, f.gp3, f.ds3, f.dp3, f.acs3, f.acp3, f.vs3, f.vp3, f.as3, f.ap3}
	altro_titolo = frame.args["titolo"]
	return wikitabella(decl, var, altricasi, f.sing, f.pl)
end

return p