This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

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 = mw.title.getCurrentTitle().text, info = nil, categories = {}}
	
	if mw.title.getCurrentTitle().namespace == 10 then
		data.title = args["title"] or data.title
	end

    local lemma = data.title
    if args["prefix"] and #args["prefix"] > 0 then
        local prefix = args["prefix"]
        if mw.ustring.sub(lemma, 1, mw.ustring.len(prefix)) ~= prefix then
            error("|prefix= does not match the lemma")
        end
        lemma = mw.ustring.sub(lemma, mw.ustring.len(prefix) + 1)
    end
    if args["suffix"] and #args["suffix"] > 0 then
        local suffix = args["suffix"]
        if mw.ustring.sub(lemma, -mw.ustring.len(suffix)) ~= suffix then
            error("|suffix= does not match the lemma")
        end
        lemma = mw.ustring.sub(lemma, 1, -mw.ustring.len(suffix) - 1)
    end
    data.lemma = lemma
	
	-- Generate the forms
	inflections[infl_type](args, data)
	
	-- Postprocess
	postprocess(args, data)
	
	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 function count_syllables(word)
	local count = 0

	local function do_count(a, b)
		if a == b then
			return a, b
		elseif b == "i" or (b == "u" and mw.ustring.find(a, "[aoäö]")) then
			count = count + 1
			return a .. b
		else
			count = count + 1
			return a, b
		end
	end
	
	require("Module:gsub lookahead")(word, "([aeiouäöü])(.?)", do_count)
	return count
end

local function get_inf3_ill(impr3_suff, potn_stem, harmony)
	local reduce_ok = mw.ustring.match(impr3_suff, "[gk]") and count_syllables(potn_stem) == 1
	if reduce_ok then
		return potn_stem .. "mh" .. harmony
	else
		return potn_stem .. "m" .. harmony .. "h" .. harmony
	end
end

local consonants = {
	["d"] = {["b"] = "b", ["d"] = "d", ["g"] = "g"},
	["t"] = {["b"] = "p", ["d"] = "t", ["g"] = "k"},
}

--[=[
	New auto-inflection types
]=]--

local function add_info(data, number, specimen)
	data.info = "inflection type " .. number .. "/" .. m_links.full_link({lang = lang, term = specimen}, "term")
	table.insert(data.categories, lang:getCanonicalName() .. " " .. specimen .. "-type verbs")
end

local function extract_stem(stem, suffix)
	local result = mw.ustring.match(stem, suffix .. "$")
	if not result then
		error("Unsupported stem for this inflection type")
	end
	return mw.ustring.gsub(stem, suffix .. "$", ""), result
end

