underscore-inflections-rails 1.0.0 → 1.1.0
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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a54f9ac3cd1312a5274c18d7dbb3d8998a7760a7
|
4
|
+
data.tar.gz: 15f0a398fead42586171331c2f6bc45819e4f6eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7705efdb64ddc54184b198948b91ee9180eb482ac4f5b9e6fd4174a290d152516af1c6dfef2057ea4ca464e93bdf8df76ac61f13bb3165e2b487f0cd658e090d
|
7
|
+
data.tar.gz: 51ae2c1f03e618aabba94dfb9d28b751f91e1daedc52fa8f815b14a0b5e144a5dc9c5a6e923d3b713f331c7ce7900d73d046ad5df41bbb27c84709ff25c23ea9
|
@@ -1,673 +1,279 @@
|
|
1
|
-
//
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
// Version '2.3.2'
|
7
|
-
|
8
|
-
!function(root, String){
|
9
|
-
'use strict';
|
10
|
-
|
11
|
-
// Defining helper functions.
|
12
|
-
|
13
|
-
var nativeTrim = String.prototype.trim;
|
14
|
-
var nativeTrimRight = String.prototype.trimRight;
|
15
|
-
var nativeTrimLeft = String.prototype.trimLeft;
|
16
|
-
|
17
|
-
var parseNumber = function(source) { return source * 1 || 0; };
|
18
|
-
|
19
|
-
var strRepeat = function(str, qty){
|
20
|
-
if (qty < 1) return '';
|
21
|
-
var result = '';
|
22
|
-
while (qty > 0) {
|
23
|
-
if (qty & 1) result += str;
|
24
|
-
qty >>= 1, str += str;
|
25
|
-
}
|
26
|
-
return result;
|
27
|
-
};
|
28
|
-
|
29
|
-
var slice = [].slice;
|
30
|
-
|
31
|
-
var defaultToWhiteSpace = function(characters) {
|
32
|
-
if (characters == null)
|
33
|
-
return '\\s';
|
34
|
-
else if (characters.source)
|
35
|
-
return characters.source;
|
36
|
-
else
|
37
|
-
return '[' + _s.escapeRegExp(characters) + ']';
|
38
|
-
};
|
39
|
-
|
40
|
-
// Helper for toBoolean
|
41
|
-
function boolMatch(s, matchers) {
|
42
|
-
var i, matcher, down = s.toLowerCase();
|
43
|
-
matchers = [].concat(matchers);
|
44
|
-
for (i = 0; i < matchers.length; i += 1) {
|
45
|
-
matcher = matchers[i];
|
46
|
-
if (!matcher) continue;
|
47
|
-
if (matcher.test && matcher.test(s)) return true;
|
48
|
-
if (matcher.toLowerCase() === down) return true;
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
var escapeChars = {
|
53
|
-
lt: '<',
|
54
|
-
gt: '>',
|
55
|
-
quot: '"',
|
56
|
-
amp: '&',
|
57
|
-
apos: "'"
|
58
|
-
};
|
59
|
-
|
60
|
-
var reversedEscapeChars = {};
|
61
|
-
for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key;
|
62
|
-
reversedEscapeChars["'"] = '#39';
|
63
|
-
|
64
|
-
// sprintf() for JavaScript 0.7-beta1
|
65
|
-
// http://www.diveintojavascript.com/projects/javascript-sprintf
|
66
|
-
//
|
67
|
-
// Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
|
68
|
-
// All rights reserved.
|
69
|
-
|
70
|
-
var sprintf = (function() {
|
71
|
-
function get_type(variable) {
|
72
|
-
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
|
73
|
-
}
|
74
|
-
|
75
|
-
var str_repeat = strRepeat;
|
1
|
+
// Generated by CoffeeScript 1.6.3
|
2
|
+
(function() {
|
3
|
+
var Inflections, root, _,
|
4
|
+
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
5
|
+
__slice = [].slice;
|
76
6
|
|
77
|
-
|
78
|
-
|
79
|
-
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
|
80
|
-
}
|
81
|
-
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
|
82
|
-
};
|
83
|
-
|
84
|
-
str_format.format = function(parse_tree, argv) {
|
85
|
-
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
|
86
|
-
for (i = 0; i < tree_length; i++) {
|
87
|
-
node_type = get_type(parse_tree[i]);
|
88
|
-
if (node_type === 'string') {
|
89
|
-
output.push(parse_tree[i]);
|
90
|
-
}
|
91
|
-
else if (node_type === 'array') {
|
92
|
-
match = parse_tree[i]; // convenience purposes only
|
93
|
-
if (match[2]) { // keyword argument
|
94
|
-
arg = argv[cursor];
|
95
|
-
for (k = 0; k < match[2].length; k++) {
|
96
|
-
if (!arg.hasOwnProperty(match[2][k])) {
|
97
|
-
throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
|
98
|
-
}
|
99
|
-
arg = arg[match[2][k]];
|
100
|
-
}
|
101
|
-
} else if (match[1]) { // positional argument (explicit)
|
102
|
-
arg = argv[match[1]];
|
103
|
-
}
|
104
|
-
else { // positional argument (implicit)
|
105
|
-
arg = argv[cursor++];
|
106
|
-
}
|
107
|
-
|
108
|
-
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
|
109
|
-
throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
|
110
|
-
}
|
111
|
-
switch (match[8]) {
|
112
|
-
case 'b': arg = arg.toString(2); break;
|
113
|
-
case 'c': arg = String.fromCharCode(arg); break;
|
114
|
-
case 'd': arg = parseInt(arg, 10); break;
|
115
|
-
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
|
116
|
-
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
|
117
|
-
case 'o': arg = arg.toString(8); break;
|
118
|
-
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
|
119
|
-
case 'u': arg = Math.abs(arg); break;
|
120
|
-
case 'x': arg = arg.toString(16); break;
|
121
|
-
case 'X': arg = arg.toString(16).toUpperCase(); break;
|
122
|
-
}
|
123
|
-
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
|
124
|
-
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
|
125
|
-
pad_length = match[6] - String(arg).length;
|
126
|
-
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
|
127
|
-
output.push(match[5] ? arg + pad : pad + arg);
|
128
|
-
}
|
129
|
-
}
|
130
|
-
return output.join('');
|
131
|
-
};
|
132
|
-
|
133
|
-
str_format.cache = {};
|
134
|
-
|
135
|
-
str_format.parse = function(fmt) {
|
136
|
-
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
|
137
|
-
while (_fmt) {
|
138
|
-
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
|
139
|
-
parse_tree.push(match[0]);
|
140
|
-
}
|
141
|
-
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
|
142
|
-
parse_tree.push('%');
|
143
|
-
}
|
144
|
-
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
|
145
|
-
if (match[2]) {
|
146
|
-
arg_names |= 1;
|
147
|
-
var field_list = [], replacement_field = match[2], field_match = [];
|
148
|
-
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
149
|
-
field_list.push(field_match[1]);
|
150
|
-
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
|
151
|
-
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
152
|
-
field_list.push(field_match[1]);
|
153
|
-
}
|
154
|
-
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
|
155
|
-
field_list.push(field_match[1]);
|
156
|
-
}
|
157
|
-
else {
|
158
|
-
throw new Error('[_.sprintf] huh?');
|
159
|
-
}
|
160
|
-
}
|
161
|
-
}
|
162
|
-
else {
|
163
|
-
throw new Error('[_.sprintf] huh?');
|
164
|
-
}
|
165
|
-
match[2] = field_list;
|
166
|
-
}
|
167
|
-
else {
|
168
|
-
arg_names |= 2;
|
169
|
-
}
|
170
|
-
if (arg_names === 3) {
|
171
|
-
throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
|
172
|
-
}
|
173
|
-
parse_tree.push(match);
|
174
|
-
}
|
175
|
-
else {
|
176
|
-
throw new Error('[_.sprintf] huh?');
|
177
|
-
}
|
178
|
-
_fmt = _fmt.substring(match[0].length);
|
179
|
-
}
|
180
|
-
return parse_tree;
|
181
|
-
};
|
7
|
+
Inflections = (function() {
|
8
|
+
Inflections.prototype.defaultUncountables = ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'jeans', 'moose', 'deer', 'news', 'music'];
|
182
9
|
|
183
|
-
|
184
|
-
})();
|
10
|
+
Inflections.prototype.defaultPluralRules = [[/$/, 's'], [/s$/i, 's'], [/^(ax|test)is$/i, '$1es'], [/(octop|vir)us$/i, '$1i'], [/(octop|vir)i$/i, '$1i'], [/(alias|status)$/i, '$1es'], [/(bu)s$/i, '$1ses'], [/(buffal|tomat)o$/i, '$1oes'], [/([ti])um$/i, '$1a'], [/([ti])a$/i, '$1a'], [/sis$/i, 'ses'], [/(?:([^f])fe|([lr])f)$/i, '$1$2ves'], [/(hive)$/i, '$1s'], [/([^aeiouy]|qu)y$/i, '$1ies'], [/(x|ch|ss|sh)$/i, '$1es'], [/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'], [/(m|l)ouse$/i, '$1ice'], [/(m|l)ice$/i, '$1ice'], [/^(ox)$/i, '$1en'], [/^(oxen)$/i, '$1'], [/(quiz)$/i, '$1zes']];
|
185
11
|
|
12
|
+
Inflections.prototype.defaultSingularRules = [[/s$/i, ''], [/(ss)$/i, '$1'], [/(n)ews$/i, '$1ews'], [/([ti])a$/i, '$1um'], [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1$2sis'], [/(^analy)(sis|ses)$/i, '$1sis'], [/([^f])ves$/i, '$1fe'], [/(hive)s$/i, '$1'], [/(tive)s$/i, '$1'], [/([lr])ves$/i, '$1f'], [/([^aeiouy]|qu)ies$/i, '$1y'], [/(s)eries$/i, '$1eries'], [/(m)ovies$/i, '$1ovie'], [/(x|ch|ss|sh)es$/i, '$1'], [/(m|l)ice$/i, '$1ouse'], [/(bus)(es)?$/i, '$1'], [/(o)es$/i, '$1'], [/(shoe)s$/i, '$1'], [/(cris|test)(is|es)$/i, '$1is'], [/^(a)x[ie]s$/i, '$1xis'], [/(octop|vir)(us|i)$/i, '$1us'], [/(alias|status)(es)?$/i, '$1'], [/^(ox)en/i, '$1'], [/(vert|ind)ices$/i, '$1ex'], [/(matr)ices$/i, '$1ix'], [/(quiz)zes$/i, '$1'], [/(database)s$/i, '$1']];
|
186
13
|
|
14
|
+
Inflections.prototype.defaultIrregularRules = [['person', 'people'], ['man', 'men'], ['child', 'children'], ['sex', 'sexes'], ['move', 'moves'], ['cow', 'kine'], ['zombie', 'zombies']];
|
187
15
|
|
188
|
-
|
16
|
+
Inflections.prototype.defaultHumanRules = [];
|
189
17
|
|
190
|
-
|
18
|
+
function Inflections() {
|
19
|
+
this.apply_inflections = __bind(this.apply_inflections, this);
|
191
20
|
|
192
|
-
|
21
|
+
this.titleize = __bind(this.titleize, this);
|
22
|
+
this.humanize = __bind(this.humanize, this);
|
23
|
+
this.underscore = __bind(this.underscore, this);
|
24
|
+
this.camelize = __bind(this.camelize, this);
|
25
|
+
this.singularize = __bind(this.singularize, this);
|
193
26
|
|
194
|
-
|
195
|
-
if (str == null) str = '';
|
196
|
-
return (/^\s*$/).test(str);
|
197
|
-
},
|
27
|
+
this.pluralize = __bind(this.pluralize, this);
|
198
28
|
|
199
|
-
|
200
|
-
if (str == null) return '';
|
201
|
-
return String(str).replace(/<\/?[^>]+>/g, '');
|
202
|
-
},
|
29
|
+
this.clearInflections = __bind(this.clearInflections, this);
|
203
30
|
|
204
|
-
|
205
|
-
|
206
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
207
|
-
},
|
31
|
+
this.human = __bind(this.human, this);
|
32
|
+
this.uncountable = __bind(this.uncountable, this);
|
208
33
|
|
209
|
-
|
210
|
-
if (str == null) return [];
|
211
|
-
str = String(str);
|
212
|
-
step = ~~step;
|
213
|
-
return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str];
|
214
|
-
},
|
34
|
+
this.irregular = __bind(this.irregular, this);
|
215
35
|
|
216
|
-
|
217
|
-
return _s.strip(str).replace(/\s+/g, ' ');
|
218
|
-
},
|
36
|
+
this.singular = __bind(this.singular, this);
|
219
37
|
|
220
|
-
|
221
|
-
if (str == null || substr == null) return 0;
|
38
|
+
this.plural = __bind(this.plural, this);
|
222
39
|
|
223
|
-
|
224
|
-
|
40
|
+
this.acronym = __bind(this.acronym, this);
|
41
|
+
this.applyDefaultPlurals = __bind(this.applyDefaultPlurals, this);
|
225
42
|
|
226
|
-
|
227
|
-
pos = 0,
|
228
|
-
length = substr.length;
|
43
|
+
this.applyDefaultUncountables = __bind(this.applyDefaultUncountables, this);
|
229
44
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
}
|
45
|
+
this.applyDefaultRules = __bind(this.applyDefaultRules, this);
|
46
|
+
this.plurals = [];
|
47
|
+
this.singulars = [];
|
48
|
+
this.uncountables = [];
|
49
|
+
this.humans = [];
|
50
|
+
this.acronyms = {};
|
51
|
+
this.applyDefaultRules();
|
52
|
+
}
|
236
53
|
|
237
|
-
|
238
|
-
|
54
|
+
Inflections.prototype.applyDefaultRules = function() {
|
55
|
+
this.applyDefaultUncountables();
|
56
|
+
this.applyDefaultPlurals();
|
57
|
+
this.applyDefaultSingulars();
|
58
|
+
return this.applyDefaultIrregulars();
|
59
|
+
};
|
239
60
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
},
|
61
|
+
Inflections.prototype.applyDefaultUncountables = function() {
|
62
|
+
return this.uncountable(this.defaultUncountables);
|
63
|
+
};
|
244
64
|
|
245
|
-
|
246
|
-
|
247
|
-
return
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
escapeHTML: function(str) {
|
253
|
-
if (str == null) return '';
|
254
|
-
return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; });
|
255
|
-
},
|
256
|
-
|
257
|
-
unescapeHTML: function(str) {
|
258
|
-
if (str == null) return '';
|
259
|
-
return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){
|
260
|
-
var match;
|
261
|
-
|
262
|
-
if (entityCode in escapeChars) {
|
263
|
-
return escapeChars[entityCode];
|
264
|
-
} else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
|
265
|
-
return String.fromCharCode(parseInt(match[1], 16));
|
266
|
-
} else if (match = entityCode.match(/^#(\d+)$/)) {
|
267
|
-
return String.fromCharCode(~~match[1]);
|
268
|
-
} else {
|
269
|
-
return entity;
|
270
|
-
}
|
65
|
+
Inflections.prototype.applyDefaultPlurals = function() {
|
66
|
+
var _this = this;
|
67
|
+
return _.each(this.defaultPluralRules, function(rule) {
|
68
|
+
var capture, regex;
|
69
|
+
regex = rule[0], capture = rule[1];
|
70
|
+
return _this.plural(regex, capture);
|
271
71
|
});
|
272
|
-
}
|
273
|
-
|
274
|
-
escapeRegExp: function(str){
|
275
|
-
if (str == null) return '';
|
276
|
-
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
|
277
|
-
},
|
278
|
-
|
279
|
-
splice: function(str, i, howmany, substr){
|
280
|
-
var arr = _s.chars(str);
|
281
|
-
arr.splice(~~i, ~~howmany, substr);
|
282
|
-
return arr.join('');
|
283
|
-
},
|
284
|
-
|
285
|
-
insert: function(str, i, substr){
|
286
|
-
return _s.splice(str, i, 0, substr);
|
287
|
-
},
|
288
|
-
|
289
|
-
include: function(str, needle){
|
290
|
-
if (needle === '') return true;
|
291
|
-
if (str == null) return false;
|
292
|
-
return String(str).indexOf(needle) !== -1;
|
293
|
-
},
|
294
|
-
|
295
|
-
join: function() {
|
296
|
-
var args = slice.call(arguments),
|
297
|
-
separator = args.shift();
|
298
|
-
|
299
|
-
if (separator == null) separator = '';
|
300
|
-
|
301
|
-
return args.join(separator);
|
302
|
-
},
|
303
|
-
|
304
|
-
lines: function(str) {
|
305
|
-
if (str == null) return [];
|
306
|
-
return String(str).split("\n");
|
307
|
-
},
|
308
|
-
|
309
|
-
reverse: function(str){
|
310
|
-
return _s.chars(str).reverse().join('');
|
311
|
-
},
|
312
|
-
|
313
|
-
startsWith: function(str, starts){
|
314
|
-
if (starts === '') return true;
|
315
|
-
if (str == null || starts == null) return false;
|
316
|
-
str = String(str); starts = String(starts);
|
317
|
-
return str.length >= starts.length && str.slice(0, starts.length) === starts;
|
318
|
-
},
|
319
|
-
|
320
|
-
endsWith: function(str, ends){
|
321
|
-
if (ends === '') return true;
|
322
|
-
if (str == null || ends == null) return false;
|
323
|
-
str = String(str); ends = String(ends);
|
324
|
-
return str.length >= ends.length && str.slice(str.length - ends.length) === ends;
|
325
|
-
},
|
326
|
-
|
327
|
-
succ: function(str){
|
328
|
-
if (str == null) return '';
|
329
|
-
str = String(str);
|
330
|
-
return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1);
|
331
|
-
},
|
332
|
-
|
333
|
-
titleize: function(str){
|
334
|
-
if (str == null) return '';
|
335
|
-
str = String(str).toLowerCase();
|
336
|
-
return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); });
|
337
|
-
},
|
338
|
-
|
339
|
-
camelize: function(str){
|
340
|
-
return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; });
|
341
|
-
},
|
342
|
-
|
343
|
-
underscored: function(str){
|
344
|
-
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
|
345
|
-
},
|
346
|
-
|
347
|
-
dasherize: function(str){
|
348
|
-
return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
|
349
|
-
},
|
350
|
-
|
351
|
-
classify: function(str){
|
352
|
-
return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, '');
|
353
|
-
},
|
354
|
-
|
355
|
-
humanize: function(str){
|
356
|
-
return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
|
357
|
-
},
|
358
|
-
|
359
|
-
trim: function(str, characters){
|
360
|
-
if (str == null) return '';
|
361
|
-
if (!characters && nativeTrim) return nativeTrim.call(str);
|
362
|
-
characters = defaultToWhiteSpace(characters);
|
363
|
-
return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), '');
|
364
|
-
},
|
365
|
-
|
366
|
-
ltrim: function(str, characters){
|
367
|
-
if (str == null) return '';
|
368
|
-
if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str);
|
369
|
-
characters = defaultToWhiteSpace(characters);
|
370
|
-
return String(str).replace(new RegExp('^' + characters + '+'), '');
|
371
|
-
},
|
372
|
-
|
373
|
-
rtrim: function(str, characters){
|
374
|
-
if (str == null) return '';
|
375
|
-
if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
|
376
|
-
characters = defaultToWhiteSpace(characters);
|
377
|
-
return String(str).replace(new RegExp(characters + '+$'), '');
|
378
|
-
},
|
379
|
-
|
380
|
-
truncate: function(str, length, truncateStr){
|
381
|
-
if (str == null) return '';
|
382
|
-
str = String(str); truncateStr = truncateStr || '...';
|
383
|
-
length = ~~length;
|
384
|
-
return str.length > length ? str.slice(0, length) + truncateStr : str;
|
385
|
-
},
|
386
|
-
|
387
|
-
/**
|
388
|
-
* _s.prune: a more elegant version of truncate
|
389
|
-
* prune extra chars, never leaving a half-chopped word.
|
390
|
-
* @author github.com/rwz
|
391
|
-
*/
|
392
|
-
prune: function(str, length, pruneStr){
|
393
|
-
if (str == null) return '';
|
394
|
-
|
395
|
-
str = String(str); length = ~~length;
|
396
|
-
pruneStr = pruneStr != null ? String(pruneStr) : '...';
|
397
|
-
|
398
|
-
if (str.length <= length) return str;
|
399
|
-
|
400
|
-
var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; },
|
401
|
-
template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
|
402
|
-
|
403
|
-
if (template.slice(template.length-2).match(/\w\w/))
|
404
|
-
template = template.replace(/\s*\S+$/, '');
|
405
|
-
else
|
406
|
-
template = _s.rtrim(template.slice(0, template.length-1));
|
407
|
-
|
408
|
-
return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr;
|
409
|
-
},
|
410
|
-
|
411
|
-
words: function(str, delimiter) {
|
412
|
-
if (_s.isBlank(str)) return [];
|
413
|
-
return _s.trim(str, delimiter).split(delimiter || /\s+/);
|
414
|
-
},
|
415
|
-
|
416
|
-
pad: function(str, length, padStr, type) {
|
417
|
-
str = str == null ? '' : String(str);
|
418
|
-
length = ~~length;
|
419
|
-
|
420
|
-
var padlen = 0;
|
421
|
-
|
422
|
-
if (!padStr)
|
423
|
-
padStr = ' ';
|
424
|
-
else if (padStr.length > 1)
|
425
|
-
padStr = padStr.charAt(0);
|
426
|
-
|
427
|
-
switch(type) {
|
428
|
-
case 'right':
|
429
|
-
padlen = length - str.length;
|
430
|
-
return str + strRepeat(padStr, padlen);
|
431
|
-
case 'both':
|
432
|
-
padlen = length - str.length;
|
433
|
-
return strRepeat(padStr, Math.ceil(padlen/2)) + str
|
434
|
-
+ strRepeat(padStr, Math.floor(padlen/2));
|
435
|
-
default: // 'left'
|
436
|
-
padlen = length - str.length;
|
437
|
-
return strRepeat(padStr, padlen) + str;
|
438
|
-
}
|
439
|
-
},
|
440
|
-
|
441
|
-
lpad: function(str, length, padStr) {
|
442
|
-
return _s.pad(str, length, padStr);
|
443
|
-
},
|
444
|
-
|
445
|
-
rpad: function(str, length, padStr) {
|
446
|
-
return _s.pad(str, length, padStr, 'right');
|
447
|
-
},
|
448
|
-
|
449
|
-
lrpad: function(str, length, padStr) {
|
450
|
-
return _s.pad(str, length, padStr, 'both');
|
451
|
-
},
|
452
|
-
|
453
|
-
sprintf: sprintf,
|
454
|
-
|
455
|
-
vsprintf: function(fmt, argv){
|
456
|
-
argv.unshift(fmt);
|
457
|
-
return sprintf.apply(null, argv);
|
458
|
-
},
|
459
|
-
|
460
|
-
toNumber: function(str, decimals) {
|
461
|
-
if (!str) return 0;
|
462
|
-
str = _s.trim(str);
|
463
|
-
if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN;
|
464
|
-
return parseNumber(parseNumber(str).toFixed(~~decimals));
|
465
|
-
},
|
466
|
-
|
467
|
-
numberFormat : function(number, dec, dsep, tsep) {
|
468
|
-
if (isNaN(number) || number == null) return '';
|
469
|
-
|
470
|
-
number = number.toFixed(~~dec);
|
471
|
-
tsep = typeof tsep == 'string' ? tsep : ',';
|
472
|
-
|
473
|
-
var parts = number.split('.'), fnums = parts[0],
|
474
|
-
decimals = parts[1] ? (dsep || '.') + parts[1] : '';
|
475
|
-
|
476
|
-
return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals;
|
477
|
-
},
|
478
|
-
|
479
|
-
strRight: function(str, sep){
|
480
|
-
if (str == null) return '';
|
481
|
-
str = String(str); sep = sep != null ? String(sep) : sep;
|
482
|
-
var pos = !sep ? -1 : str.indexOf(sep);
|
483
|
-
return ~pos ? str.slice(pos+sep.length, str.length) : str;
|
484
|
-
},
|
485
|
-
|
486
|
-
strRightBack: function(str, sep){
|
487
|
-
if (str == null) return '';
|
488
|
-
str = String(str); sep = sep != null ? String(sep) : sep;
|
489
|
-
var pos = !sep ? -1 : str.lastIndexOf(sep);
|
490
|
-
return ~pos ? str.slice(pos+sep.length, str.length) : str;
|
491
|
-
},
|
492
|
-
|
493
|
-
strLeft: function(str, sep){
|
494
|
-
if (str == null) return '';
|
495
|
-
str = String(str); sep = sep != null ? String(sep) : sep;
|
496
|
-
var pos = !sep ? -1 : str.indexOf(sep);
|
497
|
-
return ~pos ? str.slice(0, pos) : str;
|
498
|
-
},
|
499
|
-
|
500
|
-
strLeftBack: function(str, sep){
|
501
|
-
if (str == null) return '';
|
502
|
-
str += ''; sep = sep != null ? ''+sep : sep;
|
503
|
-
var pos = str.lastIndexOf(sep);
|
504
|
-
return ~pos ? str.slice(0, pos) : str;
|
505
|
-
},
|
506
|
-
|
507
|
-
toSentence: function(array, separator, lastSeparator, serial) {
|
508
|
-
separator = separator || ', ';
|
509
|
-
lastSeparator = lastSeparator || ' and ';
|
510
|
-
var a = array.slice(), lastMember = a.pop();
|
511
|
-
|
512
|
-
if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator;
|
513
|
-
|
514
|
-
return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
|
515
|
-
},
|
516
|
-
|
517
|
-
toSentenceSerial: function() {
|
518
|
-
var args = slice.call(arguments);
|
519
|
-
args[3] = true;
|
520
|
-
return _s.toSentence.apply(_s, args);
|
521
|
-
},
|
522
|
-
|
523
|
-
slugify: function(str) {
|
524
|
-
if (str == null) return '';
|
525
|
-
|
526
|
-
var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",
|
527
|
-
to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",
|
528
|
-
regex = new RegExp(defaultToWhiteSpace(from), 'g');
|
529
|
-
|
530
|
-
str = String(str).toLowerCase().replace(regex, function(c){
|
531
|
-
var index = from.indexOf(c);
|
532
|
-
return to.charAt(index) || '-';
|
533
|
-
});
|
534
|
-
|
535
|
-
return _s.dasherize(str.replace(/[^\w\s-]/g, ''));
|
536
|
-
},
|
537
|
-
|
538
|
-
surround: function(str, wrapper) {
|
539
|
-
return [wrapper, str, wrapper].join('');
|
540
|
-
},
|
72
|
+
};
|
541
73
|
|
542
|
-
|
543
|
-
|
544
|
-
|
74
|
+
Inflections.prototype.applyDefaultSingulars = function() {
|
75
|
+
var _this = this;
|
76
|
+
return _.each(this.defaultSingularRules, function(rule) {
|
77
|
+
var capture, regex;
|
78
|
+
regex = rule[0], capture = rule[1];
|
79
|
+
return _this.singular(regex, capture);
|
80
|
+
});
|
81
|
+
};
|
545
82
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
83
|
+
Inflections.prototype.applyDefaultIrregulars = function() {
|
84
|
+
var _this = this;
|
85
|
+
return _.each(this.defaultIrregularRules, function(rule) {
|
86
|
+
var plural, singular;
|
87
|
+
singular = rule[0], plural = rule[1];
|
88
|
+
return _this.irregular(singular, plural);
|
89
|
+
});
|
90
|
+
};
|
552
91
|
|
553
|
-
|
554
|
-
|
92
|
+
Inflections.prototype.acronym = function(word) {
|
93
|
+
this.acronyms[word.toLowerCase()] = word;
|
94
|
+
return this.acronym_matchers = _.values(this.acronyms).join("|");
|
95
|
+
};
|
555
96
|
|
556
|
-
|
557
|
-
|
558
|
-
|
97
|
+
Inflections.prototype.plural = function(rule, replacement) {
|
98
|
+
if (typeof rule === 'string') {
|
99
|
+
delete this.uncountables[_.indexOf(this.uncountables, rule)];
|
559
100
|
}
|
101
|
+
delete this.uncountables[_.indexOf(this.uncountables, replacement)];
|
102
|
+
return this.plurals.unshift([rule, replacement]);
|
103
|
+
};
|
560
104
|
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
// using faster implementation if separator is not needed;
|
570
|
-
if (separator == null) return strRepeat(String(str), qty);
|
105
|
+
Inflections.prototype.singular = function(rule, replacement) {
|
106
|
+
if (typeof rule === 'string') {
|
107
|
+
delete this.uncountables[_.indexOf(this.uncountables, rule)];
|
108
|
+
}
|
109
|
+
delete this.uncountables[_.indexOf(this.uncountables, replacement)];
|
110
|
+
return this.singulars.unshift([rule, replacement]);
|
111
|
+
};
|
571
112
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
113
|
+
Inflections.prototype.irregular = function(singular, plural) {
|
114
|
+
delete this.uncountables[_.indexOf(this.uncountables, singular)];
|
115
|
+
delete this.uncountables[_.indexOf(this.uncountables, plural)];
|
116
|
+
if (singular.substring(0, 1).toUpperCase() === plural.substring(0, 1).toUpperCase()) {
|
117
|
+
this.plural(new RegExp("(" + (singular.substring(0, 1)) + ")" + (singular.substring(1, plural.length)) + "$", "i"), '$1' + plural.substring(1, plural.length));
|
118
|
+
this.plural(new RegExp("(" + (plural.substring(0, 1)) + ")" + (plural.substring(1, plural.length)) + "$", "i"), '$1' + plural.substring(1, plural.length));
|
119
|
+
return this.singular(new RegExp("(" + (plural.substring(0, 1)) + ")" + (plural.substring(1, plural.length)) + "$", "i"), '$1' + singular.substring(1, plural.length));
|
120
|
+
} else {
|
121
|
+
this.plural(new RegExp("" + (singular.substring(0, 1)) + (singular.substring(1, plural.length)) + "$", "i"), plural.substring(0, 1) + plural.substring(1, plural.length));
|
122
|
+
this.plural(new RegExp("" + (singular.substring(0, 1)) + (singular.substring(1, plural.length)) + "$", "i"), plural.substring(0, 1) + plural.substring(1, plural.length));
|
123
|
+
this.plural(new RegExp("" + (plural.substring(0, 1)) + (plural.substring(1, plural.length)) + "$", "i"), plural.substring(0, 1) + plural.substring(1, plural.length));
|
124
|
+
this.plural(new RegExp("" + (plural.substring(0, 1)) + (plural.substring(1, plural.length)) + "$", "i"), plural.substring(0, 1) + plural.substring(1, plural.length));
|
125
|
+
this.singular(new RegExp("" + (plural.substring(0, 1)) + (plural.substring(1, plural.length)) + "$", "i"), singular.substring(0, 1) + singular.substring(1, plural.length));
|
126
|
+
return this.singular(new RegExp("" + (plural.substring(0, 1)) + (plural.substring(1, plural.length)) + "$", "i"), singular.substring(0, 1) + singular.substring(1, plural.length));
|
127
|
+
}
|
128
|
+
};
|
576
129
|
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
130
|
+
Inflections.prototype.uncountable = function() {
|
131
|
+
var words;
|
132
|
+
words = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
133
|
+
this.uncountables.push(words);
|
134
|
+
return this.uncountables = _.flatten(this.uncountables);
|
135
|
+
};
|
581
136
|
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
count = Math.min(tokens1.length, tokens2.length);
|
137
|
+
Inflections.prototype.human = function(rule, replacement) {
|
138
|
+
return this.humans.unshift([rule, replacement]);
|
139
|
+
};
|
586
140
|
|
587
|
-
|
588
|
-
|
141
|
+
Inflections.prototype.clearInflections = function(scope) {
|
142
|
+
if (scope == null) {
|
143
|
+
scope = 'all';
|
144
|
+
}
|
145
|
+
return this[scope] = [];
|
146
|
+
};
|
589
147
|
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
148
|
+
Inflections.prototype.pluralize = function(word, count, options) {
|
149
|
+
var result, _ref;
|
150
|
+
if (options == null) {
|
151
|
+
options = {};
|
152
|
+
}
|
153
|
+
options = _.extend({
|
154
|
+
plural: void 0,
|
155
|
+
showNumber: true
|
156
|
+
}, options);
|
157
|
+
if (count !== void 0) {
|
158
|
+
result = "";
|
159
|
+
if (options.showNumber === true) {
|
160
|
+
result += "" + (count != null ? count : 0) + " ";
|
598
161
|
}
|
162
|
+
return result += count === 1 || (count != null ? typeof count.toString === "function" ? count.toString().match(/^1(\.0+)?$/) : void 0 : void 0) ? word : (_ref = options.plural) != null ? _ref : this.pluralize(word);
|
163
|
+
} else {
|
164
|
+
return this.apply_inflections(word, this.plurals);
|
599
165
|
}
|
166
|
+
};
|
600
167
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
return str1 < str2 ? -1 : 1;
|
605
|
-
},
|
606
|
-
|
607
|
-
levenshtein: function(str1, str2) {
|
608
|
-
if (str1 == null && str2 == null) return 0;
|
609
|
-
if (str1 == null) return String(str2).length;
|
610
|
-
if (str2 == null) return String(str1).length;
|
611
|
-
|
612
|
-
str1 = String(str1); str2 = String(str2);
|
168
|
+
Inflections.prototype.singularize = function(word) {
|
169
|
+
return this.apply_inflections(word, this.singulars);
|
170
|
+
};
|
613
171
|
|
614
|
-
|
172
|
+
Inflections.prototype.camelize = function(term, uppercase_first_letter) {
|
173
|
+
var _this = this;
|
174
|
+
if (uppercase_first_letter == null) {
|
175
|
+
uppercase_first_letter = true;
|
176
|
+
}
|
177
|
+
if (uppercase_first_letter) {
|
178
|
+
term = term.replace(/^[a-z\d]*/, function(a) {
|
179
|
+
return _this.acronyms[a] || _.capitalize(a);
|
180
|
+
});
|
181
|
+
} else {
|
182
|
+
term = term.replace(RegExp("^(?:" + this.acronym_matchers + "(?=\\b|[A-Z_])|\\w)"), function(a) {
|
183
|
+
return a.toLowerCase();
|
184
|
+
});
|
185
|
+
}
|
186
|
+
return term = term.replace(/(?:_|(\/))([a-z\d]*)/gi, function(match, $1, $2, idx, string) {
|
187
|
+
$1 || ($1 = '');
|
188
|
+
return "" + $1 + (_this.acronyms[$2] || _.capitalize($2));
|
189
|
+
});
|
190
|
+
};
|
615
191
|
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
192
|
+
Inflections.prototype.underscore = function(camel_cased_word) {
|
193
|
+
var word;
|
194
|
+
word = camel_cased_word;
|
195
|
+
word = word.replace(RegExp("(?:([A-Za-z\\d])|^)(" + this.acronym_matchers + ")(?=\\b|[^a-z])", "g"), function(match, $1, $2) {
|
196
|
+
return "" + ($1 || '') + ($1 ? '_' : '') + ($2.toLowerCase());
|
197
|
+
});
|
198
|
+
word = word.replace(/([A-Z\d]+)([A-Z][a-z])/g, "$1_$2");
|
199
|
+
word = word.replace(/([a-z\d])([A-Z])/g, "$1_$2");
|
200
|
+
word = word.replace('-', '_');
|
201
|
+
return word = word.toLowerCase();
|
202
|
+
};
|
625
203
|
|
626
|
-
|
627
|
-
|
204
|
+
Inflections.prototype.humanize = function(lower_case_and_underscored_word) {
|
205
|
+
var human, replacement, rule, word, _i, _len, _ref,
|
206
|
+
_this = this;
|
207
|
+
word = lower_case_and_underscored_word;
|
208
|
+
_ref = this.humans;
|
209
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
210
|
+
human = _ref[_i];
|
211
|
+
rule = human[0];
|
212
|
+
replacement = human[1];
|
213
|
+
if (((rule.test != null) && rule.test(word)) || ((rule.indexOf != null) && word.indexOf(rule) >= 0)) {
|
214
|
+
word = word.replace(rule, replacement);
|
215
|
+
break;
|
628
216
|
}
|
217
|
+
}
|
218
|
+
word = word.replace(/_id$/g, '');
|
219
|
+
word = word.replace(/_/g, ' ');
|
220
|
+
word = word.replace(/([a-z\d]*)/gi, function(match) {
|
221
|
+
return _this.acronyms[match] || match.toLowerCase();
|
222
|
+
});
|
223
|
+
return word = _.trim(word).replace(/^\w/g, function(match) {
|
224
|
+
return match.toUpperCase();
|
225
|
+
});
|
226
|
+
};
|
629
227
|
|
630
|
-
|
631
|
-
|
228
|
+
Inflections.prototype.titleize = function(word) {
|
229
|
+
return this.humanize(this.underscore(word)).replace(/([\s¿]+)([a-z])/g, function(match, boundary, letter, idx, string) {
|
230
|
+
return match.replace(letter, letter.toUpperCase());
|
231
|
+
});
|
232
|
+
};
|
632
233
|
|
633
|
-
|
634
|
-
|
635
|
-
if (
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
234
|
+
Inflections.prototype.apply_inflections = function(word, rules) {
|
235
|
+
var capture, match, regex, result, rule, _i, _len;
|
236
|
+
if (!word) {
|
237
|
+
return word;
|
238
|
+
} else {
|
239
|
+
result = word;
|
240
|
+
match = result.toLowerCase().match(/\b\w+$/);
|
241
|
+
if (match && _.indexOf(this.uncountables, match[0]) !== -1) {
|
242
|
+
return result;
|
243
|
+
} else {
|
244
|
+
for (_i = 0, _len = rules.length; _i < _len; _i++) {
|
245
|
+
rule = rules[_i];
|
246
|
+
regex = rule[0], capture = rule[1];
|
247
|
+
if (result.match(regex)) {
|
248
|
+
result = result.replace(regex, capture);
|
249
|
+
break;
|
250
|
+
}
|
251
|
+
}
|
252
|
+
return result;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
};
|
641
256
|
|
642
|
-
|
257
|
+
return Inflections;
|
643
258
|
|
644
|
-
|
645
|
-
_s.lstrip = _s.ltrim;
|
646
|
-
_s.rstrip = _s.rtrim;
|
647
|
-
_s.center = _s.lrpad;
|
648
|
-
_s.rjust = _s.lpad;
|
649
|
-
_s.ljust = _s.rpad;
|
650
|
-
_s.contains = _s.include;
|
651
|
-
_s.q = _s.quote;
|
652
|
-
_s.toBool = _s.toBoolean;
|
259
|
+
})();
|
653
260
|
|
654
|
-
|
261
|
+
root = typeof exports !== "undefined" && exports !== null ? exports : this;
|
655
262
|
|
656
|
-
|
657
|
-
if (typeof exports !== 'undefined') {
|
658
|
-
if (typeof module !== 'undefined' && module.exports)
|
659
|
-
module.exports = _s;
|
263
|
+
_ = root._ || require('underscore');
|
660
264
|
|
661
|
-
|
265
|
+
if (typeof require !== "undefined" && require !== null) {
|
266
|
+
_.str = require('underscore.string');
|
267
|
+
_.mixin(_.str.exports());
|
268
|
+
_.str.include('Underscore.string', 'string');
|
269
|
+
} else {
|
270
|
+
_.mixin(_.str.exports());
|
662
271
|
}
|
663
272
|
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
273
|
+
if (typeof exports === 'undefined') {
|
274
|
+
_.mixin(new Inflections);
|
275
|
+
} else {
|
276
|
+
module.exports = new Inflections;
|
277
|
+
}
|
668
278
|
|
669
|
-
|
670
|
-
// or create our own underscore object.
|
671
|
-
root._ = root._ || {};
|
672
|
-
root._.string = root._.str = _s;
|
673
|
-
}(this, String);
|
279
|
+
}).call(this);
|