Skip to content

Commit

Permalink
Add rules for run away vowels in pluralizator
Browse files Browse the repository at this point in the history
  • Loading branch information
wapmorgan committed Jun 9, 2017
1 parent 8280ed2 commit 2d1d9db
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/Russian/Plurality.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ class Plurality extends \morphos\Plurality implements Cases {
'пенни',
);

static protected $runawayVowelsExceptions = array(
'писе*ц',
'песе*ц',
'глото*к',
);

static protected $runawayVowelsNormalized = false;

static protected function getRunAwayVowelsList() {
if (self::$runawayVowelsNormalized === false) {
self::$runawayVowelsNormalized = array();
foreach (self::$runawayVowelsExceptions as $word) {
self::$runawayVowelsNormalized[str_replace('*', null, $word)] = S::indexOf($word, '*') - 1;
}
}
return self::$runawayVowelsNormalized;
}

static public function pluralize($word, $count = 2, $animateness = false) {
switch (self::getNumeralForm($count)) {
case self::ONE:
Expand Down Expand Up @@ -55,6 +73,12 @@ static public function getCases($word, $animateness = false) {
$prefix = S::slice($word, 0, -1);
$last = S::slice($word, -1);

$runaway_vowels_list = static::getRunAwayVowelsList();
if (isset($runaway_vowels_list[$word])) {
$vowel_offset = $runaway_vowels_list[$word];
$word = S::slice($word, 0, $vowel_offset) . S::slice($word, $vowel_offset + 1);
}

if (in_array($word, self::$immutableWords)) {
return array(
self::IMENIT => $word,
Expand All @@ -72,21 +96,22 @@ static public function getCases($word, $animateness = false) {
} else if ($declension == GeneralDeclension::FIRST_DECLENSION) {
$soft_last = self::checkLastConsonantSoftness($word);
} else {
$soft_last = false;
$soft_last = S::slice($word, -2) == 'сь';
}

$forms = array();

if ($last == 'ч' || S::slice($word, -2) == 'чь' || (self::isVowel($last) && in_array(S::slice($word, -2, -1), array('ч', 'к')))) // before ч, чь, ч+vowel, к+vowel
if ($last == 'ч' || in_array(S::slice($word, -2), array('чь', 'сь')) || (self::isVowel($last) && in_array(S::slice($word, -2, -1), array('ч', 'к')))) // before ч, чь, сь, ч+vowel, к+vowel
$forms[Cases::IMENIT] = $prefix.'и';
else if ($last == 'н')
$forms[Cases::IMENIT] = $prefix.'ы';
else
$forms[Cases::IMENIT] = self::chooseVowelAfterConsonant($last, $soft_last, $prefix.'я', $prefix.'а');


// RODIT
if (in_array($last, array('о', 'е'))) {
if ($word == 'письмо')
$forms[Cases::RODIT] = 'писем';
else if (in_array($last, array('о', 'е'))) {
// exceptions
if (in_array($word, self::$neuterExceptions))
$forms[Cases::RODIT] = $prefix.'ей';
Expand All @@ -104,7 +129,7 @@ static public function getCases($word, $animateness = false) {
$forms[Cases::RODIT] = $prefix;
else if (in_array($last, array('я'))) // молния
$forms[Cases::RODIT] = $prefix.'й';
else if (RussianLanguage::isHissingConsonant($last) || ($soft_last && $last != 'й') || S::slice($word, -2) == 'чь')
else if (RussianLanguage::isHissingConsonant($last) || ($soft_last && $last != 'й') || in_array(S::slice($word, -2), array('чь', 'сь')))
$forms[Cases::RODIT] = $prefix.'ей';
else if ($last == 'й')
$forms[Cases::RODIT] = $prefix.'ев';
Expand All @@ -119,7 +144,7 @@ static public function getCases($word, $animateness = false) {

// TVORIT
// my personal rule
if ($last == 'ь' && $declension == GeneralDeclension::THIRD_DECLENSION && S::slice($word, -2) != 'чь') {
if ($last == 'ь' && $declension == GeneralDeclension::THIRD_DECLENSION && !in_array(S::slice($word, -2), array('чь', 'сь'))) {
$forms[Cases::TVORIT] = $prefix.'ми';
} else {
$forms[Cases::TVORIT] = self::chooseVowelAfterConsonant($last, $soft_last && S::slice($word, -2, -1) != 'ч', $prefix.'ями', $prefix.'ами');
Expand Down
8 changes: 8 additions & 0 deletions src/S.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,12 @@ static public function last_position_for_one_of_chars($string, array $chars) {
return false;
}
}

static public function indexOf($string, $substring, $caseSensetive = false, $startOffset = 0) {
if (function_exists('mb_stripos')) {
return $caseSensetive ? mb_strpos($string, $substring, $startOffset) : mb_stripos($string, $substring, $startOffset);
} else {
return false;
}
}
}

0 comments on commit 2d1d9db

Please sign in to comment.