Module:User:Surjection/cv-decl

local export = {} local m_links = require("Module:links") local lang = require("Module:languages").getByCode("cv")

-- vowel harmony

-- true for front, false for back. local function get_harmony(harmony) local index = mw.ustring.len(harmony) while index > 0 do		local character = mw.ustring.sub(harmony, index, index) if mw.ustring.find(character, "[иӳӗе]") then return true elseif mw.ustring.find(character, "[ыуӑао]") then return false end index = index - 1 end return false end

local function harmonize(suffix, harmony) if harmony then suffix = mw.ustring.gsub(suffix, "[аӑуы]", {			["а"] = "е", ["ӑ"] = "ӗ", ["у"] = "ӳ", ["ы"] = "и"		}) end return suffix end

-- utilities

local function add_form_with_suffix(forms, form, harmony, base, ...) local suffixes = { ... }   local results = {}

for _, suffix in ipairs(suffixes) do       table.insert(results, base .. harmonize(suffix, harmony)) end

forms[form] = results end

-- plural forms

local function inflect_plural(forms, nom_sg) add_form_with_suffix(forms, "nom_pl", nil, nom_sg, "сем") add_form_with_suffix(forms, "acc_pl", nil, nom_sg, "сене") add_form_with_suffix(forms, "gen_pl", nil, nom_sg, "сен", "сенӗн") add_form_with_suffix(forms, "ins_pl", nil, nom_sg, "семпе") add_form_with_suffix(forms, "loc_pl", nil, nom_sg, "сенче") add_form_with_suffix(forms, "abl_pl", nil, nom_sg, "сенчен") add_form_with_suffix(forms, "abe_pl", nil, nom_sg, "семсӗр") add_form_with_suffix(forms, "cau_pl", nil, nom_sg, "семшӗн") return forms end

-- inflection classes

local function inflect_consonant(nom_sg, stem, harmony) local forms = {["nom_sg"] = {nom_sg}} stem = stem or nom_sg add_form_with_suffix(forms, "acc_sg", harmony, stem, "а") add_form_with_suffix(forms, "gen_sg", harmony, stem, "ӑн") add_form_with_suffix(forms, "ins_sg", harmony, nom_sg, "па") add_form_with_suffix(forms, "loc_sg", harmony, nom_sg, "ра") add_form_with_suffix(forms, "abl_sg", harmony, nom_sg, "ран") add_form_with_suffix(forms, "abe_sg", harmony, nom_sg, "сӑр") add_form_with_suffix(forms, "cau_sg", harmony, nom_sg, "шӑн") return inflect_plural(forms, nom_sg) end

local function inflect_resonant(nom_sg, stem, harmony) local forms = {["nom_sg"] = {nom_sg}} stem = stem or nom_sg add_form_with_suffix(forms, "acc_sg", harmony, stem, "а") add_form_with_suffix(forms, "gen_sg", harmony, stem, "ӑн") add_form_with_suffix(forms, "ins_sg", harmony, nom_sg, "па") add_form_with_suffix(forms, "loc_sg", harmony, nom_sg, "та") add_form_with_suffix(forms, "abl_sg", harmony, nom_sg, "тан") add_form_with_suffix(forms, "abe_sg", harmony, nom_sg, "сӑр") add_form_with_suffix(forms, "cau_sg", harmony, nom_sg, "шӑн") return inflect_plural(forms, nom_sg) end

local function inflect_vowel(nom_sg, stem, harmony) local forms = {["nom_sg"] = {nom_sg}} stem = stem or nom_sg add_form_with_suffix(forms, "acc_sg", harmony, stem, "на") add_form_with_suffix(forms, "gen_sg", harmony, stem, "н") add_form_with_suffix(forms, "ins_sg", harmony, nom_sg, "па") add_form_with_suffix(forms, "loc_sg", harmony, nom_sg, "ра") add_form_with_suffix(forms, "abl_sg", harmony, nom_sg, "ран") add_form_with_suffix(forms, "abe_sg", harmony, nom_sg, "сӑр") add_form_with_suffix(forms, "cau_sg", harmony, nom_sg, "шӑн") return inflect_plural(forms, nom_sg) end

