Module:ine-nominals

local m_utilities = require("Module:utilities") local m_links = require("Module:links") local m_common = require("Module:ine-common")

local export = {}

local lang = require("Module:languages").getByCode("ine-pro")

local endings = { ["anim"] = { ["athem"] = { ["nom_sg"] = {"s"}, ["voc_sg"] = {""}, ["acc_sg"] = {"m̥"}, ["gen_sg"] = , ["abl_sg"] = , ["dat_sg"] = {"éy"}, ["loc_sg"] = {"", "i"}, ["ins_sg"] = , ["nom_du"] = {"h₁(e)"}, ["voc_du"] = {"h₁(e)"}, ["acc_du"] = {"h₁(e)"}, ["gen_du"] = "?", ["abl_du"] = "?", ["dat_du"] = "?", ["loc_du"] = "?", ["ins_du"] = "?", ["nom_pl"] = {"es"}, ["voc_pl"] = {"es"}, ["acc_pl"] = {"m̥s"}, ["gen_pl"] = {"óHom"}, ["abl_pl"] = {"mós"}, ["dat_pl"] = {"mós"}, ["loc_pl"] = {"sú"}, ["ins_pl"] = {"mís"}, },		["them"] = { ["nom_sg"] = {"ós"}, ["voc_sg"] = {"é"}, ["acc_sg"] = {"óm"}, ["gen_sg"] = {"ósyo"}, ["abl_sg"] = {"éad"}, ["dat_sg"] = {"óey"}, ["loc_sg"] = {"éy", "óy"}, ["ins_sg"] = {"óh₁"}, ["nom_du"] = {"óh₁"}, ["voc_du"] = {"óh₁"}, ["acc_du"] = {"óh₁"}, ["gen_du"] = "?", ["abl_du"] = "?", ["dat_du"] = "?", ["loc_du"] = "?", ["ins_du"] = "?", ["nom_pl"] = {"óes"}, ["voc_pl"] = {"óes"}, ["acc_pl"] = {"óms"}, ["gen_pl"] = {"óHom"}, ["abl_pl"] = {"ómos"}, ["dat_pl"] = {"ómos"}, ["loc_pl"] = {"óysu"}, ["ins_pl"] = {"ṓys"}, },		},	["inan"] = { ["athem"] = { ["nom_sg"] = {""}, ["voc_sg"] = {""}, ["acc_sg"] = {""}, ["nom_du"] = {"ih₁"}, ["voc_du"] = {"ih₁"}, ["acc_du"] = {"ih₁"}, ["nom_pl"] = {"h₂"}, ["voc_pl"] = {"h₂"}, ["acc_pl"] = {"h₂"}, },		["them"] = { ["nom_sg"] = {"óm"}, ["voc_sg"] = {"óm"}, ["acc_sg"] = {"óm"}, ["nom_du"] = {"óy(h₁)"}, ["voc_du"] = {"óy(h₁)"}, ["acc_du"] = {"óy(h₁)"}, ["nom_pl"] = {"éh₂"}, ["voc_pl"] = {"éh₂"}, ["acc_pl"] = {"éh₂"}, },		},	["coll"] = { ["athem"] = { ["nom_sg"] = {"h₂"}, ["voc_sg"] = {"h₂"}, ["acc_sg"] = {"h₂"}, },		["them"] = { ["nom_sg"] = {"éh₂"}, ["voc_sg"] = {"éh₂"}, ["acc_sg"] = {"éh₂"}, },		}, }

-- Copy over endings which are the same for animate and inanimate. for _, t in ipairs({"athem", "them"}) do	for cn, _ in pairs(endings["anim"][t]) do		if not endings["inan"][t][cn] then endings["inan"][t][cn] = endings["anim"][t][cn] end if cn:find("_sg$") and not endings["coll"][t][cn] then endings["coll"][t][cn] = endings["anim"][t][cn] end end end

