Skip to content

Commit

Permalink
Localized inflections are now autoloaded
Browse files Browse the repository at this point in the history
  • Loading branch information
olvlvl committed Jul 16, 2021
1 parent 77a5dfc commit dd0d96c
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 244 deletions.
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

A multilingual inflector that transforms words from singular to plural, underscore to camel case, and formats strings in
various ways. Inflections are localized, the default english inflections for pluralization, singularization, and
uncountable words are kept in [lib/inflections/en.php](lib/Inflections/en.php).
uncountable words are kept in [lib/Inflections/en.php](lib/Inflections/en.php).

Inflections are currently available for the following languages:

Expand Down Expand Up @@ -35,13 +35,13 @@ These are some examples of the inflector with the `en` locale (default).
```php
<?php

use ICanBoogie\Inflector;
use ICanBoogie\InflectionsConfigurator;

$inflector = Inflector::get(Inflector::DEFAULT_LOCALE);
$inflector = InflectionsConfigurator::get(InflectionsConfigurator::DEFAULT_LOCALE);
# or
$inflector = Inflector::get('en');
$inflector = InflectionsConfigurator::get('en');
# or
$inflector = Inflector::get();
$inflector = InflectionsConfigurator::get();

# pluralize

Expand All @@ -61,18 +61,18 @@ $inflector->singularize('CamelChildren'); // "CamelChild"

# camelize

$inflector->camelize('active_model', Inflector::UPCASE_FIRST_LETTER);
$inflector->camelize('active_model', InflectionsConfigurator::UPCASE_FIRST_LETTER);
# or
$inflector->camelize('active_model');
// 'ActiveModel'

$inflector->camelize('active_model', Inflector::DOWNCASE_FIRST_LETTER);
$inflector->camelize('active_model', InflectionsConfigurator::DOWNCASE_FIRST_LETTER);
// 'activeModel'

$inflector->camelize('active_model/errors');
// 'ActiveModel\Errors'

$inflector->camelize('active_model/errors', Inflector::DOWNCASE_FIRST_LETTER);
$inflector->camelize('active_model/errors', InflectionsConfigurator::DOWNCASE_FIRST_LETTER);
// 'activeModel\Errors'

# underscore
Expand Down Expand Up @@ -135,6 +135,13 @@ echo pluralize('üçgen', 'tr'); // "üçgenler"
```


## About inflections

Inflections are localized, the configurators are kept in [lib/Inflections/en.php](lib/Inflections/en.php). Since v2.1,
these configurators are auto-loaded classes, which means, in theory, you could add your own or overwrite those already
defined by specifying another `ICanBoogie\\Inflections\\` in your `composer.json` file.



### Acknowledgements

Expand Down
10 changes: 5 additions & 5 deletions lib/Inflections.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ public static function get(string $locale = INFLECTOR_DEFAULT_LOCALE): Inflectio
return self::$inflections[$locale];
}

$instance = new self();
$inflections = new self();

/* @var $inflections callable */
/* @var $configurator InflectionsConfigurator */

$inflections = require __DIR__ . "/Inflections/{$locale}.php";
$inflections($instance);
$configurator = __NAMESPACE__ . "\\Inflections\\$locale";
$configurator::configure($inflections);

return self::$inflections[$locale] = $instance;
return self::$inflections[$locale] = $inflections;
}

/**
Expand Down
139 changes: 74 additions & 65 deletions lib/Inflections/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,73 +9,82 @@
* file that was distributed with this source code.
*/

namespace ICanBoogie;
namespace ICanBoogie\Inflections;

use ICanBoogie\Inflections;
use ICanBoogie\InflectionsConfigurator;

use function explode;

