local export = {}
local KarachayBalkar = require "Module:languages".getByCode("krc")
local harmonic_types = {
["и"] = "front_unrounded",
["е"] = "front_unrounded", ["э"] = "front_unrounded",
["ы"] = "back_unrounded",
["у"] = "back_rounded", ["о"] = "back_rounded",
["ю"] = "rounded", -- ü, yu,
["ё"] = "rounded", -- ö,
["а"] = "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
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 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"] = (KarachayBalkar: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
local full_link = require "Module:links".full_link
local function link(term, tr)
return full_link({ term = term, lang = KarachayBalkar, 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 = [[
{| class="wikitable"
!
! Singular
! Plural
|-
! nominative
| {{{nom_sg}}}
| {{{nom_pl}}}
|-
! accusative
| {{{acc_sg}}}
| {{{acc_pl}}}
|-
! dative
| {{{dat_sg}}}
| {{{dat_pl}}}
|-
! locative
| {{{loc_sg}}}
| {{{loc_pl}}}
|-
! ablative
| {{{abl_sg}}}
| {{{abl_pl}}}
|-
! genitive
| {{{gen_sg}}}
| {{{gen_pl}}}
|}]]
local forms = export.generate_forms(stem, tr, is_back)
mw.log(make_testcase(forms))
return add_forms(template, forms)
end
return export