local endings_pron = { ["m"] = { ["nom_sg"] = {"ós"}, ["acc_sg"] = {"óm"}, ["gen_sg"] = {"ósyo"}, ["abl_sg"] = {"ósmead"}, ["dat_sg"] = {"ósmey"}, ["loc_sg"] = {"ósmi"}, ["ins_sg"] = {"ónoh₁"}, ["nom_du"] = {"óh₁"}, ["acc_du"] = {"óh₁"}, ["gen_du"] = "?", ["abl_du"] = "?", ["dat_du"] = "?", ["loc_du"] = "?", ["ins_du"] = "?", ["nom_pl"] = {"óy"}, ["acc_pl"] = {"óms"}, ["gen_pl"] = {"óysoHom"}, ["abl_pl"] = {"óymos"}, ["dat_pl"] = {"óymos"}, ["loc_pl"] = {"óysu"}, ["ins_pl"] = {"ṓys"}, },	["f"] = { ["nom_sg"] = {"éh₂"}, ["acc_sg"] = {"éh₂m̥"}, ["gen_sg"] = {"ósyeh₂s"}, ["abl_sg"] = {"ósyeh₂s"}, ["dat_sg"] = {"ósyeh₂ey"}, ["loc_sg"] = {"ósyeh₂"}, ["ins_sg"] = {"éh₂(e)h₁"}, ["nom_du"] = "?", ["acc_du"] = "?", ["gen_du"] = "?", ["abl_du"] = "?", ["dat_du"] = "?", ["loc_du"] = "?", ["ins_du"] = "?", ["nom_pl"] = {"éh₂es"}, ["acc_pl"] = {"éh₂m̥s"}, ["gen_pl"] = {"éh₂soHom"}, ["abl_pl"] = {"éh₂mos"}, ["dat_pl"] = {"éh₂mos"}, ["loc_pl"] = {"éh₂su"}, ["ins_pl"] = {"éh₂mis"}, },	["n"] = { ["nom_sg"] = {"ód"}, ["acc_sg"] = {"ód"}, ["nom_du"] = {"óy"}, ["acc_du"] = {"óy"}, ["nom_pl"] = {"éh₂"}, ["acc_pl"] = {"éh₂"}, }, }

-- Copy over endings which are the same for animate and inanimate. for cn, _ in pairs(endings_pron["m"]) do	if not endings_pron["n"][cn] then endings_pron["n"][cn] = endings_pron["m"][cn] end end

local function inflect(data, prefix, endings, stem1, stem2, loc_sg_stem) stem2 = stem2 or stem1 -- Is the stem thematic? local thematic_unstressed = false if mw.ustring.find(stem1, "[eoéó]$") then endings = mw.clone(endings.them or endings) if mw.ustring.find(stem1, "[eo]$") then thematic_unstressed = true end stem1 = mw.ustring.gsub(stem1, "[eoéó]$", "") stem2 = stem1 else endings = endings.athem or endings if mw.ustring.find(stem1, "[eoéó]h₂$") and stem1 == stem2 then thematic_unstressed = true end end if not loc_sg_stem then if mw.ustring.find(stem2, "[áéíĺḿńóŕúḗṓ́]") then loc_sg_stem = stem2 else loc_sg_stem = stem1 end end local stem2_zero = stem2 if mw.ustring.find(stem1, "[iu]$") then stem2_zero = mw.ustring.gsub(stem2, "é[wy]$", {["éw"] = "ú", ["éy"] = "í"}) end local stem1_full = stem1 if stem1 ~= stem2 and mw.ustring.gsub(stem1, "os$", "es") == stem2 then stem1_full = stem2 end local nom_pl_stem = mw.ustring.gsub(stem1, "[íiu]$", {["í"] = "éy", ["i"] = "ey", ["u"] = "ew"}) -- Go over each case-number combination for cn, cnendings in pairs(endings) do if cnendings == "?" then data.forms[(prefix and prefix .. "_" or "") .. cn] = {"?"} elseif cnendings then data.forms[(prefix and prefix .. "_" or "") .. cn] = {} for _, cnending in ipairs(cnendings) do				local stem = stem1 -- Use stem2 if the ending can be stressed, stem1 otherwise if cn == "loc_sg" then stem = loc_sg_stem elseif cn == "ins_sg" or cn == "abl_pl" or cn == "dat_pl" or cn == "loc_pl" or cn == "ins_pl" then stem = stem2_zero elseif (cn == "nom_du" or cn == "voc_du" or cn == "acc_du") then stem = stem1_full elseif (cn == "nom_pl" or cn == "voc_pl") and cnending == "es" then stem = nom_pl_stem elseif cnending.stressed or mw.ustring.find(cnending, "[áéíĺḿńóŕúḗṓ́]") then stem = stem2 end local ending = (thematic_unstressed and (cnending.unstressed or m_common.destress(cnending))) or cnending.stressed or cnending local ending_unstr = cnending.unstressed if (cn == "gen_sg" or cn == "abl_sg") and ending_unstr == "s" and mw.ustring.find(stem, "s$") then ending_unstr = "os" end if mw.ustring.find(stem, "[iu]$") then if cn == "acc_sg" and ending == "m̥" then ending = "m" elseif cn == "acc_pl" and ending == "m̥s" then ending = "ms" end end if mw.ustring.find(stem, "[eéoóaáiíuú]h₂$") and cn == "nom_sg" and ending == "s" then ending = "" end if not (cnending == "i" and mw.ustring.find(stem, "i$")) then table.insert(data.forms[(prefix and prefix .. "_" or "") .. cn], m_common.add_ending(stem, ending, ending_unstr, cn == "nom_sg" and ending == "s")) end end end end end

