local decl_data = {}
local sa_utils = require("Module:sa-utilities")
local SLP_to_IAST = require("Module:sa-utilities/translit/SLP1-to-IAST")
local IAST_to_SLP = require("Module:sa-utilities/translit/IAST-to-SLP1")
local match = mw.ustring.match
-- Make a detection function for ARGS that fetches the stem according to MATCH_RE (which is matched against
-- args.lemma and should have the stem in the first capture). ADDL_CONDITION is an optional function of one
-- argument (ARGS) that must return true for the detection to happen.
local function make_detect(match_re, addl_condition)
return function(args)
if addl_condition and not addl_condition(args) then
return false
end
local stem = match(args.lemma, match_re)
if stem then
args.stem = stem
return true
else
return false
end
end
end
-- Construct all or part of a given noun's declension. Each of SG, DU and PL is a table, whose keys are
-- as follows:
--
-- n = nominative
-- a = accusative
-- v = vocative
-- i = instrumental
-- d = dative
-- ab = ablative
-- g = genitive
-- l = locative
--
-- The corresponding value is one of the following:
-- 1. a "copy spec" such as "", meaning to copy from the instrumental of the same number;
-- 2. a single string (specifying an ending); or
-- 3. a list of specs, where a spec is either a string (an ending) or a table of the form
-- {"ENDING", stem = "STEM", mono = TRUE/FALSE, note = "NOTE"}. The latter format lets you explicitly specify what
-- the stem is, whether the form is monosyllabic, and what the footnote is. All named keys are optional.
--
-- In forms 2 and 3, if the ending begins with +, the stem defaults to args.lemma; otherwise it defaults to args.stem.
local function decline(args, data, sg, du, pl)
local cases = {n="nom", a="acc", v="voc", i="ins", d="dat", ab="abl", g="gen", l="loc"}
local function process_number(endings, tag)
if not endings then
return
end
for case, es in pairs(endings) do
if type(es) == "string" and es:find("^%[") then
-- copy from another case; skip and handle later
else
if type(es) == "string" then
es = {es}
end
local forms = {}
for i, e in ipairs(es) do
local stem, mono, final, note
if type(e) == "table" then
stem = e.stem
mono = e.mono
root = e.root
final = e.final
note = e.note
e = e
end
-- reduce Vedic forms to zero in case of novedic parameter
if args.novedic == true and note and (match(note, "edic$") or match(note, "Brhmaa")) then
stem = ""; e = ""; note = ""
else
if e:find("^%+") then
if stem then
error("Internal error: Can't use + in an ending when stem is explicitly given")
end
e = e:gsub("^%+", "")
stem = args.lemma
elseif not stem then
stem = args.stem
end
forms = sa_utils.internal_sandhi({
stem = stem, ending = e, has_accent = args.has_accent, recessive = case == "v",
mono = mono, root = root, final = final, ambig_final = args.ambig_final, diaspirate = args.diaspirate,
})
if note and note~= "" then
forms = note
end
end
end
data.forms .. "_" .. tag] = forms
end
end
-- Now handle cases copied from another.
for case, es in pairs(endings) do
if type(es) == "string" and es:find("^%[") then
-- copy from another case; skip and handle later
local other_case = es:match("^%$")
if not other_case then
error("Internal error: Unrecognized copy case spec " .. es)
end
local other_slot = other_case .. "_" .. tag
local value = data.forms
if not value then
error("Internal error: Slot '" .. other_slot .. "' to copy from is empty")
end
local this_slot = cases .. "_" .. tag
if data.forms then
error("Internal error: A value already exists for slot '" .. this_slot ..
"' when copying from '" .. other_slot .. "'")
end
data.forms .. "_" .. tag] = value
end
end
end
process_number(sg, "s")
process_number(du, "d")
process_number(pl, "p")
end
decl_data = {
detect = make_detect("(.+)a" .. sa_utils.accent .. "?$",
function(args) return args.g == "m" or args.g == "n" end)
}
setmetatable(decl_data, {
__call = function(self, args, data)
local oxy = match(args.lemma, "(" .. sa_utils.accent .. "?)$")
if args.pronominal then
data.decl_type = "pronominal a-stem"
else
data.decl_type = "a-stem"
end
if args.g == "m" then
decline(args, data, {
n="a" .. oxy .. "s",
a="a" .. oxy .. "m",
v="a"
}, {
n={ "O" .. oxy, { "A" .. oxy, note = "Vedic" } },
a="",
v={ "O", { "A", note = "Vedic" } }
}, {
a="A" .. oxy .. "n",
})
if args.pronominal then
decline(args, data, {}, {}, {
n="e" .. oxy,
v="e" .. oxy
})
else
decline(args, data, {}, {}, {
n={"A" .. oxy .. "s", {"A" .. oxy .. "sas", note="Vedic"}},
v={"As", {"Asas", note="Vedic"}}
})
end
else
decline(args, data, {
n="a" .. oxy .. "m",
a="",
v="a"
}, {
n="e" .. oxy,
a="",
v="e"
}, {
n={"A" .. oxy .. "ni", {"A" .. oxy, note="Vedic"}},
a="",
v={"Ani", {"A", note="Vedic"}}
})
end
if args.pronominal then
decline(args, data, {
d="a" .. oxy .. "smE",
ab="a" .. oxy .. "smAt",
l="a" .. oxy .. "smin"
}, {}, {
g="e" .. oxy .. "zAm"
})
else
decline(args, data, {
d="A" .. oxy .. "ya",
ab="A" .. oxy .. "t",
l="e" .. oxy
}, {}, {
g="A" .. oxy .. "nAm"
})
end
decline(args, data, {
i="e" .. oxy .. "na",
g="a" .. oxy .. "sya"
}, {
i="A" .. oxy .. "ByAm",
d="",
ab="",
g="a" .. oxy .. "yos",
l=""
}, {
i={ "E" .. oxy .. "s", { "e" .. oxy .. "Bis", note = "Vedic" } },
d="e" .. oxy .. "Byas",
ab="",
l="e" .. oxy .. "zu"
})
table.insert(data.categories, "Sanskrit a-stem nouns")
end
})
decl_data = {
detect = make_detect("(.+)" .. sa_utils.accent .. "?$")
}
setmetatable(decl_data, {
__call = function(self, args, data)
local vowel, oxy = match(args.lemma, "()(" .. sa_utils.accent .. "?)$")
data.decl_type = vowel .. "-stem"
if args.g == "m" then
if vowel == "i" then
decline(args, data, {
d="a" .. oxy .. "ye",
l={ "O" .. oxy, { "A" .. oxy, note = "Vedic"}}, -- Whitney §336f
}, {}, {})
elseif match(args.stem, sa_utils.consonant .. sa_utils.consonant .. "$") then
-- the dative ending -ve (vs. -ave) does not occur if the stem has two consonants before -u
decline(args, data, {
d="a" .. oxy .. "ve",
l="O" .. oxy,
}, {}, {})
else decline(args, data, {
d={ "a" .. oxy .. "ve", {stem = args.stem .. vowel, "e" .. oxy, note = "Vedic"}},
l="O" .. oxy,
}, {}, {})
end
if match(args.stem, sa_utils.consonant .. sa_utils.consonant .. "$") then
decline(args, data, {
ab={{sa_utils.up_one_grade .. "s"}},
}, {}, {})
else
decline(args, data, {
ab={sa_utils.up_one_grade .. "s", {stem = args.stem .. vowel, "a" .. oxy .. "s", note = "Vedic"}},
}, {}, {})
end
decline(args, data, {
n="+s",
a="+m",
i={ "+nA", {stem = args.stem .. vowel, "A" .. oxy, note = "Vedic" } },
g="",
v=sa_utils.up_one_grade,
}, {
n="+" .. vowel,
a="",
i="+ByAm",
d="",
ab="",
g={{stem = args.stem .. vowel, "o" .. oxy .. "s"}},
l="",
v="+" .. vowel,
}, {
n={{stem = args.stem .. sa_utils.up_one_grade, "as"}},
a="+" .. vowel .. "n",
i="+Bis",
d="+Byas",
ab="",
g=sa_utils.lengthen .. "nA" .. (oxy ~= "" and "/" or "") .. "m",
l="+su",
v={{stem = args.stem .. sa_utils.up_one_grade, "as"}},
})
elseif args.g == "f" then
if vowel == "i" then
decline(args, data, {
i={{stem = args.stem .. vowel, "A" .. oxy}, {"+i", note = "Vedic"}}, -- Whitney §336c
d={ "a" .. oxy .. "ye", {stem = args.stem .. vowel, "E" .. oxy, note = "Later Sanskrit" }, { "+i", note = "Vedic" } },
l={ "O" .. oxy, {stem = args.stem .. vowel, "A" .. oxy .."m", note = "Later Sanskrit" }, { "A" .. oxy, note = "Vedic"} },
}, {}, {})
else
decline(args, data, {
i={{stem = args.stem .. vowel, "A" .. oxy }},
d={ "a" .. oxy .. "ve", {stem = args.stem .. vowel, "E" .. oxy, note = "Later Sanskrit" } },
l={ "O" .. oxy, {stem = args.stem .. vowel, "A" .. oxy .."m", note = "Later Sanskrit" } },
}, {}, {})
end
decline(args, data, {
n="+s",
a="+m",
ab={sa_utils.up_one_grade .. "s", {stem = args.stem .. vowel, "A" .. oxy .."s", note = "Later Sanskrit"},
{stem = args.stem .. vowel, "E" .. oxy, note = "Brāhmaṇas"} },
g="",
v=sa_utils.up_one_grade,
}, {
n="+" .. vowel,
a="",
i="+ByAm",
d="",
ab="",
g={{stem = args.stem .. vowel, "o" .. oxy .. "s"}},
l="",
v="+" .. vowel,
}, {
n={{stem = args.stem .. sa_utils.up_one_grade, "as"}},
a="+" .. vowel .. "s",
i="+Bis",
d="+Byas",
ab="",
g=sa_utils.lengthen .. "nA" .. (oxy ~= "" and "/" or "") .. "m",
l="+su",
v={{stem = args.stem .. sa_utils.up_one_grade, "as"}},
})
else
if vowel == "i" then
decline(args, data, {
d={ "+ne", { "a" .. oxy .. "ye", note = "Vedic" }},
ab={ "+nas", { "e" .. oxy .. "s", note = "Vedic"}},
l={ "+ni", {"O" .. oxy, note = "Vedic"}, {"A" .. oxy, note = "Vedic"}}, -- Whitney §336f + §340f
}, {}, {})
elseif match(args.stem, sa_utils.consonant .. sa_utils.consonant .. "$") then
-- the dative ending -ve (vs. -ave) does not occur if the stem has two consonants before -u; similar for abl./gen. -vas (vs. -os)
decline(args, data, {
d={ "+ne", { "a" .. oxy .. "ve", note = "Vedic" }},
ab={ "+nas", { "o" .. oxy .. "s", note = "Vedic"}},
l={ "+ni", {"O" .. oxy, note = "Vedic"}},
}, {}, {})
else decline(args, data, {
d={ "+ne", { "a" .. oxy .. "ve", note = "Vedic" }, {stem = args.stem .. vowel, "e" .. oxy, note = "Vedic"}},
ab={ "+nas", { "o" .. oxy .. "s", note = "Vedic"}, {stem = args.stem .. vowel, "a" .. oxy .. "s", note = "Vedic"}},
l={ "+ni", {"O" .. oxy, note = "Vedic"}},
}, {}, {})
end
decline(args, data, {
n="+",
a="",
i={ "+nA", {stem = args.stem .. vowel, "A" .. oxy, note = "Vedic" }},
g="",
v={ "+", sa_utils.up_one_grade },
}, {
n="+nI",
a="",
i="+ByAm",
d="",
ab="",
g="+nos",
l="",
v="+nI",
}, {
n={ { stem = args.stem .. sa_utils.lengthen, "ni" }, { "+", note = "Vedic"}, { "+" .. vowel, note = "Vedic"} },
a="",
i="+Bis",
d="+Byas",
ab="",
g=sa_utils.lengthen .. "nA" .. (oxy ~= "" and "/" or "") .. "m",
l="+su",
v={ { stem = args.stem .. sa_utils.lengthen, "ni" }, { "+", note = "Vedic"}, { "+" .. vowel, note = "Vedic"} },
})
end
table.insert(data.categories, "Sanskrit " .. vowel .. "-stem nouns")
end
})
decl_data = {
detect = function(args)
if make_detect("(.+)" .. sa_utils.accent .. "?$")(args) then
args.true_mono = sa_utils.is_monosyllabic(args.lemma)
return true
else
return false
end
end
}
setmetatable(decl_data, {
__call = function(self, args, data)
local vowel, oxy = match(args.lemma, "()(" .. sa_utils.accent .. "?)$")
if args.pronominal then
data.decl_type = "pronominal " .. SLP_to_IAST.tr(vowel) .. "-stem"
else
data.decl_type = SLP_to_IAST.tr(vowel) .. "-stem"
end
if not (args.root or args.compound or args.true_mono) or (args.true_mono and args.root == false) then -- derived stem
if vowel == "A" then
decline(args, data, {
n="+",
i={ "a" .. oxy .. "yA", { "+", note = "Vedic" } },
v="e",
}, {
n="e" .. oxy,
g="a" .. oxy .. "yos",
v="e",
}, {
n="+s",
v="+s",
})
if args.pronominal then
decline(args, data, {
d="a" .. oxy .. "syE",
ab="a" .. oxy .. "syAs",
g="",
l="a" .. oxy .. "syAm"
}, {}, {
g="+sAm"
})
else
decline(args, data, {
d="+yE",
ab={"+yAs", {"+yE", note = "Brāhmaṇas"}},
g="",
l="+yAm"
}, {}, {
g="+nAm"
})
end
else
if vowel == "I" then
decline(args,data, {n="+"})
else
decline(args,data, {n="+s"})
end
decline(args, data, {
i={{stem = args.stem .. vowel, "A" .. oxy}},
d={{stem = args.stem .. vowel, "E" .. oxy}},
ab={{stem = args.stem .. vowel, "A" .. oxy .. "s"}, {stem = args.stem .. vowel, "E" .. oxy, note = "Brāhmaṇas"}},
g="",
l={{stem = args.stem .. vowel, "A" .. oxy .. "m"}},
v=sa_utils.shorten,
}, {
n={ "+O", { "+", note = "Vedic" } },
g={{stem = args.stem .. vowel, "o" .. oxy .. "s"}},
v={ "+O", { "+", note = "Vedic" } },
}, {
n={ "+as", { "+s", note = "Vedic" } },
v={ "+as", { "+s", note = "Vedic" } },
g="+nAm",
})
end
decline(args, data, {
a="+m",
}, {
a="",
i="+ByAm",
d="",
ab="",
l="",
}, {
a="+s",
i="+Bis",
d="+Byas",
ab="",
l="+su",
})
elseif vowel == "A" then
-- maybe not accurate for some forms of neuter adjectives, but not clear whether those had separate forms at all (Whitney §367b)
decline(args, data, {
n="+s",
a="+m",
i="+",
d="e" .. oxy,
ab="a" .. oxy .. "s",
g="",
l="i" .. oxy,
v="+s",
}, {
n={ "O" .. oxy, { "A" .. oxy, note = "Vedic" } },
a="",
i="+ByAm",
d="",
ab="",
g="o" .. oxy .. "s",
l="",
v={ "O", { "A", note = "Vedic" } }
}, {
n="+s",
a={ "+s", { "a" .. oxy .. "s", note = "Perhaps" } },
i="+Bis",
d="+Byas",
ab="",
g={ "+" .. sa_utils.lengthen .. "nAm", { "+" .. sa_utils.lengthen .. "m", note = "Perhaps" } },
l="+su",
v="+s",
})
elseif args.compound then
if match(args.stem, sa_utils.consonant .. sa_utils.consonant .. "$") then
decline(args, data, {
a={{"+am", mono = true}},
i={{"+A", mono = true}},
d={{"+e", mono = true}},
ab={{"+as", mono = true}},
l={{"+i", mono = true}},
}, {
n={{"+O", mono = true}},
g={{"+os", mono = true}},
v={{"+O", mono = true}},
}, {
n={{"+as", mono = true}},
g={ { "+Am", mono = true }, "+nAm" },
v={{"+as", mono = true}},
})
else
decline(args, data, {
a={ { "+am", mono = true }, "+am" },
i={ { "+A", mono = true }, "+A" },
d={ { "+e", mono = true }, "+e" },
ab={ { "+as", mono = true }, "+as" },
-- weird special case
l={ { "+i", mono = true }, { stem = args.stem .. sa_utils.vowel_to_cons, "i" .. (oxy ~= "" and "\\" or "") } },
}, {
n={ { "+O", mono = true }, "+O" },
g={ { "+os", mono = true }, "+os" },
v={ { "+O", mono = true }, "+O" },
}, {
n={ { "+as", mono = true }, "+as" },
g={ { "+Am", mono = true }, "+nAm", "+Am" },
v={ { "+as", mono = true }, "+as" },
})
end
decline(args, data, {
n="+s",
g="",
v="+s",
}, {
a="",
i="+ByAm",
d="",
ab="",
l="",
}, {
a="",
i="+Bis",
d="+Byas",
ab="",
l="+su",
})
elseif args.true_mono then
decline(args, data, {
n="+s",
a={ { "+am", mono = true}},
i={ { "+A" .. oxy, mono = true}},
d={ { "+e" .. oxy, mono = true }, { "+E" .. oxy, mono = true, note = "Later Sanskrit" } },
ab={ { "+a" .. oxy .. "s", mono = true }, { "+A" .. oxy .. "s", mono = true, note = "Later Sanskrit" },
{ "+E" .. oxy, mono = true, note = "Brāhmaṇas" } },
g="",
l={ { "+i" .. oxy, mono = true }, { "+A" .. oxy .. "m", mono = true, note = "Later Sanskrit" } },
v="",
}, {
n={{"+O", mono = true}},
a="",
i={{"+ByA" .. oxy .. "m", mono = true}},
d="",
ab="",
g={{"+o" .. oxy .. "s", mono = true}},
l="",
v="",
}, {
n={{"+as", mono = true}},
a="",
i={{"+Bi" .. oxy .. "s", mono = true}},
d={{"+Bya" .. oxy .. "s", mono = true}},
ab="",
g={ { "+A" .. oxy .. "m", mono = true }, { "+nA" .. oxy .. "m", mono = true, note = "Later Sanskrit" } },
l={{"+su" .. oxy, mono = true}},
v="",
})
else -- polysyllabic stems (Whitney §355 ff.)
decline(args, data, {
n="+s",
a="+am",
i="+A",
d="+e",
ab="+as",
g="",
l="+i",
v=sa_utils.shorten,
}, {
n="+A",
a="",
i="+ByAm",
d="",
ab="",
g="+os",
l="",
v="+A",
}, {
n="+as",
a="",
i="+Bis",
d="+Byas",
ab="",
g="+nAm",
l="+su",
v="+as",
})
end
table.insert(data.categories, "Sanskrit " .. SLP_to_IAST.tr(vowel) .. "-stem nouns")
end
})
decl_data = { -- actually for nouns in ṛ
detect = make_detect("(.+)f" .. sa_utils.accent .. "?$")
}
setmetatable(decl_data, { -- actually for nouns in ṛ
__call = function(self, args, data)
local oxy = match(args.lemma, "(" .. sa_utils.accent .. "?)$")
data.decl_type = SLP_to_IAST.tr("f") .. "-stem"
if args.g == "n" then
decline(args, data, {
n="f" .. oxy,
a="",
i="+nA",
d="+ne",
ab="+nas",
l="+ni",
v={ "f", "ar" },
}, {
n="+nI",
g="+nos",
v="+nI",
}, {
n="F" .. oxy .. "ni",
a="",
v="Fni",
})
else
if not args.r_stem_a then
error('Please specify the length of the accusative singular vowel with r_stem_a = "a" or "ā".')
else
args.r_stem_a = IAST_to_SLP.tr(args.r_stem_a)
end
decline(args, data, {
n="A" .. oxy,
a=args.r_stem_a .. oxy .. "ram",
i="rA" .. oxy,
d="re" .. oxy,
ab="u" .. oxy .. "r",
l="a" .. oxy .. "ri",
v="ar",
}, {
n={ args.r_stem_a .. oxy .. "rO", { args.r_stem_a .. oxy .. "rA", note = "Vedic" } },
g="ro" .. oxy .. "s",
v={ args.r_stem_a .. "rO", { args.r_stem_a .. "rA", note = "Vedic" } },
}, {
n=args.r_stem_a .. oxy .. "ras",
a=args.g == "f" and "F" .. oxy .. "s" or "F" .. oxy .. "n",
v=args.r_stem_a .. "ras",
})
end
decline(args, data, {
g="",
}, {
a="",
i="+ByAm",
d="",
ab="",
l="",
}, {
i="+Bis",
d="+Byas",
ab="",
g={{stem = args.stem .. "F", "nA" .. (oxy ~= "" and "/" or "") .. "m"}},
l="+su",
})
table.insert(data.categories, "Sanskrit " .. SLP_to_IAST.tr("f") .. "-stem nouns")
end
})
decl_data = { -- for root nouns ending on -gh/c/j/th/d/dh/p/bh/m/r/ṣ/ś/h + -āt/it/ut/ṛt + -ās/os
detect = function(args)
-- capture of vowel needed for accent
if make_detect("(.*)" .. sa_utils.vowel .. sa_utils.accent .. "?r?$")(args)
or make_detect("(.*)" .. sa_utils.accent .. "?t$")(args)
or make_detect("(.*)" .. sa_utils.accent .. "?s$")(args)
or (args.root == true and make_detect("(.*)" .. sa_utils.accent .. "?$")(args) ) then -- + āśis + numerals like triṃśát
args.true_mono = sa_utils.is_monosyllabic(args.lemma)
return true
else
return false
end
end
}
setmetatable(decl_data, {
__call = function(self, args, data)
local vowel, oxy, extra, cons = match(args.lemma, "(" .. sa_utils.vowel .. ")(" .. sa_utils.accent .. "?)(r?)()$")
if match(cons, "") ~= nil and not args.ambig_final then
error('Please specify the final consonant in the nominative singular with ambig_final = "k" or "ṭ".')
elseif args.ambig_final then -- also for cases like sarágh > saráṭ or potentially anuṣṭúbh > anuṣṭúk
args.ambig_final = IAST_to_SLP.tr(args.ambig_final)
end
local nasal = cons:gsub(".", sa_utils.homorganic_nasal)
if args.diaspirate then args.diaspirate = true end
data.decl_type = "root-stem"
-- neuter nom. plural (Whitney §389c, although saying that these forms with infixed nasal are not attested for nouns)
if args.g == "n" then
if match(cons, "") == nil and extra == "" then
decline(args, data, nil, nil, {
n= {{stem = args.stem .. vowel .. oxy .. nasal .. cons, "i"}},
v= {{stem = args.stem .. vowel .. nasal .. cons, "i"}},
})
else
decline(args, data, nil, nil, {
n= "+i",
v= "+i",
})
end
end
if args.true_mono then -- monosyllabic stem
if args.g ~= "n" then
decline(args, data, {
-- nom.sg. -s is an 'invisible' (historical) ending to provoke vowel lengthening in -ir/-ur stems, see Whitney §392
-- this ending should be removed by internal_sandhi at an early stage
n= {{"+s", root = true }},
a="+am",
v= {{"+s", root = true }},
}, {
n={ "+O", { "+A", note = "Vedic" } },
v={ "+O", { "+A", note = "Vedic" } },
}, {
n="+as",
v="+as"
})
else
decline(args, data, {
n= "+",
a="",
v= "+"
}, {
n= {{"+I" .. oxy, mono = true }},
v= "+I"
}, { })
end
decline(args, data, {
i= {{ "+A" .. oxy, mono = true }},
d= {{ "+e" .. oxy, mono = true }},
ab= {{ "+a" .. oxy .. "s", mono = true }},
g="",
l= {{ "+i" .. oxy, mono = true }},
}, {
a= "",
i= {{ "+ByA" .. oxy .. "m", mono = true, final = true, root = true }},
d="",
ab="",
g= {{ "+o" .. oxy .. "s", mono = true }},
l="",
}, {
a= "",
i= {{ "+Bi" .. oxy .. "s", mono = true, final = true, root = true }},
d= {{ "+Bya" .. oxy .. "s", mono = true, final = true, root = true }},
ab="",
g= {{ "+A" .. oxy .. "m", mono = true }},
l= {{ "+su" .. oxy, mono = true , final = true, root = true }},
})
else -- polysyllabic stem, no accent on ending
if args.g ~= "n" then
decline(args, data, {
n= {{"+s", root = true }},
a="+am",
v= {{"+s", root = true }},
}, {
n={ "+O", { "+A", note = "Vedic" } },
v={ "+O", { "+A", note = "Vedic" } },
}, {
n="+as",
v="+as"
})
else
decline(args, data, {
n= "+",
a="",
v= "+"
}, {
n= "+I",
v= "+I",
}, { })
end
decline(args, data, {
i="+A",
d="+e",
ab="+as",
g="",
l="+i",
}, {
a= "",
i= {{ "+ByAm", final = true, root = true }},
d="",
ab="",
g="+os",
l="",
}, {
a= "",
i= {{ "+Bis", final = true, root = true }},
d= {{ "+Byas", final = true, root = true }},
ab="",
g= "+Am",
l= {{ "+su", final = true, root = true }},
})
end
table.insert(data.categories, "Sanskrit root-stem nouns")
end
})
decl_datas"] = {
detect = make_detect("(.+)" .. sa_utils.accent .. "?s$")
}
setmetatable(decl_datas"], {
__call = function(self, args, data)
local vowel, oxy = match(args.lemma, "()(" .. sa_utils.accent .. "?)s$")
data.decl_type = vowel .. "s-stem"
if match(args.stem, ""..sa_utils.accent.."?y$") and vowel == "a" and args.g == "m" then -- comparatives
decline(args, data, {
n="An",
a="AMsam",
v={"an", { "+", note = "Rigvedic"}},
}, {
n={"AMsO", {"AMsA", note = "Vedic"}},
v={"AMsO", {"AMsA", note = "Vedic"}},
}, {
n="AMsas",
a="+as",
v="AMsas",
})
elseif args.g == "m" or args.g == "f" then
if vowel == "a" then
decline(args, data, {
n="A" .. oxy .. "s",
a={ "+am", { "A" .. oxy .. "m", note = "Vedic" } },
}, nil, {
n={ "+as", { "A" .. oxy .. "s", note = "Vedic" } },
v={ "+as", { "A" .. oxy .. "s", note = "Vedic" } },
})
else
decline(args, data, {
n="+",
a="+am",
}, nil, {
n="+as",
v="+as",
})
end
decline(args, data, {
v="+",
}, {
n={ "+O", { "+A", note = "Vedic" } },
v={ "+O", { "+A", note = "Vedic" } },
}, {
a="",
})
else
decline(args, data, {
n="+",
a="",
v="+",
}, {
n="+I",
v="+I",
}, {
n={{stem = args.stem .. sa_utils.lengthen .. oxy .. "Ms", "i"}},
v={{stem = args.stem .. sa_utils.lengthen .. "Ms", "i"}},
a="",
})
end
decline(args, data, {
i="+A",
d="+e",
ab="+as",
g="",
l="+i",
}, {
a="",
i= {{"+ByAm", final = true }},
d="",
ab="",
g="+os",
l="",
}, {
i= {{"+Bis", final = true }},
d= {{"+Byas", final = true }},
ab="",
g="+Am",
l= {{"+su", final = true }},
})
table.insert(data.categories, "Sanskrit " .. vowel .. "s-stem nouns")
end
})
decl_data = {
detect = make_detect("(.+)a" .. sa_utils.accent .. "?n$")
}
setmetatable(decl_data, {
__call = function(self, args, data)
local oxy = match(args.lemma, "a(" .. sa_utils.accent .. "?)n$")
data.decl_type = "an-stem"
if not match(args.stem, sa_utils.consonant .. "$") or args.contract then
decline(args, data, {
i="nA" .. oxy,
d="ne" .. oxy,
ab="na" .. oxy .. "s",
g="",
l={ "ni" .. oxy, "+i", { "+" , note = "Vedic"} }, -- Whitney §425c for Vedic form
}, {
g="no" .. oxy .. "s",
})
if args.g ~= "m" then
decline(args, data, nil, {
n={ "nI" .. oxy, "+I" },
v={ "nI", "+I" },
}, {
a={ "A" .. oxy .. "ni", {"a" .. oxy, note = "Vedic"}, {"A" .. oxy, note = "Vedic"}},
})
else
decline(args, data, nil, {
n={ "A" .. oxy .. "nO", { "A" .. oxy .. "nA", note = "Vedic" } },
v={ "AnO", { "AnA", note = "Vedic" } },
}, {
a="na" .. oxy .. "s",
})
end
decline(args, data, nil, nil, {
g="nA" .. oxy .. "m",
})
else
decline(args, data, {
i="+A",
d="+e",
ab="+as",
g="",
l= { "+i", { "+" , note = "Vedic"} }, -- Whitney §425c for Vedic form
}, {
g="+os",
})
if args.g ~= "m" then
decline(args, data, nil, {
n="+I",
v="+I",
}, {
a={ "A" .. oxy .. "ni", {"a" .. oxy, note = "Vedic"}, {"A" .. oxy, note = "Vedic"}},
})
else
decline(args, data, nil, {
n={ "A" .. oxy .. "nO", { "A" .. oxy .. "nA", note = "Vedic" } },
v={ "AnO", { "AnA", note = "Vedic" } },
}, {
a="+as",
})
end
decline(args, data, nil, nil, {
g="+Am",
})
end
if args.g ~= "m" then
decline(args, data, {
n="a" .. oxy,
a="",
v={ "+", "a" },
}, nil, {
n={ "A" .. oxy .. "ni", {"a" .. oxy, note = "Vedic"}, {"A" .. oxy, note = "Vedic"}},
v={ "Ani", {"a", note = "Vedic"}, {"A", note = "Vedic"}},
})
else
decline(args, data, {
n="A" .. oxy,
a="A" .. oxy .. "nam",
v="+",
}, nil, {
n="A" .. oxy .. "nas",
v="Anas",
})
end
decline(args, data, nil, {
a="",
i="a" .. oxy .. "ByAm",
d="",
ab="",
l="",
}, {
i="a" .. oxy .. "Bis",
d="a" .. oxy .. "Byas",
ab="",
l="a" .. oxy .. "su",
})
table.insert(data.categories, "Sanskrit an-stem nouns")
end
})
decl_data = {
detect = make_detect("(.+)i" .. sa_utils.accent .. "?n$",
function(args) return args.g == "m" or args.g == "n" end)
}
setmetatable(decl_data, {
__call = function(self, args, data)
local oxy = match(args.lemma, "i(" .. sa_utils.accent .. "?)n$")
data.decl_type = "in-stem"
if args.g ~= "n" then
decline(args, data, {
n="I" .. oxy,
a="i" .. oxy .. "nam",
v="+",
}, {
n={ "+O", { "+A", note = "Vedic" } },
v={ "+O", { "+A", note = "Vedic" } },
}, {
n="+as",
a="",
v="+as",
})
else
decline(args, data, {
n="i" .. oxy,
a="",
v={ "i", "+" },
}, {
n="+I",
v="+I",
}, {
n="I" .. oxy .. "ni",
a="",
v="Ini",
})
end
decline(args, data, {
i="+A",
d="+e",
ab="+as",
g="",
l="+i",
}, {
a="",
i="i" .. oxy .. "ByAm",
d="",
ab="",
g="+os",
l="",
}, {
i="i" .. oxy .. "Bis",
d="i" .. oxy .. "Byas",
ab="",
g="+Am",
l="i" .. oxy .. "zu",
})
table.insert(data.categories, "Sanskrit in-stem nouns")
end
})
decl_data = {
detect = make_detect("(.+)a" .. sa_utils.accent .. "?t$")
}
setmetatable(decl_data, {
__call = function(self, args, data)
local cons, oxy = match(args.lemma, "(?)a(" .. sa_utils.accent .. "?)t$")
-- for present participles
if args.lemma:find("a/?t$") == nil or args.participle == true then
data.decl_type = "at-stem"
if args.g ~= "n" then
decline(args, data, {
n="a" .. oxy .. "n",
a="a" .. oxy .. "ntam",
v="an",
}, {
n={ "a" .. oxy .. "ntO", { "a" .. oxy .. "ntA", note = "Vedic"} },
v={ "antO", { "antA", note = "Vedic"} },
}, {
n="a" .. oxy .. "ntas",
a="ata" .. oxy .. "s",
v="antas",
})
else
decline(args, data, {
n="a" .. oxy .. "t",
a="",
v="at",
}, {
n="a" .. oxy .. "ntI",
v="antI",
}, {
n="a" .. oxy .. "nti",
a="",
v="anti",
})
end
decline(args, data, {
i="atA" .. oxy,
d="ate" .. oxy,
ab="ata" .. oxy .. "s",
g="",
l="ati" .. oxy,
}, {
a="",
i="a" .. oxy .. "dByAm",
d="",
ab="",
g="ato" .. oxy .. "s",
l="",
}, {
i="a" .. oxy .. "dBis",
d="a" .. oxy .. "dByas",
ab="",
g="atA" .. oxy .. "m",
l="+su",
})
table.insert(data.categories, "Sanskrit at-stem nouns")
-- for nouns suffixed with -vat/-mat
else
data.decl_type = cons .. "at-stem"
if args.g ~= "n" then
decline(args, data, {
n="A" .. oxy .. "n",
a="a" .. oxy .. "ntam",
v={ "an", { "as", note = "Rigvedic"} },
}, {
n={ "a" .. oxy .. "ntO", { "a" .. oxy .. "ntA", note = "Vedic"} },
v={ "antO", { "antA", note = "Vedic"} },
}, {
n="a" .. oxy .. "ntas",
a="a" .. oxy .. "tas",
v="antas",
})
else
decline(args, data, {
n="a" .. oxy .. "t",
a="",
v="at",
}, {
n="+I",
v="+I",
}, {
n="a" .. oxy .. "nti",
a="",
v="anti",
})
end
decline(args, data, {
i="+A",
d="+e",
ab="+as",
g="",
l="+i",
}, {
a="",
i="a" .. oxy .. "dByAm",
d="",
ab="",
g="+os",
l="",
}, {
i="a" .. oxy .. "dBis",
d="a" .. oxy .. "dByas",
ab="",
g="+Am",
l="+su",
})
table.insert(data.categories, "Sanskrit " .. cons .. "at-stem nouns")
end
end
})
decl_data = {
detect = make_detect("(.+" .. sa_utils.accent .. "?Yc)$",
function(args) return args.g == "m" or args.g == "n" end)
}
setmetatable(decl_data, {
__call = function(self, args, data)
local cons, vowel, oxy = match(args.lemma, "(?)()(" .. sa_utils.accent .. "?)Yc$")
data.decl_type = "añc-stem"
-- make stem for 'middle' cases
args.stem = args.stem:gsub("Yc$", "c")
if args.g == "m" then
decline(args, data, {
n= "+", -- args.lemma
a="+am",
v= "+",
}, {
n={ "+O", { "+A", note = "Vedic" } },
v={ "+O", { "+A", note = "Vedic" } },
}, {
n="+as",
v="+as",
})
else -- neuter
decline(args, data, {
n= "", -- args.stem
v= "",
a=""
}, {}, {
n="+i",
v="+i",
a=""
})
end
decline(args, data, {}, {
i={{"ByAm", final = true}},
}, {
i={{"Bis", final = true}},
d={{"Byas", final = true}},
l={{"su", final = true}},
})
-- changing stem to weakest form
if vowel == "A" then
-- do nothing
elseif match(args.stem, "tirya/?c$") then -- specifically for tiryañc
args.stem = args.stem:gsub("ya(/?)c$", "a%1Sc")
elseif cons ~= "" then
args.stem = args.stem:gsub("()a(?)c$",
function(cons, acc) return (cons == "y" and "I" or "U") .. (acc == "" and "" or "/") .. "c" end)
elseif match(args.stem, "dac$") then
args.stem = args.stem:gsub("ac$", "Ic")
else
error("Not supported")
end
if vowel == "A" or oxy == "" then
if args.g == "m" then
decline(args, data, nil, nil, {
a="as",
})
else -- neuter
decline(args, data, nil, {
n="I",
v="I",
})
end
decline(args, data, {
i="A",
d="e",
ab="as",
l="i",
}, {
g="os",
}, {
g="Am",
})
else -- oxytone accent, showing two possible accentuations (Whitney §410)
if args.g == "m" then
decline(args, data, nil, nil, { a={"as", {"a" .. oxy .. "s", note = "Rigvedic", mono = true}} })
else
decline(args, data, nil, {
n= {"I", {"I" .. oxy, note = "Rigvedic", mono = true}},
v= "I",
})
end
decline(args, data, {
i= {"A", {"A" .. oxy, note = "Rigvedic", mono = true}},
d= {"e", {"e" .. oxy, note = "Rigvedic", mono = true}},
ab= {"as", {"a" .. oxy .. "s", note = "Rigvedic", mono = true}},
l= {"i", {"i" .. oxy, note = "Rigvedic", mono = true}},
}, {
g= {"os", {"o" .. oxy .. "s", note = "Rigvedic", mono = true}},
}, {
g= {"Am", {"A" .. oxy .. "m", note = "Rigvedic", mono = true}},
})
end
decline(args, data, {
g=""
}, {
a="",
d="",
ab="",
l="",
}, {
ab="",
})
-- not adding noun class (for now?) as these are all adjectives
end
})
decl_data = {
detect = make_detect("(.+)o" .. sa_utils.accent .. "?$")
}
setmetatable(decl_data, {
__call = function(self, args, data)
local oxy = match(args.lemma, "o(" .. sa_utils.accent .. "?)$")
data.decl_type = "o-stem"
if args.g ~= "n" or "f" or "m" then
decline(args, data, {
n="O" .. oxy .."s",
a="A" .. oxy .."m",
v="Os",
}, {
n={ "A" .. oxy .."vO", { "A" .. oxy .."vA", note = "Vedic" } },
v={ "AvO", { "AvA", note = "Vedic" } },
}, {
n="A" .. oxy .."vas",
a="A" .. oxy .."s",
v="Avas",
})
end
decline(args, data, {
i="+A",
d="+e",
ab="o" .. oxy .. "s",
g="",
l="+i",
}, {
a="",
i="+ByAm",
d="",
ab="",
g= "+os",
l="",
}, {
i="+Bis",
d="+Byas",
ab="",
g="+Am",
l="+su",
})
table.insert(data.categories, "Sanskrit o-stem nouns")
end
})
decl_data = {
detect = make_detect("(.+)O" .. sa_utils.accent .. "?$")
}
setmetatable(decl_data, {
__call = function(self, args, data)
local oxy = match(args.lemma, "O(" .. sa_utils.accent .. "?)$")
data.decl_type = "au-stem"
if args.g ~= "n" or "f" or "m" then
decline(args, data, {
n="+s",
a="+am",
v="+s",
}, {
n={ "+O", { "+A", note = "Vedic" } },
v={ "+O", { "+A", note = "Vedic" } },
}, {
n="+as",
v="+as"
})
end
decline(args, data, {
i= {{ "+A" .. oxy, mono = true }},
d= {{ "+e" .. oxy, mono = true }},
ab={{ "+a" .. oxy .. "s", mono = true }},
g="",
l= {{ "+i" .. oxy, mono = true }},
}, {
a="",
i= {{"+ByA" .. oxy .. "m", mono = true }},
d="",
ab="",
g= {{ "+o" .. oxy .. "s", mono = true }},
l="",
}, {
a="",
i= {{"+Bi" .. oxy .. "s", mono = true }},
d= {{"+Bya" .. oxy .. "s", mono = true }},
ab="",
g= {{ "+A" .. oxy .. "m", mono = true }},
l= {{ "+su" .. oxy, mono = true }},
})
table.insert(data.categories, "Sanskrit au-stem nouns")
end
})
decl_data = {
detect = make_detect("(.*)i?vA" .. sa_utils.accent .. "?Ms$",
function(args) return args.g == "m" or args.g == "n" end)
}
setmetatable(decl_data, {
__call = function(self, args, data)
local extra_i, oxy = match(args.lemma, "(i?)vA(" .. sa_utils.accent .. "?)Ms$")
data.decl_type = "vāṃs-stem"
if args.g == "m" then
decline(args, data, {
n= extra_i .. "vA" .. oxy .. "n",
a= extra_i .. "vA" .. oxy .. "Msam",
v={ extra_i .. "van", { extra_i .. "vas", note = "Rigvedic"} },
}, {
n= extra_i .. "vA" .. oxy .. "MsO",
a="",
v= extra_i .. "vAMsO",
}, {
n= extra_i .. "vA" .. oxy .. "Msas",
a="u" .. oxy .. "zas",
v= extra_i .. "vAMsas",
})
else
decline(args, data, {
n= extra_i .. "va" .. oxy .. "t",
a="",
v= extra_i .. "vat"
}, {
n="u" .. oxy .. "zI",
a="",
v="uzI",
}, {
n= extra_i .. "vA" .. oxy .. "MsI",
a="",
v= extra_i .. "vAMsI"
})
end
decline(args, data, {
i="u" .. oxy .. "zA",
d="u" .. oxy .. "ze",
ab="u" .. oxy .. "zas",
g="u" .. oxy .. "zas",
l="u" .. oxy .. "zi"
}, {
i= extra_i .. "va" .. oxy .. "dByAm",
d="",
ab="",
g="u" .. oxy .. "zos",
l=""
}, {
i= extra_i .. "va" .. oxy .. "dBis",
d= extra_i .. "va" .. oxy .. "dByas",
ab="u" .. oxy .. "zAm",
g="u" .. oxy .. "zAm",
l= extra_i .. "va" .. oxy .. "tsu"
})
table.insert(data.categories, "Sanskrit vāṃs-stem nouns")
end
})
return decl_data