Module:Vep-nominals

local m_utilities = require("Module:utilities")
local m_links = require("Module:links")

local export = {}

local lang = require("Module:languages").getByCode("vep")

-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
	local infl_type = frame.args[1] or error("Inflection type has not been specified. Please pass parameter 1 to the module invocation")
	local args = frame:getParent().args
	
	if not inflections[infl_type] then
		error("Unknown inflection type '" .. infl_type .. "'")
	end
	
	local data = {forms = {}, title = nil, categories = {}}
	data.n = args["n"]; if data.n == "" then data.n = nil end
	
	-- Generate the forms
	inflections[infl_type](args, data)
	
	-- Postprocess
	if infl_type ~= "ppron" then
		postprocess(args, data)
	end
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


--[=[
	Inflection functions
]=]--

local function get_param(args, first)
	local param = args[first] or ""
	
	if param == "" and mw.title.getCurrentTitle().nsText == "Template" then
		return "{{{" .. first .. "}}}"
	end
	
	return param
end

local infl_types = {
	-- One stem
	["¦n¦d¦d"] = true, -- i- and i-diphthong stem
	["¦n¦d¦id"] = true, ["?¦n¦?¦id"] = true, -- o-, u-, ü-stem
	["¦n¦d¦?d"] = true,
	["a¦an¦ad¦id"] = true, ["a¦an¦ad¦oid"] = true, ["a¦an¦ad¦?d"] = true,
	["ä¦än¦äd¦id"] = true,
	["e¦en¦ed¦id"] = true,
	["i¦en¦ed¦id"] = true,
	
	-- One stem, contraction in partitive
	["i¦en¦t¦id"] = true,
	["mi¦men¦nt¦mid"] = true,
	["zi¦den¦t¦zid"] = true, ["zi¦den¦t¦?d"] = true,
	
	-- Apocope in nominative
	["¦an¦ad¦id"] = true, ["¦an¦ad¦oid"] = true, ["¦an¦ad¦?d"] = true,
	["¦än¦äd¦id"] = true, ["¦än¦äd¦?d"] = true,
	["¦en¦ed¦id"] = true, ["¦en¦ed¦?d"] = true,
	["¦in¦id¦id"] = true,
	["¦on¦od¦oid"] = true,
	["¦un¦ud¦uid"] = true,
	
	-- Apocope in nominative, with palatalization
	["b'¦ben¦bed¦bid"] = true,
	["g'¦gen¦ged¦gid"] = true,
	["g'¦gin¦gid¦gid"] = true,
	["g'¦gän¦gäd¦gid"] = true,
	["l'¦lin¦lid¦lid"] = true,
	["l'l'¦llen¦lled¦llid"] = true,
	["l'l'¦llän¦lläd¦llid"] = true,
	["m'¦men¦med¦mid"] = true,
	["m'¦män¦mäd¦mid"] = true,
	
	-- Apocope in nominative, with j > i
	["i¦jan¦jad¦jid"] = true, ["i¦jan¦jad¦joid"] = true, ["i¦jan¦jad¦?d"] = true,
	["i¦jun¦jud¦juid"] = true,
	
	-- Apocope in nominative, contraction in partitive
	["¦en¦t¦id"] = true,
	["ič¦ičen¦št¦ičid"] = true,
	["d¦den¦t¦zid"] = true,
	["z'¦dan¦t¦zid"] = true,
	["z'¦den¦t¦zid"] = true, ["z'¦den¦t¦?d"] = true,
	["ž¦den¦t¦žid"] = true,
	["t¦den¦t¦zid"] = true,
	["¦den¦t¦zid"] = true,
	["z¦han¦st¦hid"] = true,
	["z'¦hen¦st¦hid"] = true,
	["l'¦len¦l't¦lid"] = true,
	["m'¦men¦nt¦mid"] = true,
	["n'¦nen¦n't¦nid"] = true,
	["r'¦ren¦r't¦rid"] = true,
	["s'¦sen¦st¦sid"] = true,
	["z¦sen¦st¦sid"] = true,
	["z'¦zen¦st¦zid"] = true,
	
	-- Contraction in genitive
	["ged¦ktan¦ktad¦ktoid"] = true,
	["ked¦ttan¦ttad¦ttoid"] = true,
	["av¦van¦vad¦vid"] = true,
	
	-- Contraction in genitive, contraction in partitive
	["az¦han¦ast¦hid"] = true,
	["l'az¦han¦l'ast¦hid"] = true,
	["eh¦hen¦eht¦hid"] = true,
	["ez¦hen¦est¦hid"] = true,
	["iž¦hen¦išt¦hid"] = true,
	["liž¦hen¦lišt¦hid"] = true,
	["e¦ken¦et¦kid"] = true,
	["de¦tken¦det¦tkid"] = true,
	["al'¦len¦al't¦lid"] = true,
	["im¦men¦int¦mid"] = true,
	["en¦nen¦ent¦nid"] = true,
	["är¦ren¦ärt¦rid"] = true,
	["ps'¦psen¦st¦psid"] = true,
	["ks'¦hten¦ht¦ksid"] = true,
	
	-- -ne
	["ne¦žen¦št¦žid"] = true,
	["ine¦ižen¦št¦ižid"] = true,
	
	-- Other
	["i¦man¦nt¦mid"] = true,
	["in¦imen¦nt¦imid"] = true,
	["tte¦ččen¦ttušt¦ččid"] = true,
}

