Skip to content

Commit

Permalink
Add methods to prepend words with prepositional
Browse files Browse the repository at this point in the history
  • Loading branch information
wapmorgan committed Aug 30, 2017
1 parent abd6d28 commit dd63975
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 43 deletions.
61 changes: 35 additions & 26 deletions README-ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
* [Количественные числительные](#Количественные-числительные)
* [Порядковые числительные](#Порядковые-числительные)
* [Валюты](#Валюты)
* [Окончание глаголов](#Окончание-глаголов)
* [Временные интервалы](#Временные-интервалы)
* [Предлоги и окончания](#Предлоги-и-окончания)

Для русского языка доступны следующие классы и функции из пространства имён `morphos\Russian\`:

Expand All @@ -30,11 +30,12 @@
- для генерации текстом различных данных:
- `MoneySpeller`
- `TimeSpeller`
- для добавления предлогов и окончаний:
- `RussianLanguage`

**Функции:**
* `inflectName($fullname, $case, $gender = AUTO)`
* `pluralize($count, $noun, $animateness = false)`
* `verb($verb, $gender)`


## Имена собственные
Expand Down Expand Up @@ -340,30 +341,6 @@ MoneySpeller::spell(123.45, 'RUB', MoneySpeller::CLARIFICATION_FORMAT) => '123 (
| R | рэнд |
|| гривна |

## Окончание глаголов

Глаголы в прошедшем времени в русском языке имеют признак рода. Чтобы упростить подбор правильной формы глаголы используйте функцию:

```php
string verb($verb, $gender)
```

Аргументы:
- `$verb` - глагол в мужском роде и прошедшем времени.
- `$gender` - необходимый род глагола. Если указано не `Gender::MALE`, то будет произведено преобразование в женский род.

_Пример_

```php
use function morphos\Russian\verb;

$name = 'Анастасия';
$gender = morphos\Gender::FEMALE;

$name.' '.verb('добавил', $gender) => 'Анастасия добавила'
$name.' '.verb('поделился', $gender).' публикацией' => 'Анастасия поделилась публикацией'
```

## Временные интервалы

Класс `TimeSpeller` позволяет записать человеческим языком временной интервал, задаваемый объектом `DateInterval`.
Expand All @@ -386,3 +363,35 @@ TimeSpeller::spellInterval(new DateInterval('P5YT2M'), TimeSpeller::DIRECTION) =
TimeSpeller::spellInterval(new DateInterval('P5YT2M'), TimeSpeller::SEPARATE) => '5 лет и 2 часа'
TimeSpeller::spellInterval(new DateInterval('P5YT2M'), TimeSpeller::DIRECTION | TimeSpeller::SEPARATE) => '5 лет и 2 часа назад'
```

## Предлоги и окончания
В классе `morphos\Russian\RussianLanguage` есть следующие методы для добавления предлогов или измениня окончаний разных слов:

* `in($word)` - добавляет предлог `в` или `во` в зависимости от того, с каких букв начинается слово.
* `with($word)` - добавляет предлог `с` или `со` в зависимости от того, с каких букв начинается слово.
* `about($word)` - добавляет предлог `о`, `об` или `обо` в зависимости от того, с каких букв начинается слово.
* `verb($verb, $gender)` - изменяет окончание глагола в прошедшем времени в зависимости от рода.

### Окончание глаголов

Глаголы в прошедшем времени в русском языке имеют признак рода. Чтобы упростить подбор правильной формы глаголы используйте функцию:

```php
string RussianLanguage::verb($verb, $gender)
```

Аргументы:
- `$verb` - глагол в мужском роде и прошедшем времени.
- `$gender` - необходимый род глагола. Если указано не `Gender::MALE`, то будет произведено преобразование в женский род.

_Пример_

```php
use morphos\Russian\RussianLanguage;

$name = 'Анастасия';
$gender = morphos\Gender::FEMALE;

$name.' '.RussianLanguage::verb('добавил', $gender) => 'Анастасия добавила'
$name.' '.RussianLanguage::verb('поделился', $gender).' публикацией' => 'Анастасия поделилась публикацией'
```
61 changes: 61 additions & 0 deletions src/Russian/RussianLanguage.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace morphos\Russian;

use morphos\Gender;
use morphos\S;

trait RussianLanguage
Expand Down Expand Up @@ -124,4 +125,64 @@ public static function chooseVowelAfterConsonant($last, $soft_last, $after_soft,
return $after_hard;
}
}

/**
* @param string $verb Verb to modify if gender is female
* @param string $gender If not `m`, verb will be modified
* @return string Correct verb
*/
public static function verb($verb, $gender)
{
$verb = S::lower($verb);
// возвратный глагол
if (S::slice($verb, -2) == 'ся') {
return ($gender == Gender::MALE ? $verb : mb_substr($verb, 0, -2).'ась');
}

// обычный глагол
return ($gender == Gender::MALE ? $verb : $verb.'а');
}

/**
* Add 'в' or 'во' prepositional before the word
* @param string $word
* @return string
*/
public static function in($word)
{
$normalized = trim(S::lower($word));
if (in_array(S::slice($normalized, 0, 1), ['в', 'ф']))
return 'во '.$word;
return 'в '.$word;
}

/**
* Add 'с' or 'со' prepositional before the word
* @param string $word
* @return string
*/
public static function with($word)
{
$normalized = trim(S::lower($word));
if (in_array(S::slice($normalized, 0, 1), ['c', 'з', 'ш', 'ж']) && static::isConsonant(S::slice($normalized, 1, 2)) || S::slice($normalized, 0, 1) == 'щ')
return 'со '.$word;
return 'с '.$word;
}

/**
* Add 'о' or 'об' or 'обо' prepositional before the word
* @param string $word
* @return string
*/
public static function about($word)
{
$normalized = trim(S::lower($word));
if (static::isVowel(S::slice($normalized, 0, 1)) && !in_array(S::slice($normalized, 0, 1), ['е', 'ё', 'ю', 'я']))
return 'об '.$word;

if (in_array(S::slice($normalized, 0, 3), ['все', 'всё', 'всю', 'что', 'мне']))
return 'обо '.$word;

return 'о '.$word;
}
}
16 changes: 0 additions & 16 deletions src/Russian/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,3 @@ function pluralize($count, $word, $animateness = false)
{
return $count.' '.NounPluralization::pluralize($word, $count, $animateness);
}

/**
* @param string $verb Verb to modify if gender is female
* @param string $gender If not `m`, verb will be modified
* @return string Correct verb
*/
function verb($verb, $gender)
{
// возвратный глагол
if (S::slice($verb, -2) == 'ся') {
return ($gender == 'm' ? $verb : mb_substr($verb, 0, -2).'ась');
}

// обычный глагол
return ($gender == 'm' ? $verb : $verb.'а');
}
2 changes: 1 addition & 1 deletion tests/Russian/FunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function namesProvider()
*/
public function testVerb($verb, $gender, $correctVerb)
{
$this->assertEquals($correctVerb, \morphos\Russian\verb($verb, $gender));
$this->assertEquals($correctVerb, \morphos\Russian\RussianLanguage::verb($verb, $gender));
}

public function verbsProvider()
Expand Down
52 changes: 52 additions & 0 deletions tests/Russian/RussianLanguageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
namespace morphos\test\Russian;

require __DIR__.'/../../vendor/autoload.php';

use morphos\Gender;
use morphos\NumeralGenerator;
use morphos\Russian\Cases;
use morphos\Russian\CardinalNumeralGenerator;
use morphos\Russian\RussianLanguage;

class RussianLanguageTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider verbsProvider()
*/
public function testVerb($verb, $gender, $correctVerb)
{
$this->assertEquals($correctVerb, \morphos\Russian\RussianLanguage::verb($verb, $gender));
}

public function verbsProvider()
{
return
[
['попал', Gender::MALE, 'попал'],
['попал', Gender::FEMALE, 'попала'],
['попался', Gender::MALE, 'попался'],
['попался', Gender::FEMALE, 'попалась'],
];
}

public function testIn()
{
$this->assertEquals('в море', RussianLanguage::in('море'));
$this->assertEquals('во Владивостоке', RussianLanguage::in('Владивостоке'));
}

public function testWith()
{
$this->assertEquals('с пола', RussianLanguage::with('пола'));
$this->assertEquals('со шкафа', RussianLanguage::with('шкафа'));
$this->assertEquals('со щами', RussianLanguage::with('щами'));
}

public function testAbout()
{
$this->assertEquals('о материи', RussianLanguage::about('материи'));
$this->assertEquals('об одном', RussianLanguage::about('одном'));
$this->assertEquals('обо всём', RussianLanguage::about('всём'));
}
}

0 comments on commit dd63975

Please sign in to comment.