Module:User:RichardW57/pi-conj/verb

Hello, you have come here looking for the meaning of the word Module:User:RichardW57/pi-conj/verb. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:User:RichardW57/pi-conj/verb, but we will also tell you about its etymology, its characteristics and you will know how to say Module:User:RichardW57/pi-conj/verb in singular and plural. Everything you need to know about the word Module:User:RichardW57/pi-conj/verb you have here. The definition of the word Module:User:RichardW57/pi-conj/verb will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:User:RichardW57/pi-conj/verb, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.


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 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 u = mw.ustring.char -- uses this for readability.

local function dc(x) -- Use this to make marks legible.  The name'dc' means 'drop carrier'.
	return gsub(x, "", "")
end

local endings = {
-- pa endings
	 = "ati",		 = "ati",			 = "ati",			 = "ati",
	 = "ati",									 = "ati",
	 = "ati",			 = "ati",			 = "ati",

	 = "ayati",	 = "ayati",		 = "ayati",			 = "ayati",
	 = "ayati",								 = "ayati",
	 = "ayati",		 = "ayati",		 = "ayati",

	 = "āti",		 = "āti",		 = "āti",	 = "āti",
	 = "āti",		 = "āti",		 = "āti",		 = "āti",
	 = "āti",	 = "āti",	 = "āti",

	 = "eti",								 = "eti",	 = "eti",
	 = "eti",								 = "eti",
	 = "eti",	 = "eti",	 = "eti",

	 = "oti",								 = "oti",	 = "oti",
	 = "oti",		 = "oti",		 = "oti",		 = "oti",
	 = "oti",	 = "oti",	 = "oti",
-- pm endings
	 = "ate",		 = "ate",			 = "ate",			 = "ate",
	 = "ate",									 = "ate",
	 = "ate",			 = "ate",			 = "ate",

	 = "ayate",	 = "ayate",		 = "ayate",			 = "ayate",
	 = "ayate",								 = "ayate",
	 = "ayate",		 = "ayate",		 = "ayate",

	 = "āte",		 = "āte",		 = "āte",	 = "āte",
	 = "āte",		 = "āte",		 = "āte",		 = "āte",
	 = "āte",	 = "āte",	 = "āte",

	 = "ete",								 = "ete",	 = "ete",
	 = "ete",								 = "ete",
	 = "ete",	 = "ete",	 = "ete",

	 = "ute",		 = "ute",		 = "ute",	 = "ute",
	 = "ute",							 = "ute",	
	 = "ute",	 = "ute",	 = "ute",
-- optative endings
	 = "eyya",		 = "eyya",			 = "eyya",	 = "eyya",
	 = "eyya",								 = "eyya",
	 = "eyya",	 = "eyya",	 = "eyya",

	 = "ā",			 = "ā",			 = "ā",	 = "ā",
	 = "ā",			 = "ā",			 = "ā",		 = "ā",
	 = "ā",		 = "ā",		 = "ā",

	 = "etha",		 = "etha",			 = "etha",	 = "etha",
	 = "etha",								 = "etha",
	 = "etha",	 = "etha",	 = "etha",
-- imperfect endings
	 = "attha",	 = "attha",		 = "attha",	 = "attha",
	 = "attha",		 = "attha",
	 = "attha",		 = "attha",		 = "attha",
}

function export.detectEnding(cite3s)
	local len
	local ending
	for len = 5, 1, -1 do
		wordEnd = sub(cite3s, -len)
		ending = endings
		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 ending == 'ayati' and len == 3 then
			if match(sub(cite3s,-4,-4),
				"^") then
				return ending
			else
				return "ati"
			end
		elseif ending == 'ayate' and len == 3 then
			if match(sub(cite3s,-4,-4),
				"^") then
				return ending
			else
				return "ate"
			end
		else
-- debug_outer = debug_outer..'\n'..cite3s..'='..ending..'\n'
			return ending
		end
	end
