Module:User:Surjection/cv-decl
- This module sandbox lacks a documentation subpage. You may create it.
- Useful links: root page • root page’s subpages • links • transclusions • testcases • user page • user talk page • userspace
This is a private module sandbox of Surjection, for their own experimentation. Items in this module may be added and removed at Surjection's discretion; do not rely on this module's stability.
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 {{{title}}}
|- class="vsHide" style="background:rgb(80%,80%,100%);vertical-align:top;"
! style="width:11em;" |
! style="width:12em;" | singular
! style="width:12em;" | plural
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);width:11em" | nominative
|style="width:12em" | {{{nom_sg}}}
|style="width:12em" | {{{nom_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | dative-accusative
|{{{acc_sg}}}
|{{{acc_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | genitive
|{{{gen_sg}}}
|{{{gen_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | instrumental
|{{{ins_sg}}}
|{{{ins_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | locative
|{{{loc_sg}}}
|{{{loc_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | ablative
|{{{abl_sg}}}
|{{{abl_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | abessive
|{{{abe_sg}}}
|{{{abe_pl}}}
|- class="vsHide" style="background:rgb(95%,95%,100%);vertical-align:top;" |
! style="background:rgb(80%,80%,100%);" | causative
|{{{cau_sg}}}
|{{{cau_pl}}}
|}]=]
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 "—"
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, "{{{([a-z0-9_:]+)}}}", 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