Module:pi-decl/noun

local export = {} -- require("Module:log globals") -- Examine Lua logs at end of preview for results. local links = require("Module:links") local lang = require("Module:languages").getByCode("pi") local m_parameters = require("Module:parameters") local m_str_utils = require("Module:string utilities") local m_translit local to_script

local find = m_str_utils.find local gsub = m_str_utils.gsub local match = m_str_utils.match local sub = m_str_utils.sub local u = m_str_utils.char -- For readability. local load = mw.loadData local ti = table.insert local currentScript local scriptCode

local genders = { ["m"] = "masculine", ["f"] = "feminine", ["n"] = "neuter", } local rows = { "Nominative (first)", "Accusative (second)", "Instrumental (third)", "Dative (fourth)", "Ablative (fifth)", "Genitive (sixth)", "Locative (seventh)", "Vocative (calling)", }

local endings = { ["one"] = { -- key(Ln) Thai Deva      Beng       Mymr       Lana     Laoo       Khmr --          Sinh     Brah       Cakm ["a"] = {}, ["ā"] = { "า", "ा", "आ", "া", "আ", "ါ", "ာ", " ႃ", "ᩣ", "ᩤ", "າ",  "ា", u(0x17A4), "ා", "ආ", "𑀸", "𑀆", "𑄂" }, ["i"] = { "ิ",  "ि", "इ",  "ি", "ই", "ိ", "ဣ",  "ᩥ", "ᩍ", "ິ",        "ិ", "ឥ", "ි", "ඉ", "𑀺", "𑀇", "𑄨" }, ["ī"] = { "ี",  "ी", "ई",  "ী", "ঈ", "ီ", "ဳ", "ဤ", "ᩦ", "ᩎ", "ີ",   "ី", "ឦ", "ී", "ඊ", "𑀻", "𑀈", "𑄩" }, ["u"] = { "ุ",  "ु", "उ",  "ু", "উ", "ု", "ဥ",  "ᩩ", "ᩏ",  "ຸ",        "ុ", "ឧ", "ු", "උ", "𑀼", "𑀉", "𑄪" }, ["ū"] = { "ู",  "ू", "ऊ",  "ূ", "ঊ", "ူ", "ဦ",  "ᩪ", "ᩐ",  "ູ",        "ូ", "ឨ", "ឩ", "ූ", "ඌ", "𑀽", "𑀊", "𑄫" }, ["ah"] = { "ะ",                                          "ະ"}, },	["two"] = { -- key(Ln) Thai     Deva    Beng       Mymr       Lana          Laoo        Khmr --        Sinh     Brah   Cakm ["ar"] = { "รฺ", "ัร", "र्",     "র্",      "ရ်",       "ᩁ᩺", "ᩁ᩼", "ຣ໌", "ຣ຺", "ັຣ",   "រ៑", "ර්",    "𑀭𑁆",  "𑄢𑄴"}, ["as"] = { "สฺ", "ัส", "स्",   "স্",      "သ်",      "ᩈ᩺", "ᩈ᩼",  "ສ໌", "ສ຺", "ັສ",  "ស៑", "ස්",   "𑀲𑁆",  "𑄥𑄴"  }, ["an"] = { "นฺ", "ัน", "न्",   "ন্",      "န်",       "ᨶ᩺", "ᨶ᩼",  "ນ໌", "ນ຺", "ັນ",   "ន៑", "න්",    "𑀦𑁆", "𑄚𑄴"}, ent   = { "นต",										  "ນຕ"}, ["in"] = { "ิน",                                          "ິນ"}, },	three = { -- key(Ln) Thai Deva      Beng       Mymr       Lana     Laoo       Khmr --        Sinh     Brah  Cakm ant  =  { "ันต",                                         "ັນຕ"}, ent  =  {}, ont  =  {}, ["in"] = { "ินฺ", "िन्",      "িন্",     "ိန်",        "ᩥᨶ᩺",     "ິນ຺",		"ិន៑", "ින්",   "𑀺𑀦𑁆", "𑄨𑄚𑄴" }, },	four = { -- key(Ln) Thai Deva      Beng       Mymr       Lana     Laoo       Khmr --	      Sinh        Brah   Cakm ant  =  { "นฺตฺ", "न्त्",     "ন্ত্",      "န္တ်",       "ᨶ᩠ᨲ᩺", "ᨶ᩠ᨲ᩼", "ນ຺ຕ໌", "ນ຺ຕ຺", "ន្ត៑", "න්ත්",    "𑀦𑁆𑀢𑁆",  "𑄚𑄴𑄖𑄴"   }, vant =  { "วันต",                                         "ວັນຕ" }, mant =  { "มันต",                                         "ມັນຕ" }, },	five = { -- 'ent' and 'ont' are discontiguous for Thai and Lao. Assume NFC (as above). -- key(Ln) Thai Deva      Beng       Mymr       Lana        Laoo          Khmr --        Sinh        Brah  Cakm antT =  {                                                                       "න‍්ත්"          }, vant =  { "วนฺตฺ", "वन्त्",  "ৱন্ত্","ৰন্ত্",  "ွန္တ်", "ဝန္တ်", "ᩅᨶ᩠ᨲ᩺", "ᩅᨶ᩠ᨲ᩼", "ວນ຺ຕ຺", "ວນ຺ຕ໌",  "វន្ត៑", "වන්ත්",  "𑀯𑀦𑁆𑀢𑁆", "𑅇𑄚𑄴𑄖𑄴"      }, mant =  { "มนฺตฺ", "मन्त्",   "মন্ত্",     "မန္တ်",       "ᨾᨶ᩠ᨲ᩺", "ᨾᨶ᩠ᨲ᩼", "ມນ຺ຕ຺", "ມນ຺ຕ໌", "មន្ត៑", "ᩜᨶ᩠ᨲ᩺", "ᩜᨶ᩠ᨲ᩼", "මන්ත්",  "𑀫𑀦𑁆𑀢𑁆", "𑄟𑄚𑄴𑄖𑄴"}, ent  =  {         "ेन्त्",   "েন্ত্",    "ေန္တ်",      "ᩮᨶ᩠ᨲ᩺", "ᩮᨶ᩠ᨲ᩼",             "េន្ត៑", "एन्त्",  "এন্ত্",     "ဧန္တ်",       "ᩑᨶ᩠ᨲ᩺",  "ᩑᨶ᩠ᨲ᩼",              "ឯន្ត៑", "ෙන්ත්", "𑁂𑀦𑁆𑀢𑁆",   "𑄬𑄚𑄴𑄖𑄴"  , "එන්ත්",  "𑀏𑀦𑁆𑀢𑁆"     }, ont  =  {        "ोन्त्",   "োন্ত্",   "ာန္တ်", "ါန္တ်", "ᩣᨶ᩠ᨲ᩺", "ᩣᨶ᩠ᨲ᩼",           "ោន្ត៑", "ᩤᨶ᩠ᨲ᩺", "ᩤᨶ᩠ᨲ᩼", "ओन्त्", "ওন্ত্",     "ဩန္တ်",      "ᩰᨶ᩠ᨲ᩺", "ᩰᨶ᩠ᨲ᩼",             "ឲន្ត៑", "ᩒᨶ᩠ᨲ᩺", "ᩒᨶ᩠ᨲ᩼", "ොන්ත්",  "𑁄𑀦𑁆𑀢𑁆", "𑄮𑄚𑄴𑄖𑄴", "ඔන්ත්",  "𑀑𑀦𑁆𑀢𑁆"}, },	six = { -- key(Ln) Thai Deva      Beng       Mymr       Lana        Laoo          Khmr --        Sinh     Brah vantT =  {"වන‍්ත්"        }, mantT =  {"මන‍්ත්"   }, entT  =  {"ෙන‍්ත්", "එන‍්ත්"    }, ontT  =  {"ොන‍්ත්", "ඔන‍්ත්"  }, }, }