local function inflect_reduced(nom_sg, stem, harmony) local forms = {["nom_sg"] = {nom_sg}} if not stem then stem = mw.ustring.sub(nom_sg, 1, -2) local final_consonant = mw.ustring.sub(stem, -1, -1) if not mw.ustring.find(mw.ustring.sub(stem, -2, -2), final_consonant) then stem = stem .. final_consonant end end add_form_with_suffix(forms, "acc_sg", harmony, stem, "а") add_form_with_suffix(forms, "gen_sg", harmony, stem, "ӑн") add_form_with_suffix(forms, "ins_sg", harmony, nom_sg, "па") add_form_with_suffix(forms, "loc_sg", harmony, nom_sg, "ра") add_form_with_suffix(forms, "abl_sg", harmony, nom_sg, "ран") add_form_with_suffix(forms, "abe_sg", harmony, nom_sg, "сӑр") add_form_with_suffix(forms, "cau_sg", harmony, nom_sg, "шӑн") return inflect_plural(forms, nom_sg) end

local function inflect_rounded(nom_sg, stem, harmony) local forms = {["nom_sg"] = {nom_sg}} if not stem or not mw.ustring.find(stem, "в$") then error("Must specify a stem ending in в as the first parameter for nouns ending in у/ӳ in the nominative singular form") end add_form_with_suffix(forms, "acc_sg", harmony, stem, "а") add_form_with_suffix(forms, "gen_sg", harmony, stem, "ӑн") add_form_with_suffix(forms, "ins_sg", harmony, nom_sg, "па") add_form_with_suffix(forms, "loc_sg", harmony, nom_sg, "ра") add_form_with_suffix(forms, "abl_sg", harmony, nom_sg, "ран") add_form_with_suffix(forms, "abe_sg", harmony, nom_sg, "сӑр") add_form_with_suffix(forms, "cau_sg", harmony, nom_sg, "шӑн") return inflect_plural(forms, nom_sg) end

-- inflection entry point

local function inflect(nominative_singular, stem, harmony) harmony = get_harmony(harmony or stem or nominative_singular)

local final = mw.ustring.sub(nominative_singular, -1, -1) if mw.ustring.find(final, "[рлмн]") then return inflect_resonant(nominative_singular, stem, harmony) elseif mw.ustring.find(final, "[уӳ]") then return inflect_rounded(nominative_singular, stem, harmony) elseif mw.ustring.find(final, "[ӑӗ]") then return inflect_reduced(nominative_singular, stem, harmony) elseif mw.ustring.find(final, "[ае]") then return inflect_vowel(nominative_singular, stem, harmony) elseif mw.ustring.find(final, "[вйкпсҫтхчш]") then return inflect_consonant(nominative_singular, stem, harmony) else error("Unsupported inflection type") end end

-- inflection table

local infl_table = [=[{| class="inflection-table vsSwitcher" data-toggle-category="declension" style="border:1px solid #CCCCFF" !colspan=3 class="vsToggleElement" style="background:rgb(80%,80%,100%);text-align:left;"|Declension of ! style="width:11em;" | ! style="width:12em;" | singular ! style="width:12em;" | plural ! style="background:rgb(80%,80%,100%);width:11em" | nominative ! style="background:rgb(80%,80%,100%);" | dative-accusative ! style="background:rgb(80%,80%,100%);" | genitive ! style="background:rgb(80%,80%,100%);" | instrumental ! style="background:rgb(80%,80%,100%);" | locative ! style="background:rgb(80%,80%,100%);" | ablative ! style="background:rgb(80%,80%,100%);" | abessive ! style="background:rgb(80%,80%,100%);" | causative
 * - class="vsHide" style="background:rgb(80%,80%,100%);vertical-align:top;"
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * style="width:12em" |
 * style="width:12em" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * - class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
 * }]=]
 * }]=]
 * }]=]

local function link(text) return require("Module:links").full_link{ term = text, lang = lang } end

local function show_forms(data) local function repl(form) if form == "title" then return "'''" .. data.title .. "'''"		else local value = data[form] if not value then return "&mdash;" elseif type(value) == "table" then local result = {} for _, f in ipairs(value) do					table.insert(result, link(f)) end return table.concat(result, ", ") else return link(value) end end end

local result = mw.ustring.gsub(infl_table, "", repl) return result end

-- module entry point

function export.show(frame) local args = frame:getParent.args local title = args["title"] or mw.title.getCurrentTitle local stem = args[1] or nil local harmony = args[2] or nil

local forms = inflect(title, stem, harmony) forms["title"] = title return show_forms(forms) end

return export