Module:hu-nominals

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

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

local export = {}

-- 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 = {}} -- Generate the forms inflections[infl_type](args, data) -- Postprocess postprocess(args, data) if args["form"] then table.insert(data.categories, "hu-decl with form") end return make_table(data) .. m_utilities.format_categories(data.categories, lang) end

-- Inflection functions

local function check_acc(stem, acc_sg_vowel, acc_sg_vowel2) if (mw.ustring.find(stem, "[nsz]$") or mw.ustring.find(stem, "[aáeéiíoóöőuúüű][lr]$") or mw.ustring.find(stem, "ny$") or mw.ustring.find(stem, "[aáeéiíoóöőuúüű]ly$")) and not mw.ustring.find(stem, "cs$") then acc_sg_vowel2 = "" end if acc_sg_vowel ~= acc_sg_vowel2 then require("Module:debug").track("hu-nominals/acc") end end

local function make_stems(stem) local stems = {normal = stem} stems.b = mw.ustring.gsub(stem, "bb$", "b") .. "b" stems.k = mw.ustring.gsub(stem, "kk$", "k") .. "k" stems.n = mw.ustring.gsub(stem, "nn$", "n") .. "n" stems.r = mw.ustring.gsub(stem, "rr$", "r") .. "r" stems.t = mw.ustring.gsub(stem, "tt$", "t") .. "t" stems.v = stem .. "v" -- Remove v after a long consonant stems.v = mw.ustring.gsub(stems.v, "(ccs)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(ddz)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(ddzs)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(ggy)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(lly)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(nny)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(ssz)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(tty)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "(zzs)v$", "%1") stems.v = mw.ustring.gsub(stems.v, "([bcdfghjklmnpqrstvwz])%1v$", "%1%1") -- Assimilate v to preceding short consonant stems.v = mw.ustring.gsub(stems.v, "csv$", "ccs") stems.v = mw.ustring.gsub(stems.v, "dzv$", "ddz") stems.v = mw.ustring.gsub(stems.v, "dzsv$", "ddzs") stems.v = mw.ustring.gsub(stems.v, "gyv$", "ggy") stems.v = mw.ustring.gsub(stems.v, "lyv$", "lly") stems.v = mw.ustring.gsub(stems.v, "nyv$", "nny") stems.v = mw.ustring.gsub(stems.v, "szv$", "ssz") stems.v = mw.ustring.gsub(stems.v, "thv$", "tht") stems.v = mw.ustring.gsub(stems.v, "tyv$", "tty") stems.v = mw.ustring.gsub(stems.v, "xv$", "xsz") stems.v = mw.ustring.gsub(stems.v, "zsv$", "zzs") stems.v = mw.ustring.gsub(stems.v, "([bcdfghjklmnpqrstvwz])v$", "%1%1") return stems end

local function make_plural(data, stem, vh) if vh == "o" then vh = {a = "a", aa = "á", o = "o", oo = "ó", u = "u"} elseif vh == "ö" then vh = {a = "e", aa = "é", o = "ö", oo = "ő", u = "ü"} elseif vh == "e" then vh = {a = "e", aa = "é", o = "e", oo = "ő", u = "ü"} end

data.forms["nom_pl"] = {stem .. "k"} data.forms["acc_pl"] = {stem .. "k" .. vh.a .. "t"} data.forms["dat_pl"] = {stem .. "kn" .. vh.a .. "k"} data.forms["ins_pl"] = {stem .. "kk" .. vh.a .. "l"} data.forms["cfi_pl"] = {stem .. "kért"} data.forms["tra_pl"] = {stem .. "kk" .. vh.aa} data.forms["ter_pl"] = {stem .. "kig"} data.forms["esf_pl"] = {stem .. "kként"} data.forms["esm_pl"] = {stem .. "k" .. vh.u .. "l"} data.forms["ine_pl"] = {stem .. "kb" .. vh.a .. "n"} data.forms["spe_pl"] = {stem .. "k" .. vh.o .. "n"} data.forms["ade_pl"] = {stem .. "kn" .. vh.aa .. "l"} data.forms["ill_pl"] = {stem .. "kb" .. vh.a} data.forms["sbl_pl"] = {stem .. "kr" .. vh.a} data.forms["all_pl"] = {stem .. "kh" .. vh.o .. "z"} data.forms["ela_pl"] = {stem .. "kb" .. vh.oo .. "l"} data.forms["del_pl"] = {stem .. "kr" .. vh.oo .. "l"} data.forms["abl_pl"] = {stem .. "kt" .. vh.oo .. "l"} data.forms["np1_pl"] = {stem .. "ké"} data.forms["np2_pl"] = {stem .. "kéi"} end

local function make_singular_short(data, stem, stem2, spe_sg_stem, acc_sg_vowel, v, vh) if vh == "o" then vh = {a = "a", aa = "á", o = "o", oo = "ó", u = "u"} elseif vh == "ö" then vh = {a = "e", aa = "é", o = "ö", oo = "ő", u = "ü"} elseif vh == "e" then vh = {a = "e", aa = "é", o = "e", oo = "ő", u = "ü"} end stem2 = make_stems(stem2 or mw.ustring.gsub(stem, "[aeoö]$", "")) if v then stem2.v = stem2.normal .. v	end local stem_no_vowel = mw.ustring.gsub(stem, "[aeoö]$", "") spe_sg_stem = spe_sg_stem or stem2.normal spe_sg_stem = spe_sg_stem .. (mw.ustring.find(spe_sg_stem, "[aáeéiíoóöőuúüű]$") and "" or vh.o)	local acc_sg_stem = stem if acc_sg_vowel == "-" then acc_sg_stem = stem2.normal elseif acc_sg_vowel then acc_sg_stem = stem_no_vowel .. acc_sg_vowel end data.forms["nom_sg"] = {mw.title.getCurrentTitle.text} data.forms["acc_sg"] = {acc_sg_stem .. "t"} data.forms["dat_sg"] = {stem2.n .. vh.a .. "k"} data.forms["ins_sg"] = {stem2.v .. vh.a .. "l"} data.forms["cfi_sg"] = {stem2.normal .. "ért"} data.forms["tra_sg"] = {stem2.v .. vh.aa} data.forms["ter_sg"] = {stem2.normal .. "ig"} data.forms["esf_sg"] = {stem2.k .. "ént"} data.forms["esm_sg"] = {stem2.normal .. vh.u .. "l"} data.forms["ine_sg"] = {stem2.b .. vh.a .. "n"} data.forms["spe_sg"] = {spe_sg_stem .. "n"} data.forms["ade_sg"] = {stem2.n .. vh.aa .. "l"} data.forms["ill_sg"] = {stem2.b .. vh.a} data.forms["sbl_sg"] = {stem2.r .. vh.a} data.forms["all_sg"] = {stem2.normal .. "h" .. vh.o .. "z"} data.forms["ela_sg"] = {stem2.b .. vh.oo .. "l"} data.forms["del_sg"] = {stem2.r .. vh.oo .. "l"} data.forms["abl_sg"] = {stem2.t .. vh.oo .. "l"} data.forms["np1_sg"] = {stem2.normal .. "é"} data.forms["np2_sg"] = {stem2.normal .. "éi"} end

local function make_singular_long(data, stem, vh) if not mw.ustring.find(stem, "%-$") then if not mw.ustring.find(stem, "[iuüáéíóőúű]$") then require("Module:debug").track("hu-nominals/vowel") elseif stem ~= mw.ustring.gsub(mw.title.getCurrentTitle.text, "([aeoö])$", {["a"] = "á", ["e"] = "é", ["o"] = "ó", ["ö"] = "ő"}) then require("Module:debug").track("hu-nominals/pagename") end end if vh == "o" then vh = {a = "a", aa = "á", o = "o", oo = "ó", u = "u"} elseif vh == "ö" then vh = {a = "e", aa = "é", o = "ö", oo = "ő", u = "ü"} elseif vh == "e" then vh = {a = "e", aa = "é", o = "e", oo = "ő", u = "ü"} end local stems = make_stems(stem) data.forms["nom_sg"] = {mw.title.getCurrentTitle.text} data.forms["acc_sg"] = {stems.normal .. "t"} data.forms["dat_sg"] = {stems.n .. vh.a .. "k"} data.forms["ins_sg"] = {stems.v .. vh.a .. "l"} data.forms["cfi_sg"] = {stems.normal .. "ért"} data.forms["tra_sg"] = {stems.v .. vh.aa} data.forms["ter_sg"] = {stems.normal .. "ig"} data.forms["esf_sg"] = {mw.title.getCurrentTitle.text .. (mw.ustring.find(stems.normal, "%-$") and "-" or "") .. "ként"} data.forms["esm_sg"] = {stems.normal .. vh.u .. "l"} data.forms["ine_sg"] = {stems.b .. vh.a .. "n"} data.forms["spe_sg"] = {stems.normal .. "n"} data.forms["ade_sg"] = {stems.n .. vh.aa .. "l"} data.forms["ill_sg"] = {stems.b .. vh.a} data.forms["sbl_sg"] = {stems.r .. vh.a} data.forms["all_sg"] = {stems.normal .. "h" .. vh.o .. "z"} data.forms["ela_sg"] = {stems.b .. vh.oo .. "l"} data.forms["del_sg"] = {stems.r .. vh.oo .. "l"} data.forms["abl_sg"] = {stems.t .. vh.oo .. "l"} data.forms["np1_sg"] = {stems.normal .. "é"} data.forms["np2_sg"] = {stems.normal .. "éi"} end

local function make_singular_Vk(data, stem, stem2, spe_sg_stem, acc_t, v, vh) if vh == "o" then vh = {a = "a", aa = "á", o = "o", oo = "ó", u = "u"} elseif vh == "ö" then vh = {a = "e", aa = "é", o = "ö", oo = "ő", u = "ü"} elseif vh == "e" then vh = {a = "e", aa = "é", o = "e", oo = "ő", u = "ü"} end local stems = make_stems(stem) if v then stems.v = stems.normal .. v	end stem2 = stem2 or stem spe_sg_stem = spe_sg_stem or stem2 acc_t = acc_t or "t" local fill_vowel = mw.ustring.find(spe_sg_stem, "[aáeéiíoóöőuúüű]$") and "" or vh.o	data.forms["nom_sg"] = {mw.title.getCurrentTitle.text} data.forms["acc_sg"] = {stem2 .. acc_t} data.forms["dat_sg"] = {stems.n .. vh.a .. "k"} data.forms["ins_sg"] = {stems.v .. vh.a .. "l"} data.forms["cfi_sg"] = {stems.normal .. "ért"} data.forms["tra_sg"] = {stems.v .. vh.aa} data.forms["ter_sg"] = {stems.normal .. "ig"} data.forms["esf_sg"] = {stems.k .. "ént"} data.forms["esm_sg"] = {stems.normal .. vh.u .. "l"} data.forms["ine_sg"] = {stems.b .. vh.a .. "n"} data.forms["spe_sg"] = {spe_sg_stem .. fill_vowel .. "n"} data.forms["ade_sg"] = {stems.n .. vh.aa .. "l"} data.forms["ill_sg"] = {stems.b .. vh.a} data.forms["sbl_sg"] = {stems.r .. vh.a} data.forms["all_sg"] = {stems.normal .. "h" .. vh.o .. "z"} data.forms["ela_sg"] = {stems.b .. vh.oo .. "l"} data.forms["del_sg"] = {stems.r .. vh.oo .. "l"} data.forms["abl_sg"] = {stems.t .. vh.oo .. "l"} data.forms["np1_sg"] = {stems.normal .. "é"} data.forms["np2_sg"] = {stems.normal .. "éi"} end

inflections["regular"] = function(args, data) local stem = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if stem == "" then error("Parameter 1 (base stem) may not be empty.") end local vh = args[2] or (mw.title.getCurrentTitle.nsText == "Template" and "o") local acc_sg_vowel = args[3]; if acc_sg_vowel == "" then acc_sg_vowel = nil end local stem2 = args["stem2"]; if stem2 == "" then stem2 = nil end local spe_sg_stem = args["spe_sg_stem"]; if spe_sg_stem == "" then spe_sg_stem = nil end local v = args["v"]; if v == "" then v = nil end if not (vh == "o" or vh == "ö" or vh == "e") then error("Vowel harmony type must be \"o\", \"ö\" or \"e\".") end local vh_pl = vh	if mw.ustring.find(stem, "[aeoö]$") then data.title = "stem in " .. m_links.full_link({lang = lang, alt = "-" .. mw.ustring.match(stem, "([aeoö])$") .. "-"}, "term") if vh == "ö" and mw.ustring.find(stem, "e$") then vh_pl = "e" end make_singular_short(data, stem, stem2, spe_sg_stem, acc_sg_vowel, v, vh) elseif mw.ustring.find(stem, "[iuüáéíóőúű%-]$") or mw.title.getCurrentTitle.nsText == "Template" then data.title = "stem in long/high vowel" make_singular_long(data, stem, vh) else error("The stem must end in vowel or \"-\".") end if vh == "o" then data.title = data.title .. ", back harmony" elseif vh == "ö" then data.title = data.title .. ", front rounded harmony" elseif vh == "e" then data.title = data.title .. ", front unrounded harmony" end

make_plural(data, stem, vh_pl) end

inflections["ak"] = function(args, data) data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-ak"}, "term") .. ", back harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" local acc_t = args[3]; if acc_t == "" then acc_t = nil end local stem2 = args["stem"]; if stem2 == "" then stem2 = nil end local spe_sg_stem = args["sup"]; if spe_sg_stem == "" then spe_sg_stem = nil end local v = args["v"]; if v == "" then v = nil end if acc_t and not mw.ustring.find(acc_t, "^[aeoö]t$") then error("Invalid accusative singular") end make_singular_Vk(data, base .. final, stem2, spe_sg_stem, acc_t, v, "o") make_plural(data, (stem2 or base .. final) .. "a", "o") end

inflections["ek"] = function(args, data) data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-ek"}, "term") .. ", front unrounded harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" local acc_t = args[3]; if acc_t == "" then acc_t = nil end local stem2 = args["stem"]; if stem2 == "" then stem2 = nil end local spe_sg_stem = args["sup"]; if spe_sg_stem == "" then spe_sg_stem = nil end local v = args["v"]; if v == "" then v = nil end if acc_t and not mw.ustring.find(acc_t, "^[aeoö]t$") then error("Invalid accusative singular") end make_singular_Vk(data, base .. final, stem2, spe_sg_stem, acc_t, v, "e") make_plural(data, (stem2 or base .. final) .. "e", "e") end

inflections["ek2"] = function(args, data) data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-ek"}, "term") .. ", front rounded harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" local acc_t = args[3]; if acc_t == "" then acc_t = nil end local stem2 = args["stem"]; if stem2 == "" then stem2 = nil end local spe_sg_stem = args["sup"]; if spe_sg_stem == "" then spe_sg_stem = nil end local v = args["v"]; if v == "" then v = nil end if acc_t and not mw.ustring.find(acc_t, "^[aeoö]t$") then error("Invalid accusative singular") end make_singular_Vk(data, base .. final, stem2, spe_sg_stem, acc_t, v, "ö") make_plural(data, (stem2 or base .. final) .. "e", "e") end

inflections["ok"] = function(args, data) data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-ok"}, "term") .. ", back harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" local acc_t = args[3]; if acc_t == "" then acc_t = nil end local stem2 = args["stem"]; if stem2 == "" then stem2 = nil end local spe_sg_stem = args["sup"]; if spe_sg_stem == "" then spe_sg_stem = nil end local v = args["v"]; if v == "" then v = nil end if acc_t and not mw.ustring.find(acc_t, "^[aeoö]t$") then error("Invalid accusative singular") end make_singular_Vk(data, base .. final, stem2, spe_sg_stem, acc_t, v, "o") make_plural(data, (stem2 or base .. final) .. "o", "o") end

inflections["ök"] = function(args, data) data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-ök"}, "term") .. ", front rounded harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" local acc_t = args[3]; if acc_t == "" then acc_t = nil end local stem2 = args["stem"]; if stem2 == "" then stem2 = nil end local spe_sg_stem = args["sup"]; if spe_sg_stem == "" then spe_sg_stem = nil end local v = args["v"]; if v == "" then v = nil end if acc_t and not mw.ustring.find(acc_t, "^[aeoö]t$") then error("Invalid accusative singular") end

make_singular_Vk(data, base .. final, stem2, spe_sg_stem, acc_t, v, "ö") make_plural(data, (stem2 or base .. final) .. "ö", "ö") end

inflections["k-back"] = function(args, data) if args["stem"] or args["sup"] then require("Module:debug").track("hu-nominals/stem2") end data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-k"}, "term") .. ", back harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" make_singular_long(data, base .. final, "o") make_plural(data, base .. final, "o") end

inflections["k-front1"] = function(args, data) if args["stem"] or args["sup"] then require("Module:debug").track("hu-nominals/stem2") end data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-k"}, "term") .. ", front unrounded harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" make_singular_long(data, base .. final, "e") make_plural(data, base .. final, "e") end

inflections["k-front2"] = function(args, data) if args["stem"] or args["sup"] then require("Module:debug").track("hu-nominals/stem2") end data.title = "plural in " .. m_links.full_link({lang = lang, alt = "-k"}, "term") .. ", front rounded harmony" local base = args[1] or (mw.title.getCurrentTitle.nsText == "Template" and "") or ""; if base == "" then error("Parameter 1 (base stem) may not be empty.") end local final = args[2] or "" make_singular_long(data, base .. final, "ö") make_plural(data, base .. final, "ö") end

function postprocess(args, data) local n = args["n"] or args["form"]; if n == "" then n = nil end if n and not (n == "sg" or n == "sing" or n == "pl" or n == "isg") then error("The parameter \"n\" must be \"sg\", \"pl\", \"isg\" or empty.") -- isg: "i-type singular" like képeim, képeid, képei, which need to be inflected like singular but displayed as plural end

if n == "isg" then data.forms["esm_pl"] = data.forms["esm_sg"] end -- sortedPairs saves a list of keys so that we can modify the table -- while iterating over it. for key, form in require "Module:table".sortedPairs(data.forms) do		-- Do not show singular or plural forms for nominals that don't have them if (n == "pl" and key:find("_sg$")) or ((n == "sg" or n == "sing") and key:find("_pl$")) then data.forms[key] = nil end -- if "isg" is given for "n", singular forms are copied into the plural, then the singular forms are set to nil if (n == "isg" and key:find("_sg$")) then data.forms[string.gsub(key, "sg", "pl")] = form data.forms[key] = nil end end local function any_arg(...) for _, key in ipairs {...} do			if args[key] and args[key] ~= "" then return true end end return false end local has_esm_sg = any_arg("esm_sg", "ul", "ül") local has_esm_pl = any_arg("esm_pl", "akul", "ekül", "okul", "ökül", "kul", "kül") local has_noposs = any_arg("noposs", "é", "éi")

if not has_esm_sg then data.forms["esm_sg"] = nil end if not ((n == "isg" and has_esm_sg) or has_esm_pl) then data.forms["esm_pl"] = nil end

-- Blank the non-attributive possessive rows if noposs is specified in the call if has_noposs then data.forms["np1_sg"] = nil data.forms["np2_sg"] = nil data.forms["np1_pl"] = nil data.forms["np2_pl"] = nil end end

-- Make the table function make_table(data) local function show_form(forms, code) local form = forms[code] if not form then return "&mdash;" elseif type(form) ~= "table" then error("a non-table value was given in the list of inflected forms.") end local ret = {} local accel = { form = code:gsub("%f[^_](%a%a)$", {sg = "s", pl = "p"}):gsub("_", "|"), }		for key, subform in ipairs(form) do			table.insert(ret, m_links.full_link({ lang = lang, term = subform, accel = accel, }))		end return table.concat(ret, " ") 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 wikicode = [=[

return mw.ustring.gsub(wikicode, "", repl) end

return export