inflections["stems"] = function(args, data)
	local base        = get_param(args, 1)
	local nom_sg_suff = get_param(args, 2)
	local gen_sg_suff = get_param(args, 3)
	local par_sg_suff = get_param(args, 4)
	local par_pl_suff = get_param(args, 5)
	
	if data.n == "sg" then
		par_pl_suff = "?"
	elseif data.n == "pl" then
		nom_sg_suff = "?"
		gen_sg_suff = get_param(args, 2)
		par_sg_suff = "?"
		par_pl_suff = get_param(args, 3)
	end
	
	if mw.title.getCurrentTitle().nsText ~= "Template" then
		if data.n == "pl" then
			if mw.ustring.find(gen_sg_suff, "d$") then
				gen_sg_suff = mw.ustring.gsub(gen_sg_suff, "d$", "")
			else
				error("Nominative plural must end in a vowel followed by -d.")
			end
		else
			if mw.ustring.find(gen_sg_suff, "n$") then
				gen_sg_suff = mw.ustring.gsub(gen_sg_suff, "n$", "")
			else
				error("Genitive singular must end in a vowel followed by -n.")
			end
		end
		
		if mw.ustring.find(par_pl_suff, "d$") then
			par_pl_suff = mw.ustring.gsub(par_pl_suff, "d$", "")
		elseif data.n ~= "sg" then
			error("Partitive plural must end in -id.")
		end
		
		if data.n == "sg" then
			if nom_sg_suff ~= "" and gen_sg_suff ~= "" and par_sg_suff ~= "" and mw.ustring.match(nom_sg_suff, "^(.'?)") == mw.ustring.match(gen_sg_suff, "^(.'?)") and mw.ustring.match(gen_sg_suff, "^(.'?)") == mw.ustring.match(par_sg_suff, "^(.'?)") then
				error("The suffixes share some initial letters. These should be moved over to the base parameter.")
			end
		else
			if nom_sg_suff ~= "" and gen_sg_suff ~= "" and par_sg_suff ~= "" and par_pl_suff ~= "" and mw.ustring.match(nom_sg_suff, "^(.'?)") == mw.ustring.match(gen_sg_suff, "^(.'?)") and mw.ustring.match(gen_sg_suff, "^(.'?)") == mw.ustring.match(par_sg_suff, "^(.'?)") and mw.ustring.match(par_sg_suff, "^(.'?)") == mw.ustring.match(par_pl_suff, "^(.'?)") then
				error("The suffixes share some initial letters. These should be moved over to the base parameter.")
			end
		end
		
		local infl_type = nom_sg_suff .. "¦" .. gen_sg_suff .. "n¦" .. par_sg_suff .. "¦" .. par_pl_suff .. "d"
		require("Module:debug").track("vep-nominals/type/" .. infl_type)
		
		if infl_types[infl_type] then
			require("Module:debug").track("vep-nominals/known")
		else
			require("Module:debug").track("vep-nominals/unknown")
		end
	end
	
	local nom_sg_stem = base .. nom_sg_suff
	local gen_sg_stem = base .. gen_sg_suff
	local par_sg_stem = base .. par_sg_suff
	local ill_sg_stem = "?"
	local par_pl_stem = base .. par_pl_suff
	
	if mw.title.getCurrentTitle().nsText ~= "Template" then
		if not mw.ustring.find(gen_sg_stem, "[aeiouüäö]$") then
			if data.n == "pl" then
				error("Nominative plural must end in a vowel followed by -d.")
			else
				error("Genitive singular must end in a vowel followed by -n.")
			end
		end
		
		if data.n ~= "sg" and not mw.ustring.find(par_pl_stem, "i$") then
			error("Partitive plural must end in -id.")
		end
	end
	
	local s_sg = mw.ustring.find(gen_sg_stem, "i$") and "š" or "s"
	local s_pl = mw.ustring.find(par_pl_stem, "i$") and "š" or "s"
	
	local ill_sg_ending = "?"
	
	if mw.ustring.find(gen_sg_stem, "h[aeiouäöü]+$") then
		ill_sg_ending = mw.ustring.find(gen_sg_stem, "i$") and "že" or "ze"
	else
		local vowel = mw.ustring.match(gen_sg_stem, "([aeiouäöü])$") or "a"
		ill_sg_ending = "h" .. (vowel == "i" and "e" or vowel)
	end
	
	local ill_pl_ending = "?"
	
	if mw.ustring.find(par_pl_stem, "h[aeiouäöü]+$") then
		ill_pl_ending = mw.ustring.find(par_pl_stem, "i$") and "že" or "ze"
	elseif n ~= "sg" then
		local vowel = mw.ustring.match(par_pl_stem, "([aeiouäöü])$") or "i"
		ill_pl_ending = "h" .. (vowel == "i" and "e" or vowel)
	end
	
	-- Singular
	data.forms["nom_sg"] = {nom_sg_stem}
	data.forms["acc_sg"] = {gen_sg_stem .. "n"}
	data.forms["gen_sg"] = {gen_sg_stem .. "n"}
	data.forms["par_sg"] = {par_sg_stem}
	data.forms["ess_sg"] = {gen_sg_stem .. "n"}
	data.forms["tra_sg"] = {gen_sg_stem .. "k" .. s_sg}
	
	data.forms["ine_sg"] = {gen_sg_stem .. s_sg}
	data.forms["ela_sg"] = {gen_sg_stem .. s_sg .. "päi"}
	data.forms["ill_sg"] = {ill_sg_stem .. ill_sg_ending}
	
	data.forms["ade_sg"] = {gen_sg_stem .. "l"}
	data.forms["abl_sg"] = {gen_sg_stem .. "lpäi"}
	data.forms["all_sg"] = {gen_sg_stem .. "le"}
	
	data.forms["abe_sg"] = {gen_sg_stem .. "ta"}
	data.forms["com_sg"] = {gen_sg_stem .. "nke"}
	data.forms["pro_sg"] = {par_sg_stem .. "me"}
	
	data.forms["ap1_sg"] = {gen_sg_stem .. "nno"}
	data.forms["ap2_sg"] = {gen_sg_stem .. "nnoks"}
	data.forms["egr_sg"] = {gen_sg_stem .. "nnopäi"}
	
	data.forms["te1_sg"] = {ill_sg_stem .. ill_sg_ending .. "sai"}
	data.forms["te2_sg"] = {gen_sg_stem .. "lesai"}
	data.forms["te3_sg"] = {gen_sg_stem .. "ssai"}
	
	data.forms["ad1_sg"] = {ill_sg_stem .. ill_sg_ending .. "päi"}
	data.forms["ad2_sg"] = {gen_sg_stem .. "lepäi"}
	
	-- Plural
	data.forms["nom_pl"] = {gen_sg_stem .. "d"}
	data.forms["acc_pl"] = {gen_sg_stem .. "d"}
	data.forms["gen_pl"] = {par_pl_stem .. "den"}
	data.forms["par_pl"] = {par_pl_stem .. "d"}
	data.forms["ess_pl"] = {par_pl_stem .. "n"}
	data.forms["tra_pl"] = {par_pl_stem .. "k" .. s_pl}
	
	data.forms["ine_pl"] = {par_pl_stem .. s_pl}
	data.forms["ela_pl"] = {par_pl_stem .. s_pl .. "päi"}
	data.forms["ill_pl"] = {par_pl_stem .. ill_pl_ending}
	
	data.forms["ade_pl"] = {par_pl_stem .. "l"}
	data.forms["abl_pl"] = {par_pl_stem .. "lpäi"}
	data.forms["all_pl"] = {par_pl_stem .. "le"}
	
	data.forms["abe_pl"] = {par_pl_stem .. "ta"}
	data.forms["com_pl"] = {par_pl_stem .. "denke"}
	data.forms["pro_pl"] = {par_pl_stem .. "dme"}
	
	data.forms["ap1_pl"] = {par_pl_stem .. "denno"}
	data.forms["ap2_pl"] = {par_pl_stem .. "dennoks"}
	data.forms["egr_pl"] = {par_pl_stem .. "dennopäi"}
	
	data.forms["te1_pl"] = {par_pl_stem .. ill_pl_ending .. "sai"}
	data.forms["te2_pl"] = {par_pl_stem .. "lesai"}
	data.forms["te3_pl"] = nil
	
	data.forms["ad1_pl"] = {par_pl_stem .. ill_pl_ending .. "päi"}
	data.forms["ad2_pl"] = {par_pl_stem .. "lepäi"}
