Modul:Ru
Qiyofa
Bu modul uchun Modul:Ru/doc nomli hujjat sahifasini yaratishingiz mumkin
--[[ This module is intended to form plural from Russian nouns, ajectives and simple phrases.
It's designed to replace ru:Template:Множ and its subpages, ru:Template:Локатив etc.
For declesion, consider please extending grammar: parser function in PHP engine code
]]
local o={};
local cons='бвгджзйклмнпрстфхцчшщ'; -- all consonants
local cons7='кгхчжшщ'; -- consonants requiring -и
local adjends={['ой']='ые',['ый']='ые',['ий']='ие',['ое']='ые',['ая']='ые',['яя']='ие',['ое']='ые',['ее']='ие'};
local specpl={
["человек"]="люди",
['мать']='матери',
['дочь']='дочери',
['брат']='братья',
['сын']='сыновья',
['дерево']='деревья',
['чудо']='чудеса',
['ребёнок']='дети',
['дитя']='дети',
['край'] = 'края',
['перо']='перья',
['знамя']='знамёна',
['грузин']='грузины',
['татарин']='татары',
['болгарин']='болгары',
['боярин']='бояре',
['цыган']='цыгане',
['друг']='друзья',
['веко']='веки',
['день']='дни',
['век']='века',
['директор']='директора',
['доктор']='доктора',
['инспектор']='инспектора',
['город']='города',
['вес']='веса',
['поезд']='поезда',
['звезда']='звёзды',
['список']='списки',
['церковь']='церкви'
}; -- table of some common special plural cases
function o.pl(p) -- plural formator, second argument mb 0 (undeclesed), 1, 2, 3 or 4 (adjective)
local word = p.args[1];
if specpl[word] then return specpl[word] end;
local d=p.args[2];
if d==nil then d=o.guessdecl(p) end;
if d=='0' then return word
elseif d=='a' then
if mw.ustring.match(word,'['..cons7..']..$') then
return mw.ustring.sub(word,1,-3)..'ие'
else return mw.ustring.sub(word,1,-3)..adjends[mw.ustring.sub(word,-2)]
end
elseif d=='1' then
if mw.ustring.sub(word,-1)=='я' or mw.ustring.match(word,'['..cons7..']а$')
then return mw.ustring.sub(word,1,-2)..'и'
else return mw.ustring.sub(word,1,-2)..'ы' end
elseif d=='2' then
if mw.ustring.match(word,'о$') then return mw.ustring.sub(word,1,-2)..'а'
elseif mw.ustring.match(word,'е$') then return mw.ustring.sub(word,1,-2)..'я'
elseif mw.ustring.match(word,'[ьй]$') then return mw.ustring.sub(word,1,-2)..'и'
elseif mw.ustring.match(word,'онок$') then return mw.ustring.sub(word,1,-5)..'ата'
elseif mw.ustring.match(word,'ёнок$') then return mw.ustring.sub(word,1,-5)..'ята'
elseif mw.ustring.match(word,'анин$') then return mw.ustring.sub(word,1,-5)..'ане'
elseif mw.ustring.match(word,'янин$') then return mw.ustring.sub(word,1,-5)..'яне'
elseif mw.ustring.match(word,'ец$') and not mw.ustring.match(word,'['..cons7..']['..cons7..']ец$') then -- !!second re is wrong for etnochoronims with unstressed -ец like ньюйоркцы
if mw.ustring.match(word,'лец$') then return mw.ustring.sub(word,1,-3)..'ьцы'
elseif mw.ustring.match(word,'[аоуыэяёюие]ец$') then return mw.ustring.sub(word,1,-3)..'ьцы'
else return mw.ustring.sub(word,1,-3)..'цы'
end
elseif mw.ustring.match(word,'['..cons7..']$') then return word..'и'
else return word..'ы'
end
elseif d=='3' then
if mw.ustring.match(word,'мя$') then return mw.ustring.sub(word,1,-3)..'ена'
else return mw.ustring.sub(word,1,-2)..'и'
end
else return "<span class=error>Wrong declesion '"..d.."' in RuGrammar::pl()</span>"
end
end
function o.guessdecl(p) -- guesses declesion type, yet not the best reliable way
local word=p.args[1];
if mw.ustring.match(word,'['..cons..'][оыи]й$')
or mw.ustring.match(word,'['..cons..'][ая]я$')
or mw.ustring.match(word,'['..cons..'][ое]е$')
then return 'a' --sometimes wrong
elseif mw.ustring.match(word,'['..cons..'][оеь]?$') then return '2' --but mb 3, can't guess w/o dict
elseif mw.ustring.match(word,'['..cons..'][ая]$') then
if mw.ustring.match(word,'[^'..cons..']мя$') then return '3' else return '1' end
else return '0'
end
end
function o.locative(p) -- consider rewritting grammar: instead of using it!
local word=p.args[1];
local locend={['а']='е', ['я']='е', ['й']='е', ['ы']="ах", ['ь']='и'}; -- the last is disputed, most Russian cities on -ь are 3 declesion but some foreign a 2 and thus -е
local ec=mw.ustring.sub(word,-1);
if mw.ustring.match(word,'ия$') then return mw.ustring.sub(word,1,-2)..'и'
elseif mw.ustring.match(word,'['..cons..']ль$') or mw.ustring.sub(word,-4)=='поль' then return mw.ustring.sub(word,1,-2)..'е'
elseif locend[ec] then return mw.ustring.sub(word,1,-2)..locend[ec]
elseif ec=='я' then return mw.ustring.sub(word,1,-2)..'е'
elseif mw.ustring.match(ec,'['..cons..']') then return word..'е'
elseif ec=='о' then
if mw.ustring.match(word,'[оеё]во$') then return mw.ustring.sub(word,1,-2)..'е'
else return word
end
else return word end
end;
return o;