wapmorgan / Morphos

A morphological solution for Russian and English language written completely in PHP. Provides classes to inflect personal names, geographical names, decline and pluralize nouns, generate cardinal and ordinal numerals, spell out money amounts and time intervals. / Морфологическая библиотека для английского и русского языков. Склоняет имена собственные, названия географических объектов, склонение и плюрализация имен собственных и другое.
http://wapmorgan.github.io/Morphos/
MIT License
788 stars 105 forks source link

Добавить параметр $case к NounPluralization::pluralize() #42

Closed duzun closed 5 years ago

duzun commented 5 years ago

Как склонять в множественом числе?

Желательный пример:

NounPluralization::pluralize('цвет', 7, false, 'prepositional'); // -> цветах

Я экспериментировал с этим методом, но не уверен в правильности для всех падежей:

    // @file morphos/src/Russian/NounPluralization.php

    public static function pluralize($word, $count = 2, $animateness = false, $case = NULL)
    {
        $case = isset($case) ? self::canonizeCase($case) : self::RODIT;

        // меняем местами аргументы, если они переданы в старом формате
        if (is_string($count) && is_numeric($word)) {
            list($count, $word) = [$word, $count];
        }

        // для адъективных существительных правила склонения проще:
        // только две формы
        if (self::isAdjectiveNoun($word)) {
            if (self::getNumeralForm($count) == self::ONE)
                return $case == self::RODIT ? $word : NounDeclension::getCase($word, $case, $animateness);
            else
                return NounPluralization::getCase($word, $case, $animateness);
        }

        switch (self::getNumeralForm($count)) {
            case self::ONE:
                return $case == self::RODIT ? $word : NounDeclension::getCase($word, $case, $animateness);
            case self::TWO_FOUR:
                if ( $case != self::PREPOSITIONAL ) {
                    return NounDeclension::getCase($word, $case, $animateness);
                }
            case self::FIVE_OTHER:
                // special case for YEAR >= 5
                if ($word === 'год') {
                    return 'лет';
                }

                return NounPluralization::getCase($word, $case, $animateness);
        }
    }
wapmorgan commented 5 years ago

А смысл есть в этом? Где-то это используется?

wapmorgan commented 5 years ago

@duzun мне бы реальный use-case для этого.

duzun commented 5 years ago

В моем случае, у каталога товаров есть список параметров / характеристик. К примеру есть параметр "цвет". В описании колекции товаров я генерирую общий обзор типа:

и.т.д.

Имя параметра "цвет".

По такому же принципу генерирую описание и по другим параметрам.

wapmorgan commented 5 years ago

Добавил к morphos\Russian\pluralize() и morphos\Russian\NounPluralization::pluralize() параметр, в котором можно передать нужный падеж. Например,

NounPluralization::pluralize('цвет', 1, false, 'п') //=> цвете
NounPluralization::pluralize('цвет', 2, false, 'п') //=> цветах
duzun commented 5 years ago

Спасибо @wapmorgan ! Я обновил morphos в моем проекте, и на первый взгляд все работает. Если буудут исключения, дам знать.

Почему в случае self::getNumeralForm($count) == self::ONE не склоняется $word? Тут: R84 и R91

wapmorgan commented 5 years ago

https://github.com/wapmorgan/Morphos/blob/3.2.15/src/Russian/NounPluralization.php#L81 Насчёт адъективное существительного - ещё подумаю, может там тоже нужна проверка "не указан ли падеж".

https://github.com/wapmorgan/Morphos/blob/3.2.15/src/Russian/NounPluralization.php#L93 Здесь всё просто. Если падеж не указан, значит необходима форма "1 предмет / 2 предмета / 5 предметов". Если указан, то склонение идёт уже по заданному падежу (https://github.com/wapmorgan/Morphos/blob/3.2.15/src/Russian/NounPluralization.php#L101).

duzun commented 5 years ago

Ясно, я не там смотрел :) Я смотрел только на один комит.

Мой последний вопрос не уместен.