Модуль:inflection/ru/old/declension/reducable
Внешний вид
Для документации этого модуля может быть создана страница Модуль:inflection/ru/old/declension/reducable/Документация
local dev_prefix = ''
-- dev_prefix = 'User:Vitalik/' -- comment this on `prod` version
local export = {}
local _ = require('Module:' .. dev_prefix .. 'inflection/tools')
local module = 'declension.reducable'
-- @starts
function export.apply_specific_degree(stems, endings, word, stem, stem_type, gender, stress_type, rest_index, data)
func = "apply_specific_degree"
_.starts(module, func)
-- If degree sign °
if _.contains(rest_index, '°') and _.endswith(word, '[ая]нин') then
_.replace(stems, 'all_pl', '([ая])ни́ н$', '%1́ н')
_.replace(stems, 'all_pl', '([ая]́ ?н)ин$', '%1')
endings['nom_pl'] = 'е'
endings['gen_pl'] = ''
_.ends(module, func)
return rest_index
end
if _.contains(rest_index, '°') and _.endswith(word, 'ин') then
_.replace(stems, 'all_pl', 'и́ ?н$', '')
if not _.contains(rest_index, {'%(1%)', '①'}) then
endings['nom_pl'] = 'е'
end
endings['gen_pl'] = ''
end
if _.contains(rest_index, '°') and _.endswith(word, {'ёнок', 'онок'}) then
_.replace(stems, 'all_pl', 'ёнок$', 'я́т')
_.replace(stems, 'all_pl', 'о́нок$', 'а́т')
-- INFO: Эмуляция среднего рода `1a` для форм мн. числа
endings['nom_pl'] = 'а'
endings['gen_pl'] = ''
export.apply_specific_reducable(stems, endings, word, stem, stem_type, gender, stress_type, rest_index .. '*', data, true)
_.ends(module, func)
return rest_index
end
if _.contains(rest_index, '°') and _.endswith(word, {'ёночек', 'оночек'}) then
_.replace(stems, 'all_pl', 'ёночек$', 'я́тк')
_.replace(stems, 'all_pl', 'о́ночек$', 'а́тк')
-- INFO: Черездование для единичной формы (возможно применится также и для множественной, но это не страшно, потом заменится по идее)
export.apply_specific_reducable(stems, endings, word, stem, stem_type, gender, stress_type, rest_index .. '*', data, false)
-- INFO: По сути должно примениться только к мн. формам (случай `B`)
export.apply_specific_reducable(stems, endings, word, stem, stem_type, 'f', stress_type, rest_index .. '*', data, false)
endings['gen_pl'] = '' -- INFO: Странный фикс, но он нужен.. <_<
_.ends(module, func)
return rest_index
end
if _.contains(rest_index, '°') and gender == 'n' and _.endswith(word, 'мя') then
_.replace(stems, 'all_sg', 'м$', 'мен')
_.replace(stems, 'ins_sg', 'м$', 'мен')
_.replace(stems, 'all_pl', 'м$', 'мен')
endings['nom_sg'] = 'я'
endings['gen_sg'] = 'и'
endings['dat_sg'] = 'и'
endings['ins_sg'] = 'ем'
endings['prp_sg'] = 'и'
end
_.ends(module, func)
return rest_index
end
-- Сложный алгоритм обработки всех случаев чередования
-- @starts
function export.apply_specific_reducable(stems, endings, word, stem, stem_type, gender, stress_type, rest_index, data, only_sg)
func = "apply_specific_reducable"
_.starts(module, func)
local reduced, reduced_letter, f_3rd, prev
local case_2_a, case_2_b, case_2_c, case_3_a, case_3_b
local skip_b_1, skip_b_2, skip_b_3, force_b
local case
if _.contains(rest_index, '%*') then
reduced = '?'
if data.adj then
if gender == 'm' then
if _.contains(rest_index, {'%(1%)', '①'}) then
if gender == 'm' and data.adj and _.endswith(word, 'ний') and endings['srt_sg'] == 'ь' then -- fixme: temporary duplicated with the same code at the ending of function...
endings['srt_sg'] = '' -- вместо `ь` для `2*a`
end
return _.ends(module, func)
end
if _.contains(rest_index, {'%(2%)', '②'}) then
return _.ends(module, func)
end
reduced = 'B'
else
return _.ends(module, func)
end
elseif gender == 'm' or data.pronoun then
reduced = 'A'
elseif gender == 'n' then
reduced = 'B'
elseif gender == 'f' then
if _.equals(stem_type, {'f-3rd', 'f-3rd-sibilant'}) then
reduced = 'A'
else
reduced = 'B'
end
end
mw.log('# Случай чередования: ' .. tostring(reduced))
if reduced == 'A' then
reduced_letter = _.extract(word, '({vowel+ё}){consonant}+$')
f_3rd = _.In(stem_type, {'f-3rd', 'f-3rd-sibilant'})
_.log_value(reduced_letter, 'reduced_letter')
if reduced_letter == 'о' then
_.replace(stems, 'all_sg', '(.)о́ ?([^о]+)$', '%1%2')
-- local stem_gen_pl
-- -- У этих имён последняя гласная основы исходной формы заменяется на нуль, о или й во всех формах, не совпадающих с исходной (кроме Т. ед. на -ью).
-- -- if endings['gen_pl'] == '' then -- ботинок, глазок
-- if _.contains(rest_index, {'%(2%)', '②'}) then
-- stem_gen_pl = stems['gen_pl']
-- end
if not only_sg then
_.replace(stems, 'all_pl', '(.)о́ ?([^о]+)$', '%1%2')
end
-- if stem_gen_pl then -- ботинок, глазок
-- stems['gen_pl'] = stem_gen_pl
-- end
if not f_3rd then
_.replace(stems, 'ins_sg', '(.)о́ ?([^о]+)$', '%1%2')
end
elseif reduced_letter == 'и' then -- бывает только в подтипе мс 6*
_.replace(stems, 'all_sg', '(.)и́ ?([^и]+)$', '%1ь%2')
if not only_sg then
_.replace(stems, 'all_pl', '(.)и́ ?([^и]+)$', '%1ь%2')
end
elseif _.In(reduced_letter, {'е', 'ё'}) then
prev = _.extract(word, '(.)[её][^её]+$')
case_2_a = stem_type == 'vowel' -- 2) а).
case_2_b = stem_type == 'velar' and _.contains(prev, '[^аеёиоуыэюяшжчщц]') -- 2) б).
case_2_c = not _.equals(stem_type, {'vowel', 'velar'}) and prev == 'л' -- 2) в).
if _.contains(prev, '{vowel+ё}') then -- 1).
mw.log(' -- Подслучай A.1).')
_.replace(stems, 'all_sg', '[её]́ ?([^её]+)$', 'й%1')
if not f_3rd then
_.replace(stems, 'ins_sg', '[её]́ ?([^её]+)$', 'й%1')
end
if not only_sg then
_.replace(stems, 'all_pl', '[её]́ ?([^её]+)$', 'й%1')
end
elseif case_2_a or case_2_b or case_2_c then -- 2).
mw.log(' -- Подслучай A.2).')
_.replace(stems, 'all_sg', '[её]́ ?([^её]*)$', 'ь%1')
if not f_3rd then
_.replace(stems, 'ins_sg', '[её]́ ?([^её]*)$', 'ь%1')
end
if not only_sg then
_.replace(stems, 'all_pl', '[её]́ ?([^её]*)$', 'ь%1')
end
else -- 3).
mw.log(' -- Подслучай A.3).')
_.replace(stems, 'all_sg', '[её]́ ?([^её]*)$', '%1')
if not f_3rd then
_.replace(stems, 'ins_sg', '[её]́ ?([^её]*)$', '%1')
end
if not only_sg then
_.replace(stems, 'all_pl', '[её]́ ?([^её]*)$', '%1')
end
end
end
end -- reduced A
if only_sg then
return _.ends(module, func) -- ниже всё равно обрабатывается только множественное число уже
end
-- we should ignore asterix for 2*b and 2*f (so to process it just like 2b or 2f)
skip_b_1 = stem_type == 'soft' and _.In(stress_type, {'b', 'f'})
-- and also the same for (2)-specific and 3,5,6 stem-types
skip_b_2 = _.contains(rest_index, {'%(2%)', '②'}) and (
_.In(stem_type, {'soft'}) -- 'soft' из сходня 2*a(2)
-- TODO: Разобраться, почему это нужно было на самом деле?
-- _.In(stem_type, {'velar', 'letter-ц', 'vowel'}) -- так было раньше, без прочих skip
)
-- TODO: Разобраться, почему это нужно на самом деле?
skip_b_3 = _.contains(rest_index, {'%(2%)', '②'}) and gender == 'n' -- temp fix
force_b = false
if _.contains(rest_index, {'%(2%)', '②'}) then
gender = 'n'
data.forced_stem = stems['gen_pl']
stem = stems['gen_pl']
mw.log(' -- New force stem (gen_pl): ' .. tostring(stem))
force_b = true
end
-- TODO: б) в словах прочих схем ударения — на последний слог основы, если основа не содержит беглой гласной, и на предпоследний слог основы, если основа содержит беглую гласную, на¬пример: величина, тюрьма, полотно (схема d) — И.мн. величины, тюрьмы, полотна, Р.мн. ве¬личин, тюрем, полотен.
-- это для глАзок
if (reduced == 'B' or force_b) and not skip_b_1 and not skip_b_2 and not skip_b_3 then
if data.adj then
case = 'srt_sg'
else
case = 'gen_pl'
end
mw.log(' -- Зашли в случай чередования B')
if stem_type == 'vowel' then -- 1).
mw.log(' -- Подслучай B.1).')
if _.In(stress_type, {'b', 'c', 'e', 'f', "f'", "b'" }) then -- gen_pl ending stressed -- TODO: special vars for that
_.replace(stems, case, 'ь$', 'е́')
else
_.replace(stems, case, 'ь$', 'и')
end
elseif _.contains(stem, '[ьй]{consonant}$') then -- 2).
mw.log(' -- Подслучай B.2).')
if data.adj then
e = stem_type == 'letter-ц' or not _.contains(stress_type, 'b') or _.endswith(stress_type, {'/b', "/b'"}) -- todo: fix only "b" for srt...
else
e = stem_type == 'letter-ц' or _.equals(stress_type, {'a', 'd', "d'"}) -- gen_pl ending unstressed -- TODO: special vars for that
end
if e then
_.replace(stems, case, '[ьй]({consonant})$', 'е%1')
else
_.replace(stems, case, '[ьй]({consonant})$', 'ё%1')
end
else -- 3).
prev = _.extract(stem, '(.){consonant}$')
case_3_a = stem_type == 'velar' and _.contains(prev, '[^жшчщц]') -- 3). а).
case_3_b = _.contains(prev, '[кгх]') -- 3). б).
if case_3_a or case_3_b then
mw.log(' -- Подслучай B.3). а,б).')
_.replace(stems, case, '(.)({consonant})$', '%1о%2')
else -- 3). в).
mw.log(' -- Подслучай B.3). в).')
if stem_type == 'letter-ц' then
mw.log(' -- stem_type == "letter-ц"')
_.replace(stems, case, '(.)({consonant})$', '%1е%2')
else
if data.adj then
e = _.equals(stress_type, 'b') or _.endswith(stress_type, {'/b', "/b'"}) -- TODO: special vars for that
else
e = _.In(stress_type, {'b', 'c', 'e', 'f', "f'", "b'" }) -- gen_pl ending stressed -- TODO: special vars for that
end
if e then
mw.log(' -- в `' .. case .. '` ударение на окончание')
stems[case] = data.stem
if _.contains(prev, '[жшчщ]') then
mw.log(' -- предыдущая [жшчщ]')
_.replace(stems, case, '(.)({consonant})$', '%1о́%2')
else
mw.log(' -- предыдущая не [жшчщ]')
_.replace(stems, case, '(.)({consonant})$', '%1ё%2')
end
else
mw.log(' -- ударение на основу в ["' .. case .. '"] ')
_.replace(stems, case, '(.)({consonant})$', '%1е%2')
end
end
end
end
if stem_type == 'soft' and _.endswith(word, 'ня') and stress_type == 'a' and endings['gen_pl'] == 'ь' then
endings['gen_pl'] = '' -- вместо `ь` для `2*a`
end
if gender == 'm' and data.adj and _.endswith(word, 'ний') and endings['srt_sg'] == 'ь' then
endings['srt_sg'] = '' -- вместо `ь` для `2*a`
end
-- if _.contains(rest_index, 'ё') then
-- if _.contains(stems['gen_pl'], 'ё.*е') then
-- mw.log('% Специальный случай-исправление типа "сёстер" -> "сестёр"')
-- _.replace(stems, 'gen_pl', 'ё(.*)е([^е]*)$', 'е%1ё%2')
-- end
-- end
end -- reduced B
end -- specific *
_.ends(module, func)
end
return export