-- debug_outer = debug_outer..'\n'..cite3s..'='.."ati"..'\n'
	return "ati"
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 = {"⌫⌫⌫eyyāmi", "⌫⌫⌫eyyaṃ"}
active_optative_aati = {"⌫⌫⌫eyyāsi"}
local active_optative_eti  = mw.clone(active_optative_aati)
active_optative_eti = {"⌫⌫⌫eyya"}
local active_optative_oti  = 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 pattern = {
	 = {
		{"⌫⌫⌫ā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"}},
	},
	 = { 
		{"⌫⌫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_ati,
		optative_middle = middle_optative_aati,
		participle = {{"⌫⌫⌫ant"}},
	},
	 = {
		{"⌫⌫mi"}, {"⌫⌫ma"},   {"⌫⌫si"}, {"⌫ha"},    {""}, {"⌫⌫nti"},
		mid = nil, -- "ete",
		imperative = {
			{"⌫⌫mi"}, {"⌫⌫ma"},   {"⌫⌫hi"}, {"⌫ha"},    {"⌫u"}, {"⌫⌫ntu"},
		},
		optative_active = active_optative_eti,
		optative_middle = middle_optative_eti,
		participle = {{"⌫⌫nt"}},
	},
	 = {
		{"⌫⌫mi"}, {"⌫⌫ma"},   {"⌫⌫si"}, {"⌫ha"},    {""}, {"⌫⌫nti"},
		mid = "oti_ute",
		imperative = {
			{"⌫⌫mi"}, {"⌫⌫ma"},   {"⌫⌫hi"}, {"⌫ha"},    {"⌫u"}, {"⌫⌫ntu"},
		},
		optative_active = active_optative_oti,
		optative_middle = middle_optative_oti,
		participle = {{"⌫⌫nt"}},
	},
	 = { -- Also services "ati"
		{"⌫⌫⌫e"}, {"⌫⌫⌫āmhe"},  {"⌫⌫se"}, {"⌫⌫vhe"},  {"⌫e"}, {"⌫⌫nte", "⌫⌫re"},
		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"}},
	},
	 = { -- Also services "āti"
		{"⌫⌫⌫e"},	{"⌫⌫mhe"},
		{"⌫⌫se"},	{"⌫⌫⌫avhe"},
		{"⌫e"},		{"⌫⌫⌫ante", "⌫⌫re"},
		optative_active = active_optative_aati,
		optative_middle = middle_optative_aati,
		participle = {{"⌫⌫⌫amāna"}},
	},
	 = { -- Also services "eti"
		{"⌫⌫⌫aye"},		{"⌫⌫⌫ayāmhe"},
		{"⌫⌫⌫ayase"},	{"⌫⌫⌫ayavhe"},
		{"⌫⌫⌫ayate"},	{"⌫⌫⌫ayante", "⌫⌫⌫ayare"},
		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"}},
	},
	 = { -- Actual ending is "oti" when copied to "oti_ute".
		{"⌫⌫⌫ve"},	{"⌫⌫⌫umhe"},
		{"⌫⌫⌫use"},	{"⌫⌫⌫uvhe"},
		{"⌫⌫⌫ute"},	{"⌫⌫⌫unte", "⌫⌫⌫ure"},
		imperative = {
			{"⌫⌫⌫ve"},		{"⌫⌫⌫vāmase"},
			{"⌫⌫⌫ussu"},	{"⌫⌫⌫uvho"},
			{"⌫⌫⌫utaṃ"},	{"⌫⌫⌫untaṃ"}
			-- 1s, 1pl and 3pl will often need manual repair.
		},
	},
	 = {
		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ṃ"}
		}
	},
	 = {
		optative_middle = {
			{"⌫⌫⌫yyaṃ"}, {"⌫⌫⌫yyāmhe"},
			{"⌫o"},      {"⌫⌫⌫yyavho"},
			{""},        {"⌫⌫⌫raṃ"}
		},
	},
	 = {
		imperfect = {
			{"⌫⌫⌫⌫⌫iṃ"}, {"⌫⌫⌫⌫mhase"},  {"⌫⌫⌫⌫se"}, {"⌫⌫⌫⌫vhaṃ"}, {""}, {"⌫uṃ"}
		}
	},
}

-- -oti is too different from -ute in some scripts.
pattern.oti_ute = mw.clone(pattern.ute)

