মডিউল:be-noun-old
অবয়ব
এই মডিউলের জন্য মডিউল:be-noun-old/নথি-এ নথিপত্র তৈরি করা হয়ে থাকতে পারে
local strutils = require("Module:string utilities")
local export = {}
templates = {
["half"] = "be-decl-noun-unc|{nom_sg}|{gen_sg}|{dat_sg}|{acc_sg}|{ins_sg}|{loc_sg}",
["half_pl"] = "be-decl-noun-pl|{nom_pl}|{gen_pl}|{dat_pl}|{acc_pl}|{ins_pl}|{loc_pl}",
["full"] = "be-decl-noun|{nom_sg}|{nom_pl}|{gen_sg}|{gen_pl}|{dat_sg}|{dat_pl}|{acc_sg}|{acc_pl}|{ins_sg}|{ins_pl}|{loc_sg}|{loc_pl}"
}
-- Make the table
function make_table(args)
local temp = nil
if args.n == "s" then
temp = "half"
elseif args.n == "p" then
temp = "half_pl"
else
temp = "full"
end
return strutils.format(templates[temp], args)
end
-- "s" – lexical accent somewhere on the stem
-- "e" – accent on the ending
-- "1" – accent on the first syllable of the word
-- "<" – accent on the last syllable of the stem
accent_curves = {
["a"] = { ["nom_sg"] = "s", ["gen_sg"] = "s", ["dat_sg"] = "s", ["acc_sg"] = "s", ["ins_sg"] = "s", ["loc_sg"] = "s",
["nom_pl"] = "s", ["gen_pl"] = "s", ["dat_pl"] = "s", ["acc_pl"] = "s", ["ins_pl"] = "s", ["loc_pl"] = "s" },
["b"] = { ["nom_sg"] = "e", ["gen_sg"] = "e", ["dat_sg"] = "e", ["acc_sg"] = "e", ["ins_sg"] = "e", ["loc_sg"] = "e",
["nom_pl"] = "e", ["gen_pl"] = "e", ["dat_pl"] = "e", ["acc_pl"] = "e", ["ins_pl"] = "e", ["loc_pl"] = "e" },
["c"] = { ["nom_sg"] = "1", ["gen_sg"] = "1", ["dat_sg"] = "1", ["acc_sg"] = "1", ["ins_sg"] = "1", ["loc_sg"] = "1",
["nom_pl"] = "e", ["gen_pl"] = "e", ["dat_pl"] = "e", ["acc_pl"] = "e", ["ins_pl"] = "e", ["loc_pl"] = "e" },
["e"] = { ["nom_sg"] = "1", ["gen_sg"] = "1", ["dat_sg"] = "1", ["acc_sg"] = "1", ["ins_sg"] = "1", ["loc_sg"] = "1",
["nom_pl"] = "1", ["gen_pl"] = "e", ["dat_pl"] = "e", ["acc_pl"] = "1", ["ins_pl"] = "e", ["loc_pl"] = "e" },
["d"] = { ["nom_sg"] = "e", ["gen_sg"] = "e", ["dat_sg"] = "e", ["acc_sg"] = "e", ["ins_sg"] = "e", ["loc_sg"] = "e",
["nom_pl"] = "<", ["gen_pl"] = "<", ["dat_pl"] = "<", ["acc_pl"] = "<", ["ins_pl"] = "<", ["loc_pl"] = "<" },
["f"] = { ["nom_sg"] = "e", ["gen_sg"] = "e", ["dat_sg"] = "e", ["acc_sg"] = "e", ["ins_sg"] = "e", ["loc_sg"] = "e",
["nom_pl"] = "1", ["gen_pl"] = "e", ["dat_pl"] = "e", ["acc_pl"] = "1", ["ins_pl"] = "e", ["loc_pl"] = "e" },
["f''"] = { ["nom_sg"] = "e", ["gen_sg"] = "e", ["dat_sg"] = "e", ["acc_sg"] = "e", ["ins_sg"] = "<", ["loc_sg"] = "e",
["nom_pl"] = "<", ["gen_pl"] = "e", ["dat_pl"] = "e", ["acc_pl"] = "<", ["ins_pl"] = "e", ["loc_pl"] = "e" },
}
palat = { ["к"] = "ц", ["г"] = "з", ["х"] = "с", ["т"] = "ц", ["д"] = "дз" }
back = { ["е"] = "э", ["ё"] = "о", ["і"] = "ы", ["ь"] = "", ["ю"] = "у", ["я"] = "а" }
front = { ["э"] = "е", ["о"] = "ё", ["ы"] = "і", [""] = "ь", ["у"] = "ю", ["а"] = "я" }
function generate_form(stem, ending, accent)
stem = stem .. "/"
if accent == "e" and mw.ustring.match(ending, "[аеёіоуыюэя]") then
stem = mw.ustring.gsub(stem, mw.ustring.char(0x301), "")
ending = mw.ustring.gsub(ending, "([аеёіоуыюэя])(_?)", "%1" .. mw.ustring.char(0x301) .. "%2", 1)
else
ending = mw.ustring.gsub(ending, mw.ustring.char(0x301), "")
if accent == "1" then
ending = mw.ustring.gsub(ending, mw.ustring.char(0x301), "")
stem = mw.ustring.gsub(stem, "[аеёіоуыюэя]", "%1" .. mw.ustring.char(0x301), 1)
elseif accent ~= "s" then
if accent == "<" or not mw.ustring.match(ending, "[аеёіоуыюэя]") then
stem = mw.ustring.gsub(stem, "([аеёіоуыюэя∅])([^аеёіоуыюэя∅]*)/", "%1" .. mw.ustring.char(0x301) .. "%2/")
else
error("Accent undetermined")
end
end
end
form = "#" .. stem .. ending .. "#"
-- Handle reduced vowels
form = mw.ustring.gsub(form, "ь∅(" .. mw.ustring.char(0x301) .. "[^аеёіоуыюэя]ь)", "ье_%1")
form = mw.ustring.gsub(form, "ь∅(" .. mw.ustring.char(0x301) .. "[йцчшж])", "ье_%1")
form = mw.ustring.gsub(form, "∅" .. mw.ustring.char(0x301), "о_" .. mw.ustring.char(0x301))
form = mw.ustring.gsub(form, "ь∅([^аеёіоуыюэя]ь/[^аеёіоуыюэя])", "ье_%1")
form = mw.ustring.gsub(form, "ь∅([йцчшж]/[^аеёіоуыюэя])", "ье_%1")
form = mw.ustring.gsub(form, "∅([^аеёіоуыюэя]*/[^аеёіоуыюэя])", "о_%1")
form = mw.ustring.gsub(form, "ль∅", "ль")
form = mw.ustring.gsub(form, "([цсзн])ь∅([бпмвфкгх])", "%1ь%2")
form = mw.ustring.gsub(form, "ць∅", "т")
form = mw.ustring.gsub(form, "дзь∅", "д")
form = mw.ustring.gsub(form, "ь?∅", "")
-- Syllabic sonorants
form = mw.ustring.gsub(form, "([^аеёіоуыюэя/_" .. mw.ustring.char(0x301) .. "][рл])([^аеёіоуыюэя/])", "%1ы%2")
-- Vocalic /v/
form = mw.ustring.gsub(form, "вь?(/?[^/аеёіоуьыюэя])", "ў%1")
form = mw.ustring.gsub(form, "([^/_∅аеёіоуыюэябпфмрйў" .. mw.ustring.char(0x301) .. "])(ь?)(/?)й", "%1%1%2%3")
-- ‘Soft’ vowel letters
form = mw.ustring.gsub(form, "ь(/?)([аоуыэ])", function (a, b) return a .. front[b] end)
form = mw.ustring.gsub(form, "ь(/?)([еёіюя])", function (a, b) return a .. b end)
form = mw.ustring.gsub(form, "й(/?)([аоуыэ])", function (a, b) return a .. front[b] end)
form = mw.ustring.gsub(form, "й/([еёіюя])", "/%1")
-- Velar palatalisation
form = mw.ustring.gsub(form, "([кгх])(/[еі])", function (a, b) return palat[a] .. b end)
-- Vowel reduction
form = mw.ustring.gsub(form, "о_([^" .. mw.ustring.char(0x301) .. "])", "а%1")
form = mw.ustring.gsub(form, "ё_([^" .. mw.ustring.char(0x301) .. "])", "е%1")
form = mw.ustring.gsub(form, "е_([^" .. mw.ustring.char(0x301) .. "][^аеёіоуыюэя]*[аеёіоуыюэя]_?" .. mw.ustring.char(0x301) .. ")", "я%1")
form = mw.ustring.gsub(form, "э_([^" .. mw.ustring.char(0x301) .. "][^аеёіоуыюэя]*[аеёіоуыюэя]_?" .. mw.ustring.char(0x301) .. ")", "а%1")
-- Prosthetic /v/
form = mw.ustring.gsub(form, "#о́_", "во́")
-- Deaccent monosyllabic forms
if not mw.ustring.match(form, "[аеёіоуыюэя][^ ]*[аеёіоуыюэя]") then
form = mw.ustring.gsub(form, mw.ustring.char(0x301), "")
end
-- /ɨ/ fronting after velars
form = mw.ustring.gsub(form, "([кгх])/ы", "%1/і")
-- Hard-only consonants
form = mw.ustring.gsub(form, "([рцчшж])/([еёіьюя])", function (a, b) return a .. "/" .. back[b] end)
-- Dental assibilation
form = mw.ustring.gsub(form, "([тд])/([еёіьюя])", function (a, b) return palat[a] .. "/" .. b end)
-- Strip juncture marks
form = mw.ustring.gsub(form, "[_/#]", "")
-- Deaccent ё
form = mw.ustring.gsub(form, "ё" .. mw.ustring.char(0x301), "ё")
return form
end
function generate_forms(args)
local forms = {}
term = args["term"]
if not term then
error("No term specified")
end
decl = args["decl"]
number = args["number"]
gender = args["gender"]
animate = args["animate"]
accent = args["accent"]
reduced = args["reduced"]
number = args["number"]
if (not accent) or (accent == "a") then
if mw.ustring.match(term, "[аеёіоуыюэя][^ ]*[аеёіоуыюэя]") then
acute = mw.ustring.find(term, mw.ustring.char(0x301))
if acute == mw.ustring.len(term) then
term = mw.ustring.sub(term, 1, -2)
ending = mw.ustring.sub(term, -1)
if ending == "а" or ending == "я" then
gender = "f"
end
accent = "b"
elseif not acute then
error("Accent must be given")
else
if not mw.ustring.find(term, mw.ustring.char(0x301), acute + 1) then
accent = "a"
else
error("Only one accent must be specified")
end
end
else
term = mw.ustring.gsub(term, "([аеёіоуыюэя])([^ ])", "%1" .. mw.ustring.char(0x301) .. "%2")
accent = "a"
end
else
term = mw.ustring.gsub(term, mw.ustring.char(0x301), "")
end
local stem = mw.ustring.sub(term, 1, -2)
local ending = mw.ustring.sub(term, -1)
if ending == "ы" or number == "p" then
gender = ""
number = "p"
end
if gender == "f" then
if ending == "ь" then
decl = "i"
stem = stem .. "ь"
elseif ending == "ў" then
decl = "i"
stem = stem .. "вь"
else
if ending == "я" then
stem = stem .. "ь"
decl = "a"
elseif ending ~= "а" then
if mw.ustring.match(ending, "[чшжр]") then
if not (decl or (accent == "a" or accent == "b")) then
error("Must specify declension")
else
stem = stem .. ending
end
else
stem = stem .. ending
decl = "a"
end
else
decl = "a"
end
end
else
decl = "o"
if ending ~= "а" then
gender = "n"
if ending ~= "о" then
if ending == "е" then
stem = stem .. "ь"
else
gender = "m"
stem = stem .. ending
end
end
elseif not gender then
error("Gender must be specified")
end
end
-- Mark reduced vowels
if reduced then
stem = mw.ustring.gsub(stem .. "/", "([^аеёіоуъьыюэя])[её]([^аеёіоуъьыюэя]ь?)/", "%1ь%2")
stem = mw.ustring.gsub(stem .. "/", "([^аеёіоуъыюэя])[оа]?([^аеёіоуъьыюэя]ь?)//?", "%1∅%2")
end
local datloc_sg = function()
if gender == "m" then
if accent_curves[accent]["dat_sg"] ~= "e" or mw.ustring.match(stem .. "/", "[кгх]/") then
return "у"
else
return mw.ustring.match(stem .. "/", "ь/") and "і" or "е"
end
else
if mw.ustring.sub(stem, -1) == "к" then
return accent_curves[accent]["dat_sg"] == "e" and "е" or "і"
else
return mw.ustring.find(stem .. "/", "[рцчшж]/") and "ы" or "е"
end
end
end
local gen_pl = function()
if mw.ustring.match(stem .. "/", "[^аеёіоуыюэя∅_" .. mw.ustring.char(0x301) .. "][^аеёіоуъьыюэя]ь?/") then
return "о_ў"
else
return ""
end
end
endings_sg = {
["a"] = { ["nom_sg"] = "а", ["gen_sg"] = "ы", ["dat_sg"] = datloc_sg, ["acc_sg"] = "у", ["ins_sg"] = "о_й", ["loc_sg"] = datloc_sg },
["o"] = { ["nom_sg"] = function() return gender == "n" and "о_" or "" end, ["gen_sg"] = function() return number == "s" and "у" or "а" end, ["dat_sg"] = "у", ["ins_sg"] = "о_м",
["loc_sg"] = function() return mw.ustring.match(stem .. "/", "[кгх]/") and "у" or (mw.ustring.match(stem .. "/", "[йь]/") and "і" or "е") end },
["i"] = { ["nom_sg"] = "", ["gen_sg"] = "і", ["dat_sg"] = "і", ["ins_sg"] = "йу", ["loc_sg"] = "і" }
}
endings_pl = { ["nom_pl"] = "ы", ["gen_pl"] = function() return gender == "m" and "о_ў" or (decl == "i" and "ей" or gen_pl()) end, ["dat_pl"] = "ам", ["ins_pl"] = "амі", ["loc_pl"] = "ах" }
-- Mark reducible vowels
for k, v in pairs(accent_curves[accent]) do
ending = endings_sg[decl][k] or endings_pl[k]
if type(ending) == "function" then
ending = ending()
end
if v ~= "s" then
if v == "1" then
stem = mw.ustring.gsub(stem, "[аеёіоуыюэя]", "%1_", 1)
elseif v == "<" or ending == "" then
stem = mw.ustring.gsub(stem .. "/", "([аеёіоуыюэя∅])([^аеёіоуыюэя∅]*)/", "%1_%2", 1)
stem = mw.ustring.gsub(stem .. "/", "([аеёіоуыюэя∅])([^аеёіоуыюэя∅]*[аеёіоуыюэя∅][^аеёіоуыюэя∅]*)/", "%1_%2", 1)
stem = mw.ustring.gsub(stem, "∅_", "∅") -- redundant
stem = mw.ustring.gsub(stem, "/", "")
end
end
end
for k, v in pairs(endings_sg[decl]) do
if type(v) == "function" then v = v() end
forms[k] = generate_form(stem, v, accent_curves[accent][k])
end
if decl ~= "a" then
if gender == "m" and animate then
forms["acc_sg"] = forms["gen_sg"]
else
forms["acc_sg"] = forms["nom_sg"]
end
end
for k, v in pairs(endings_pl) do
if type(v) == "function" then v = v() end
forms[k] = generate_form(stem, v, accent_curves[accent][k])
end
if animate then
forms["acc_pl"] = forms["gen_pl"]
else
forms["acc_pl"] = forms["nom_pl"]
end
forms.n = number
return forms
end
function export.decline(term, gender, animate, accent, reduced, number, decl)
term = mw.ustring.gsub(term, "ѐ", "ѐ")
term = mw.ustring.gsub(term, "ѝ", "ѝ")
return mw.ustring.toNFC("{{" .. make_table(generate_forms({ ["term"] = term, ["gender"] = gender, ["animate"] = animate, ["accent"] = accent, ["reduced"] = reduced, ["number"] = number, ["decl"] = decl })) .. "}}")
end
return export