local function postprocess(data) for key, form in pairs(data.forms) do		-- Do not show singular, dual or plural forms for nouns that don't have them if (not data.sg and key:find("_sg$")) or (not data.du and key:find("_du$")) or (not data.pl and key:find("_pl$")) or (not data.coll and key:find("_coll$")) then form = nil end data.forms[key] = form end end

function export.masc(frame) local params = { [1] = {required = true}, [2] = {},		["nom_sg"] = {}, ["loc_sg"] = {}, ["coll"] = {}, ["coll2"] = {}, ["coll_loc"] = {}, ["ac"] = {}, ["n"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) if mw.title.getCurrentTitle.nsText == "Template" then args[1] = args[1] or "h₂éǵro" end args[2] = args[2] or args[1] local data = {forms = {}, title = nil, categories = {}} data.sg = true data.du = true data.pl = true data.coll = false data.voc = true if args["n"] then if not mw.ustring.find(args["n"], "s") then data.sg = false end if not mw.ustring.find(args["n"], "d") then data.du = false end if not mw.ustring.find(args["n"], "p") then data.pl = false end end local stem_type = {} if mw.ustring.find(args[1], "[eoéó]$") then data.info = "Thematic" table.insert(data.categories, lang:getCanonicalName .. " thematic o-stem nouns") elseif mw.ustring.find(args[1], "[eoéó]h₂$") and args[1] == args[2] then data.info = "Thematic in " .. m_links.full_link({lang = lang, alt = "*-eh₂"}, "term") table.insert(data.categories, lang:getCanonicalName .. " thematic eh₂-stem nouns") else data.info = "Athematic" if mw.ustring.find(args[1], "ti$") then stem_type = " ti-stem" elseif mw.ustring.find(args[1], "tu$") then stem_type = " tu-stem" elseif mw.ustring.find(args[1], "i$") then stem_type = " i-stem" elseif mw.ustring.find(args[1], "ih₂$") then stem_type = " ih₂-stem" elseif mw.ustring.find(args[1], "u$") then stem_type = " u-stem" elseif mw.ustring.find(args[1], "uh₂$") then stem_type = " uh₂-stem" elseif mw.ustring.find(args[1], "[eéoóaáiíuú][%a₁₂₃]+[eéoó]m$") then stem_type = " m-stem" elseif mw.ustring.find(args[1], "[eéoóaáiíuú][%a₁₂₃]+m[eéoó]n$") then stem_type = " men-stem" elseif mw.ustring.find(args[1], "[eéoóaáiíuú][%a₁₂₃]+[eéoó]n$") then stem_type = " n-stem" elseif mw.ustring.find(args[1], "[eéoóaáiíuú][%a₁₂₃]+[eéoó][lr]$") then stem_type = " r-stem" else stem_type = " root" end if args["ac"] then data.info = data.info .. ", " .. args["ac"] table.insert(data.categories, lang:getCanonicalName .. " " .. args["ac"] .. stem_type .." nouns") else table.insert(data.categories, lang:getCanonicalName .. " athematic nouns") end end -- Create the forms inflect(data, nil, endings["anim"], args[1], args[2], args["loc_sg"]) if args["nom_sg"] then data.forms["nom_sg"] = {args["nom_sg"]} end -- Collective if args["coll"] then args["coll2"] = args["coll2"] or args["coll"] data.coll = true local tempdata = {forms = {}} inflect(tempdata, nil, endings["coll"], args["coll"], args["coll2"], args["coll_loc"]) for cn, forms in pairs(tempdata.forms) do			if cn:find("_sg$") then local coll = cn:gsub("_sg$", "_coll") data.forms[coll] = forms end end end postprocess(data) return make_table(data) end

function export.neut(frame) local params = { [1] = {required = true}, [2] = {},		["loc_sg"] = {}, ["coll"] = {}, ["coll2"] = {}, ["coll_loc"] = {}, ["ac"] = {}, ["n"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) if mw.title.getCurrentTitle.nsText == "Template" then args[1] = args[1] or "wérǵo" end args[2] = args[2] or args[1] local data = {forms = {}, title = nil, categories = {}} data.sg = true data.du = true data.pl = true data.coll = false data.voc = true if args["n"] then if not mw.ustring.find(args["n"], "s") then data.sg = false end if not mw.ustring.find(args["n"], "d") then data.du = false end if not mw.ustring.find(args["n"], "p") then data.pl = false end end local stem_type = {} if mw.ustring.find(args[1], "[eoéó]$") then data.info = "Thematic" table.insert(data.categories, lang:getCanonicalName .. " thematic neuter o-stem nouns") else data.info = "Athematic" if mw.ustring.find(args[1], "i$") then stem_type = " i-stem" elseif mw.ustring.find(args[1], "u$") then stem_type = " u-stem" elseif mw.ustring.find(args[1], "mn̥$") then stem_type = " men-stem" elseif mw.ustring.find(args[1], "[lr]̥$") then stem_type = " r/n-stem" elseif mw.ustring.find(args[1], "os$") then stem_type = " s-stem" else stem_type = " root" end if args["ac"] then data.info = data.info .. ", " .. args["ac"] table.insert(data.categories, lang:getCanonicalName .. " " .. args["ac"] .. " neuter".. stem_type .. " nouns") else table.insert(data.categories, lang:getCanonicalName .. " athematic nouns") end end -- Create the forms inflect(data, nil, endings["inan"], args[1], args[2], args["loc_sg"]) -- Collective if args["coll"] then args["coll2"] = args["coll2"] or args["coll"] data.coll = true local tempdata = {forms = {}} inflect(tempdata, nil, endings["coll"], args["coll"], args["coll2"], args["coll_loc"]) for cn, forms in pairs(tempdata.forms) do			if cn:find("_sg$") then local coll = cn:gsub("_sg$", "_coll") data.forms[coll] = forms end end end postprocess(data) return make_table(data) end

function export.adj(frame) local params = { [1] = {required = true}, [2] = {},		["loc_sg"] = {}, [3] = {},		[4] = {},		["ac"] = {}, ["n"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) if mw.title.getCurrentTitle.nsText == "Template" then args[1] = args[1] or "néwo" end args[2] = args[2] or args[1] local data = {forms = {}, title = nil, categories = {}} data.genders = true data.sg = true data.du = true data.pl = true data.voc = true if args["n"] then if not mw.ustring.find(args["n"], "s") then data.sg = false end if not mw.ustring.find(args["n"], "d") then data.du = false end if not mw.ustring.find(args["n"], "p") then data.pl = false end end if mw.ustring.find(args[1], "[eoéó]$") then data.info = "Thematic" table.insert(data.categories, lang:getCanonicalName .. " thematic adjectives") if not args[3] then args[3] = mw.ustring.gsub(args[1], "[eoéó]$", {["e"] = "eh₂", ["o"] = "eh₂", ["é"] = "éh₂", ["ó"] = "éh₂"}) args[4] = args[3] end else data.info = "Athematic" if args["ac"] then data.info = data.info .. ", " .. args["ac"] table.insert(data.categories, lang:getCanonicalName .. " " .. args["ac"] .. " adjectives") else table.insert(data.categories, lang:getCanonicalName .. " athematic adjectives") end end -- Create the forms inflect(data, "m", endings["anim"], args[1], args[2], args["loc_sg"]) inflect(data, "f", endings["anim"], args[3], args[4]) inflect(data, "n", endings["inan"], args[1], args[2], args["loc_sg"]) postprocess(data) return make_table(data) end

function export.pron_adj(frame) local params = { [1] = {required = true}, ["m_nom_sg"] = {}, ["f_nom_sg"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) if mw.title.getCurrentTitle.nsText == "Template" then args[1] = args[1] or "h₂élyo" end local data = {forms = {}, title = nil, categories = {}} data.genders = true data.sg = true data.du = true data.pl = true data.voc = false if mw.ustring.find(args[1], "[eoéó]$") then data.info = "Thematic pronominal" else error("Thematic only for now.") end -- Create the forms inflect(data, "m", endings_pron["m"], args[1]) inflect(data, "f", endings_pron["f"], args[1]) inflect(data, "n", endings_pron["n"], args[1]) data.forms["m_nom_sg"] = args["m_nom_sg"] and {args["m_nom_sg"]} or data.forms["m_nom_sg"] data.forms["f_nom_sg"] = args["f_nom_sg"] and {args["f_nom_sg"]} or data.forms["f_nom_sg"] postprocess(data) return make_table(data) end

local names = { ["nom"] = "nominative", ["voc"] = "vocative", ["acc"] = "accusative", ["gen"] = "genitive", ["abl"] = "ablative", ["dat"] = "dative", ["loc"] = "locative", ["ins"] = "instrumental", ["sg"] = "singular", ["du"] = "dual", ["pl"] = "plural", ["coll"] = "collective", ["m"] = "masculine", ["f"] = "feminine", ["n"] = "neuter", }

-- Make the table function make_table(data) local function repl(param) if param == "info" then return mw.getContentLanguage:ucfirst(data.info or "") end local form = data.forms[param] if not form or #form == 0 then return "&mdash;" end local ret = {} for key, subform in ipairs(form) do table.insert(ret, m_links.full_link({lang = lang, alt = "*" .. subform})) end return table.concat(ret, ", ") end local numbers = {"sg", "du", "pl"} local genders = {"x"} local cases = {"nom", "acc", "gen", "abl", "dat", "loc", "ins"} if data.voc then table.insert(cases, 2, "voc") end if data.genders then genders = {"m", "f", "n"} elseif data.coll then table.insert(numbers, "coll") end local first_number = "sg" if not data.sg then first_number = "du" if not data.du then first_number = "pl" end end local wikicode = {} table.insert(wikicode, "{| class=\"inflection-table vsSwitcher\" data-toggle-category=\"inflection\" style=\"background: #FAFAFA; border: 1px solid #d0d0d0; text-align: left;\" cellspacing=\"1\" cellpadding=\"2\"") table.insert(wikicode, "|- style=\"background: #CCCCFF;\"\n! class=\"vsToggleElement\" colspan=\"" .. (#numbers + 1) .. "\" | ") table.insert(wikicode, "|- class=\"vsShow\" style=\"background: #CCCCFF;\"") table.insert(wikicode, "!") if data.genders then table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names["m"]) table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names["f"]) else table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names[first_number]) if data.coll then table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names["coll"]) end end table.insert(wikicode, "|- class=\"vsShow\" style=\"background: #F2F2FF;\"") table.insert(wikicode, "! style=\"min-width: 8em; background: #E6E6FF;\" | " .. names["nom"]) if data.genders then table.insert(wikicode, "| style=\"min-width: 11em;\" | ") table.insert(wikicode, "| style=\"min-width: 11em;\" | ") else table.insert(wikicode, "| style=\"min-width: 11em;\" | ") if data.coll then table.insert(wikicode, "| style=\"min-width: 11em;\" | ") end end table.insert(wikicode, "|- class=\"vsShow\" style=\"background: #F2F2FF;\"") table.insert(wikicode, "! style=\"min-width: 8em; background: #E6E6FF;\" | " .. names["gen"]) if data.genders then table.insert(wikicode, "| style=\"min-width: 11em;\" | ") table.insert(wikicode, "| style=\"min-width: 11em;\" | ") else table.insert(wikicode, "| style=\"min-width: 11em;\" | ") if data.coll then table.insert(wikicode, "| style=\"min-width: 11em;\" | ") end end for _, gender in ipairs(genders) do		table.insert(wikicode, "|- class=\"vsHide\" style=\"background: #CCCCFF;\"") if data.genders then table.insert(wikicode, "! " .. names[gender]) else table.insert(wikicode, "!") end for _, number in ipairs(numbers) do table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names[number]) end for _, case in ipairs(cases) do table.insert(wikicode, "|- class=\"vsHide\" style=\"background-color: #F2F2FF;\"\n! style=\"min-width: 8em; background-color: #E6E6FF;\" | " .. names[case]) for _, number in ipairs(numbers) do				if data.genders then table.insert(wikicode, "| ") else table.insert(wikicode, "| ") end end end end table.insert(wikicode, [=[|}]=]) wikicode = table.concat(wikicode, "\n") return (mw.ustring.gsub(wikicode, "", repl)) .. m_utilities.format_categories(data.categories, lang) end

return export