Module:pi-conj/verb
Jump to navigation
Jump to search
- This module lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • transclusions • testcases • sandbox
local export = {}
local links = require("Module:links")
local lang = require("Module:languages").getByCode("pi")
local m_parameters = require("Module:parameters")
local m_noun = require("Module:pi-decl/noun")
local m_scripts = require("Module:scripts")
local to_script = require("Module:pi-Latn-translit").tr
local debug_outer = ''
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local sub = mw.ustring.sub
local asub = string.sub -- quicker for ASCII, but works on bytes.
local ti = table.insert
-- require "Module:log globals" -- Check for abuse of globals. Only require for testing!
local function dc(x) -- Use this to make marks legible. The name 'dc' means 'drop carrier'.
return gsub(x, "[𑀓कকකကกᨠកກ𑄇]", "") -- These are the letter ka in the 10 supported Indic scripts.
end
local endings = {
-- pa endings
["ati"] = "ati", ["ติ"] = "ati", ["ति"] = "ati", ["তি"] = "ati",
["တိ"] = "ati", ["ᨲᩥ"] = "ati",
["តិ"] = "ati", ["ති"] = "ati", ["𑀢𑀺"] = "ati", ["ຕິ"] = "ati",
["𑄖𑄨"] = "ati",
["ayati"] = "ayati", ["ยติ"] = "ayati", ["यति"] = "ayati", ["যতি"] = "ayati",
["ယတိ"] = "ayati", ["ะยะติ"] = "ayati", ["ᨿᨲᩥ"] = "ayati", ["ຢຕິ"] = "ayati",
["យតិ"] = "ayati", ["යති"] = "ayati", ["𑀬𑀢𑀺"] = "ayati", ["ະຢະຕິ"] = "ayati",
["ຍຕິ"] = "ayati", ["ະຍະຕິ"] = "ayati", ["𑄠𑄖𑄨"] = "ayati",
["āti"] = "āti", ["าติ"] = "āti", [dc("काति")] = "āti", [dc("কাতি")] = "āti",
["ာတိ"] = "āti", ["ါတိ"] = "āti", ["ᩣᨲᩥ"] = "āti", ["ᩤᨲᩥ"] = "āti",
[dc("កាតិ")] = "āti", [dc("කාති")] = "āti", [dc("𑀓𑀸𑀢𑀺")] = "āti", ["າຕິ"] = "āti",
[dc("𑄇𑄂𑄖𑄨")] = "āti",
["eti"] = "eti", [dc("केति")] = "eti", [dc("কেতি")] = "eti",
["ေတိ"] = "eti", [dc("ᨠᩮᨲᩥ")] = "eti",
[dc("កេតិ")] = "eti", [dc("කෙති")] = "eti", [dc("𑀓𑁂𑀢𑀺")] = "eti", [dc("𑄇𑄬𑄖𑄨")] = "eti",
["oti"] = "oti", [dc("कोति")] = "oti", [dc("কোতি")] = "oti",
["ောတိ"] = "oti", ["ေါတိ"] = "oti", ["ᩮᩣᨲᩥ"] = "oti", ["ᩮᩤᨲᩥ"] = "oti",
[dc("កោតិ")] = "oti", [dc("කොති")] = "oti", [dc("𑀓𑁄𑀢𑀺")] = "oti", [dc("𑄇𑄮𑄖𑄨")] = "oti",
-- pm endings
["ate"] = "ate", ["เต"] = "ate", ["ते"] = "ate", ["তে"] = "ate",
["တေ"] = "ate", ["ᨲᩮ"] = "ate",
["តេ"] = "ate", ["තෙ"] = "ate", ["𑀢𑁂"] = "ate", ["ເຕ"] = "ate",
["𑄖𑄬"] = "ate",
["ayate"] = "ayate", ["ยเต"] = "ayate", ["यते"] = "ayate", ["যতে"] = "ayate",
["ယတေ"] = "ayate", ["ะยะเต"] = "ayate", ["ᨿᨲᩮ"] = "ayate", ["ຢເຕ"] = "ayate",
["យតេ"] = "ayate", ["යතෙ"] = "ayate", ["𑀬𑀢𑁂"] = "ayate", ["ະຢະເຕ"] = "ayate",
["ຍເຕ"] = "ayate", ["ະຍະເຕ"] = "ayate", ["𑄠𑄖𑄬"] = "ayate",
["āte"] = "āte", ["าเต"] = "āte", [dc("काते")] = "āte", [dc("কাতে")] = "āte",
["ာတေ"] = "āte", ["ါတေ"] = "āte", ["ᩣᨲᩮ"] = "āte", ["ᩤᨲᩮ"] = "āte",
[dc("កាតេ")] = "āte", [dc("කාතෙ")] = "āte", [dc("𑀓𑀸𑀢𑁂")] = "āte", ["າເຕ"] = "āte",
[dc("𑄇𑄂𑄖𑄬")] = "āte",
["ete"] = "ete", [dc("केते")] = "ete", [dc("কেতে")] = "ete",
["ေတေ"] = "ete", [dc("ᨠᩮᨲᩮ")] = "ete",
[dc("កេតេ")] = "ete", [dc("කෙතෙ")] = "ete", [dc("𑀓𑁂𑀢𑁂")] = "ete", [dc("𑄇𑄬𑄖𑄬")] = "ete",
["ute"] = "ute", [dc("กุเต")] = "ute", [dc("कुते")] = "ute", [dc("কুতে")] = "ute",
[dc("ကုတေ")] = "ute", [dc("ᨠᩩᨲᩮ")] = "ute",
[dc("កុតេ")] = "ute", [dc("කුතෙ")] = "ute", [dc("𑀓𑀼𑀢𑁂")] = "ute", [dc("ກຸເຕ")] = "ute",
[dc("𑄇𑄪𑄖𑄬")] = "ute",
-- optative endings
["eyya"] = "eyya", ["ยฺย"] = "eyya", [dc("केय्य")] = "eyya", [dc("কেয্য")] = "eyya",
["ေယျ"] = "eyya", ["ยยะ"] = "eyya", [dc("ᨠᩮᨿ᩠ᨿ")] = "eyya", ["ຢຢະ"] = "eyya",
[dc("កេយ្យ")] = "eyya", [dc("කෙය්ය")] = "eyya", [dc("𑀓𑁂𑀬𑁆𑀬")] = "eyya", ["ຢ຺ຢ"] = "eyya",
["ຍ຺ຍ"] = "eyya", ["ຍຍະ"] = "eyya", [dc("𑄇𑄬𑄠𑄳𑄠")] = "eyya",
["ā"] = "ā", ["า"] = "ā", [dc("का")] = "ā", [dc("কা")] = "ā",
["ာ"] = "ā", ["ါ"] = "ā", ["ᩣ"] = "ā", ["ᩤ"] = "ā",
[dc("កា")] = "ā", [dc("කා")] = "ā", [dc("𑀓𑀸")] = "ā", ["າ"] = "ā",
[dc("𑄇𑄂")] = "ā",
["etha"] = "etha", ["ถ"] = "etha", [dc("केथ")] = "etha", [dc("কেথ")] = "etha",
["ေထ"] = "etha", ["ถะ"] = "etha", [dc("ᨠᩮᨳ")] = "etha", ["ຖ"] = "etha",
[dc("កេថ")] = "etha", [dc("කෙථ")] = "etha", [dc("𑀓𑁂𑀣")] = "etha", ["ຖະ"] = "etha",
[dc("𑄇𑄬𑄗")] = "etha",
-- imperfect endings
["attha"] = "attha", ["ตฺถ"] = "attha", ["त्थ"] = "attha", ["ত্থ"] = "attha",
["တ္ထ"] = "attha", ["ᨲ᩠ᨳ"] = "attha", ["ตถะ"] = "attha", ["ຕຖະ"] = "attha",
["ត្ថ"] = "attha", ["ත්ථ"] = "attha", ["𑀢𑁆𑀣"] = "attha", ["ຕ຺ຖ"] = "attha",
["𑄖𑄴𑄗"] = "attha",
["a"] = "a", ["ะ"] = "a", ["ະ"] = "a", -- Only good for alphabets!
}
local aorist_endings = {
-- aorist endings. Only active seems predictable enough.
["i"] = "i", [dc("กิ")] = "i", [dc("कि")] = "i", [dc("কি")] = "i",
[dc("ကိ")] = "i", [dc("ᨠᩥ")] = "i",
[dc("កិ")] = "i", [dc("කි")] = "i", [dc("𑀓𑀺")] = "i", [dc("ກິ")] = "i",
[dc("𑄇𑄨")] = "i",
["esi"] = "esi", ["สิ"] = "esi", [dc("केसि")] = "esi", [dc("কেসি")] = "esi",
[dc("ကေသိ")] = "esi", [dc("ᨠᩮᩈᩥ")] = "esi",
[dc("កេសិ")] = "esi", [dc("කෙසි")] = "esi", [dc("𑀓𑁂𑀲𑀺")] = "esi", ["ສິ"] = "esi",
[dc("𑄇𑄬𑄥𑄨")] = "esi",
["āsi"] = "āsi", ["าสิ"] = "āsi", [dc("कासि")] = "āsi", [dc("কাসি")] = "āsi",
[dc("ကာသိ")] = "āsi", [dc("ကါသိ")] = "āsi", [dc("ᨠᩣᩈᩥ")] = "āsi", [dc("ᨠᩤᩈᩥ")] = "āsi",
[dc("កាសិ")] = "āsi", [dc("කාසි")] = "āsi", [dc("𑀓𑀸𑀲𑀺")] = "āsi", [dc("ກາສິ")] = "āsi",
[dc("𑄇𑄂𑄖𑄨")] = "āsi",
-- Purpose of "osi" is to bleed "āsi" when the vowel is written as two characters in from NFC
[dc("ကောသိ")] = "osi", [dc("ကေါသိ")] = "osi", [dc("ᨠᩮᩣᩈᩥ")] = "osi", [dc("ᨠᩮᩤᩈᩥ")] = "osi",
["ayi"] = "ayi", ["ยิ"] = "ayi", ["यि"] = "ayi", ["যি"] = "ayi",
["ယိ"] = "ayi", ["ᨿᩥ"] = "ayi", ["ะยิ"] = "ayi", ["ະຍິ"] = "ayi", ["ະຢິ"] = "ayi",
["យិ"] = "ayi", ["යි"] = "ayi", ["𑀬𑀺"] = "ayi", ["ຍິ"] = "ayi", ["ຢິ"] = "ayi",
["𑄠𑄨"] = "ayi",
}
local future_endings = {
-- fa endings
["ati"] = "ati", ["ติ"] = "ati", ["ति"] = "ati", ["তি"] = "ati",
["တိ"] = "ati", ["ᨲᩥ"] = "ati",
["តិ"] = "ati", ["ති"] = "ati", ["𑀢𑀺"] = "ati", ["ຕິ"] = "ati",
["𑄖𑄨"] = "ati",
["iti"] = "iti", [dc("กิติ")]="iti", [dc("किति")]="iti", [dc("কিতি")]="iti",
[dc("ကိတိ")]="iti", [dc("ᨠᩥᨲᩥ")]="iti",
[dc("កិតិ")]="iti", [dc("කිති")]="iti", [dc("𑀓𑀺𑀢𑀺")]="iti", [dc("ກິຕິ")]="iti",
[dc("𑄇𑄨𑄖𑄨")]="iti",
["heti"] = "heti", ["เหติ"] = "heti", ["हेति"] = "heti", ["হেতি"] = "heti",
["ဟေတိ"] = "heti", ["ᩉᩮᨲᩥ"] = "heti",
["ហេតិ"] = "heti", ["හෙති"] = "heti", ["𑀳𑁂𑀢𑀺"] = "heti", ["ເຫຕິ"] = "heti",
["𑄦𑄬𑄖𑄨"] = "heti",
["kāhiti"] = "kāhiti", ["กาหิติ"] = "kāhiti", ["काहिति"] = "kāhiti", ["কাহিতি"] = "kāhiti",
["ကာဟိတိ"] = "kāhiti", ["ᨠᩣᩉᩥᨲᩥ"] = "kāhiti",
["កាហិតិ"] = "kāhiti", ["කාහිති"] = "kāhiti", ["𑀓𑀸𑀳𑀺𑀢𑀺"] = "kāhiti", ["ກາຫິຕິ"] = "kāhiti",
["𑄇𑄂𑄦𑄨𑄖𑄨"] = "kāhiti",
-- fm endings
["ate"] = "ate", ["เต"] = "ate", ["ते"] = "ate", ["তে"] = "ate",
["တေ"] = "ate", ["ᨲᩮ"] = "ate",
["តេ"] = "ate", ["තෙ"] = "ate", ["𑀢𑁂"] = "ate", ["ເຕ"] = "ate",
["𑄖𑄬"] = "ate",
-- ca ending.
["ā"] = "ā", ["า"] = "ā", [dc("का")] = "ā", [dc("কা")] = "ā",
["ာ"] = "ā", ["ါ"] = "ā", ["ᩣ"] = "ā", ["ᩤ"] = "ā",
[dc("កា")] = "ā", [dc("කා")] = "ā", [dc("𑀓𑀸")] = "ā", ["າ"] = "ā",
[dc("𑄇𑄂")] = "ā",
["a"] = "a",
-- cm ending
["atha"] = "atha", ["ถ"] = "atha", ["थ"] = "atha", ["থ"] = "atha",
["ထ"] = "atha", ["ถะ"] = "atha", ["ᨳ"] = "atha", ["ຖ"] = "atha",
["ថ"] = "atha", ["ථ"] = "atha", ["𑀣"] = "atha", ["ຖະ"] = "atha",
["𑄗"] = "atha",
}
local cons = "^[ก-ฮअक-हঅক-হက-ဢᨠ-ᩌᩔ-ᩖᩚ-ᩞក-អඅක-ෆ𑀅𑀓-𑀷ກ-ຮໜ-ໟ𑄇-𑄦𑅇]"
local detectEndingFromList = function(cite3s, endings, latinise, flags)
if latinise then
local cfin = cite3s -- In general, this logic would need the
cite3s = (lang:transliterate(cfin, latinise)) -- trwo() function from the transliterator.
end
local len
local ending
local wordEnd
for len = 5, 1, -1 do
wordEnd = sub(cite3s, -len)
ending = endings[wordEnd]
if not ending then
-- Try again
elseif wordEnd == "ติ" then
if match(cite3s, 'เ.ติ$') then
return "eti"
elseif match(cite3s, 'โ.ติ$') then
return "oti"
elseif match(cite3s, dc('เ.กฺ.ติ$')) then
return "eti"
elseif match(cite3s, dc('โ.กฺ.ติ$')) then
return "oti"
else
return ending
end
elseif wordEnd == "เต" then
if match(cite3s, 'เ.เต$') then
return "ete"
elseif match(cite3s, dc('เ.กฺ.เต$')) then
return "ete"
else
return ending
end
elseif wordEnd == "ຕິ" then
if match(cite3s, 'ເ.ຕິ$') then
return "eti"
elseif match(cite3s, 'ໂ.ຕິ$') then
return "oti"
elseif match(cite3s, dc('ເ.ກ຺.ຕິ$')) then
return "eti"
elseif match(cite3s, dc('ໂ.ກ຺.ຕິ$')) then
return "oti"
else
return ending
end
elseif wordEnd == "ເຕ" then
if match(cite3s, 'ເ.ເຕ$') then
return "ete"
elseif match(cite3s, dc('ເ.ກ຺.ເຕ$')) then
return "ete"
else
return ending
end
elseif wordEnd == "สิ" then
if match(cite3s, 'เ.สิ$') then
return "esi"
elseif match(cite3s, dc('เ.กฺ.สิ$')) then
return "esi"
else
-- Try again
end
elseif wordEnd == "ສິ" then
if match(cite3s, 'ເ.ສິ$') then
return "esi"
elseif match(cite3s, dc('ເ.ກ຺.ສິ$')) then
return "esi"
else
-- Try again
end
elseif ending == 'ayati' and len == 3 then
if match(sub(cite3s,-4,-4), cons) then
return ending
else
return "ati"
end
elseif ending == 'ayate' and len == 3 then
if match(sub(cite3s,-4,-4), cons) then
return ending
else
return "ate"
end
elseif ending == 'ayi' and len == 2 then
if match(sub(cite3s,-3,-3), cons) then
return ending
else
return "i"
end
elseif ending == 'āsi' and flags then
if flags.aasi == '1' then
return ending
else
-- Try again
end
elseif ending == 'osi' then
return "i" -- Avoid misrecognising as 'āsi' in Burmese and similar.
else
-- if ending == "i" and not allowi then
-- ending = "ati" -- For brūti and similar
-- end
-- debug_outer = debug_outer..'\n'..cite3s..'='..ending..'\n'
return ending
end
end
if match(sub(cite3s, -1, -1), cons) then
-- debug_outer = debug_outer..'\n'..cite3s..'='.."a"..'\n'
return "a"
else
-- debug_outer = debug_outer..'\n'..cite3s..'='.."ati"..'\n'
return "ati"
end
end
export.detectEnding = function(cite3s, latinise)
return detectEndingFromList(cite3s, endings, latinise)
end
export.detectAoristEnding = function(cite3s, latinise, flags)
return detectEndingFromList(cite3s, aorist_endings, latinise, flags)
end
local active_optative = {
{"⌫⌫⌫eyyāmi", "⌫⌫⌫eyyaṃ", "⌫⌫⌫e"}, {"⌫⌫⌫eyyāma"},
{"⌫⌫⌫eyyāsi", "⌫⌫⌫e"}, {"⌫⌫⌫eyyātha"},
{"⌫⌫⌫eyya", "⌫⌫⌫e"}, {"⌫⌫⌫eyyuṃ"}
}
local active_optative_ati = mw.clone(active_optative)
local active_optative_aati = mw.clone(active_optative)
active_optative_aati[1] = {"⌫⌫⌫eyyāmi", "⌫⌫⌫eyyaṃ"}
active_optative_aati[3] = {"⌫⌫⌫eyyāsi"}
local active_optative_eti = mw.clone(active_optative_aati)
active_optative_eti[5] = {"⌫⌫⌫eyya"}
local active_optative_oti = mw.clone(active_optative_eti)
local active_optative_ute = mw.clone(active_optative_eti)
local middle_optative = {
{"⌫⌫⌫eyyaṃ"}, {"⌫⌫⌫eyyāmhe"},
{"⌫⌫⌫etho"}, {"⌫⌫⌫eyyavho"},
{"⌫⌫⌫etha"}, {"⌫⌫⌫eraṃ"}
}
local middle_optative_ati = mw.clone(middle_optative)
local middle_optative_aati = mw.clone(middle_optative)
local middle_optative_eti = mw.clone(middle_optative)
local middle_optative_oti = mw.clone(middle_optative)
local middle_optative_ute = mw.clone(middle_optative)
local empty = {{}, {}, {}, {}, {}, {}}
local pattern = {
["ati"] = {
{"⌫⌫⌫āmi"}, {"⌫⌫⌫āma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫nti"},
mid = "ate",
imperfect = {
{"⌫⌫", "⌫⌫ṃ"}, {"⌫⌫mhā"},
{"⌫⌫⌫o"}, {"⌫tha"},
{"⌫⌫", "⌫⌫⌫ā"}, {"⌫⌫⌫u", "⌫⌫⌫ū"},
},
imperative = {
{"⌫⌫⌫āmi"}, {"⌫⌫⌫āma"}, {"⌫⌫", "⌫⌫⌫āhi"}, {"⌫ha"}, {"⌫u"}, {"⌫⌫ntu"}
},
optative_active = active_optative_ati,
optative_middle = middle_optative_ati,
participle = {{"⌫⌫nt"}},
},
["āti"] = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫⌫anti"},
mid = "āte",
imperfect = {
{"⌫⌫⌫a", "⌫⌫⌫aṃ"}, {"⌫⌫⌫amhā"},
{"⌫⌫⌫o"}, {"⌫⌫⌫attha"},
{"⌫⌫⌫a", "⌫⌫"}, {"⌫⌫⌫u", "⌫⌫⌫ū"},
},
imperative = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫", "⌫⌫hi"}, {"⌫ha"}, {"⌫u"}, {"⌫⌫⌫antu"},
},
optative_active = active_optative_aati,
optative_middle = middle_optative_aati,
participle = {{"⌫⌫⌫ant"}},
},
["eti"] = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫nti"},
mid = nil, -- "ete",
imperfect = empty,
imperative = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫hi"}, {"⌫ha"}, {"⌫u"}, {"⌫⌫ntu"},
},
optative_active = active_optative_eti,
optative_middle = middle_optative_eti,
participle = {{"⌫⌫nt"}},
},
["oti"] = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫nti"},
mid = "oti_ute",
imperfect = empty,
imperative = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫hi"}, {"⌫ha"}, {"⌫u"}, {"⌫⌫ntu"},
},
optative_active = active_optative_oti,
optative_middle = middle_optative_oti,
participle = {{"⌫⌫nt"}},
},
["ate"] = { -- Also services "ati"
{"⌫⌫⌫e"}, {"⌫⌫⌫āmhe"}, {"⌫⌫se"}, {"⌫⌫vhe"}, {"⌫e"}, {"⌫⌫nte", "⌫⌫re"},
mid = "ate",
imperfect = {
{"⌫⌫⌫iṃ"}, {"⌫⌫⌫āmhase", "⌫⌫mhase"},
{"⌫⌫se"}, {"⌫⌫vhaṃ"},
{"⌫tha"}, {"⌫thuṃ"},
},
imperative = {
{"⌫⌫⌫e"}, {"⌫⌫⌫āmase"}, {"⌫⌫ssu"}, {"⌫⌫vho"}, {"⌫aṃ"}, {"⌫⌫ntaṃ"},
},
optative_active = active_optative_ati,
optative_middle = middle_optative_ati,
participle = {{"⌫⌫māna"}},
},
["āte"] = { -- Also services "āti"
{"⌫⌫⌫e"}, {"⌫⌫mhe"},
{"⌫⌫se"}, {"⌫⌫⌫avhe"},
{"⌫e"}, {"⌫⌫⌫ante", "⌫⌫re"},
mid = "āte",
imperfect = empty,
optative_active = active_optative_aati,
optative_middle = middle_optative_aati,
participle = {{"⌫⌫⌫amāna"}},
},
["ete"] = { -- Also services "eti"
{"⌫⌫⌫aye"}, {"⌫⌫⌫ayāmhe"},
{"⌫⌫⌫ayase"}, {"⌫⌫⌫ayavhe"},
{"⌫⌫⌫ayate"}, {"⌫⌫⌫ayante", "⌫⌫⌫ayare"},
mid = "ete",
imperfect = empty,
imperative = {
{"⌫⌫⌫aye"}, {"⌫⌫⌫ayāmase"},
{"⌫⌫⌫ayassu"}, {"⌫⌫⌫ayavho"},
{}, -- {"⌫⌫⌫ayataṃ", "⌫aṃ"}, -- 3s needs review
{"⌫⌫⌫ayantaṃ"}
},
optative_active = active_optative_eti,
optative_middle = middle_optative_eti,
participle = {{"⌫⌫⌫ayamāna"}},
},
["ute"] = { -- Actual ending is "oti" when copied to "oti_ute".
{"⌫⌫⌫ve"}, {"⌫⌫⌫umhe"},
{"⌫⌫⌫use"}, {"⌫⌫⌫uvhe"},
{"⌫⌫⌫ute"}, {"⌫⌫⌫unte", "⌫⌫⌫ure"},
mid = "ute",
imperfect = empty,
imperative = {
{"⌫⌫⌫ve"}, {"⌫⌫⌫vāmase"},
{"⌫⌫⌫ussu"}, {"⌫⌫⌫uvho"},
{"⌫⌫⌫utaṃ"}, {"⌫⌫⌫untaṃ"}
-- 1s, 1pl and 3pl will often need manual repair.
},
optative_active = active_optative_ute,
optative_middle = middle_optative_ute,
},
["eyya"] = {
optative_active = { -- '-e' is not included!
{"⌫āmi", "⌫aṃ"}, {"⌫āma"},
{"⌫āsi"}, {"⌫ātha"},
{""}, {"⌫uṃ"}
},
optative_middle = {
{"ṃ"}, {"⌫āmhe"},
{"⌫⌫⌫tho"}, {"vho"},
{"⌫⌫⌫tha"}, {"⌫⌫⌫raṃ"}
},
},
["ā"] = {
optative_active = {
{"mi"}, {"ma"}, {"si"}, {"tha"}, {""}, {"⌫uṃ"}
}
},
["etha"] = {
mid = "etha",
optative_middle = {
{"⌫⌫⌫yyaṃ"}, {"⌫⌫⌫yyāmhe"},
{"⌫o"}, {"⌫⌫⌫yyavho"},
{""}, {"⌫⌫⌫raṃ"}
},
},
["a"] = {
mid="a_attha",
imperfect = {
{"", "ṃ"}, {"mhā"},
{"⌫o"}, {"ttha"},
{"", "⌫ā"}, {"⌫u", "⌫ū"},
}
},
["ā2"] = { -- imperfect form
mid="ā_attha",
imperfect = {
{"⌫a", "⌫aṃ"}, {"⌫amhā"},
{"⌫o"}, {"⌫attha"},
{"⌫a", ""}, {"⌫u", "⌫ū"},
}
},
["attha"] = {
mid = "attha",
imperfect = {
{"⌫⌫⌫⌫⌫iṃ"}, {"⌫⌫⌫⌫⌫āmhase", "⌫⌫⌫⌫mhase"},
{"⌫⌫⌫⌫se"}, {"⌫⌫⌫⌫vhaṃ"}, {""}, {"⌫uṃ"}
}
},
["a_attha"] = {
mid = "a_attha",
imperfect = {
{"⌫iṃ"}, {"⌫āmhase", "mhase"},
{"se"}, {"vhaṃ"}, {"ttha"}, {"tthuṃ"}
}
},
["ā_attha"] = {
mid = "ā_attha",
imperfect = {
{"⌫iṃ"}, {"mhase", "⌫amhase"},
{"⌫ase"}, {"⌫avhaṃ"}, {"⌫attha"}, {"⌫atthuṃ"}
}
},
["i"] = {
mid = nil,
aorist = {{"ṃ"}, {"mha"}, {""}, {"ttha"}, {""}, {"ṃsu"}} -- 3p might be wrong too often
-- However, -ayi seems to consistently yield -ayiṃsu rather than ayuṃ.
},
["esi"] = {
mid = nil,
aorist = {{"ṃ"}, {}, {""}, {}, {""}, {"⌫uṃ"}} -- 3p might be wrong too often
},
["āsi"] = { -- A common mix of sigmatic and thematic aorists!
mid = nil,
aorist = {{"ṃ"}, {"⌫⌫⌫amha", "⌫⌫⌫amhā"}, {""}, {"⌫⌫⌫attha"}, {""}, {"⌫⌫⌫aṃsu"}}
},
}
-- -oti is too different from -ute in some scripts.
pattern.oti_ute = mw.clone(pattern.ute)
pattern.oti_ute.mid = "oti_ute"
pattern.ayati = mw.clone(pattern.ati)
pattern.ayati.mid = "ayate"
-- Lose some of the shorter forms.
pattern.ayati.imperative[3] = {"⌫⌫⌫āhi"}
pattern.ayati.optative_active[1] = {"⌫⌫⌫eyyāmi", "⌫⌫⌫eyyaṃ"}
pattern.ayati.optative_active[3] = {"⌫⌫⌫eyyāsi"}
pattern.ayate = mw.clone(pattern.ate)
pattern.ayate.mid = "ayate"
pattern.ayate.imperative[5] = {} -- {"⌫aṃ", "⌫⌫⌫⌫⌫etaṃ"} -- 3s needs review
pattern.ayate.optative_active = pattern.ayati.optative_active
pattern.ayi = mw.clone(pattern.i)
pattern.ayi.aorist = mw.clone(pattern.i.aorist)
pattern.ayi.aorist[6] = {"ṃsu"}
-- convert Latin script inflections to another script
-- Ⓓ deletes last preposed vowel (for Thai and Lao)
-- Ⓣ toggles last preposed vowel between 'e' and 'o' (for Thai and Lao)
local convert_suffixes = function(stem, nstrip, suffixes, sc, impl, yopt)
local form, pre, stem_pre
local yung, yaa
local xlitend = {}
local strip = string.rep("⌫", nstrip)
local altstem, as1
local option = {impl = impl}
if sc == 'Thai' or sc == 'Laoo' then
altstem = to_script(stem, sc)
stem_pre = match(altstem, "^[เโເໂ]")
as1 = sub(altstem, 1, 1)
if yopt and sc == 'Laoo' then
if yopt == 'yung' or yopt == 'ຍ' then
yung = 1
elseif yopt == 'yaa' or yopt == 'ຢ' then
yaa = 1
elseif yopt == 'both' then
yung = 1 yaa = 1
else
error('Parameter yaa has invalid value "'..yopt..'"')
end
end
end
for k = 1, #suffixes do
xlitend[k] = {}
form = export.joinSuffix('Latn', stem, suffixes[k])
local altforms = {}
for ia, va in pairs(form) do
altform = to_script(va, sc, option)
if yung or yaa then
local y1, y2
if yung then y1 = gsub(altform, 'ຢ', 'ຍ') end
if yaa then y2 = gsub(altform, 'ຍ', 'ຢ') end
if y1 then
table.insert(altforms, y1)
if y2 then
if y1 ~= y2 then table.insert(altforms, y2) end
end
else
table.insert(altforms, y2)
end
else
table.insert(altforms, altform)
end
end
local ib = 1 -- Conversion is not one-to-one!
for ia, altform in pairs(altforms) do
local ibin = ib
-- Special handling is needed for a preposed vowel.
pre = match(altform, "^[เโເໂ]")
if pre then
if stem_pre then
if sub(altform, 1, 1) == as1 then
xlitend[k][ib] = sub(strip, 2) .. sub(altform, 3)
ib = ib + 1
else
-- mw.addWarning("Cannot abstract derivation "..altstem.." > "..altform)
xlitend[k].voi = true
xlitend[k][ib] = sub(strip, 2) .. 'Ⓣ' .. sub(altform, 3)
ib = ib + 1
end -- Don't generate gibberish
else
xlitend[k][ib] = strip .. "↶" .. pre .. sub(altform, 3)
ib = ib + 1
end
else
if stem_pre then
xlitend[k].voi = true
xlitend[k][ib] = sub(strip, 2) .. 'Ⓓ' .. sub(altform, 2)
ib = ib + 1
else
xlitend[k][ib] = strip .. sub(altform, 2)
ib = ib + 1
end
end
-- Add alternative Thai/Lao endings
-- A lot of data is needed to decide whether the disabled logic is needed.
-- Any dead code here must be kept around in case facts later show that it is
-- needed for some spelling variant.
if (sc == 'Thai' or sc == 'Laoo') and impl == 'yes' and ib > ibin then
local altend
if impl=='yes' then
altend = gsub(xlitend[k][ibin], dc("([มวມວ][กฺກ຺])([เโເໂ])([หຫ])"), "%2%1%3")
else
xlitend[k][ibin] = gsub(xlitend[k][ibin], "ัว", "ะว") -- TBC!
altend = gsub(xlitend[k][ibin], dc("([มวມວ])([เโເໂ])([หຫ])"), "%2%1%3")
end
if altend ~= xlitend[k][ibin] then
xlitend[k][ib] = xlitend[k][ibin]
xlitend[k][ibin] = altend
ib = ib + 1
end
end
end
end
return xlitend
end
function export.getSuffixes(sc, ending, tense, option)
local impl = option and option.impl or 'yes'
local yopt = option and option.y
local pat
if not pattern[ending] then
error('No verb pattern for ending "'..ending..'".')
end
if tense then
pat = pattern[ending][tense]
else
pat = pattern[ending]
end
if 'Latn' == sc then
return pat
elseif not pat then
return nil
elseif pat[sc] then
return pat[sc]
else
local olen = {Mymr = 2, Lana = 2} -- Assume NFC
local attha_len = {Latn = 5, Sinh = 4}
eyya_len = {Mymr = 3, Sinh = 5}
local alen
if impl == 'no' and (sc == 'Thai' or sc == 'Laoo') then
alen = 1
else
alen = 0
end
local way = {
["ati"] = {pseudostem = "kati", ndel = 2 + alen},
["ayati"] = {pseudostem = "kayati", ndel = 3 + 2 * alen},
["āti"] = {pseudostem = "kāti", ndel = 3},
["eti"] = {pseudostem = "keti", ndel = 3},
["oti"] = {pseudostem = "soti", ndel = 2 + (olen[sc] or 1)},
["oti_ute"] = {pseudostem = "soti", ndel = 2 + (olen[sc] or 1)},
["ate"] = {pseudostem = "kate", ndel = 2 + alen},
["ayate"] = {pseudostem = "kayate", ndel = 3 + 2 * alen},
["āte"] = {pseudostem = "kāte", ndel = 3},
["ete"] = {pseudostem = "kete", ndel = 3},
["ute"] = {pseudostem = "sute", ndel = 3},
["eyya"] = {pseudostem = "keyya", ndel = eyya_len[sc] or 4},
["ā"] = {pseudostem = "kā", ndel = 1},
["ā2"] = {pseudostem = "kā", ndel = 1},
["a"] = {pseudostem = "ka", ndel = alen},
["a_attha"] = {pseudostem = "ka", ndel = alen},
["ā_attha"] = {pseudostem = "kā", ndel = 1},
["etha"] = {pseudostem = "ketha", ndel = 2 + alen},
["attha"] = {pseudostem = "kattha", ndel = (attha_len[sc] or 3) + alen},
["i"] = {pseudostem = "ki", ndel = 1},
["esi"] = {pseudostem = "kesi", ndel = 3},
["āsi"] = {pseudostem = "kāsi", ndel = 3},
["ayi"] = {pseudostem = "kayi", ndel = 2 + alen},
}
way = way[ending]
if way then
pat[sc] = convert_suffixes(way.pseudostem, way.ndel, pat, sc,
impl, yopt)
if ending == 'etha' then
debug_outer=debug_outer..'tr:'..pat[sc][1][1]
end
else
error('Cannot convert derivations from suffix '..ending..' for '..sc)
end
return pat[sc]
end
end
local function dump_table(name, futargs) -- For debugging only!
for k, v in pairs(futargs) do
local t = type(v)
if t == 'string' then
mw.addWarning(name..'.'..k..'='..v)
elseif t == 'table' then
mw.addWarning(name..'.'..k..' is a table of '..#v)
else
mw.addWarning(name..'.'..k..' is a '..type(v))
end
end
end
local function define_overrides(params, prefix, mod_default)
for _, pn in pairs({"1s", "2s", "3s", "1p", "2p", "3p"}) do
params[prefix.."a"..pn] = {list = true}
params[prefix.."m"..pn] = {list = true}
params[prefix.."a"..pn.."_mod"] = {default = mod_default}
params[prefix.."m"..pn.."_mod"] = {default = mod_default}
end
end
local function addFutureParams(params, mod_default) -- i.e. future specific
params.cond = {list = true} -- Only forms including augment
params.cond_midl = {list = true} -- Only forms including augment
params.cond_voice = {} -- defaults to (corrected) value of voice
params.fap_mod = {default = mod_default}
params.fap = {list = true}
params.fmp_mod = {default = mod_default}
params.fmp = {list = true}
define_overrides(params, 'cond_', mod_default)
end
function export.parse(args)
local mod_default = 'after'
if args.impf_midl and not args.midl then
error("Argument impf_midl may only be used if argument midl is.")
end
local params = {
[1] = {}, -- Just ignore
cite = {list = true},
midl = {list = true},
label = {},
impl = {},
y = {},
aa = {},
showtr = {},
subst = {},
sc = {},
voice = {default = 'both'}, -- Overridden by cite and midl
impf_voice = {default = 'none'},
augment = {default = 'both_made'},
impf = {list = true}, -- Only forms including augment
impf_midl = {list = true}, -- Only forms including augment
impr_voice = {}, -- defaults to (corrected) value of voice
opta_voice = {}, -- defaults to (corrected) value of voice
opta_mod = {default = mod_default},
opta = {list = true},
opta_midl = {list = true},
aori = {list = true},
aor2 = {list = true},
aori_voice = {default = 'act'}, -- paradigms only generate active forms!
aori_augment = {}, -- No default!
aasi = {}, -- Set to 1 to recognise "āsi" as a special ending.
perf = {list = true},
perf_voice = {default = 'both'},
part_voice = {}, -- defaults to (corrected) value of voice
pap_mod = {default = mod_default},
pap = {list = true},
pmp_mod = {default = mod_default},
pmp = {list = true},
-- Options for future system:
futu = {list = true},
futu_midl = {list = true},
futu_voice = {},
cond_augment = {},
futu_part_voice = {},
}
addFutureParams(params, mod_default)
define_overrides(params, '', mod_default)
define_overrides(params, 'impf_', mod_default)
define_overrides(params, 'impr_', mod_default)
define_overrides(params, 'opta_', mod_default)
define_overrides(params, 'aori_', mod_default)
define_overrides(params, 'perf_', mod_default)
-- Options for future system:
define_overrides(params, 'futu_', mod_default)
define_overrides(params, 'cond_', mod_default)
return m_parameters.process(args, params)
end
function export.futureParse(args, subset)
local mod_default = 'after'
if args.cond_midl and not args.midl then
error("Argument cond_midl may only be used if argument midl is.")
end
local params = {
[1] = {}, -- Just ignore
cite = {list = true},
midl = {list = true},
label = {},
impl = {},
y = {},
aa = {},
showtr = {},
subst = {},
sc = {},
voice = {default = 'both'}, -- Overridden by cite and midl
augment = {default = 'with_made'},
part_voice = {} -- defaults to (corrected) value of voice
}
addFutureParams(params, mod_default)
define_overrides(params, '', mod_default)
if subset then -- Lists have already been formed.
define_overrides(params, 'futu_', mod_default)
local futargs = {}
local replaced = {
[1] = 1, cite = 1, midl = 1, voice = 1, augment = 1, part_voice = 1
}
for k, v in pairs(args) do
if params[k] and not replaced[k] then
if type(k) ~= 'string' then
-- Weird! Just skip.
elseif match(k, '^futu_[am][123]') then
futargs[sub(k, 6)] = args[k]
elseif match(k, '^[am][123][sp]') then
-- Don't copy
else
futargs[k] = args[k]
end
end
end
futargs.cite = args.futu
futargs.midl = args.futu_midl
futargs.voice = args.futu_voice or 'both'
futargs.augment = args.cond_augment or
match(args.augment, '^with') and args.augment or 'with_made'
futargs.part_voice = args.futu_part_voice or args.part_voice
-- dump_table('futargs', futargs)
return futargs
else
return m_parameters.process(args, params)
end
end
local arrcat_nodup = m_noun.arrcat_nodup
local function kill_final_vole(stem)
return gsub(stem, "([เโເໂ])([^เโເໂ]*)$", "%2")
end
local function toggle_vo(stem)
local toggle = {["เ"]="โ", ["โ"]="เ", ["ເ"]="ໂ", ["ໂ"]="ເ"}
local function f_toggle(m1, m2) return toggle[m1]..m2 end
return gsub(stem, "([เโເໂ])([^เโເໂ]*)$", f_toggle)
end
function export.joinSuffix(sc, base, pattern, option)
if pattern.voi then
local res = {}
for _,v in ipairs(pattern) do
local forms, rest
local base2 = nil
if match(v, '⌫⌫⌫⌫⌫Ⓓ') then
base2 = kill_final_vole(sub(base, 1, -6))
rest = sub(v,7)
elseif match(v, '⌫⌫⌫⌫Ⓓ') then
base2 = kill_final_vole(sub(base, 1, -5))
rest = sub(v,6)
elseif match(v, '⌫⌫⌫Ⓓ') then
base2 = kill_final_vole(sub(base, 1, -4))
rest = sub(v,5)
elseif match(v, '⌫⌫Ⓓ') then
base2 = kill_final_vole(sub(base, 1, -3))
rest = sub(v,4)
elseif match(v, '⌫Ⓓ') then
base2 = kill_final_vole(sub(base, 1, -2))
rest = sub(v,3)
elseif match(v, 'Ⓓ') then
base2 = kill_final_vole(sub(base, 1, -1))
rest = sub(v,2)
elseif match(v, '⌫⌫⌫⌫⌫Ⓣ') then
base2 = toggle_vo(sub(base, 1, -6))
rest = sub(v,7)
elseif match(v, '⌫⌫⌫⌫Ⓣ') then
base2 = toggle_vo(sub(base, 1, -5))
rest = sub(v,6)
elseif match(v, '⌫⌫⌫Ⓣ') then
base2 = toggle_vo(sub(base, 1, -4))
rest = sub(v,5)
elseif match(v, '⌫⌫Ⓣ') then
base2 = toggle_vo(sub(base, 1, -3))
rest = sub(v,4)
elseif match(v, '⌫Ⓣ') then
base2 = toggle_vo(sub(base, 1, -2))
rest = sub(v,3)
elseif match(v, 'Ⓣ') then
base2 = toggle_vo(sub(base, 1, -1))
rest = sub(v,2)
end
if base2 then
forms = m_noun.joinSuffix(sc, base2, {rest})
else
forms = m_noun.joinSuffix(sc, base, {v})
end
res = arrcat_nodup(res, forms)
end
return res
elseif pattern.kill_final_preposed then
return m_noun.joinSuffix(sc, kill_final_vole(base), pattern, option)
else
return m_noun.joinSuffix(sc, base, pattern, option)
end
end
function export.joinSuffixes(scriptCode, stem, pattern, option)
local forms = {}
for i = 1, 6 do
forms[i] = export.joinSuffix(scriptCode, stem, pattern[i], option)
end
return forms
end
function export.modify_voice(forms, prefix, args)
-- Only null action is implemented.
for i, pn in pairs({"1s", "1p", "2s", "2p", "3s", "3p"}) do
local flag = pn..'_mod'
if #args[pn] > 0 then
if args[flag] == 'after' then
forms[i] = arrcat_nodup(forms[i], args[pn])
forms.isnil = false
elseif args[flag] == 'replace' then
forms[i] = args[pn]
forms.isnil = false
elseif args[flag] == 'before' then
forms[i] = arrcat_nodup(args[pn], forms[i])
forms.isnil = false
elseif args[flag] == 'blank' then
forms[i] = {}
else
error('Argument '..prefix..pn..' has invalid value '..args[flag])
end
elseif args[flag] == 'blank' then
forms[i] = {}
end
end
end
function export.modify_voice(forms, prefix, args)
for i, pn in pairs({"1s", "1p", "2s", "2p", "3s", "3p"}) do
local flag = pn..'_mod'
local added = nil;
if args[pn] and #args[pn] > 0 then
added = true;
if args[flag] == 'after' then
forms[i] = arrcat_nodup(forms[i], args[pn])
forms.isnil = false
elseif args[flag] == 'replace' then
forms[i] = args[pn]
forms.isnil = false
elseif args[flag] == 'before' then
forms[i] = arrcat_nodup(args[pn], forms[i])
forms.isnil = false
elseif args[flag] == 'blank' then
forms[i] = {}
added = nil;
else
error('Argument '..prefix..pn..' has invalid value '..args[flag])
end
if added and (i == 2) then forms.add1p = true end
elseif args[flag] == 'blank' then
forms[i] = {}
end
end
end
function export.present(cite, tense, formsa, formsm)
local rows = {"1st", "2nd", "3rd"}
local forms1
local output = {}
ti(output, '<div class="NavFrame" style="min-width:30%">'..
'<div class="NavHead" style="background:#d9ebff">'..tense..
' forms of "' .. cite .. '"' ..'</div><div class="NavContent">')
ti(output,
'<table class="inflection-table" style="background:#F9F9F9;'..
'text-align:center;width:100%">')
if formsa and formsm then
ti(output, '<tr style="background:#eff7ff"><th></th><th colspan=2>Active</th><th colspan=2>Middle</th></tr>')
ti(output, '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th><th>Singular</th><th>Plural</th></tr>')
for i,v in ipairs(rows) do
if #formsa[2*i-1] > 0 or #formsa[2*i] > 0 or #formsm[2*i-1] > 0 or #formsm[2*i] > 0 then
ti(output, "<tr><th style=\"background-color:#eff7ff;\">" .. v .. "</th>")
ti(output, "<td>" .. m_noun.orJoin(currentScript, formsa[2 * i - 1]) .. "</td>")
ti(output, "<td>" .. m_noun.orJoin(currentScript, formsa[2 * i]) .. "</td>")
ti(output, "<td>" .. m_noun.orJoin(currentScript, formsm[2 * i - 1]) .. "</td>")
ti(output, "<td>" .. m_noun.orJoin(currentScript, formsm[2 * i]) .. "</td>")
ti(output, "</tr>")
end
end
else
if formsa then
forms1 = formsa
else
forms1 = formsm
end
ti(output, '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th></tr>')
for i,v in ipairs(rows) do
if #forms1[2*i-1] > 0 or #forms1[2*i] > 0 then
ti(output, "<tr><td style=\"background-color:#eff7ff;\">" .. v .. "</td>")
ti(output, "<td>" .. m_noun.orJoin(currentScript, forms1[2 * i - 1]) .. "</td>")
ti(output, "<td>" .. m_noun.orJoin(currentScript, forms1[2 * i]) .. "</td>")
ti(output, "</tr>")
end
end
end
ti(output, "</table></div></div>")
return table.concat(output)
end
-- Basic form of augment:
local augment = {
Latn="a",
Thai="อ",
Deva="अ",
Beng="অ",
Mymr="အ",
Lana="ᩋ",
Khmr="អ",
Sinh="අ",
Brah="𑀅",
Laoo="ອ",
Cakm="𑄃",
}
local augment_alph= {
Thai = "อะ",
Laoo = "ອະ"
}
local enda3s = {
Latn="ti",
Thai="ติ",
Deva="ति",
Beng="তি",
Mymr="တိ",
Lana="ᨲᩥ",
Khmr="តិ",
Sinh="ති",
Brah="𑀢𑀺",
Laoo="ຕິ",
Cakm="𑄖𑄨",
}
local function select_args(old, prefix) -- prefix must be in ASCII
local new = {}
local pattern = '^'..prefix
local follow = string.len(pattern)
for i, v in pairs(old) do
if string.match(i,pattern) then
new[asub(i, follow)] = v
end
end
return new
end
function export.modify(formsa, formsm, prefix, args)
local subprefix
if not formsa then formsa = {{}, {}, {}, {}, {}, {}, isnil=true} end
subprefix = prefix..'a'
export.modify_voice(formsa, subprefix, select_args(args,subprefix))
if formsa.isnil then formsa = nil end
if not formsm then formsm = {{}, {}, {}, {}, {}, {}, isnil=true} end
subprefix = prefix..'m'
export.modify_voice(formsm, subprefix, select_args(args,subprefix))
if formsm.isnil then formsm = nil end
return formsa, formsm
end
local hike = true -- Whether heading for voices and numbers should be in common for tables.
local function rows2v(currentScript, tense, formsa, formsm, x0)
local rows = {"1st", "2nd", "3rd"}
local output = {}
formsa = formsa or empty
formsm = formsm or empty
ti(output, '<tr style="background:#d9ebff"><th colspan=5>'..tense..'</th></tr>')
if not hike then
ti(output, '<tr style="background:#eff7ff"><th></th><th colspan=2>Active</th><th colspan=2>Middle</th></tr>')
ti(output, '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th><th>Singular</th><th>Plural</th></tr>')
end
for i,v in ipairs(rows) do
if #formsa[2*i-1] > 0 or #formsa[2*i] > 0 or #formsm[2*i-1] > 0 or #formsm[2*i] > 0 then
ti(output, "<tr><th style=\"background-color:#eff7ff;\">" .. v .. "</th>")
ti(output, "<td>")
ti(output, m_noun.orJoin(currentScript, formsa[2 * i - 1], x0))
ti(output, "</td>")
ti(output, "<td>")
ti(output, m_noun.orJoin(currentScript, formsa[2 * i], x0))
ti(output, "</td>")
ti(output, "<td>")
ti(output, m_noun.orJoin(currentScript, formsm[2 * i - 1], x0))
ti(output, "</td>")
ti(output, "<td>")
ti(output, m_noun.orJoin(currentScript, formsm[2 * i], x0))
ti(output, "</td>")
ti(output, "</tr>")
end
end
return table.concat(output)
end
local function rows1v(currentScript, tense, formsa, formsm, xo)
local rows = {"1st", "2nd", "3rd"}
local output = {}
local forms1 = formsa or formsm or empty
ti(output, '<tr style="background:#d9ebff"><th colspan=3>'..tense..'</th></tr>')
if not hike then
ti(output, '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th></tr>')
end
for i,v in ipairs(rows) do
if #forms1[2*i-1] > 0 or #forms1[2*i] > 0 then
ti(output, "<tr><td style=\"background-color:#eff7ff;\">")
ti(output, v)
ti(output, "</td>")
ti(output, "<td>")
ti(output, m_noun.orJoin(currentScript, forms1[2 * i - 1], xo))
ti(output, "</td>")
ti(output, "<td>")
ti(output, m_noun.orJoin(currentScript, forms1[2 * i], xo))
ti(output, "</td>")
ti(output, "</tr>")
end
end
return table.concat(output)
end
function export.present_conj(label, currentScript, parts, xo)
local output = {}
parts.cat = parts.cat or {}
local havea = parts.presa or parts.impra or parts.impfa or parts.optaa
local havea = havea or parts.aoria or parts.futua or parts.conda or parts.perfa
local havem = parts.presm or parts.imprm or parts.impfm or parts.optam
havem = havem or parts.aorim or parts.futum or parts.condm or parts.perfa
local have2 = parts.presa and parts.presm or parts.impra and parts.imprm or
parts.impfa and parts.impfm or parts.optaa and parts.optam or
parts.aoria and parts.aorim or parts.futua and parts.futum or
parts.conda and parts.condm or parts.perfa and parts.perfm
ti(output, '<div class="NavFrame" style="min-width:30%">'..
'<div class="NavHead" style="background:#d9ebff">'..
'Conjugation of "' .. label .. '"</div><div class="NavContent">')
ti(output, '<table class="inflection-table" style="background:#F9F9F9;'..
'text-align:center;width:100%">')
if have2 then
if hike then
ti(output, '<tr style="background:#eff7ff"><th></th><th colspan=2>Active</th><th colspan=2>Middle</th></tr>')
ti(output, '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th><th>Singular</th><th>Plural</th></tr>')
end
if parts.presa or parts.presm then
ti(output, rows2v(currentScript, 'Present', parts.presa, parts.presm, xo))
end
if parts.impfa or parts.impfm then
ti(output, rows2v(currentScript, 'Imperfect', parts.impfa, parts.impfm, xo))
end
if parts.impra or parts.imprm then
ti(output, rows2v(currentScript, 'Imperative', parts.impra, parts.imprm, xo))
end
if parts.optaa or parts.optam then
ti(output, rows2v(currentScript, 'Optative', parts.optaa, parts.optam, xo))
end
if parts.aoria or parts.aorim then
ti(output, rows2v(currentScript, 'Aorist', parts.aoria, parts.aorim, xo))
end
if parts.futua or parts.futum then
ti(output, rows2v(currentScript, 'Future', parts.futua, parts.futum, xo))
end
if parts.conda or parts.condm then
ti(output, rows2v(currentScript, 'Conditional', parts.conda, parts.condm, xo))
end
if parts.perfa or parts.perfm then
ti(output, rows2v(currentScript, 'Perfect', parts.perfa, parts.perfm, xo))
end
else
if hike then
ti(output, '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th></tr>')
end
if parts.presa or parts.presm then
ti(output, rows1v(currentScript, 'Present', parts.presa, parts.presm, xo))
end
if parts.impfa or parts.impfm then
ti(output, rows1v(currentScript, 'Imperfect', parts.impfa, parts.impfm, xo))
end
if parts.impra or parts.imprm then
ti(output, rows1v(currentScript, 'Imperative', parts.impra, parts.imprm, xo))
end
if parts.optaa or parts.optam then
ti(output, rows1v(currentScript, 'Optative', parts.optaa, parts.optam, xo))
end
if parts.aoria or parts.aorim then
ti(output, rows1v(currentScript, 'Aorist', parts.aoria, parts.aorim, xo))
end
if parts.futua or parts.futum then
ti(output, rows1v(currentScript, 'Future', parts.futua, parts.futum, xo))
end
if parts.conda or parts.condm then
ti(output, rows1v(currentScript, 'Conditional', parts.conda, parts.condm, xo))
end
if parts.perfa or parts.perfm then
ti(output, rows1v(currentScript, 'Perfect', parts.perfa, parts.perfm, xo))
end
end
if parts.conda or parts.condm then
ti(parts.cat, "[[category:Pali verbs exhibiting conditional mood]]")
if parts.conda and parts.conda.add1p then
ti(parts.cat, "[[category:Pali verbs with manual 1p conditional]]")
end
end
ti(output, "</table></div></div>")
if parts.pap and #parts.pap > 0 then
table.insert(output, '\n* Present active participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.pap, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.pmp and #parts.pmp > 0 then
table.insert(output, '\n* Present middle participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.pmp, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.fap and #parts.fap > 0 then
table.insert(output, '\n* Future active participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.fap, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.fmp and #parts.fmp > 0 then
table.insert(output, '\n* Future middle participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.fmp, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.debug then table.insert(output, parts.debug) end
if parts.cat then ti(output, table.concat(parts.cat)) end
return table.concat(output)
end
function export.present_special_oldway(label, currentScript, parts, xo)
output = {}
parts.cat = parts.cat or {}
if parts.presa or parts.presm then
table.insert(output, export.present(label, 'Present', parts.presa, parts.presm, xo))
end
if parts.impfa or parts.impfm then
table.insert(output, export.present(label, 'Imperfect', parts.impfa, parts.impfm, xo))
end
if parts.impra or parts.imprm then
table.insert(output, export.present(label, 'Imperative', parts.impra, parts.imprm, xo))
end
if parts.optaa or parts.optam then
table.insert(output, export.present(label, 'Optative', parts.optaa, parts.optam, xo))
end
if parts.futua or parts.futum then
ti(output, export.present(label, 'Future', parts.futua, parts.futum, xo))
end
if parts.conda or parts.condm then
ti(output, export.present(label, 'Conditional', parts.conda, parts.condm, xo))
ti(parts.cat, "[[category:Pali verbs exhibiting conditional mood]]")
if parts.conda and parts.conda.add1p then
ti(parts.cat, "[[category:Pali verbs with manual 1p conditional]]")
end
end
if parts.pap and #parts.pap > 0 then
table.insert(output, '\n* Present active participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.pap, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.pmp and #parts.pmp > 0 then
table.insert(output, '\n* Present middle participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.pmp, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.fap and #parts.fap > 0 then
table.insert(output, '\n* Future active participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.fap, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.fmp and #parts.fmp > 0 then
table.insert(output, '\n* Future middle participle: ')
table.insert(output, m_noun.orJoin(currentScript, parts.fmp, xo))
table.insert(output, ', which see for forms and usage')
end
if parts.debug then table.insert(output, parts.debug) end
if parts.cat then ti(output, table.concat(parts.cat)) end
return table.concat(output)
end
function export.present_future(label, currentScript, parts, xo)
if true then -- Newer table format
return export.present_conj(label, currentScript, parts, xo)
else
return export.present_special_oldway(label, currentScript, parts, xo)
end
end
function export.present_special(label, currentScript, parts, xo)
if true then -- Newer table format
return export.present_conj(label, currentScript, parts, xo)
else
return export.present_special_oldway(label, currentScript, parts, xo)
end
end
function export.special_forms(cite, args)
local currentScript = lang:findBestScript(cite)
local scriptCode = currentScript:getCode()
local latinise = nil
if scriptCode == "None" and args.sc then -- Resort to sc
scriptCode = args["sc"]
currentScript = m_scripts.getByCode(scriptCode, "No such script as ".. scriptCode .. ".")
latinise = currentScript
augment[scriptCode] = to_script("a", scriptCode)
end
args = export.parse(args)
args.cite = arrcat_nodup({cite}, args.cite)
local debug = '\n\nAt (1), args.cite = '..table.concat(args.cite, ' ')
local patpa, patpm, basepa, basepm
local parts = {}
local option = {}
option.aa = args.aa
-- Handle present tense. This forms a base for others.
local ending = export.detectEnding(cite, latinise)
-- mw.addWarning('ending='..ending)
patpa = export.getSuffixes(scriptCode, ending, nil, args)
basepa = cite
local mset = nil
local forBoth = false
local aset = args.cite
local voice = "both"
if 'e' == asub(ending, -1) then -- No active inflection
patpm = patpa
patpa = nil
basepm = cite
aset = nil
mset = args.cite
voice = "midl"
elseif args.midl and args.midl[1] then
basepm = args.midl[1]
mset = args.midl
local midend = export.detectEnding(basepm, latinise)
patpm = pattern[midend].mid and
export.getSuffixes(scriptCode, pattern[midend].mid, nil, args)
elseif args.voice == 'act' then
patpm = nil
voice = "act"
else
patpm = pattern[ending].mid and
export.getSuffixes(scriptCode, pattern[ending].mid, nil, args)
basepm = cite
forBoth = true
mset = args.cite
end
local formsa = nil
local formsm = nil
if patpa then
formsa = export.joinSuffixes(scriptCode, basepa, patpa, option)
for k = 2, #aset do
basepa = aset[k]
patpa = export.getSuffixes(
scriptCode, export.detectEnding(basepa, latinise), nil, args)
local extras = export.joinSuffixes(scriptCode, basepa, patpa, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
end
end
if patpm or forBoth then
if patpm then
formsm = export.joinSuffixes(scriptCode, basepm, patpm, option)
else
formsm = {{}, {}, {}, {}, {}, {}}
end
for k = 2, #mset do
basepm = mset[k]
local kend = export.detectEnding(basepm, latinise)
kend = pattern[kend].mid
if kend then
patpm = export.getSuffixes(scriptCode, kend, nil, args)
local extras = export.joinSuffixes(scriptCode, basepm, patpm, option)
for ip = 1, 6 do
formsm[ip] = arrcat_nodup(formsm[ip], extras[ip])
end
end
end
end
if args.voice == "act" or args.voice == "both" then
-- handled already
elseif args.voice == "none" then
formsa = nil
formsm = nil
voice = "none"
elseif args.voice then
error('Argument voice has bad value "'..args.voice..'.')
end
formsa, formsm = export.modify(formsa, formsm, '', args)
parts.presa = formsa
parts.presm = formsm
-- Form imperative from present
formsa = nil
formsm = nil
local imperativeVoice = args.impr_voice or voice
if imperativeVoice == 'act' or imperativeVoice == 'both' then
local patma, kend
formsa = {{}, {}, {}, {}, {}, {}}
for k = 1, #aset do
kend = export.detectEnding(aset[k], latinise)
patma = export.getSuffixes(scriptCode, kend, 'imperative', args)
if patma then
local extras = export.joinSuffixes(scriptCode, aset[k], patma, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
end
end
end
if imperativeVoice == 'midl' or imperativeVoice == 'both' then
local patmm
formsm = {{}, {}, {}, {}, {}, {}}
local nstem, form3s
if forBoth then
nstem = #aset
else
nstem = #mset
end
for k = 1, nstem do
form3s = mset[k]
local kend = export.detectEnding(form3s, latinise)
if pattern[kend].mid then
kend = pattern[kend].mid
elseif kend == "eti" then
kend = nil
else
error('No middle endings for ending "'..kend..'".')
kend = nil
end
patmm = kend and export.getSuffixes(scriptCode, kend, 'imperative', args)
if patmm then
local extras = export.joinSuffixes(scriptCode, form3s, patmm, option)
for ip = 1, 6 do
formsm[ip] = arrcat_nodup(formsm[ip], extras[ip])
end
end
end
end
debug = debug..'\n\nAt (8), formsa='..tostring(formsa)
formsa, formsm = export.modify(formsa, formsm, 'impr_', args)
if formsa then
debug = debug..'\n\nAt (9), formsa='..tostring(formsa)..
' formsa.isnil='..tostring(formsa.isnil)
else
debug = debug..'\n\nAt (9), formsa='..tostring(formsa)
end
parts.impra = formsa
parts.imprm = formsm
-- Form imperfect from present. Existence defaults to false for both voices.
local aug
if args["impl"] == 'no' then
aug = augment_alph[scriptCode] or augment[scriptCode]
else
aug = augment[scriptCode]
end
-- error("impl="..tostring(args["impl"]).." aug="..aug)
local impf = {}
if (args.impf_voice ~= 'none') then
if args.augment == 'without' then
impf = aset or {}
elseif args.augment == 'with_made' then
if aset then
for k = 1, #aset do
impf[k] = aug .. aset[k]
end
end
elseif args.augment == 'with_given' then
impf = args.impf
elseif args.augment == 'both_made' then
if aset then
for k = 1, #aset do
impf[k] = aug .. aset[k]
end
for k = 1, #aset do
impf[#aset+k] = aset[k]
end
end
elseif args.augment == 'both_given' then
impf = arrcat_nodup(args.impf or {}, aset or {})
else
error('Argument augment has bad value "'..args.augment..'".')
end
end
if (args.impf_voice == 'both' or args.impf_voice == 'act')
-- and (voice == 'both' or voice == 'act')
then
formsa = {{}, {}, {}, {}, {}, {}}
for k = 1, #impf do
kend = export.detectEnding(impf[k], latinise)
if kend == "ā" then kend = "ā2" end
patma = export.getSuffixes(scriptCode, kend, 'imperfect', args)
if true then -- Make false for debugging.
elseif patma == nil or patma[5] == nil or patma[5][1] == nil then
mw.addWarning('impf['..k..']='..impf[k]..' kend='..kend..' patma[5][1]=nil')
else
mw.addWarning('impf['..k..']='..impf[k]..' kend='..kend..' patma[5][1]='..patma[5][1])
end
if patma then
local extras = export.joinSuffixes(scriptCode, impf[k], patma, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
end
end
elseif (args.impf_voice == 'none' or args.impf_voice == 'midl') then
formsa = nil
else
error('Argument impf_voice has bad value "'..args.impf_voice..'".')
end
if (args.impf_voice == 'both' or args.impf_voice == 'midl')
-- and (voice == 'both' or voice == 'midl')
then
formsm = {{}, {}, {}, {}, {}, {}}
if not forBoth then
impf = {}
if args.augment == 'without' then
impf = mset
elseif args.augment == 'with_made' then
for k = 1, #mset do
impf[k] = aug .. mset[k]
end
elseif args.augment == 'with_given' then
impf = args.midl and args.midl[1] and args.impf_midl or args.midl
elseif args.augment == 'both_made' then
for k = 1, #mset do
impf[k] = aug .. mset[k]
end
for k = 1, #mset do
impf[#mset+k] = mset[k]
end
elseif args.augment == 'both_given' then
impf = arrcat_nodup(
args.midl and args.midl[1] and (args.impf_midl or {}) or
args.impf or {},
mset or {})
else
error('Argument augment has bad value "'..args.augment..'".')
end
end
for k = 1, #impf do
kend = export.detectEnding(impf[k], latinise)
debug=debug..'\n\nAt (7) impf[k]='..impf[k]
if kend == "ā" then kend = "ā2" end
if forBoth then
if pattern[kend].mid then
kend = pattern[kend].mid
elseif kend == "eti" then
kend = nil
else
error('No middle endings for ending "'..kend..'".')
kend = nil
end
end
local pat = kend and export.getSuffixes(scriptCode, kend, 'imperfect', args)
if not kend then
-- nothng to do
elseif pat then
local extras = export.joinSuffixes(scriptCode, impf[k], pat, option)
for ip = 1, 6 do
formsm[ip] = arrcat_nodup(formsm[ip], extras[ip])
end
else
mw.addWarning('No imperfect middle suffixes for '..impf[k]..
' ('..kend..')')
end
end
else
formsm = nil
end
formsa, formsm = export.modify(formsa, formsm, 'impf_', args)
parts.impfa = formsa
parts.impfm = formsm
-- Form optative from present citation forms.
args.opta_voice = args.opta_voice or voice
debug = debug .. '\n\nAt (2), args.cite = '..table.concat(args.cite, ' ')
local opta = args.cite
debug = debug .. '\n\nAt (3), opta = '..table.concat(opta, ' ')
if args.opta then
debug = debug..'\n\nAt (4), args.opta='..table.concat(args.opta)..', args.opta_mod='..args.opta_mod
if args.opta_mod == 'replace' then
opta = args.opta
elseif args.opta_mod == 'after' then
opta = arrcat_nodup(opta, args.opta)
elseif args.opta_mod == 'before' then
opta = arrcat_nodup(args.opta, opta)
elseif args.opta_mod == 'blank' then
args.opta_voice = 'none'
else
error('Argument opta_mod has bad value "'..args.opta_mode..'".')
end
end
debug = debug .. '\n\nAt (5), opta = '..table.concat(opta, ' ')..
', args.opta_voice='..args.opta_voice
if args.opta_voice == 'both' or args.opta_voice == 'act' then
formsa = {{}, {}, {}, {}, {}, {}}
local kend, patma
for k = 1, #opta do
kend = export.detectEnding(opta[k], latinise)
patma = export.getSuffixes(scriptCode, kend, 'optative_active', args)
if true then -- Make false for debugging.
elseif patma == nil or patma[5] == nil or patma[5][1] == nil then
mw.addWarning('opta['..k..']='..opta[k]..' kend='..kend..' patma[5][1]=nil')
else
mw.addWarning('opta['..k..']='..opta[k]..' kend='..kend..' patma[5][1]='..patma[5][1])
end
if patma then
local extras = export.joinSuffixes(scriptCode, opta[k], patma, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
end
end
elseif args.opta_voice == 'midl' or args.opta_voice == 'none' then
formsa = nil
else
error('Argument opta_voice has bad value "'..args.opta_voice..'".')
end
if #args.opta_midl > 0 then opta = args.opta_midl end
formsm = nil
if args.opta_voice == 'both' or args.opta_voice == 'midl' then
formsm = {{}, {}, {}, {}, {}, {}}
local kend, patma
debug=debug..'\n\nAt (6), opta='..table.concat(opta)
for k = 1, #opta do
kend = export.detectEnding(opta[k], latinise)
patma = export.getSuffixes(scriptCode, kend, 'optative_middle', args)
if patma then
local extras = export.joinSuffixes(scriptCode, opta[k], patma, option)
for ip = 1, 6 do
formsm[ip] = arrcat_nodup(formsm[ip], extras[ip])
end
else
debug = debug.."\n\nNo "..kend..".optative_middle"
end
end
else
formsm = nil
end
formsa, formsm = export.modify(formsa, formsm, 'opta_', args)
parts.optaa = formsa
parts.optam = formsm
-- Generate aorist forms - currently only from aorist specific parameters.
formsa = nil
formsm = nil
if args.aori and #args.aori > 0 or args.aor2 and #args.aor2 > 0 then
local flags = {}
flags.aasi = args.aasi
formsa = { {}, {}, {}, {}, {}, {} }
local aori = {} -- List of *aorist* 3s. Cannnot tell -ati from -i!
for k = 1, #(args.aor2 or {}) do
aori[k] = aug .. args.aor2[k]
end
aori = arrcat_nodup(aori, args.aor2 or {})
aori = arrcat_nodup(aori, args.aori)
for k = 1, #aori do
local kend = export.detectAoristEnding(aori[k], latinise, flags)
if kend == "āsi" then
parts.cat = parts.cat or {}
ti(parts.cat, "[[category:Pali verbs with aorist in -āsi/-a]]")
end
local patma = export.getSuffixes(scriptCode, kend, 'aorist', args)
if patma then
local extras = export.joinSuffixes(scriptCode, aori[k], patma, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
else
debug = debug.."\n\nNo "..kend..".aorist"
end
end
if #formsa[1] == 0 and #formsa[2] == 0 and #formsa[3] == 0 and
#formsa[4] == 0 and #formsa[5] == 0 and #formsa[6] == 0 then
formsa = nil
end
end
parts.aoria, parts.aorim = export.modify(formsa, formsm, 'aori_', args)
-- Generate perfect tense by write in
formsa = nil
formsm = nil
parts.perfa, parts.perfm = export.modify(formsa, formsm, 'perf_', args)
-- List present participles.
local pap, pmp = {}, {}
args.part_voice = args.part_voice or voice
if args.part_voice == 'both' or args.part_voice == 'act' then
if voice == 'both' or voice == 'act' then
for k = 1, aset and #aset or 0 do
local kend = export.detectEnding(aset[k], latinise)
local pat = kend and export.getSuffixes(scriptCode, kend, "participle", args)
if pat then
local extra = export.joinSuffix(scriptCode, aset[k], pat[1])
pap = arrcat_nodup(pap, extra)
end
end
end
if args.pap_mod == 'blank' then
pap = {}
elseif args.pap_mod == 'after' then
pap = arrcat_nodup(pap, args.pap)
elseif args.pap_mod == 'before' then
pap = arrcat_nodup(args.pap, pap)
elseif args.pap_mod == 'replace' then
pap = args.pap
else
error('Argument pap_mod has invalid value '..args.pap_mod)
end
parts.pap = pap
elseif args.part_voice == 'midl' or args.part_voice == 'none' then
-- permissible
else
error('Argument part_voice has invalid value '..args.part_voice)
end
if args.part_voice == 'both' or args.part_voice == 'midl' then
local list
local from_active = forBoth or voice == 'act'
if from_active then
list = aset
else
list = mset
end
for k = 1, list and #list or 0 do
local kend = export.detectEnding(list[k], latinise)
if from_active then kend = pattern[kend].mid end
local pat = kend and export.getSuffixes(scriptCode, kend, "participle", args)
if pat then
local extra = export.joinSuffix(scriptCode, list[k], pat[1])
pmp = arrcat_nodup(pmp, extra)
end
end
if args.pmp_mod == 'blank' then
pmp = {}
elseif args.pmp_mod == 'after' then
pmp = arrcat_nodup(pmp, args.pmp)
elseif args.pmp_mod == 'before' then
pmp = arrcat_nodup(args.pmp, pmp)
elseif args.pmp_mod == 'replace' then
pmp = args.pmp
else
error('Argument pmp_mod has invalid value '..args.pmp_mod)
end
parts.pmp = pmp
end
-- parts.debug = debug..'\n\n'..debug_outer
return parts
end
function export.show(frame)
local args = mw.clone(frame:getParent().args)
local cite = args[1] or args["cite"] or mw.title.getCurrentTitle().text
local currentScript = lang:findBestScript(cite)
local xo = {impl = args.impl, y = args.y, showtr = args.showtr, subst = args.subst}
local parts = export.special_forms(cite, args)
parts.cat = parts.cat or {}
if args.futu then
local fuparts = export.future_forms(args.futu, args, true)
fuparts.cat = fuparts.cat or {}
for k, v in pairs(fuparts) do
if k == 'cat' then
parts.cat = arrcat_nodup(parts.cat, fuparts.cat)
else
parts[k] = fuparts[k]
end
end
-- dump_table('parts', parts)
end
local label = args.label or cite
return export.present_special(label, currentScript, parts, xo)
end
function export.detectFutureEnding(cite3s, latinise)
if latinise then
local cfin = cite3s
cite3s = (lang:transliterate(cfin, latinise))
end
local len, wordEnd
local ending
for len = 6, 1, -1 do
wordEnd = sub(cite3s, -len)
ending = future_endings[wordEnd]
if not ending then
-- Try again
else
-- debug_outer = debug_outer..'\n'..cite3s..'='..ending..'\n'
return ending
end
end
-- debug_outer = debug_outer..'\n'..cite3s..'='.."a"..'\n'
return "a"
end
local future_pattern = {
["ati"] = {
{"⌫⌫⌫āmi"}, {"⌫⌫⌫āma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫nti"},
mid = "ate",
conditional = {
{"⌫⌫ṃ"}, -- Collins also has 1s {"⌫⌫⌫āmi"}
{}, -- Kaccayano, Aggavamsa and Duroiselle have -amhā
-- while Warder and Collins have -āma.
-- {"⌫⌫mhā", "⌫⌫⌫āma"}, -- We need to gather evidence and then decide.
{"⌫⌫", "⌫⌫⌫i"}, {"⌫ha"}, -- Duroiselle also has 2s "⌫⌫⌫e", which Collins says is middle.
{"⌫⌫⌫ā", "⌫⌫"}, {"⌫⌫ṃsu"}, -- Duroiselle also has 3s as in future.
},
participle = {{"⌫⌫nt"}},
},
["ate"] = { -- Also services "ati"
{"⌫⌫ṃ"}, {"⌫⌫⌫āmhe"}, {"⌫⌫se"}, {"⌫⌫vhe"}, {"⌫e"}, {"⌫⌫nte"},
conditional = {
{"⌫⌫ṃ"}, {"⌫⌫⌫āmhase"},
{"⌫⌫⌫e", "⌫⌫se"}, {"⌫⌫vhe"}, -- Duroiselle has first 2s as active.
{"⌫ha"}, {"⌫⌫⌫iṃsu"},
},
participle = {{"⌫⌫māna", "⌫⌫⌫āna"}},
mid = "ate"
},
["ā"] = {
conditional = {
{"⌫aṃ"}, -- Collins also has 1s {"mi"}
{}, -- {"⌫amhā", "ma"}, -- See above for controversy.
{"⌫a", "⌫i"}, {"⌫atha"}, -- Duroiselle also has 2s "⌫⌫⌫e", which Collins says is middle.
{"", "⌫a"}, {"⌫aṃsu"}, -- Duroiselle also has 3s as in future.
},
mid = "atha_for_aa",
},
["a"] = {
conditional = {
{"ṃ"}, -- Collins also has 1s {"āmi"}
{}, -- {"mhā", "⌫āma"}, -- See above for controversy.
{"", "⌫i"}, {"tha"}, -- Duroiselle also has 2s "⌫⌫⌫e", which Collins says is middle.
{"⌫ā", ""}, {"ṃsu"}, -- Duroiselle also has 3s as in future.
},
mid = "atha_for_a",
},
["atha"] = {
conditional = {
{"⌫⌫⌫ṃ"}, {"⌫⌫⌫⌫āmhase"},
{"⌫⌫⌫⌫e", "⌫⌫⌫se"}, {"⌫⌫⌫vhe"}, -- Duroiselle has first 2s as active.
{""}, {"⌫⌫⌫⌫iṃsu"},
},
mid = "atha"
},
["atha_for_a"] = {
conditional = {
{"ṃ"}, {"⌫āmhase"},
{"⌫e", "se"}, {"vhe"}, -- Duroiselle has first 2s as active.
{"tha"}, {"⌫iṃsu"},
},
mid = "atha_for_a"
},
atha_for_aa = {
conditional = {
{"⌫aṃ"}, {"mhase"},
{"⌫e", "⌫ase"}, {"⌫avhe"}, -- Duroiselle has first 2s as active.
{"⌫atha"}, {"⌫iṃsu"},
},
mid = "atha_for_aa"
},
iti = {
{"⌫⌫⌫āmi"}, {"⌫⌫⌫āma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫nti"},
mid = "void"
},
heti = {
{"⌫⌫mi"}, {"⌫⌫ma"}, {"⌫⌫si"}, {"⌫ha"}, {""}, {"⌫⌫nti"},
mid = "void"
},
["kāhiti"] = {
{"⌫⌫⌫āmi"}, {"⌫⌫⌫āma"}, {"⌫⌫si"}, {}, {""}, {"⌫⌫nti"},
mid = "void"
},
void = { {}, {}, {}, {}, {}, {}, mid = "void"}
}
-- convert Latin script inflections to another script
-- ⒹⓉ
function export.getFutureSuffixes(sc, ending, tense, option)
local impl = option and option.impl or 'yes'
local yopt = option and option.y
local pat
if not future_pattern[ending] then
error('No verb pattern for ending "'..ending..'".')
end
if tense then
pat = future_pattern[ending][tense]
else
pat = future_pattern[ending]
end
if 'Latn' == sc then
return pat
elseif not pat then
return nil
elseif pat[sc] then
return pat[sc]
else
local olen = {Mymr = 2, Lana = 2} -- Assume NFC
local attha_len = {Latn = 5, Sinh = 4}
eyya_len = {Mymr = 3, Sinh = 5}
local alen
if impl == 'no' and (sc == 'Thai' or sc == 'Laoo') then
alen = 1
else
alen = 0
end
local way = {
["ati"] = {pseudostem = "kati", ndel = 2 + alen},
["heti"] = {pseudostem = "heti", ndel = 3}, -- Tricky code
["iti"] = {pseudostem = "kiti", ndel = 3},
["ate"] = {pseudostem = "kate", ndel = 2 + alen},
["ā"] = {pseudostem = "kā", ndel = 1},
["a"] = {pseudostem = "ka", ndel = alen},
["atha"] = {pseudostem = "katha", ndel = 1 + 2 * alen},
atha_for_a = {pseudostem = "ka", ndel = alen},
atha_for_aa = {pseudostem = "kā", ndel = 1},
["kāhiti"] = {pseudostem = "kāhiti", ndel = 5}, --Tricky code
void = {pseudostem = "ku", ndel = 1}, -- rhubarb
}
way = way[ending]
if way then
pat[sc] = convert_suffixes(way.pseudostem, way.ndel, pat, sc,
impl, yopt)
else
error('Cannot convert derivations from suffix '..ending..' for '..sc)
end
return pat[sc]
end
end
function export.future_forms(cite, args, subset)
local currentScript = lang:findBestScript(cite)
local scriptCode = currentScript:getCode()
local latinise = nil
if scriptCode == "None" and args.sc then -- Resort to sc
scriptCode = args["sc"]
currentScript = m_scripts.getByCode(scriptCode, "No such script as ".. scriptCode .. ".")
latinise = currentScript
augment[scriptCode] = to_script("a", scriptCode)
end
if subset then args = export.parse(args) end
args = export.futureParse(args, subset)
args.cite = arrcat_nodup({cite}, args.cite)
local debug = '\n\nAt (1), args.cite = '..table.concat(args.cite, ' ')
local patpa, patpm, basepa, basepm
local parts = {}
local option = {}
option.aa = args.aa
-- Handle future tense. This forms a base for others.
local ending = export.detectFutureEnding(cite, latinise)
patpa = export.getFutureSuffixes(scriptCode, ending, nil, args)
basepa = cite
local mset = nil
local forBoth = false
local aset = args.cite
local voice = "both"
if 'e' == asub(ending, -1) then -- No active inflection
patpm = patpa
patpa = nil
basepm = cite
aset = nil
mset = args.cite
voice = "midl"
elseif args.midl and args.midl[1] then
basepm = args.midl[1]
mset = args.midl
local midend = export.detectFutureEnding(basepm, latinise)
patpm = future_pattern[midend].mid and
export.getFutureSuffixes(scriptCode, future_pattern[midend].mid, nil, args)
elseif args.voice == 'act' then
patpm = nil
voice = "act"
else
patpm = future_pattern[ending].mid and
export.getFutureSuffixes(scriptCode, future_pattern[ending].mid, nil, args)
basepm = cite
forBoth = true
mset = args.cite
end
local formsa = nil
local formsm = nil
if patpa then
formsa = export.joinSuffixes(scriptCode, basepa, patpa, option)
for k = 2, #aset do
basepa = aset[k]
patpa = export.getFutureSuffixes(
scriptCode, export.detectFutureEnding(basepa, latinise), nil, args)
local extras = export.joinSuffixes(scriptCode, basepa, patpa, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
end
end
if patpm or forBoth then
if patpm then
formsm = export.joinSuffixes(scriptCode, basepm, patpm, option)
else
formsm = {{}, {}, {}, {}, {}, {}}
end
for k = 2, #mset do
basepm = mset[k]
local kend = export.detectFutureEnding(basepm, latinise)
kend = future_pattern[kend].mid
if kend then
patpm = export.getFutureSuffixes(scriptCode, kend, nil, args)
local extras = export.joinSuffixes(scriptCode, basepm, patpm, option)
for ip = 1, 6 do
formsm[ip] = arrcat_nodup(formsm[ip], extras[ip])
end
end
end
end
if args.voice == "act" or args.voice == "both" then
-- handled already
elseif args.voice == "none" then
formsa = nil
formsm = nil
voice = "none"
elseif args.voice then
error('Argument voice has bad value "'..args.voice..'.')
end
formsa, formsm = export.modify(formsa, formsm, '', args)
parts.futua = formsa
parts.futum = formsm
-- Form conditional from future.
local aug
if args["impl"] == 'no' then
aug = augment_alph[scriptCode] or augment[scriptCode]
else
aug = augment[scriptCode]
end
-- error("impl="..tostring(args["impl"]).." aug="..aug)
-- error("impl="..tostring(args["impl"]).." aug="..aug.." aset="..tostring(aset[1])..
-- " args.augment="..args.augment)
args.cond_voice = args.cond_voice or voice
-- error("args.cond_voice="..tostring(args.cond_voice))
local cond = {}
if (args.cond_voice ~= 'none') then
if args.augment == 'without' then
if aset then cond = aset end
elseif args.augment == 'with_made' then
if aset then
for k = 1, #aset do
cond[k] = aug .. aset[k]
end
end
elseif args.augment == 'with_given' then
cond = args.cond
elseif args.augment == 'both_made' then
if aset then
for k = 1, #aset do
cond[k] = aug .. aset[k]
end
for k = 1, #aset do
cond[#aset+k] = aset[k]
end
end
elseif args.augment == 'both_given' then
cond = arrcat_nodup(args.cond or {}, aset or {})
else
error('Argument augment has bad value "'..args.augment..'".')
end
end
-- mw.addWarning('args.cite[1]='..args.cite[1]..', args.cond_voice='..args.cond_voice)
if (args.cond_voice == 'both' or args.cond_voice == 'act')
then
formsa = {{}, {}, {}, {}, {}, {}}
for k = 1, #cond do
local kend = export.detectFutureEnding(cond[k], latinise)
local patma = export.getFutureSuffixes(scriptCode, kend, 'conditional', args)
if patma then
local extras = export.joinSuffixes(scriptCode, cond[k], patma, option)
for ip = 1, 6 do
formsa[ip] = arrcat_nodup(formsa[ip], extras[ip])
end
end
end
elseif (args.cond_voice == 'none' or args.cond_voice == 'midl') then
formsa = nil
else
error('Argument cond_voice has bad value "'..args.cond_voice..'".')
end
if (args.cond_voice == 'both' or args.cond_voice == 'midl')
then
formsm = {{}, {}, {}, {}, {}, {}}
if not forBoth then
cond = {}
if args.augment == 'without' then
cond = mset
elseif args.augment == 'with_made' then
for k = 1, #mset do
cond[k] = aug .. mset[k]
end
elseif args.augment == 'with_given' then
cond = args.midl and args.midl[1] and args.cond_midl or args.cond
elseif args.augment == 'both_made' then
for k = 1, #mset do
cond[k] = aug .. mset[k]
end
for k = 1, #mset do
cond[#mset+k] = mset[k]
end
elseif args.augment == 'both_given' then
cond = arrcat_nodup(
args.midl and args.midl[1] and (args.cond_midl or {}) or
args.cond or {},
mset or {})
else
error('Argument augment has bad value "'..args.augment..'".')
end
end
for k = 1, #cond do
local kend = export.detectFutureEnding(cond[k], latinise)
debug=debug..'\n\nAt (7) cond[k]='..cond[k]
if forBoth then
if future_pattern[kend].mid then
kend = future_pattern[kend].mid
elseif kend == "eti" then
kend = nil
else
mw.addWarning('No middle endings for ending "'..kend..'".')
kend = nil
end
end
local pat = kend and export.getFutureSuffixes(scriptCode, kend, 'conditional', args)
if not kend then
-- nothing to do
elseif pat then
local extras = export.joinSuffixes(scriptCode, cond[k], pat, option)
for ip = 1, 6 do
formsm[ip] = arrcat_nodup(formsm[ip], extras[ip])
end
else
mw.addWarning('No conditional middle suffixes for '..cond[k]..
' ('..kend..')')
end
end
else
formsm = nil
end
formsa, formsm = export.modify(formsa, formsm, 'cond_', args)
parts.conda = formsa
parts.condm = formsm
-- List present participles.
local pap, pmp = {}, {}
args.part_voice = args.part_voice or voice
if args.part_voice == 'both' or args.part_voice == 'act' then
if voice == 'both' or voice == 'act' then
for k = 1, aset and #aset or 0 do
local kend = export.detectFutureEnding(aset[k], latinise)
local pat = kend and export.getFutureSuffixes(scriptCode, kend, "participle", args)
if pat then
local extra = export.joinSuffix(scriptCode, aset[k], pat[1])
pap = arrcat_nodup(pap, extra)
end
end
end
if args.fap_mod == 'blank' then
pap = {}
elseif args.fap_mod == 'after' then
pap = arrcat_nodup(pap, args.fap)
elseif args.fap_mod == 'before' then
pap = arrcat_nodup(args.fap, pap)
elseif args.fap_mod == 'replace' then
pap = args.fap
else
error('Argument fap_mod has invalid value '..args.fap_mod)
end
parts.fap = pap
elseif args.part_voice == 'midl' or args.part_voice == 'none' then
-- permissible
else
error('Argument part_voice has invalid value '..tostring(args.part_voice))
end
if args.part_voice == 'both' or args.part_voice == 'midl' then
local list
local from_active = forBoth or voice == 'act'
if from_active then
list = aset
else
list = mset
end
for k = 1, list and #list or 0 do
local kend = export.detectFutureEnding(list[k], latinise)
if from_active then kend = future_pattern[kend].mid end
local pat = kend and export.getFutureSuffixes(scriptCode, kend, "participle", args)
if pat then
-- if 2 == k then
-- error("k="..k.."list[k]="..list[k])
-- end
local extra = export.joinSuffix(scriptCode, list[k], pat[1])
pmp = arrcat_nodup(pmp, extra)
end
end
if args.fmp_mod == 'blank' then
pmp = {}
elseif args.fmp_mod == 'after' then
pmp = arrcat_nodup(pmp, args.fmp)
elseif args.fmp_mod == 'before' then
pmp = arrcat_nodup(args.fmp, pmp)
elseif args.fmp_mod == 'replace' then
pmp = args.fmp
else
error('Argument fmp_mod has invalid value '..args.fmp_mod)
end
parts.fmp = pmp
end
-- parts.debug = debug..'\n\n'..debug_outer
return parts
end
function export.show_future(frame)
local args = mw.clone(frame:getParent().args)
local cite = args[1] or args["cite"] -- or mw.title.getCurrentTitle().text
local xo = {impl = args.impl, y = args.y, showtr = args.showtr, subst = args.subst}
local parts = export.future_forms(cite, args, false)
local label = args.label or cite
local currentScript = lang:findBestScript(cite)
return export.present_future(label, currentScript, parts, xo)
end
return export