-
Notifications
You must be signed in to change notification settings - Fork 2
/
owl.js
191 lines (159 loc) · 6.04 KB
/
owl.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* This file is part of OWL Pluralization. http://www.oranlooney.com/js-plural/
OWL Pluralization is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
OWL Pluralization is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OWL Pluralization. If not, see
<http://www.gnu.org/licenses/>.
*/
// prepare the owl namespace.
if ( typeof owl === 'undefined' ) owl = {};
owl.pluralize = (function() {
var userDefined = {};
function capitalizeSame(word, sampleWord) {
if ( sampleWord.match(/^[A-Z]/) ) {
return word.charAt(0).toUpperCase() + word.slice(1);
} else {
return word;
}
}
// returns a plain Object having the given keys,
// all with value 1, which can be used for fast lookups.
function toKeys(keys) {
keys = keys.split(',');
var keysLength = keys.length;
var table = {};
for ( var i=0; i < keysLength; i++ ) {
table[ keys[i] ] = 1;
}
return table;
}
// words that are always singular, always plural, or the same in both forms.
var uninflected = toKeys("aircraft,advice,blues,corn,molasses,equipment,gold,information,cotton,jewelry,kin,legislation,luck,luggage,moose,music,offspring,rice,silver,trousers,wheat,bison,bream,breeches,britches,carp,chassis,clippers,cod,contretemps,corps,debris,diabetes,djinn,eland,elk,flounder,gallows,graffiti,headquarters,herpes,high,homework,innings,jackanapes,mackerel,measles,mews,mumps,news,pincers,pliers,proceedings,rabies,salmon,scissors,sea,series,shears,species,swine,trout,tuna,whiting,wildebeest,pike,oats,tongs,dregs,snuffers,victuals,tweezers,vespers,pinchers,bellows,cattle");
var irregular = {
// pronouns
I: 'we',
you: 'you',
he: 'they',
it: 'they', // or them
me: 'us',
you: 'you',
him: 'them',
them: 'them',
myself: 'ourselves',
yourself: 'yourselves',
himself: 'themselves',
herself: 'themselves',
itself: 'themselves',
themself: 'themselves',
oneself: 'oneselves',
child: 'children',
dwarf: 'dwarfs', // dwarfs are real; dwarves are fantasy.
mongoose: 'mongooses',
mythos: 'mythoi',
ox: 'oxen',
soliloquy: 'soliloquies',
trilby: 'trilbys',
person: 'people',
forum: 'forums', // fora is ok but uncommon.
// latin plural in popular usage.
syllabus: 'syllabi',
alumnus: 'alumni',
genus: 'genera',
viscus: 'viscera',
stigma: 'stigmata'
};
var suffixRules = [
// common suffixes
[ /man$/i, 'men' ],
[ /([lm])ouse$/i, '$1ice' ],
[ /tooth$/i, 'teeth' ],
[ /goose$/i, 'geese' ],
[ /foot$/i, 'feet' ],
[ /zoon$/i, 'zoa' ],
[ /([tcsx])is$/i, '$1es' ],
// fully assimilated suffixes
[ /ix$/i, 'ices' ],
[ /^(cod|mur|sil|vert)ex$/i, '$1ices' ],
[ /^(agend|addend|memorand|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi)um$/i, '$1a' ],
[ /^(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|\w+hedr)on$/i, '$1a' ],
[ /^(alumn|alg|vertebr)a$/i, '$1ae' ],
// churches, classes, boxes, etc.
[ /([cs]h|ss|x)$/i, '$1es' ],
// words with -ves plural form
[ /([aeo]l|[^d]ea|ar)f$/i, '$1ves' ],
[ /([nlw]i)fe$/i, '$1ves' ],
// -y
[ /([aeiou])y$/i, '$1ys' ],
[ /(^[A-Z][a-z]*)y$/, '$1ys' ], // case sensitive!
[ /y$/i, 'ies' ],
// -o
[ /([aeiou])o$/i, '$1os' ],
[ /^(pian|portic|albin|generalissim|manifest|archipelag|ghett|medic|armadill|guan|octav|command|infern|phot|ditt|jumb|pr|dynam|ling|quart|embry|lumbag|rhin|fiasc|magnet|styl|alt|contralt|sopran|bass|crescend|temp|cant|sol|kimon)o$/i, '$1os' ],
[ /o$/i, 'oes' ],
// words ending in s...
[ /s$/i, 'ses' ]
];
// pluralizes the given singular noun. There are three ways to call it:
// pluralize(noun) -> pluralNoun
// Returns the plural of the given noun.
// Example:
// pluralize("person") -> "people"
// pluralize("me") -> "us"
//
// pluralize(noun, count) -> plural or singular noun
// Inflect the noun according to the count, returning the singular noun
// if the count is 1.
// Examples:
// pluralize("person", 3) -> "people"
// pluralize("person", 1) -> "person"
// pluralize("person", 0) -> "people"
//
// pluralize(noun, count, plural) -> plural or singular noun
// you can provide an irregular plural yourself as the 3rd argument.
// Example:
// pluralize("château", 2 "châteaux") -> "châteaux"
function pluralize(word, count, plural) {
// handle the empty string reasonably.
if ( word === '' ) return '';
// singular case.
if ( count === 1 ) return word;
// life is very easy if an explicit plural was provided.
if ( typeof plural === 'string' ) return plural;
var lowerWord = word.toLowerCase();
// user defined rules have the highest priority.
if ( lowerWord in userDefined ) {
return capitalizeSame(userDefined[lowerWord], word);
}
// single letters are pluralized with 's, "I got five A's on
// my report card."
if ( word.match(/^[A-Z]$/) ) return word + "'s";
// some word don't change form when plural.
if ( word.match(/fish$|ois$|sheep$|deer$|pox$|itis$/i) ) return word;
if ( word.match(/^[A-Z][a-z]*ese$/) ) return word; // Nationalities.
if ( lowerWord in uninflected ) return word;
// there's a known set of words with irregular plural forms.
if ( lowerWord in irregular ) {
return capitalizeSame(irregular[lowerWord], word);
}
// try to pluralize the word depending on its suffix.
var suffixRulesLength = suffixRules.length;
for ( var i=0; i < suffixRulesLength; i++ ) {
var rule = suffixRules[i];
if ( word.match(rule[0]) ) {
return word.replace(rule[0], rule[1]);
}
}
// if all else fails, just add s.
return word + 's';
}
pluralize.define = function(word, plural) {
userDefined[word.toLowerCase()] = plural;
}
return pluralize;
})();