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: 8460fbb659c42d3a202edad123a3baa4ff8f7c50
4
- data.tar.gz: 0868b31bef4c9f0ae7629cfde753a470009b2b50
3
+ metadata.gz: a54f9ac3cd1312a5274c18d7dbb3d8998a7760a7
4
+ data.tar.gz: 15f0a398fead42586171331c2f6bc45819e4f6eb
5
5
  SHA512:
6
- metadata.gz: 8dc5f6e055baa189b2c0908dd3991a899621c2029859e6d36f458bbd6ef96a887523c8b021f3c2cb84d9c7f5b3f2fba84fbad99af727ff4819ceef6e3558ae96
7
- data.tar.gz: 785031163ab07de61b4ebb5eeb9009c2b8a929d1430c1f1ca0fad00066af6d45e2e87f235bb28466075f3fc0d9f3d6a81ce913395f5fe042fb36db597ea83e44
6
+ metadata.gz: 7705efdb64ddc54184b198948b91ee9180eb482ac4f5b9e6fd4174a290d152516af1c6dfef2057ea4ca464e93bdf8df76ac61f13bb3165e2b487f0cd658e090d
7
+ data.tar.gz: 51ae2c1f03e618aabba94dfb9d28b751f91e1daedc52fa8f815b14a0b5e144a5dc9c5a6e923d3b713f331c7ce7900d73d046ad5df41bbb27c84709ff25c23ea9
@@ -1,7 +1,7 @@
1
1
  module Underscore
2
2
  module Inflections
3
3
  module Rails
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
6
6
  end
7
7
  end