end

inflections["ppron"] = function(args, data)
	local person = args[1]
	
	if not person or person == "" then
		if mw.title.getCurrentTitle().nsText == "Template" then
			person = 3
		else
			error("Please specify the person, 1, 2 or 3.")
		end
	else
		person = tonumber(person)
	end
	
	local sg_letter
	local sg
	local pl
	
	if person == 1 then
		sg_letter = "m"
		sg = "minu"
		pl = "m"
	elseif person == 2 then
		sg_letter = "s"
		sg = "sinu"
		pl = "t"
	elseif person == 3 then
		sg_letter = "h"
		sg = "häne"
		pl = "h"
	end
	
	data.forms["nom_sg"] = {person == 3 and "hän" or sg_letter .. "inä"}
	data.forms["acc_sg"] = {sg .. "n"}
	data.forms["gen_sg"] = {sg .. "n"}
	data.forms["par_sg"] = {person == 3 and "händast" or sg_letter .. "indai"}
	
	data.forms["ine_sg"] = {sg .. "s"}
	data.forms["ela_sg"] = {sg .. "späi"}
	data.forms["ill_sg"] = {sg .. "h" .. (person == 3 and "e" or "u")}
	
	data.forms["ade_sg"] = {person == 3 and "hänel" or sg_letter .. "inai"}
	data.forms["abl_sg"] = {person == 3 and "hänelpäi" or sg_letter .. "inaipäi"}
	data.forms["all_sg"] = {person == 3 and "hänele" or sg_letter .. "inei"}
	
	data.forms["abe_sg"] = {sg .. "ta"}
	data.forms["com_sg"] = {sg .. "nke"}
	
	data.forms["nom_pl"] = {pl .. "ö"}
	data.forms["acc_pl"] = {pl .. "ö"}
	data.forms["gen_pl"] = {pl .. "eiden"}
	data.forms["par_pl"] = {pl .. "eid"}
	
	data.forms["ine_pl"] = {pl .. "eiš"}
	data.forms["ela_pl"] = {pl .. "eišpäi"}
	data.forms["ill_pl"] = {pl .. "eihe"}
	
	data.forms["ade_pl"] = {pl .. "eil"}
	data.forms["abl_pl"] = {pl .. "eilpäi"}
	data.forms["all_pl"] = {pl .. "eile"}
	
	data.forms["abe_pl"] = {pl .. "eita"}
	data.forms["com_pl"] = {pl .. "eidenke"}
