Module:gmw-noun

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

local export = {}

local genders = { ["m"] = "masculine", ["f"] = "feminine", ["n"] = "neuter", }

local function detect_j(stem) -- match long vowel or diphthong followed by consonants local rest, nucleus, coda = mw.ustring.match(stem, "^(.-)([āēīōūąįų]?̄?[aeiou]*)([bdfghjklmnprʀstþw]+)$")

if not rest or nucleus == "" then error("Stem does not end in a vowel or diphthong followed by consonants") elseif mw.ustring.len(coda) > 1 or mw.ustring.find(nucleus, "^[āēīōūąįų]̄?$") or mw.ustring.find(nucleus, "^[aeiou][aeiou]$") then return "ij" elseif mw.ustring.find(rest, "^[bdfghjklmnprʀstþwBDFGHJKLMNPRƦSTÞW]*$") then return "j" else error("Stem consists of multiple syllables or its weight cannot be otherwise be determined") end end

local function geminate(stem) stem = mw.ustring.gsub(stem, "w$", "uw") stem = mw.ustring.gsub(stem, "([bdghklmnpstþ])$", "%1%1") return stem end

-- Inflection functions

function export.a(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "" or mw.title.getCurrentTitle.subpageText}, ["g"] = {required = true, default = "m"}, ["n"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) if not (args["g"] == "m" or args["g"] == "n") then error("g= must be m or n") end local data = { forms = {}, info = nil, categories = {}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)([iīu])$") local stem_u

if suffix == "ī" then stem = stem .. "ij" data.info = "ja-stem" table.insert(data.categories, lang:getCanonicalName .. " " .. genders[args["g"]] .. " ja-stem nouns") elseif suffix == "i" then stem = geminate(stem) .. "j" data.info = "ja-stem" table.insert(data.categories, lang:getCanonicalName .. " " .. genders[args["g"]] .. " ja-stem nouns") elseif suffix == "u" then stem_u = stem stem = stem .. "w" data.info = "wa-stem" table.insert(data.categories, lang:getCanonicalName .. " " .. genders[args["g"]] .. " wa-stem nouns") else stem = args[1] data.info = "a-stem" table.insert(data.categories, lang:getCanonicalName .. " " .. genders[args["g"]] .. " a-stem nouns") end stem_u = stem_u or stem data.info = genders[args["g"]] .. " " .. data.info data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = data.forms["nom|s"] data.forms["gen|s"] = {stem .. "as"} data.forms["dat|s"] = {stem .. "ē"} data.forms["ins|s"] = {stem_u .. "u"} data.forms["nom|p"] = args["g"] == "n" and {stem_u .. "u"} or {stem .. "ō", stem .. "ōs"} data.forms["acc|p"] = args["g"] == "n" and {stem_u .. "u"} or {stem .. "ā"} data.forms["gen|p"] = {stem .. "ō"} data.forms["dat|p"] = {stem_u .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.an(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "ō" or mw.title.getCurrentTitle.subpageText}, ["n"] = {}, ["wk"] = {}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local stem, suffix = mw.ustring.match(args[1], "^(.-)([āō])$") local g

if suffix == "ā" then g = "n" elseif suffix == "ō" then g = "m" else error("an-stems must end in -ō or -ā") end local data = { forms = {}, info = "an-stem", categories = {lang:getCanonicalName .. " " .. genders[g] .. " an-stem nouns"}, }

data.info = genders[g] .. " " .. data.info if args["wk"] then stem_weak = args["wk"] table.insert(data.categories, lang:getCanonicalName .. " irregular nouns") else stem_weak = stem end data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = g == "n" and {args[1]} or {stem .. "an"} data.forms["gen|s"] = {stem_weak .. "ini", stem_weak .. "an"} data.forms["dat|s"] = data.forms["gen|s"] data.forms["ins|s"] = data.forms["gen|s"] data.forms["nom|p"] = g == "n" and {stem .. "ōn"} or {stem .. "an"} data.forms["acc|p"] = data.forms["nom|p"] data.forms["gen|p"] = {stem_weak .. "anō"} data.forms["dat|p"] = {stem_weak .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.cons(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "" or mw.title.getCurrentTitle.subpageText}, ["n"] = {}, ["ns"] = {}, ["wk"] = {}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = "consonant stem", categories = {lang:getCanonicalName .. " consonant stem nouns"}, }	if args["wk"] then stem_weak = args["wk"] table.insert(data.categories, lang:getCanonicalName .. " irregular nouns") else stem_weak = args[1] end if args["ns"] then table.insert(data.categories, lang:getCanonicalName .. " irregular nouns") end

data.forms["nom|s"] = {args["ns"] or args[1]} data.forms["acc|s"] = {args["ns"] or args[1] .. "u"} data.forms["gen|s"] = {stem_weak .. "i"} data.forms["dat|s"] = data.forms["gen|s"] data.forms["ins|s"] = data.forms["gen|s"] data.forms["nom|p"] = {args[1] .. "i"} data.forms["acc|p"] = data.forms["nom|p"] data.forms["gen|p"] = {stem_weak .. "ō"} data.forms["dat|p"] = {stem_weak .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.i(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "i" or mw.title.getCurrentTitle.subpageText},

["j"] = {default = mw.title.getCurrentTitle.nsText == "Template" and "ij" or nil}, ["n"] = {}, ["wk"] = {}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = nil, categories = {}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)(i)$") local stem_j, stem_weak_j if args["wk"] then stem_weak = args["wk"] table.insert(data.categories, lang:getCanonicalName .. " irregular nouns") else stem_weak = stem end if suffix == "i" then if (args["j"] or detect_j(stem)) == "ij" then stem_j = stem .. "ij" stem_weak_j = stem_weak .. "ij" else stem_j = geminate(stem) .. "j" stem_weak_j = geminate(stem_weak) .. "j" end else error("i-stems must end in -i") end data.info = "i-stem" table.insert(data.categories, lang:getCanonicalName .. " i-stem nouns") data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = data.forms["nom|s"] data.forms["gen|s"] = {stem_weak .. "ī"} data.forms["dat|s"] = data.forms["gen|s"] data.forms["ins|s"] = data.forms["gen|s"] data.forms["nom|p"] = {stem .. "ī"} data.forms["acc|p"] = data.forms["nom|p"] data.forms["gen|p"] = {stem_weak_j .. "ō"} data.forms["dat|p"] = {stem_weak .. "im", stem_weak_j .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

export["in"] = function(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "ī" or mw.title.getCurrentTitle.subpageText},

["n"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = "īn-stem", categories = {lang:getCanonicalName .. " īn-stem nouns"}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)(ī)$")

if suffix ~= "ī" then error("īn-stems must end in -ī") end data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = {stem .. "īn"} data.forms["gen|s"] = data.forms["acc|s"] data.forms["dat|s"] = data.forms["acc|s"] data.forms["ins|s"] = data.forms["acc|s"]

postprocess(args, data) return make_table(data) end

function export.o(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "u" or mw.title.getCurrentTitle.subpageText},

["j"] = {}, ["n"] = {}, ["w"] = {type = "boolean"}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = nil, categories = {}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)([iu])$") local stem_u

