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 = {
= {
"^(**)(.+)$",
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)([" .. m_common.vowel .. ".+)$",
},
= {
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(*)(.+)$",
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(**)(.+)$",
},
= {
"^(*)(.+)$",
--"^(**)(.+)$",
--"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
"^(*?)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
},
= {
"^(**)(.+)$",
"^(*)(.+)$",
},
}
local function split_prefix(word, class, tone)
if not prefixes then
error("Invalid class \"" .. class .. "\".")
end
local prefix, stem
word = mw.ustring.toNFD(word)
for _, pattern in ipairs(prefixes) 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 = {"b" .. base}
elseif class == "5" then
data.forms = {(mw.ustring.gsub(base, "^i", "li"))}
elseif class == "11" then
data.forms = {(mw.ustring.gsub(base, "^u", "lu"))}
else
data.forms = {(mw.ustring.gsub(base, "^%-?", ""))}
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, "^") then
data.forms = {m_common.apply_tone("ku" .. mw.ustring.gsub(base, "^", ""), tone)}
elseif mw.ustring.find(base, "^") then
data.forms = {m_common.apply_tone("k" .. base)}
elseif base == "mi" or base == "thi" or base == "ni" then
data.forms = {m_common.apply_tone("ki" .. base, tone)}
else
data.forms = {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, "^", "e")
end
data.forms = {base}
end
local function locative_extend(base)
base = (lang:makeEntryName(base))
base = mw.ustring.gsub(base, "$", { = "e", = "we", = "wi"}) .. "ni"
base = mw.ustring.gsub(base, "mbw(ni)$", "nj%1")
base = mw.ustring.gsub(base, "mpw(ni)$", "ntsh%1")
base = mw.ustring.gsub(base, "bhw(ni)$", "j%1")
base = mw.ustring.gsub(base, "w(ni)$", "tsh%1")
base = mw.ustring.gsub(base, "phw(ni)$", "sh%1")
base = mw.ustring.gsub(base, "mw(ni)$", "ny%1")
base = mw.ustring.gsub(base, "()w(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 = {m_common.apply_tone("w" .. base)}
elseif mw.ustring.find(base, "^") then
data.forms = {m_common.apply_tone("ng" .. base)}
elseif mw.ustring.find(base, "^i") then
data.forms = {m_common.apply_tone("y" .. base)}
elseif base == "we" or base == "ye" then
data.forms = {m_common.apply_tone("ngu" .. base, tone)}
else
data.forms = {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 = { "ka" .. base}
data.forms = {"baka" .. base}
data.forms = { "ka" .. base}
data.forms = { "ka" .. base}
data.forms = {"lika" .. base}
data.forms = { "ka" .. base}
data.forms = {"sika" .. base}
data.forms = {"zika" .. base}
data.forms = { "ka" .. base}
data.forms = {"zika" .. base}
data.forms = {"luka" .. base}
data.forms = {"buka" .. base}
data.forms = {"kuka" .. base}
data.forms = {"kuka" .. base}
data.forms = { "oka" .. base}
data.forms = {"abaka" .. base}
data.forms = { "oka" .. base}
data.forms = { "eka" .. base}
data.forms = {"elika" .. base}
data.forms = { "aka" .. base}
data.forms = {"esika" .. base}
data.forms = {"ezika" .. base}
data.forms = { "eka" .. base}
data.forms = {"ezika" .. base}
data.forms = {"oluka" .. base}
data.forms = {"obuka" .. base}
data.forms = {"okuka" .. base}
data.forms = {"okuka" .. base}
else
local w
if mw.ustring.find(base, "^") then
base = mw.ustring.gsub(base, "^u", "o")
w = ""
elseif mw.ustring.find(base, "^") then
base = mw.ustring.gsub(base, "^i", "e")
w = "w"
else
base = "a" .. base
w = "w"
end
data.forms = {m_common.apply_tone("w" .. base, tone)}
data.forms = {m_common.apply_tone("b" .. base, tone)}
data.forms = {m_common.apply_tone("w" .. base, tone)}
data.forms = {m_common.apply_tone("y" .. base, tone)}
data.forms = {m_common.apply_tone("l" .. base, tone)}
data.forms = {m_common.apply_tone(base, tone)}
data.forms = {m_common.apply_tone("s" .. base, tone)}
data.forms = {m_common.apply_tone("z" .. base, tone)}
data.forms = {m_common.apply_tone("y" .. base, tone)}
data.forms = {m_common.apply_tone("z" .. base, tone)}
data.forms = {m_common.apply_tone("l" .. w .. base, tone)}
data.forms = {m_common.apply_tone("b" .. base, tone)}
data.forms = {m_common.apply_tone("k" .. w .. base, tone)}
data.forms = {m_common.apply_tone("k" .. w .. base, tone)}
data.forms = {m_common.apply_tone("ow" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ab" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ow" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ey" .. base, tone_subst)}
data.forms = {m_common.apply_tone("el" .. base, tone_subst)}
data.forms = {m_common.apply_tone("aw" .. base, tone_subst)}
data.forms = {m_common.apply_tone("es" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ez" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ey" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ez" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ol" .. w .. base, tone_subst)}
data.forms = {m_common.apply_tone("ob" .. base, tone_subst)}
data.forms = {m_common.apply_tone("ok" .. w .. base, tone_subst)}
data.forms = {m_common.apply_tone("ok" .. w .. base, tone_subst)}
end
end
local function forms(data, n, class, base, shortloc, loc)
-- Full form
data.forms = {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 = {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 = {
= {default = mw.title.getCurrentTitle().nsText == "Template" and "L" or nil},
= {required = true, default = "1"},
= {default = mw.title.getCurrentTitle().nsText == "Template" and "2" or nil},
= {default = mw.title.getCurrentTitle().nsText == "Template" and "abantu" or nil},
= {type = "boolean"},
= true,
= true
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local data = {forms = {}, info = "", categories = {lang:getCanonicalName() .. " class " .. args .. " nouns"}}
if args then
table.insert(data.categories, lang:getCanonicalName() .. " nouns with tone " .. args)
else
table.insert(data.categories, "Requests for tone in " .. lang:getCanonicalName() .. " noun entries")
end
data.info = "class " .. args .. (args and "/" .. args or "")
if args == "2" or args == "2a" or args == "4" or args == "6" or args == "8" or args == "10" then
if args or args then
error("Nouns of plural classes cannot have plural forms.")
end
forms(data, "pl", args, mw.title.getCurrentTitle().subpageText, args, args or false)
table.insert(data.categories, lang:getCanonicalName() .. " pluralia tantum")
else
forms(data, "sg", args, mw.title.getCurrentTitle().subpageText, args, args or false)
-- Plural
if args then
forms(data, "pl", args, args, args, args or false)
else
table.insert(data.categories, lang:getCanonicalName() .. " singularia tantum")
end
end
if args 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)))
end
function export.pron(frame)
local params = {
= {},
= {},
= {},
= {},
= {},
= {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local data = {forms = {}, info = "", categories = {}}
data.pron = true
if args then
table.insert(data.categories, lang:getCanonicalName() .. " pronouns with tone " .. args)
else
table.insert(data.categories, "Requests for tone in " .. lang:getCanonicalName() .. " pronoun entries")
end
local base = m_common.apply_tone(args or mw.title.getCurrentTitle().subpageText, args)
local stem = args and m_common.apply_tone(args, args) or base
local pstem = args and m_common.apply_tone(args, args) or stem
data.info = "stem " .. m_links.full_link({lang = lang, alt = "-" .. stem}, "term")
if args then
data.info = data.info .. ", poss. stem " .. m_links.full_link({lang = lang, alt = "-" .. pstem}, "term")
end
data.forms = {base}
if args then
locative_ku(data, stem, nil, "H" .. args)
copulative(data, stem, nil, nil, "H" .. args)
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 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
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 form",
= "simple form",
= "locative",
= "copulative",
= "singular",
= "plural",
= "modifier",
= "substantive",
= "class 1",
= "class 2",
= "class 3",
= "class 4",
= "class 5",
= "class 6",
= "class 7",
= "class 8",
= "class 9",
= "class 10",
= "class 11",
= "class 14",
= "class 15",
= "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, mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = "{{{info}}} (locative ''" .. (data.pron and '{{{loc}}}' or '{{{sg_loc}}}') .. "'')",
palette = 'green',
tall = 'yes',
}
})
if not data.pron then
table.insert(wikicode, "|-")
table.insert(wikicode, "!")
for _, number in ipairs(numbers) do
table.insert(wikicode, "! colspan=\"" .. tostring(#columns) .. "\" | " .. names)
end
end
for _, case in ipairs(cases) do
table.insert(wikicode, "|-")
table.insert(wikicode, "! " .. names)
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, "|-")
table.insert(wikicode, "! class=\"outer\" colspan=\"" .. tostring(#numbers * #columns + 1) .. "\" | Possessive forms")
if not data.pron then
table.insert(wikicode, "|-")
table.insert(wikicode, "!")
for _, number in ipairs(numbers) do
table.insert(wikicode, "! colspan=\"" .. tostring(#columns) .. "\" | " .. names)
end
end
table.insert(wikicode, "|-")
table.insert(wikicode, "!")
for _, number in ipairs(numbers) do
for _, column in ipairs(columns) do
table.insert(wikicode, "! class=\"secondary\" | " .. names)
end
end
for _, class in ipairs(classes) do
table.insert(wikicode, "|-")
table.insert(wikicode, "! " .. names)
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, mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' })
wikicode = table.concat(wikicode, "\n")
return mw.ustring.gsub(wikicode, "{{{(+)}}}", repl)
end
return export