end

inflections["ken"] = function(args, data)
	data.forms["nom_sg"] = {"ken"}
	data.forms["acc_sg"] = {"kenen"}
	data.forms["gen_sg"] = {"kenen"}
	data.forms["par_sg"] = {"keda"}
	data.forms["ess_sg"] = {"kenen"}
	data.forms["tra_sg"] = {"keneks"}
	
	data.forms["ine_sg"] = {"kes", "kenes"}
	data.forms["ela_sg"] = {"kespäi", "kenespäi"}
	data.forms["ill_sg"] = {"kehe", "kenehe"}
	
	data.forms["ade_sg"] = {"kel", "kenel"}
	data.forms["abl_sg"] = {"kelpäi", "kenelpäi"}
	data.forms["all_sg"] = {"kelle", "kenele"}
	
	data.forms["abe_sg"] = {"keneta"}
	data.forms["com_sg"] = {"kenenke"}
	data.forms["pro_sg"] = {"kedame"}
	
	data.forms["ap1_sg"] = {"kenenno"}
	data.forms["ap2_sg"] = {"kenennoks"}
	data.forms["egr_sg"] = {"kenennopäi"}
	
	data.forms["te1_sg"] = {"kehesai", "kenehesai"}
	data.forms["te2_sg"] = {"kellesai", "kenelesai"}
	
	data.forms["ad1_sg"] = {"kehepäi", "kenehepäi"}
	data.forms["ad2_sg"] = {"kellepäi", "kenelepäi"}
	
	if args["prefix"] == "" and args["suffix"] == "" then
		data.forms["nom_pl"] = {"ked"}
	end