function export.detectEnding(stem, options) -- Correct checking order is last 6, last 5, last 4, last 3, last 2, last 1, but we -- Can do slightly better by knowing the data. local oneLetter = sub(stem, -1) for key, arr in pairs(endings.one) do		if oneLetter == key then return key end for _, val in ipairs(arr) do			if oneLetter == val then return key end end end -- Check Latin script first local fourLetters = sub(stem, -4) if 'mant' == fourLetters or 'vant' == fourLetters then return fourLetters end local wordEnd = sub(stem, -6) for key, arr in pairs(endings.six) do --		if wordEnd == key then --			return key --		end for _, val in ipairs(arr) do			if wordEnd == val then return key end end end wordEnd = sub(stem, -5) for key, arr in pairs(endings.five) do --		if wordEnd == key then --			return key --		end for _, val in ipairs(arr) do			if wordEnd == val then return key end end end for key, arr in pairs(endings.four) do		if fourLetters == key then return key end for _, val in ipairs(arr) do			if fourLetters == val then -- Scripts with visually ordered preposed vowels have not been checked thoroughly if key == 'ant' and (oneLetter == u(0x0E3A) or oneLetter == u(0xECC) or				 oneLetter == u(0x0EBA)) then local pm6 = sub(stem, -6, -6) if match(pm6, '[เโເໂ]') then -- 1 char onset return 'ent' -- 'ent' for 'ont' matters not. elseif match(pm6, '['..u(0x0E3A)..u(0x0EBA)..']') and match(sub(stem, -8, -8), '[เโເໂ]') then -- 2 char onset return 'ent' -- 'ent' for 'ont' matters not. else return key end else return key end end end end local threeLetters = sub(stem, -3) for key, arr in pairs(endings.three) do		if threeLetters == key then return key end for _, val in ipairs(arr) do			if threeLetters == val then return key; end end end local impl = options and options.impl or 'yes' -- Fudge to pass old tests. wordEnd = sub(stem, -2) for key, arr in pairs(endings.two) do		if wordEnd == key then return key end for _, val in ipairs(arr) do			if wordEnd == val then if key == 'ent' then local pm3 = sub(stem, -3, -3) if match(pm3, '['..u(0x0e31)..u(0xeb1)..']') then -- Recognise below return 'ant' elseif match(sub(stem, -4, -3), '[เโເໂ][ก-ฮກ-ຮ]') then -- 1 char onset return 'ent' elseif match(sub(stem, -5, -3), '[เโເໂ][ก-ฮກ-ຮ][ก-ฮກ-ຮ]') then -- 2 char onset return 'ent' end elseif wordEnd == "ิน" or wordEnd == "ິນ" then if impl == 'yes' then return 'a'					elseif impl == 'both' then error("Does "..stem.." end in -in or -ina?") else return key end else return key end end end end