if suffix == "i" then if (args["j"] or detect_j(stem)) == "ij" then stem = stem .. "ij" elseif mw.ustring.match(stem, "^(.-)([bdfghjklmnprʀstþw-]+)(in)$") then stem = mw.ustring.gsub(stem, "in$", "unn") .. "j" else stem = geminate(stem) .. "j" end

data.info = "ī/jō-stem" table.insert(data.categories, lang:getCanonicalName .. " ī/jō-stem nouns") elseif suffix == "u" then if args["w"] then stem_u = stem stem = stem .. "w" data.info = "wō-stem" table.insert(data.categories, lang:getCanonicalName .. " wō-stem nouns") else data.info = "ō-stem" table.insert(data.categories, lang:getCanonicalName .. " ō-stem nouns") end else error("ō-stems must end in -i or -u") end

stem_u = stem_u or stem

data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = {stem .. "ā"} data.forms["gen|s"] = data.forms["acc|s"] data.forms["dat|s"] = {stem .. "ē"} data.forms["ins|s"] = {stem_u .. "u"} data.forms["nom|p"] = {stem .. "ō"} data.forms["acc|p"] = {stem .. "ā"} data.forms["gen|p"] = {stem .. "ō"} data.forms["dat|p"] = {stem .. "ōm", stem_u .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.on(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "ā" or mw.title.getCurrentTitle.subpageText},

["n"] = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = "ōn-stem", categories = {lang:getCanonicalName .. " ōn-stem nouns"}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)(ā)$")

if suffix ~= "ā" then error("ōn-stems must end in -ā") end data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = {stem .. "ōn"} data.forms["gen|s"] = data.forms["acc|s"] data.forms["dat|s"] = data.forms["acc|s"] data.forms["ins|s"] = data.forms["acc|s"] data.forms["nom|p"] = data.forms["acc|s"] data.forms["acc|p"] = data.forms["acc|s"] data.forms["gen|p"] = {stem .. "ōnō"} data.forms["dat|p"] = {stem .. "ōm", stem .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.r(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "er" or mw.title.getCurrentTitle.subpageText},

["n"] = {}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = "r-stem", categories = {lang:getCanonicalName .. " r-stem nouns"}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)(er)$")

if suffix ~= "er" then error("r-stems must end in -er") end data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = {stem .. "ar"} data.forms["gen|s"] = {stem .. "ur"} data.forms["dat|s"] = {stem .. "ri"} data.forms["ins|s"] = data.forms["dat|s"] data.forms["nom|p"] = {stem .. "ar"} data.forms["acc|p"] = data.forms["nom|p"] data.forms["gen|p"] = {stem .. "rō"} data.forms["dat|p"] = {stem .. "rum"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.u(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "u" or mw.title.getCurrentTitle.subpageText},

["n"] = {}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = nil, categories = {}, }

local stem, suffix = mw.ustring.match(args[1], "^(.-)(u)$")

