Zaliznyak | Our template | Description |
---|---|---|
м |
m-in |
masculine inanimate |
мо |
m-an |
masculine animate |
ж |
f-in |
feminine inanimate |
жо |
f-an |
feminine animate |
с |
n-in |
neuter inanimate |
со |
n-an |
neuter animate |
singular | plural | ||||||
---|---|---|---|---|---|---|---|
masculine | neuter | feminine | masculine | neuter | feminine | ||
nominative | ∅ | -о | -а | -ы | -а | -ы | |
genitive | -а | -ы | -ов | ∅ | |||
dative | -у | -е | -ам | ||||
accusative | inanimate | = nominative | = nominative | -у | = nominative | ||
animate | = genitive | = genitive | |||||
instrumental | -ом | -ой,-ою | -ами | ||||
prepositional | -е | -ах |
singular | plural | ||||||
---|---|---|---|---|---|---|---|
masculine | neuter | feminine | masculine | neuter | feminine | ||
nominative | -ь | -е (unstressed) -ё (stressed) |
-я | -и | -я | -и | |
genitive | -я | -и | -ей | -ь (unstressed) -ей (stressed) | |||
dative | -ю | -е | -ям | ||||
accusative | inanimate | = nominative | = nominative | -ю | = nominative | ||
animate | = genitive | = genitive | |||||
instrumental | -ем (unstressed) -ём (stressed) |
-ей,-ею (unstressed) -ёй,-ёю (stressed) |
-ями | ||||
prepositional | -е | -ях |
type | stem ends with | endings like | changes in endings |
changes in genitive plural | other changes in endings |
---|---|---|---|---|---|
velar (#3) | к, г, х | hard (#1) | ы → и | — | — |
sibilant (#4) | ш, ж, ч, щ | ы → и unstressed o → е |
masculine: -ей feminine and neuter: ∅ (unstressed) |
— | |
letter-ц (#5) | ц | unstressed o → е | — | — | |
vowel (#6) | vowels (except и) or й | soft (#2) | ь → й | masculine: -ев (unstressed) -ёв (stressed) feminine and neuter: -й |
— |
letter-и (#7) | и | feminine dative singular and prepositional (all genders):
-и (unstressed) |
applies to:
description:
reducable | the rule | when applies | examples | |
---|---|---|---|---|
о | о → ∅ | always | любовь → любви сон → сна |
{3.A.1} |
е/ё | е/ё → й | if letter before e/ё is vowel | боец → бойца паёк → пайка |
{3.A.2} |
е/ё → ь | if stem type is vowel (#6) | улей → улья | {3.A.3.1} | |
if stem type is velar (#3) and letter before е/ё is consonant (except ш, ж, ч, щ, ц) |
зверёк → зверька | {3.A.3.2} | ||
if letter before e/ё is л | лёд → льда палец → пальца |
{3.A.3.3} | ||
е/ё → ∅ | in all other cases | орёл → орла кашель → кашля |
{3.A.4} |
applies to:
description:
reducable | the rule | when applies | examples |
---|---|---|---|
TODO description |
Form | Stress type | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
a | b | b' | c | d | d' | e | f | f' | f'' | ||
singular | nominative | stém-ending | stem-énding | ← like b | stém-ending | stem-énding | ← like d | stém-ending | stem-énding | ← like f | ← like f |
genitive | stém-ending | stem-énding | stém-ending | stem-énding | stém-ending | stem-énding | |||||
dative | stém-ending | stem-énding | stém-ending | stem-énding | stém-ending | stem-énding | |||||
accusative | stém-ending | stem-énding | stém-ending | stem-énding | stém-ending | stém-ending | stem-énding | stém-ending | |||
instrumental | stém-ending | stem-énding | stém-ending | stém-ending | stem-énding | ← like d | stém-ending | stem-énding | ← like f | stém-ending | |
prepositional | stém-ending | stem-énding | ← like b | stém-ending | stem-énding | stém-ending | stem-énding | ← like f | |||
plural | nominative | stém-ending | stem-énding | ← like b | stem-énding | stém-ending | ← like d | stém-ending | stém-ending | ← like f | ← like f |
genitive | stém-ending | stem-énding | stem-énding | stém-ending | stem-énding | stem-énding | |||||
dative | stém-ending | stem-énding | stem-énding | stém-ending | stem-énding | stem-énding | |||||
instrumental | stém-ending | stem-énding | stem-énding | stém-ending | stem-énding | stem-énding | |||||
prepositional | stém-ending | stem-énding | stem-énding | stém-ending | stem-énding | stem-énding |
-- Inflection unit for Russian nouns
-- Version 2.0.38
-- Date: 2015-08-25
local dev_prefix = ''
dev_prefix = 'User:Vitalik/' -- comment this on active version
local export = {}
local _ = require('Module:' .. dev_prefix .. 'inflection-tools')
-- local lang = require("Module:languages").getByCode("ru")
-- local m_links = require("Module:links")
-- local strutils = require("Module:string utilities")
-- constants:
local unstressed = 1
local stressed = 2
function export.template(base, args)
return dev_prefix .. 'ru-decl-noun-table-z'
end
local function get_standard_endings()
return {
m = { -- masculine endings
hard = {
nom_sg = '',
gen_sg = 'а',
dat_sg = 'у',
ins_sg = 'ом',
nom_pl = 'ы',
gen_pl = {'ов', 'ов'}, -- possibly we can join them together again (m_hard_gen_pl stressed and unstressed)
},
soft = {
nom_sg = 'ь',
gen_sg = 'я',
dat_sg = 'ю',
ins_sg = {'ем', 'ём'},
nom_pl = 'и',
gen_pl = {'ей', 'ей'},
},
},
f = { -- feminine endings
hard = {
nom_sg = 'а',
gen_sg = 'ы',
dat_sg = 'е',
acc_sg = 'у',
ins_sg = 'ой',
nom_pl = 'ы',
gen_pl = {'', ''},
},
soft = {
nom_sg = 'я',
gen_sg = 'и',
dat_sg = {'е', 'е'},
acc_sg = 'ю',
ins_sg = {'ей', 'ёй'},
nom_pl = 'и',
gen_pl = {'ь', 'ей'},
},
},
n = { -- neuter endings
hard = {
nom_sg = 'о',
gen_sg = 'а',
dat_sg = 'у',
ins_sg = 'ом',
nom_pl = 'а',
gen_pl = {'', ''},
},
soft = {
nom_sg = 'е', -- was: {'е', 'ё'}
gen_sg = 'я',
dat_sg = 'ю',
ins_sg = {'ем', 'ём'},
nom_pl = 'я',
gen_pl = {'ь', 'ей'},
},
},
common = { -- common endings
hard = {
prp_sg = {'е', 'е'},
dat_pl = 'ам',
ins_pl = 'ами',
prp_pl = 'ах',
},
soft = {
prp_sg = {'е', 'е'},
dat_pl = 'ям',
ins_pl = 'ями',
prp_pl = 'ях',
},
}
}
end
local function get_stress_flags(stress_type)
return {
stem = {
sg = _.equals(stress_type, {"a", "c", "e"}) and stressed or unstressed,
acc_sg = _.equals(stress_type, {"a", "c", "e", "d'", "f'"}) and stressed or unstressed,
ins_sg = _.equals(stress_type, {"a", "c", "e", "b'", "f''"}) and stressed or unstressed,
pl = _.equals(stress_type, {"a", "d", "d'"}) and stressed or unstressed,
nom_pl = _.equals(stress_type, {"a", "d", "d'", "e", "f", "f'", "f''"}) and stressed or unstressed,
},
ending = {
sg = _.equals(stress_type, {"b", "b'", "d", "d'", "f", "f'", "f''"}) and stressed or unstressed,
acc_sg = _.equals(stress_type, {"b", "b'", "d", "f", "f''"}) and stressed or unstressed,
ins_sg = _.equals(stress_type, {"b", "d", "d'", "f", "f'"}) and stressed or unstressed,
pl = _.equals(stress_type, {"b", "b'", "c", "e", "f", "f'", "f''"}) and stressed or unstressed,
nom_pl = _.equals(stress_type, {"b", "b'", "c"}) and stressed or unstressed,
}
}
end
local function get_stem_type(z)
if _.endswith(z.stem, '') then
z.stem_type = 'velar'
elseif _.endswith(z.stem, '') then
z.stem_type = 'sibilant'
elseif _.endswith(z.stem, 'ц') then
z.stem_type = 'letter-ц'
elseif _.endswith(z.stem, {'', ''}) then
z.stem_type = 'vowel'
elseif _.endswith(z.stem, 'и') then
z.stem_type = 'letter-и'
else
if z.gender == 'm' then
if z.stem == z.word or _.endswith(z.word, 'ы') then
z.stem_type = 'hard'
elseif _.endswith(z.word, 'путь') then
z.stem_type = 'm-3rd'
elseif _.endswith(z.word, 'ь') or _.endswith(z.word, 'и') then
z.stem_type = 'soft'
elseif _.endswith(z.word, 'а') then
z.gender = 'f'
z.stem_type = 'hard'
elseif _.endswith(z.word, 'я') then
z.gender = 'f'
z.stem_type = 'soft'
end
elseif z.gender == 'f' then
if _.endswith(z.word, 'а') or _.endswith(z.word, 'ы') then
z.stem_type = 'hard'
elseif _.endswith(z.word, 'я') or _.endswith(z.word, 'и') then
z.stem_type = 'soft'
elseif _.endswith(z.word, 'ь') then -- conflict in pl
z.stem_type = 'f-3rd'
end
elseif z.gender == 'n' then
if _.endswith(z.word, 'о') or _.endswith(z.word, 'а') then
z.stem_type = 'hard'
elseif _.endswith(z.word, 'е') or _.endswith(z.word, 'я') then
z.stem_type = 'soft'
elseif _.endswith(z.word, 'мя') or _.endswith(z.word, 'мена') then
z.stem_type = 'n-3rd'
end
end
end
if z.gender == 'm' then
if _.endswith(z.word, {'а', 'я'}) then
z.gender = 'f'
end
end
if z.gender == 'f' and z.stem_type == 'sibilant' and _.endswith(z.word, 'ь') then
z.stem_type = 'f-3rd-sibilant'
end
if z.stem_type == '' then
z.stem_type = 'hard'
end
end
local function change_endings_for_other_stem_types(z)
if _.equals(z.stem_type, {'velar', 'sibilant'}) then
-- Replace "ы" to "и"
z.e = 'и'
z.e = 'и'
z.e = 'и'
end
if _.equals(z.stem_type, {'sibilant', 'letter-ц'}) then
-- Replace unstressed "о" to "е"
if z.stress_flags == unstressed then
z.e = 'е'
end
if z.stress_flags == unstressed then
z.e = 'ем'
z.e = 'ем'
z.e = 'ей'
end
if z.stress_flags == unstressed then
z.e = {'ев', 'ев'} -- TODO: should we change stressed value here?
end
end
if _.equals(z.stem_type, 'sibilant') then
-- Replace "ов", "ев", "ёв" and null to "ей"
z.e = {'ей', 'ей'}
z.e = 'ей'
-- z.e_unstressed = '' this is just don't changed
z.e = 'ей'
-- z.e_unstressed = '' this is just don't changed
end
if _.equals(z.stem_type, {'vowel', 'letter-и'}) then
-- Replace "ь" to "й"
z.e = 'й'
z.e = 'й'
z.e = 'й'
end
if _.equals(z.stem_type, {'vowel', 'letter-и'}) then
-- Replace "ей" to "ев/ёв", and "ь,ей" to "й"
z.e = {'ев', 'ёв'}
z.e = {'й', 'й'}
z.e = {'й', 'й'}
end
if _.equals(z.stem_type, 'letter-и') then
z.e = 'и'
z.e = 'и'
end
if _.equals(z.stem_type, 'm-3rd') then
z.e = 'и'
z.e = 'и'
z.e = {'и', 'и'}
end
if _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
z.e = 'ь'
z.e = {'и', 'и'}
z.e = 'ь'
z.e = {'ью', 'ью'}
z.e = {'и', 'и'}
z.e = {'ей', 'ей'}
end
if _.equals(z.stem_type, 'f-3rd-sibilant') then
z.e = 'ам'
z.e = 'ами'
z.e = 'ах'
end
end
local function apply_specific_1_2(z)
-- If we have specific (1) or (2)
if _.contains(z.specific, '%(1%)') then
z.e = 'а'
z.e = 'я'
z.e = 'ы'
z.e = 'и'
if _.equals(z.stem_type, {'velar', 'sibilant'}) then
-- Replace "ы" to "и"
z.e = 'и'
end
end
if _.contains(z.specific, '%(2%)') then
z.e = {'', ''}
z.e = {'ь', 'ь'}
z.e = {'ов', 'ов'}
z.e = {'ев', 'ёв'}
z.e = {'ей', 'ей'}
z.e = {'ей', 'ей'}
if _.equals(z.stem_type, {'sibilant', 'letter-ц'}) then
-- Replace unstressed "о" to "е"
z.e = 'ев'
end
--[=[ Possibly we don't need this:
-- Replace "ов", "ев", "ёв" and null to "ей"
if z.stem_type = {'sibilant'}}
z.e = {'ей', 'ей'}
z.e = 'ей'
end
-- Replace "ь" to "й"
if z.stem_type = {'vowel', 'letter-и'}}
z.e = {'й', 'й'}
end
-- Replace "ей" to "ев/ёв", and "ь,ей" to "й"
if z.stem_type = {'vowel', 'letter-и'}}
z.e = {'ев', 'ёв'}
z.e = {'й', 'й'}
end
]=]--
end
end
local function choose(endings, case, type)
endings = endings
end
local function choose_stress_for_endings(z)
local s
s = z.stress_flags
choose(z.e, 'dat_sg', s)
choose(z.e, 'prp_sg', s)
choose(z.e, 'prp_sg', s)
s = z.stress_flags
choose(z.e, 'ins_sg', s)
choose(z.e, 'ins_sg', s)
choose(z.e, 'ins_sg', s)
s = z.stress_flags
choose(z.e, 'gen_pl', s)
choose(z.e, 'gen_pl', s)
choose(z.e, 'gen_pl', s)
choose(z.e, 'gen_pl', s)
choose(z.e, 'gen_pl', s)
choose(z.e, 'gen_pl', s)
end
local function choose_endings_by_stem_type(z)
local base_stem_type
if _.equals(z.stem_type, {'hard', 'soft'}) then
base_stem_type = z.stem_type
elseif _.equals(z.stem_type, {'velar', 'sibilant', 'letter-ц'}) then
base_stem_type = 'hard'
elseif _.equals(z.stem_type, {'vowel', 'letter-и', 'm-3rd', 'f-3rd', 'f-3rd-sibilant'}) then
base_stem_type = 'soft'
else
return {error_msg = 'Unexpected internal error: Unknown stem type'}
end
for key, value in pairs(z.e) do
z.e = value
end
z.endings = z.e
end
local function add_stress(endings, case)
endings = _.replace(endings, '^({vowel})', '%1́ ')
end
local function apply_stress_type(z)
if z.stress_flags == stressed then
z.stems = z.stem_stressed
else
z.stems = z.stem
add_stress(z.endings, 'nom_sg')
add_stress(z.endings, 'gen_sg')
add_stress(z.endings, 'dat_sg')
add_stress(z.endings, 'prp_sg')
end
if z.stress_flags == stressed then
z.stems = z.stem_stressed
else
z.stems = z.stem
add_stress(z.endings, 'ins_sg')
end
if z.gender == 'f' then
if z.stress_flags == stressed then
z.stems = z.stem_stressed
else
z.stems = z.stem
add_stress(z.endings, 'acc_sg')
end
end
if z.stress_flags == stressed then
z.stems = z.stem_stressed
else
z.stems = z.stem
add_stress(z.endings, 'nom_pl')
end
if z.stress_flags == stressed then
z.stems = z.stem_stressed
else
z.stems = z.stem
add_stress(z.endings, 'gen_pl')
add_stress(z.endings, 'dat_pl')
add_stress(z.endings, 'ins_pl')
add_stress(z.endings, 'prp_pl')
end
end
local function apply_specific_degree(z)
-- If degree sign °
if _.endswith(z.word, 'нин') and z.animacy == 'an' and z.word ~= 'семьянин' then
z.stems = _.replace(z.stems, '()ни́ н$', '%1́ н')
z.stems = _.replace(z.stems, '(́ ?н)ин$', '%1')
z.stems = _.replace(z.stems, '()ни́ н$', '%1́ н')
z.stems = _.replace(z.stems, '(́ ?н)ин$', '%1')
z.endings = 'е'
z.endings = ''
z.specific = z.specific .. '°'
end
if _.endswith(z.word, {'ёнок', 'онок', 'ёночек', 'оночек'}) then
if _.endswith(z.word, 'ёнок') then
z.stems = _.replace(z.stems, 'ёнок$', 'я́т')
z.stems = _.replace(z.stems, 'ёнок$', 'я́т')
end
if _.endswith(z.word, 'онок') then
z.stems = _.replace(z.stems, 'о́нок$', 'а́т')
z.stems = _.replace(z.stems, 'о́нок$', 'а́т')
end
if _.endswith(z.word, 'ёночек') then
z.stems = _.replace(z.stems, 'ёночек$', 'я́тк')
z.stems = _.replace(z.stems, 'ёночек$', 'я́тк')
end
if _.endswith(z.word, 'оночек') then
z.stems = _.replace(z.stems, 'о́ночек$', 'а́тк')
z.stems = _.replace(z.stems, 'о́ночек$', 'а́тк')
end
z.endings = z.e
z.endings = z.e
z.specific = z.specific .. '*'
z.specific = z.specific .. '°'
end
end
local function apply_specific_reducable(z)
if _.contains(z.specific, '%*') then
if z.gender == 'm' then
reduced = 'A'
elseif z.gender == 'n' then
reduced = 'B'
elseif z.gender == 'f' then
if _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
reduced = 'A'
else
reduced = 'B'
end
end
if reduced == 'A' then
reduced_letter = _.extract(z.word, '({vowel+ё}){consonant}+$')
if reduced_letter == 'о' then
z.stems = _.replace(z.stems, 'о́ ?(+)$', '%1')
if not _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
z.stems = _.replace(z.stems, 'о́ ?(+)$', '%1')
end
z.stems = _.replace(z.stems, 'о́ ?(+)$', '%1')
z.stems = _.replace(z.stems, 'о́ ?(+)$', '%1')
elseif _.equals(reduced_letter, {'е', 'ё'}) then
prev = _.extract(z.word, '(.)+$')
if _.contains(prev, '{vowel+ё}') then -- 1).
z.stems = _.replace(z.stems, '́ ?(+)$', 'й%1')
if not _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
z.stems = _.replace(z.stems, '́ ?(+)$', 'й%1')
end
z.stems = _.replace(z.stems, '́ ?(+)$', 'й%1')
z.stems = _.replace(z.stems, '́ ?(+)$', 'й%1')
elseif z.stem_type == 'vowel' -- 2) а).
or z.stem_type == 'velar' and _.contains(prev, '') -- 2) б).
or not _.equals(z.stem_type, {'vowel', 'velar'}) and prev == 'л' then -- 2) в).
z.stems = _.replace(z.stems, '́ ?(*)$', 'ь%1')
if not _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
z.stems = _.replace(z.stems, '́ ?(*)$', 'ь%1')
end
z.stems = _.replace(z.stems, '́ ?(*)$', 'ь%1')
z.stems = _.replace(z.stems, '́ ?(*)$', 'ь%1')
else -- 3).
z.stems = _.replace(z.stems, '́ ?(*)$', '%1')
if not _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
z.stems = _.replace(z.stems, '́ ?(*)$', '%1')
end
z.stems = _.replace(z.stems, '́ ?(*)$', '%1')
z.stems = _.replace(z.stems, '́ ?(*)$', '%1')
end
end
end -- reduced A
-- TODO: pcerhaps this line is redundant?
z.stems = z.stems -- apply changes in stems for stems
if reduced == 'B' and
not (z.stem_type == 'soft' and _.equals(z.stress_type, {'b', 'f'}) -- we should ignore asterix for 2*b and 2*f (so to process it just like 2b or 2f)
or _.contains(z.specific, '(2)') and _.equals(z.stem_type, {'velar', 'letter-ц', 'vowel'})) -- and also the same for (2)-specific and 3,5,6 stem-types
then
if z.stem_type == 'vowel' then -- 1).
if _.equals(z.stress_type, {'b', 'c', 'e', 'f', "f'", "b'" }) then -- gen_pl ending stressed -- TODO: special vars for that
z.stems = _.replace(z.stems, 'ь$', 'е́')
else
z.stems = _.replace(z.stems, 'ь$', 'и')
end
elseif _.contains(z.stem, '{consonant}$') then -- 2).
if z.stem_type == 'letter-ц' or _.equals(z.stress_type, {'a', 'd', "d'"}) then -- gen_pl ending unstressed -- TODO: special vars for that
z.stems = _.replace(z.stems, '({consonant})$', 'е%1')
else
z.stems = _.replace(z.stems, '({consonant})$', 'ё%1')
end
else -- 3).
prev = _.extract(z.stem, '(.){consonant}$')
if z.stem_type == 'velar' and _.contains(prev, '') -- 3). а).
or _.contains(prev, '') then -- 3). б).
z.stems = _.replace(z.stems, '(.)({consonant})$', '%1о%2')
else -- 3). в).
if z.stem_type == 'letter-ц' then
z.stems = _.replace(z.stems, '(.)({consonant})$', '%1е%2')
else
if _.equals(z.stress_type, {'b', 'c', 'e', 'f', "f'", "b'" }) then -- gen_pl ending stressed -- TODO: special vars for that
if _.contains(prev, '') then
z.stems = _.replace(z.stems, '(.)({consonant})$', '%1о́%2')
else
z.stems = _.replace(z.stems, '(.)({consonant})$', '%1ё%2')
end
else
z.stems = _.replace(z.stems, '(.)({consonant})$', '%1е%2')
end
end
end
end
if z.stem_type == 'soft' and _.endswith(z.word, 'ня') and z.stress_type == 'a' then
z.endings = ''
end
end -- reduced B
end -- specific *
end
local function choose_accusative_forms(z, forms)
forms = ''
forms = ''
forms = ''
forms = ''
if z.gender == 'n' then
forms = forms
elseif z.gender == 'm' then
if z.animacy == 'in' then
forms = forms
elseif z.animacy == 'an' then
forms = forms
else
forms = forms
forms = forms
end
elseif z.gender == 'f' then
if _.equals(z.stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
forms = forms
else
forms = z.stems .. z.endings
end
end
if z.animacy == 'in' then
forms = forms
elseif z.animacy == 'an' then
forms = forms
else
forms = forms
forms = forms
end
end
function get_zaliznyak_index(z)
local stem_types = {
= '1',
= '2',
= '3',
= '4',
= '5',
= '6',
= '7',
= '8',
= '8',
= '8',
= '8',
}
local index = z.gender_animacy .. ' ' .. stem_types
if _.contains(z.specific, '°') then
index = index .. '°'
elseif _.contains(z.specific, '%*') then
index = index .. '*'
end
index = index .. _.replace(z.stress_type, "'", "'")
if _.contains(z.specific, '%(1%)') then
index = index .. '①'
end
if _.contains(z.specific, '%(2%)') then
index = index .. '②'
end
if _.contains(z.specific, '%(3%)') then
index = index .. '③'
end
if _.contains(z.specific, 'ё') then
index = index .. ', ё'
end
return index
end
function export.forms(base, args)
_.clear_stash()
_.add_stash('{vowel}', '')
_.add_stash('{vowel+ё}', '')
_.add_stash('{consonant}', '')
local z = {}
z.e = get_standard_endings()
z.word_stressed = args
if _.contains_several(z.word_stressed, '{vowel+ё}') and not _.contains(z.word_stressed, '') then
return {error_msg = 'Error in template {{ru-decl-noun-z}}: You should add stress mark for the argument "word_stressed"'}
end
z.word = _.replace(z.word_stressed, '́ ', '')
-- Parse "gender_animacy" argument and get values for "gender" and "animacy"'
z.gender_animacy = args
z.gender = _.extract(z.gender_animacy, '()%-+')
z.animacy = _.extract(z.gender_animacy, '%-(+)')
z.stress_type = args
if not _.equals(z.stress_type, {'a', 'b', "b'", 'c', 'd', "d'", 'e', 'f', "f'", "f''"}) then
return {error_msg = 'Error in template {{ru-decl-noun-z}}: Wrong value for the argument "stress_type"'}
end
z.stress_flags = get_stress_flags(z.stress_type)
z.specific = args
-- Remove ending (-а, -е, -ё, -о, -я, -й, -ь) to get stem
z.stem = _.replace(z.word, '$', '')
z.stem_stressed = _.replace(z.word_stressed, '́ ?$', '')
-- Add stress to stem_stressed if stress is absent (i.e. there is only one syllable or stress was on the ending)
if not _.contains(z.stem_stressed, '') then
if _.equals(z.stress_type, {"f", "f'"}) then
z.stem_stressed = _.replace(z.stem_stressed, '^({consonant}*)({vowel})', '%1%2́ ')
else
-- if _.equals(stress_type, {'a', "b'", 'b', 'c', 'd', "d'", 'e'}) then
z.stem_stressed = _.replace(z.stem_stressed, '({vowel})({consonant}*)$', '%1́ %2')
end
-- TODO: process cases with * (stress on penultimate syllable)
end
-- Determination of stem type
get_stem_type(z)
-- Special changes in endings for velar, sibilant, vowel etc. stem types
change_endings_for_other_stem_types(z)
-- apply special cases (1) or (2) in specific
apply_specific_1_2(z)
-- Resolve stressed/unstressed cases of endings
choose_stress_for_endings(z)
if z.gender == 'n' and _.endswith(z.word, 'ё') then
z.e = 'ё'
end
-- Choose endings by stem type and gender (either 'hard' or 'soft' key from changed "z.e")
choose_endings_by_stem_type(z)
-- If we have "ё" specific
if _.contains(z.specific, 'ё') then
z.stem_stressed = _.replace(z.stem_stressed, 'е́?(*)$', 'ё%1')
end
z.stems = {}
apply_stress_type(z)
apply_specific_degree(z)
-- Changes for reduceable cases
z.stems = z.stems -- *save* unchanged stem value for nominative singular
z.stems = z.stems -- set default stem value for genitive plural
apply_specific_reducable(z)
-- If we have "ё" specific
if _.contains(z.specific, 'ё') and not _.contains(z.endings, '{vowel+ё}') and not _.contains(z.stems, 'ё') then
z.stems = _.replace(z.stems, 'е́?(*)$', 'ё%1')
z.specific = z.specific .. 'ё'
end
-- Generate forms
local forms = {
nom_sg = z.stems .. z.endings,
gen_sg = z.stems .. z.endings,
dat_sg = z.stems .. z.endings,
acc_sg = '',
ins_sg = z.stems .. z.endings,
prp_sg = z.stems .. z.endings,
nom_pl = z.stems .. z.endings,
gen_pl = z.stems .. z.endings,
dat_pl = z.stems .. z.endings,
acc_pl = '',
ins_pl = z.stems .. z.endings,
prp_pl = z.stems .. z.endings,
}
-- Add stress if there is no one
if _.contains_several(forms, '{vowel}') and not _.contains(forms, '') then
-- perhaps this is redundant for nom_sg?
forms = _.replace(forms, '({vowel})({consonant}*)$', '%1́ %2')
end
if _.contains_several(forms, '{vowel+ё}') and not _.contains(forms, '') then
forms = _.replace(forms, '({vowel})({consonant}*)$', '%1́ %2')
end
for key, value in pairs(forms) do
-- Remove stress if there is only one syllable
if _.contains_once(value, '{vowel+ё}') then
forms = _.replace(value, '́ ', '')
end
-- Replace 'ё' with 'е' when unstressed
if _.contains_once(value, 'ё') and _.contains(value, '́ ') then
forms = _.replace(value, 'ё', 'е')
end
end
choose_accusative_forms(z, forms)
-- partitive case
if args and args ~= '' then
forms = forms
end
-- locative case
if args and args ~= '' then
loc = forms
loc = _.replace(loc, '́ ', '')
loc = _.replace(loc, 'ё', 'е')
loc = _.replace(loc, '({vowel})({consonant}*)$', '%1́ %2')
forms = loc
if args == 'в' or args == 'на' then
forms = '(' .. args .. ')'
else
forms = '(в, на) '
end
end
forms = z.stem_type -- for testcases
forms = z.stress_type -- for categories
forms = get_zaliznyak_index(z)
forms = dev_prefix
local keys = {
'nom_sg', 'gen_sg', 'dat_sg', 'acc_sg', 'ins_sg', 'prp_sg',
'nom_pl', 'gen_pl', 'dat_pl', 'acc_pl', 'ins_pl', 'prp_pl',
'voc', 'n', 'note',
}
for i, key in pairs(keys) do
if args and args ~= '' then
forms = args
end
--[=[ -- I think we don't need this here, let's do it in template
if form_key == 'nom_sg' then
if forms and forms ~= '' then
value = forms
transliterated = lang:transliterate(m_links.remove_links(value))
link = m_links.full_link(value, nil, lang, nil, nil, nil, {tr = "-"}, false)
forms = strutils.format("{link}<br/><span style='color: #888'>{transliterated}</span>", {link=link, transliterated=transliterated})
else
forms = '—'
end
end
]=]--
end
return forms
end
return export