return "a" end

-- Selectively converts touching to conjoining. local sinh_flip = {["කⒿ‍්ව"]="ක්‍ව", ["තⒿ‍්ථ"]="ත්‍ථ", ["තⒿ‍්ව"]="ත්‍ව", ["නⒿ‍්ථ"]="න්‍ථ", ["නⒿ‍්ද"]="න්‍ද", ["නⒿ‍්ධ"]="න්‍ධ", ["නⒿ‍්ව"]="න්‍ව", } -- Argument option is optional. function export.joinSuffix(scriptCode, stem, suffixes, option)

if stem == nil then errmes = {} table.insert(errmes, 'joinSuffix('..scriptCode)		table.insert(errmes, tostring(stem))		table.insert(errmes, tostring(suffixes))		table.insert(errmes, tostring(option)..')') error(table.concat(errmes, ',')) end

local output = {} local term local aa = option and option.aa or "default" local join, term2

if scriptCode == 'Lana' or scriptCode == 'Mymr' or scriptCode == 'Sinh' then join = 'Ⓙ' else join = "" end

for _,suffix in ipairs(suffixes) do		if match(suffix, "^⌫⌫⌫⌫⌫") then --backspace term = sub(stem, 1, -6) .. join .. sub(suffix, 6, -1) elseif match(suffix, "^⌫⌫⌫⌫") then --backspace term = sub(stem, 1, -5) .. join .. sub(suffix, 5, -1) elseif match(suffix, "^⌫⌫⌫") then --backspace term = sub(stem, 1, -4) .. join .. sub(suffix, 4, -1) elseif match(suffix, "^⌫⌫") then --backspace term = sub(stem, 1, -3) .. join .. sub(suffix, 3, -1) elseif match(suffix, "^⌫") then --backspace term = sub(stem, 1, -2) .. join .. sub(suffix, 2, -1) else term = stem .. join .. suffix end