@@ -1,673 +1,279 @@
1
- // Underscore.string
2
- // (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
3
- // Underscore.string is freely distributable under the terms of the MIT license.
4
- // Documentation: https://github.com/epeli/underscore.string
5
- // Some code is borrowed from MooTools and Alexandru Marasteanu.
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
- var str_format = function() {
78
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
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
- return str_format;
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
- // Defining underscore.string
16
+ Inflections.prototype.defaultHumanRules = [];
189
17
 
190
- var _s = {
18
+ function Inflections() {
19
+ this.apply_inflections = __bind(this.apply_inflections, this);
191
20
 
192
- VERSION: '2.3.0',
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
- isBlank: function(str){
195
- if (str == null) str = '';
196
- return (/^\s*$/).test(str);
197
- },
27
+ this.pluralize = __bind(this.pluralize, this);
198
28
 
199
- stripTags: function(str){
200
- if (str == null) return '';
201
- return String(str).replace(/<\/?[^>]+>/g, '');
202
- },
29
+ this.clearInflections = __bind(this.clearInflections, this);
203
30
 
204
- capitalize : function(str){
205
- str = str == null ? '' : String(str);
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
- chop: function(str, step){
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
- clean: function(str){
217
- return _s.strip(str).replace(/\s+/g, ' ');
218
- },
36
+ this.singular = __bind(this.singular, this);
219
37
 
220
- count: function(str, substr){
221
- if (str == null || substr == null) return 0;
38
+ this.plural = __bind(this.plural, this);
222
39
 
223
- str = String(str);
224
- substr = String(substr);
40
+ this.acronym = __bind(this.acronym, this);
41
+ this.applyDefaultPlurals = __bind(this.applyDefaultPlurals, this);
225
42
 
226
- var count = 0,
227
- pos = 0,
228
- length = substr.length;
43
+ this.applyDefaultUncountables = __bind(this.applyDefaultUncountables, this);
229
44
 
230
- while (true) {
231
- pos = str.indexOf(substr, pos);
232
- if (pos === -1) break;
233
- count++;
234
- pos += length;
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
- return count;
238
- },
54
+ Inflections.prototype.applyDefaultRules = function() {
55
+ this.applyDefaultUncountables();
56
+ this.applyDefaultPlurals();
57
+ this.applyDefaultSingulars();
58
+ return this.applyDefaultIrregulars();
59
+ };
239
60
 
240
- chars: function(str) {
241
- if (str == null) return [];
242
- return String(str).split('');
243
- },
61
+ Inflections.prototype.applyDefaultUncountables = function() {
62
+ return this.uncountable(this.defaultUncountables);
63
+ };
244
64
 
245
- swapCase: function(str) {
246
- if (str == null) return '';
247
- return String(str).replace(/\S/g, function(c){
248
- return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase();
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
- quote: function(str, quoteChar) {
543
- return _s.surround(str, quoteChar || '"');
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
- unquote: function(str, quoteChar) {
547
- quoteChar = quoteChar || '"';
548
- if (str[0] === quoteChar && str[str.length-1] === quoteChar)
549
- return str.slice(1,str.length-1);
550
- else return str;
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
- exports: function() {
554
- var result = {};
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
- for (var prop in this) {
557
- if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue;
558
- result[prop] = this[prop];
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
- return result;
562
- },
563
-
564
- repeat: function(str, qty, separator){
565
- if (str == null) return '';
566
-
567
- qty = ~~qty;
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
- // this one is about 300x slower in Google Chrome
573
- for (var repeat = []; qty > 0; repeat[--qty] = str) {}
574
- return repeat.join(separator);
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
- naturalCmp: function(str1, str2){
578
- if (str1 == str2) return 0;
579
- if (!str1) return -1;
580
- if (!str2) return 1;
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
- var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g,
583
- tokens1 = String(str1).toLowerCase().match(cmpRegex),
584
- tokens2 = String(str2).toLowerCase().match(cmpRegex),
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
- for(var i = 0; i < count; i++) {
588
- var a = tokens1[i], b = tokens2[i];
141
+ Inflections.prototype.clearInflections = function(scope) {
142
+ if (scope == null) {
143
+ scope = 'all';
144
+ }
145
+ return this[scope] = [];
146
+ };
589
147
 
590
- if (a !== b){
591
- var num1 = parseInt(a, 10);
592
- if (!isNaN(num1)){
593
- var num2 = parseInt(b, 10);
594
- if (!isNaN(num2) && num1 - num2)
595
- return num1 - num2;
596
- }
597
- return a < b ? -1 : 1;
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
- if (tokens1.length === tokens2.length)
602
- return tokens1.length - tokens2.length;
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
- var current = [], prev, value;
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
- for (var i = 0; i <= str2.length; i++)
617
- for (var j = 0; j <= str1.length; j++) {
618
- if (i && j)
619
- if (str1.charAt(j - 1) === str2.charAt(i - 1))
620
- value = prev;
621
- else
622
- value = Math.min(current[j], current[j - 1], prev) + 1;
623
- else
624
- value = i + j;
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
- prev = current[j];
627
- current[j] = value;
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
- return current.pop();
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
- toBoolean: function(str, trueValues, falseValues) {
634
- if (typeof str === "number") str = "" + str;
635
- if (typeof str !== "string") return !!str;
636
- str = _s.trim(str);
637
- if (boolMatch(str, trueValues || ["true", "1"])) return true;
638
- if (boolMatch(str, falseValues || ["false", "0"])) return false;
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
- // Aliases
257
+ return Inflections;
643
258
 
644
- _s.strip = _s.trim;
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
- // Exporting
261
+ root = typeof exports !== "undefined" && exports !== null ? exports : this;
655
262
 
656
- // CommonJS module is defined
657
- if (typeof exports !== 'undefined') {
658
- if (typeof module !== 'undefined' && module.exports)
659
- module.exports = _s;
263
+ _ = root._ || require('underscore');
660
264
 
661
- exports._s = _s;
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
- // Register as a named module with AMD.
665
- if (typeof define === 'function' && define.amd)
666
- define('underscore.string', [], function(){ return _s; });
667
-
273
+ if (typeof exports === 'undefined') {
274
+ _.mixin(new Inflections);
275
+ } else {
276
+ module.exports = new Inflections;
277
+ }
668
278
 
669
- // Integrate with Underscore.js if defined
670
- // or create our own underscore object.
671
- root._ = root._ || {};
672
- root._.string = root._.str = _s;
673
- }(this, String);
279
+ }).call(this);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: underscore-inflections-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Vonderscher