natural 6.10.2 → 6.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/.github/workflows/npm-publish.yml +4 -4
  3. package/lib/natural/brill_pos_tagger/lib/Brill_POS_Tagger.js +33 -31
  4. package/lib/natural/brill_pos_tagger/lib/Brill_POS_Tester.js +33 -35
  5. package/lib/natural/brill_pos_tagger/lib/Brill_POS_Trainer.js +326 -324
  6. package/lib/natural/brill_pos_tagger/lib/Corpus.js +140 -138
  7. package/lib/natural/brill_pos_tagger/lib/Lexicon.js +78 -76
  8. package/lib/natural/brill_pos_tagger/lib/Predicate.js +19 -17
  9. package/lib/natural/brill_pos_tagger/lib/RuleSet.js +58 -56
  10. package/lib/natural/brill_pos_tagger/lib/RuleTemplate.js +11 -9
  11. package/lib/natural/brill_pos_tagger/lib/Sentence.js +21 -20
  12. package/lib/natural/brill_pos_tagger/lib/TransformationRule.js +58 -58
  13. package/lib/natural/classifiers/bayes_classifier.js +24 -29
  14. package/lib/natural/classifiers/classifier.js +136 -121
  15. package/lib/natural/classifiers/logistic_regression_classifier.js +33 -37
  16. package/lib/natural/classifiers/maxent/Classifier.js +81 -79
  17. package/lib/natural/classifiers/maxent/Context.js +11 -9
  18. package/lib/natural/classifiers/maxent/Distribution.js +107 -105
  19. package/lib/natural/classifiers/maxent/Element.js +12 -10
  20. package/lib/natural/classifiers/maxent/Feature.js +56 -54
  21. package/lib/natural/classifiers/maxent/FeatureSet.js +40 -38
  22. package/lib/natural/classifiers/maxent/GISScaler.js +110 -109
  23. package/lib/natural/classifiers/maxent/POS/ME_Corpus.js +26 -31
  24. package/lib/natural/classifiers/maxent/POS/ME_Sentence.js +37 -42
  25. package/lib/natural/classifiers/maxent/POS/POS_Element.js +119 -124
  26. package/lib/natural/classifiers/maxent/Sample.js +96 -94
  27. package/lib/natural/classifiers/maxent/SimpleExample/SE_Element.js +14 -20
  28. package/lib/natural/inflectors/fr/count_inflector.js +1 -1
  29. package/lib/natural/inflectors/fr/noun_inflector.js +179 -196
  30. package/lib/natural/inflectors/ja/noun_inflector.js +67 -84
  31. package/lib/natural/inflectors/noun_inflector.js +124 -139
  32. package/lib/natural/inflectors/present_verb_inflector.js +34 -48
  33. package/lib/natural/inflectors/singular_plural_inflector.js +62 -61
  34. package/lib/natural/tfidf/tfidf.js +118 -114
  35. package/lib/natural/trie/trie.js +161 -159
  36. package/lib/natural/util/directed_edge.js +49 -0
  37. package/lib/natural/util/edge_weighted_digraph.js +54 -74
  38. package/lib/natural/util/index.js +1 -0
  39. package/lib/natural/util/longest_path_tree.js +54 -52
  40. package/lib/natural/util/shortest_path_tree.js +56 -54
  41. package/lib/natural/util/topological.js +17 -15
  42. package/package.json +1 -1
@@ -31,205 +31,188 @@
31
31
  */
32
32
 
33
33
  const SingularPluralInflector = require('../singular_plural_inflector')
34
- const util = require('util')
35
34
  const FormSet = require('../form_set')
36
35
 