--note: Sinh conjuncts are already ready. if scriptCode == "Thai" then term = gsub(term, "(.)↶([เโ])", "%2%1") --swap elseif scriptCode == "Mymr" then --			term = gsub(term, "င္", "င်္") -- Pali doesn't have -Vr mid-word like Sanskrit, so no need to include repha. term = gsub(term, "(င်္)([ခဂငဒပဝ])(ေ?)Ⓙာ", "%1%2%3ါ") -- redundant! --			term = gsub(term, "္[ယရ]", { ["္ယ"] = "ျ", ["္ရ"] = "ြ" }) --these not need tall aa			term = gsub(term, "Ⓙ္[ယရ]", { ["Ⓙ္ယ"] = "ျ", ["Ⓙ္ရ"] = "ြ" }) --these not need tall aa			term = gsub(term, "^([ခဂငဒပဝ])Ⓙ(ေ?)ာ", "%1%2ါ") term = gsub(term, "([^္])([ခဂငဒပဝ])Ⓙ(ေ?)ာ", "%1%2%3ါ") term = gsub(term, "([^္])Ⓙ([ခဂငဒပဝ])(ေ?)ာ", "%1%2%3ါ") term = gsub(term, "([ခဂငဒပဝ])(္[က-အဿ])Ⓙ(ေ?)ာ", "%1%2%3ါ") term = gsub(term, "([ခဂငဒပဝ])Ⓙ(္[က-အဿ])(ေ?)ာ", "%1%2%3ါ") --			term = gsub(term, "္[ဝဟ]", { ["္ဝ"] = "ွ", ["္ဟ"] = "ှ" }) --			term = gsub(term, "ဉ္ဉ", "ည") --			term = gsub(term, "သ္သ", "ဿ") term = gsub(term, 'Ⓙ', '') elseif scriptCode == "Lana" then if aa == "both" then term2 = gsub(term, 'Ⓙ', '') end if aa == "tall" or aa == "both" then term = gsub(term, "^([ᨣᨴᨵᨷᩅ])Ⓙ(ᩮ?)ᩣ", "%1%2ᩤ") term = gsub(term, "([^᩠])([ᨣᨴᨵᨷᩅ])Ⓙ(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "([^᩠])Ⓙ([ᨣᨴᨵᨷᩅ])(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "([ᨣᨴᨵᨷᩅ])(᩠[ᨠ-ᩌᩔ])Ⓙ(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "([ᨣᨴᨵᨷᩅ])Ⓙ(᩠[ᨠ-ᩌᩔ])(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "(ᨻᩛ)Ⓙ(ᩮ?)ᩣ", "%1%2ᩤ") term = gsub(term, 'Ⓙ', '') if aa == "tall" then term2 = term end elseif aa == "round" then term = gsub(term, 'Ⓙ', '') term2 = term elseif aa == "default" then --				term = gsub(term, "ᨦ᩠", "ᩘ") term = gsub(term, "^([ᨣᨴᨵᨷᩅ])Ⓙ(ᩮ?)ᩣ", "%1%2ᩤ") term = gsub(term, "([^᩠])([ᨣᨴᨵᨷᩅ])Ⓙ(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "([^᩠])Ⓙ([ᨣᨴᨵᨷᩅ])(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "([ᨣᨴᨵᨷᩅ])(᩠[ᨠ-ᩌᩔ])Ⓙ(ᩮ?)ᩣ", "%1%2%3ᩤ") term = gsub(term, "([ᨣᨴᨵᨷᩅ])Ⓙ(᩠[ᨠ-ᩌᩔ])(ᩮ?)ᩣ", "%1%2%3ᩤ") --				term = gsub(term, "᩠[ᩁᩃ]", { ["᩠ᩁ"] = "ᩕ", ["᩠ᩃ"] = "ᩖ" }) --				term = gsub(term, "([ᨭ-ᨱ])᩠ᨮ", "%1ᩛ") --				term = gsub(term, "([ᨷ-ᨾ])᩠ᨻ", "%1ᩛ") --				term = gsub(term, "ᩈ᩠ᩈ", "ᩔ") term = gsub(term, 'Ⓙ', '') term2 = term else error('Parameter aa has undefined value "'..aa..'".') end if term ~= term2 then table.insert(output, term2) end elseif scriptCode == "Beng" then term = gsub(term, "ৰ্", "ৰ"..u(0x200d).."্") -- ৰ্(v-) needs ZWJ to display correctly elseif scriptCode == "Laoo" then term = gsub(term, "(.຺?)↶([ເໂ])", "%2%1") elseif scriptCode == "Sinh" then -- Assume cluster formation appends the joiner. term = gsub(term, "[කතන]Ⓙ..[ථදධව]", sinh_flip) term = gsub(term, 'Ⓙ', '') end table.insert(output, term) end

