Module:kum-decl/sandbox

local export = {}

local Kumyk = require "Module:languages".getByCode("kum")

local harmonic_types = { ["и"] = "front_unrounded", ["е"] = "front_unrounded", ["э"] = "front_unrounded", ["ә"] = "front_unrounded", ["уь"] = "front_rounded", ["оь"] = "front_rounded", ["ы"] = "back_unrounded", ["у"] = "back_rounded", ["о"] = "back_rounded", ["ю"] = "rounded", -- ü, yü, yu	["ё"] = "rounded", -- ö, yö, yo	["а"] = "back_unrounded", ["я"] = "back_unrounded", }

local function last_harmonic_type_and_vowel(word) local harmonic_type, last_vowel for pos, vowel_digraph, vowel_letter in mw.ustring.gmatch(mw.ustring.lower(word), "(([иеэәуыоаяёю])ь?)") do		if harmonic_types[vowel_digraph] then last_vowel = vowel_digraph harmonic_type = harmonic_types[vowel_digraph] else last_vowel = vowel_letter harmonic_type = harmonic_types[vowel_letter] end end return harmonic_type, last_vowel end

local function split_vowel_dimensions(harmonic_type) local parts = mw.text.split(harmonic_type, "_") assert(#parts == 1 or #parts == 2) local roundedness = parts[#parts] local backness = #parts == 2 and parts[1] or nil return backness, roundedness end

-- Assumes that the only vowels in the ending are е or и. local function harmonize(stem, ending, is_back) local harmonic_type, last_vowel = last_harmonic_type_and_vowel(stem) if not harmonic_type then error("No last harmonic type for " .. tostring(stem)) end if (last_vowel == "ю" or last_vowel == "ё") and is_back then harmonic_type = harmonic_types["у"] end local backness, roundedness = split_vowel_dimensions(harmonic_type) return (mw.ustring.gsub(ending, "[геи]", function(letter) local result if letter == "е" then if not backness or backness == "front" then result = "е" else result = "а" end elseif letter == "и" then if not backness or backness == "front" then if not roundedness or roundedness == "unrounded" then result = "и" else result = "ю" end else if not roundedness or roundedness == "unrounded" then result = "ы" else result = "у" end end elseif letter == "г" then if not backness or backness == "front" then result = "г" else result = "гъ" end end local harmonic_type = last_harmonic_type_and_vowel(result) if harmonic_type then backness, roundedness = split_vowel_dimensions(harmonic_type) end return result end)) end

local possessive_suffixes = { {"1_sg", "им"}, {"1_pl", "ибиз"}, {"2_sg", "инг"}, {"2_pl", "игиз"}, {"3", "и"}, }

function export.generate_case_forms(stem, stem_translit, is_back) local forms = {} local function make_form(key, ending) ending = harmonize(stem, ending, is_back) forms[key] = stem .. ending if stem_translit then -- Transliterating a transliterated stem plus Cyrillic ending does -- not work in all cases, but should work with these noun endings. forms[key .. "_tr"] = Kumyk:transliterate(stem_translit .. ending) end end -- vowels given in front unrounded forms make_form("nom_sg", "") make_form("acc_sg", "ни") make_form("dat_sg", "ге") make_form("loc_sg", "де") make_form("abl_sg", "ден") make_form("gen_sg", "ни") make_form("nom_pl", "лер") make_form("acc_pl", "лени") make_form("dat_pl", "леге") make_form("loc_pl", "лерде") make_form("abl_pl", "лерден") make_form("gen_pl", "лени") return forms end

function export.generate_forms(stem, stem_translit, is_back) assert(type(stem) == "string") assert(stem_translit == nil or type(stem_translit) == "string") local forms = {} local basic_forms = export.generate_case_forms(stem, stem_translit, is_back) forms.basic = basic_forms for _, info in ipairs(possessive_suffixes) do		local code, possessive_suffix = unpack(info) local harmonized_suffix = harmonize(stem, possessive_suffix, is_back) local possessive_forms = export.generate_case_forms(			stem .. harmonized_suffix,			stem_translit .. harmonized_suffix,			is_back) forms[code] = possessive_forms end return forms end

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

local function add_forms(text, forms) return (text		:gsub( "",			function(code) local form = forms[code] local tr = forms[code .. "_tr"] if not form then return end if code == "testcase" then return form else return link(form, tr) end end)) end

local function make_testcase(forms) local number_abbrs = { "sg", "pl" } local case_abbrs = { "nom", "acc", "dat", "loc", "abl", "gen" } local rows = {} for _, number in ipairs(number_abbrs) do		local row = {} for _, case in ipairs(case_abbrs) do table.insert(row, forms[case .. "_" .. number]) end table.insert(rows, table.concat(row, " ")) end return table.concat(rows, "\n") end

function export.noun(frame) local args = frame:getParent.args local stem = args[1] or frame.args[1] local tr = args.tr or frame.args.tr	local is_back = require "Module:yesno"(args.back or frame.args.back, false) if stem then stem = mw.text.trim(stem) end if stem == "" then stem = nil end if not stem then local title = mw.title.getCurrentTitle local namespace = title.nsText if namespace == "" then stem = title.text else error("Parameter 1 (stem) is required.") end end local template = [[	local forms = export.generate_case_forms(stem, tr, is_back)	mw.log(make_testcase(forms))	return add_forms(template, forms) end

return export