-- convert Latin script inflections to another script
--ⒹⓉ
local convert_suffixes = function(stem, nstrip, suffixes, sc)
	local form, pre, stem_pre
	local xlitend = {}
	local strip = string.rep("⌫", nstrip)
	local altstem, as1
	if sc == 'Thai' then
		altstem = to_script(stem, sc)
		stem_pre = match(altstem, "^")
		as1 = sub(altstem, 1, 1)
	end
	for k = 1, #suffixes do
		xlitend = {}
		form = export.joinSuffix('Latn', stem, suffixes)
		local ib = 1 -- Conversion is not one-to-one!
		for ia, va in pairs(form) do
			local ibin = ib
			altform = to_script(va, sc)
-- 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 = sub(strip, 2) .. sub(altform, 3)
						ib = ib + 1
					else
--						mw.addWarning("Cannot abstract derivation "..altstem.." > "..altform)
						xlitend.voi = true
						xlitend = sub(strip, 2) .. 'Ⓣ' .. sub(altform, 3)
						ib = ib + 1
					end -- Don't generate gibberish
				else
					xlitend = strip .. "↶" .. pre .. sub(altform, 3)
					ib = ib + 1
				end
			else
				if stem_pre then
					xlitend.voi = true
					xlitend = sub(strip, 2) .. 'Ⓓ' .. sub(altform, 2)
					ib = ib + 1
				else
					xlitend = strip .. sub(altform, 2)
					ib = ib + 1
				end
			end
			if sc == 'Thai' and ib > ibin then -- New Thai ending
				local altend = gsub(xlitend, dc("(กฺ)()(ห)"), "%2%1%3")
				if altend ~= xlitend then
					xlitend = xlitend
					xlitend = altend
					ib = ib + 1
				end
			end
		end
	end
	return xlitend
end

function export.getSuffixes(sc, ending, tense)
	local pat
	if not pattern then
		error('No verb pattern for ending "'..ending..'".')
	end
	if tense then
		pat = pattern
	else
		pat = pattern
	end
	if 'Latn' == sc then
		return pat
	elseif not pat then
		return nil
	elseif pat then
		return pat
	else
		local olen = {Mymr = 2, Lana = 2} -- Assume NFC
		local attha_len = {Latn = 5, Sinh = 4}
		eyya_len = {Sinh = 5} 
		local way = {
			  = {pseudostem = "kati", ndel = 2},
			  = {pseudostem = "kayati", ndel = 3},
			  = {pseudostem = "kāti", ndel = 3},
			  = {pseudostem = "keti", ndel = 3},
			  = {pseudostem = "koti", ndel = 2 + (olen or 1)},
			  = {pseudostem = "koti", ndel = 2 + (olen or 1)},
			  = {pseudostem = "kate", ndel = 2},
			  = {pseudostem = "kayate", ndel = 3},
			  = {pseudostem = "kāte", ndel = 3},
			  = {pseudostem = "kete", ndel = 3},
			  = {pseudostem = "kute", ndel = 3},
			 = {pseudostem = "keyya", ndel = eyya_len or 4},
			    = {pseudostem = "kā", ndel = 1},
			 = {pseudostem = "ketha", ndel = 2},
			 = {pseudostem = "kattha", ndel = attha_len or 3},
		}
		way = way
		if way then
			pat = convert_suffixes(way.pseudostem, way.ndel, pat, sc)
			if ending == 'etha' then
				debug_outer=debug_outer..'tr:'..pat
			end
		else
			error('Cannot convert derivations from suffix '..ending..' for '..sc)
		end
		return pat
	end
end

local function define_overrides(params, prefix, mod_default)
	for _, pn in pairs({"1s", "2s", "3s", "1p", "2p", "3p"}) do
		params = {list = true}
		params = {list = true}
		params = {default = mod_default}
		params = {default = mod_default}
	end
end

function export.parse(args)
	mod_default = 'after'
	local params = {
		 = {}, -- Just ignore
		cite = {list = true},
		midl = {list = true},
		label = {},
		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},
		part_voice = {}, -- defaults to (corrected) value of voice
		pap_mod = {default = mod_default},
		pap = {list = true},
		pmp_mod = {default = mod_default},
		pmp = {list = true},
	}
	define_overrides(params, '',      mod_default)
	define_overrides(params, 'impf_', mod_default)
	define_overrides(params, 'impr_', mod_default)
	define_overrides(params, 'opta_', mod_default)
	return m_parameters.process(args, params)
end

