underscore-inflections-rails 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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