This module provides inflection tables for Pali for nouns, adjectives and pronouns. For pronouns, one currently uses the interface for nouns, while for adjectives one uses separate invocations for each gender.
Some functions are exported from this module to service the testing of noun inflection. The module also provides utility functions for the conjugation of verbs.
The normal way to use this module is to invoke the template {{pi-decl-noun}}
, which see for the interface. This invokes the exported function show
.
The primary data table for the inflections is the data module Module:pi-decl/noun/Latn, which contains the Latin script tables. These are supplemented by identically structured tables for each of the other supported scripts. If the table for a particular paradigm is missing from one of these, the table will be generated using the transliteration functions in Module:pi-Latn-translit. The data modules for the other scripts are:
With the exception of the masculine and neuter thematic nouns, the Thai and Lao tables are not used for declension with explicit vowels.
There is no such redundant table for the Chakma script.
The following Lua functions are exported by this module:
orJoin()
joinSuffix
arrcat_nodup
present
show
The original idea was to share this function with the code for verb conjugation. However, the conjugation of verbs in the Thai and Lao scripts is more complicated, and there is therefore a more general function in use for verbs.
detectEnding()
joinSuffixes
getSuffixes
modify
The paradigm to use is determined using the script of the stem, the ending of the stem (for which there are a few conventional values - see {{pi-decl-noun}}
) and gender of the stem. The script is always deduced from the script of the stem, while the ending may be supplied explicitly (in Latin script) or deduced from the stem. The gender is always supplied explicitly. The deduction of the ending from the stem is performed by function detectEnding
.
The set of suffixes is obtained by function getSuffixes
. This first attempts to load the paradigm from the data files. However, if the paradigm is unacceptable or missing, it will generate it itself. Paradigms from data files are only acceptable for some combinations of settings. At present, they are not acceptable for non-Roman scripts when using explicit vowels, except for the conventional ending 'ah', which denotes masculine or neuter nouns with stems in explicit -a. (The convention was chosen because the explicit vowel also represents the Sanskrit ending -aḥ.)
When paradigms are generated internally, they are converted from Latin script to the required script and implicit vowel settings. This is implemented in function convert_suffixes
.
The second stage of the generation, applicable to the Lao script only, is to, where needed, convert the ablative and instrumental plural in -bhi to the correct forms. The editor specifies the correct form using the parameter |liap=
.
The third stage of the generation, applicable to Lao script only, is to, where needed, convert the letter corresponding to <y> in the suffixes to the correct letter. This setting is treated as orthogonal to the choice between using or not using implicit vowels.
The endings are then attached to the stem using the function joinSuffixes
. This invokes function joinSuffixes
to apply the writing system-dependent rules for the attachment of suffixes. There is one user-controlled input to this process, the parameter |aa=
, which is applicable to the Burmes and Tai Tham scripts.
Next, the function modify
is applied to add, remove or replace the forms generated so far in accordance a list of modifications included in the invocation of {{pi-decl-noun}}
.
Finally, the function present
formats the list of forms for each combination of case and number. This formatting includes adding the transliteration, which is done in function orJoin
. Function show
then returns the inflection table for display on the page.
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 = {
= "masculine", = "feminine", = "neuter",
}
local rows = {
"Nominative (first)", "Accusative (second)", "Instrumental (third)", "Dative (fourth)",
"Ablative (fifth)", "Genitive (sixth)", "Locative (seventh)", "Vocative (calling)",
}
local endings = {
= {
-- key(Ln) Thai Deva Beng Mymr Lana Laoo Khmr
-- Sinh Brah Cakm
= {},
= { "า", "ा", "आ", "া", "আ", "ါ", "ာ", " ႃ", "ᩣ", "ᩤ", "າ", "ា", u(0x17A4),
"ා", "ආ", "𑀸", "𑀆", "𑄂" },
= { "ิ", "ि", "इ", "ি", "ই", "ိ", "ဣ", "ᩥ", "ᩍ", "ິ", "ិ", "ឥ",
"ි", "ඉ", "𑀺", "𑀇", "𑄨" },
= { "ี", "ी", "ई", "ী", "ঈ", "ီ", "ဳ", "ဤ", "ᩦ", "ᩎ", "ີ", "ី", "ឦ",
"ී", "ඊ", "𑀻", "𑀈", "𑄩" },
= { "ุ", "ु", "उ", "ু", "উ", "ု", "ဥ", "ᩩ", "ᩏ", "ຸ", "ុ", "ឧ",
"ු", "උ", "𑀼", "𑀉", "𑄪" },
= { "ู", "ू", "ऊ", "ূ", "ঊ", "ူ", "ဦ", "ᩪ", "ᩐ", "ູ", "ូ", "ឨ", "ឩ",
"ූ", "ඌ", "𑀽", "𑀊", "𑄫" },
= { "ะ", "ະ"},
},
= {
-- key(Ln) Thai Deva Beng Mymr Lana Laoo Khmr
-- Sinh Brah Cakm
= { "รฺ", "ัร", "र्", "র্", "ရ်", "ᩁ᩺", "ᩁ᩼", "ຣ໌", "ຣ຺", "ັຣ", "រ៑",
"ර්", "𑀭𑁆", "𑄢𑄴"},
= { "สฺ", "ัส", "स्", "স্", "သ်", "ᩈ᩺", "ᩈ᩼", "ສ໌", "ສ຺", "ັສ", "ស៑",
"ස්", "𑀲𑁆", "𑄥𑄴" },
= { "นฺ", "ัน", "न्", "ন্", "န်", "ᨶ᩺", "ᨶ᩼", "ນ໌", "ນ຺", "ັນ", "ន៑",
"න්", "𑀦𑁆", "𑄚𑄴"},
ent = { "นต", "ນຕ"},
= { "ิน", "ິນ"},
},
three = {
-- key(Ln) Thai Deva Beng Mymr Lana Laoo Khmr
-- Sinh Brah Cakm
ant = { "ันต" , "ັນຕ"},
ent = {},
ont = {},
= { "ินฺ", "िन्", "িন্", "ိန်", "ᩥᨶ᩺", "ິນ຺", "ិន៑",
"ින්", "𑀺𑀦𑁆", "𑄨𑄚𑄴" },
},
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, '')
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, '') 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 = export.joinSuffix(scriptCode, stem, pattern,
option)
forms = export.joinSuffix(scriptCode, stem, pattern,
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 = " <small style=\"color:888\">or</small> "
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, subsplit)
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
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 = strip .. "↶" .. pre .. sub(altform, 3)
-- Quick cheat for Myanmar script variants.
elseif c2 and c2 == sub(altform,2,2) then
xlitend = sub(strip, 2) .. sub(altform, 3)
-- Back to the normal case.
else
xlitend = 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 = convert_one_set(stem, nstrip, suffixes, 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
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 = 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
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 = 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 = a1v
end
for _, a2v in ipairs(a2) do
local met = false
for j = 1, n1 do
if a2v == cat then
met = true
break
end
end
if not met then
n1 = n1 + 1
cat = 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..' e='..eset)
for ic = 1, 16 do
retval = arrcat(iset, eset)
end
-- error('m1='..'<'..tostring(retval)..'>'..' m2='..'<'..tostring(retval)..'>')
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},
ent = {pseudoStem = 'kant', ndel = antlen},
ont = {pseudoStem = 'kant', ndel = antlen},
mant = {pseudoStem = 'kant', ndel = antlen},
vant = {pseudoStem = 'kant', ndel = antlen},
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},
= {pseudoStem = 'kin', ndel = inlen},
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
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 and pattern
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 and
pattern
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 .. ')'
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, '<div class="NavFrame" style="min-width:30%"><div class="NavHead" style="background:var(--wikt-palette-lightblue,#d9ebff)">Declension table of "' .. stem .. '"' .. gmark..'</div><div class="NavContent">')
table.insert(output, '<table class="inflection-table" style="background:var(--wikt-palette-paleblue,#f8f9fa);text-align:center;width:100%"><tr><th style="background:var(--wikt-palette-cyan,#eaffff)">Case \\ Number</th>')
if dos then
table.insert(output, '<th style="background:var(--wikt-palette-cyan,#eaffff)">Singular</th>')
end
if dop then
table.insert(output, '<th style="background:var(--wikt-palette-cyan,#eaffff)">Plural</th></tr>')
end
for i,v in ipairs(rows) do
if #forms > 0 or #forms > 0 then
table.insert(output, "<tr><td style=\"background:var(--wikt-palette-cyan,#eaffff)\">" .. v .. "</td>")
if dos then
table.insert(output, "<td>")
table.insert(output, export.orJoin(currentScript, forms, options))
table.insert(output, "</td>")
end
if dop then
table.insert(output, "<td>")
table.insert(output, export.orJoin(currentScript, forms, options))
table.insert(output, "</td>")
end
table.insert(output, "</tr>")
end
end
table.insert(output, "</table></div></div>")
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
end
local function modify_form_set(stem, ending, name, caseno, forms, at)
local ipalts = at
local way = at
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 = arrcat(forms, alts)
elseif 'before' == way then
forms = arrcat(alts, forms)
elseif 'replace' == way then
forms = alts;
elseif 'blank' == way then
-- Issue warning about alts?
forms = {}
else
error('Bad value for parameter '..name..'_mod')
end
elseif 'blank' == way then
forms = {}
end
end
local function modify(stem, ending, forms, args)
local mod_default = 'after'
local params = {
= {alias_of = 'stem'},
= {alias_of = 'ending'},
= {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 then
forms = {}
forms = {}
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 or args or PAGENAME
currentScript = lang:findBestScript(stem)
scriptCode = currentScript:getCode()
if scriptCode == "None" and args then
scriptCode = args
currentScript = require("Module:scripts").getByCode(scriptCode, "No such script as "..scriptCode)
end
local g = args or args or args -- for each gender only
local variation = args or args -- 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 or 'yes'}
local xlit_options = {}
xlit_options.impl = option.impl
xlit_options.showtr = args.showtr
local ending = args or args 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 and (scriptCode == 'Laoo') then
selectedPattern = liapise(selectedPattern, args)
end
if args.y and (scriptCode == 'Laoo') then
selectedPattern = yselect(selectedPattern, args.y, 16)
xlit_options.y = args.y
end
option.aa = args -- Reusable!
local forms = export.joinSuffixes(scriptCode, stem, selectedPattern, option)
modify(stem, ending, forms, args)
for ic = 1, 16 do forms = arrcat({}, forms) end -- Remove duplicates.
xlit_options.subst = args
-- for name, _ in pairs(_G) do mw.addWarning('Global '..name) end
return export.present(args or stem, g, forms, args, xlit_options)
end
return export