local arrcat_nodup = function(a1, a2) -- Concatenate two arrays
	local n1 = #a1
	local n2 = #a2
	local cat = {}
	for i = 1, n1 do cat = a1 end
	for i = 1, n2 do
		local met = false
		for j = 1, n1 do
			if a2 == cat then
				met = true;
				break;
			end
		end
		if not met then
			n1 = n1 + 1
			cat = a2
		end
	end
	return cat
end

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..m2 end
	return gsub(stem, "()(*)$", f_toggle)
end

function export.joinSuffix(sc, base, pattern)
	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)
	else
		return m_noun.joinSuffix(sc, base, pattern)
	end
end

function export.joinSuffixes(scriptCode, stem, pattern)
	local forms = {}
	for i = 1, 6 do
		forms = export.joinSuffix(scriptCode, stem, pattern)
	end
	return forms
end

pattern.ayati = mw.clone(pattern.ati)
pattern.ayati.mid = "ayate"
-- Lose some of the shorter forms.
pattern.ayati.imperative = {"⌫⌫⌫āhi"}
pattern.ayati.imperative = {} -- {"⌫aṃ", "⌫⌫⌫⌫⌫etaṃ"} -- 3s needs review
pattern.ayati.optative_active = {"⌫⌫⌫eyyāmi", "⌫⌫⌫eyyaṃ"}
pattern.ayati.optative_active = {"⌫⌫⌫eyyāsi"}
pattern.ayate = mw.clone(pattern.ate)

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 > 0 then
				if args == 'after' then
					forms = arrcat_nodup(forms, args)
					forms.isnil = false
				elseif args == 'replace' then
					forms = args
					forms.isnil = false
				elseif args == 'before' then
					forms = arrcat_nodup(args, forms)
					forms.isnil = false
				elseif args == 'blank' then
					forms = {}
				else
					error('Argument '..prefix..pn..' has invalid value '..args)
				end
			elseif args == 'blank' then
				forms = {}
			end
		end
end

function export.present(cite, tense, formsa, formsm)
	local rows = {"1st", "2nd", "3rd"}
	local forms1
	local output = '<div class="NavFrame" style="min-width:30%">'..
				'<div class="NavHead" style="background:#d9ebff">'..tense..
				' forms of "' .. cite .. '"' ..'</div><div class="NavContent">'
	output = output ..
	'<table class="inflection-table" style="background:#F9F9F9;'..
		'text-align:center;width:100%">'

	if formsa and formsm then
		output = output .. '<tr style="background:#eff7ff"><th></th><th colspan=2>Active</th><th colspan=2>Middle</th></tr>'
		output = 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 > 0 or #formsa > 0 or #formsm > 0 or #formsm > 0 then
				output = output .. "<tr><th style=\"background-color:#eff7ff;\">" .. v .. "</th>"
				output = output .. "<td>" .. m_noun.orJoin(currentScript, formsa) .. "</td>"
				output = output .. "<td>" .. m_noun.orJoin(currentScript, formsa) .. "</td>"
				output = output .. "<td>" .. m_noun.orJoin(currentScript, formsm) .. "</td>"
				output = output .. "<td>" .. m_noun.orJoin(currentScript, formsm) .. "</td>"
				output = output .. "</tr>"
			end
		end
	else
		if formsa then
			forms1 = formsa
		else
			forms1 = formsm
		end
		output = output .. '<tr style="background:#eff7ff"><th></th><th>Singular</th><th>Plural</th></tr>'
		for i,v in ipairs(rows) do
			if #forms1 > 0 or #forms1 > 0 then
				output = output .. "<tr><td style=\"background-color:#eff7ff;\">" .. v .. "</td>"
				output = output .. "<td>" .. m_noun.orJoin(currentScript, forms1) .. "</td>"
				output = output .. "<td>" .. m_noun.orJoin(currentScript, forms1) .. "</td>"
				output = output .. "</tr>"
			end
		end
	end
	output = output .. "</table></div></div>"
	return output
end

-- Basic from of augment:
local augment = {
	Latn="a",
	Thai="อ",
	Deva="अ",
	Beng="অ",
	Mymr="အ",
	Lana="ᩋ",
	Khmr="អ",
	Sinh="අ",
	Brah="𑀅",
}

local enda3s = {
	Latn="ti",
	Thai="ติ",
	Deva="ति",
	Beng="তি ",
	Mymr="တိ",
	Lana="ᨲᩥ",
	Khmr="តិ",
	Sinh="ති",
	Brah="𑀢𑀺",
}