37
- /*
38
- function attach () {
39
- const inflector = this
40
-
41
- String.prototype.singularizeNoun = function () {
42
- return inflector.singularize(this)
43
- }
44
-
45
- String.prototype.pluralizeNoun = function () {
46
- return inflector.pluralize(this)
47
- }
48
- }
49
- */
50
-
51
- /**
52
- * @constructor
53
- */
54
- const NounInflector = function () {
55
- // Ambiguous a.k.a. invariant.
56
- // \@todo Expand this list to be as comprehensive as possible.
57
- this.ambiguous = [
58
- // Nouns ending by -s
59
- 'à-peu-près', 'à-propos', 'abattis', 'abcès', 'abois', 'abribus', 'abus',
60
- 'accès', 'acquis', 'adénovirus', 'adonis', 'ados', 'agrès', 'aguets',
61
- 'ailleurs', 'ais', 'albatros', 'albinos', 'alias', 'aloès', 'amaryllis',
62
- 'amas', 'ampélopsis', 'ananas', 'anchois', 'angélus', 'anis', 'anticorps',
63
- 'antihéros', 'antirides', 'anus', 'appas', 'appentis', 'appui-bras',
64
- 'appuie-bras', 'arcanes', 'argus', 'arrérages', 'arrière-pays', 'as',
65
- 'ascaris', 'asparagus', 'atlas', 'atours', 'aurochs', 'autobus',
66
- 'autofocus', 'avant-bras', 'avant-corps', 'avant-propos', 'avers', 'avis',
67
- 'axis', 'barbouillis', 'bas', 'beaujolais', 'beaux-arts', 'biais',
68
- 'bibliobus', 'biceps', 'bicross', 'bien-fonds', 'bloc-notes', 'blockhaus',
69
- 'blocus', 'blues', 'bois', 'bonus', 'bout-dehors', 'bouts-rimés',
70
- 'branle-bas', 'bras', 'brebis', 'bris', 'brise-lames', 'brise-mottes',
71
- 'brûlis', 'buis', 'burnous', 'bus', 'business', 'cabas', 'cacatoès',
72
- 'cacatois', 'cactus', 'cadenas', 'cafouillis', 'caillebotis', 'calvados',
73
- 'cambouis', 'campus', 'canevas', 'cannabis', 'carquois', 'cas',
74
- 'casse-noisettes', 'casse-pieds', 'cassis', 'caucus', 'cens', 'cervelas',
75
- 'chablis', 'chamois', 'chaos', 'chas', 'chasselas', 'châssis',
76
- 'chatouillis', 'chauffe-assiettes', 'chauve-souris', 'chorus', 'choucas',
77
- 'circoncis', 'cirrus', 'clafoutis', 'clapotis', 'cliquetis', 'clos',
78
- 'cochylis', 'colis', 'coloris', 'commis', 'compas', 'compromis',
79
- 'compte-chèques', 'compte-gouttes', 'compte-tours', 'concours', 'confins',
80
- 'congrès', 'consensus', 'contrepoids', 'contresens', 'contretemps',
81
- 'corn flakes', 'corps', 'corps-à-corps', 'corpus', 'cosinus', 'cosmos',
82
- 'coulis', 'coupe-ongles', 'cours', 'court-jus', 'couscous', 'coutelas',
83
- 'crocus', 'croquis', 'cross', 'cubitus', 'cumulus', 'cure-dents',
84
- 'cure-ongles', 'cure-pipes', 'cursus', 'cyclo-cross', 'cyprès', 'dais',
85
- 'damas', 'débarras', 'débours', 'débris', 'décès', 'dedans', 'dehors',
86
- 'delirium tremens', 'demi-gros', 'dépens', 'dessous', 'dessus', 'détritus',
87
- 'deux-mâts', 'deux-pièces', 'deux-points', 'deux-roues', 'deux-temps',
88
- 'dévers', 'devis', 'diplodocus', 'discours', 'dos', 'ébats', 'éboulis',
89
- 'échalas', 'edelweiss', 'élaeis', 'éleis', 'éléphantiasis', 'embarras',
90
- 'empois', 'en-cas', 'encens', 'enclos', 'endos', 'engrais', 'entrelacs',
91
- 'entremets', 'envers', 'épluche-légumes', 'ers', 'espace-temps',
92
- 'essuie-mains', 'eucalyptus', 'ex-libris', 'excès', 'express', 'extrados',
93
- 'faciès', 'fait-divers', 'fatras', 'faux-sens', 'favoris', 'ficus',
94
- 'fier-à-bras', 'finnois', 'florès', 'focus', 'fœtus', 'fois', 'forceps',
95
- 'fouillis', 'fracas', 'frais', 'français', 'franglais', 'frimas',
96
- 'friselis', 'frisottis', 'froncis', 'frottis', 'fucus', 'gâchis', 'galetas',
97
- 'galimatias', 'garde-à-vous', 'garde-corps', 'gargouillis', 'gars',
98
- 'gâte-bois', 'gazouillis', 'génois', 'gibus', 'glacis', 'glas', 'gneiss',
99
- 'gobe-mouches', 'grès', 'gribouillis', 'guet-apens', 'habeas corpus',
100
- 'hachis', 'haras', 'hardes', 'harnais', 'haut-le-corps', 'hautbois',
101
- 'herbe-aux-chats', 'héros', 'herpès', 'hiatus', 'hibiscus', 'hors-concours',
102
- 'hors-pistes', 'hourdis', 'huis-clos', 'humérus', 'humus', 'ibis', 'iléus',
103
- 'indique-fuites', 'infarctus', 'inlandsis', 'insuccès', 'intercours',
104
- 'intrados', 'intrus', 'iris', 'isatis', 'jais', 'jars', 'jeans',
105
- 'jeuconcours', 'judas', 'juliénas', 'jus', 'justaucorps', 'kakatoès',
106
- 'kermès', 'kriss', 'lacis', 'laïus', 'lambris', 'lapis', 'laps', 'lapsus',
107
- 'laquais', 'las', 'lattis', 'lave-mains', 'lavis', 'lèche-bottes',
108
- 'lèche-vitrines', 'legs', 'lias', 'liégeois', 'lilas', 'lis', 'lœss',
109
- 'logis', 'loris', 'lotus', 'louis', 'lupus', 'lys', 'mâchicoulis', 'madras',
110
- 'maïs', 'malappris', 'malus', 'mânes', 'maquis', 'marais', 'maroilles',
111
- 'marquis', 'mas', 'mass-médias', 'matelas', 'matois', 'médius', 'mépris',
112
- 'mérinos', 'mess', 'mets', 'mi-bas', 'micro-ondes', 'mille-pattes',
113
- 'millepertuis', 'minibus', 'minois', 'minus', 'mirabilis', 'mois',
114
- 'monocorps', 'monte-plats', 'mors', 'motocross', 'mots-croisés', 'motus',
115
- 'mouchetis', 'mucus', 'myosotis', 'nævus', 'négus', 'niais',
116
- 'nimbo-stratus', 'nimbus', 'norois', 'nounours', 'nu-pieds', 'oasis',
117
- 'obus', 'olibrius', 'omnibus', 'opus', 'os', 'ours', 'ouvre-boîtes',
118
- 'ouvre-bouteilles', 'palais', 'palis', 'palmarès', 'palus', 'panais',
119
- 'panaris', 'pancréas', 'papyrus', 'par-dehors', 'paradis', 'parcours',
120
- 'pardessus', 'pare-balles', 'pare-chocs', 'parvis', 'pas', 'passe-temps',
121
- 'pataquès', 'pathos', 'patois', 'pavois', 'pays', 'permis',
122
- 'petit-bourgeois', 'petit-gris', 'petit-pois', 'phallus', 'phimosis',
123
- 'pickles', 'pilotis', 'pique-fleurs', 'pis', 'pithiviers', 'pityriasis',
124
- 'plateau-repas', 'plâtras', 'plein-temps', 'plexiglas', 'plexus', 'plus',
125
- 'poids', 'pois', 'pont-levis', 'porte-avions', 'porte-bagages',
126
- 'porte-billets', 'porte-bouteilles', 'porte-clés', 'porte-hélicoptères',
127
- 'porte-jarretelles', 'porte-revues', 'pouls', 'préavis', 'presse-fruits',
128
- 'presse-papiers', 'princeps', 'printemps', 'procès', 'processus', 'progrès',
129
- 'propos', 'prospectus', 'protège-dents', 'psoriasis', 'pubis', 'puits',
130
- 'pus', 'putois', 'quatre-épices', 'quatre-feuilles', 'quatre-heures',
131
- 'quatre-mâts', 'quatre-quarts', 'quatre-temps', 'quitus', 'rabais',
132
- 'rachis', 'radis', 'radius', 'raïs', 'ramassis', 'rébus', 'reclus',
133
- 'recours', 'refus', 'relais', 'remords', 'remous', 'remue-méninges',
134
- 'rendez-vous', 'repas', 'répons', 'repos', 'repris', 'reps', 'rétrovirus',
135
- 'revers', 'rhinocéros', 'rictus', 'rince-doigts', 'ris', 'rollmops',
136
- 'rosé-des-prés', 'roulis', 'rubis', 'salmigondis', 'salsifis', 'sans-logis',
137
- 'sas', 'sassafras', 'sauternes', 'schnaps', 'schuss', 'secours', 'semis',
138
- 'sens', 'serre-fils', 'serre-livres', 'sévices', 'sinus', 'skunks',
139
- 'souris', 'sournois', 'sous-bois', 'stradivarius', 'stras', 'strass',
140
- 'strato-cumulus', 'stratus', 'stress', 'succès', 'surdos', 'surplus',
141
- 'surpoids', 'sursis', 'suspens', 'synopsis', 'syphilis', 'taffetas',
142
- 'taillis', 'talus', 'tamaris', 'tamis', 'tapis', 'tas', 'taudis', 'temps',
143
- 'tennis', 'terminus', 'terre-neuvas', 'tétanos', 'tétras', 'thalamus',
144
- 'thermos', 'thesaurus', 'thésaurus', 'thymus', 'tire-fesses', 'tonus',
145
- 'torchis', 'torticolis', 'tournedos', 'tournevis', 'tournis', 'tracas',
146
- 'traîne-savates', 'travers', 'tréfonds', 'treillis', 'trépas', 'trias',
147
- 'triceps', 'trichomonas', 'trois-étoiles', 'trois-mâts', 'trois-quarts',
148
- 'trolleybus', 'tumulus', 'typhus', 'univers', 'us', 'utérus', 'vasistas',
149
- 'vélocross', 'velours', 'verglas', 'verjus', 'vernis', 'vers',
150
- 'vert-de-gris', 'vide-ordures', 'vide-poches', 'villageois', 'virus',
151
- 'vis-à-vis', 'volubilis', 'vulgum pecus', 'waters', 'williams', 'xérès',
152
-
153
- // Nouns ending by -x
154
- 'abat-voix', 'afflux', 'alpax', 'anthrax', 'apex', 'aptéryx',
155
- 'archéoptéryx', 'arrière-faix', 'bombyx', 'borax', 'bordeaux', 'bouseux',
156
- 'box', 'carex', 'casse-noix', 'cedex', 'céphalothorax', 'cérambyx', 'chaux',
157
- 'choix', 'coccyx', 'codex', 'contumax', 'coqueleux', 'cortex', 'courroux',
158
- 'croix', 'crucifix', 'culex', 'demodex', 'duplex', 'entre-deux', 'époux',
159
- 'équivaux', 'eux', 'ex', 'faix', 'faucheux', 'faux', 'fax', 'ferreux',
160
- 'flux', 'fox', 'freux', 'furax', 'hapax', 'harengueux', 'hélix',
161
- 'horse-pox', 'houx', 'index', 'influx', 'inox', 'juke-box', 'kleenex',
162
- 'lagothrix', 'larynx', 'lastex', 'latex', 'lux', 'lynx', 'macareux', 'max',
163
- 'mésothorax', 'mi-voix', 'mirepoix', 'motteux', 'multiplex', 'murex',
164
- 'narthex', 'noix', 'onyx', 'opopanax', 'oropharynx', 'paix', 'panax',
165
- 'perdrix', 'pharynx', 'phénix', 'phlox', 'phoenix', 'pneumothorax', 'poix',
166
- 'portefaix', 'pousse-cailloux', 'preux', 'prix', 'prothorax', 'pucheux',
167
- 'pyrex', 'pyroligneux', 'quadruplex', 'queux', 'redoux', 'reflex', 'reflux',
168
- 'relax', 'rhinopharynx', 'rose-croix', 'rouvieux', 'roux', 'rumex',
169
- 'saindoux', 'sardonyx', 'scolex', 'sèche-cheveux', 'silex', 'simplex',
170
- 'sioux', 'sirex', 'smilax', 'solex', 'songe-creux', 'spalax', 'sphex',
171
- 'sphinx', 'storax', 'strix', 'styrax', 'surfaix', 'surtaux', 'syrinx',
172
- 'tamarix', 'taux', 'télex', 'thorax', 'tord-boyaux', 'toux', 'trionyx',
173
- 'tripoux', 'tubifex', 'vertex', 'vidéotex', 'vielleux', 'vieux',
174
- 'violoneux', 'voix', 'volvox', 'vortex',
175
-
176
- // Nouns ending by -z
177
- 'allume-gaz', 'assez', 'biogaz', 'cache-nez', 'camping-gaz', 'chez',
178
- 'chintz', 'ersatz', 'fez', 'free-jazz', 'fritz', 'gaz', 'gin-fizz', 'hertz',
179
- 'jazz', 'jerez', 'kibboutz', 'kilohertz', 'kolkhoz', 'kronprinz', 'lapiaz',
180
- 'lez', 'mégahertz', 'merguez', 'nez', 'pince-nez', 'quartz', 'quiz', 'ranz',
181
- 'raz', 'recez', 'rémiz', 'rez', 'riz', 'ruolz', 'seltz', 'serre-nez'
182
- ]
183
-
184
- this.customPluralForms = []
185
- this.customSingularForms = []
186
- this.singularForms = new FormSet()
187
- this.pluralForms = new FormSet()
188
-
189
- // this.attach = attach
190
-
191
- this.addIrregular('ail', 'aulx')
192
- this.addIrregular('bétail', 'bestiaux')
193
- this.addIrregular('bonhomme', 'bonshommes')
194
- this.addIrregular('ciel', 'cieux')
195
- this.addIrregular('monsieur', 'messieurs')
196
- this.addIrregular('mafioso', 'mafiosi')
197
- this.addIrregular('œil', 'yeux')
198
- this.addIrregular('putto', 'putti')
199
- this.addIrregular('targui', 'touareg') // touareg -> touaregs is also OK.
200
-
201
- // Pluralize
202
- this.pluralForms.regularForms.push([/^(av|b|c|carnav|cérémoni|chac|corr|emment|emmenth|festiv|fut|gavi|gra|narv|p|récit|rég|rit|rorqu|st)al$/i, '$1als'])
203
- this.pluralForms.regularForms.push([/^(aspir|b|cor|ém|ferm|gemm|soupir|trav|vant|vent|vitr)ail$/i, '$1aux'])
204
- this.pluralForms.regularForms.push([/^(bij|caill|ch|gen|hib|jouj|p|rip|chouch)ou$/i, '$1oux'])
205
- this.pluralForms.regularForms.push([/^(gr|berimb|don|karb|land|pil|rest|sarr|un)au$/i, '$1aus'])
206
- this.pluralForms.regularForms.push([/^(bl|ém|enf|pn)eu$/i, '$1eus'])
207
- this.pluralForms.regularForms.push([/(au|eau|eu|œu)$/i, '$1x'])
208
- this.pluralForms.regularForms.push([/al$/i, 'aux'])
209
- this.pluralForms.regularForms.push([/(s|x)$/i, '$1'])
210
- this.pluralForms.regularForms.push([/(.*)$/i, '$1s'])
211
-
212
- // Singularize
213
- this.singularForms.regularForms.push([/^(aspir|b|cor|ém|ferm|gemm|soupir|trav|vant|vent|vitr)aux$/i, '$1ail'])
214
- this.singularForms.regularForms.push([/^(aloy|b|bouc|boy|burg|conoy|coy|cr|esquim|ét|fabli|flé|flûti|glu|gr|gru|hoy|joy|kérab|matéri|nobli|noy|pré|sen|sén|t|touch|tuss|tuy|v|ypré)aux$/i, '$1au'])
215
- this.singularForms.regularForms.push([/^(bij|caill|ch|gen|hib|jouj|p|rip|chouch)oux$/i, '$1ou'])
216
- this.singularForms.regularForms.push([/^(bis)?aïeux$/i, '$1aïeul'])
217
- this.singularForms.regularForms.push([/^apparaux$/i, 'appareil']) // One way transform, don't put on irregular list.
218
- this.singularForms.regularForms.push([/^ciels$/i, 'ciel'])
219
- this.singularForms.regularForms.push([/^œils$/i, 'œil'])
220
- this.singularForms.regularForms.push([/(eau|eu|œu)x$/i, '$1'])
221
- this.singularForms.regularForms.push([/aux$/i, 'al'])
222
- this.singularForms.regularForms.push([/(.*)s$/i, '$1'])
223
-
224
- this.pluralize = function (token) {
225
- return this.ize(token, this.pluralForms, this.customPluralForms)
226
- }
227
-
228
- this.singularize = function (token) {
229
- return this.ize(token, this.singularForms, this.customSingularForms)
36
+ class NounInflector extends SingularPluralInflector {
37
+ constructor () {
38
+ super()
39
+ // Ambiguous a.k.a. invariant.
40
+ // \@todo Expand this list to be as comprehensive as possible.
41
+ this.ambiguous = [
42
+ // Nouns ending by -s
43
+ 'à-peu-près', 'à-propos', 'abattis', 'abcès', 'abois', 'abribus', 'abus',
44
+ 'accès', 'acquis', 'adénovirus', 'adonis', 'ados', 'agrès', 'aguets',
45
+ 'ailleurs', 'ais', 'albatros', 'albinos', 'alias', 'aloès', 'amaryllis',
46
+ 'amas', 'ampélopsis', 'ananas', 'anchois', 'angélus', 'anis', 'anticorps',
47
+ 'antihéros', 'antirides', 'anus', 'appas', 'appentis', 'appui-bras',
48
+ 'appuie-bras', 'arcanes', 'argus', 'arrérages', 'arrière-pays', 'as',
49
+ 'ascaris', 'asparagus', 'atlas', 'atours', 'aurochs', 'autobus',
50
+ 'autofocus', 'avant-bras', 'avant-corps', 'avant-propos', 'avers', 'avis',
51
+ 'axis', 'barbouillis', 'bas', 'beaujolais', 'beaux-arts', 'biais',
52
+ 'bibliobus', 'biceps', 'bicross', 'bien-fonds', 'bloc-notes', 'blockhaus',
53
+ 'blocus', 'blues', 'bois', 'bonus', 'bout-dehors', 'bouts-rimés',
54
+ 'branle-bas', 'bras', 'brebis', 'bris', 'brise-lames', 'brise-mottes',
55
+ 'brûlis', 'buis', 'burnous', 'bus', 'business', 'cabas', 'cacatoès',
56
+ 'cacatois', 'cactus', 'cadenas', 'cafouillis', 'caillebotis', 'calvados',
57
+ 'cambouis', 'campus', 'canevas', 'cannabis', 'carquois', 'cas',
58
+ 'casse-noisettes', 'casse-pieds', 'cassis', 'caucus', 'cens', 'cervelas',
59
+ 'chablis', 'chamois', 'chaos', 'chas', 'chasselas', 'châssis',
60
+ 'chatouillis', 'chauffe-assiettes', 'chauve-souris', 'chorus', 'choucas',
61
+ 'circoncis', 'cirrus', 'clafoutis', 'clapotis', 'cliquetis', 'clos',
62
+ 'cochylis', 'colis', 'coloris', 'commis', 'compas', 'compromis',
63
+ 'compte-chèques', 'compte-gouttes', 'compte-tours', 'concours', 'confins',
64
+ 'congrès', 'consensus', 'contrepoids', 'contresens', 'contretemps',
65
+ 'corn flakes', 'corps', 'corps-à-corps', 'corpus', 'cosinus', 'cosmos',
66
+ 'coulis', 'coupe-ongles', 'cours', 'court-jus', 'couscous', 'coutelas',
67
+ 'crocus', 'croquis', 'cross', 'cubitus', 'cumulus', 'cure-dents',
68
+ 'cure-ongles', 'cure-pipes', 'cursus', 'cyclo-cross', 'cyprès', 'dais',
69
+ 'damas', 'débarras', 'débours', 'débris', 'décès', 'dedans', 'dehors',
70
+ 'delirium tremens', 'demi-gros', 'dépens', 'dessous', 'dessus', 'détritus',
71
+ 'deux-mâts', 'deux-pièces', 'deux-points', 'deux-roues', 'deux-temps',
72
+ 'dévers', 'devis', 'diplodocus', 'discours', 'dos', 'ébats', 'éboulis',
73
+ 'échalas', 'edelweiss', 'élaeis', 'éleis', 'éléphantiasis', 'embarras',
74
+ 'empois', 'en-cas', 'encens', 'enclos', 'endos', 'engrais', 'entrelacs',
75
+ 'entremets', 'envers', 'épluche-légumes', 'ers', 'espace-temps',
76
+ 'essuie-mains', 'eucalyptus', 'ex-libris', 'excès', 'express', 'extrados',
77
+ 'faciès', 'fait-divers', 'fatras', 'faux-sens', 'favoris', 'ficus',
78
+ 'fier-à-bras', 'finnois', 'florès', 'focus', 'fœtus', 'fois', 'forceps',
79
+ 'fouillis', 'fracas', 'frais', 'français', 'franglais', 'frimas',
80
+ 'friselis', 'frisottis', 'froncis', 'frottis', 'fucus', 'gâchis', 'galetas',
81
+ 'galimatias', 'garde-à-vous', 'garde-corps', 'gargouillis', 'gars',
82
+ 'gâte-bois', 'gazouillis', 'génois', 'gibus', 'glacis', 'glas', 'gneiss',
83
+ 'gobe-mouches', 'grès', 'gribouillis', 'guet-apens', 'habeas corpus',
84
+ 'hachis', 'haras', 'hardes', 'harnais', 'haut-le-corps', 'hautbois',
85
+ 'herbe-aux-chats', 'héros', 'herpès', 'hiatus', 'hibiscus', 'hors-concours',
86
+ 'hors-pistes', 'hourdis', 'huis-clos', 'humérus', 'humus', 'ibis', 'iléus',
87
+ 'indique-fuites', 'infarctus', 'inlandsis', 'insuccès', 'intercours',
88
+ 'intrados', 'intrus', 'iris', 'isatis', 'jais', 'jars', 'jeans',
89
+ 'jeuconcours', 'judas', 'juliénas', 'jus', 'justaucorps', 'kakatoès',
90
+ 'kermès', 'kriss', 'lacis', 'laïus', 'lambris', 'lapis', 'laps', 'lapsus',
91
+ 'laquais', 'las', 'lattis', 'lave-mains', 'lavis', 'lèche-bottes',
92
+ 'lèche-vitrines', 'legs', 'lias', 'liégeois', 'lilas', 'lis', 'lœss',
93
+ 'logis', 'loris', 'lotus', 'louis', 'lupus', 'lys', 'mâchicoulis', 'madras',
94
+ 'maïs', 'malappris', 'malus', 'mânes', 'maquis', 'marais', 'maroilles',
95
+ 'marquis', 'mas', 'mass-médias', 'matelas', 'matois', 'médius', 'mépris',
96
+ 'mérinos', 'mess', 'mets', 'mi-bas', 'micro-ondes', 'mille-pattes',
97
+ 'millepertuis', 'minibus', 'minois', 'minus', 'mirabilis', 'mois',
98
+ 'monocorps', 'monte-plats', 'mors', 'motocross', 'mots-croisés', 'motus',
99
+ 'mouchetis', 'mucus', 'myosotis', 'nævus', 'négus', 'niais',
100
+ 'nimbo-stratus', 'nimbus', 'norois', 'nounours', 'nu-pieds', 'oasis',
101
+ 'obus', 'olibrius', 'omnibus', 'opus', 'os', 'ours', 'ouvre-boîtes',
102
+ 'ouvre-bouteilles', 'palais', 'palis', 'palmarès', 'palus', 'panais',
103
+ 'panaris', 'pancréas', 'papyrus', 'par-dehors', 'paradis', 'parcours',
104
+ 'pardessus', 'pare-balles', 'pare-chocs', 'parvis', 'pas', 'passe-temps',
105
+ 'pataquès', 'pathos', 'patois', 'pavois', 'pays', 'permis',
106
+ 'petit-bourgeois', 'petit-gris', 'petit-pois', 'phallus', 'phimosis',
107
+ 'pickles', 'pilotis', 'pique-fleurs', 'pis', 'pithiviers', 'pityriasis',
108
+ 'plateau-repas', 'plâtras', 'plein-temps', 'plexiglas', 'plexus', 'plus',
109
+ 'poids', 'pois', 'pont-levis', 'porte-avions', 'porte-bagages',
110
+ 'porte-billets', 'porte-bouteilles', 'porte-clés', 'porte-hélicoptères',
111
+ 'porte-jarretelles', 'porte-revues', 'pouls', 'préavis', 'presse-fruits',
112
+ 'presse-papiers', 'princeps', 'printemps', 'procès', 'processus', 'progrès',
113
+ 'propos', 'prospectus', 'protège-dents', 'psoriasis', 'pubis', 'puits',
114
+ 'pus', 'putois', 'quatre-épices', 'quatre-feuilles', 'quatre-heures',
115
+ 'quatre-mâts', 'quatre-quarts', 'quatre-temps', 'quitus', 'rabais',
116
+ 'rachis', 'radis', 'radius', 'raïs', 'ramassis', 'rébus', 'reclus',
117
+ 'recours', 'refus', 'relais', 'remords', 'remous', 'remue-méninges',
118
+ 'rendez-vous', 'repas', 'répons', 'repos', 'repris', 'reps', 'rétrovirus',
119
+ 'revers', 'rhinocéros', 'rictus', 'rince-doigts', 'ris', 'rollmops',
120
+ 'rosé-des-prés', 'roulis', 'rubis', 'salmigondis', 'salsifis', 'sans-logis',
121
+ 'sas', 'sassafras', 'sauternes', 'schnaps', 'schuss', 'secours', 'semis',
122
+ 'sens', 'serre-fils', 'serre-livres', 'sévices', 'sinus', 'skunks',
123
+ 'souris', 'sournois', 'sous-bois', 'stradivarius', 'stras', 'strass',
124
+ 'strato-cumulus', 'stratus', 'stress', 'succès', 'surdos', 'surplus',
125
+ 'surpoids', 'sursis', 'suspens', 'synopsis', 'syphilis', 'taffetas',
126
+ 'taillis', 'talus', 'tamaris', 'tamis', 'tapis', 'tas', 'taudis', 'temps',
127
+ 'tennis', 'terminus', 'terre-neuvas', 'tétanos', 'tétras', 'thalamus',
128
+ 'thermos', 'thesaurus', 'thésaurus', 'thymus', 'tire-fesses', 'tonus',
129
+ 'torchis', 'torticolis', 'tournedos', 'tournevis', 'tournis', 'tracas',
130
+ 'traîne-savates', 'travers', 'tréfonds', 'treillis', 'trépas', 'trias',
131
+ 'triceps', 'trichomonas', 'trois-étoiles', 'trois-mâts', 'trois-quarts',
132
+ 'trolleybus', 'tumulus', 'typhus', 'univers', 'us', 'utérus', 'vasistas',
133
+ 'vélocross', 'velours', 'verglas', 'verjus', 'vernis', 'vers',
134
+ 'vert-de-gris', 'vide-ordures', 'vide-poches', 'villageois', 'virus',
135
+ 'vis-à-vis', 'volubilis', 'vulgum pecus', 'waters', 'williams', 'xérès',
136
+
137
+ // Nouns ending by -x
138
+ 'abat-voix', 'afflux', 'alpax', 'anthrax', 'apex', 'aptéryx',
139
+ 'archéoptéryx', 'arrière-faix', 'bombyx', 'borax', 'bordeaux', 'bouseux',
140
+ 'box', 'carex', 'casse-noix', 'cedex', 'céphalothorax', 'cérambyx', 'chaux',
141
+ 'choix', 'coccyx', 'codex', 'contumax', 'coqueleux', 'cortex', 'courroux',
142
+ 'croix', 'crucifix', 'culex', 'demodex', 'duplex', 'entre-deux', 'époux',
143
+ 'équivaux', 'eux', 'ex', 'faix', 'faucheux', 'faux', 'fax', 'ferreux',
144
+ 'flux', 'fox', 'freux', 'furax', 'hapax', 'harengueux', 'hélix',
145
+ 'horse-pox', 'houx', 'index', 'influx', 'inox', 'juke-box', 'kleenex',
146
+ 'lagothrix', 'larynx', 'lastex', 'latex', 'lux', 'lynx', 'macareux', 'max',
147
+ 'mésothorax', 'mi-voix', 'mirepoix', 'motteux', 'multiplex', 'murex',
148
+ 'narthex', 'noix', 'onyx', 'opopanax', 'oropharynx', 'paix', 'panax',
149
+ 'perdrix', 'pharynx', 'phénix', 'phlox', 'phoenix', 'pneumothorax', 'poix',
150
+ 'portefaix', 'pousse-cailloux', 'preux', 'prix', 'prothorax', 'pucheux',
151
+ 'pyrex', 'pyroligneux', 'quadruplex', 'queux', 'redoux', 'reflex', 'reflux',
152
+ 'relax', 'rhinopharynx', 'rose-croix', 'rouvieux', 'roux', 'rumex',
153
+ 'saindoux', 'sardonyx', 'scolex', 'sèche-cheveux', 'silex', 'simplex',
154
+ 'sioux', 'sirex', 'smilax', 'solex', 'songe-creux', 'spalax', 'sphex',
155
+ 'sphinx', 'storax', 'strix', 'styrax', 'surfaix', 'surtaux', 'syrinx',
156
+ 'tamarix', 'taux', 'télex', 'thorax', 'tord-boyaux', 'toux', 'trionyx',
157
+ 'tripoux', 'tubifex', 'vertex', 'vidéotex', 'vielleux', 'vieux',
158
+ 'violoneux', 'voix', 'volvox', 'vortex',
159
+
160
+ // Nouns ending by -z
161
+ 'allume-gaz', 'assez', 'biogaz', 'cache-nez', 'camping-gaz', 'chez',
162
+ 'chintz', 'ersatz', 'fez', 'free-jazz', 'fritz', 'gaz', 'gin-fizz', 'hertz',
163
+ 'jazz', 'jerez', 'kibboutz', 'kilohertz', 'kolkhoz', 'kronprinz', 'lapiaz',
164
+ 'lez', 'mégahertz', 'merguez', 'nez', 'pince-nez', 'quartz', 'quiz', 'ranz',
165
+ 'raz', 'recez', 'rémiz', 'rez', 'riz', 'ruolz', 'seltz', 'serre-nez'
166
+ ]
167
+
168
+ this.customPluralForms = []
169
+ this.customSingularForms = []
170
+ this.singularForms = new FormSet()
171
+ this.pluralForms = new FormSet()
172
+
173
+ // this.attach = attach
174
+
175
+ this.addIrregular('ail', 'aulx')
176
+ this.addIrregular('bétail', 'bestiaux')
177
+ this.addIrregular('bonhomme', 'bonshommes')
178
+ this.addIrregular('ciel', 'cieux')
179
+ this.addIrregular('monsieur', 'messieurs')
180
+ this.addIrregular('mafioso', 'mafiosi')
181
+ this.addIrregular('œil', 'yeux')
182
+ this.addIrregular('putto', 'putti')
183
+ this.addIrregular('targui', 'touareg') // touareg -> touaregs is also OK.
184
+
185
+ // Pluralize
186
+ this.pluralForms.regularForms.push([/^(av|b|c|carnav|cérémoni|chac|corr|emment|emmenth|festiv|fut|gavi|gra|narv|p|récit|rég|rit|rorqu|st)al$/i, '$1als'])
187
+ this.pluralForms.regularForms.push([/^(aspir|b|cor|ém|ferm|gemm|soupir|trav|vant|vent|vitr)ail$/i, '$1aux'])
188
+ this.pluralForms.regularForms.push([/^(bij|caill|ch|gen|hib|jouj|p|rip|chouch)ou$/i, '$1oux'])
189
+ this.pluralForms.regularForms.push([/^(gr|berimb|don|karb|land|pil|rest|sarr|un)au$/i, '$1aus'])
190
+ this.pluralForms.regularForms.push([/^(bl|ém|enf|pn)eu$/i, '$1eus'])
191
+ this.pluralForms.regularForms.push([/(au|eau|eu|œu)$/i, '$1x'])
192
+ this.pluralForms.regularForms.push([/al$/i, 'aux'])
193
+ this.pluralForms.regularForms.push([/(s|x)$/i, '$1'])
194
+ this.pluralForms.regularForms.push([/(.*)$/i, '$1s'])
195
+
196
+ // Singularize
197
+ this.singularForms.regularForms.push([/^(aspir|b|cor|ém|ferm|gemm|soupir|trav|vant|vent|vitr)aux$/i, '$1ail'])
198
+ this.singularForms.regularForms.push([/^(aloy|b|bouc|boy|burg|conoy|coy|cr|esquim|ét|fabli|flé|flûti|glu|gr|gru|hoy|joy|kérab|matéri|nobli|noy|pré|sen|sén|t|touch|tuss|tuy|v|ypré)aux$/i, '$1au'])
199
+ this.singularForms.regularForms.push([/^(bij|caill|ch|gen|hib|jouj|p|rip|chouch)oux$/i, '$1ou'])
200
+ this.singularForms.regularForms.push([/^(bis)?aïeux$/i, '$1aïeul'])
201
+ this.singularForms.regularForms.push([/^apparaux$/i, 'appareil']) // One way transform, don't put on irregular list.
202
+ this.singularForms.regularForms.push([/^ciels$/i, 'ciel'])
203
+ this.singularForms.regularForms.push([/^œils$/i, 'œil'])
204
+ this.singularForms.regularForms.push([/(eau|eu|œu)x$/i, '$1'])
205
+ this.singularForms.regularForms.push([/aux$/i, 'al'])
206
+ this.singularForms.regularForms.push([/(.*)s$/i, '$1'])
207
+
208
+ this.pluralize = function (token) {
209
+ return this.ize(token, this.pluralForms, this.customPluralForms)
210
+ }
211
+
212
+ this.singularize = function (token) {
213
+ return this.ize(token, this.singularForms, this.customSingularForms)
214
+ }
230
215
  }
231
216
  }
232
217
 
233
- util.inherits(NounInflector, SingularPluralInflector)
234
-
235
218
  module.exports = NounInflector
@@ -40,93 +40,76 @@
40
40
  */
41
41
 
42
42
  const SingularPluralInflector = require('../singular_plural_inflector')
43
- const util = require('util')
44
43
  const FormSet = require('../form_set')
45
44
 
46
- /*
47
- function attach () {
48
- const inflector = this
49
-
50
- String.prototype.singularizeNoun = function () {
51
- return inflector.singularize(this)
52
- }
53
-
54
- String.prototype.pluralizeNoun = function () {
55
- return inflector.pluralize(this)
45
+ class NounInflector extends SingularPluralInflector {
46
+ constructor () {
47
+ super()
48
+ // Ambiguous a.k.a. invariant.
49
+ this.ambiguous = [
50
+ 'ともだち', '友だち', '友達', '遊び友達', '飲み友達', '酒飲み友達', '茶飲み友達',
51
+ '学校友達', '女友達', '男友達', '幼友達'
52
+ ]
53
+
54
+ this.customPluralForms = []
55
+ this.customSingularForms = []
56
+ this.singularForms = new FormSet()
57
+ this.pluralForms = new FormSet()
58
+
59
+ // this.attach = attach
60
+
61
+ this.addIrregular('神', '神神')
62
+ this.addIrregular('人', '人人')
63
+ this.addIrregular('年', '年年')
64
+ this.addIrregular('月', '月月')
65
+ this.addIrregular('日', '日日')
66
+ this.addIrregular('星', '星星')
67
+ this.addIrregular('島', '島島')
68
+ this.addIrregular('我', '我我')
69
+ this.addIrregular('山', '山山')
70
+ this.addIrregular('国', '国国')
71
+ this.addIrregular('所', '所所')
72
+ this.addIrregular('隅', '隅隅')
73
+
74
+ /**
75
+ * Notes:
76
+ * -たち exceptions: いたち, おいたち, ついたち, かたち, かおかたち, なりかたち, いでたち, はたち, からたち, なりたち
77
+ * -達 exceptions: 伊達, 男伊達, 栄達, 上意下達, 熟達, 上達, 下意上達, 先達, 送達, 速達, 即日速達, 書留速達, 調達, 通達, 伝達, 到達, 配達, 牛乳配達, 新聞配達, 無料配達, 四通八達, 発達, 未発達, 御用達, 宮内庁御用達, 練達, 闊達
78
+ * -等 exceptions: 一等, 下等, 何等, 均等, 勲等, 高等, 三等, 初等, 上等, 親等, 二親等, 数等, 対等, 中等, 同等, 特等, 二等, 品等, 不等, 平等, 悪平等, 男女平等, 不平等, 優等, 劣等
79
+ */
80
+
81
+ // Pluralize
82
+ this.pluralForms.regularForms.push([/^(.+)$/i, '$1たち'])
83
+
84
+ // Singularize
85
+ this.singularForms.regularForms.push([/^(.+)たち$/i, function (a, mask) {
86
+ if (['い', 'おい', 'つい', 'か', 'かおか', 'なりか', 'いで', 'は', 'から',
87
+ 'なり'].indexOf(mask) >= 0) { return mask + 'たち' }
88
+ return mask
89
+ }])
90
+ this.singularForms.regularForms.push([/^(.+)達$/i, function (a, mask) {
91
+ if (['伊', '伊', '栄', '上意下', '熟', '上', '下意上', '先', '送', '速',
92
+ '即日速', '書留速', '調', '通', '伝', '到', '配', '牛乳配', '新聞配', '無料配',
93
+ '四通八', '発', '未発', '御用', '宮内庁御用', '練', '闊'].indexOf(mask) >= 0) { return mask + '達' }
94
+ return mask
95
+ }]) // Singularize nouns ending by -等, but not exceptions.
96
+ this.singularForms.regularForms.push([/^(.+)等$/i, function (a, mask) {
97
+ if (['一', '下', '何', '均', '勲', '高', '三', '初', '親', '二親', '数', '対',
98
+ '中', '同', '特', '二', '品', '不', '平', '悪平', '男女平', '不平', '優',
99
+ '劣'].indexOf(mask) >= 0) { return mask + '等' }
100
+ return mask
101
+ }])
102
+ this.singularForms.regularForms.push([/^(人間|わたくし|私|てまえ|手前|野郎|やろう|勇者|がき|ガキ|餓鬼|あくとう|悪党|猫|家来)(共|ども)$/i, '$1'])
103
+ this.singularForms.regularForms.push([/^(神様|先生|あなた|大名|女中|奥様)(方|がた)$/i, '$1'])
104
+
105
+ this.pluralize = function (token) {
106
+ return this.ize(token, this.pluralForms, this.customPluralForms)
107
+ }
108
+
109
+ this.singularize = function (token) {
110
+ return this.ize(token, this.singularForms, this.customSingularForms)
111
+ }
56
112
  }
57
113
  }