/**
* English Inflections.
*
* @codeCoverageIgnore
*/
//@codeCoverageIgnoreStart
return function (Inflections $inflect): void {
$inflect
->plural('/$/', 's')
->plural('/s$/i', 's')
->plural('/^(ax|test)is$/i', '\1es')
->plural('/(alias|status)$/i', '\1es')
->plural('/(bu)s$/i', '\1ses')
->plural('/(buffal|tomat|potat|volcan|her)o$/i', '\1oes')
->plural('/([ti])um$/i', '\1a')
->plural('/([ti])a$/i', '\1a')
->plural('/sis$/i', 'ses')
->plural('/(?:([^f])fe|([lr])f)$/i', '\1\2ves')
->plural('/(hive)$/i', '\1s')
->plural('/([^aeiouy]|qu)y$/i', '\1ies')
->plural('/(x|ch|ss|sh)$/i', '\1es')
->plural('/(matr|vert|ind)(?:ix|ex)$/i', '\1ices')
->plural('/^(m|l)ouse$/i', '\1ice')
->plural('/^(m|l)ice$/i', '\1ice')
->plural('/^(ox)$/i', '\1en')
->plural('/^(oxen)$/i', '\1')
->plural('/(quiz)$/i', '\1zes')
->singular('/s$/i', '')
->singular('/(ss)$/i', '\1')
->singular('/(n)ews$/i', '\1ews')
->singular('/([ti])a$/i', '\1um')
->singular('/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i', '\1sis')
->singular('/(^analy)(sis|ses)$/i', '\1sis')
->singular('/([^f])ves$/i', '\1fe')
->singular('/(hive)s$/i', '\1')
->singular('/(tive)s$/i', '\1')
->singular('/([lr])ves$/i', '\1f')
->singular('/([^aeiouy]|qu)ies$/i', '\1y')
->singular('/(s)eries$/i', '\1eries')
->singular('/(m)ovies$/i', '\1ovie')
->singular('/(x|ch|ss|sh)es$/i', '\1')
->singular('/^(m|l)ice$/i', '\1ouse')
->singular('/(bus)(es)?$/i', '\1')
->singular('/(o)es$/i', '\1')
->singular('/(shoe)s$/i', '\1')
->singular('/(cris|test)(is|es)$/i', '\1is')
->singular('/^(a)x[ie]s$/i', '\1xis')
->singular('/(alias|status)(es)?$/i', '\1')
->singular('/^(ox)en/i', '\1')
->singular('/(vert|ind)ices$/i', '\1ex')
->singular('/(matr)ices$/i', '\1ix')
->singular('/(quiz)zes$/i', '\1')
->singular('/(database)s$/i', '\1')
->irregular('leaf', 'leaves')
->irregular('loaf', 'loaves')
->irregular('octopus', 'octopuses')
->irregular('virus', 'viruses')
->irregular('person', 'people')
->irregular('man', 'men')
->irregular('child', 'children')
->irregular('sex', 'sexes')
->irregular('move', 'moves')
->irregular('zombie', 'zombies')
->irregular('goose', 'geese')
->irregular('genus', 'genera')
final class en implements InflectionsConfigurator
{
public static function configure(Inflections $inflections): void
{
$inflections
->plural('/$/', 's')
->plural('/s$/i', 's')
->plural('/^(ax|test)is$/i', '\1es')
->plural('/(alias|status)$/i', '\1es')
->plural('/(bu)s$/i', '\1ses')
->plural('/(buffal|tomat|potat|volcan|her)o$/i', '\1oes')
->plural('/([ti])um$/i', '\1a')
->plural('/([ti])a$/i', '\1a')
->plural('/sis$/i', 'ses')
->plural('/(?:([^f])fe|([lr])f)$/i', '\1\2ves')
->plural('/(hive)$/i', '\1s')
->plural('/([^aeiouy]|qu)y$/i', '\1ies')
->plural('/(x|ch|ss|sh)$/i', '\1es')
->plural('/(matr|vert|ind)(?:ix|ex)$/i', '\1ices')
->plural('/^(m|l)ouse$/i', '\1ice')
->plural('/^(m|l)ice$/i', '\1ice')
->plural('/^(ox)$/i', '\1en')
->plural('/^(oxen)$/i', '\1')
->plural('/(quiz)$/i', '\1zes')
->singular('/s$/i', '')
->singular('/(ss)$/i', '\1')
->singular('/(n)ews$/i', '\1ews')
->singular('/([ti])a$/i', '\1um')
->singular('/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i', '\1sis')
->singular('/(^analy)(sis|ses)$/i', '\1sis')
->singular('/([^f])ves$/i', '\1fe')
->singular('/(hive)s$/i', '\1')
->singular('/(tive)s$/i', '\1')
->singular('/([lr])ves$/i', '\1f')
->singular('/([^aeiouy]|qu)ies$/i', '\1y')
->singular('/(s)eries$/i', '\1eries')
->singular('/(m)ovies$/i', '\1ovie')
->singular('/(x|ch|ss|sh)es$/i', '\1')
->singular('/^(m|l)ice$/i', '\1ouse')
->singular('/(bus)(es)?$/i', '\1')
->singular('/(o)es$/i', '\1')
->singular('/(shoe)s$/i', '\1')
->singular('/(cris|test)(is|es)$/i', '\1is')
->singular('/^(a)x[ie]s$/i', '\1xis')
->singular('/(alias|status)(es)?$/i', '\1')
->singular('/^(ox)en/i', '\1')
->singular('/(vert|ind)ices$/i', '\1ex')
->singular('/(matr)ices$/i', '\1ix')
->singular('/(quiz)zes$/i', '\1')
->singular('/(database)s$/i', '\1')
->irregular('leaf', 'leaves')
->irregular('loaf', 'loaves')
->irregular('octopus', 'octopuses')
->irregular('virus', 'viruses')
->irregular('person', 'people')
->irregular('man', 'men')
->irregular('child', 'children')
->irregular('sex', 'sexes')
->irregular('move', 'moves')
->irregular('zombie', 'zombies')
->irregular('goose', 'geese')
->irregular('genus', 'genera')

// http://easenglish.net/Files/Grammar/uncountable%20words.pdf
->uncountable(explode(' ', 'advice aircraft art baggage butter clothing coal cotton deer equipment experience feedback fish flour food furniture gas homework impatience information jeans knowledge leather love luggage management money moose music news oil patience police polish progress research rice salmon sand series sheep silk sms soap spam species staff sugar swine talent toothpaste traffic travel vinegar weather wood wool work'));
};
//@codeCoverageIgnoreEnd
// http://easenglish.net/Files/Grammar/uncountable%20words.pdf
->uncountable(explode(' ', 'advice aircraft art baggage butter clothing coal cotton deer equipment experience feedback fish flour food furniture gas homework impatience information jeans knowledge leather love luggage management money moose music news oil patience police polish progress research rice salmon sand series sheep silk sms soap spam species staff sugar swine talent toothpaste traffic travel vinegar weather wood wool work'));
}
}
65 changes: 36 additions & 29 deletions lib/Inflections/es.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,46 @@
* file that was distributed with this source code.
*/