end

inflections["mi"] = function(args, data)
	data.forms["nom_sg"] = {"mi"}
	data.forms["acc_sg"] = {"min"}
	data.forms["gen_sg"] = {"min"}
	data.forms["par_sg"] = {"midä"}
	data.forms["ess_sg"] = {"min"}
	data.forms["tra_sg"] = {"mikš"}
	
	data.forms["ine_sg"] = {"miš"}
	data.forms["ela_sg"] = {"mišpäi"}
	data.forms["ill_sg"] = {"mihe"}
	
	data.forms["ade_sg"] = {"mil"}
	data.forms["abl_sg"] = {"milpäi"}
	data.forms["all_sg"] = {"mille"}
	
	data.forms["abe_sg"] = {"mita"}
	data.forms["com_sg"] = {"minke"}
	data.forms["pro_sg"] = {"midäme"}
	
	data.forms["ap1_sg"] = {"minno"}
	data.forms["ap2_sg"] = {"minnoks"}
	data.forms["egr_sg"] = {"minnopäi"}
	
	data.forms["te1_sg"] = {"mihesai"}
	data.forms["te2_sg"] = {"millesai"}
	
	data.forms["ad1_sg"] = {"mihepäi"}
	data.forms["ad2_sg"] = {"millepäi"}
	
	if args["prefix"] == "" and args["suffix"] == "" then
		data.forms["nom_pl"] = {"mid"}
	end
end

inflections["se"] = function(args, data)
	-- Singular
	data.forms["nom_sg"] = {"se"}
	data.forms["acc_sg"] = {"sen"}
	data.forms["gen_sg"] = {"sen"}
	data.forms["par_sg"] = {"sidä"}
	data.forms["ess_sg"] = {"sen"}
	data.forms["tra_sg"] = {"sikš"}
	
	data.forms["ine_sg"] = {"siš"}
	data.forms["ela_sg"] = {"sišpäi"}
	data.forms["ill_sg"] = {"sihe"}
	
	data.forms["ade_sg"] = {"sil"}
	data.forms["abl_sg"] = {"silpäi"}
	data.forms["all_sg"] = {"sile"}
	
	data.forms["abe_sg"] = {"sita"}
	data.forms["com_sg"] = {"senke"}
	data.forms["pro_sg"] = {"sidäme"}
	
	data.forms["ap1_sg"] = {"senno"}
	data.forms["ap2_sg"] = {"sennoks"}
	data.forms["egr_sg"] = {"sennopäi"}
	
	data.forms["te1_sg"] = {"sihesai"}
	data.forms["te2_sg"] = {"silesai"}
	
	data.forms["ad1_sg"] = {"sihepäi"}
	data.forms["ad2_sg"] = {"silepäi"}
	
	-- Plural
	data.forms["nom_pl"] = {"ne", "ned"}
	data.forms["acc_pl"] = {"ne", "ned"}
	data.forms["gen_pl"] = {"niiden"}
	data.forms["par_pl"] = {"niid"}
	data.forms["ess_pl"] = nil
	data.forms["tra_pl"] = {"niikš"}
	
	data.forms["ine_pl"] = {"niiš"}
	data.forms["ela_pl"] = {"niišpäi"}
	data.forms["ill_pl"] = {"niihe"}
	
	data.forms["ade_pl"] = {"niil"}
	data.forms["abl_pl"] = {"niilpäi"}
	data.forms["all_pl"] = {"niile"}
	
	data.forms["abe_pl"] = {"niita"}
	data.forms["com_pl"] = {"niidenke"}
	data.forms["pro_pl"] = {"niidme"}
	
	data.forms["ap1_pl"] = {"niidenno"}
	data.forms["ap2_pl"] = {"niidennoks"}
	data.forms["egr_pl"] = {"niidennopäi"}
	
	data.forms["te1_pl"] = {"niihesai"}
	data.forms["te2_pl"] = {"niilesai"}
	data.forms["te3_pl"] = nil
	
	data.forms["ad1_pl"] = {"niihepäi"}
	data.forms["ad2_pl"] = {"niilepäi"}