local function generate_from_stems(args, data, inf, pres, past, impr3)
	local inf_stem
	local pres_stem = pres
	local past_stem = past
	local past_actv_ptcp_stem
	local cond_stem
	local potn_stem

    local cons, harmony
    inf_stem, cons, harmony = mw.ustring.match(inf, "^(.-)([dt])([aä])$")
	cons = consonants[cons]
	
    if not mw.ustring.find(pres_stem, "[aeiouüäö]$") then
        error("Present must end in a vowel followed by -b.")
    end
    
    if not mw.ustring.find(past_stem, "i$") then
        error("Past must end in -i.")
    end
	
	-- Conditional stem
	if mw.ustring.find(pres_stem, "[aeiouüäö-][^aeiouüäö]+[eiä]$") or mw.ustring.find(pres_stem, "[aeiouüäö]i$") then
		cond_stem = mw.ustring.gsub(pres_stem, "[eiä]$", "")
	else
		cond_stem = pres_stem
	end
	
	-- Past active participle stem
	local past_actv_ptcp_stem = inf_stem
	
	if mw.ustring.find(inf_stem, "[kpsšt]$") then
		local inf_stem_voiced = mw.ustring.gsub(inf_stem, "[kpsšt]$", {["k"] = "g", ["p"] = "b", ["s"] = "z", ["š"] = "ž", ["t"] = "d"})
		local pres_stem_novowel = mw.ustring.gsub(pres_stem, "[aeiouüäö]+$", "")
		
		if inf_stem_voiced == pres_stem_novowel then
			past_actv_ptcp_stem = inf_stem_voiced
		end
	end
	
	-- Potential stem
	if mw.ustring.find(inf_stem, "[aeiouüäö]$") then
		potn_stem = pres_stem
	else
		potn_stem = past_actv_ptcp_stem
	end

	-- Third-person imperative stem and suffix
	local impr3_stem = inf_stem
	if not mw.ustring.find(impr3, "^[čdgkt]") then
        impr3 = cons["g"] .. impr3
	end
	if mw.ustring.find(impr3, "^g") and mw.ustring.find(impr3_stem, "k$") then
		impr3_stem = mw.ustring.sub(impr3_stem, 1, -2) .. "g"
	elseif mw.ustring.find(impr3, "^k") and mw.ustring.find(impr3_stem, "g$") then
		impr3_stem = mw.ustring.sub(impr3_stem, 1, -2) .. "k"
	end
	
	-- Present indicative
	data.forms["1sg_pres_indc"] = {pres_stem .. "n"}
	data.forms["2sg_pres_indc"] = {pres_stem .. "d"}
	data.forms["3sg_pres_indc"] = {pres_stem .. "b"}
	data.forms["1pl_pres_indc"] = {pres_stem .. "m"}
	data.forms["2pl_pres_indc"] = {pres_stem .. "t"}
	data.forms["3pl_pres_indc"] = {inf_stem .. cons["d"] .. "as", pres_stem .. "ba"}
	data.forms["sg_pres_indc_conn"] = {pres_stem}
	data.forms["pl_pres_indc_conn"] = {inf_stem .. cons["g"] .. "oi"}
	
	-- Past indicative
	data.forms["1sg_past_indc"] = {past_stem .. "n"}
	data.forms["2sg_past_indc"] = {past_stem .. "d"}
	data.forms["3sg_past_indc"] = {past_stem}
	data.forms["1pl_past_indc"] = {past_stem .. "m"}
	data.forms["2pl_past_indc"] = {past_stem .. "t"}
	data.forms["3pl_past_indc"] = {past_stem .. "ba"}
	data.forms["sg_past_indc_conn"] = {pres_stem .. "nd"}
	data.forms["pl_past_indc_conn"] = {past_actv_ptcp_stem .. "nugoi"}
	
	-- Imperative
	data.forms["1sg_impr"] = nil
	data.forms["2sg_impr"] = {pres_stem}
	data.forms["3sg_impr"] = {impr3_stem .. impr3 .. "ha"}
	data.forms["1pl_impr"] = {inf_stem .. cons["g"] .. "am"}
	data.forms["2pl_impr"] = {inf_stem .. cons["g"] .. "at"}
	data.forms["3pl_impr"] = {data.forms["3sg_impr"][1]}
	data.forms["sg_impr_conn"] = {pres_stem}
	data.forms["pl_impr_conn"] = {inf_stem .. cons["g"] .. "oi"}
	
	-- Present conditional
	data.forms["1sg_pres_cond"] = {cond_stem .. "ižin"}
	data.forms["2sg_pres_cond"] = {cond_stem .. "ižid"}
	data.forms["3sg_pres_cond"] = {cond_stem .. "iži"}
	data.forms["1pl_pres_cond"] = {cond_stem .. "ižim"}
	data.forms["2pl_pres_cond"] = {cond_stem .. "ižit"}
	data.forms["3pl_pres_cond"] = {cond_stem .. "ižiba"}
	data.forms["pres_cond_conn"] = {cond_stem .. "iži"}
	
	-- Past conditional
	data.forms["1sg_past_cond"] = {past_actv_ptcp_stem .. "nuižin"}
	data.forms["2sg_past_cond"] = {past_actv_ptcp_stem .. "nuižid"}
	data.forms["3sg_past_cond"] = {past_actv_ptcp_stem .. "nuiži"}
	data.forms["1pl_past_cond"] = {past_actv_ptcp_stem .. "nuižim"}
	data.forms["2pl_past_cond"] = {past_actv_ptcp_stem .. "nuižit"}
	data.forms["3pl_past_cond"] = {past_actv_ptcp_stem .. "nuižiba"}
	data.forms["past_cond_conn"] = {past_actv_ptcp_stem .. "nuiži"}
	
	-- Potential
	data.forms["1sg_potn"] = {potn_stem .. "nen"}
	data.forms["2sg_potn"] = {potn_stem .. "ned"}
	data.forms["3sg_potn"] = {potn_stem .. "neb"}
	data.forms["1pl_potn"] = {potn_stem .. "nem"}
	data.forms["2pl_potn"] = {potn_stem .. "net"}
	data.forms["3pl_potn"] = {potn_stem .. "neba"}
	data.forms["potn_conn"] = {potn_stem .. "ne"}
	
	-- Infinitives
	data.forms["inf1"]     = {inf_stem .. cons["d"] .. harmony}
	
	data.forms["inf2_ine"] = {inf_stem .. cons["d"] .. "es"}
	data.forms["inf2_ins"] = {inf_stem .. cons["d"] .. "en"}
	
	data.forms["inf3_ine"] = {potn_stem .. "m" .. harmony .. "s"}
	
	if mw.ustring.find(potn_stem, "^[^aeiouüäö-]*[aeiouüäö]i?$") then
		data.forms["inf3_ill"] = {potn_stem .. "mh" .. harmony}
	elseif mw.ustring.find(potn_stem, "[^aeiouüäö]$") then
		data.forms["inf3_ill"] = {potn_stem .. "m" .. harmony .. "h" .. harmony}
	else
		data.forms["inf3_ill"] = {get_inf3_ill(impr3, potn_stem, harmony)}
	end
	
	data.forms["inf3_ela"] = {potn_stem .. "m" .. harmony .. "späi"}
	data.forms["inf3_ade"] = {potn_stem .. "m" .. harmony .. "l"}
	data.forms["inf3_abe"] = {potn_stem .. "m" .. harmony .. "t"}
	
	-- Participles
	if mw.ustring.find(pres_stem, "[aeiouüäö]i$") then
		data.forms["pres_actv_ptcp"] = {pres_stem}
	elseif mw.ustring.find(pres_stem, "[aeiouüäö-][^aeiouüäö]+e$") then
		data.forms["pres_actv_ptcp"] = {mw.ustring.gsub(pres_stem, "e$", "i") .. "i"}
	else
		data.forms["pres_actv_ptcp"] = {pres_stem .. "i"}
	end
	
	data.forms["past_actv_ptcp"] = {past_actv_ptcp_stem .. "nu"}
	data.forms["past_pasv_ptcp"] = {inf_stem .. cons["d"] .. "ud"}
