Skip to content

Commit 3c5aa5a

Browse files
committed
dutch
1 parent e579cfd commit 3c5aa5a

File tree

9 files changed

+346
-0
lines changed

9 files changed

+346
-0
lines changed

docs/en/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ you want to create an inflector for to the ``createForLanguage()`` method:
3838
3939
The supported languages are as follows:
4040

41+
- ``Language::DUTCH``
4142
- ``Language::ENGLISH``
4243
- ``Language::FRENCH``
4344
- ``Language::NORWEGIAN_BOKMAL``

lib/Doctrine/Inflector/InflectorFactory.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Doctrine\Inflector;
66

7+
use Doctrine\Inflector\Rules\Dutch;
78
use Doctrine\Inflector\Rules\English;
89
use Doctrine\Inflector\Rules\French;
910
use Doctrine\Inflector\Rules\NorwegianBokmal;
@@ -23,6 +24,8 @@ public static function create() : LanguageInflectorFactory
2324
public static function createForLanguage(string $language) : LanguageInflectorFactory
2425
{
2526
switch ($language) {
27+
case Language::DUTCH:
28+
return new Dutch\InflectorFactory();
2629
case Language::ENGLISH:
2730
return new English\InflectorFactory();
2831
case Language::FRENCH:

lib/Doctrine/Inflector/Language.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
final class Language
88
{
9+
public const DUTCH = 'dutch';
910
public const ENGLISH = 'english';
1011
public const FRENCH = 'french';
1112
public const NORWEGIAN_BOKMAL = 'norwegian-bokmal';
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Inflector\Rules\Dutch;
6+
7+
use Doctrine\Inflector\Rules\Pattern;
8+
use Doctrine\Inflector\Rules\Substitution;
9+
use Doctrine\Inflector\Rules\Transformation;
10+
use Doctrine\Inflector\Rules\Word;
11+
12+
/**
13+
* // http://nl.wikipedia.org/wiki/Klinker_(klank)
14+
* private $klinker = '(a|e|i|o|u|ij)';
15+
* private $korteKlinker = '(u|i|e|a|o)'; // @todo '(ie|oe)'. $plofKlank
16+
*
17+
* // http://nl.wikipedia.org/wiki/Medeklinker
18+
* private $plofKlank = '(p|t|k|b|d)';
19+
* private $wrijfKlank = '(f|s|ch|sj|v|z|g|j)'; // journaal
20+
* private $neusKlank = '(m|n|ng)';
21+
* private $vloeiKlank = '(l|r)';
22+
* private $glijKlank = '(j|w)'; // jaar
23+
* private $affricate = '(ts|zz|tsj|g)'; // /d3/ gin
24+
* private $missingFromWiki = '(c|h|p|q|x|y|z)';
25+
*
26+
* public function __construct()
27+
* {
28+
* $this->medeklinker = '(' . $this->missingFromWiki . '|' . $this->plofKlank . '|' . $this->wrijfKlank . '|' . $this->neusKlank . '|' . $this->vloeiKlank . '|' . $this->glijKlank . '|' . $this->affricate . ')';
29+
* $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))';
30+
* }
31+
*/
32+
class Inflectible
33+
{
34+
/**
35+
* @return Transformation[]
36+
*/
37+
public static function getSingular() : iterable
38+
{
39+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Klinkerverandering
40+
yield new Transformation(new Pattern('()heden$'), '\1heid');
41+
42+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Beroepen_eindigend_op_-man
43+
yield new Transformation(new Pattern('()mannen$'), '\1man');
44+
45+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Latijnse_meervoudsvormen
46+
yield new Transformation(new Pattern('()ices$'), '\1ex');
47+
48+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Stapelmeervoud
49+
yield new Transformation(new Pattern('^(ei|gemoed|goed|hoen|kind|lied|rad|rund)eren$'), '\1');
50+
51+
// http://nl.wikipedia.org/wiki/Nederlandse_grammatica
52+
yield new Transformation(new Pattern('()ijen$'), '\1ij');
53+
54+
yield new Transformation(new Pattern('()ieen$'), '\1ie'); // ën
55+
56+
yield new Transformation(new Pattern('()((a|e|i|o|u|ij))s$'), '\1\2');
57+
58+
yield new Transformation(new Pattern('()((s)s)en$'), '\1s');
59+
60+
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');
61+
}
62+
63+
/**
64+
* @return Transformation[]
65+
*/
66+
public static function getPlural() : iterable
67+
{
68+
// @todo already in plural (?)
69+
// @todo refine
70+
yield new Transformation(new Pattern('()(e)(s)$'), '\1\2\3\3en');
71+
72+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Klinkerverandering
73+
yield new Transformation(new Pattern('()heid$'), '\1heden');
74+
75+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Beroepen_eindigend_op_-man
76+
yield new Transformation(new Pattern('()man$'), '\1mannen');
77+
78+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Latijnse_meervoudsvormen
79+
yield new Transformation(new Pattern('()ix$'), '\1ices');
80+
81+
yield new Transformation(new Pattern('()ex$'), '\1ices');
82+
83+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Stapelmeervoud
84+
yield new Transformation(new Pattern('^(ei|gemoed|goed|hoen|kind|lied|rad|rund)$'), '\1eren');
85+
86+
// http://nl.wikipedia.org/wiki/Nederlandse_grammatica
87+
yield new Transformation(new Pattern('()ij$'), '\1ijen');
88+
89+
yield new Transformation(new Pattern('()orie$'), '\1orieen'); // ën klemtoon
90+
91+
yield new Transformation(new Pattern('()io$'), '\1io\'s');
92+
93+
yield new Transformation(new Pattern('()(a|e|i|o|u|ij)$'), '\1\2s');
94+
95+
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');
96+
97+
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');
98+
99+
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');
100+
101+
yield new Transformation(new Pattern('()s$'), '\1zen');
102+
103+
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');
104+
}
105+
106+
/**
107+
* @return Substitution[]
108+
*/
109+
public static function getIrregular() : iterable
110+
{
111+
// http://nl.wikipedia.org/wiki/Klemtoon
112+
yield new Substitution(new Word('olie'), new Word('oliën'));
113+
114+
yield new Substitution(new Word('industrie'), new Word('industrieën'));
115+
116+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Klinkerverandering
117+
yield new Substitution(new Word('lid'), new Word('leden'));
118+
119+
yield new Substitution(new Word('smid'), new Word('smeden'));
120+
121+
yield new Substitution(new Word('schip'), new Word('schepen'));
122+
123+
yield new Substitution(new Word('stad'), new Word('steden'));
124+
125+
yield new Substitution(new Word('gelid'), new Word('gelederen'));
126+
127+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Stapelmeervoud
128+
yield new Substitution(new Word('gelid'), new Word('gelederen'));
129+
130+
yield new Substitution(new Word('kalf'), new Word('kalveren'));
131+
132+
yield new Substitution(new Word('lam'), new Word('lammeren'));
133+
134+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Onregelmatige_meervoudsvorming
135+
yield new Substitution(new Word('koe'), new Word('koeien'));
136+
137+
yield new Substitution(new Word('vlo'), new Word('vlooien'));
138+
139+
yield new Substitution(new Word('leerrede'), new Word('leerredenen'));
140+
141+
yield new Substitution(new Word('lende'), new Word('lendenen'));
142+
143+
yield new Substitution(new Word('epos'), new Word('epen'));
144+
145+
yield new Substitution(new Word('genius'), new Word('geniën'));
146+
147+
yield new Substitution(new Word('aanbod'), new Word('aanbiedingen'));
148+
149+
yield new Substitution(new Word('beleg'), new Word('belegeringen'));
150+
151+
yield new Substitution(new Word('dank'), new Word('dankbetuigingen'));
152+
153+
yield new Substitution(new Word('gedrag'), new Word('gedragingen'));
154+
155+
yield new Substitution(new Word('genot'), new Word('genietingen'));
156+
157+
yield new Substitution(new Word('lof'), new Word('lofbetuigingen'));
158+
159+
// http://nl.wikipedia.org/wiki/Meervoud_(Nederlands)#Latijnse_meervoudsvormen
160+
yield new Substitution(new Word('qaestrices'), new Word('quaestrix'));
161+
162+
yield new Substitution(new Word('matrices'), new Word('matrix'));
163+
}
164+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Inflector\Rules\Dutch;
6+
7+
use Doctrine\Inflector\GenericLanguageInflectorFactory;
8+
use Doctrine\Inflector\Rules\Ruleset;
9+
10+
final class InflectorFactory extends GenericLanguageInflectorFactory
11+
{
12+
protected function getSingularRuleset() : Ruleset
13+
{
14+
return Rules::getSingularRuleset();
15+
}
16+
17+
protected function getPluralRuleset() : Ruleset
18+
{
19+
return Rules::getPluralRuleset();
20+
}
21+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Inflector\Rules\Dutch;
6+
7+
use Doctrine\Inflector\Rules\Patterns;
8+
use Doctrine\Inflector\Rules\Ruleset;
9+
use Doctrine\Inflector\Rules\Substitutions;
10+
use Doctrine\Inflector\Rules\Transformations;
11+
12+
final class Rules
13+
{
14+
public static function getSingularRuleset() : Ruleset
15+
{
16+
return new Ruleset(
17+
new Transformations(...Inflectible::getSingular()),
18+
new Patterns(...Uninflected::getSingular()),
19+
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
20+
);
21+
}
22+
23+
public static function getPluralRuleset() : Ruleset
24+
{
25+
return new Ruleset(
26+
new Transformations(...Inflectible::getPlural()),
27+
new Patterns(...Uninflected::getPlural()),
28+
new Substitutions(...Inflectible::getIrregular())
29+
);
30+
}
31+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Inflector\Rules\Dutch;
6+
7+
use Doctrine\Inflector\Rules\Pattern;
8+
9+
final class Uninflected
10+
{
11+
/**
12+
* @return Pattern[]
13+
*/
14+
public static function getSingular() : iterable
15+
{
16+
yield from self::getDefault();
17+
18+
// http://nl.wikipedia.org/wiki/Plurale_tantum
19+
yield new Pattern('hersenen');
20+
yield new Pattern('ingewanden');
21+
yield new Pattern('mazelen');
22+
yield new Pattern('pokken');
23+
yield new Pattern('waterpokken');
24+
yield new Pattern('financiën');
25+
yield new Pattern('activa');
26+
yield new Pattern('passiva');
27+
yield new Pattern('onkosten');
28+
yield new Pattern('kosten');
29+
yield new Pattern('bescheiden');
30+
yield new Pattern('paperassen');
31+
yield new Pattern('notulen');
32+
yield new Pattern('Roma');
33+
yield new Pattern('Sinti');
34+
yield new Pattern('Inuit');
35+
yield new Pattern('taliban');
36+
yield new Pattern('illuminati');
37+
yield new Pattern('aanstalten');
38+
yield new Pattern('hurken');
39+
yield new Pattern('lurven');
40+
yield new Pattern('luren');
41+
}
42+
43+
/**
44+
* @return Pattern[]
45+
*/
46+
public static function getPlural() : iterable
47+
{
48+
yield from self::getDefault();
49+
50+
// http://nl.wikipedia.org/wiki/Singulare_tantum
51+
yield new Pattern('letterkunde');
52+
yield new Pattern('muziek');
53+
yield new Pattern('heelal');
54+
yield new Pattern('vastgoed');
55+
yield new Pattern('have');
56+
yield new Pattern('nageslacht');
57+
}
58+
59+
/**
60+
* @return Pattern[]
61+
*/
62+
private static function getDefault() : iterable
63+
{
64+
yield new Pattern('twitter');
65+
}
66+
}

tests/Doctrine/Tests/Inflector/InflectorFactoryTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Doctrine\Inflector\InflectorFactory;
88
use Doctrine\Inflector\Language;
9+
use Doctrine\Inflector\Rules\Dutch\InflectorFactory as DutchInflectorFactory;
910
use Doctrine\Inflector\Rules\English\InflectorFactory as EnglishInflectorFactory;
1011
use Doctrine\Inflector\Rules\French\InflectorFactory as FrenchInflectorFactory;
1112
use Doctrine\Inflector\Rules\NorwegianBokmal\InflectorFactory as NorwegianBokmalInflectorFactory;
@@ -33,6 +34,7 @@ public function testCreateForLanguageWithCustomLanguage(string $expectedClass, s
3334

3435
public static function provideLanguages() : Generator
3536
{
37+
yield 'Dutch' => [DutchInflectorFactory::class, Language::DUTCH];
3638
yield 'English' => [EnglishInflectorFactory::class, Language::ENGLISH];
3739
yield 'French' => [FrenchInflectorFactory::class, Language::FRENCH];
3840
yield 'Norwegian Bokmal' => [NorwegianBokmalInflectorFactory::class, Language::NORWEGIAN_BOKMAL];
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Tests\Inflector\Rules\Dutch;
6+
7+
use Doctrine\Inflector\Inflector;
8+
use Doctrine\Inflector\InflectorFactory;
9+
use Doctrine\Inflector\Language;
10+
use Doctrine\Tests\Inflector\Rules\LanguageFunctionalTest;
11+
12+
class DutchFunctionalTest extends LanguageFunctionalTest
13+
{
14+
/**
15+
* @return string[][]
16+
*/
17+
public function dataSampleWords() : array
18+
{
19+
return [
20+
['weerman', 'weermannen'],
21+
['ei', 'eieren'],
22+
['rij', 'rijen'],
23+
['mogelijkheid', 'mogelijkheden'],
24+
['adres', 'adressen'],
25+
['olie', 'oliën'],
26+
['industrie', 'industrieën'],
27+
['lid', 'leden'],
28+
['smid', 'smeden'],
29+
['schip', 'schepen'],
30+
['stad', 'steden'],
31+
['gelid', 'gelederen'],
32+
['gelid', 'gelederen'],
33+
['kalf', 'kalveren'],
34+
['lam', 'lammeren'],
35+
['koe', 'koeien'],
36+
['vlo', 'vlooien'],
37+
['leerrede', 'leerredenen'],
38+
['lende', 'lendenen'],
39+
['epos', 'epen'],
40+
['genius', 'geniën'],
41+
['aanbod', 'aanbiedingen'],
42+
['beleg', 'belegeringen'],
43+
['dank', 'dankbetuigingen'],
44+
['gedrag', 'gedragingen'],
45+
['genot', 'genietingen'],
46+
['lof', 'lofbetuigingen'],
47+
['qaestrices', 'quaestrix'],
48+
['matrices', 'matrix'],
49+
['twitter', 'twitter'],
50+
];
51+
}
52+
53+
protected function createInflector() : Inflector
54+
{
55+
return InflectorFactory::createForLanguage(Language::DUTCH)->build();
56+
}
57+
}

0 commit comments

Comments
 (0)