end

inflections["nece"] = function(args, data)
	-- Singular
	data.forms["nom_sg"] = {"nece"}
	data.forms["acc_sg"] = {"necen"}
	data.forms["gen_sg"] = {"necen"}
	data.forms["par_sg"] = {"necidä"}
	data.forms["ess_sg"] = {"necen"}
	data.forms["tra_sg"] = {"necikš"}
	
	data.forms["ine_sg"] = {"neciš"}
	data.forms["ela_sg"] = {"necišpäi"}
	data.forms["ill_sg"] = {"neche"}
	
	data.forms["ade_sg"] = {"necil"}
	data.forms["abl_sg"] = {"necilpäi"}
	data.forms["all_sg"] = {"necile"}
	
	data.forms["abe_sg"] = {"necita"}
	data.forms["com_sg"] = {"necenke"}
	data.forms["pro_sg"] = {"necidäme"}
	
	data.forms["ap1_sg"] = {"necenno"}
	data.forms["ap2_sg"] = {"necennoks"}
	data.forms["egr_sg"] = {"necennopäi"}
	
	data.forms["te1_sg"] = {"nechesai"}
	data.forms["te2_sg"] = {"necilesai"}
	
	data.forms["ad1_sg"] = {"nechepäi"}
	data.forms["ad2_sg"] = {"necilepäi"}
	
	-- Plural
	data.forms["nom_pl"] = {"nene", "nened"}
	data.forms["acc_pl"] = {"nene", "nened"}
	data.forms["gen_pl"] = {"neniden"}
	data.forms["par_pl"] = {"nenid"}
	data.forms["ess_pl"] = nil
	data.forms["tra_pl"] = {"nenikš"}
	
	data.forms["ine_pl"] = {"neniš"}
	data.forms["ela_pl"] = {"nenišpäi"}
	data.forms["ill_pl"] = {"nenihe"}
	
	data.forms["ade_pl"] = {"nenil"}
	data.forms["abl_pl"] = {"nenilpäi"}
	data.forms["all_pl"] = {"nenile"}
	
	data.forms["abe_pl"] = {"nenita"}
	data.forms["com_pl"] = {"nenidenke"}
	data.forms["pro_pl"] = {"nenidme"}
	
	data.forms["ap1_pl"] = {"nenidenno"}
	data.forms["ap2_pl"] = {"nenidennoks"}
	data.forms["egr_pl"] = {"nenidennopäi"}
	
	data.forms["te1_pl"] = {"nenihesai"}
	data.forms["te2_pl"] = {"nenilesai"}
	data.forms["te3_pl"] = nil
	
	data.forms["ad1_pl"] = {"nenihepäi"}
	data.forms["ad2_pl"] = {"nenilepäi"}
end

-- Helper functions

function postprocess(args, data)
	local prefix = args["prefix"] or ""
	local suffix = args["suffix"] or ""
	
	for key, form in pairs(data.forms) do
		-- Do not show singular or plural forms for nominals that don't have them
		if (data.n == "pl" and key:find("_sg$")) or (data.n == "sg" and key:find("_pl$")) then
			form = nil
		elseif form then
			for key2, subform in pairs(form) do
				form[key2] = prefix .. subform .. suffix
			end
		end
		
		data.forms[key] = form
	end
	
	-- Check if the lemma form matches the page name
	local lemma_key = data.n == "pl" and "nom_pl" or "nom_sg"
	
	if data.forms[lemma_key] and data.forms[lemma_key][1] and lang:makeEntryName(data.forms[lemma_key][1]) ~= mw.title.getCurrentTitle().text then
		table.insert(data.categories, lang:getCanonicalName() .. " entries with inflection not matching pagename")
	end