namespace ICanBoogie;
namespace ICanBoogie\Inflections;

use ICanBoogie\Inflections;
use ICanBoogie\InflectionsConfigurator;

/**
* Spanish Inflections.
*
* @see http://www.studyspanish.com/lessons/plnoun.htm
* @see http://spanish.about.com/cs/writing/a/writing_plurals.htm
*
* @codeCoverageIgnore
*/
//@codeCoverageIgnoreStart
return function (Inflections $inflect): void {
$inflect
->plural('/$/', 's')
->plural('/([^aeéiou])$/i', '\1es')
->plural('/([aeiou]s)$/i', '\1')
->plural('/z$/i', 'ces')
->plural('/á([sn])$/i', 'a\1es')
->plural('/é([sn])$/i', 'e\1es')
->plural('/í([sn])$/i', 'i\1es')
->plural('/ó([sn])$/i', 'o\1es')
->plural('/ú([sn])$/i', 'u\1es')
->singular('/s$/', '')
->singular('/es$/', '')
->singular('/ces$/', 'z')
->singular('/iones$/', 'ión')
->singular('/ereses$/', 'erés')
->irregular('el', 'los')
->irregular('lunes', 'lunes')
->irregular('rompecabezas', 'rompecabezas')
->irregular('crisis', 'crisis')
->irregular('papá', 'papás')
->irregular('mamá', 'mamás')
->irregular('sofá', 'sofás')
// because 'mes' is considered already a plural
->irregular('mes', 'meses');
};
//@codeCoverageIgnoreEnd
final class es implements InflectionsConfigurator
{
public static function configure(Inflections $inflections): void
{
$inflections
->plural('/$/', 's')
->plural('/([^aeéiou])$/i', '\1es')
->plural('/([aeiou]s)$/i', '\1')
->plural('/z$/i', 'ces')
->plural('/á([sn])$/i', 'a\1es')
->plural('/é([sn])$/i', 'e\1es')
->plural('/í([sn])$/i', 'i\1es')
->plural('/ó([sn])$/i', 'o\1es')
->plural('/ú([sn])$/i', 'u\1es')
->singular('/s$/', '')
->singular('/es$/', '')
->singular('/ces$/', 'z')
->singular('/iones$/', 'ión')
->singular('/ereses$/', 'erés')
->irregular('el', 'los')
->irregular('lunes', 'lunes')
->irregular('rompecabezas', 'rompecabezas')
->irregular('crisis', 'crisis')
->irregular('papá', 'papás')
->irregular('mamá', 'mamás')
->irregular('sofá', 'sofás')
// because 'mes' is considered already a plural
->irregular('mes', 'meses');
}
}
49 changes: 28 additions & 21 deletions lib/Inflections/fr.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,37 @@
* file that was distributed with this source code.
*/

