underscore-string-set-rails 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3e1338756b86e598e1f915f75d571c64ad0b3fc6
4
+ data.tar.gz: bc036696acdb639ab5b371dbd5cb5c0868bc110e
5
+ SHA512:
6
+ metadata.gz: 176422d9435b9d77ebb99663a9fbacca7048999b877b232ccb5dd155c7137bd6a616ca7a16a6411b0030c7a8bb1376e2984c22f68f501bd5694206f70087fc31
7
+ data.tar.gz: 198a259594b9d8bfa1d039e44cd864628b947fa69e5d36490ac935c1c90a676486e4c97c8cb6fbf64ffb87d726cd8293dea0af1045e15ae816ecf5f07b538046
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ test/dummy/db/*.sqlite3
5
+ test/dummy/db/*.sqlite3-journal
6
+ test/dummy/log/*.log
7
+ test/dummy/tmp/
8
+ test/dummy/.sass-cache
9
+ .idea
10
+ .idea/*
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,93 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ underscore-string-set-rails (0.0.4)
5
+ rails (>= 3.2)
6
+ railties (>= 3.0)
7
+ underscore-rails (~> 1.6.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionmailer (4.1.0)
13
+ actionpack (= 4.1.0)
14
+ actionview (= 4.1.0)
15
+ mail (~> 2.5.4)
16
+ actionpack (4.1.0)
17
+ actionview (= 4.1.0)
18
+ activesupport (= 4.1.0)
19
+ rack (~> 1.5.2)
20
+ rack-test (~> 0.6.2)
21
+ actionview (4.1.0)
22
+ activesupport (= 4.1.0)
23
+ builder (~> 3.1)
24
+ erubis (~> 2.7.0)
25
+ activemodel (4.1.0)
26
+ activesupport (= 4.1.0)
27
+ builder (~> 3.1)
28
+ activerecord (4.1.0)
29
+ activemodel (= 4.1.0)
30
+ activesupport (= 4.1.0)
31
+ arel (~> 5.0.0)
32
+ activesupport (4.1.0)
33
+ i18n (~> 0.6, >= 0.6.9)
34
+ json (~> 1.7, >= 1.7.7)
35
+ minitest (~> 5.1)
36
+ thread_safe (~> 0.1)
37
+ tzinfo (~> 1.1)
38
+ arel (5.0.1.20140414130214)
39
+ builder (3.2.2)
40
+ erubis (2.7.0)
41
+ hike (1.2.3)
42
+ i18n (0.6.9)
43
+ json (1.8.1)
44
+ mail (2.5.4)
45
+ mime-types (~> 1.16)
46
+ treetop (~> 1.4.8)
47
+ mime-types (1.25.1)
48
+ minitest (5.3.3)
49
+ multi_json (1.9.2)
50
+ polyglot (0.3.4)
51
+ rack (1.5.2)
52
+ rack-test (0.6.2)
53
+ rack (>= 1.0)
54
+ rails (4.1.0)
55
+ actionmailer (= 4.1.0)
56
+ actionpack (= 4.1.0)
57
+ actionview (= 4.1.0)
58
+ activemodel (= 4.1.0)
59
+ activerecord (= 4.1.0)
60
+ activesupport (= 4.1.0)
61
+ bundler (>= 1.3.0, < 2.0)
62
+ railties (= 4.1.0)
63
+ sprockets-rails (~> 2.0)
64
+ railties (4.1.0)
65
+ actionpack (= 4.1.0)
66
+ activesupport (= 4.1.0)
67
+ rake (>= 0.8.7)
68
+ thor (>= 0.18.1, < 2.0)
69
+ rake (10.3.1)
70
+ sprockets (2.12.1)
71
+ hike (~> 1.2)
72
+ multi_json (~> 1.0)
73
+ rack (~> 1.0)
74
+ tilt (~> 1.1, != 1.3.0)
75
+ sprockets-rails (2.1.3)
76
+ actionpack (>= 3.0)
77
+ activesupport (>= 3.0)
78
+ sprockets (~> 2.8)
79
+ thor (0.19.1)
80
+ thread_safe (0.3.3)
81
+ tilt (1.4.1)
82
+ treetop (1.4.15)
83
+ polyglot
84
+ polyglot (>= 0.3.1)
85
+ tzinfo (1.1.0)
86
+ thread_safe (~> 0.1)
87
+ underscore-rails (1.6.0)
88
+
89
+ PLATFORMS
90
+ ruby
91
+
92
+ DEPENDENCIES
93
+ underscore-string-set-rails!
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Alexander Gorbunov (lexgorbunov@gmail.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # underscore-string-set-rails
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/underscore-string-set-rails.svg)](http://badge.fury.io/rb/underscore-string-set-rails)
4
+ [![Code Climate](https://codeclimate.com/github/lexgorbunov/underscore-string-set-rails.png)](https://codeclimate.com/github/lexgorbunov/underscore-string-set-rails)
5
+ [![Dependency Status](https://gemnasium.com/lexgorbunov/underscore-string-set-rails.svg)](https://gemnasium.com/lexgorbunov/underscore-string-set-rails)
6
+
7
+ Гем включает в себя underscore-js и underscore.string. При этом underscore-js расширена функциями underscore.string
8
+ при помощи .mixin. Доступ к функциям обоих библиотек осуществляется через ```_```
9
+
10
+ This gem is combination of two libraries: underscore-js and underscore.string. The underscore-js extended via mixin.
11
+
12
+ ## Установка (Installation)
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'underscore-string-set-rails'
17
+
18
+ And then execute:
19
+
20
+ $ bundle install
21
+
22
+ Add this line to your application.js
23
+
24
+ //= require underscore-string-set-rails
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'UnderscoreStringSetRails'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,3 @@
1
+ //= require underscore
2
+ //= require ./underscore.string
3
+ _.mixin(_.string.exports())
@@ -0,0 +1,673 @@
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.3'
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;
76
+
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
+ };
182
+
183
+ return str_format;
184
+ })();
185
+
186
+
187
+
188
+ // Defining underscore.string
189
+
190
+ var _s = {
191
+
192
+ VERSION: '2.3.0',
193
+
194
+ isBlank: function(str){
195
+ if (str == null) str = '';
196
+ return (/^\s*$/).test(str);
197
+ },
198
+
199
+ stripTags: function(str){
200
+ if (str == null) return '';
201
+ return String(str).replace(/<\/?[^>]+>/g, '');
202
+ },
203
+
204
+ capitalize : function(str){
205
+ str = str == null ? '' : String(str);
206
+ return str.charAt(0).toUpperCase() + str.slice(1);
207
+ },
208
+
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
+ },
215
+
216
+ clean: function(str){
217
+ return _s.strip(str).replace(/\s+/g, ' ');
218
+ },
219
+
220
+ count: function(str, substr){
221
+ if (str == null || substr == null) return 0;
222
+
223
+ str = String(str);
224
+ substr = String(substr);
225
+
226
+ var count = 0,
227
+ pos = 0,
228
+ length = substr.length;
229
+
230
+ while (true) {
231
+ pos = str.indexOf(substr, pos);
232
+ if (pos === -1) break;
233
+ count++;
234
+ pos += length;
235
+ }
236
+
237
+ return count;
238
+ },
239
+
240
+ chars: function(str) {
241
+ if (str == null) return [];
242
+ return String(str).split('');
243
+ },
244
+
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
+ }
271
+ });
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
+ },
541
+
542
+ quote: function(str, quoteChar) {
543
+ return _s.surround(str, quoteChar || '"');
544
+ },
545
+
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
+ },
552
+
553
+ exports: function() {
554
+ var result = {};
555
+
556
+ for (var prop in this) {
557
+ if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue;
558
+ result[prop] = this[prop];
559
+ }
560
+
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);
571
+
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
+ },
576
+
577
+ naturalCmp: function(str1, str2){
578
+ if (str1 == str2) return 0;
579
+ if (!str1) return -1;
580
+ if (!str2) return 1;
581
+
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);
586
+
587
+ for(var i = 0; i < count; i++) {
588
+ var a = tokens1[i], b = tokens2[i];
589
+
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;
598
+ }
599
+ }
600
+
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);
613
+
614
+ var current = [], prev, value;
615
+
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;
625
+
626
+ prev = current[j];
627
+ current[j] = value;
628
+ }
629
+
630
+ return current.pop();
631
+ },
632
+
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
+ };
641
+
642
+ // Aliases
643
+
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;
653
+
654
+ // Exporting
655
+
656
+ // CommonJS module is defined
657
+ if (typeof exports !== 'undefined') {
658
+ if (typeof module !== 'undefined' && module.exports)
659
+ module.exports = _s;
660
+
661
+ exports._s = _s;
662
+ }
663
+
664
+ // Register as a named module with AMD.
665
+ if (typeof define === 'function' && define.amd)
666
+ define('underscore.string', [], function(){ return _s; });
667
+
668
+
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);
@@ -0,0 +1,5 @@
1
+ module UnderscoreStringSetRails
2
+ class Engine < ::Rails::Engine
3
+ require 'underscore-rails'
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module UnderscoreStringSetRails
2
+ VERSION = '0.0.4'
3
+ end
@@ -0,0 +1,21 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'underscore-string-set-rails/version'
3
+ Gem::Specification.new do |s|
4
+ s.name = 'underscore-string-set-rails'
5
+ s.version = UnderscoreStringSetRails::VERSION
6
+ s.authors = %w(Alexander\ Gorbunov)
7
+ s.email = %w(lexgorbunov@gmail.com)
8
+ s.homepage = 'https://github.com/lexgorbunov/underscore-string-set-rails'
9
+ s.summary = 'This gem is combination of two libraries: underscore and underscorejs.'
10
+ s.description = 'This gem is combination of two libraries: underscore and underscorejs. The underscorejs extended via mixin. (underscore v1.6.0; underscore.string v2.3.3)'
11
+
12
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+
16
+ s.add_dependency 'rails', '>= 3.2'
17
+ s.add_dependency 'railties', '>= 3.0'
18
+ s.add_dependency 'underscore-rails', '~> 1.6.0'
19
+
20
+ s.require_paths = %w(lib)
21
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: underscore-string-set-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Gorbunov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: railties
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: underscore-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.0
55
+ description: 'This gem is combination of two libraries: underscore and underscorejs.
56
+ The underscorejs extended via mixin. (underscore v1.6.0; underscore.string v2.3.3)'
57
+ email:
58
+ - lexgorbunov@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - MIT-LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - app/assets/javascripts/underscore-string-set-rails.js
70
+ - app/assets/javascripts/underscore.string.js
71
+ - lib/underscore-string-set-rails.rb
72
+ - lib/underscore-string-set-rails/version.rb
73
+ - underscore-string-set-rails.gemspec
74
+ homepage: https://github.com/lexgorbunov/underscore-string-set-rails
75
+ licenses: []
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.1.11
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: 'This gem is combination of two libraries: underscore and underscorejs.'
97
+ test_files: []