Skip to content

Commit

Permalink
dutch
Browse files Browse the repository at this point in the history
  • Loading branch information
noud authored and greg0ire committed Oct 28, 2020
1 parent cc041e1 commit eea1cb9
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/en/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ you want to create an inflector for to the ``createForLanguage()`` method:
The supported languages are as follows:

- ``Language::DUTCH``
- ``Language::ENGLISH``
- ``Language::FRENCH``
- ``Language::NORWEGIAN_BOKMAL``
Expand Down
4 changes: 4 additions & 0 deletions lib/Doctrine/Inflector/InflectorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\Inflector;

use Doctrine\Inflector\Rules\Dutch;
use Doctrine\Inflector\Rules\English;
use Doctrine\Inflector\Rules\French;
use Doctrine\Inflector\Rules\NorwegianBokmal;
Expand All @@ -24,6 +25,9 @@ public static function create(): LanguageInflectorFactory
public static function createForLanguage(string $language): LanguageInflectorFactory
{
switch ($language) {
case Language::DUTCH:
return new Dutch\InflectorFactory();

case Language::ENGLISH:
return new English\InflectorFactory();

Expand Down
1 change: 1 addition & 0 deletions lib/Doctrine/Inflector/Language.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

final class Language
{
public const DUTCH = 'dutch';
public const ENGLISH = 'english';
public const FRENCH = 'french';
public const NORWEGIAN_BOKMAL = 'norwegian-bokmal';
Expand Down
164 changes: 164 additions & 0 deletions lib/Doctrine/Inflector/Rules/Dutch/Inflectible.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Dutch;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

/**
* // http://nl.wikipedia.org/wiki/Klinker_(klank)
* private $klinker = '(a|e|i|o|u|ij)';
* private $korteKlinker = '(u|i|e|a|o)'; // @todo '(ie|oe)'. $plofKlank
*
* // http://nl.wikipedia.org/wiki/Medeklinker
* private $plofKlank = '(p|t|k|b|d)';
* private $wrijfKlank = '(f|s|ch|sj|v|z|g|j)'; // journaal
* private $neusKlank = '(m|n|ng)';
* private $vloeiKlank = '(l|r)';
* private $glijKlank = '(j|w)'; // jaar
* private $affricate = '(ts|zz|tsj|g)'; // /d3/ gin
* private $missingFromWiki = '(c|h|p|q|x|y|z)';
*
* public function __construct()
* {
* $this->medeklinker = '(' . $this->missingFromWiki . '|' . $this->plofKlank . '|' . $this->wrijfKlank . '|' . $this->neusKlank . '|' . $this->vloeiKlank . '|' . $this->glijKlank . '|' . $this->affricate . ')';
* $this->medeklinker = '((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g))';
* }
*/
class Inflectible
{
/**
* @return Transformation[]
*/
public static function getSingular(): iterable
{
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Klinkerverandering
yield new Transformation(new Pattern('()heden$'), '\1heid');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Beroepen_eindigend_op_-man
yield new Transformation(new Pattern('()mannen$'), '\1man');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Latijnse_meervoudsvormen
yield new Transformation(new Pattern('()ices$'), '\1ex');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Stapelmeervoud
yield new Transformation(new Pattern('^(ei|gemoed|goed|hoen|kind|lied|rad|rund)eren$'), '\1');

// http://nl.wikipedia.org/wiki/Nederlandse_grammatica
yield new Transformation(new Pattern('()ijen$'), '\1ij');

yield new Transformation(new Pattern('()ieen$'), '\1ie'); // ën

yield new Transformation(new Pattern('()((a|e|i|o|u|ij))s$'), '\1\2');

yield new Transformation(new Pattern('()((s)s)en$'), '\1s');

yield new Transformation(new Pattern('()((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g))en$'), '\1\2');
}

/**
* @return Transformation[]
*/
public static function getPlural(): iterable
{
// @todo already in plural (?)
// @todo refine
yield new Transformation(new Pattern('()(e)(s)$'), '\1\2\3\3en');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Klinkerverandering
yield new Transformation(new Pattern('()heid$'), '\1heden');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Beroepen_eindigend_op_-man
yield new Transformation(new Pattern('()man$'), '\1mannen');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Latijnse_meervoudsvormen
yield new Transformation(new Pattern('()ix$'), '\1ices');

yield new Transformation(new Pattern('()ex$'), '\1ices');

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Stapelmeervoud
yield new Transformation(new Pattern('^(ei|gemoed|goed|hoen|kind|lied|rad|rund)$'), '\1eren');

// http://nl.wikipedia.org/wiki/Nederlandse_grammatica
yield new Transformation(new Pattern('()ij$'), '\1ijen');

yield new Transformation(new Pattern('()orie$'), '\1orieen'); // ën klemtoon

yield new Transformation(new Pattern('()io$'), '\1io\'s');

yield new Transformation(new Pattern('()(a|e|i|o|u|ij)$'), '\1\2s');

yield new Transformation(new Pattern('()(((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g))e((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g)))$'), '\1\2s');

yield new Transformation(new Pattern('()(((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g))(u|i|e|a|o)s)$'), '\1\2sen');

yield new Transformation(new Pattern('()(((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g))s)$'), '\1\2en');

yield new Transformation(new Pattern('()s$'), '\1zen');

yield new Transformation(new Pattern('()((c|h|p|q|x|y|z)|(p|t|k|b|d)|(f|s|ch|sj|v|z|g|j)|(m|n|ng)|(l|r)|(j|w)|(ts|zz|tsj|g))$'), '\1\2en');
}

/**
* @return Substitution[]
*/
public static function getIrregular(): iterable
{
// http://nl.wikipedia.org/wiki/Klemtoon
yield new Substitution(new Word('olie'), new Word('oliën'));

yield new Substitution(new Word('industrie'), new Word('industrieën'));

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Klinkerverandering
yield new Substitution(new Word('lid'), new Word('leden'));

yield new Substitution(new Word('smid'), new Word('smeden'));

yield new Substitution(new Word('schip'), new Word('schepen'));

yield new Substitution(new Word('stad'), new Word('steden'));

yield new Substitution(new Word('gelid'), new Word('gelederen'));

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Stapelmeervoud
yield new Substitution(new Word('gelid'), new Word('gelederen'));

yield new Substitution(new Word('kalf'), new Word('kalveren'));

yield new Substitution(new Word('lam'), new Word('lammeren'));

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Onregelmatige_meervoudsvorming
yield new Substitution(new Word('koe'), new Word('koeien'));

yield new Substitution(new Word('vlo'), new Word('vlooien'));

yield new Substitution(new Word('leerrede'), new Word('leerredenen'));

yield new Substitution(new Word('lende'), new Word('lendenen'));

yield new Substitution(new Word('epos'), new Word('epen'));

yield new Substitution(new Word('genius'), new Word('geniën'));

yield new Substitution(new Word('aanbod'), new Word('aanbiedingen'));

yield new Substitution(new Word('beleg'), new Word('belegeringen'));

yield new Substitution(new Word('dank'), new Word('dankbetuigingen'));

yield new Substitution(new Word('gedrag'), new Word('gedragingen'));

yield new Substitution(new Word('genot'), new Word('genietingen'));

yield new Substitution(new Word('lof'), new Word('lofbetuigingen'));

// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Latijnse_meervoudsvormen
yield new Substitution(new Word('qaestrices'), new Word('quaestrix'));

yield new Substitution(new Word('matrices'), new Word('matrix'));
}
}
21 changes: 21 additions & 0 deletions lib/Doctrine/Inflector/Rules/Dutch/InflectorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Dutch;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
31 changes: 31 additions & 0 deletions lib/Doctrine/Inflector/Rules/Dutch/Rules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Dutch;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
66 changes: 66 additions & 0 deletions lib/Doctrine/Inflector/Rules/Dutch/Uninflected.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Dutch;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{
/**
* @return Pattern[]
*/
public static function getSingular(): iterable
{
yield from self::getDefault();

// http://nl.wikipedia.org/wiki/Plurale_tantum
yield new Pattern('hersenen');
yield new Pattern('ingewanden');
yield new Pattern('mazelen');
yield new Pattern('pokken');
yield new Pattern('waterpokken');
yield new Pattern('financiën');
yield new Pattern('activa');
yield new Pattern('passiva');
yield new Pattern('onkosten');
yield new Pattern('kosten');
yield new Pattern('bescheiden');
yield new Pattern('paperassen');
yield new Pattern('notulen');
yield new Pattern('Roma');
yield new Pattern('Sinti');
yield new Pattern('Inuit');
yield new Pattern('taliban');
yield new Pattern('illuminati');
yield new Pattern('aanstalten');
yield new Pattern('hurken');
yield new Pattern('lurven');
yield new Pattern('luren');
}

/**
* @return Pattern[]
*/
public static function getPlural(): iterable
{
yield from self::getDefault();

// http://nl.wikipedia.org/wiki/Singulare_tantum
yield new Pattern('letterkunde');
yield new Pattern('muziek');
yield new Pattern('heelal');
yield new Pattern('vastgoed');
yield new Pattern('have');
yield new Pattern('nageslacht');
}

/**
* @return Pattern[]
*/
private static function getDefault(): iterable
{
yield new Pattern('twitter');
}
}
2 changes: 2 additions & 0 deletions tests/Doctrine/Tests/Inflector/InflectorFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Inflector\InflectorFactory;
use Doctrine\Inflector\Language;
use Doctrine\Inflector\LanguageInflectorFactory;
use Doctrine\Inflector\Rules\Dutch\InflectorFactory as DutchInflectorFactory;
use Doctrine\Inflector\Rules\English\InflectorFactory as EnglishInflectorFactory;
use Doctrine\Inflector\Rules\French\InflectorFactory as FrenchInflectorFactory;
use Doctrine\Inflector\Rules\NorwegianBokmal\InflectorFactory as NorwegianBokmalInflectorFactory;
Expand Down Expand Up @@ -38,6 +39,7 @@ public function testCreateForLanguageWithCustomLanguage(string $expectedClass, s
*/
public static function provideLanguages(): Generator
{
yield 'Dutch' => [DutchInflectorFactory::class, Language::DUTCH];
yield 'English' => [EnglishInflectorFactory::class, Language::ENGLISH];
yield 'French' => [FrenchInflectorFactory::class, Language::FRENCH];
yield 'Norwegian Bokmal' => [NorwegianBokmalInflectorFactory::class, Language::NORWEGIAN_BOKMAL];
Expand Down
57 changes: 57 additions & 0 deletions tests/Doctrine/Tests/Inflector/Rules/Dutch/DutchFunctionalTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Inflector\Rules\Dutch;

use Doctrine\Inflector\Inflector;
use Doctrine\Inflector\InflectorFactory;
use Doctrine\Inflector\Language;
use Doctrine\Tests\Inflector\Rules\LanguageFunctionalTest;

class DutchFunctionalTest extends LanguageFunctionalTest
{
/**
* @return string[][]
*/
public function dataSampleWords(): array
{
return [
['weerman', 'weermannen'],
['ei', 'eieren'],
['rij', 'rijen'],
['mogelijkheid', 'mogelijkheden'],
['adres', 'adressen'],
['olie', 'oliën'],
['industrie', 'industrieën'],
['lid', 'leden'],
['smid', 'smeden'],
['schip', 'schepen'],
['stad', 'steden'],
['gelid', 'gelederen'],
['gelid', 'gelederen'],
['kalf', 'kalveren'],
['lam', 'lammeren'],
['koe', 'koeien'],
['vlo', 'vlooien'],
['leerrede', 'leerredenen'],
['lende', 'lendenen'],
['epos', 'epen'],
['genius', 'geniën'],
['aanbod', 'aanbiedingen'],
['beleg', 'belegeringen'],
['dank', 'dankbetuigingen'],
['gedrag', 'gedragingen'],
['genot', 'genietingen'],
['lof', 'lofbetuigingen'],
['qaestrices', 'quaestrix'],
['matrices', 'matrix'],
['twitter', 'twitter'],
];
}

protected function createInflector(): Inflector
{
return InflectorFactory::createForLanguage(Language::DUTCH)->build();
}
}

0 comments on commit eea1cb9

Please sign in to comment.