58
- */
59
-
60
- /**
61
- * @constructor
62
- */
63
- const NounInflector = function () {
64
- // Ambiguous a.k.a. invariant.
65
- this.ambiguous = [
66
- 'ともだち', '友だち', '友達', '遊び友達', '飲み友達', '酒飲み友達', '茶飲み友達',
67
- '学校友達', '女友達', '男友達', '幼友達'
68
- ]
69
-
70
- this.customPluralForms = []
71
- this.customSingularForms = []
72
- this.singularForms = new FormSet()
73
- this.pluralForms = new FormSet()
74
-
75
- // this.attach = attach
76
-
77
- this.addIrregular('神', '神神')
78
- this.addIrregular('人', '人人')
79
- this.addIrregular('年', '年年')
80
- this.addIrregular('月', '月月')
81
- this.addIrregular('日', '日日')
82
- this.addIrregular('星', '星星')
83
- this.addIrregular('島', '島島')
84
- this.addIrregular('我', '我我')
85
- this.addIrregular('山', '山山')
86
- this.addIrregular('国', '国国')
87
- this.addIrregular('所', '所所')
88
- this.addIrregular('隅', '隅隅')
89
-
90
- /**
91
- * Notes:
92
- * -たち exceptions: いたち, おいたち, ついたち, かたち, かおかたち, なりかたち, いでたち, はたち, からたち, なりたち
93
- * -達 exceptions: 伊達, 男伊達, 栄達, 上意下達, 熟達, 上達, 下意上達, 先達, 送達, 速達, 即日速達, 書留速達, 調達, 通達, 伝達, 到達, 配達, 牛乳配達, 新聞配達, 無料配達, 四通八達, 発達, 未発達, 御用達, 宮内庁御用達, 練達, 闊達
94
- * -等 exceptions: 一等, 下等, 何等, 均等, 勲等, 高等, 三等, 初等, 上等, 親等, 二親等, 数等, 対等, 中等, 同等, 特等, 二等, 品等, 不等, 平等, 悪平等, 男女平等, 不平等, 優等, 劣等
95
- */
96
-
97
- // Pluralize
98
- this.pluralForms.regularForms.push([/^(.+)$/i, '$1たち'])
99
-
100
- // Singularize
101
- this.singularForms.regularForms.push([/^(.+)たち$/i, function (a, mask) {
102
- if (['い', 'おい', 'つい', 'か', 'かおか', 'なりか', 'いで', 'は', 'から',
103
- 'なり'].indexOf(mask) >= 0) { return mask + 'たち' }
104
- return mask
105
- }])
106
- this.singularForms.regularForms.push([/^(.+)達$/i, function (a, mask) {
107
- if (['伊', '伊', '栄', '上意下', '熟', '上', '下意上', '先', '送', '速',
108
- '即日速', '書留速', '調', '通', '伝', '到', '配', '牛乳配', '新聞配', '無料配',
109
- '四通八', '発', '未発', '御用', '宮内庁御用', '練', '闊'].indexOf(mask) >= 0) { return mask + '達' }
110
- return mask
111
- }]) // Singularize nouns ending by -等, but not exceptions.
112
- this.singularForms.regularForms.push([/^(.+)等$/i, function (a, mask) {
113
- if (['一', '下', '何', '均', '勲', '高', '三', '初', '親', '二親', '数', '対',
114
- '中', '同', '特', '二', '品', '不', '平', '悪平', '男女平', '不平', '優',
115
- '劣'].indexOf(mask) >= 0) { return mask + '等' }
116
- return mask
117
- }])
118
- this.singularForms.regularForms.push([/^(人間|わたくし|私|てまえ|手前|野郎|やろう|勇者|がき|ガキ|餓鬼|あくとう|悪党|猫|家来)(共|ども)$/i, '$1'])
119
- this.singularForms.regularForms.push([/^(神様|先生|あなた|大名|女中|奥様)(方|がた)$/i, '$1'])
120
-
121
- this.pluralize = function (token) {
122
- return this.ize(token, this.pluralForms, this.customPluralForms)
123
- }
124
-
125
- this.singularize = function (token) {
126
- return this.ize(token, this.singularForms, this.customSingularForms)
127
- }
128
- }
129
-
130
- util.inherits(NounInflector, SingularPluralInflector)
131
114
 
132
115
  module.exports = NounInflector