Module:odt-conj

From Wiktionary, the free dictionary
Jump to navigation Jump to search

Called by {{odt-conj}} and {{odt-conj-st}}. Do not use directly.


local export = {}

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

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

local conj_data = {}

--

local function devoice(stem)
	stem = mw.ustring.gsub(stem, "ng$", "nc")
	stem = mw.ustring.gsub(stem, "g$", "h")
	stem = mw.ustring.gsub(stem, "d$", "t")
	stem = mw.ustring.gsub(stem, "b$", "p")
	stem = mw.ustring.gsub(stem, "v$", "f")
	stem = mw.ustring.gsub(stem, "z$", "s")
	return stem
end

local function spirantize(stem)
	stem = mw.ustring.gsub(stem, "([kcgh])t?d?$", "ht")
	stem = mw.ustring.gsub(stem, "([pbfv])t?d?$", "ft")
	stem = mw.ustring.gsub(stem, "([tsz])t$", "st")
	stem = mw.ustring.gsub(stem, "dt", "t")
	stem = mw.ustring.gsub(stem, "rt", "rst")
	return stem
end

local function verner(stem)
	stem = mw.ustring.gsub(stem, "hh$", "g")
	stem = mw.ustring.gsub(stem, "th$", "d")
	stem = mw.ustring.gsub(stem, "ff$", "v")
	stem = mw.ustring.gsub(stem, "s$", "r")
	return stem
end

local function umlaut(stem)
    	stem = stem.gsub(stem, "ie", "iu")
    if not string.find(stem, "ei") then
    	stem = stem.gsub(stem, "e", "i")
    end
    	stem = stem.gsub(stem, "a", "e")
    if not string.find(stem, "u") then
    	stem = stem.gsub(stem, "o", "u")
    end
    return stem
end

local function backumlaut(stem)
	if not string.find(stem, "i") then
    	stem = stem.gsub(stem, "e", "a")
    end
    if not string.find(stem, "e") then	
    	stem = stem.gsub(stem, "i", "e")
    end
    if not string.find(stem, "o") then
    	stem = stem.gsub(stem, "u", "o")
    end
    return stem
end

local function degeminate(stem)
	stem = mw.ustring.gsub(stem, "([cdghjklmnprstvwzþ])%1$", "%1")
	stem = mw.ustring.gsub(stem, "ck$", "k")
	stem = mw.ustring.gsub(stem, "bb$", "v")
	stem = mw.ustring.gsub(stem, "ff$", "v")
	return stem
end

local function C_to_K(stem)
    stem = mw.ustring.gsub(stem, "cc$", "ck")
    stem = mw.ustring.gsub(stem, "c$", "k")
    return stem
end

local function K_to_C(stem)
    stem = mw.ustring.gsub(stem, "ck$", "cc")
    stem = mw.ustring.gsub(stem, "k$", "c")
    return stem
end

local function initial_C_to_K(stem)
	stem = mw.ustring.gsub(stem, "^sc", "sk")
	stem = mw.ustring.gsub(stem, "^c", "k")
    return stem
end

local function initial_K_to_C(stem)
    stem = mw.ustring.gsub(stem, "^sk", "sc")
    stem = mw.ustring.gsub(stem, "^k", "c")
    return stem
end

--