local function presentify(imp3s, sc)
	return imp3s..enda3s
end

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 = 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

function export.show(frame)
	local args = mw.clone(frame:getParent().args)
	local PAGENAME = mw.title.getCurrentTitle().text
	local cite = args or args or PAGENAME
	currentScript = lang:findBestScript(cite)
	scriptCode = currentScript:getCode()
	args = export.parse(args)
	args.cite = arrcat_nodup({cite}, args.cite)
	if not args.label then args.label = cite end
	local debug = '\n\nAt (1), args.cite = '..table.concat(args.cite, ' ')
	local patpa, patpm, basepa, basepm

    local tables = {"", "", "", "", "", ""}
-- Handle present tense.  This forms a base for others.
	local ending = export.detectEnding(cite)
	patpa = export.getSuffixes(scriptCode, ending)
	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 then
		basepm = args.midl
		mset = args.midl
		local midend = export.detectEnding(basepm)
		patpm = export.getSuffixes(scriptCode, midend)
	elseif args.voice == 'act' then
		patpm = nil
		voice = "act"
	else
		patpm = pattern.mid and
				export.getSuffixes(scriptCode, pattern.mid)
		basepm = cite
		forBoth = true
		mset = args.cite
	end
	local formsa = nil
	local formsm = nil
	if patpa then
		formsa = export.joinSuffixes(scriptCode, basepa, patpa)
		for k = 2, #aset do
			basepa = aset
			patpa = export.getSuffixes(scriptCode, export.detectEnding(basepa))
			local extras = export.joinSuffixes(scriptCode, basepa, patpa)
			for ip = 1, 6 do
				formsa = arrcat_nodup(formsa, extras)
			end
		end
	end
	if patpm or forBoth then
		if patpm then
			formsm = export.joinSuffixes(scriptCode, basepm, patpm)
		else
			formsm = {{}, {}, {}, {}, {}, {}}
		end
		for k = 2, #mset do
			basepm = mset
			local kend = export.detectEnding(basepm)
			if forBoth then kend = pattern.mid end
			if kend then
				patpm = export.getSuffixes(scriptCode, kend)
				local extras = export.joinSuffixes(scriptCode, basepm, patpm)
				for ip = 1, 6 do
					formsm = arrcat_nodup(formsm, extras)
				end
			end
		end
	end
	formsa, formsm = export.modify(formsa, formsm, '', args)

	if formsa or formsm then
		tables = export.present(args.label, 'Present', formsa, formsm)
	end

-- Form imperative from present
    formsa = nil
    formsm = nil
    local imperativeVoice = args.impr_voice or voice
    if imperativeVoice == 'act' or imperativeVoice == 'both' then
    	local patma
    	formsa = {{}, {}, {}, {}, {}, {}}
    	for k = 1, #aset do
    		kend = export.detectEnding(aset)
    		patma = export.getSuffixes(scriptCode, kend, 'imperative')
    		if patma then 
	   			local extras = export.joinSuffixes(scriptCode, aset, patma)
    			for ip = 1, 6 do
    				formsa = arrcat_nodup(formsa, extras)
    			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
    		if forBoth then
    			form3s = aset
	    		kend = export.detectEnding(form3s)
	    		if pattern.mid then
	    			kend = pattern.mid
	    		elseif kend == "eti" then
	    			kend = nil
	    		else
	    			error('No middle endings for ending "'..kend..'".')
	    			kend = nil
	    		end
    		else
    			form3s = mset
	    		kend = export.detectEnding(form3s)
    		end
    		patmm = kend and export.getSuffixes(scriptCode, kend, 'imperative')
    		if patmm then 
	   			local extras = export.joinSuffixes(scriptCode, form3s, patmm)
    			for ip = 1, 6 do
    				formsm = arrcat_nodup(formsm, extras)
    			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
    if formsa or formsm then
		tables = export.present(args.label, 'Imperative', formsa, formsm)
	end