end

inflections["ujuda"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "da")
	extract_stem(stem, "[ouöü]")
    
    local syllables = count_syllables(stem)
    local reduce = syllables <= 3 and syllables % 2 == 1

	add_info(data, 1, "ujuda")
	return generate_from_stems(args, data, data.lemma,
			stem, stem .. "i", reduce and "" or "a")
end

inflections["jauhta"] = function(args, data)
	local stem = args[1]
	if not stem or not mw.ustring.find(stem, "[ou]$") then
		error("A present stem ending in -o/u, equivalent to the third-person indicative present singular without the final -b, must be specified.")
	end
	add_info(data, 2, "jauhta")
	return generate_from_stems(args, data, data.lemma,
			stem, stem .. "i", "a")
end

inflections["kacta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "[dt]a") .. "u"
	add_info(data, 3, "kacta")
	return generate_from_stems(args, data, data.lemma,
			stem, stem .. "i", "a")
end

inflections["lahota"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    if mw.ustring.find(stem, "[kpsš]$") then
        local final
        stem, final = extract_stem(stem, "[kpsš]")
        final = ({["k"] = "g", ["p"] = "b", ["s"] = "z", ["š"] = "ž"})[final]
        stem = stem .. final .. "u"
    else
        stem = stem .. "du"
    end
	add_info(data, 4, "lahota")
	return generate_from_stems(args, data, data.lemma,
			stem, stem .. "i", "a")
end

inflections["vodada"] = function(args, data)
	local stem = data.lemma
    local harmony = args[1]
	if not harmony or not mw.ustring.find(harmony, "[aä]$") then
		error("The vowel harmony of the present stem must be specified as a or ä.")
	end
    stem = extract_stem(stem, harmony .. "da")

    local syllables = count_syllables(stem .. harmony)
    local reduce = syllables <= 3 and syllables % 2 == 1

	add_info(data, 5, "vodada")
	return generate_from_stems(args, data, data.lemma,
			stem .. harmony, stem .. "i", reduce and "" or "a")
end

inflections["kuida"] = function(args, data)
	local stem = args[1]
	if not stem or not mw.ustring.find(stem, "[aä]$") then
		error("A present stem ending in -a/ä, equivalent to the third-person indicative present singular without the final -b, must be specified.")
	end

    local reduce = not mw.ustring.find(data.lemma, "[aeiouäöü]d[aä]$")

	add_info(data, 6, "kuida")
	return generate_from_stems(args, data, data.lemma,
			stem, mw.ustring.sub(stem, 1, -2) .. "i", reduce and "" or "a")
end

inflections["lüpsta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    local harmony = args[1]
	if not harmony or not mw.ustring.find(harmony, "[aä]$") then
		error("The vowel harmony of the present stem must be specified as a or ä.")
	end

	add_info(data, 7, "lüpsta")
	return generate_from_stems(args, data, data.lemma,
			stem .. harmony, stem .. "i", "a")
end

inflections["püta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    local harmony = args[1]
	if not harmony or not mw.ustring.find(harmony, "[aä]$") then
		error("The vowel harmony of the present stem must be specified as a or ä.")
	end

	local diphthong = false
    local reduce = false
    if count_syllables(stem) == 1 then
    	diphthong = mw.ustring.find(stem, "[aoäö]u$") 
    	reduce = mw.ustring.find(stem, "[ruü]$")
    end

	add_info(data, 8, "püta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "d" .. harmony, stem .. "di", diphthong and "tka" or reduce and "" or "a")
end

inflections["kogota"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    local harmony = args[1]
	if not harmony or not mw.ustring.find(harmony, "[aä]$") then
		error("The vowel harmony of the present stem must be specified as a or ä.")
	end

	local diphthong = count_syllables(stem) == 1 and mw.ustring.find(stem, "[aoäö]u$")

	add_info(data, 9, "kogota")
	return generate_from_stems(args, data, data.lemma,
			stem .. "d" .. harmony, stem .. "zi", diphthong and "tka" or "a")
end

inflections["küntta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    local harmony = args[1]
	if not harmony or not mw.ustring.find(harmony, "[aä]$") then
		error("The vowel harmony of the present stem must be specified as a or ä.")
	end

    local final
    stem, final = extract_stem(stem, "[kpt]")
    stem = stem .. ({["k"] = "g", ["p"] = "b", ["t"] = "d"})[final]

	add_info(data, 10, "küntta")
	return generate_from_stems(args, data, data.lemma,
			stem .. harmony, stem .. "i", "a")
end

inflections["käta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    local harmony = args[1]
	if not harmony or not mw.ustring.find(harmony, "[aä]$") then
		error("The vowel harmony of the present stem must be specified as a or ä.")
	end

	add_info(data, 11, "käta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "nd" .. harmony, stem .. "ndi", "a")
end

inflections["ajada"] = function(args, data)
	local stem = args[1]
	if not stem or not mw.ustring.find(stem, "[aä]$") then
		error("A present stem ending in -a/ä, equivalent to the third-person indicative present singular without the final -b, must be specified.")
	end

	add_info(data, 12, "ajada")
	return generate_from_stems(args, data, data.lemma,
			stem, mw.ustring.sub(stem, 1, -2) .. "oi", "a")
end

inflections["maksta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
	
	if mw.ustring.match(stem, "^[^aeiouäöü]?[aeiouäöü]$") then
		stem = stem .. "d"
	end

	add_info(data, 13, "maksta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "a", stem .. "oi", "a")
end

inflections["antta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")

    local final
    stem, final = extract_stem(stem, "[kpt]")
    stem = stem .. ({["k"] = "g", ["p"] = "b", ["t"] = "d"})[final]

	add_info(data, 14, "antta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "a", stem .. "oi", "a")
end

inflections["lugeda"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "eda")

    local syllables = count_syllables(stem .. "e")
    local reduce = syllables <= 3 and syllables % 2 == 1

	add_info(data, 15, "lugeda")
	return generate_from_stems(args, data, data.lemma,
			stem .. "e", stem .. "i", reduce and "" or "a")
end

inflections["särkta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")

    local final
    stem, final = extract_stem(stem, "[kpt]")
    stem = stem .. ({["k"] = "g", ["p"] = "b", ["t"] = "d"})[final]

	add_info(data, 16, "särkta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "e", stem .. "i", "ga")
end

inflections["tuntta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "tta")

	add_info(data, 17, "tuntta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "de", stem .. "zi", "a")
end

inflections["lähtta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "htta")

	add_info(data, 18, "lähtta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "hte", stem .. "ksi", "a")
end

inflections["pureskelda"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "da")

    local syllables = count_syllables(stem)
    local reduce = syllables <= 3 and syllables % 2 == 1

	add_info(data, 19, "pureskelda")
	return generate_from_stems(args, data, data.lemma,
			stem .. "e", stem .. "i", reduce and "" or "a")
end

inflections["oppida"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "[dt][aä]")

    local reduce
    if mw.ustring.match(stem, "i$") then
        local syllables = count_syllables(stem)
        reduce = syllables <= 3 and syllables % 2 == 1
    else
        stem = mw.ustring.gsub(stem, "'$", "") .. "i"
    end

	add_info(data, 20, "oppida")
	return generate_from_stems(args, data, data.lemma,
			stem, stem, reduce and "" or "a")
end

inflections["henkta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")

    local final
    stem, final = extract_stem(stem, "[kps]")
    stem = stem .. ({["k"] = "g", ["p"] = "b", ["s"] = "z"})[final] .. "i"

	add_info(data, 21, "henkta")
	return generate_from_stems(args, data, data.lemma,
			stem, stem, "a")
end

inflections["laida"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ida") .. "ji"

    local syllables = count_syllables(stem)
    local reduce = syllables <= 2

	add_info(data, 22, "laida")
	return generate_from_stems(args, data, data.lemma,
			stem, stem, reduce and "" or "a")
end

inflections["toda"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "da")

	add_info(data, 23, "toda")
	return generate_from_stems(args, data, data.lemma,
			stem, stem .. "i", "")
end

inflections["voida"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "da")
    extract_stem(stem, "i")

	add_info(data, 24, "voida")
	return generate_from_stems(args, data, data.lemma,
			stem, stem, "")
end

inflections["purda"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "[dt]a")
    
    stem = mw.ustring.gsub(stem, "([aeiouäöü])([sš])$",
            function (v, c)
                return v .. ({["s"] = "z", ["š"] = "ž"})[c]
            end)
    stem = mw.ustring.gsub(stem, "'$", "")

	add_info(data, 25, "purda")
	return generate_from_stems(args, data, data.lemma,
			stem .. "e", stem .. "i", "a")
end

inflections["valita"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    
    local syllables = count_syllables(stem)
    local diphthong = syllables == 1
    local reduce = syllables == 3

	add_info(data, 26, "valita")
	return generate_from_stems(args, data, data.lemma,
			stem .. "če", stem .. "či", diphthong and "čka" or reduce and "" or "a")
end

inflections["nähta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "hta")
    
	add_info(data, 27, "nähta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "ge", stem .. "gi", "a")
end

inflections["edeta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    
	add_info(data, 28, "edeta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "ne", stem .. "ni", "a")
end

inflections["koheta"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ta")
    
	add_info(data, 29, "koheta")
	return generate_from_stems(args, data, data.lemma,
			stem .. "nda", stem .. "nzi", "a")
end

inflections["harjata"] = function(args, data)
	local stem = data.lemma
    stem = extract_stem(stem, "ata")
    
	add_info(data, 30, "harjata")
	return generate_from_stems(args, data, data.lemma,
			stem .. "a", stem .. "oi", "a")
end

-- Helper functions

function postprocess(args, data)
	-- Check if the lemma form matches the page name
	local lemma_key = "inf1"
	
	local prefix = args["prefix"] or ""
	local suffix = args["suffix"] or ""
	
	for key, form in pairs(data.forms) do
		if form then
			for key2, subform in pairs(form) do
				form[key2] = prefix .. subform .. suffix
			end
		end
		
		data.forms[key] = form
	end

	
	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 "&mdash;"
		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.info and " (" .. data.info .. ")" or ""
		else
			return show_form(data.forms[param])
		end
	end
	
	local wikicode = [=[
{| class="inflection-table vsSwitcher" data-toggle-category="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}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="min-width: 10em; background: #CCCCFF;" | 1st infinitive
| style="min-width: 10em;" | {{{inf1}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | present indic.
| {{{3sg_pres_indc}}}
|- class="vsShow" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | past indic.
| {{{3sg_past_indc}}}
|- class="vsHide" style="background: #CCCCFF; text-align: center;"
! style="min-width: 10em;" |
! style="min-width: 10em;" | present<br/>indicative
! style="min-width: 10em;" | past<br/>indicative
! style="min-width: 10em;" | imperative
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 1st singular
| {{{1sg_pres_indc}}}
| {{{1sg_past_indc}}}
| {{{1sg_impr}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 2nd singular
| {{{2sg_pres_indc}}}
| {{{2sg_past_indc}}}
| {{{2sg_impr}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 3rd singular
| {{{3sg_pres_indc}}}
| {{{3sg_past_indc}}}
| {{{3sg_impr}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 1st plural
| {{{1pl_pres_indc}}}
| {{{1pl_past_indc}}}
| {{{1pl_impr}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 2nd plural
| {{{2pl_pres_indc}}}
| {{{2pl_past_indc}}}
| {{{2pl_impr}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 3rd plural
| {{{3pl_pres_indc}}}
| {{{3pl_past_indc}}}
| {{{3pl_impr}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | sing. conneg.<sup style="border-bottom: 1px dotted black; cursor: help;" title="In imperative: used only in the second-person singular. The plural form is used with other persons.">1</sup>
| {{{sg_pres_indc_conn}}}
| {{{sg_past_indc_conn}}}
| {{{sg_impr_conn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | plur. conneg.
| {{{pl_pres_indc_conn}}}
| {{{pl_past_indc_conn}}}
| {{{pl_impr_conn}}}
|- class="vsHide" style="background: #CCCCFF; text-align: center;"
!
! present<br/>conditional
! past<br/>conditional
! potential
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 1st singular
| {{{1sg_pres_cond}}}
| {{{1sg_past_cond}}}
| {{{1sg_potn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 2nd singular
| {{{2sg_pres_cond}}}
| {{{2sg_past_cond}}}
| {{{2sg_potn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 3rd singular
| {{{3sg_pres_cond}}}
| {{{3sg_past_cond}}}
| {{{3sg_potn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 1st plural
| {{{1pl_pres_cond}}}
| {{{1pl_past_cond}}}
| {{{1pl_potn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 2nd plural
| {{{2pl_pres_cond}}}
| {{{2pl_past_cond}}}
| {{{2pl_potn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 3rd plural
| {{{3pl_pres_cond}}}
| {{{3pl_past_cond}}}
| {{{3pl_potn}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | connegative
| {{{pres_cond_conn}}}
| {{{past_cond_conn}}}
| {{{potn_conn}}}
|- class="vsHide" style="background: #CCCCFF; text-align: center;"
! colspan="4" | non-finite forms
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | 1st infinitive
| colspan="3" | {{{inf1}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top; text-align: center;"
! style="background: #CCCCFF;" colspan="2" | 2nd infinitive
! style="background: #CCCCFF;" colspan="2" | 3rd infinitive
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | inessive
| {{{inf2_ine}}}
! style="background: #CCCCFF;" | inessive
| {{{inf3_ine}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | instructive
| {{{inf2_ins}}}
! style="background: #CCCCFF;" | illative
| {{{inf3_ill}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF; text-align: center;" colspan="2" | participles
! style="background: #CCCCFF;" | elative
| {{{inf3_ela}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | present active
| {{{pres_actv_ptcp}}}
! style="background: #CCCCFF;" | adessive
| {{{inf3_ade}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | past active
| {{{past_actv_ptcp}}}
! style="background: #CCCCFF;" | abessive
| {{{inf3_abe}}}
|- class="vsHide" style="background: #F2F2FF; vertical-align: top;"
! style="background: #CCCCFF;" | past passive
| {{{past_pasv_ptcp}}}
| style="background: #CCCCFF;" colspan="2" |
|- class="vsHide"
| colspan="4" | <sup>1</sup> In imperative: used only in the second-person singular. The plural form is used with other persons.
|}]=]
	return mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)
end

return export