Module:pi-conj/verb

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 = , },	["ā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 = , },	["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 = , },	["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 = , },	["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 = , },	["ā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 = , },	["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 = , },	["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, ' '..				' '..tense..				' forms of "' .. cite .. '"' ..' ') ti(output,	' ")	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, ' '..tense..' ') if not hike then ti(output, ' Active Middle  ') ti(output, '  Singular  Plural  Singular  Plural  ') 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, " " .. v .. " ") ti(output, " ") ti(output, m_noun.orJoin(currentScript, formsa[2 * i - 1], x0)) ti(output, " ") ti(output, " ") ti(output, m_noun.orJoin(currentScript, formsa[2 * i], x0)) ti(output, " ") ti(output, " ") ti(output, m_noun.orJoin(currentScript, formsm[2 * i - 1], x0)) ti(output, " ") ti(output, " ") ti(output, m_noun.orJoin(currentScript, formsm[2 * i], x0)) ti(output, " ") ti(output, " ") 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, ' '..tense..' ') if not hike then ti(output, '  Singular  Plural  ') end for i,v in ipairs(rows) do		if #forms1[2*i-1] > 0 or #forms1[2*i] > 0 then ti(output, " ") ti(output, v)			ti(output, " ") ti(output, " ") ti(output, m_noun.orJoin(currentScript, forms1[2 * i - 1], xo)) ti(output, " ") ti(output, " ") ti(output, m_noun.orJoin(currentScript, forms1[2 * i], xo)) ti(output, " ") ti(output, " ") 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, ' '..				' '..				'Conjugation of "' .. label .. '" ') ti(output, ' ")	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, "") if parts.conda and parts.conda.add1p then ti(parts.cat, "") 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, "") 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 = , },	["ate"] = { -- Also services "ati" {"⌫⌫ṃ"}, {"⌫⌫⌫āmhe"}, {"⌫⌫se"}, {"⌫⌫vhe"},  {"⌫e"}, {"⌫⌫nte"}, conditional = { {"⌫⌫ṃ"},	       {"⌫⌫⌫āmhase"}, {"⌫⌫⌫e", "⌫⌫se"},	{"⌫⌫vhe"}, -- Duroiselle has first 2s as active. {"⌫ha"},	       {"⌫⌫⌫iṃsu"}, },		participle = , 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