if suffix ~= "u" then error("u-stems must end in -u") end data.info = "u-stem" table.insert(data.categories, lang:getCanonicalName .. " u-stem nouns") data.forms["nom|s"] = {args[1]} data.forms["acc|s"] = data.forms["nom|s"] data.forms["gen|s"] = {stem .. "ō"} data.forms["dat|s"] = {stem .. "iwi", stem .. "ō"} data.forms["ins|s"] = {stem .. "u"}

data.forms["nom|p"] = {stem .. "iwi", stem .. "ō"} data.forms["acc|p"] = {stem .. "ū"} data.forms["gen|p"] = {stem .. "iwō"} data.forms["dat|p"] = {stem .. "um"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function export.z(frame) local params = { [1] = {default = mw.title.getCurrentTitle.nsText == "Template" and "" or mw.title.getCurrentTitle.subpageText},

["n"] = {}, ["ns"] = {}, }

local args = require("Module:parameters").process(frame:getParent.args, params)

local data = { forms = {}, info = "z-stem", categories = {lang:getCanonicalName .. " z-stem nouns"}, }	local stem_i = mw.ustring.gsub(args[1], "e(u?[bdfghklmnprʀstþw]*)$", "i%1") if args["ns"] then table.insert(data.categories, lang:getCanonicalName .. " irregular nouns") end

data.forms["nom|s"] = {args["ns"] or args[1]} data.forms["acc|s"] = data.forms["nom|s"] data.forms["gen|s"] = {stem_i .. "iʀi"} data.forms["dat|s"] = data.forms["gen|s"] data.forms["ins|s"] = data.forms["gen|s"] data.forms["nom|p"] = {stem_i .. "iʀu"} data.forms["acc|p"] = data.forms["nom|p"] data.forms["gen|p"] = {stem_i .. "iʀō"} data.forms["dat|p"] = {stem_i .. "iʀum"} data.forms["ins|p"] = data.forms["dat|p"]

postprocess(args, data) return make_table(data) end

function postprocess(args, data) data.n = args["n"] if args["n"] == "p" then table.insert(data.categories, lang:getCanonicalName .. " pluralia tantum") elseif args["n"] == "s" then table.insert(data.categories, lang:getCanonicalName .. " singularia tantum") elseif args["n"] then error("args= must be \"s\" or \"p\".") end

for key, form in pairs(data.forms) do		-- Do not show singular or plural forms for nominals that don't have them if (args["n"] == "p" and key:find("|s$")) or (args["n"] == "s" and key:find("|p$")) then form = nil end

data.forms[key] = form end end

-- Make the table function make_table(data) local function repl(param) if param == "info" then return mw.getContentLanguage:ucfirst(data.info or "") end local forms = data.forms[param] if not forms then return "&mdash;" end local ret = {} for key, subform in ipairs(forms) do			-- i-umlaut if mw.ustring.find(subform, "[iīįǐj]") then subform = mw.ustring.gsub(subform, "([bdfghjklmnprʀstþwBDFGHJKLMNPRƦSTÞW])e(u?)([bdfghjklmnprʀstþw]+)([iīįj])", "%1i%2%3%4") subform = mw.ustring.gsub(subform, "([bdfghjklmnprʀstþwBDFGHJKLMNPRƦSTÞW])o([bdfghjklmnprʀstþw]+)([iīįj])", "%1u%2%3") end -- *u[+stress] > *o /{C,#}_C[-nasal]V[+back] if mw.ustring.find(subform, "u") then subform = mw.ustring.gsub(subform, "^([bdfghjklmnprʀstþwBDFGHJKLMNPRƦSTÞW]+)u([bdfghklprʀstþw]+)([aoāōą])", "%1o%2%3") end -- *w > ∅ /V́_*u if mw.ustring.find(subform, "[aeiouāēīōūAEIOUĀĒĪŌŪ]wu") then subform = mw.ustring.gsub(subform, "^([bdfghjklmnprʀstþwBDFGHJKLMNPRƦSTÞW]*)uwu", "%1ū") subform = mw.ustring.gsub(subform, "^([bdfghjklmnprʀstþwBDFGHJKLMNPRƦSTÞW]*)([aeiouāēīōūAEIOUĀĒĪŌŪ])w(u)", "%1%2%3") end -- Mahlow's Law (*ōu > *ō / _C{#,V}) if mw.ustring.find(subform, "ō[uw]") then subform = mw.ustring.gsub(subform, "(ō)[uw]", "%1") end if mw.ustring.find(subform, "ū[uw]") then subform = mw.ustring.gsub(subform, "(ū)[uw]", "%1") end -- C[+plosive -voice] > CC /_LV (Ringe 2014:54) if mw.ustring.find(subform, "[ptkh][lr]") then subform = mw.ustring.gsub(subform, "([aeiouāēīōūAEIOUĀĒĪŌŪ])([ptkh])([lr][aeiouāēīōūąįų])", "%1%2%2%3") end table.insert(ret, require("Module:links").full_link({lang = lang, alt = "*" .. subform})) end return table.concat(ret, ", ") end local wikicode = {} table.insert(wikicode, [=[

return mw.ustring.gsub(table.concat(wikicode), "", repl) .. require("Module:utilities").format_categories(data.categories, lang) end

return export