Moduł:odmiana-rzeczownik-kirgiski
Wygląd
Moduł wykorzystywany przez szablon {{odmiana-rzeczownik-kirgiski}}.
local p = {}
local KYRGYZ_VOICELESS_CONSONANTS = 'пфктшсхцчщ' -- voiceless consonants
local KYRGYZ_VOICED_CONSONANTS = 'бвгджзлмнрй' -- voiced consonants
local KYRGYZ_VOWELS = 'аыоуэеиөү'
endings = require('Moduł:odmiana-rzeczownik-kirgiski/końcówki')
--[[ Helper functions ]]
x_in_y = function(x, y, on_true, on_false)
if not y then return on_false or false end
for _, n in pairs(y) do
if x == n then
return on_true or true
end
end
return on_false or false
end
ifexpr = function(cond, on_true, on_false)
if cond then
return on_true
end
return on_false
end
is_string_empty = function(x)
return x == nil or x == ''
end
ends_with = function(str, pattern)
if is_string_empty(str) or is_string_empty(pattern) then
return false
end
return mw.ustring.sub(str, -#pattern) == pattern
end
--[[ Other helper functions to construct a suffix ]]
is_vowel = function(letter)
if is_string_empty(letter) then
return false
end
return mw.ustring.find(KYRGYZ_VOWELS, letter, 1, true) ~= nil
end
is_voiceless_consonant = function(letter)
if is_string_empty(letter) then
return false
end
return mw.ustring.find(KYRGYZ_VOICELESS_CONSONANTS, letter, 1, true) ~= nil
end
is_voiced_consonant = function(letter)
if is_string_empty(letter) then
return false
end
return mw.ustring.find(KYRGYZ_VOICED_CONSONANTS, letter, 1, true) ~= nil
end
get_last_letter_type = function(stem)
if is_string_empty(stem) then
return 'V' -- default to vowel type
end
local final_letter = mw.ustring.sub(stem, -1)
if is_vowel(final_letter) then
return 'V'
elseif is_voiceless_consonant(final_letter) then
return 'T' -- T for voiceless
elseif is_voiced_consonant(final_letter) then
return 'D' -- D for voiced
end
return 'V' -- default to vowel type for other characters
end
get_last_vowel_of_stem = function(stem)
if is_string_empty(stem) then
return 'а' -- default vowel
end
for i = -1,-#stem,-1 do
local letter = mw.ustring.sub(stem, i, i)
if is_vowel(letter) then
return letter
end
end
return 'а' -- default vowel if no vowel found
end
get_vowel_harmony = function(letter)
if not is_vowel(letter) then
return 'а' -- default vowel
end
local types = {
['а'] = 'а',
['ы'] = 'ы',
['о'] = 'о',
['у'] = 'у',
['э'] = 'э',
['е'] = 'е',
['и'] = 'и',
['ө'] = 'ө',
['ү'] = 'ү'
}
return types[letter] or 'а'
end
-- Parameter [1] is used only for singular possessive forms
get_plural_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local plural_map = {
['а'] = 'лар',
['ы'] = 'лар',
['о'] = 'лор',
['у'] = 'лар',
['э'] = 'лер',
['е'] = 'лер',
['и'] = 'лер',
['ө'] = 'лөр',
['ү'] = 'лөр'
}
return plural_map[letter] or 'лар'
elseif stem_type == 'D' then
local plural_map = {
['а'] = 'дар',
['ы'] = 'дар',
['о'] = 'дор',
['у'] = 'дар',
['э'] = 'дер',
['е'] = 'дер',
['и'] = 'дер',
['ө'] = 'дөр',
['ү'] = 'дөр'
}
return plural_map[letter] or 'дар'
else -- 'T' voiceless
local plural_map = {
['а'] = 'тар',
['ы'] = 'тар',
['о'] = 'тор',
['у'] = 'тар',
['э'] = 'тер',
['е'] = 'тер',
['и'] = 'тер',
['ө'] = 'төр',
['ү'] = 'төр'
}
return plural_map[letter] or 'тар'
end
end
get_genitive_suffix = function(letter, stem_type)
if stem_type == 'V' then
local genitive_map = {
['а'] = 'нын',
['ы'] = 'нын',
['о'] = 'нун',
['у'] = 'нун',
['э'] = 'нин',
['е'] = 'нин',
['и'] = 'нин',
['ө'] = 'нүн',
['ү'] = 'нүн'
}
return genitive_map[letter] or 'нын'
elseif stem_type == 'D' or stem_type == 'й' or stem_type == 'р' then
local genitive_map = {
['а'] = 'дын',
['ы'] = 'дын',
['о'] = 'дун',
['у'] = 'дун',
['э'] = 'дин',
['е'] = 'дин',
['и'] = 'дин',
['ө'] = 'дүн',
['ү'] = 'дүн'
}
return genitive_map[letter] or 'дын'
else -- 'T' voiceless
local genitive_map = {
['а'] = 'тын',
['ы'] = 'тын',
['о'] = 'тун',
['у'] = 'тун',
['э'] = 'тин',
['е'] = 'тин',
['и'] = 'тин',
['ө'] = 'түн',
['ү'] = 'түн'
}
return genitive_map[letter] or 'тын'
end
end
get_genitive_plural_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local genitive_map = {
['а'] = 'дын',
['ы'] = 'дын',
['о'] = 'дун',
['у'] = 'дын',
['э'] = 'дин',
['е'] = 'дин',
['и'] = 'дин',
['ө'] = 'дүн',
['ү'] = 'дүн'
}
return genitive_map[letter] or 'дын'
else
local genitive_map = {
['а'] = 'дын',
['ы'] = 'дын',
['о'] = 'дун',
['у'] = 'дын',
['э'] = 'дин',
['е'] = 'дин',
['и'] = 'дин',
['ө'] = 'дүн',
['ү'] = 'дүн'
}
return genitive_map[letter] or 'дын'
end
end
get_dative_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local dative_map = {
['а'] = 'га',
['ы'] = 'га',
['о'] = 'го',
['у'] = 'га',
['э'] = 'ге',
['е'] = 'ге',
['и'] = 'ге',
['ө'] = 'гө',
['ү'] = 'гө'
}
return dative_map[letter] or 'га'
elseif stem_type == 'D' then
local dative_map = {
['а'] = 'га',
['ы'] = 'га',
['о'] = 'го',
['у'] = 'га',
['э'] = 'ге',
['е'] = 'ге',
['и'] = 'ге',
['ө'] = 'гө',
['ү'] = 'гө'
}
return dative_map[letter] or 'га'
else -- 'T' voiceless
local dative_map = {
['а'] = 'ка',
['ы'] = 'ка',
['о'] = 'ко',
['у'] = 'ка',
['э'] = 'ке',
['е'] = 'ке',
['и'] = 'ке',
['ө'] = 'кө',
['ү'] = 'кө'
}
return dative_map[letter] or 'ка'
end
end
get_dative_plural_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local dative_map = {
['а'] = 'га',
['ы'] = 'га',
['о'] = 'го',
['у'] = 'га',
['э'] = 'ге',
['е'] = 'ге',
['и'] = 'ге',
['ө'] = 'гө',
['ү'] = 'гө'
}
return dative_map[letter] or 'га'
else
local dative_map = {
['а'] = 'га',
['ы'] = 'га',
['о'] = 'го',
['у'] = 'га',
['э'] = 'ге',
['е'] = 'ге',
['и'] = 'ге',
['ө'] = 'гө',
['ү'] = 'гө'
}
return dative_map[letter] or 'га'
end
end
get_accusative_suffix = function(letter, stem_type)
if stem_type == 'V' then
local accusative_map = {
['а'] = 'ны',
['ы'] = 'ны',
['о'] = 'ну',
['у'] = 'ну',
['э'] = 'ни',
['е'] = 'ни',
['и'] = 'ни',
['ө'] = 'нү',
['ү'] = 'нү'
}
return accusative_map[letter] or 'ны'
elseif stem_type == 'D' or stem_type == 'й' or stem_type == 'р' then
local accusative_map = {
['а'] = 'ды',
['ы'] = 'ды',
['о'] = 'ду',
['у'] = 'ду',
['э'] = 'ди',
['е'] = 'ди',
['и'] = 'ди',
['ө'] = 'дү',
['ү'] = 'дү'
}
return accusative_map[letter] or 'ды'
else -- 'T' voiceless
local accusative_map = {
['а'] = 'ты',
['ы'] = 'ты',
['о'] = 'ту',
['у'] = 'ту',
['э'] = 'ти',
['е'] = 'ти',
['и'] = 'ти',
['ө'] = 'тү',
['ү'] = 'тү'
}
return accusative_map[letter] or 'ты'
end
end
get_accusative_plural_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local accusative_map = {
['а'] = 'ды',
['ы'] = 'ды',
['о'] = 'ду',
['у'] = 'ду',
['э'] = 'ди',
['е'] = 'ди',
['и'] = 'ди',
['ө'] = 'дү',
['ү'] = 'дү'
}
return accusative_map[letter] or 'ды'
else
local accusative_map = {
['а'] = 'ды',
['ы'] = 'ды',
['о'] = 'ду',
['у'] = 'ды',
['э'] = 'ди',
['е'] = 'ди',
['и'] = 'ди',
['ө'] = 'дү',
['ү'] = 'дү'
}
return accusative_map[letter] or 'ды'
end
end
get_locative_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local locative_map = {
['а'] = 'да',
['ы'] = 'да',
['о'] = 'до',
['у'] = 'до',
['э'] = 'де',
['е'] = 'де',
['и'] = 'де',
['ө'] = 'дө',
['ү'] = 'дө'
}
return locative_map[letter] or 'да'
elseif stem_type == 'D' then
local locative_map = {
['а'] = 'да',
['ы'] = 'да',
['о'] = 'до',
['у'] = 'да',
['э'] = 'де',
['е'] = 'де',
['и'] = 'де',
['ө'] = 'дө',
['ү'] = 'дө'
}
return locative_map[letter] or 'да'
else -- 'T' voiceless
local locative_map = {
['а'] = 'та',
['ы'] = 'та',
['о'] = 'то',
['у'] = 'та',
['э'] = 'те',
['е'] = 'те',
['и'] = 'те',
['ө'] = 'тө',
['ү'] = 'тө'
}
return locative_map[letter] or 'та'
end
end
get_locative_plural_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local locative_map = {
['а'] = 'да',
['ы'] = 'да',
['о'] = 'до',
['у'] = 'да',
['э'] = 'де',
['е'] = 'де',
['и'] = 'де',
['ө'] = 'дө',
['ү'] = 'дө'
}
return locative_map[letter] or 'да'
else
local locative_map = {
['а'] = 'да',
['ы'] = 'да',
['о'] = 'до',
['у'] = 'да',
['э'] = 'де',
['е'] = 'де',
['и'] = 'де',
['ө'] = 'дө',
['ү'] = 'дө'
}
return locative_map[letter] or 'да'
end
end
get_ablative_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local ablative_map = {
['а'] = 'дан',
['ы'] = 'дан',
['о'] = 'дон',
['у'] = 'дан',
['э'] = 'ден',
['е'] = 'ден',
['и'] = 'ден',
['ө'] = 'дөн',
['ү'] = 'дөн'
}
return ablative_map[letter] or 'дан'
elseif stem_type == 'D' then
local ablative_map = {
['а'] = 'дан',
['ы'] = 'дан',
['о'] = 'дон',
['у'] = 'дан',
['э'] = 'ден',
['е'] = 'ден',
['и'] = 'ден',
['ө'] = 'дөн',
['ү'] = 'дөн'
}
return ablative_map[letter] or 'дан'
else -- 'T' voiceless
local ablative_map = {
['а'] = 'тан',
['ы'] = 'тан',
['о'] = 'тон',
['у'] = 'тан',
['э'] = 'тен',
['е'] = 'тен',
['и'] = 'тен',
['ө'] = 'төн',
['ү'] = 'төн'
}
return ablative_map[letter] or 'тан'
end
end
get_ablative_plural_suffix = function(letter, stem_type)
if stem_type == 'V' or stem_type == 'й' or stem_type == 'р' then
local ablative_map = {
['а'] = 'дан',
['ы'] = 'дан',
['о'] = 'дон',
['у'] = 'дан',
['э'] = 'ден',
['е'] = 'ден',
['и'] = 'ден',
['ө'] = 'дөн',
['ү'] = 'дөн'
}
return ablative_map[letter] or 'дан'
else
local ablative_map = {
['а'] = 'дан',
['ы'] = 'дан',
['о'] = 'дон',
['у'] = 'дан',
['э'] = 'ден',
['е'] = 'ден',
['и'] = 'ден',
['ө'] = 'дөн',
['ү'] = 'дөн'
}
return ablative_map[letter] or 'дан'
end
end
p.get_buffer_letter = function(letter_table, class, default)
return letter_table[class] or default or ''
end
p.has_dropping_vowel = function(x, y)
if is_string_empty(x) or is_string_empty(y) or x == y then
return false
end
local length = ifexpr(
mw.ustring.len(x) < mw.ustring.len(y),
mw.ustring.len(x),
mw.ustring.len(y))
for i=1,length do
local fx = mw.ustring.sub(x, i, i)
local fy = mw.ustring.sub(y, i, i)
if fx ~= fy then
return is_vowel(fx)
end
end
return false
end
construct_noun_ending = function(stem, pattern, ending_vowel, final_stem_class, is_possessive, is_plural_possessive)
local ending = pattern
local last_vowel = ending_vowel or get_last_vowel_of_stem(stem)
local stem_type = final_stem_class or get_last_letter_type(stem)
local special_chars = {
['{Vh}'] = function()
return get_vowel_harmony(last_vowel)
end,
['{P}'] = function()
return get_plural_suffix(last_vowel, stem_type)
end,
['{N}'] = function()
return get_genitive_suffix(last_vowel, stem_type)
end,
['{N2}'] = function()
return get_genitive_plural_suffix(last_vowel, stem_type)
end,
['{Da}'] = function()
return get_dative_suffix(last_vowel, stem_type)
end,
['{Da2}'] = function()
return get_dative_plural_suffix(last_vowel, stem_type)
end,
['{A}'] = function()
return get_accusative_suffix(last_vowel, stem_type)
end,
['{A2}'] = function()
return get_accusative_plural_suffix(last_vowel, stem_type)
end,
['{L}'] = function()
return get_locative_suffix(last_vowel, stem_type)
end,
['{L2}'] = function()
return get_locative_plural_suffix(last_vowel, stem_type)
end,
['{Ab}'] = function()
return get_ablative_suffix(last_vowel, stem_type)
end,
['{Ab2}'] = function()
return get_ablative_plural_suffix(last_vowel, stem_type)
end,
-- Singular possessive - use the current stem (which could be parameter [1])
['{Ps1sg}'] = function()
if stem_type == 'V' then
return 'м'
else
local vowel = get_vowel_harmony(last_vowel)
local third_person_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return third_person_map[vowel] .. 'м'
end
end,
['{Ps2sg}'] = function()
if stem_type == 'V' then
return 'ң'
else
local vowel = get_vowel_harmony(last_vowel)
local third_person_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return third_person_map[vowel] .. 'ң'
end
end,
['{Ps2sgf}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local formal_map = {
['а'] = 'ңыз',
['ы'] = 'ңыз',
['о'] = 'ңуз',
['у'] = 'ңуз',
['э'] = 'ңиз',
['е'] = 'ңиз',
['и'] = 'ңиз',
['ө'] = 'ңүз',
['ү'] = 'ңүз'
}
return formal_map[vowel] or 'ңыз'
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local formal_map = {
['а'] = 'ңыз',
['ы'] = 'ңыз',
['о'] = 'ңуз',
['у'] = 'ңуз',
['э'] = 'ңиз',
['е'] = 'ңиз',
['и'] = 'ңиз',
['ө'] = 'ңүз',
['ү'] = 'ңүз'
}
return possessive_vowel_map[vowel] .. (formal_map[vowel] or 'ңыз')
end
end,
['{Ps3sg}'] = function()
if stem_type == 'V' then
-- For vowel-ending stems: -сы/-си/-су/-сү
local vowel = get_vowel_harmony(last_vowel)
local third_person_map = {
['а'] = 'сы',
['ы'] = 'сы',
['о'] = 'су',
['у'] = 'су',
['э'] = 'си',
['е'] = 'си',
['и'] = 'си',
['ө'] = 'сү',
['ү'] = 'сү'
}
return third_person_map[vowel] or 'сы'
else
local vowel = get_vowel_harmony(last_vowel)
local third_person_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return third_person_map[vowel] or 'ы'
end
end,
['{Ps1pl}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local plural_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'буз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return plural_map[vowel] or 'быз'
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'буз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return (possessive_vowel_map[vowel] or 'ы') .. (plural_map[vowel] or 'быз')
end
end,
['{Ps2pl}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local plural_map = {
['а'] = 'ңар',
['ы'] = 'ңар',
['о'] = 'ңор',
['у'] = 'ңар',
['э'] = 'ңер',
['е'] = 'ңeр',
['и'] = 'ңер',
['ө'] = 'ңөр',
['ү'] = 'ңөр'
}
return plural_map[vowel] or 'ңар'
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_map = {
['а'] = 'ңар',
['ы'] = 'ңар',
['о'] = 'ңар',
['у'] = 'ңар',
['э'] = 'ңер',
['е'] = 'ңер',
['и'] = 'ңер',
['ө'] = 'ңөр',
['ү'] = 'ңөр'
}
return (possessive_vowel_map[vowel] or 'ы') .. (plural_map[vowel] or 'ңар')
end
end,
['{Ps2plf}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local formal_map = {
['а'] = 'ңыздар',
['ы'] = 'ңыздар',
['о'] = 'ңуздар',
['у'] = 'ңуздар',
['э'] = 'ңиздер',
['е'] = 'ңиздер',
['и'] = 'ңиздер',
['ө'] = 'ңүздөр',
['ү'] = 'ңүздөр'
}
return formal_map[vowel] or 'ңыздар'
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local formal_map = {
['а'] = 'ңыздар',
['ы'] = 'ңыздар',
['о'] = 'ңуздар',
['у'] = 'ңуздар',
['э'] = 'ңиздер',
['е'] = 'ңиздер',
['и'] = 'ңиздер',
['ө'] = 'ңүздөр',
['ү'] = 'ңүздөр'
}
return (possessive_vowel_map[vowel] or 'ы') .. (formal_map[vowel] or 'ңыздар')
end
end,
['{Ps3pl}'] = function()
if stem_type == 'V' then
-- For vowel-ending stems: -сы/-си/-су/-сү
local vowel = get_vowel_harmony(last_vowel)
local third_person_map = {
['а'] = 'сы',
['ы'] = 'сы',
['о'] = 'су',
['у'] = 'су',
['э'] = 'си',
['е'] = 'си',
['и'] = 'си',
['ө'] = 'сү',
['ү'] = 'сү'
}
return third_person_map[vowel] or 'сы'
else
-- For consonant-ending stems: just the vowel
return get_vowel_harmony(last_vowel)
end
end,
-- Plural possessive - these will use the basic stem (not parameter [1])
['{Pps1sg}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. 'м'
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. 'м'
end
end,
['{Pps2sg}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. 'ң'
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. 'ң'
end
end,
['{Pps2sgf}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'ңыз',
['ы'] = 'ңыз',
['о'] = 'ңуз',
['у'] = 'ңыз',
['э'] = 'ңиз',
['е'] = 'ңиз',
['и'] = 'ңиз',
['ө'] = 'ңүз',
['ү'] = 'ңүз'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'ңыз')
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'ңыз',
['ы'] = 'ңыз',
['о'] = 'ңуз',
['у'] = 'ңыз',
['э'] = 'ңиз',
['е'] = 'ңиз',
['и'] = 'ңиз',
['ө'] = 'ңүз',
['ү'] = 'ңүз'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'ңыз')
end
end,
['{Pps3sg}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы')
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'у',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы')
end
end,
['{Pps1pl}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'быз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'быз')
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'быз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'быз')
end
end,
['{Pps2pl}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'ңар',
['ы'] = 'ңар',
['о'] = 'ңар',
['у'] = 'ңар',
['э'] = 'ңер',
['е'] = 'ңер',
['и'] = 'ңер',
['ө'] = 'ңөр',
['ү'] = 'ңөр'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'ңар')
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'ңар',
['ы'] = 'ңар',
['о'] = 'ңар',
['у'] = 'ңар',
['э'] = 'ңер',
['е'] = 'ңер',
['и'] = 'ңер',
['ө'] = 'ңөр',
['ү'] = 'ңөр'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'ңар')
end
end,
['{Pps2plf}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'ңыздар',
['ы'] = 'ңыздар',
['о'] = 'ңуздар',
['у'] = 'ңыздар',
['э'] = 'ңиздер',
['е'] = 'ңиздер',
['и'] = 'ңиздер',
['ө'] = 'ңүздөр',
['ү'] = 'ңүздөр'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'ңыздар')
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
local plural_ending_map = {
['а'] = 'ңыздар',
['ы'] = 'ңыздар',
['о'] = 'ңуздар',
['у'] = 'ңыздар',
['э'] = 'ңиздер',
['е'] = 'ңиздер',
['и'] = 'ңиздер',
['ө'] = 'ңүздөр',
['ү'] = 'ңүздөр'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы') .. (plural_ending_map[vowel] or 'ңыздар')
end
end,
['{Pps3pl}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы')
else
local vowel = get_vowel_harmony(last_vowel)
local possessive_vowel_map = {
['а'] = 'ы',
['ы'] = 'ы',
['о'] = 'у',
['у'] = 'ы',
['э'] = 'и',
['е'] = 'и',
['и'] = 'и',
['ө'] = 'ү',
['ү'] = 'ү'
}
return plural_suffix .. (possessive_vowel_map[vowel] or 'ы')
end
end,
-- Predicate forms
['{Pr1sg}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'мын',
['ы'] = 'мын',
['о'] = 'мун',
['у'] = 'мун',
['э'] = 'мин',
['е'] = 'мин',
['и'] = 'мин',
['ө'] = 'мүн',
['ү'] = 'мүн'
}
return predicate_map[vowel] or 'мын'
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'мын',
['ы'] = 'мын',
['о'] = 'мун',
['у'] = 'мун',
['э'] = 'мин',
['е'] = 'мин',
['и'] = 'мин',
['ө'] = 'мүн',
['ү'] = 'мүн'
}
return predicate_map[vowel] or 'мын'
end
end,
['{Pr2sg}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сың',
['ы'] = 'сың',
['о'] = 'суң',
['у'] = 'суң',
['э'] = 'сиң',
['е'] = 'сиң',
['и'] = 'сиң',
['ө'] = 'сүң',
['ү'] = 'сүң'
}
return predicate_map[vowel] or 'сың'
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сың',
['ы'] = 'сың',
['о'] = 'суң',
['у'] = 'суң',
['э'] = 'сиң',
['е'] = 'сиң',
['и'] = 'сиң',
['ө'] = 'сүң',
['ү'] = 'сүң'
}
return predicate_map[vowel] or 'сың'
end
end,
['{Pr2sgf}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыз',
['ы'] = 'сыз',
['о'] = 'суз',
['у'] = 'суз',
['э'] = 'сиз',
['е'] = 'сиз',
['и'] = 'сиз',
['ө'] = 'сүз',
['ү'] = 'сүз'
}
return predicate_map[vowel] or 'сыз'
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыз',
['ы'] = 'сыз',
['о'] = 'суз',
['у'] = 'суз',
['э'] = 'сиз',
['е'] = 'сиз',
['и'] = 'сиз',
['ө'] = 'сүз',
['ү'] = 'сүз'
}
return predicate_map[vowel] or 'сыз'
end
end,
['{Pr1pl}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'быз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return predicate_map[vowel] or 'быз'
elseif stem_type == 'T' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'пыз',
['ы'] = 'пыз',
['о'] = 'пуз',
['у'] = 'пыз',
['э'] = 'пиз',
['е'] = 'пиз',
['и'] = 'пиз',
['ө'] = 'пүз',
['ү'] = 'пүз'
}
return predicate_map[vowel] or 'быз'
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'быз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return predicate_map[vowel] or 'быз'
end
end,
['{Ppr1pl}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'быз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return plural_suffix .. (predicate_map[vowel] or 'быз')
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'быз',
['ы'] = 'быз',
['о'] = 'буз',
['у'] = 'быз',
['э'] = 'биз',
['е'] = 'биз',
['и'] = 'биз',
['ө'] = 'бүз',
['ү'] = 'бүз'
}
return plural_suffix .. (predicate_map[vowel] or 'быз')
end
end,
['{Pr2pl}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыңар',
['ы'] = 'сыңар',
['о'] = 'суңар',
['у'] = 'суңар',
['э'] = 'сиңер',
['е'] = 'сиңер',
['и'] = 'сиңер',
['ө'] = 'сүңөр',
['ү'] = 'сүңөр'
}
return predicate_map[vowel] or 'сыңар'
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыңар',
['ы'] = 'сыңар',
['о'] = 'суңар',
['у'] = 'суңар',
['э'] = 'сиңер',
['е'] = 'сиңер',
['и'] = 'сиңер',
['ө'] = 'сүңөр',
['ү'] = 'сүңөр'
}
return predicate_map[vowel] or 'сыңар'
end
end,
['{Ppr2pl}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыңар',
['ы'] = 'сыңар',
['о'] = 'суңар',
['у'] = 'сыңар',
['э'] = 'сиңер',
['е'] = 'сиңер',
['и'] = 'сиңер',
['ө'] = 'сүңөр',
['ү'] = 'сүңөр'
}
return plural_suffix .. (predicate_map[vowel] or 'сыңар')
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыңар',
['ы'] = 'сыңар',
['о'] = 'суңар',
['у'] = 'сыңар',
['э'] = 'сиңер',
['е'] = 'сиңер',
['и'] = 'сиңер',
['ө'] = 'сүңөр',
['ү'] = 'сүңөр'
}
return plural_suffix .. (predicate_map[vowel] or 'сыңар')
end
end,
['{Pr2plf}'] = function()
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыздар',
['ы'] = 'сыздар',
['о'] = 'суздар',
['у'] = 'суздар',
['э'] = 'сиздер',
['е'] = 'сиздер',
['и'] = 'сиздер',
['ө'] = 'сүздөр',
['ү'] = 'сүздөр'
}
return predicate_map[vowel] or 'сыздар'
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыздар',
['ы'] = 'сыздар',
['о'] = 'суздар',
['у'] = 'суздар',
['э'] = 'сиздер',
['е'] = 'сиздер',
['и'] = 'сиздер',
['ө'] = 'сүздөр',
['ү'] = 'сүздөр'
}
return predicate_map[vowel] or 'сыздар'
end
end,
['{Ppr2plf}'] = function()
local plural_suffix = get_plural_suffix(last_vowel, stem_type)
if stem_type == 'V' then
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыздар',
['ы'] = 'сыздар',
['о'] = 'суздар',
['у'] = 'сыздар',
['э'] = 'сиздер',
['е'] = 'сиздер',
['и'] = 'сиздер',
['ө'] = 'сүздөр',
['ү'] = 'сүздөр'
}
return plural_suffix .. (predicate_map[vowel] or 'сыздар')
else
local vowel = get_vowel_harmony(last_vowel)
local predicate_map = {
['а'] = 'сыздар',
['ы'] = 'сыздар',
['о'] = 'суздар',
['у'] = 'сыздар',
['э'] = 'сиздер',
['е'] = 'сиздер',
['и'] = 'сиздер',
['ө'] = 'сүздөр',
['ү'] = 'сүздөр'
}
return plural_suffix .. (predicate_map[vowel] or 'сыздар')
end
end
}
for k, v in pairs(special_chars) do
if mw.ustring.find(ending, k, 1, true) ~= nil then
ending = mw.ustring.gsub(ending, k, v())
end
end
return ending
end
decline = function(stem, alt_stem, ending_pattern, ending_vowel, final_stem_class, apostrophe_required, is_possessive, is_plural_possessive)
if is_string_empty(stem) then
return ''
end
local apostrophe = ifexpr(apostrophe_required == 'tak', '\'', '')
-- Use parameter [1] (alt_stem) only for singular possessive forms
-- For plural possessives and all other forms, use the basic stem
local current_stem = stem
if is_possessive and not is_plural_possessive and not is_string_empty(alt_stem) then
current_stem = alt_stem
end
return current_stem
.. apostrophe
.. construct_noun_ending(
current_stem,
ending_pattern,
ending_vowel,
final_stem_class,
is_possessive,
is_plural_possessive)
end
handle_alt_stem = function(stem, alt_stem, check_for_dropping_vowel)
if is_string_empty(alt_stem) then
return stem
end
if check_for_dropping_vowel then
if p.has_dropping_vowel(stem, alt_stem) then
return stem
end
end
return alt_stem
end
handle_frame_arg = function(arg, on_nil)
if is_string_empty(arg) then
return on_nil
end
return arg
end
get_case_endings_table = function(blp, stem)
local no_singular = blp == 'tak'
if is_string_empty(stem) then
return endings.endings2['']
end
local ends_with_plural = ends_with(stem, 'лар') or ends_with(stem, 'лер') or
ends_with(stem, 'лор') or ends_with(stem, 'лөр') or
ends_with(stem, 'дар') or ends_with(stem, 'дер') or
ends_with(stem, 'дор') or ends_with(stem, 'дөр') or
ends_with(stem, 'тар') or ends_with(stem, 'тер') or
ends_with(stem, 'тор') or ends_with(stem, 'төр')
return endings.endings2[ifexpr(no_singular and ends_with_plural, 'blp-plural', '')]
end
get_case_names = function(case_endings)
local res = {}
for _, v in pairs(case_endings) do
for k2, _ in pairs(v) do
table.insert(res, k2)
end
end
return res
end
fetch_args = function(frame, args_to_fetch)
local ret = {}
local args = frame.args
for _, n in pairs(args_to_fetch) do
if not is_string_empty(args[n]) then
ret[n] = args[n]
end
end
return ret
end
decline_noun = function(args, case_endings, special_cases,
stem, alt_stem, ending_vowel, final_stem_class, apostrophe_required,
check_for_dropping_vowel, is_possessive, is_plural_possessive)
local res = args or {}
for k, v in pairs(case_endings) do
if res[k] == nil then
res[k] = decline(
stem,
alt_stem,
v,
ending_vowel,
final_stem_class,
apostrophe_required,
is_possessive,
is_plural_possessive)
end
end
return res
end
p.main = function(frame)
local TABLE_NAME = 'Szablon:odmiana-rzeczownik-kirgiski/tabela'
local args = frame.args
local stem = args[1] or '' -- Basic stem
local alt_stem = handle_frame_arg(args[2], '') -- Parameter [1] - stem with alternations for singular possessives
local ending_vowel = handle_frame_arg(args[3], get_last_vowel_of_stem(stem))
local final_stem_class = handle_frame_arg(args[4], get_last_letter_type(stem))
local apostrophe_required = args[5]
local create_predicate_table = args['formy osobowe']
local is_animate = args['żywotny']
local case_endings = get_case_endings_table(args['blp'], stem)
local arguments = fetch_args(frame, get_case_names(case_endings))
-- Always show cases and possessives
local decline_for = {'normal', 'possessive'}
-- Show predicatives only if both conditions are met
local should_show_predicatives = (create_predicate_table == 'tak')
if should_show_predicatives then
table.insert(decline_for, 'predicate')
end
for _, v in ipairs(decline_for) do
-- Check if case endings exist for this category before declining
if case_endings[v] then
local is_possessive_form = (v == 'possessive')
local is_plural_possessive_form = false
arguments = decline_noun(arguments, case_endings[v], {},
stem, alt_stem, ending_vowel, final_stem_class, apostrophe_required,
ifexpr(v == 'predicate', true, false),
is_possessive_form,
is_plural_possessive_form)
end
end
-- Handle plural possessive forms separately - use basic stem (not parameter [1])
if case_endings['possessive'] then
local plural_possessive_forms = {
'Mianownik lm 1 os lp dzierżawczy',
'Mianownik lm 2 os lp dzierżawczy',
'Mianownik lm 2 os lp grzecznościowy dzierżawczy',
'Mianownik lm 3 os lp dzierżawczy',
'Mianownik lm 1 os lm dzierżawczy',
'Mianownik lm 2 os lm dzierżawczy',
'Mianownik lm 2 os lm grzecznościowy dzierżawczy',
'Mianownik lm 3 os lm dzierżawczy',
}
for _, form_name in ipairs(plural_possessive_forms) do
if case_endings['possessive'][form_name] and not arguments[form_name] then
arguments[form_name] = decline(
stem,
'', -- Don't use parameter [1] for plural possessives - use basic stem
case_endings['possessive'][form_name],
ending_vowel,
final_stem_class,
apostrophe_required,
true, -- is_possessive
true) -- is_plural_possessive
end
end
end
-- If predicatives shouldn't be shown, set them to empty strings
if not should_show_predicatives then
local predicate_forms = {
'Mianownik lp 1 os lp osobowy',
'Mianownik lp 2 os lp osobowy',
'Mianownik lp 2 os lp grzecznościowy osobowy',
'Mianownik lp 1 os lm osobowy',
'Mianownik lp 2 os lm osobowy',
'Mianownik lp 2 os lm grzecznościowy osobowy',
'Mianownik lm 1 os lp osobowy',
'Mianownik lm 2 os lp osobowy',
'Mianownik lm 2 os lp grzecznościowy osobowy',
'Mianownik lp 3 os lp krótki osobowy',
'Mianownik lp 3 os lp długi osobowy',
'Mianownik lm 3 os lp krótki osobowy',
'Mianownik lm 3 os lp długi osobowy',
'Mianownik lm 1 os lm osobowy',
'Mianownik lm 2 os lm osobowy',
'Mianownik lm 2 os lm grzecznościowy osobowy',
'Mianownik lp 3 os lm krótki osobowy',
'Mianownik lp 3 os lm długi osobowy',
'Mianownik lm 3 os lm osobowy'
}
for _, predicate_case in ipairs(predicate_forms) do
arguments[predicate_case] = ''
end
end
if args['blp'] == 'tak' then
arguments['Mianownik lp'] = ''
end
if args['blm'] == 'tak' then
arguments['Mianownik lm'] = ''
end
arguments['formy osobowe'] = create_predicate_table or nil
arguments['żywotny'] = is_animate or nil
arguments['blp'] = args['blp'] or nil
arguments['blm'] = args['blm'] or nil
return frame:expandTemplate{title = TABLE_NAME, args = arguments}
end
return p