-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
113 lines (89 loc) · 3.49 KB
/
index.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
'use strict';
var rules = []
function type(obj) {
return Object.prototype.toString.call(obj).slice(8, -1)
}
function addRule(match, result) {
rules.unshift([match, result])
return plural
}
// words like cherry, where a word ends in a y, but the letter before the y is a consonant
// also contains unique rule for words that end with 'quy' (soliloquy)
addRule(/[^aeiou]y$|quy$/i, function(w) { return w.substr(0, w.length - 1) + 'ies' })
// words that end with ch, x, s append 'es'
addRule(/x$|ch$|s$/i, function(w) { return w + 'es' })
// words that maintain latin/greek plural
addRule(/nucleus|syllabus|focus|fungus|cactus/i, function(w) { return w.substr(0, w.length - 2) + 'i' });
addRule(/thesis|crisis/i, function(w) { return w.substr(0, w.length - 2) + 'es' });
addRule(/appendix|index/i, function(w) { return w.substr(0, w.length - 2) + 'ices' });
// stereo -> stereos
addRule(/[aeiouy]o$/i, function(w) { return w + 's' });
addRule(/[^aeiouy]o$/i, function(w) { return w + 'es' });
// f/fe ending words gets switched to ves
// unless it's dwarf or roof
addRule(/(fe?$)/i, function(w, regex) {
if (w === 'dwarf' || w === 'roof') {
return w + 's'
}
return w.replace(regex, 'ves')
})
addRule('criterion', 'criteria')
addRule('bacterium', 'bacteria')
addRule('memo', 'memos')
addRule('cello', 'cellos')
addRule('die', 'dice')
addRule('goose', 'geese')
addRule('mouse', 'mice')
addRule('person', 'people')
addRule('chilli', 'chillies')
addRule(/^(?:wo)?man$/i, function(w) { return w.replace(/a/, 'e') })
// animals w/ no plural
addRule(/\b(?:bison|cod|deer|fowl|halibut|moose|sheep)\b/i, function(w) { return w })
// singular nouns that end in -s
var tools = ['goggle', 'scissor', 'plier', 'tong', 'tweezer']
var clothes = ['trouser', 'pant', 'pantie', 'clothe']
var games = ['billiard', 'bowl', 'card', 'dart', 'skittle', 'draught']
var illnesses = ['diabete', 'measle', 'mump', 'rabie', 'ricket', 'shingle']
var misc = ['kudo', 'premise', 'shamble', 'glasse', 'spectacle', 'jitter',
'alm', 'fece', 'bowel', 'sud', 'entrail', 'electronic', 'outskirt', 'odd', 'tropic',
'riche', 'surrounding', 'thank', 'heroic', 'remain', 'amend'
]
addRule(new RegExp('\\b(?:' + tools.concat(clothes, games, illnesses, misc).join('|') + ')s\\b', 'i'), function(w) { return w})
// most words ending in -ics are the same in their plural form
// mathematics, statistics, linguistics, classics, acoustics
addRule(/ics$/i, function(w) { return w })
// uncountable
addRule(/\b(?:tea|sugar|water|air|rice|knowledge|beauty|anger|fear|love|money|research|safety|evidence)\b/i, function(w) { return w })
function plural(word, num) {
var i
, rule
if (num !== 1 || num === undefined) {
for (i = 0; i < rules.length; i++) {
rule = rules[i]
if (type(rule[0]) === 'RegExp' && rule[0].test(word)) {
return type(rule[1]) === 'Function' ? rule[1](word, rule[0]) : rule[1]
}
if (type(rule[0]) === 'String' && rule[0] === word) {
return type(rule[1]) === 'Function' ? rule[1](word) : rule[1]
}
}
return word + 's'
}
return word
}
module.exports = plural
module.exports.addRule = addRule
module.exports.unmonkeyPatch = function() {
String.prototype.plural = null;
}
module.exports.monkeyPatch = function() {
if (String.prototype.plural === undefined) {
String.prototype.plural = function(num) {
return plural(this, num)
}
}
else {
throw new Error('Unable to add plural function to String object')
}
}
module.exports.VERSION = require('./package.json').version