namespace ICanBoogie;
namespace ICanBoogie\Inflections;

use ICanBoogie\Inflections;
use ICanBoogie\InflectionsConfigurator;

/**
* French Inflections.
*
* @see http://grammaire.reverso.net/5_5_01_pluriel_des_noms_et_des_adjectifs.shtml
*
* @codeCoverageIgnore
*/
//@codeCoverageIgnoreStart
return function (Inflections $inflect): void {
$inflect
->plural('/$/', 's')
->singular('/s$/', '')
->plural('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)$/', '\1x')
->singular('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/', '\1')
->plural('/(bleu|émeu|landau|lieu|pneu|sarrau)$/', '\1s')
->plural('/al$/', 'aux')
->plural('/ail$/', 'ails')
->singular('/(journ|chev)aux$/', '\1al')
->singular('/ails$/', 'ail')
->plural('/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/', '\1aux')
->singular('/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/', '\1ail')
->plural('/(s|x|z)$/', '\1')
->irregular('monsieur', 'messieurs')
->irregular('madame', 'mesdames')
->irregular('mademoiselle', 'mesdemoiselles');
};
//@codeCoverageIgnoreEnd
final class fr implements InflectionsConfigurator
{
public static function configure(Inflections $inflections): void
{
$inflections
->plural('/$/', 's')
->singular('/s$/', '')
->plural('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)$/', '\1x')
->singular('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/', '\1')
->plural('/(bleu|émeu|landau|lieu|pneu|sarrau)$/', '\1s')
->plural('/al$/', 'aux')
->plural('/ail$/', 'ails')
->singular('/(journ|chev)aux$/', '\1al')
->singular('/ails$/', 'ail')
->plural('/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/', '\1aux')
->singular('/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/', '\1ail')
->plural('/(s|x|z)$/', '\1')
->irregular('monsieur', 'messieurs')
->irregular('madame', 'mesdames')
->irregular('mademoiselle', 'mesdemoiselles');
}
}

0 comments on commit dd0d96c

Please sign in to comment.