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 = {
= {
= {
= {"s"},
= {""},
= {"m̥"},
= {{stressed = "és", unstressed = "s"}},
= {{stressed = "és", unstressed = "s"}},
= {"éy"},
= {"", "i"},
= {{stressed = "éh₁", unstressed = "h₁"}},
= {"h₁(e)"},
= {"h₁(e)"},
= {"h₁(e)"},
= "?",
= "?",
= "?",
= "?",
= "?",
= {"es"},
= {"es"},
= {"m̥s"},
= {"óHom"},
= {"mós", "bʰós"},
= {"mós", "bʰós"},
= {"sú"},
= {"mís", "bʰís"},
},
= {
= {"ós"},
= {"é"},
= {"óm"},
= {"ósyo"},
= {"éad"},
= {"óey"},
= {"éy", "óy"},
= {"óh₁"},
= {"óh₁"},
= {"óh₁"},
= {"óh₁"},
= "?",
= "?",
= "?",
= "?",
= "?",
= {"óes"},
= {"óes"},
= {"óms"},
= {"óHom"},
= {"ómos", "óbʰos"},
= {"ómos", "óbʰos"},
= {"óysu"},
= {"ṓys"},
},
},
= {
= {
= {""},
= {""},
= {""},
= {"ih₁"},
= {"ih₁"},
= {"ih₁"},
= {"h₂"},
= {"h₂"},
= {"h₂"},
},
= {
= {"óm"},
= {"óm"},
= {"óm"},
= {"óy(h₁)"},
= {"óy(h₁)"},
= {"óy(h₁)"},
= {"éh₂"},
= {"éh₂"},
= {"éh₂"},
},
},
= {
= {
= {"h₂"},
= {"h₂"},
= {"h₂"},
},
= {
= {"éh₂"},
= {"éh₂"},
= {"éh₂"},
},
},
}
-- Copy over endings which are the same for animate and inanimate.
for _, t in ipairs({"athem", "them"}) do
for cn, _ in pairs(endings) do
if not endings then
endings = endings
end
if cn:find("_sg$") and not endings then
endings = endings
end
end
end
local endings_pron = {
= {
= {"ós"},
= {"óm"},
= {"ósyo"},
= {"ósmead"},
= {"ósmey"},
= {"ósmi"},
= {"ónoh₁"},
= {"óh₁"},
= {"óh₁"},
= "?",
= "?",
= "?",
= "?",
= "?",
= {"óy"},
= {"óms"},
= {"óysoHom"},
= {"óymos", "óybʰos"},
= {"óymos", "óybʰos"},
= {"óysu"},
= {"ṓys"},
},
= {
= {"éh₂"},
= {"éh₂m̥"},
= {"ósyeh₂s"},
= {"ósyeh₂s"},
= {"ósyeh₂ey"},
= {"ósyeh₂"},
= {"éh₂(e)h₁"},
= "?",
= "?",
= "?",
= "?",
= "?",
= "?",
= "?",
= {"éh₂es"},
= {"éh₂m̥s"},
= {"éh₂soHom"},
= {"éh₂mos", "éh₂bʰos"},
= {"éh₂mos", "éh₂bʰos"},
= {"éh₂su"},
= {"éh₂mis", "éh₂bʰis"},
},
= {
= {"ód"},
= {"ód"},
= {"óy"},
= {"óy"},
= {"éh₂"},
= {"éh₂"},
},
}
-- Copy over endings which are the same for animate and inanimate.
for cn, _ in pairs(endings_pron) do
if not endings_pron then
endings_pron = endings_pron
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, "$") then
endings = mw.clone(endings.them or endings)
if mw.ustring.find(stem1, "$") then
thematic_unstressed = true
end
stem1 = mw.ustring.gsub(stem1, "$", "")
stem2 = stem1
else
endings = endings.athem or endings
if mw.ustring.find(stem1, "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, "$") then
stem2_zero = mw.ustring.gsub(stem2, "é$", { = "ú", = "í"})
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, "$", { = "éy", = "ey", = "ew"})
-- Go over each case-number combination
for cn, cnendings in pairs(endings) do
if cnendings == "?" then
data.forms = {"?"}
elseif cnendings then
data.forms = {}
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, "$") 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, "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, 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 = form
end
end
function export.masc(frame)
local params = {
= {required = true},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
if mw.title.getCurrentTitle().nsText == "Template" then
args = args or "h₂éǵro"
end
args = args or args
local data = {forms = {}, title = nil, categories = {}}
data.sg = true
data.du = true
data.pl = true
data.coll = false
data.voc = true
if args then
if not mw.ustring.find(args, "s") then
data.sg = false
end
if not mw.ustring.find(args, "d") then
data.du = false
end
if not mw.ustring.find(args, "p") then
data.pl = false
end
end
local stem_type = {}
if mw.ustring.find(args, "$") then
data.info = "Thematic"
if mw.ustring.find(args, "-+$") then
table.insert(data.categories, lang:getCanonicalName() .. " thematic o-stem suffixes")
else
table.insert(data.categories, lang:getCanonicalName() .. " thematic o-stem nouns")
end
elseif mw.ustring.find(args, "h₂$") and args == args then
data.info = "Thematic in " .. m_links.full_link({lang = lang, alt = "*-eh₂"}, "term")
if mw.ustring.find(args, "-+h₂$") then
table.insert(data.categories, lang:getCanonicalName() .. " thematic eh₂-stem suffixes")
else
table.insert(data.categories, lang:getCanonicalName() .. " thematic eh₂-stem nouns")
end
else
data.info = "Athematic"
if mw.ustring.find(args, "+t(y|i|í)$") then
stem_type = " ti-stem"
elseif mw.ustring.find(args, "+t(w|u|ú)$") then
stem_type = " tu-stem"
elseif mw.ustring.find(args, "+(y|i|í)$") then
stem_type = " i-stem"
elseif mw.ustring.find(args, "+(y|y|í)h₂$") then
stem_type = " ih₂-stem"
elseif mw.ustring.find(args, "+(w|u|ú)$") then
stem_type = " u-stem"
elseif mw.ustring.find(args, "+(w|w|ú)h₂$") then
stem_type = " uh₂-stem"
elseif mw.ustring.find(args, "+m$") then
stem_type = " m-stem"
elseif mw.ustring.find(args, "+mn$") then
stem_type = " men-stem"
elseif mw.ustring.find(args, "+n$") then
stem_type = " n-stem"
elseif mw.ustring.find(args, "+$") then
stem_type = " r-stem"
elseif mw.ustring.find(args, "+$") then
stem_type = " t-stem"
elseif mw.ustring.find(args, "+$") then
stem_type = " s-stem"
elseif mw.ustring.find(args, "+$") then
stem_type = " h₁-stem"
else
stem_type = " root"
end
if args then
data.info = data.info .. ", " .. args
if mw.ustring.find(args, "-+$") then
table.insert(data.categories, lang:getCanonicalName() .. " " .. args .. stem_type .." suffixes")
else
table.insert(data.categories, lang:getCanonicalName() .. " " .. args .. stem_type .." nouns")
end
else
table.insert(data.categories, lang:getCanonicalName() .. " athematic nouns")
end
end
-- Create the forms
inflect(data, nil, endings, args, args, args)
if args then
data.forms = {args}
end
-- Collective
if args then
args = args or args
data.coll = true
local tempdata = {forms = {}}
inflect(tempdata, nil, endings, args, args, args)
for cn, forms in pairs(tempdata.forms) do
if cn:find("_sg$") then
local coll = cn:gsub("_sg$", "_coll")
data.forms = forms
end
end
end
postprocess(data)
return make_table(data)
end
function export.neut(frame)
local params = {
= {required = true},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
if mw.title.getCurrentTitle().nsText == "Template" then
args = args or "wérǵo"
end
args = args or args
local data = {forms = {}, title = nil, categories = {}}
data.sg = true
data.du = true
data.pl = true
data.coll = false
data.voc = true
if args then
if not mw.ustring.find(args, "s") then
data.sg = false
end
if not mw.ustring.find(args, "d") then
data.du = false
end
if not mw.ustring.find(args, "p") then
data.pl = false
end
end
local stem_type = {}
if mw.ustring.find(args, "$") then
data.info = "Thematic"
if mw.ustring.find(args, "-+$") then
table.insert(data.categories, lang:getCanonicalName() .. " thematic neuter o-stem suffixes")
else
table.insert(data.categories, lang:getCanonicalName() .. " thematic neuter o-stem nouns")
end
else
data.info = "Athematic"
if mw.ustring.find(args, "i$") then
stem_type = " i-stem"
elseif mw.ustring.find(args, "u$") then
stem_type = " u-stem"
elseif mw.ustring.find(args, "mn̥$") then
stem_type = " men-stem"
elseif mw.ustring.find(args, "n̥$") then
stem_type = " n-stem"
elseif mw.ustring.find(args, "̥$") then
stem_type = " r/n-stem"
elseif mw.ustring.find(args, "os$") then
stem_type = " s-stem"
elseif mw.ustring.find(args, "t$") then
stem_type = " t-stem"
else
stem_type = " root"
end
if args then
data.info = data.info .. ", " .. args
if mw.ustring.find(args, "-+$") then
table.insert(data.categories, lang:getCanonicalName() .. " " .. args .. " neuter".. stem_type .." suffixes")
else
table.insert(data.categories, lang:getCanonicalName() .. " " .. args .. " neuter".. stem_type .. " nouns")
end
else
table.insert(data.categories, lang:getCanonicalName() .. " athematic nouns")
end
end
-- Create the forms
inflect(data, nil, endings, args, args, args)
-- Collective
if args then
args = args or args
data.coll = true
local tempdata = {forms = {}}
inflect(tempdata, nil, endings, args, args, args)
for cn, forms in pairs(tempdata.forms) do
if cn:find("_sg$") then
local coll = cn:gsub("_sg$", "_coll")
data.forms = forms
end
end
end
postprocess(data)
return make_table(data)
end
function export.adj(frame)
local params = {
= {required = true},
= {},
= {},
= {},
= {},
= {},
= {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
if mw.title.getCurrentTitle().nsText == "Template" then
args = args or "néwo"
end
args = args or args
local data = {forms = {}, title = nil, categories = {}}
data.genders = true
data.sg = true
data.du = true
data.pl = true
data.voc = true
if args then
if not mw.ustring.find(args, "s") then
data.sg = false
end
if not mw.ustring.find(args, "d") then
data.du = false
end
if not mw.ustring.find(args, "p") then
data.pl = false
end
end
if mw.ustring.find(args, "$") then
data.info = "Thematic"
table.insert(data.categories, lang:getCanonicalName() .. " thematic adjectives")
if not args then
args = mw.ustring.gsub(args, "$", { = "eh₂", = "eh₂", = "éh₂", = "éh₂"})
args = args
end
else
data.info = "Athematic"
if args then
data.info = data.info .. ", " .. args
table.insert(data.categories, lang:getCanonicalName() .. " " .. args .. " adjectives")
else
table.insert(data.categories, lang:getCanonicalName() .. " athematic adjectives")
end
end
-- Create the forms
inflect(data, "m", endings, args, args, args)
inflect(data, "f", endings, args, args)
inflect(data, "n", endings, args, args, args)
postprocess(data)
return make_table(data)
end
function export.pron_adj(frame)
local params = {
= {required = true},
= {},
= {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
if mw.title.getCurrentTitle().nsText == "Template" then
args = args 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, "$") then
data.info = "Thematic pronominal"
else
error("Thematic only for now.")
end
-- Create the forms
inflect(data, "m", endings_pron, args)
inflect(data, "f", endings_pron, args)
inflect(data, "n", endings_pron, args)
data.forms = args and {args} or data.forms
data.forms = args and {args} or data.forms
postprocess(data)
return make_table(data)
end
local names = {
= "nominative",
= "vocative",
= "accusative",
= "genitive",
= "ablative",
= "dative",
= "locative",
= "instrumental",
= "singular",
= "dual",
= "plural",
= "collective",
= "masculine",
= "feminine",
= "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
if not form or #form == 0 then
return "—"
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) .. "\" | {{{info}}}")
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)
table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names)
else
table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names)
if data.coll then
table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names)
end
end
table.insert(wikicode, "|- class=\"vsShow\" style=\"background: #F2F2FF;\"")
table.insert(wikicode, "! style=\"min-width: 8em; background: #E6E6FF;\" | " .. names)
if data.genders then
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{m_nom_" .. first_number .. "}}}")
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{f_nom_" .. first_number .. "}}}")
else
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{nom_" .. first_number .. "}}}")
if data.coll then
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{nom_coll}}}")
end
end
table.insert(wikicode, "|- class=\"vsShow\" style=\"background: #F2F2FF;\"")
table.insert(wikicode, "! style=\"min-width: 8em; background: #E6E6FF;\" | " .. names)
if data.genders then
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{m_gen_" .. first_number .. "}}}")
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{f_gen_" .. first_number .. "}}}")
else
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{gen_" .. first_number .. "}}}")
if data.coll then
table.insert(wikicode, "| style=\"min-width: 11em;\" | {{{gen_coll}}}")
end
end
for _, gender in ipairs(genders) do
table.insert(wikicode, "|- class=\"vsHide\" style=\"background: #CCCCFF;\"")
if data.genders then
table.insert(wikicode, "! " .. names)
else
table.insert(wikicode, "!")
end
for _, number in ipairs(numbers) do
table.insert(wikicode, "! style=\"min-width: 11em; background: #CCCCFF;\" | " .. names)
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)
for _, number in ipairs(numbers) do
if data.genders then
table.insert(wikicode, "| {{{" .. gender .. "_" .. case .. "_" .. number .. "}}}")
else
table.insert(wikicode, "| {{{" .. case .. "_" .. number .. "}}}")
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