-- Form imperfect from present.  Existence defaults to false for both voices.
	impf = {}
	if (args.impf_voice ~= 'none') then
		if args.augment == 'without' then
			if not aset then impf = aset end
		elseif args.augment == 'with_made' then
			if aset then
				for k = 1, #aset do
					impf = augment .. aset
				end
			end
		elseif args.augment == 'with_given' then
			for k = 1, #args.impf do
				impf = presentify(args.impf, scriptCode)
			end
		elseif args.augment == 'both_made' then
			if aset then
				for k = 1, #aset do
					impf = augment .. aset
				end
				for k = 1, #aset do
					impf = aset
				end
			end
		elseif args.argument == 'both_given' then
			for k = 1, #args.impf do
				impf = presentify(args.impf, scriptCode)
			end
			if aset then
				for k = 1, #aset do
					impf = aset
				end
			end
		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)
			patma = export.getSuffixes(scriptCode, kend, 'imperfect')
			if patma then
				local extras = export.joinSuffixes(scriptCode, impf, patma)
				for ip = 1, 6 do
					formsa = arrcat_nodup(formsa, extras)
				end
			end
		end
	else
		formsa = nil
	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 = augment .. mset
				end
			elseif args.augment == 'with_given' then
				impf = args.impf_midl
			elseif args.augment == 'both_made' then
				for k = 1, #mset do
					impf = augment .. mset
				end
				for k = 1, #mset do
					impf = mset
				end
			elseif args.argument == 'both_given' then
				for k = 1, #args.impf_midl do
					impf = args.impf_midl
				end
				for k = 1, #mset do
					impf = mset
				end
			else
				error('Argument augment has bad value "'..args.augment..'".')
			end
		end
		for k = 1, #impf do
			kend = export.detectEnding(impf)
			debug=debug..'\n\nAt (7) impf='..impf
			if forBoth then
	    		if pattern.mid then
	    			kend = pattern.mid
	    		else
	    			error('No middle endings for ending "'..kend..'".')
	    			kend = nil
	    		end
			end
			local pat = export.getSuffixes(scriptCode, kend, 'imperfect')
			if pat then
				local extras = export.joinSuffixes(scriptCode, impf, pat)
				for ip = 1, 6 do
					formsm = arrcat_nodup(formsm, extras)
				end
			else
				mw.addWarning('No imperfect middle suffixes for '..impf..
					' ('..kend..')')
			end
		end
	else
		formsm = nil
	end
	formsa, formsm = export.modify(formsa, formsm, 'impf_', args)
	if formsa or formsm then
		tables = export.present(args.label, 'Imperfect', formsa, formsm)
	end
-- 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 = {{}, {}, {}, {}, {}, {}}
		for k = 1, #opta do
			kend = export.detectEnding(opta)
			patma = export.getSuffixes(scriptCode, kend, 'optative_active')
			if patma then
				local extras = export.joinSuffixes(scriptCode, opta, patma)
				for ip = 1, 6 do
					formsa = arrcat_nodup(formsa, extras)
				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 = {{}, {}, {}, {}, {}, {}}
		debug=debug..'\n\nAt (6), opta='..table.concat(opta)
		for k = 1, #opta do
			kend = export.detectEnding(opta)
			patma = export.getSuffixes(scriptCode, kend, 'optative_middle')
			if patma then
				local extras = export.joinSuffixes(scriptCode, opta, patma)
				for ip = 1, 6 do
					formsm = arrcat_nodup(formsm, extras)
				end
			else
				debug = debug.."\n\nNo "..kend..".optative_middle"
			end
		end
	else
		formsm = nil
	end

	formsa, formsm = export.modify(formsa, formsm, 'opta_', args)
	if formsa or formsm then
		tables = export.present(args.label, 'Optative', formsa, formsm)
	end

--	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)
				local pat = kend and export.getSuffixes(scriptCode, kend, "participle")
				if pat then
					local extra = export.joinSuffix(scriptCode, aset, pat)
					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
		if #pap > 0 then
			tables = tables..'\n* Present participle: '..
			m_noun.orJoin(currentScript, pap)..', which see for forms and usage'
		end
	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)
			if from_active then kend = pattern.mid end
			local pat = kend and export.getSuffixes(scriptCode, kend, "participle")
			if pat then
				local extra = export.joinSuffix(scriptCode, list, pat)
				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
		if #pmp > 0 then
			tables = tables..'\n* Present participle: '..
			m_noun.orJoin(currentScript, pmp)..', which see for forms and usage'
		end
	end
	
--	tables = debug..'\n\n'..debug_outer

	return table.concat(tables)

end

return export