end

-- Make the table
function make_table(data)
	local function show_form(form)
		if not form then
			return "—"
		end
		
		if type(form) ~= "table" then
			error("a non-table value was given in the list of inflected forms.")
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			if mw.ustring.find(subform, "?", nil, true) then
				table.insert(ret, "?")
			else
				table.insert(ret, m_links.full_link({lang = lang, term = subform}))
			end
		end
		
		return table.concat(ret, "<br/>")
	end
	
	local function repl(param)
		if param == "lemma" then
			return m_links.full_link({lang = lang, alt = mw.title.getCurrentTitle().text}, "term")
		elseif param == "info" then
			return data.title and " (" .. data.title .. ")" or ""
		else
			return show_form(data.forms[param])
		end
	end
	
	local collapsed_cells = [=[
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="min-width: 11em; background: #CCCCFF;" | nominative sing.
| style="min-width: 13em;" | {{{nom_sg}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | genitive sing.
| {{{gen_sg}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | partitive sing.
| {{{par_sg}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | partitive plur.
| {{{par_pl}}}]=]
	
	if data.n == "pl" then
		collapsed_cells = [=[
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="min-width: 11em; background: #CCCCFF;" | nominative sing.
| style="min-width: 13em;" | {{{nom_sg}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | nominative plur.
| {{{nom_pl}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | partitive plur.
| {{{par_pl}}}]=]
	end
	
	local wikicode = [=[
{| class="inflection-table vsSwitcher vsToggleCategory-inflection" style="border: solid 1px #CCCCFF; text-align:left;" cellspacing="1" cellpadding="2"
|- style="background: #CCCCFF; vertical-align: top;"
! class="vsToggleElement" colspan="4" | Inflection of {{{lemma}}}{{{info}}}
]=] .. collapsed_cells .. [=[

|- class="vsHide" style="background: #CCCCFF; vertical-align: top;"
! style="min-width: 11em;" |
! style="min-width: 13em;" | seengular
! style="min-width: 13em;" | plural
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | nominative
| {{{nom_sg}}}
| {{{nom_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | accusative
| {{{acc_sg}}}
| {{{acc_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | genitive
| {{{gen_sg}}}
| {{{gen_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | pairtitive
| {{{par_sg}}}
| {{{par_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | essive-instructive
| {{{ess_sg}}}
| {{{ess_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | translative
| {{{tra_sg}}}
| {{{tra_pl}}}
|- class="vsHide" style="background: #E6E6FF; vertical-align:top;"
| colspan="3" |
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | inessive
| {{{ine_sg}}}
| {{{ine_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | elative
| {{{ela_sg}}}
| {{{ela_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | illative
| {{{ill_sg}}}
| {{{ill_pl}}}
|- class="vsHide" style="background: #E6E6FF; vertical-align:top;"
| colspan="3" |
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | adessive
| {{{ade_sg}}}
| {{{ade_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | ablative
| {{{abl_sg}}}
| {{{abl_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | allative
| {{{all_sg}}}
| {{{all_pl}}}
|- class="vsHide" style="background: #E6E6FF; vertical-align:top;"
| colspan="3" |
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | abessive
| {{{abe_sg}}}
| {{{abe_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | comitative
| {{{com_sg}}}
| {{{com_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | prolative
| {{{pro_sg}}}
| {{{pro_pl}}}
|- class="vsHide" style="background: #E6E6FF; vertical-align:top;"
| colspan="3" |
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | approximative I
| {{{ap1_sg}}}
| {{{ap1_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | approximative II
| {{{ap2_sg}}}
| {{{ap2_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | egressive
| {{{egr_sg}}}
| {{{egr_pl}}}
|- class="vsHide" style="background: #E6E6FF; vertical-align:top;"
| colspan="3" |
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | terminative I
| {{{te1_sg}}}
| {{{te1_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | terminative II
| {{{te2_sg}}}
| {{{te2_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | terminative III
| {{{te3_sg}}}
| {{{te3_pl}}}
|- class="vsHide" style="background: #E6E6FF; vertical-align:top;"
| colspan="3" |
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | additive I
| {{{ad1_sg}}}
| {{{ad1_pl}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | additive II
| {{{ad2_sg}}}
| {{{ad2_pl}}}
|}]=]
	return mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)
end

return export