return output

end

function export.joinSuffixes(scriptCode, stem, pattern, option) local forms = {} for i,_ in ipairs(rows) do		forms[2*i-1] = export.joinSuffix(scriptCode, stem, pattern[2 * i - 1],										option) forms[2*i]  = export.joinSuffix(scriptCode, stem, pattern[2 * i],										option) end return forms end

function export.orJoin(script, list, options) -- options is optional! local output = {}; local scriptCode = script:getCode local showtr = options and options.showtr or 'plain' local sep = '' if 'Latn' == scriptCode then showtr = 'none' end for _,term in ipairs(list) do local item = {sc = script, lang = lang, term = term} -- links.full_link is at liberty to trash this table. ti(output, sep) sep = " or " if showtr == 'none' then item.tr = '-' else if options and options.subst then -- Legal stuff: -- The contents of this block were lifted from English Wiktionary Module:usex lines 97 to 101 -- of 3 July 2021, which see for attribution, and then localised. local substs = mw.text.split(options.subst, ",") for _, subpair in ipairs(substs) do					local subsplit = mw.text.split(subpair, find(subpair, "//") and "//" or "/") term = gsub(term, subsplit[1], subsplit[2]) end end local aslat = nil if (scriptCode == 'Thai' and options and options.impl == 'no' or				scriptCode == 'Laoo') then m_translit = m_translit or require("Module:pi-translit") aslat = m_translit.trwo(term, 'pi', scriptCode, options) elseif term ~= item.term then -- Must complete transliteration aslat = (lang:transliterate(term, script)) end if showtr == 'plain' then item.tr = aslat elseif showtr == 'link' then aslat = aslat or (lang:transliterate(term, script)) item.tr = links.full_link({term = aslat, lang = lang}) else item.tr = '-' error('Bad value for option showtr.') end end item.no_check_redundant_translit = item.tr and item.tr ~= '-' ti(output, links.full_link(item)) end

return table.concat(output) end

-- convert Latin script inflections to another script -- C2 is second character of pseudostem. Ignored if NIL. local function convert_one_set(stem, nstrip, suffixes, sc, impl, c2) local form, pre local strip = string.rep("⌫", nstrip) local option = {impl = impl} local xlitend = {} form = export.joinSuffix('Latn', stem, suffixes) for ia, va in pairs(form) do		local altform = sub(to_script(va..'#', sc, option), 1, -2) -- Special handling is needed for a preposed vowel. pre = match(altform, "^[เโເໂ]") if pre then xlitend[ia] = strip .. "↶" .. pre .. sub(altform, 3) -- Quick cheat for Myanmar script variants. elseif c2 and c2 == sub(altform,2,2) then xlitend[ia] = sub(strip, 2) .. sub(altform, 3) -- Back to the normal case. else xlitend[ia] = strip .. sub(altform, 2) end end return xlitend end local convert_suffixes = function(stem, nstrip, suffixes, sc, impl) local xlitend = {} to_script = to_script or require("Module:pi-Latn-translit").tr	local c2	if nstrip > 0 and sc == 'Mymr' then c2 = sub(to_script(stem, sc, option), 2, 2) end -- Seemingly #suffixes doesn't work because the module is loaded! -- Testing didn't reveal a problem, but avoiding it solved the problem! --	for k = 1, #suffixes do if #suffixes ~= 16 then error('#suffixes = '..tostring(#suffixes)) end for k, _ in ipairs(suffixes) do		xlitend[k] = convert_one_set(stem, nstrip, suffixes[k], sc, impl, c2) end return xlitend end

local liapise = function(retval, liap) -- Change Lao abl/ins plural -- Copy list to avoid changing data from data module. local oval = retval retval = {} for _, forms in ipairs(oval) do table.insert(retval, forms) end local dob = nil local dobh = nil local sena = nil if liap == 'b' then dob = 1 elseif liap == 'bh' then dobh = 1 elseif liap == 'b.' then sena = 1 elseif liap == 'bbh' then dob = 1 dobh = 1 elseif liap == 'bb.' then dob = 1 sena = 1 elseif liap == 'bhb.' then dobh = 1 sena = 1 elseif liap == 'none' then elseif liap == 'all' or liap == 'bbhb.' then dob = 1 dobh = 1 sena = 1 else error('Value "'..liap..'" of liap is not understood.') end for caseno = 6, 10, 4 do		local forms = retval[caseno] local nuforms = {} for _, form in ipairs(forms) do			if sub(form, -2, -1) == 'ຠິ' then if dob then table.insert(nuforms, sub(form,1,-3)..'ພິ') end if dobh then table.insert(nuforms, form) end if sena then table.insert(nuforms, sub(form,1,-3)..'ພ຺ິ') end else table.insert(nuforms, form) end end retval[caseno] = nuforms end return retval end