conj_data["st"] = {
	params = {
		[1] = {},
		["sep"] = {},
		["pref"] = {},
		["class"] = {},
		["irr"] = {},
		},
}
setmetatable(conj_data["st"], {__call = function(self, args, data)
	if not args.class then
		error("Class parameter required for strong verbs")
	end
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	if args["irr"] == 'verner' then
	   data.conj_type = "strong class " .. args.class .. " irregular, [[Verner alternation]]"
	   table.insert(data.categories, "Old Dutch Verner alternating verbs")
	   table.insert(data.categories, "Old Dutch irregular strong verbs")
	elseif args["irr"] == 'hiatus' then
	   table.insert(data.categories, "Old Dutch hiatus verbs")
	   table.insert(data.categories, "Old Dutch irregular strong verbs")
	elseif args["irr"] == 'contracted' then
	   table.insert(data.categories, "Old Dutch contracted verbs")
	   table.insert(data.categories, "Old Dutch irregular strong verbs")
	elseif args["irr"] == 'j-present' then
	   data.conj_type = "strong class " .. args.class .. " j-present"
	   table.insert(data.categories, "Old Dutch class " .. args.class .. " strong j-present verbs")
	   table.insert(data.categories, "Old Dutch irregular strong verbs")
	elseif not args["irr"] then
		data.conj_type = "strong class " .. args.class
	end
	
	stem = args[1]
	pres_stem = stem
	pres_stem_i = umlaut(pres_stem)
	pres_stem_dgm = degeminate(pres_stem)
	pres_stem_i_k = C_to_K(pres_stem_i)
	pres_stem_k = C_to_K(pres_stem)
	
	stem_voiced = stem
    stem_devoiced = devoice(stem)
	if not args["irr"] then
			stem_voiced = stem
    		stem_devoiced = devoice(stem)
		elseif args["irr"]=='verner' then       
			stem_voiced = verner(stem)
			stem_devoiced = devoice(stem)
		elseif args.irr=='j-present' then 	
			stem_voiced = verner(stem)
			stem_devoiced = devoice(degeminate(stem_voiced))
		elseif args.irr=='hiatus' then
			if string.find(args.class, "[125]") then
				if args[1]=="scrī" then
					stem_voiced = stem .. "w"
					stem_devoiced = stem
					data.conj_type = "strong class " .. args.class .. " irregular, [[hiatus]]"
				else 
					stem_voiced = stem .. "g"
					if args["class"] == '2' then
						stem_voiced = stem_voiced:gsub("i", "ie")
					end
					stem_devoiced = devoice(stem_voiced)
					data.conj_type = "strong class " .. args.class .. " irregular, [[Verner alternation]]"
					table.insert(data.categories, "Old Dutch Verner alternating verbs")
				end
			elseif args["class"] == '7' then
				stem_voiced = stem
				stem_devoiced = stem
				data.conj_type = "strong class " .. args.class .. " irregular / weak class 1"
				table.insert(data.categories, "Old Dutch class 1 weak verbs")
			end
		elseif args.irr=='contracted' then
			if args["class"] == '6' then
				if args[1]=="stā" then
					stem_voiced = stem .. "nd"
					stem_devoiced = devoice(stem_voiced)
					data.conj_type = "strong class " .. args.class .. " irregular, [[suppletive]]"
					table.insert(data.categories, "Old Dutch suppletive verbs")
				else
					stem_voiced = stem .. "g"
					stem_devoiced = devoice(stem_voiced)
					data.conj_type = "strong class " .. args.class .. " irregular, [[Verner alternation]]"
					table.insert(data.categories, "Old Dutch Verner alternating verbs")
				end
			elseif args["class"] == '7' then
				stem_voiced = stem .. "ng"
				stem_devoiced = devoice(stem_voiced)
				if args[1]=="gā" then
					data.conj_type = "strong class " .. args.class .. " irregular, [[suppletive]]"
					table.insert(data.categories, "Old Dutch suppletive verbs")
				else
					data.conj_type = "strong class " .. args.class .. " irregular, [[Verner alternation]]"
					table.insert(data.categories, "Old Dutch Verner alternating verbs")
				end
			end
		end
		
	past_s_stem = stem_devoiced
	past_p_stem = stem_voiced
	past_part = stem_voiced
	past_part_2 = past_part
	past_part_gi = past_part
		
	if args["class"] == "1" then
		past_s_stem = stem_devoiced:gsub("ī", "ē")
		past_p_stem = stem_voiced:gsub("ī", "i")
		past_part = stem_voiced:gsub("ī", "i")
	elseif args["class"] == "2" then
		if mw.ustring.find(stem, "i") then
				past_s_stem = initial_K_to_C(stem_devoiced:gsub("(i[e]?[u]?)", "ō"))
				past_p_stem = initial_K_to_C(stem_voiced:gsub("(i[e]?[u]?)", "u"))
				past_part = initial_K_to_C(stem_voiced:gsub("(i[e]?[u]?)", "o"))
		elseif mw.ustring.find(stem, "ū") then
				past_s_stem = stem_devoiced:gsub("ū", "ō")
				past_p_stem = stem_voiced:gsub("ū", "u")	
				past_part = stem_voiced:gsub("ū", "o")
		end
	elseif args["class"] == "3" then
		past_s_stem = initial_K_to_C(degeminate(stem_devoiced:gsub("[(i)(e)]", "a")))
		past_p_stem = initial_K_to_C(stem_voiced:gsub("[(i)(e)]", "u"))
		if mw.ustring.find(stem, "[mn].$") then
			past_part = initial_K_to_C(stem_voiced:gsub("i", "u"))
		else
			past_part = initial_K_to_C(stem_voiced:gsub("e", "o"))
		end
    elseif args["class"] == "4" then
        if mw.ustring.find(stem, "u") then
        	past_s_stem = stem_devoiced:gsub("cu", "qua")
			past_p_stem = stem_voiced:gsub("cu", "quā")
			data.conj_type = "strong class " .. args.class .. " irregular"
			table.insert(data.categories, "Old Dutch irregular strong verbs")
        else
		    past_s_stem = initial_K_to_C(stem_devoiced:gsub("e", "a"))
		    past_p_stem = initial_K_to_C(stem_voiced:gsub("e", "ā"))
		end
		if mw.ustring.find(stem, "[mn]$") then
			past_part = initial_K_to_C(stem_voiced:gsub("e", "u"))
		else
			past_part = initial_K_to_C(stem_voiced:gsub("e", "o"))
		end
    elseif args["class"] == "5" then
		if not args.irr or args.irr == 'verner' then
			past_s_stem = initial_K_to_C(stem_devoiced:gsub("e", "a"))
			past_p_stem = initial_K_to_C(stem_voiced:gsub("e", "ā"))
			past_part = initial_K_to_C(stem_voiced)
		elseif args.irr == "j-present" then
			pres_stem_i = degeminate(pres_stem) .. "i"
			past_s_stem = degeminate(stem_devoiced:gsub("i", "a"))
			past_p_stem = degeminate(stem_voiced:gsub("i", "ā"))
			past_part = degeminate(stem_voiced:gsub("i", "e"))
		elseif args.irr == "hiatus" then
			past_s_stem = stem_devoiced:gsub("i", "a")
			past_p_stem = stem_voiced:gsub("i", "ā")
			past_part = stem
		end
	elseif args["class"] == "6" then
		if not args.irr then
			past_s_stem = degeminate(stem_devoiced:gsub("a", "uo"))
			past_p_stem = degeminate(stem_voiced:gsub("a", "uo"))
			past_part = stem
		elseif args.irr=="verner" then
			pres_stem_i = pres_stem
			past_s_stem = degeminate(stem_devoiced:gsub("a", "uo"))
			past_p_stem = degeminate(stem_voiced:gsub("a", "uo"))
			past_part = pres_stem
		elseif args.irr=="j-present" then
			pres_stem_i = degeminate(pres_stem) .. "i"
			past_s_stem = initial_K_to_C(degeminate(stem_voiced:gsub("e", "uo")))
			past_p_stem = initial_K_to_C(degeminate(stem_voiced:gsub("e", "uo")))
			past_part = initial_K_to_C(degeminate(stem:gsub("e", "a")))
		elseif args.irr == "contracted" then
			if args[1]=="stā" then
				pres_stem_i = pres_stem:gsub("ā", "ē")
				past_s_stem = stem_devoiced:gsub("ā", "u")
				past_p_stem = stem_voiced:gsub("ā", "u")
			elseif args[1]~="stā" then
				past_s_stem = stem_devoiced:gsub("ā", "uo")
				past_p_stem = stem_voiced:gsub("ā", "uo")
			end
			past_part = pres_stem
			past_part_2 = stem_voiced:gsub("ā", "a")
		end
	elseif args["class"] == "7" then
		if not args.irr then
			past_s_stem = degeminate(stem_devoiced:gsub("([aeiouāēīōū(uo)(ei)(ie)]+)", "ie"))
			past_p_stem = degeminate(stem_voiced:gsub("([aeiouāēīōū(uo)(ei)(ie)]+)", "ie"))
			past_part = stem
		elseif args.irr == "hiatus" then
			pres_stem_i = pres_stem
			past_s_stem = stem_devoiced:gsub("([aeiouāēīōū(uo)(ei)(ie)]+)", "iew")
			past_p_stem = stem_voiced:gsub("([aeiouāēīōū(uo)(ei)(ie)]+)", "iew")
			past_part = stem
		elseif args.irr == "contracted" then
			if args[1]=="gā" then
				pres_stem_i = pres_stem:gsub("ā", "ē")
			else
				pres_stem_i = pres_stem
			end
			past_s_stem = stem_devoiced:gsub("ā", "ie")
			past_p_stem = stem_voiced:gsub("ā", "ie")
			past_part = pres_stem
			past_part_2 = stem_voiced:gsub("ā", "a")
		end
	end
	
	past_s_stem_dv = devoice(past_s_stem)
	past_p_stem_k = C_to_K(past_p_stem)
	
	impr_s_stem = degeminate(stem_devoiced)
	impr_s_stem_i = umlaut(impr_s_stem)
	impr_p_stem = pres_stem_k

	if args["pref"] then
		if args["sep"] then
			impr_s_stem = args.pref .. impr_s_stem
			impr_s_stem_i = args.pref .. impr_s_stem_i
			past_part = args.sep .. args.pref .. past_part 
			past_part_2 = args.sep .. args.pref .. past_part_2
			past_part_gi = past_part
			table.insert(data.categories, "Old Dutch separable verbs")
			table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		elseif not args["sep"] then
			args.sep = ""
			impr_s_stem = args.pref .. impr_s_stem 
			impr_s_stem_i = args.pref .. impr_s_stem_i
			past_part = args.pref .. past_part 
			past_part_2 = args.pref .. past_part_2
			past_part_gi = past_part 
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		end
	elseif args["sep"] then	
			args.pref = ""
			past_part_2 = args.sep .. "gi" .. past_part_2
			past_part_gi = args.sep .. "gi" .. past_part
			past_part = args.sep .. past_part
			table.insert(data.categories, "Old Dutch separable verbs")
			table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
	else
			args.sep = ""
			args.pref = ""
			past_part_2 = "gi" .. past_part_2
			past_part_gi = "gi" .. past_part
			table.insert(data.categories, "Old Dutch basic verbs")
	end

	data.forms["inf"] = {args.head or (args.sep .. args.pref .. args[1] .. "an")}
	data.forms["pres_ind_1s"] = {args.pref .. pres_stem .. "o" .. " " .. args.sep , args.pref .. pres_stem .. "on" .. " " .. args.sep}
	data.forms["pres_ind_2s"] = {args.pref .. pres_stem_i_k .. "is" .. " " .. args.sep, args.pref .. pres_stem_i_k .. "ist" .. " " .. args.sep}
 	data.forms["pres_ind_3s"] = {args.pref .. pres_stem_i_k .. "it" .. " " .. args.sep}
	data.forms["pres_ind_1p"] = {args.pref .. pres_stem .. "on" .. " " .. args.sep}
	data.forms["pres_ind_2p"] = {args.pref .. pres_stem_k .. "et" .. " " .. args.sep}
	data.forms["pres_ind_3p"] = {args.pref .. pres_stem .. "ont" .. " " .. args.sep}
	
	data.forms["past_ind_1s"] = {args.pref .. past_s_stem_dv .. " " .. args.sep}
	data.forms["past_ind_2s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep, args.pref .. past_p_stem_k .. "is" .. " " .. args.sep}
	data.forms["past_ind_3s"] = {args.pref .. past_s_stem_dv .. " " .. args.sep}
	data.forms["past_ind_1p"] = {args.pref .. past_p_stem .. "un" .. " " .. args.sep}
	data.forms["past_ind_2p"] = {args.pref .. past_p_stem .. "ut" .. " " .. args.sep}
	data.forms["past_ind_3p"] = {args.pref .. past_p_stem .. "un" .. " " .. args.sep}

	data.forms["pres_sub_1s"] = {args.pref .. pres_stem_k .. "e" .. " " .. args.sep}
	data.forms["pres_sub_2s"] = {args.pref .. pres_stem_k .. "es" .. " " .. args.sep, args.pref .. pres_stem_k .. "est" .. " " .. args.sep}
	data.forms["pres_sub_3s"] = {args.pref .. pres_stem_k .. "e" .. " " .. args.sep}
	data.forms["pres_sub_1p"] = {args.pref .. pres_stem_k .. "en" .. " " .. args.sep}
	data.forms["pres_sub_2p"] = {args.pref .. pres_stem_k .. "et" .. " " .. args.sep}
	data.forms["pres_sub_3p"] = {args.pref .. pres_stem_k .. "en" .. " " .. args.sep}
	
	data.forms["past_sub_1s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep}
	data.forms["past_sub_2s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep, args.pref .. past_p_stem_k .. "is" .. " " .. args.sep}
	data.forms["past_sub_3s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep}
	data.forms["past_sub_1p"] = {args.pref .. past_p_stem_k .. "in" .. " " .. args.sep}
	data.forms["past_sub_2p"] = {args.pref .. past_p_stem_k .. "it" .. " " .. args.sep}
	data.forms["past_sub_3p"] = {args.pref .. past_p_stem_k .. "in" .. " " .. args.sep}
	
	data.forms["imp_s"] = {impr_s_stem .. " " .. args.sep, impr_s_stem_i .. " " .. args.sep}
	data.forms["imp_p"] = {args.pref .. impr_p_stem .. "et" .. " " .. args.sep}	
	data.forms["pres_part"] = {args.sep .. args.pref .. pres_stem .. "andi"}
	data.forms["past_part"] = {past_part .. "an"}
	if args.pref == "" then
		data.forms["past_part"] = {past_part .. "an", past_part_gi .. "an"}
	end
	
	if string.find(args.class, "[167]") then
			data.forms["imp_s"] = {impr_s_stem .. " " .. args.sep}
    elseif impr_s_stem == impr_s_stem_i then
			data.forms["imp_s"] = {impr_s_stem .. " " .. args.sep}
	end
	
	if args.irr=="j-present" then
			data.forms["inf"] = {args.head or (args.sep .. args.pref .. args[1] .. "en")}
			data.forms["pres_ind_2s"] = {args.pref .. pres_stem_dgm .. "is" .. " " .. args.sep, args.pref .. pres_stem_dgm .. "ist" .. " " .. args.sep}
			data.forms["pres_ind_3s"] = {args.pref .. pres_stem_dgm .. "it" .. " " .. args.sep}
			data.forms["pres_ind_1p"] = {args.pref .. pres_stem .. "en" .. " " .. args.sep}
			data.forms["pres_ind_2p"] = {args.pref .. pres_stem_dgm .. "et" .. " " .. args.sep}
			data.forms["pres_ind_3p"] = {args.pref .. pres_stem .. "ent" .. " " .. args.sep}
			data.forms["imp_s"] = {args.pref .. pres_stem_dgm .. "i" .. " " .. args.sep}
			data.forms["imp_p"] = {args.pref .. pres_stem_dgm .. "et" .. " " .. args.sep}
			data.forms["pres_part"] = {args.pref .. pres_stem .. "endi" .. " " .. args.sep}
		end	
	
	if args.irr=="hiatus" then
			data.forms["pres_ind_2s"] = {args.pref .. pres_stem .. "es" .. " " .. args.sep, args.pref .. pres_stem .. "est" .. " " .. args.sep}
	    	data.forms["pres_ind_3s"] = {args.pref .. pres_stem .. "et" .. " " .. args.sep}
	    	data.forms["imp_s"] = {impr_s_stem .. " " .. args.sep}
		if args["class"] == "7" then
			data.forms["inf"] = {args.head or (args.pref .. args[1] .. "en")}
			data.forms["pres_ind_2s"] = {args.pref .. pres_stem .. "s" .. " " .. args.sep, args.pref .. pres_stem .. "st" .. " " .. args.sep}
	    	data.forms["pres_ind_3s"] = {args.pref .. pres_stem .. "t" .. " " .. args.sep}
			data.forms["pres_ind_1p"] = {args.pref .. pres_stem .. "en" .. " " .. args.sep}
	    	data.forms["pres_ind_2p"] = {args.pref .. pres_stem .. "t" .. " " .. args.sep}
			data.forms["pres_ind_3p"] = {args.pref .. pres_stem .. "ent" .. " " .. args.sep}
			data.forms["past_ind_1s"] = {args.pref .. past_s_stem_dv .. " " .. args.sep, args.pref .. pres_stem .. "da" .. " " .. args.sep}
			data.forms["past_ind_2s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep, args.pref .. pres_stem .. "dos" .. " " .. args.sep}
			data.forms["past_ind_3s"] = {args.pref .. past_s_stem_dv .. " " .. args.sep, args.pref .. pres_stem .. "da" .. " " .. args.sep}
			data.forms["past_ind_1p"] = {args.pref .. past_p_stem .. "un" .. " " .. args.sep, args.pref .. pres_stem .. "dun" .. " " .. args.sep}
			data.forms["past_ind_2p"] = {args.pref .. past_p_stem .. "ut" .. " " .. args.sep, args.pref .. pres_stem .. "dut" .. " " .. args.sep}
			data.forms["past_ind_3p"] = {args.pref .. past_p_stem .. "un" .. " " .. args.sep, args.pref .. pres_stem .. "dun" .. " " .. args.sep}
			data.forms["past_sub_1s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep, args.pref .. pres_stem .. "di" .. " " .. args.sep}
			data.forms["past_sub_2s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep, args.pref .. pres_stem .. "dis" .. " " .. args.sep}
			data.forms["past_sub_3s"] = {args.pref .. past_p_stem_k .. "i" .. " " .. args.sep, args.pref .. pres_stem .. "di" .. " " .. args.sep}
			data.forms["past_sub_1p"] = {args.pref .. past_p_stem_k .. "in" .. " " .. args.sep, args.pref .. pres_stem .. "din" .. " " .. args.sep}
			data.forms["past_sub_2p"] = {args.pref .. past_p_stem_k .. "it" .. " " .. args.sep, args.pref .. pres_stem .. "dit" .. " " .. args.sep}
			data.forms["past_sub_3p"] = {args.pref .. past_p_stem_k .. "in" .. " " .. args.sep, args.pref .. pres_stem .. "din" .. " " .. args.sep}
			data.forms["imp_p"] = {args.pref .. pres_stem_dgm .. "t" .. " " .. args.sep}
			data.forms["past_part"] = {past_part .. "t"}
			if args.pref == "" then
				data.forms["past_part"] = {past_part .. "t", past_part_gi .. "t"}
			end
			data.forms["pres_part"] = {args.sep .. args.pref .. pres_stem .. "endi"}
		    end
		end

	if args.irr=="contracted" then
			data.forms["inf"] = {args.head or (args.sep .. args.pref .. args[1] .. "n")}
			data.forms["pres_ind_1s"] = {args.pref .. pres_stem .. " " .. args.sep, args.pref .. pres_stem .. "n" .. " " .. args.sep}
			data.forms["pres_ind_2s"] = {args.pref .. pres_stem_i .. "s" .. " " .. args.sep, args.pref .. pres_stem_i .. "st" .. " " .. args.sep}
	    	data.forms["pres_ind_3s"] = {args.pref .. pres_stem_i .. "t" .. " " .. args.sep}
			data.forms["pres_ind_1p"] = {args.pref .. pres_stem .. "n" .. " " .. args.sep}
			data.forms["pres_ind_2p"] = {args.pref .. pres_stem .. "t" .. " " .. args.sep}
			data.forms["pres_ind_3p"] = {args.pref .. pres_stem .. "nt" .. " " .. args.sep}
			data.forms["pres_sub_1s"] = {args.pref .. pres_stem .. " " .. args.sep}
			data.forms["pres_sub_2s"] = {args.pref .. pres_stem .. "s" .. " " .. args.sep, args.pref .. pres_stem .. "st" .. " " .. args.sep}
			data.forms["pres_sub_3s"] = {args.pref .. pres_stem .. " " .. args.sep}
			data.forms["pres_sub_1p"] = {args.pref .. pres_stem .. "n" .. " " .. args.sep}
			data.forms["pres_sub_2p"] = {args.pref .. pres_stem .. "t" .. " " .. args.sep}
			data.forms["pres_sub_3p"] = {args.pref .. pres_stem .. "n" .. " " .. args.sep}
			data.forms["imp_s"] = {args.pref .. pres_stem .. " " .. args.sep}
			data.forms["imp_p"] = {args.pref .. pres_stem .. "t" .. " " .. args.sep}
			data.forms["pres_part"] = {args.sep .. args.pref .. pres_stem .. "ndi"}
			data.forms["past_part"] = {past_part .. "n", past_part_2 .. "an"}
			if args.pref == "" then
				data.forms["past_part"] = {past_part_gi .. "n", past_part_2 .. "an"}
			end
		end
	
	table.insert(data.categories, "Old Dutch class " .. args.class .. " strong verbs")
end
})

conj_data["wk1"] = {
	params = {
		[1] = {},
		["sep"] = {},
		["pref"] = {},
		["degem"] = {},
		["irr"] = {},
		},
}
setmetatable(conj_data["wk1"], {__call = function(self, args, data)

	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	if args["irr"] == 'rückumlaut' then
			data.conj_type = "weak class 1 irregular, [[Rückumlaut]]"
			table.insert(data.categories, "Old Dutch class 1 weak rückumlaut verbs")
		elseif args["irr"] == 'j-present' then
			data.conj_type = "weak class 1 j-present"
			table.insert(data.categories, "Old Dutch class 1 weak j-present verbs")
		elseif args["irr"] == 'hiatus' then
			data.conj_type = "weak class 1 irregular, [[hiatus]]"
			table.insert(data.categories, "Old Dutch hiatus verbs")
		elseif not args["irr"] then
			data.conj_type = "weak class 1"
		end
--
    stem = args[1]
	pres_stem = stem
	pres_stem_c = K_to_C(pres_stem)
	past_part = stem
	past_stem = stem
	past_conj_stem = stem
--
	if args["degem"] then
	   		pres_stem_dgm = degeminate(pres_stem)
		elseif not args["degem"] then
	   		pres_stem_dgm = pres_stem
		end
--
	if not args.irr then
			if args["degem"]=='true' then 
		 		past_stem = degeminate(stem) .. "id"
		 		past_conj_stem = past_stem
		 		past_part = devoice(past_stem)
			else
		 		past_stem = stem .. "id"	
		 		past_conj_stem = past_stem
	     		past_part = devoice(past_stem)	
			end
		elseif args.irr=="hiatus" then
			past_stem = stem .. "d"	
		 	past_conj_stem = past_stem	
	     	past_part = devoice(past_stem)
		elseif args.irr=="rückumlaut" then
			past_stem = degeminate(backumlaut(degeminate(initial_K_to_C(stem))) .. "d")
			past_conj_stem = degeminate(degeminate(stem) .. "d")
			past_part = spirantize(devoice(past_stem))
		elseif args.irr=="j-present" then
			past_stem = stem:gsub("en", "ā")
			past_stem = past_stem:gsub("un", "ū")
			past_stem = past_stem:gsub("ir", "or")
			past_stem = spirantize(past_stem .. "t")
			past_conj_stem = umlaut(past_stem)
			past_part = past_stem
		end

	if args["pref"] then
		if args["sep"] then
			past_part = args.sep .. args.pref .. past_part
			table.insert(data.categories, "Old Dutch separable verbs")
			table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		elseif not args["sep"] then
			args.sep = ""
			past_part = args.pref .. past_part
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		end
	elseif args["sep"] then
		args.pref = ""
		past_part_gi = args.sep .. "gi" .. past_part
		past_part = args.sep .. past_part
		table.insert(data.categories, "Old Dutch separable verbs")
		table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
	else
		args.sep = ""
		args.pref = ""
		past_part_gi = "gi" .. past_part
		table.insert(data.categories, "Old Dutch basic verbs")
	end

	data.forms["inf"] = {args.head or (args.sep .. args.pref .. args[1] .. "en")}
	
	data.forms["pres_ind_1s"] = {args.pref .. pres_stem_c .. "o" .. " " .. args.sep, args.pref .. pres_stem_c .. "on" .. " " .. args.sep}
	data.forms["pres_ind_2s"] = {args.pref .. pres_stem_dgm .. "is" .. " " .. args.sep, args.pref .. pres_stem_dgm .. "ist" .. " " .. args.sep}
	data.forms["pres_ind_3s"] = {args.pref .. pres_stem_dgm .. "it" .. " " .. args.sep}
	data.forms["pres_ind_1p"] = {args.pref .. pres_stem .. "en" .. " " .. args.sep}
	data.forms["pres_ind_2p"] = {args.pref .. pres_stem_dgm .. "it" .. " " .. args.sep}
	data.forms["pres_ind_3p"] = {args.pref .. pres_stem .. "ent" .. " " .. args.sep}

	data.forms["past_ind_1s"] = {args.pref .. past_stem .. "a" .. " " .. args.sep}
	data.forms["past_ind_2s"] = {args.pref .. past_stem .. "os" .. " " .. args.sep}
	data.forms["past_ind_3s"] = {args.pref .. past_stem .. "a" .. " " .. args.sep}
	data.forms["past_ind_1p"] = {args.pref .. past_stem .. "un" .. " " .. args.sep}
	data.forms["past_ind_2p"] = {args.pref .. past_stem .. "ut" .. " " .. args.sep}
	data.forms["past_ind_3p"] = {args.pref .. past_stem .. "un" .. " " .. args.sep}

	data.forms["pres_sub_1s"] = {args.pref .. pres_stem .. "e" .. " " .. args.sep}
	data.forms["pres_sub_2s"] = {args.pref .. pres_stem .. "es" .. " " .. args.sep, args.pref .. pres_stem .. "est" .. " " .. args.sep}
	data.forms["pres_sub_3s"] = {args.pref .. pres_stem .. "e" .. " " .. args.sep}
	data.forms["pres_sub_1p"] = {args.pref .. pres_stem .. "en" .. " " .. args.sep}
	data.forms["pres_sub_2p"] = {args.pref .. pres_stem .. "et" .. " " .. args.sep}
	data.forms["pres_sub_3p"] = {args.pref .. pres_stem .. "en" .. " " .. args.sep}
	
	data.forms["past_sub_1s"] = {args.pref .. past_conj_stem .. "i" .. " " .. args.sep}
	data.forms["past_sub_2s"] = {args.pref .. past_conj_stem .. "is" .. " " .. args.sep}
	data.forms["past_sub_3s"] = {args.pref .. past_conj_stem .. "i" .. " " .. args.sep}
	data.forms["past_sub_1p"] = {args.pref .. past_conj_stem .. "in" .. " " .. args.sep}
	data.forms["past_sub_2p"] = {args.pref .. past_conj_stem .. "it" .. " " .. args.sep}
	data.forms["past_sub_3p"] = {args.pref .. past_conj_stem .. "in" .. " " .. args.sep}
	
	data.forms["imp_s"] = {args.pref .. pres_stem_dgm .. "i" .. " " .. args.sep}
	data.forms["imp_p"] = {args.pref .. pres_stem_dgm .. "it" .. " " .. args.sep}
	
	data.forms["pres_part"] = {args.sep .. args.pref .. pres_stem .. "endi"}
	data.forms["past_part"] = {past_part, past_part_gi}
	
	if args.irr=="hiatus" then
		data.forms["pres_ind_2s"] = {args.pref .. pres_stem_dgm .. "s" .. args.sep, args.pref .. pres_stem_dgm .. "st" .. args.sep}
		data.forms["pres_ind_3s"] = {args.pref .. pres_stem_dgm .. "t" .. args.sep}
		data.forms["pres_ind_2p"] = {args.pref .. pres_stem_dgm .. "t" .. args.sep}
		data.forms["imp_s"] = {args.pref .. pres_stem_dgm .. " " .. args.sep}
		data.forms["imp_p"] = {args.pref .. pres_stem_dgm .. "t" .. args.sep}
	end
	
	table.insert(data.categories, "Old Dutch class 1 weak verbs")
end
})

conj_data["wk2"] = {
	params = {
		[1] = {},
		["sep"] = {},
		["pref"] = {},
		},
}
setmetatable(conj_data["wk2"], {__call = function(self, args, data)
	data.conj_type = "weak class 2" 
	
	stem = args[1]
	
	if args["pref"] then
		if args["sep"] then
			past_part = args.sep .. args.pref .. stem .. "ot"
			table.insert(data.categories, "Old Dutch separable verbs")
			table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		elseif not args["sep"] then
			args.sep = ""
			past_part = args.pref .. stem .. "ot"
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		end
	elseif args["sep"] then
		args.pref = ""
		past_part_gi = args.sep .. "gi" .. stem .. "ot"
		past_part = args.sep .. stem .. "ot"
		table.insert(data.categories, "Old Dutch separable verbs")
		table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
	else
		args.sep = ""
		args.pref = ""
		past_part_gi = "gi" .. stem .. "ot"
		past_part = stem .. "ot"
		table.insert(data.categories, "Old Dutch basic verbs")
	end
	
	data.forms["inf"] = {args.head or (args.sep .. args.pref .. stem .. "on")}
	
	data.forms["pres_ind_1s"] = {args.pref .. stem .. "o" .. " " .. args.sep, args.pref .. args[1] .. "on" .. " " .. args.sep}
	data.forms["pres_ind_2s"] = {args.pref .. stem .. "os" .. " " .. args.sep, args.pref .. args[1] .. "ost" .. " " .. args.sep}
	data.forms["pres_ind_3s"] = {args.pref .. stem .. "ot" .. " " .. args.sep}
	data.forms["pres_ind_1p"] = {args.pref .. stem .. "on" .. " " .. args.sep}
	data.forms["pres_ind_2p"] = {args.pref .. stem .. "ot" .. " " .. args.sep}
	data.forms["pres_ind_3p"] = {args.pref .. stem .. "ont" .. " " .. args.sep}

	data.forms["past_ind_1s"] = {args.pref .. stem .. "oda" .. " " .. args.sep}
	data.forms["past_ind_2s"] = {args.pref .. stem .. "odos" .. " " .. args.sep}
	data.forms["past_ind_3s"] = {args.pref .. stem .. "oda" .. " " .. args.sep}
	data.forms["past_ind_1p"] = {args.pref .. stem .. "odun" .. " " .. args.sep}
	data.forms["past_ind_2p"] = {args.pref .. stem .. "odut" .. " " .. args.sep}
	data.forms["past_ind_3p"] = {args.pref .. stem .. "odun" .. " " .. args.sep}

	data.forms["pres_sub_1s"] = {args.pref .. stem .. "o" .. " " .. args.sep}
	data.forms["pres_sub_2s"] = {args.pref .. stem .. "os" .. " " .. args.sep, args.pref .. stem .. "ost" .. " " .. args.sep}
	data.forms["pres_sub_3s"] = {args.pref .. stem .. "o" .. " " .. args.sep}
	data.forms["pres_sub_1p"] = {args.pref .. stem .. "on" .. " " .. args.sep}
	data.forms["pres_sub_2p"] = {args.pref .. stem .. "ot" .. " " .. args.sep}
	data.forms["pres_sub_3p"] = {args.pref .. stem .. "on" .. " " .. args.sep}
	
	data.forms["past_sub_1s"] = {args.pref .. stem .. "odi" .. " " .. args.sep}
	data.forms["past_sub_2s"] = {args.pref .. stem .. "odis" .. " " .. args.sep}
	data.forms["past_sub_3s"] = {args.pref .. stem .. "odi" .. " " .. args.sep}
	data.forms["past_sub_1p"] = {args.pref .. stem .. "odin" .. " " .. args.sep}
	data.forms["past_sub_2p"] = {args.pref .. stem .. "odit" .. " " .. args.sep}
	data.forms["past_sub_3p"] = {args.pref .. stem .. "odin" .. " " .. args.sep}
	
	data.forms["imp_s"] = {args.pref .. stem .. "o" .. " " .. args.sep}
	data.forms["imp_p"] = {args.pref .. stem .. "ot" .. " " .. args.sep}
	
	data.forms["pres_part"] = {args.sep .. args.pref .. stem .. "ondi"}
	data.forms["past_part"] = {past_part, past_part_gi}
	
	table.insert(data.categories, "Old Dutch class 2 weak verbs")
end
})

conj_data["wk3"] = {
	params = {
		[1] = {},
		["sep"] = {},
		["pref"] = {},
		},
}
setmetatable(conj_data["wk3"], {__call = function(self, args, data)
	data.conj_type = "weak class 3" 
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	stem_1 = args[1]
	stem_2 = backumlaut(degeminate(stem_1))
	
	pres_stem_1 = stem_1
	pres_stem_1_dgm = degeminate(stem_1)
	
	past_stem_1 = backumlaut(pres_stem_1_dgm) .. "d"
	past_conj_stem_1 = umlaut(past_stem_1)
	
	past_part_1 = spirantize(past_stem_1)
	past_part_2 = stem_2

	if args["pref"] then
		if args["sep"] then
			past_part_1 = args.sep .. args.pref .. past_part_1
			past_part_2 = args.sep .. args.pref .. past_part_2
			table.insert(data.categories, "Old Dutch separable verbs")
			table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		elseif not args["sep"] then
			args.sep = ""
			past_part_1 = args.pref .. past_part_1
			past_part_2 = args.pref .. past_part_2
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		end
	elseif args["sep"] then
		args.pref = ""
		past_part_1 = args.sep .. past_part_1
		past_part_2 = args.sep .. past_part_2
		table.insert(data.categories, "Old Dutch separable verbs")
		table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
	else
		args.sep = ""
		args.pref = ""
		past_part_1 = "gi" .. past_part_1
		past_part_2 = "gi" .. past_part_2
		table.insert(data.categories, "Old Dutch basic verbs")
	end

	data.forms["inf"] = {args.head or (args.sep .. args.pref .. pres_stem_1 .. "en"), args.head or (args.sep .. args.pref .. stem_2 .. "on")}
	
	data.forms["pres_ind_1s"] = {args.pref .. pres_stem_1 .. "o(n)" .. " " .. args.sep, args.pref .. stem_2 .. "o(n)" .. " " .. args.sep}
	data.forms["pres_ind_2s"] = {args.pref .. pres_stem_1_dgm .. "es(t)" .. " " .. args.sep, args.pref .. stem_2 .. "os(t)" .. " " .. args.sep}
	data.forms["pres_ind_3s"] = {args.pref .. pres_stem_1_dgm .. "et" .. " " .. args.sep, args.pref .. stem_2 .. "ot" .. " " .. args.sep}
	data.forms["pres_ind_1p"] = {args.pref .. pres_stem_1 .. "on" .. " " .. args.sep, args.pref .. stem_2 .. "on" .. " " .. args.sep}
	data.forms["pres_ind_2p"] = {args.pref .. pres_stem_1_dgm .. "et" .. " " .. args.sep, args.pref .. stem_2 .. "ot" .. " " .. args.sep}
	data.forms["pres_ind_3p"] = {args.pref .. pres_stem_1 .. "ent" .. " " .. args.sep, args.pref .. stem_2 .. "ont" .. " " .. args.sep}

	data.forms["past_ind_1s"] = {args.pref .. past_stem_1 .. "a" .. " " .. args.sep, args.pref .. stem_2 .. "oda" .. " " .. args.sep}
	data.forms["past_ind_2s"] = {args.pref .. past_stem_1 .. "os" .. " " .. args.sep, args.pref .. stem_2 .. "odos" .. " " .. args.sep}
	data.forms["past_ind_3s"] = {args.pref .. past_stem_1 .. "a" .. " " .. args.sep, args.pref .. stem_2 ..  "oda" .. " " .. args.sep}
	data.forms["past_ind_1p"] = {args.pref .. past_stem_1 .. "un" .. " " .. args.sep, args.pref .. stem_2 .. "odun" .. " " .. args.sep}
	data.forms["past_ind_2p"] = {args.pref .. past_stem_1 .. "ut" .. " " .. args.sep, args.pref .. stem_2 .. "odut" .. " " .. args.sep}
	data.forms["past_ind_3p"] = {args.pref .. past_stem_1 .. "un" .. " " .. args.sep, args.pref .. stem_2 .. "odun" .. " " .. args.sep}

	data.forms["pres_sub_1s"] = {args.pref .. pres_stem_1 .. "e" .. " " .. args.sep, args.pref .. stem_2 .. "o" .. " " .. args.sep}
	data.forms["pres_sub_2s"] = {args.pref .. pres_stem_1 .. "es(t)" .. " " .. args.sep, args.pref .. stem_2 .. "os(t)" .. " " .. args.sep}
	data.forms["pres_sub_3s"] = {args.pref .. pres_stem_1 .. "e" .. " " .. args.sep, args.pref .. stem_2 .. "o" .. " " .. args.sep}
	data.forms["pres_sub_1p"] = {args.pref .. pres_stem_1 .. "en" .. " " .. args.sep, args.pref .. stem_2 .. "on" .. " " .. args.sep}
	data.forms["pres_sub_2p"] = {args.pref .. pres_stem_1 .. "et" .. " " .. args.sep, args.pref .. stem_2 .. "ot" .. " " .. args.sep}
	data.forms["pres_sub_3p"] = {args.pref .. pres_stem_1 .. "en" .. " " .. args.sep, args.pref .. stem_2 .. "on" .. " " .. args.sep}
	
	data.forms["past_sub_1s"] = {args.pref .. past_conj_stem_1 .. "i" .. " " .. args.sep, args.pref .. stem_2 .. "odi" .. " " .. args.sep}
	data.forms["past_sub_2s"] = {args.pref .. past_conj_stem_1 .. "is" .. " " .. args.sep, args.pref .. stem_2 .. "odis" .. " " .. args.sep}
	data.forms["past_sub_3s"] = {args.pref .. past_conj_stem_1 .. "i" .. " " .. args.sep, args.pref .. stem_2 .. "odi" .. " " .. args.sep}
	data.forms["past_sub_1p"] = {args.pref .. past_conj_stem_1 .. "in" .. " " .. args.sep, args.pref .. stem_2 .. "odin" .. " " .. args.sep}
	data.forms["past_sub_2p"] = {args.pref .. past_conj_stem_1 .. "it" .. " " .. args.sep, args.pref .. stem_2 .. "odit" .. " " .. args.sep}
	data.forms["past_sub_3p"] = {args.pref .. past_conj_stem_1 .. "in" .. " " .. args.sep, args.pref .. stem_2 .. "odin" .. " " .. args.sep}
	
	data.forms["imp_s"] = {args.pref .. pres_stem_1_dgm  .. "e" .. " " .. args.sep, args.pref .. stem_2 .. "o" .. " " .. args.sep}
	data.forms["imp_p"] = {args.pref .. pres_stem_1_dgm  .. "et" .. " " .. args.sep, args.pref .. stem_2 .. "ot" .. " " .. args.sep}
	
	data.forms["pres_part"] = {args.pref .. pres_stem_1 .. "endi", args.pref .. stem_2 .. "ondi"}
	data.forms["past_part"] = {past_part_1, past_part_2 .. "ot"}
	
	table.insert(data.categories, "Old Dutch class 3 weak verbs")
end
})

conj_data["pp"] = {
	params = {
		[1] = {},
		["sep"] = {},
		["pref"] = {},
		["pp_an"] = {},
		},
}

setmetatable(conj_data["pp"], {__call = function(self, args, data)
	data.conj_type = "preterite-present" 
	
	if args[1]:sub(1,1) == "*" then
		error("Redundant asterisks")
	end
	
	stem = args[1]
	
	if stem == 'wit' then
			pres_s_stem = devoice(stem:gsub("i", "ē"))
		elseif stem == 'dug' then
			pres_s_stem = devoice(stem:gsub("u", "ō"))
		elseif stem ~= 'muot' then
			pres_s_stem = devoice(stem:gsub("u", "a"))
		else
			pres_s_stem = stem
		end
		
	pres_s_stem = devoice(degeminate(pres_s_stem))
	pres_s_stem_2p = spirantize(pres_s_stem .. "t")
	pres_p_stem = stem
	
	if stem.sub(stem, -1) == 'n' or stem.sub(stem, -1) == 'l' then
		past_suffix = 'd'
	else
		past_suffix = 't'
	end
	
	past_conj_stem = spirantize(degeminate(stem) .. past_suffix)
	if stem.sub(stem, -1) == 'n' or stem.sub(stem, -1) == 't' then
		past_stem = past_conj_stem
	else
		past_stem = backumlaut(past_conj_stem)
	end
	
	if args["pref"] then
		if args["sep"] then
			past_part = args.sep .. args.pref .. devoice(past_stem)
			if args["pp_an"] then
				past_part_an = args.sep .. args.pref .. pres_p_stem .. "an"
			end
			table.insert(data.categories, "Old Dutch separable verbs")
			table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		elseif not args["sep"] then
			args.sep = ""
			past_part = args.pref .. devoice(past_stem)
			if args["pp_an"] then
				past_part_an = args.pref .. pres_p_stem .. "an"
			end
			table.insert(data.categories, "Old Dutch prefixed verbs")
			table.insert(data.categories, "Old Dutch verbs prefixed with " .. args["pref"] .. "-")
		end
	elseif args["sep"] then
		args.pref = ""
		past_part = args.sep .. devoice(past_stem)
		if args["pp_an"] then
			past_part_an = args.sep .. pres_p_stem .. "an"
		end
		table.insert(data.categories, "Old Dutch separable verbs")
		table.insert(data.categories, "Old Dutch separable verbs with " .. args["sep"])
	else
		args.sep = ""
		args.pref = ""
		past_part = "gi" .. devoice(past_stem)
		if args["pp_an"] then
			past_part_an = "gi".. pres_p_stem .. "an"
		end
		table.insert(data.categories, "Old Dutch basic verbs")
	end

	data.forms["inf"] = {args.head or (args.sep .. args.pref .. stem .. "an")}
	
	data.forms["pres_ind_1s"] = {args.pref .. pres_s_stem .. " " .. args.sep}
	data.forms["pres_ind_2s"] = {args.pref .. pres_s_stem_2p .. " " .. args.sep}
	data.forms["pres_ind_3s"] = {args.pref .. pres_s_stem .. " " .. args.sep}
	data.forms["pres_ind_1p"] = {args.pref .. pres_p_stem .. "un" .. " " .. args.sep}
	data.forms["pres_ind_2p"] = {args.pref .. pres_p_stem .. "ut" .. " " .. args.sep}
	data.forms["pres_ind_3p"] = {args.pref .. pres_p_stem .. "un" .. " " .. args.sep}

	data.forms["past_ind_1s"] = {args.pref .. past_stem .. "a" .. " " .. args.sep}
	data.forms["past_ind_2s"] = {args.pref .. past_stem .. "os" .. " " .. args.sep}
	data.forms["past_ind_3s"] = {args.pref .. past_stem .. "a" .. " " .. args.sep}
	data.forms["past_ind_1p"] = {args.pref .. past_stem .. "un" .. " " .. args.sep}
	data.forms["past_ind_2p"] = {args.pref .. past_stem .. "ut" .. " " .. args.sep}
	data.forms["past_ind_3p"] = {args.pref .. past_stem .. "un" .. " " .. args.sep}

	data.forms["pres_sub_1s"] = {args.pref .. pres_p_stem .. "i" .. " " .. args.sep}
	data.forms["pres_sub_2s"] = {args.pref .. pres_p_stem .. "is" .. " " .. args.sep, pres_p_stem .. "ist" .. " " .. args.sep}
	data.forms["pres_sub_3s"] = {args.pref .. pres_p_stem .. "i" .. " " .. args.sep}
	data.forms["pres_sub_1p"] = {args.pref .. pres_p_stem .. "in" .. " " .. args.sep}
	data.forms["pres_sub_2p"] = {args.pref .. pres_p_stem .. "it" .. " " .. args.sep}
	data.forms["pres_sub_3p"] = {args.pref .. pres_p_stem .. "in" .. " " .. args.sep}
	
	data.forms["past_sub_1s"] = {args.pref .. past_conj_stem .. "i" .. " " .. args.sep}
	data.forms["past_sub_2s"] = {args.pref .. past_conj_stem .. "is" .. " " .. args.sep}
	data.forms["past_sub_3s"] = {args.pref .. past_conj_stem .. "i" .. " " .. args.sep}
	data.forms["past_sub_1p"] = {args.pref .. past_conj_stem .. "in" .. " " .. args.sep}
	data.forms["past_sub_2p"] = {args.pref .. past_conj_stem .. "it" .. " " .. args.sep}
	data.forms["past_sub_3p"] = {args.pref .. past_conj_stem .. "in" .. " " .. args.sep}
	
	data.forms["imp_s"] = {"-"}
	data.forms["imp_p"] = {"-"}
	
	data.forms["pres_part"] = {args.sep .. args.pref .. pres_p_stem .. "andi"}
	data.forms["past_part"] = {past_part, past_part_an}
	
	table.insert(data.categories, "Old Dutch preterite-present verbs")
end
})

conj_data.irregular = {}

conj_data.irregular["bringan"] = function(data)
	data.conj_type = "weak [[irregular]]"
	
	data.forms["inf"] = {"bringan"}
	
	data.forms["pres_ind_1s"] = {"bringo", "bringon"}
	data.forms["pres_ind_2s"] = {"bringis", "bringist"}
	data.forms["pres_ind_3s"] = {"bringit"}
	data.forms["pres_ind_1p"] = {"bringon"}
	data.forms["pres_ind_2p"] = {"bringit"}
	data.forms["pres_ind_3p"] = {"bringont"}

	data.forms["past_ind_1s"] = {"brāhta"}
	data.forms["past_ind_2s"] = {"brāhtos"}
	data.forms["past_ind_3s"] = {"brāhta"}
	data.forms["past_ind_1p"] = {"brāhtun"}
	data.forms["past_ind_2p"] = {"brāhtut"}
	data.forms["past_ind_3p"] = {"brāhtun"}
	
	data.forms["pres_sub_1s"] = {"bringe"}
	data.forms["pres_sub_2s"] = {"bringes", "bringest"}
	data.forms["pres_sub_3s"] = {"bringe"}
	data.forms["pres_sub_1p"] = {"bringen"}
	data.forms["pres_sub_2p"] = {"bringet"}
	data.forms["pres_sub_3p"] = {"bringen"}

	data.forms["past_sub_1s"] = {"brāhti"}
	data.forms["past_sub_2s"] = {"brāhtis"}
	data.forms["past_sub_3s"] = {"brāhti"}
	data.forms["past_sub_1p"] = {"brāhtin"}
	data.forms["past_sub_2p"] = {"brāhtit"}
	data.forms["past_sub_3p"] = {"brāhtin"}
	
	data.forms["imp_s"] = {"bring"}
	data.forms["imp_p"] = {"bringit"}
	
	data.forms["pres_part"] = {"bringandi"}
	data.forms["past_part"] = {"gibrāht"}
	
	table.insert(data.categories, "Old Dutch irregular weak verbs")
end

conj_data.irregular["duon"] = function(data)
	data.conj_type = "[[irregular]]"
	
	data.forms["inf"] = {"duon"}
	
	data.forms["pres_ind_1s"] = {"duo", "duon"}
	data.forms["pres_ind_2s"] = {"duos", "duost"}
	data.forms["pres_ind_3s"] = {"duot"}
	data.forms["pres_ind_1p"] = {"duon"}
	data.forms["pres_ind_2p"] = {"duot"}
	data.forms["pres_ind_3p"] = {"duont"}

	data.forms["past_ind_1s"] = {"deda"}
	data.forms["past_ind_2s"] = {"dedi", "dedis"}
	data.forms["past_ind_3s"] = {"deda"}
	data.forms["past_ind_1p"] = {"dādun"}
	data.forms["past_ind_2p"] = {"dādut"}
	data.forms["past_ind_3p"] = {"dādun"}
	
	data.forms["pres_sub_1s"] = {"duo"}
	data.forms["pres_sub_2s"] = {"duos", "duost"}
	data.forms["pres_sub_3s"] = {"duo"}
	data.forms["pres_sub_1p"] = {"duon"}
	data.forms["pres_sub_2p"] = {"duot"}
	data.forms["pres_sub_3p"] = {"duon"}

	data.forms["past_sub_1s"] = {"dādi"}
	data.forms["past_sub_2s"] = {"dādis"}
	data.forms["past_sub_3s"] = {"dādi"}
	data.forms["past_sub_1p"] = {"dādin"}
	data.forms["past_sub_2p"] = {"dādit"}
	data.forms["past_sub_3p"] = {"dādin"}
	
	data.forms["imp_s"] = {"duo"}
	data.forms["imp_p"] = {"duot"}
	
	data.forms["pres_part"] = {"duondi"}
	data.forms["past_part"] = {"gidān"}
	
	table.insert(data.categories, "Old Dutch irregular verbs")
	table.insert(data.categories, "Old Dutch contracted verbs")
end

conj_data.irregular["wesan"] = function(data)
	data.conj_type = "irregular [[suppletive]]"
	
	data.forms["inf"] = {"wesan", "sīn"}
	
	data.forms["pres_ind_1s"] = {"bim", "bin"}
	data.forms["pres_ind_2s"] = {"bis", "bist"}
	data.forms["pres_ind_3s"] = {"is", "ist"}
	data.forms["pres_ind_1p"] = {"sīn"}
	data.forms["pres_ind_2p"] = {"sīt"}
	data.forms["pres_ind_3p"] = {"sint", "sīn"}

	data.forms["past_ind_1s"] = {"was"}
	data.forms["past_ind_2s"] = {"wāri"}
	data.forms["past_ind_3s"] = {"was"}
	data.forms["past_ind_1p"] = {"wārun"}
	data.forms["past_ind_2p"] = {"wārut"}
	data.forms["past_ind_3p"] = {"wārun"}
	
	data.forms["pres_sub_1s"] = {"sī"}
	data.forms["pres_sub_2s"] = {"sīs", "sīst"}
	data.forms["pres_sub_3s"] = {"sī"}
	data.forms["pres_sub_1p"] = {"sīn"}
	data.forms["pres_sub_2p"] = {"sīt"}
	data.forms["pres_sub_3p"] = {"sīn"}

	data.forms["past_sub_1s"] = {"wāri"}
	data.forms["past_sub_2s"] = {"wāris", "wārist"}
	data.forms["past_sub_3s"] = {"wāri"}
	data.forms["past_sub_1p"] = {"wārin"}
	data.forms["past_sub_2p"] = {"wārit"}
	data.forms["past_sub_3p"] = {"wārin"}
	
	data.forms["imp_s"] = {"wis"}
	data.forms["imp_p"] = {"wisit"}
	
	data.forms["pres_part"] = {"wesandi"}
	data.forms["past_part"] = {"giwesan"}
	
	table.insert(data.categories, "Old Dutch suppletive verbs")
end

conj_data.irregular["willen"] = function(data)
	data.conj_type = "weak [[irregular]]"
	
	data.forms["inf"] = {"willen"}
	
	data.forms["pres_ind_1s"] = {"wil", "willo", "willon"}
	data.forms["pres_ind_2s"] = {"wilt", "willis", "willist"}
	data.forms["pres_ind_3s"] = {"wil", "wilt"}
	data.forms["pres_ind_1p"] = {"willon"}
	data.forms["pres_ind_2p"] = {"willet"}
	data.forms["pres_ind_3p"] = {"willent"}

	data.forms["past_ind_1s"] = {"wolda"}
	data.forms["past_ind_2s"] = {"woldos"}
	data.forms["past_ind_3s"] = {"wolda"}
	data.forms["past_ind_1p"] = {"woldun"}
	data.forms["past_ind_2p"] = {"woldut"}
	data.forms["past_ind_3p"] = {"woldun"}
	
	data.forms["pres_sub_1s"] = {"wille"}
	data.forms["pres_sub_2s"] = {"willes", "willest"}
	data.forms["pres_sub_3s"] = {"wille"}
	data.forms["pres_sub_1p"] = {"willen"}
	data.forms["pres_sub_2p"] = {"willet"}
	data.forms["pres_sub_3p"] = {"willen"}

	data.forms["past_sub_1s"] = {"wuldi"}
	data.forms["past_sub_2s"] = {"wuldis"}
	data.forms["past_sub_3s"] = {"wuldi"}
	data.forms["past_sub_1p"] = {"wuldin"}
	data.forms["past_sub_2p"] = {"wuldit"}
	data.forms["past_sub_3p"] = {"wuldin"}
	
	data.forms["imp_s"] = {"-"}
	data.forms["imp_p"] = {"-"}
	
	data.forms["pres_part"] = {"willendi"}
	data.forms["past_part"] = {"giwilt", "giwolt"}
	
	table.insert(data.categories, "Old Dutch irregular weak verbs")
end

local function add_asterisks(forms, data)
	for _, form in ipairs(forms) do
		for i, subform in ipairs(data.forms[form]) do
			data.forms[form][i] = "*" .. subform
		end
	end
end

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)

	local parent_args = frame:getParent().args
	local conj_type = (frame.args["conj"] or parent_args["conj"]) or "st"

	if not conj_data[conj_type] then
		error("Unknown conjugation '" .. conj_type .. "'")
	end
	
	local data = {forms = {}, categories = {}}
	
	data.head = parent_args["head"] or nil

	local args = require("Module:parameters").process(parent_args, conj_data[conj_type].params, true)
	
	-- Override for templates
	if not args[1] then
		setmetatable(args, {__index = function(self, key)
			return "{{{" .. key .. "}}}"
		end
		})
	end
	
	-- Generate the forms
	if parent_args.irr then
		table.insert(data.categories, "Old Dutch irregular verbs")
		if conj_data.irregular[parent_args.irr] then
			conj_data.irregular[parent_args.irr](data)
		else
			conj_data[conj_type](args, data)
		end
	else
		conj_data[conj_type](args, data)
	end

	-- Make the table
	return make_table(data)
end

function make_table(data)
	local function show_form(form)
		if not form then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
				subform = "*" .. subform
			end
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
			
		return table.concat(ret, ", ")
	end
	
	local function repl(param)
		if param == "conj_type" then
			return data.conj_type
		else
			return show_form(data.forms[param])
		end
	end
	
	local wikicode = [=[
<div class="NavFrame" style="width: 42em">
<div class="NavHead" style="background-color:#CCCCFF;">Conjugation of ''{{{inf}}}'' ({{{conj_type}}})</div>
<div class="NavContent">
{| style="width: 100%; border:1px solid #CCCCFF; line-height: 125%; background-color:#F9F9F9; text-align:center; border: 1px solid #CCCCFF;" cellspacing="1" cellpadding="3" cellspacing="1" class="inflection-table"
|- style="background-color:#F2F2FF;"
|-
! style="background-color:#DEDEEE;" | infinitive
| colspan="2" style="background-color:#EFEFEF;" | {{{inf}}}
|-
! style="background-color:#CCCCFF;" | [[indicative mood|indicative]]
! style="background-color:#DEDEEE;" | [[present tense|present]]
! style="background-color:#DEDEEE;" | [[past tense|past]]
|-
! style="background-color:#EEEEEE;" | 1st&nbsp;person&nbsp;singular
| style="background-color:#efefff;" | {{{pres_ind_1s}}}
| style="background-color:#efefff;" | {{{past_ind_1s}}}
|-
! style="background-color:#EEEEEE;" | 2nd&nbsp;person&nbsp;singular
| style="background-color:#efefff;" | {{{pres_ind_2s}}}
| style="background-color:#efefff;" | {{{past_ind_2s}}}
|-
! style="background-color:#EEEEEE;" | 3rd&nbsp;person&nbsp;singular
| style="background-color:#efefff;" | {{{pres_ind_3s}}}
| style="background-color:#efefff;" | {{{past_ind_3s}}}
|-
! style="background-color:#EEEEEE;" | 1st&nbsp;person&nbsp;plural
| style="background-color:#efefff;" | {{{pres_ind_1p}}}
| style="background-color:#efefff;" | {{{past_ind_1p}}}
|-
! style="background-color:#EEEEEE;" | 2nd&nbsp;person&nbsp;plural
| style="background-color:#efefff;" | {{{pres_ind_2p}}}
| style="background-color:#efefff;" | {{{past_ind_2p}}}
|-
! style="background-color:#EEEEEE;" | 3rd&nbsp;person&nbsp;plural
| style="background-color:#efefff;" | {{{pres_ind_3p}}}
| style="background-color:#efefff;" | {{{past_ind_3p}}}
|-
! style="background-color:#CCCCFF;" | [[subjunctive mood|subjunctive]]
! style="background-color:#eeeede;" | present
! style="background-color:#eeeede;" | past
|-
! style="background-color:#eeeeee;" | 1st&nbsp;person&nbsp;singular
| style="background-color:#ffffef;" | {{{pres_sub_1s}}}
| style="background-color:#ffffef;" | {{{past_sub_1s}}}
|-
! style="background-color:#eeeeee;" | 2nd&nbsp;person&nbsp;singular
| style="background-color:#ffffef;" | {{{pres_sub_2s}}}
| style="background-color:#ffffef;" | {{{past_sub_2s}}}
|-
! style="background-color:#eeeeee;" | 3rd&nbsp;person&nbsp;singular
| style="background-color:#ffffef;" | {{{pres_sub_3s}}}
| style="background-color:#ffffef;" | {{{past_sub_3s}}}
|-
! style="background-color:#eeeeee;" | 1st&nbsp;person&nbsp;plural
| style="background-color:#ffffef;" | {{{pres_sub_1p}}}
| style="background-color:#ffffef;" | {{{past_sub_1p}}}
|-
! style="background-color:#eeeeee;" | 2nd&nbsp;person&nbsp;plural
| style="background-color:#ffffef;" | {{{pres_sub_2p}}}
| style="background-color:#ffffef;" | {{{past_sub_2p}}}
|-
! style="background-color:#eeeeee;" | 3rd&nbsp;person&nbsp;plural
| style="background-color:#ffffef;" | {{{pres_sub_3p}}}
| style="background-color:#ffffef;" | {{{past_sub_3p}}}
|-
! style="background-color:#CCCCFF;" | [[imperative mood|imperative]]
! style="background-color:#eedede;" | present
! rowspan="3" style="background-color:#e0e0e0;" |
|-
! style="background-color:#eeeeee;" | singular
| style="background-color:#ffefef;" | {{{imp_s}}}
|-
! style="background-color:#eeeeee;" | plural
| style="background-color:#ffefef;" | {{{imp_p}}}
|-
! style="background-color:#CCCCFF; font-weight:bold;" | [[participle]]
! style="background-color:#deeede; font-weight:bold;" | [[present tense|present]]
! style="background-color:#deeede; font-weight:bold;" | [[past tense|past]]
|-
! style="background-color:#eeeeee; font-weight:bold;" |
| style="background-color:#efffef;" | {{{pres_part}}} 
| style="background-color:#efffef;" | {{{past_part}}}
|}</div></div>]=]

	return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end

return export