Module:zu-nouns
Jump to navigation
Jump to search
- The following documentation is located at Module:zu-nouns/documentation. [edit] Categories were auto-generated by Module:module categorization. [edit]
- Useful links: subpage list • links • transclusions • testcases • sandbox
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local m_common = require("Module:zu-common")
local lang = require("Module:languages").getByCode("zu")
local export = {}
local prefixes = {
["1"] = {
"^([uU][" .. m_common.diacritic .. "]*[mM][uU][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*[mM][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*)([nN].+)$",
},
["1a"] = {
"^([uU][" .. m_common.diacritic .. "]*)(.+)$",
},
["2"] = {
"^([aA][" .. m_common.diacritic .. "]*[bB][aeAE][" .. m_common.diacritic .. "]*)(.+)$",
"^([aA][" .. m_common.diacritic .. "]*[bB])([" .. m_common.vowel .. ".+)$",
},
["2a"] = {
"^([oO][" .. m_common.diacritic .. "]*)(.+)$",
},
["3"] = {
"^([uU][" .. m_common.diacritic .. "]*[mM][uU][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*[mM][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*)([nN].+)$",
},
["4"] = {
"^([iI][" .. m_common.diacritic .. "]*[mM][iI][" .. m_common.diacritic .. "]*)(.+)$",
"^([iI][" .. m_common.diacritic .. "]*[mM])([" .. m_common.vowel .. "].+)$",
},
["5"] = {
"^([iI][" .. m_common.diacritic .. "]*)(.+)$",
},
["6"] = {
"^([aA][" .. m_common.diacritic .. "]*[mM][aA][" .. m_common.diacritic .. "]*)(.+)$",
"^([aA][" .. m_common.diacritic .. "]*[mM])([" .. m_common.vowel .. "].+)$",
},
["7"] = {
"^([iI][" .. m_common.diacritic .. "]*[sS][iI][" .. m_common.diacritic .. "]*)(.+)$",
"^([iI][" .. m_common.diacritic .. "]*[sS])([" .. m_common.vowel .. "].+)$",
},
["8"] = {
"^([iI][" .. m_common.diacritic .. "]*[zZ][iI][" .. m_common.diacritic .. "]*)(.+)$",
"^([iI][" .. m_common.diacritic .. "]*[zZ])([" .. m_common.vowel .. "].+)$",
},
["9"] = {
"^([iI][" .. m_common.diacritic .. "]*[mMnN])([^" .. m_common.vowel .. "].+)$",
"^([iI][" .. m_common.diacritic .. "]*)([lLmMnN][" .. m_common.vowel .. "].+)$",
},
["10"] = {
"^([iI][" .. m_common.diacritic .. "]*[zZ][iI][" .. m_common.diacritic .. "]*[mMnN])([^" .. m_common.vowel .. "].+)$",
"^([iI][" .. m_common.diacritic .. "]*[zZ][iI][" .. m_common.diacritic .. "]*)([hHlLmMnN][" .. m_common.vowel .. "wW].+)$",
},
["11"] = {
"^([uU][" .. m_common.diacritic .. "]*)(.+)$",
--"^([uU][" .. m_common.diacritic .. "]*[lL][uU][" .. m_common.diacritic .. "]*)(.+)$",
--"^([uU][" .. m_common.diacritic .. "]*[lL][wW])([" .. m_common.vowel .. "].+)$",
},
["14"] = {
"^([uU][" .. m_common.diacritic .. "]*[bB][uU][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*[bB])([" .. m_common.vowel .. "].+)$",
"^([uU][" .. m_common.diacritic .. "]*[tT][sS][hH][wW]?)([aA].+)$",
},
["15"] = {
"^([uU][" .. m_common.diacritic .. "]*[kK][uU][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*[kK][wW])([" .. m_common.vowel .. "].+)$",
},
["17"] = {
"^([uU][" .. m_common.diacritic .. "]*[kK][uU][" .. m_common.diacritic .. "]*)(.+)$",
"^([uU][" .. m_common.diacritic .. "]*[kK][wW])([" .. m_common.vowel .. "].+)$",
},
}
local function split_prefix(word, class, tone)
if not prefixes[class] then
error("Invalid class \"" .. class .. "\".")
end
local prefix, stem
word = mw.ustring.toNFD(word)
for _, pattern in ipairs(prefixes[class]) do
prefix, stem = mw.ustring.match(word, pattern)
if prefix then
break
end
end
if not prefix then
if mw.title.getCurrentTitle().nsText ~= "Template" then
error("Word \"" .. word .. "\" does not match any valid prefix of class \"" .. class .. "\".")
end
else
local sstem = m_common.split_syllables(stem)
local stone = mw.text.split(tone or mw.ustring.rep("L", #sstem), "")
if #sstem ~= #stone then
error("The word \"" .. stem .. "\" and the tone pattern " .. tone .. " have different numbers of syllables.")
end
return mw.ustring.toNFC(prefix), mw.ustring.toNFC(stem)
end
end
function makeSortKey(word, class)
local prefix, stem = split_prefix(word, class)
return (lang:makeSortKey(stem or word))
end
local function simple(data, base, prefix, class)
base = (lang:makeEntryName(base))
if prefix then
prefix = prefix .. "_"
else
prefix = ""
end
if class == "2a" then
data.forms[prefix .. "simp"] = {"b" .. base}
elseif class == "5" then
data.forms[prefix .. "simp"] = {(mw.ustring.gsub(base, "^i", "li"))}
elseif class == "11" then
data.forms[prefix .. "simp"] = {(mw.ustring.gsub(base, "^u", "lu"))}
else
data.forms[prefix .. "simp"] = {(mw.ustring.gsub(base, "^[aiu]%-?", ""))}
end
end
local function locative_ku(data, base, prefix, tone)
base = (lang:makeEntryName(base))
if prefix then
prefix = prefix .. "_"
else
prefix = ""
end
if mw.ustring.find(base, "^[au]") then
data.forms[prefix .. "loc"] = {m_common.apply_tone("ku" .. mw.ustring.gsub(base, "^[au]", ""), tone)}
elseif mw.ustring.find(base, "^[" .. m_common.vowel .. "]") then
data.forms[prefix .. "loc"] = {m_common.apply_tone("k" .. base)}
elseif base == "mi" or base == "thi" or base == "ni" then
data.forms[prefix .. "loc"] = {m_common.apply_tone("ki" .. base, tone)}
else
data.forms[prefix .. "loc"] = {m_common.apply_tone("ku" .. base, tone)}
end
end
local function locative_e(data, base, prefix, class)
base = (lang:makeEntryName(base))
if prefix then
prefix = prefix .. "_"
else
prefix = ""
end
if mw.ustring.find(base, "^u") and class == "11" then
base = mw.ustring.gsub(base, "^u", "o")
else
base = mw.ustring.gsub(base, "^[aiu]", "e")
end
data.forms[prefix .. "loc"] = {base}
end
local function locative_extend(base)
base = (lang:makeEntryName(base))
base = mw.ustring.gsub(base, "[aou]$", {["a"] = "e", ["o"] = "we", ["u"] = "wi"}) .. "ni"
base = mw.ustring.gsub(base, "mbw([ei]ni)$", "nj%1")
base = mw.ustring.gsub(base, "mpw([ei]ni)$", "ntsh%1")
base = mw.ustring.gsub(base, "bhw([ei]ni)$", "j%1")
base = mw.ustring.gsub(base, "[bp]w([ei]ni)$", "tsh%1")
base = mw.ustring.gsub(base, "phw([ei]ni)$", "sh%1")
base = mw.ustring.gsub(base, "mw([ei]ni)$", "ny%1")
base = mw.ustring.gsub(base, "([fvw])w([ei]ni)$", "%1%2")
return base
end
local function copulative(data, base, prefix, class, tone)
base = (lang:makeEntryName(base))
if prefix then
prefix = prefix .. "_"
else
prefix = ""
end
if mw.ustring.find(base, "^u") and class == "11" then
data.forms[prefix .. "cop"] = {m_common.apply_tone("w" .. base)}
elseif mw.ustring.find(base, "^[aou]") then
data.forms[prefix .. "cop"] = {m_common.apply_tone("ng" .. base)}
elseif mw.ustring.find(base, "^i") then
data.forms[prefix .. "cop"] = {m_common.apply_tone("y" .. base)}
elseif base == "we" or base == "ye" then
data.forms[prefix .. "cop"] = {m_common.apply_tone("ngu" .. base, tone)}
else
data.forms[prefix .. "cop"] = {m_common.apply_tone("yi" .. base, tone)}
end
end
local function possessive(data, base, prefix, ka, tone)
base = (lang:makeEntryName(base))
local tone_subst
if tone then
tone_subst = "H" .. tone
end
if prefix then
prefix = prefix .. "_"
else
prefix = ""
end
if ka then
base = mw.ustring.gsub(base, "^u", "")
data.forms[prefix .. "poss_mod_c1" ] = { "ka" .. base}
data.forms[prefix .. "poss_mod_c2" ] = {"baka" .. base}
data.forms[prefix .. "poss_mod_c3" ] = { "ka" .. base}
data.forms[prefix .. "poss_mod_c4" ] = { "ka" .. base}
data.forms[prefix .. "poss_mod_c5" ] = {"lika" .. base}
data.forms[prefix .. "poss_mod_c6" ] = { "ka" .. base}
data.forms[prefix .. "poss_mod_c7" ] = {"sika" .. base}
data.forms[prefix .. "poss_mod_c8" ] = {"zika" .. base}
data.forms[prefix .. "poss_mod_c9" ] = { "ka" .. base}
data.forms[prefix .. "poss_mod_c10"] = {"zika" .. base}
data.forms[prefix .. "poss_mod_c11"] = {"luka" .. base}
data.forms[prefix .. "poss_mod_c14"] = {"buka" .. base}
data.forms[prefix .. "poss_mod_c15"] = {"kuka" .. base}
data.forms[prefix .. "poss_mod_c17"] = {"kuka" .. base}
data.forms[prefix .. "poss_subst_c1" ] = { "oka" .. base}
data.forms[prefix .. "poss_subst_c2" ] = {"abaka" .. base}
data.forms[prefix .. "poss_subst_c3" ] = { "oka" .. base}
data.forms[prefix .. "poss_subst_c4" ] = { "eka" .. base}
data.forms[prefix .. "poss_subst_c5" ] = {"elika" .. base}
data.forms[prefix .. "poss_subst_c6" ] = { "aka" .. base}
data.forms[prefix .. "poss_subst_c7" ] = {"esika" .. base}
data.forms[prefix .. "poss_subst_c8" ] = {"ezika" .. base}
data.forms[prefix .. "poss_subst_c9" ] = { "eka" .. base}
data.forms[prefix .. "poss_subst_c10"] = {"ezika" .. base}
data.forms[prefix .. "poss_subst_c11"] = {"oluka" .. base}
data.forms[prefix .. "poss_subst_c14"] = {"obuka" .. base}
data.forms[prefix .. "poss_subst_c15"] = {"okuka" .. base}
data.forms[prefix .. "poss_subst_c17"] = {"okuka" .. base}
else
local w
if mw.ustring.find(base, "^[ou]") then
base = mw.ustring.gsub(base, "^u", "o")
w = ""
elseif mw.ustring.find(base, "^[ai]") then
base = mw.ustring.gsub(base, "^i", "e")
w = "w"
else
base = "a" .. base
w = "w"
end
data.forms[prefix .. "poss_mod_c1" ] = {m_common.apply_tone("w" .. base, tone)}
data.forms[prefix .. "poss_mod_c2" ] = {m_common.apply_tone("b" .. base, tone)}
data.forms[prefix .. "poss_mod_c3" ] = {m_common.apply_tone("w" .. base, tone)}
data.forms[prefix .. "poss_mod_c4" ] = {m_common.apply_tone("y" .. base, tone)}
data.forms[prefix .. "poss_mod_c5" ] = {m_common.apply_tone("l" .. base, tone)}
data.forms[prefix .. "poss_mod_c6" ] = {m_common.apply_tone(base, tone)}
data.forms[prefix .. "poss_mod_c7" ] = {m_common.apply_tone("s" .. base, tone)}
data.forms[prefix .. "poss_mod_c8" ] = {m_common.apply_tone("z" .. base, tone)}
data.forms[prefix .. "poss_mod_c9" ] = {m_common.apply_tone("y" .. base, tone)}
data.forms[prefix .. "poss_mod_c10"] = {m_common.apply_tone("z" .. base, tone)}
data.forms[prefix .. "poss_mod_c11"] = {m_common.apply_tone("l" .. w .. base, tone)}
data.forms[prefix .. "poss_mod_c14"] = {m_common.apply_tone("b" .. base, tone)}
data.forms[prefix .. "poss_mod_c15"] = {m_common.apply_tone("k" .. w .. base, tone)}
data.forms[prefix .. "poss_mod_c17"] = {m_common.apply_tone("k" .. w .. base, tone)}
data.forms[prefix .. "poss_subst_c1" ] = {m_common.apply_tone("ow" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c2" ] = {m_common.apply_tone("ab" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c3" ] = {m_common.apply_tone("ow" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c4" ] = {m_common.apply_tone("ey" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c5" ] = {m_common.apply_tone("el" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c6" ] = {m_common.apply_tone("aw" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c7" ] = {m_common.apply_tone("es" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c8" ] = {m_common.apply_tone("ez" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c9" ] = {m_common.apply_tone("ey" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c10"] = {m_common.apply_tone("ez" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c11"] = {m_common.apply_tone("ol" .. w .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c14"] = {m_common.apply_tone("ob" .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c15"] = {m_common.apply_tone("ok" .. w .. base, tone_subst)}
data.forms[prefix .. "poss_subst_c17"] = {m_common.apply_tone("ok" .. w .. base, tone_subst)}
end
end
local function forms(data, n, class, base, shortloc, loc)
-- Full form
data.forms[n .. "_full"] = {base}
-- Simple form
simple(data, base, n, class)
-- Locative
if class == "1" or class == "1a" or class == "2" or class == "2a" then
locative_ku(data, base, n)
elseif shortloc then
locative_e(data, base, n, class)
elseif loc then
data.forms[n .. "_loc"] = {loc}
else
local loc = locative_extend(base)
locative_e(data, loc, n, class)
end
-- Copulative
copulative(data, base, n, class)
-- Possessive forms
possessive(data, base, n, class == "1a")
end
function export.noun(frame)
local params = {
[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "L" or nil},
[2] = {required = true, default = "1"},
[3] = {default = mw.title.getCurrentTitle().nsText == "Template" and "2" or nil},
[4] = {default = mw.title.getCurrentTitle().nsText == "Template" and "abantu" or nil},
["shortloc"] = {type = "boolean"},
["loc_sg"] = {default = false},
["loc_pl"] = {default = false}
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local data = {forms = {}, info = "", categories = {lang:getCanonicalName() .. " class " .. args[2] .. " nouns"}}
if args[1] then
table.insert(data.categories, lang:getCanonicalName() .. " nouns with tone " .. args[1])
else
table.insert(data.categories, "Requests for tone in " .. lang:getCanonicalName() .. " noun entries")
end
data.info = "class " .. args[2] .. (args[3] and "/" .. args[3] or "")
if args[2] == "2" or args[2] == "2a" or args[2] == "4" or args[2] == "6" or args[2] == "8" or args[2] == "10" then
if args[3] or args[4] then
error("Nouns of plural classes cannot have plural forms.")
end
forms(data, "pl", args[2], mw.title.getCurrentTitle().subpageText, args["shortloc"], args["loc_pl"])
table.insert(data.categories, lang:getCanonicalName() .. " pluralia tantum")
else
forms(data, "sg", args[2], mw.title.getCurrentTitle().subpageText, args["shortloc"], args["loc_sg"])
-- Plural
if args[3] then
forms(data, "pl", args[3], args[4], args["shortloc"], args["loc_pl"])
else
table.insert(data.categories, lang:getCanonicalName() .. " singularia tantum")
end
end
if args["shortloc"] then
data.info = data.info .. ", short locative"
table.insert(data.categories, lang:getCanonicalName() .. " nouns with short locative")
end
return make_table(data) .. m_utilities.format_categories(data.categories, lang, (makeSortKey(mw.title.getCurrentTitle().subpageText, args[2])))
end
function export.pron(frame)
local params = {
[1] = {},
[2] = {},
[3] = {},
[4] = {},
[5] = {},
["head"] = {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local data = {forms = {}, info = "", categories = {}}
data.pron = true
if args[1] then
table.insert(data.categories, lang:getCanonicalName() .. " pronouns with tone " .. args[1])
else
table.insert(data.categories, "Requests for tone in " .. lang:getCanonicalName() .. " pronoun entries")
end
local base = m_common.apply_tone(args["head"] or mw.title.getCurrentTitle().subpageText, args[1])
local stem = args[2] and m_common.apply_tone(args[2], args[3]) or base
local pstem = args[4] and m_common.apply_tone(args[4], args[5]) or stem
data.info = "stem " .. m_links.full_link({lang = lang, alt = "-" .. stem}, "term")
if args[4] then
data.info = data.info .. ", poss. stem " .. m_links.full_link({lang = lang, alt = "-" .. pstem}, "term")
end
data.forms["full"] = {base}
if args[3] then
locative_ku(data, stem, nil, "H" .. args[3])
copulative(data, stem, nil, nil, "H" .. args[3])
else
locative_ku(data, stem)
copulative(data, stem)
end
if stem == "mi" or stem == "we" then
possessive(data, pstem, nil, nil, "HL")
elseif pstem == "ithu" or stem == "inu" then
possessive(data, pstem, nil, nil, "FL")
else
if args[5] then
possessive(data, pstem, nil, nil, "FL")
else
possessive(data, pstem)
end
end
return make_table(data) .. m_utilities.format_categories(data.categories, lang)
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 form = data.forms[param]
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, term = subform}))
end
return table.concat(ret, ", ")
end
local names = {
["full"] = "full form",
["simp"] = "simple form",
["loc"] = "locative",
["cop"] = "copulative",
["sg"] = "singular",
["pl"] = "plural",
["mod"] = "modifier",
["subst"] = "substantive",
["c1"] = "class 1",
["c2"] = "class 2",
["c3"] = "class 3",
["c4"] = "class 4",
["c5"] = "class 5",
["c6"] = "class 6",
["c7"] = "class 7",
["c8"] = "class 8",
["c9"] = "class 9",
["c10"] = "class 10",
["c11"] = "class 11",
["c14"] = "class 14",
["c15"] = "class 15",
["c17"] = "class 17",
}
local columns = {"mod", "subst"}
local numbers = {"sg", "pl"}
local cases = {"full", "simp", "loc", "cop"}
local classes = {"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c14", "c15", "c17"}
if data.pron then
numbers = {""}
cases = {"full", "loc", "cop"}
end
local wikicode = {}
table.insert(wikicode, "{| class=\"wikitable inflection-table vsSwitcher\" data-toggle-category=\"inflection\" style=\"border-style: double; border-width: 3px; margin: 0;\"")
table.insert(wikicode, "|-")
table.insert(wikicode, "! class=\"vsToggleElement\" style=\"background: #CCC; text-align: left;\" colspan=\"" .. tostring(#numbers * #columns + 1) .. "\" | {{{info}}}")
if not data.pron then
table.insert(wikicode, "|- class=\"vsShow\"")
table.insert(wikicode, "|")
for _, number in ipairs(numbers) do
table.insert(wikicode, "! " .. mw.getContentLanguage():ucfirst(names[number]))
end
end
for _, case in ipairs({"full", "loc"}) do
table.insert(wikicode, "|- class=\"vsShow\"")
table.insert(wikicode, "! style=\"min-width: 8em;\" | " .. mw.getContentLanguage():ucfirst(names[case]))
if data.pron then
table.insert(wikicode, "| style=\"min-width: 10em;\" | {{{" .. case .. "}}}")
else
for _, number in ipairs(numbers) do
table.insert(wikicode, "| style=\"min-width: 10em;\" | {{{" .. number .. "_" .. case .. "}}}")
end
end
end
if not data.pron then
table.insert(wikicode, "|- class=\"vsHide\"")
table.insert(wikicode, "|")
for _, number in ipairs(numbers) do
table.insert(wikicode, "! colspan=\"" .. tostring(#columns) .. "\" | " .. mw.getContentLanguage():ucfirst(names[number]))
end
end
for _, case in ipairs(cases) do
table.insert(wikicode, "|- class=\"vsHide\"")
table.insert(wikicode, "! style=\"min-width: 8em;\" | " .. mw.getContentLanguage():ucfirst(names[case]))
if data.pron then
table.insert(wikicode, "| colspan=\"" .. tostring(#columns) .. "\" | {{{" .. case .. "}}}")
else
for _, number in ipairs(numbers) do
table.insert(wikicode, "| colspan=\"" .. tostring(#columns) .. "\" | {{{" .. number .. "_" .. case .. "}}}")
end
end
end
table.insert(wikicode, "|- class=\"vsHide\"")
table.insert(wikicode, "! colspan=\"" .. tostring(#numbers * #columns + 1) .. "\" | Possessive forms")
if not data.pron then
table.insert(wikicode, "|- class=\"vsHide\"")
table.insert(wikicode, "|")
for _, number in ipairs(numbers) do
table.insert(wikicode, "! colspan=\"" .. tostring(#columns) .. "\" | " .. mw.getContentLanguage():ucfirst(names[number]))
end
end
table.insert(wikicode, "|- class=\"vsHide\"")
table.insert(wikicode, "|")
for _, number in ipairs(numbers) do
for _, column in ipairs(columns) do
table.insert(wikicode, "! style=\"min-width: 8em;\" | " .. mw.getContentLanguage():ucfirst(names[column]))
end
end
for _, class in ipairs(classes) do
table.insert(wikicode, "|- class=\"vsHide\"")
table.insert(wikicode, "! " .. mw.getContentLanguage():ucfirst(names[class]))
for _, number in ipairs(numbers) do
for _, column in ipairs(columns) do
table.insert(wikicode, "| {{{" .. (data.pron and "" or number .. "_") .. "poss_" .. column .. "_" .. class .. "}}}")
end
end
end
table.insert(wikicode, "|}")
wikicode = table.concat(wikicode, "\n")
return mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)
end
return export