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