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 ~= "แม่แบบ" 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)
base = lang:makeEntryName(base)
if prefix then
prefix = prefix .. "_"
else
prefix = ""
end
if mw.ustring.find(base, "^[au]") then
data.forms[prefix .. "loc"] = {"ku" .. mw.ustring.gsub(base, "^[au]", "")}
elseif mw.ustring.find(base, "^[" .. m_common.vowel .. "]") then
data.forms[prefix .. "loc"] = {"k" .. base}
else
data.forms[prefix .. "loc"] = {"ku" .. base}
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)
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"] = {"w" .. base}
elseif mw.ustring.find(base, "^[aou]") then
data.forms[prefix .. "cop"] = {"ng" .. base}
elseif mw.ustring.find(base, "^i") then
data.forms[prefix .. "cop"] = {"y" .. base}
else
data.forms[prefix .. "cop"] = {"yi" .. base}
end
end
local function possessive(data, base, prefix, ka)
base = lang:makeEntryName(base)
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
if mw.ustring.find(base, "^[aiou]") then
base = mw.ustring.gsub(base, "^[iu]", {["i"] = "e", ["u"] = "o"})
else
base = "a" .. base
end
data.forms[prefix .. "poss_mod_c1" ] = { "w" .. base}
data.forms[prefix .. "poss_mod_c2" ] = { "b" .. base}
data.forms[prefix .. "poss_mod_c3" ] = { "w" .. base}
data.forms[prefix .. "poss_mod_c4" ] = { "y" .. base}
data.forms[prefix .. "poss_mod_c5" ] = { "l" .. base}
data.forms[prefix .. "poss_mod_c6" ] = { base}
data.forms[prefix .. "poss_mod_c7" ] = { "s" .. base}
data.forms[prefix .. "poss_mod_c8" ] = { "z" .. base}
data.forms[prefix .. "poss_mod_c9" ] = { "y" .. base}
data.forms[prefix .. "poss_mod_c10"] = { "z" .. base}
data.forms[prefix .. "poss_mod_c11"] = {"lw" .. base}
data.forms[prefix .. "poss_mod_c14"] = { "b" .. base}
data.forms[prefix .. "poss_mod_c15"] = {"kw" .. base}
data.forms[prefix .. "poss_mod_c17"] = {"kw" .. base}
data.forms[prefix .. "poss_subst_c1" ] = { "ow" .. base}
data.forms[prefix .. "poss_subst_c2" ] = { "ab" .. base}
data.forms[prefix .. "poss_subst_c3" ] = { "ow" .. base}
data.forms[prefix .. "poss_subst_c4" ] = { "ey" .. base}
data.forms[prefix .. "poss_subst_c5" ] = { "el" .. base}
data.forms[prefix .. "poss_subst_c6" ] = { "aw" .. base}
data.forms[prefix .. "poss_subst_c7" ] = { "es" .. base}
data.forms[prefix .. "poss_subst_c8" ] = { "ez" .. base}
data.forms[prefix .. "poss_subst_c9" ] = { "ey" .. base}
data.forms[prefix .. "poss_subst_c10"] = { "ez" .. base}
data.forms[prefix .. "poss_subst_c11"] = {"olw" .. base}
data.forms[prefix .. "poss_subst_c14"] = { "ob" .. base}
data.forms[prefix .. "poss_subst_c15"] = {"okw" .. base}
data.forms[prefix .. "poss_subst_c17"] = {"okw" .. base}
end
end
local function forms(data, n, class, base, shortloc)
-- 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)
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 == "แม่แบบ" and "L" or nil},
[2] = {required = true, default = "1"},
[3] = {default = mw.title.getCurrentTitle().nsText == "แม่แบบ" and "2" or nil},
[4] = {default = mw.title.getCurrentTitle().nsText == "แม่แบบ" and "abantu" or nil},
["shortloc"] = {type = "boolean"},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local data = {forms = {}, info = "", categories = {"คำนามกลุ่ม " .. args[2] .. " " .. lang:getCategoryName()}}
if args[1] then
table.insert(data.categories, "คำนาม" .. lang:getCategoryName() .. "ที่มีวรรณยุกต์ " .. args[1])
else
table.insert(data.categories, "คำนาม" .. lang:getCategoryName() .. "ที่ขาดวรรณยุกต์")
end
split_prefix(mw.title.getCurrentTitle().subpageText, args[2], args[1])
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"])
table.insert(data.categories, "คำนามพหูพจน์เท่านั้น" .. lang:getCategoryName())
else
forms(data, "sg", args[2], mw.title.getCurrentTitle().subpageText, args["shortloc"])
-- Plural
if args[3] then
split_prefix(args[4], args[3], args[1])
forms(data, "pl", args[3], args[4], args["shortloc"])
else
table.insert(data.categories, "คำนามเอกพจน์เท่านั้น" .. lang:getCategoryName())
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:getCategoryName() .. "ที่มีวรรณยุกต์ " .. args[1])
else
table.insert(data.categories, "คำสรรพนาม" .. lang:getCategoryName() .. "ที่ขาดวรรณยุกต์")
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}
locative_ku(data, stem)
copulative(data, stem, nil)
possessive(data, pstem, nil)
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"] = "รูปเต็ม",
["simp"] = "รูปย่อ",
["loc"] = "locative",
["cop"] = "copulative",
["sg"] = "เอกพจน์",
["pl"] = "พหูพจน์",
["mod"] = "modifier",
["subst"] = "substantive",
["c1"] = "กลุ่ม 1",
["c2"] = "กลุ่ม 2",
["c3"] = "กลุ่ม 3",
["c4"] = "กลุ่ม 4",
["c5"] = "กลุ่ม 5",
["c6"] = "กลุ่ม 6",
["c7"] = "กลุ่ม 7",
["c8"] = "กลุ่ม 8",
["c9"] = "กลุ่ม 9",
["c10"] = "กลุ่ม 10",
["c11"] = "กลุ่ม 11",
["c14"] = "กลุ่ม 14",
["c15"] = "กลุ่ม 15",
["c17"] = "กลุ่ม 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 vsToggleCategory-inflection\" style=\"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