local yselect = function(retval, yval, nvals) -- Change Lao case ending -- Copy list to avoid changing data from data module. local oval = retval retval = {} for _, forms in ipairs(oval) do table.insert(retval, forms) end local yung = nil local yaa = nil if yval == 'both' then yung = 1 yaa = 1 elseif yval == 'ຍ' then yung = 1 elseif yval == 'ຢ' then yaa = 1 elseif yval == 'yung' then yung = 1 elseif yval == 'yaa' then yaa = 1 else error('Value "'..yval..'" of argument y is not understood.') end for caseno = 1, nvals do		local forms = retval[caseno] local nuforms = {} for _, form in ipairs(forms) do			if yung then local s = gsub(form, '[ຍຢ]', 'ຍ') -- gsub is a bad actual arg! table.insert(nuforms, s)			end if yaa then local s = gsub(form, '[ຍຢ]', 'ຢ') table.insert(nuforms, s)			end end retval[caseno] = nuforms end return retval end

function export.arrcat_nodup(a1, a2) -- Concatenate two arrays without duplication -- One of the arrays may have been 'loaded', so cannot use the # operator. local n1 = 0 local cat = {} for _, a1v in ipairs(a1) do		n1 = n1 + 1 cat[n1] = a1v end for _, a2v in ipairs(a2) do		local met = false for j = 1, n1 do			if a2v == cat[j] then met = true break end end if not met then n1 = n1 + 1 cat[n1] = a2v end end return cat end

local arrcat = export.arrcat_nodup

local both_sets = function(scriptCode, ending, g, option) option.impl= 'yes' iset = export.getSuffixes(scriptCode, ending, g, option) option.impl = 'no' eset = export.getSuffixes(scriptCode, ending, g, option) retval = {} --	error('i='..iset[3][1]..' e='..eset[3][1]) for ic = 1, 16 do		retval[ic] = arrcat(iset[ic], eset[ic]) end --	error('m1='..'<'..tostring(retval[1][1])..'>'..' m2='..'<'..tostring(retval[1][2])..'>') return retval end local function wayToConvert(ending, impl) local antlen = {yes = 4, no = 3} -- Length by implicitness. local inlen = {yes = 3, no = 2} local way = { a    = {pseudoStem = 'ka',  ndel = 0}, ar   = {pseudoStem = 'kar', ndel = 2}, as   = {pseudoStem = 'kas', ndel = 2}, an   = {pseudoStem = 'kan', ndel = 2}, ant  = {pseudoStem = 'kant', ndel = antlen[impl]}, ent  = {pseudoStem = 'kant', ndel = antlen[impl]}, ont  = {pseudoStem = 'kant', ndel = antlen[impl]}, mant = {pseudoStem = 'kant', ndel = antlen[impl]}, vant = {pseudoStem = 'kant', ndel = antlen[impl]}, antT = {pseudoStem = 'kant', ndel = 5}, entT = {pseudoStem = 'kant', ndel = 5}, ontT = {pseudoStem = 'kant', ndel = 5}, mantT = {pseudoStem = 'kant', ndel = 5}, vantT = {pseudoStem = 'kant', ndel = 5}, ["ā"] = {pseudoStem = 'kā', ndel = 1}, i    = {pseudoStem = 'ki', ndel = 1}, ["ī"] = {pseudoStem = 'kī', ndel = 1}, ["in"]= {pseudoStem = 'kin', ndel = inlen[impl]}, u    = {pseudoStem = 'ku', ndel = 1}, ["ū"] = {pseudoStem = 'kū', ndel = 1}, }	if impl == 'no' then way.a  = {pseudoStem = 'ka',  ndel = 1} way.ent = {pseudoStem = 'knt', ndel = 2} way.ont = {pseudoStem = 'knt', ndel = 2} end return way[ending] end

function export.getSuffixes(scriptCode, ending, g, option) local impl = option and option.impl or 'yes' if (impl == 'both') then return both_sets(scriptCode, ending, g, option) end local pattern = load("Module:pi-decl/noun/" .. scriptCode) local applicable = pattern and pattern[ending] and pattern[ending][g] if applicable then if impl == 'yes' or ending == 'ah' then return applicable end elseif 'Latn' == scriptCode then return nil elseif 'ah' == ending then ending = 'a'		impl = 'no' end pattern = require("Module:pi-decl/noun/Latn") -- Why doesn't load work with testcases? local tabulated_ending = ending if 'T' == sub(ending, -1) then tabulated_ending = sub(ending, 1, -2) end applicable = pattern and pattern[tabulated_ending] and pattern[tabulated_ending][g] if not applicable then error('Not even Latin script has ' .. g .. ' -'..tabulated_ending..			 ' endings.') return nil -- If you don't like the message above! end way = wayToConvert(ending, impl) if not way then return nil end return convert_suffixes(way.pseudoStem, way.ndel, applicable,							scriptCode, impl) end

function export.present(stem, g, forms, number, options) -- options is optional local gmark, dos, dop if 'no' == g then gmark = '' else gmark = ' (' .. genders[g] .. ')' end if not number or number == 'both'then dos = 1; dop = 1 elseif number == 's' then dos = 1; dop = nil; elseif number == 'p' then dos = nil; dop = 1; else error('Parameter "number" has meaningless value "'..number..'".' ) end local output = {} table.insert(output, ' Declension table of "' .. stem .. '"' .. gmark..' ') table.insert(output, ' ")	return table.concat(output) end

local function unwritten error('Code missing.') end

local function liapise_one_set(set, liap) local forms = {	{}, {}, {}, {}, {}, set, {}, {}, {}, {}, {},					{}, {}, {}, {}, {} }	local modified = liapise(forms, liap) return modified[6] end

local function modify_form_set(stem, ending, name, caseno, forms, at) local ipalts = at[name] local way = at[name..'_mod'] to_script = to_script or require("Module:pi-Latn-translit").tr	if ipalts and #ipalts > 0 then local alts = {} for j, v in ipairs(ipalts) do			local c1 = string.sub(v,1,1) local vsc = lang:findBestScript(v):getCode if vsc == 'None' then vsc = at.sc and sc or vsc end if '+' == c1 then local vext v = string.sub(v,2) if vsc ~= 'Latn' then vext = {at.dc and dc(v) or v}				elseif scriptCode ~= 'Latn' then local impls if at.impl == 'both' then impls = {'yes', 'no'} else impls = {at.impl} end vext = {} for _, impl in ipairs(impls) do						local cvtway = wayToConvert(ending, impl) local vset = convert_one_set(cvtway.pseudoStem, cvtway.ndel,                   								{v}, scriptCode, impl, nil) vext = arrcat(vext, vset) end if scriptCode == 'Laoo' then local vexset = yselect({vext}, at.y, 1) vext = vexset(1) end else vext = {v} end if scriptCode == 'Laoo' and vsc == 'Latn' and (caseno == 6 or caseno == 10) then vext = liapise_one_set(vext, at.liap) end local vext = export.joinSuffix(scriptCode, stem, vext, at) for _, vv in ipairs(vext) do ti(alts, vv) end elseif vsc == scriptCode then ti(alts, v)			elseif vsc == 'Latn' then -- TODO: Sane Myanmar and Lao script support. local options = {} local vext = {} if at.impl and at.impl == 'both' then options.y = at.y -- Probably ineffective options.impl = 'yes' ti(vext, to_script(v, scriptCode, options)) options.impl = 'no' ti(vext, to_script(v, scriptCode, options)) else ti(vext, to_script(v, scriptCode, options)) end if scriptCode == 'Laoo' and vsc == 'Latn' and (caseno == 6 or caseno == 10) then vext = liapise_one_set(vext, at.liap) local vexset = yselect({vext}, at.y, 1) vext = vexset(1) end for _, vv in ipairs(vext) do ti(alts, vv) end else ti(alts, v) -- Go ahead anyway end end if 'after' == way then forms[caseno] = arrcat(forms[caseno], alts) elseif 'before' == way then forms[caseno] = arrcat(alts, forms[caseno]) elseif 'replace' == way then forms[caseno] = alts; elseif 'blank' == way then -- Issue warning about alts? forms[caseno] = {} else error('Bad value for parameter '..name..'_mod') end elseif 'blank' == way then forms[caseno] = {} end end

local function modify(stem, ending, forms, args) local mod_default = 'after' local params = { [1] = {alias_of = 'stem'}, [2] = {alias_of = 'ending'}, [3] = {alias_of = 'g'}, stem = {}, ending = {}, g = {required = true}, gender = {alias_of = 'g'}, v = {}, variation = {alias_of = 'v'}, label = {}, number = {}, showtr = {}, subst = {}, sc = {},

aa = {default = 'default'}, liap = {default = 'default'}, impl = {default = 'yes'}, y = {default = 'default'},

nonom = {type = 'boolean'}, noms = {list = true}, noms_mod = {default = mod_default}, nomp = {list = true}, nomp_mod = {default = mod_default}, noacc = {type = 'boolean'}, accs = {list = true}, accs_mod = {default = mod_default}, accp = {list = true}, accp_mod = {default = mod_default}, noins = {type = 'boolean'}, inss = {list = true}, inss_mod = {default = mod_default}, insp = {list = true}, insp_mod = {default = mod_default}, nodat = {type = 'boolean'}, dats = {list = true}, dats_mod = {default = mod_default}, datp = {list = true}, datp_mod = {default = mod_default}, noabl = {type = 'boolean'}, abls = {list = true}, abls_mod = {default = mod_default}, ablp = {list = true}, ablp_mod = {default = mod_default}, nogen = {type = 'boolean'}, gens = {list = true}, gens_mod = {default = mod_default}, genp = {list = true}, genp_mod = {default = mod_default}, noloc = {type = 'boolean'}, locs = {list = true}, locs_mod = {default = mod_default}, locp = {list = true}, locp_mod = {default = mod_default}, novoc = {type = 'boolean'}, vocs = {list = true}, vocs_mod = {default = mod_default}, vocp = {list = true}, vocp_mod = {default = mod_default}, }	local at = m_parameters.process(args, params) if ending == 'ah' then at.impl = 'no' end for i, v in ipairs(rows) do		local name = string.lower(string.sub(v,1,3)) if at['no'..name] then forms[2*i] = {} forms[2*i-1] = {} else modify_form_set(stem, ending, name..'s', 2*i-1, forms, at) modify_form_set(stem, ending, name..'p', 2*i,  forms, at) end end return forms; end

function export.show(frame) local args = frame:getParent.args local PAGENAME = mw.title.getCurrentTitle.text local stem = args[1] or args["stem"] or PAGENAME currentScript = lang:findBestScript(stem) scriptCode = currentScript:getCode if scriptCode == "None" and args["sc"] then scriptCode = args["sc"] currentScript = require("Module:scripts").getByCode(scriptCode, "No such script as "..scriptCode) end local g = args[3] or args["g"] or args["gender"] -- for each gender only local variation = args["v"] or args["variation"] -- for some scripts

if not g then error("A gender is required to display proper declensions.") end

local lookup_g = g	if 'no' == lookup_g then lookup_g = 'm' end -- Arbitrary! local option = {impl = args["impl"] or 'yes'} local xlit_options = {} xlit_options.impl = option.impl xlit_options.showtr = args.showtr local ending = args[2] or args["ending"] or export.detectEnding(stem, option) if ending == 'ah' then xlit_options.impl = 'no' end local selectedPattern = export.getSuffixes(scriptCode, ending, lookup_g, option) if args["liap"] and (scriptCode == 'Laoo') then selectedPattern = liapise(selectedPattern, args["liap"]) end if args.y and (scriptCode == 'Laoo') then selectedPattern = yselect(selectedPattern, args.y, 16) xlit_options.y = args.y	end option.aa = args["aa"] -- Reusable! local forms = export.joinSuffixes(scriptCode, stem, selectedPattern, option) modify(stem, ending, forms, args) for ic = 1, 16 do forms[ic] = arrcat({}, forms[ic]) end -- Remove duplicates. xlit_options.subst = args["subst"] --	for name, _ in pairs(_G) do mw.addWarning('Global '..name) end return export.present(args["label"] or stem, g, forms, args["number"], xlit_options) end

return export