string_awesome 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/string_awesome/awesome_methods.rb +264 -0
- data/lib/string_awesome/version.rb +3 -0
- data/lib/string_awesome.rb +5 -0
- data/spec/awesome_methods_spec.rb +277 -0
- data/spec/spec_helper.rb +7 -0
- data/string_awesome.gemspec +28 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5d675469875aea4b7c4d6530e3047ab432fc6ce2
|
4
|
+
data.tar.gz: ecd620e210b9b26361c81d6db69bc20318edd2b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eb4a11e17dad5c39df691c91b6b43c50a385236495df4d2d768b56dc538d4f7b79b4565b9262e69360469e7961ef60b8b5f991051c577b2e90bbe6b07a17fb0c
|
7
|
+
data.tar.gz: 5901dc93bee876e56ef2c15a45f84aee79da423d72df5340480f7798dcda1f812315819e3d6d0e353197ad2bce4d80abdf4d22dfaa96d8070ec59ee9887fbbf0
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Tiago Guedes
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# StringAwesome
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'string_awesome'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install string_awesome
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,264 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'active_support/inflector'
|
4
|
+
require 'sanitize'
|
5
|
+
|
6
|
+
module StringAwesome
|
7
|
+
# These methods are all included into the String class.
|
8
|
+
module AwesomeMethods
|
9
|
+
# Replaces \n to <br /> tags.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# >> "Hello
|
13
|
+
# world!".nl2br
|
14
|
+
# => "Hello <br/ > world!"
|
15
|
+
|
16
|
+
def nl2br
|
17
|
+
self.gsub /\n/, '<br />'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Converts the string to the title style and prevents other
|
21
|
+
# letters in the middle of the word from being uppercase.
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
# >> 'loREm IPsuM DOLOR'.to_title
|
25
|
+
# => 'Lorem Ipsum Dolor'
|
26
|
+
|
27
|
+
def to_title
|
28
|
+
self.downcase.titleize
|
29
|
+
end
|
30
|
+
|
31
|
+
# Removes HTML tags from text.
|
32
|
+
#
|
33
|
+
# Example:
|
34
|
+
# >> '<h1><a href="http://somecoolurl.com">Aloha!</a></h1>'.strip_tags
|
35
|
+
# => 'Aloha!'
|
36
|
+
#
|
37
|
+
# Arguments:
|
38
|
+
# allow_whitespace: (Boolean)
|
39
|
+
# - Let it returns the replaced block HTML tags as whitespaces.
|
40
|
+
|
41
|
+
def strip_tags(allow_whitespace = false)
|
42
|
+
str = Sanitize.clean self
|
43
|
+
allow_whitespace ? str : str.strip
|
44
|
+
end
|
45
|
+
|
46
|
+
# Remove accents from words in the text.
|
47
|
+
#
|
48
|
+
# Example:
|
49
|
+
# >> 'lórem ipsùm dólor sìt ãmet!'.no_accents
|
50
|
+
# => 'lorem ipsum dolor sit amet!'
|
51
|
+
|
52
|
+
def no_accents
|
53
|
+
self.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, '').to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
# Parses text to a valid format for URL's.
|
57
|
+
#
|
58
|
+
# Example:
|
59
|
+
# >> 'Lórem IPSUM Dolor?'.slug
|
60
|
+
# => 'lorem-ipsum-dolor'
|
61
|
+
#
|
62
|
+
# Arguments:
|
63
|
+
# downcase: (Boolean)
|
64
|
+
# - If true, it will force the String to be in downcase.
|
65
|
+
|
66
|
+
def slug(downcase = true)
|
67
|
+
str = self.no_accents.gsub(/\W|_/, '-').gsub(/[-]{2,}/, '-').gsub(/^-|-$/, '').to_s
|
68
|
+
downcase ? str.downcase : str
|
69
|
+
end
|
70
|
+
|
71
|
+
# Append ellipsis to the text.
|
72
|
+
#
|
73
|
+
# Example:
|
74
|
+
# >> "It's a very loooooong text!".ellipsis 11
|
75
|
+
# => "It's a very..."
|
76
|
+
# >> "It's a very loooooong text!".ellipsis 8, after_a_word: true
|
77
|
+
# => "It's a..."
|
78
|
+
#
|
79
|
+
# Arguments:
|
80
|
+
# max_length: (Integer)
|
81
|
+
# - Indicates the max length expected, before ellipsis, for the result.
|
82
|
+
# options: (Hash)
|
83
|
+
# - Other options such as:
|
84
|
+
# - :html_encoded - If true, the ellipsis will be displayed in HTML encoded format: ….
|
85
|
+
# - :after_a_word - If true, the ellipsis will be displayed necessarily after a word.
|
86
|
+
|
87
|
+
def ellipsis(max_length = 0, options = {})
|
88
|
+
length = self.length
|
89
|
+
|
90
|
+
if length > 1 and max_length <= length
|
91
|
+
# Adjusts the max_length
|
92
|
+
max_length = (length / 2).round if max_length == 0
|
93
|
+
|
94
|
+
# Truncates the text according to the max_length
|
95
|
+
str = self[0...max_length]
|
96
|
+
|
97
|
+
# Defines how the ellipsis will be displayed
|
98
|
+
ellip = options[:html_encoded] == true ? '…' : '...'
|
99
|
+
|
100
|
+
# If ellipsis must be applied after a word
|
101
|
+
if options[:after_a_word] == true
|
102
|
+
words = str.split(/\s/)
|
103
|
+
words = words[0..words.length - 2] if words.length > 1
|
104
|
+
str = words.join(' ')
|
105
|
+
else
|
106
|
+
str = str.gsub(/\s+$/, '')
|
107
|
+
end
|
108
|
+
|
109
|
+
str + ellip
|
110
|
+
else
|
111
|
+
self
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Reverses a string by words, instead of reversing it by every character (String#reverse).
|
116
|
+
#
|
117
|
+
# Example:
|
118
|
+
# >> 'lorem ipsum dolor'.reverse_words
|
119
|
+
# => 'dolor ipsum lorem'
|
120
|
+
|
121
|
+
def reverse_words
|
122
|
+
self.split(/\s/).reverse.join(' ')
|
123
|
+
end
|
124
|
+
|
125
|
+
# Counts how many words there are in the string limited by the max_length value.
|
126
|
+
#
|
127
|
+
# Example:
|
128
|
+
# >> 'lorem ipsum dolor'.count_words
|
129
|
+
# => 3
|
130
|
+
# >> 'lorem ipsum dolor'.count_words 7
|
131
|
+
# => 1
|
132
|
+
# Arguments:
|
133
|
+
# max_length: (Integer)
|
134
|
+
# - References where it will stop counting words in the string.
|
135
|
+
|
136
|
+
def count_words(max_length = nil)
|
137
|
+
# No duplicated whitespaces
|
138
|
+
str = self.gsub(/[\s\W]+/, ' ')
|
139
|
+
# Counts words
|
140
|
+
count = (max_length ? str[0...max_length] : str).split(/\s/).count
|
141
|
+
# Checks whether the last word is really a word (must be followed by a whitespace)
|
142
|
+
count -= 1 unless !max_length or (str[max_length - 1] =~ /\s/) or (!(str[max_length - 1] =~ /\W/) and (str[max_length] =~ /\s/))
|
143
|
+
|
144
|
+
count
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns an Array with the N first words of a string.
|
148
|
+
#
|
149
|
+
# Example:
|
150
|
+
# >> 'lorem ipsum'.first_words
|
151
|
+
# => 'lorem ipsum'
|
152
|
+
# >> 'lorem ipsum dolor'.first_words 2
|
153
|
+
# => 'lorem ipsum'
|
154
|
+
# Arguments:
|
155
|
+
# amount: (Integer)
|
156
|
+
# - Indicates how many words it expects to ge
|
157
|
+
|
158
|
+
def first_words(amount = nil)
|
159
|
+
words = self.split(/[\s\W]+/)
|
160
|
+
amount ? words[0...amount] : words
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns the N last words of a string.
|
164
|
+
#
|
165
|
+
# Example:
|
166
|
+
# >> 'lorem ipsum'.last_words
|
167
|
+
# => 'lorem ipsum'
|
168
|
+
# >> 'lorem ipsum dolor'.last_words 2
|
169
|
+
# => 'ipsum dolor'
|
170
|
+
# Arguments:
|
171
|
+
# amount: (Integer)
|
172
|
+
# - Indicates how many words it expects to ge
|
173
|
+
|
174
|
+
def last_words(amount = nil)
|
175
|
+
words = self.split(/[\s\W]+/).reverse
|
176
|
+
(amount ? words[0...amount] : words).reverse
|
177
|
+
end
|
178
|
+
|
179
|
+
# Replaces all URL's in the text with HTML link tags
|
180
|
+
#
|
181
|
+
# Example:
|
182
|
+
# >> 'Awesome site: http://foobar.com'.linkify
|
183
|
+
# => 'Awesome site: <a href="http://foobar.com">http://foobar.com</a>'
|
184
|
+
# >> 'Awesome site: http://foobar.com'.linkify(class: 'link', truncate: 10)
|
185
|
+
# => 'Awesome site: <a href="http://foobar.com" class="link">http://foo...</a>'
|
186
|
+
# Arguments:
|
187
|
+
# options: (Hash)
|
188
|
+
# - Options for the link tag, such as:
|
189
|
+
# - :truncate - If set, it will truncate the URL displayed in the link tag
|
190
|
+
# and put an ellipsis according to the given length. It can
|
191
|
+
# be also a Hash of options:
|
192
|
+
# - :length - URL's new length.
|
193
|
+
# - :html_encoded - Ellipsis will be displayed as HTML encoded char.
|
194
|
+
# - :class - Value for "class" attribute: <a href="url" class="link">url</a>
|
195
|
+
# - :target - Value for "target" attribute: <a href="url" target="_blank">url</a>
|
196
|
+
|
197
|
+
def linkify(options = {})
|
198
|
+
self.gsub!(/\b(((ht|f)tp[s]?:\/\/)?([a-z0-9]+\.)?(?<!@)([a-z0-9\_\-]+)(\.[a-z]+)+([\?\/\:][a-z0-9_=%&@\?\.\/\-\:\#\(\)]+)?\/?)/i) do
|
199
|
+
displayed = match = $1
|
200
|
+
|
201
|
+
# Truncates the URL
|
202
|
+
if options[:truncate]
|
203
|
+
t = options[:truncate]
|
204
|
+
displayed = t.instance_of?(Hash) ? match.ellipsis(t[:length], html_encoded: t[:html_encoded]) : match.ellipsis(t)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Applies 'class' and 'target' options
|
208
|
+
if !options
|
209
|
+
options = ''
|
210
|
+
else
|
211
|
+
options = options.reduce ' ' do |s, v|
|
212
|
+
s << (v[0] == :truncate ? '' : "#{v[0]}=\"#{v[1]}\" ")
|
213
|
+
end.gsub(/\s+$/, '')
|
214
|
+
end
|
215
|
+
|
216
|
+
# Forces the presence of the 'http://'
|
217
|
+
match = "http://#{match}" unless match =~ /(ht|f)tp[s]?/i
|
218
|
+
|
219
|
+
"<a href=\"#{match}\"#{options}>#{displayed}</a>"
|
220
|
+
end
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
224
|
+
# Matches URL's, Twitter handles and hashtags putting them into HTML link tags.
|
225
|
+
#
|
226
|
+
# Example:
|
227
|
+
# >> 'What about to follow @tiagopog?'
|
228
|
+
# => 'What about to follow <a href="https://twitter.com/tiagopog" target="_blank" class="tt-handle">@tiagopog</a>?'
|
229
|
+
# >> "Let's code! #rubyrocks"
|
230
|
+
# => "Let's code! <a href=\"https://twitter.com/search?q=%23rubyrocks\" target=\"_blank\" class=\"hashtag\">#rubyrocks</a>"
|
231
|
+
# Arguments:
|
232
|
+
# options: (Hash)
|
233
|
+
# - Options such as:
|
234
|
+
# - :only - Array of Symbols restricting what will be matched on the text.
|
235
|
+
|
236
|
+
def tweetify(options = {})
|
237
|
+
# Applies linkify unless there's some restriction
|
238
|
+
only = options[:only]
|
239
|
+
str = only ? self : self.linkify(class: 'link')
|
240
|
+
|
241
|
+
# Stores the regex in a variable just to make it more readable
|
242
|
+
regex = /(((^#)([a-z0-9\_]+))|(([^a-z0-9\W]|\s)((#)([a-z0-9\_]+))))|(((^@)([a-z0-9\_]+))|(([^a-z0-9\W]|\s)((@)([a-z0-9\_]+))))/i
|
243
|
+
|
244
|
+
# Iterates with the matched expressions
|
245
|
+
str.gsub!(regex) do |match|
|
246
|
+
is_hashtag = match =~ /#/
|
247
|
+
|
248
|
+
if only and ([:hashtag, :tt_handle] != only.sort) and ((is_hashtag and !only.include?(:hashtag)) or (!is_hashtag and !only.include?(:tt_handle)))
|
249
|
+
match
|
250
|
+
else
|
251
|
+
match = match.strip
|
252
|
+
tt_url = 'https://twitter.com/'
|
253
|
+
tag = {
|
254
|
+
href: is_hashtag ? "#{tt_url}search?q=%23#{match.gsub(/#/, '')}" : "#{tt_url}#{match.gsub(/@/, '')}",
|
255
|
+
class: is_hashtag ? 'hashtag' : 'tt-handle'
|
256
|
+
}
|
257
|
+
|
258
|
+
" <a href=\"#{tag[:href]}\" target=\"_blank\" class=\"#{tag[:class]}\">#{match}</a>"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
str
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
#
|
6
|
+
# String#nl2br
|
7
|
+
#
|
8
|
+
describe 'String#nl2br' do
|
9
|
+
it 'should replace "\n" to "<br />"' do
|
10
|
+
"break\nrow".nl2br.should eq 'break<br />row'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should not replace "\n" to "<br />" when "\n" is literal' do
|
14
|
+
"\\no break row".nl2br.should_not eq '<br />o break row'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# String#to_title
|
20
|
+
#
|
21
|
+
describe 'String#to_title' do
|
22
|
+
it 'should format the text properly to looks like a title' do
|
23
|
+
"here's aN AWEsome TiTle!".to_title.should eq "Here's An Awesome Title!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# String#strip_tags
|
29
|
+
#
|
30
|
+
describe 'String#strip_tags' do
|
31
|
+
it 'should remove any HTML tag from a given text' do
|
32
|
+
'<h1><a href="http://somecoolurl.com">Aloha!</a></h1>'.strip_tags.should eq 'Aloha!'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should remove by default the whitespaces that were allocated in place of HTML tags' do
|
36
|
+
'<h1>no whitespaces</h1>'.strip_tags.should eq 'no whitespaces'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should not remove the whitespaces that were allocated in place of HTML tags, when required' do
|
40
|
+
'<h1>whitespaces</h1>'.strip_tags(true).should eq ' whitespaces '
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# String#no_accents
|
46
|
+
#
|
47
|
+
describe 'String#no_accents' do
|
48
|
+
it 'should remove accents from words in the text' do
|
49
|
+
'lórem ipsùm dólor sìt ãmet!'.no_accents.should eq 'lorem ipsum dolor sit amet!'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# String#slug
|
55
|
+
#
|
56
|
+
describe 'String#slug' do
|
57
|
+
it 'should parse the text to an URL valid format, downcase by default' do
|
58
|
+
'Lorem IPSUM Dolor?'.slug.should eq 'lorem-ipsum-dolor'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should parse the text to an URL valid format without forcing it to downcase' do
|
62
|
+
'Lorem Ipsum Dolor 2013!'.slug(false).should eq 'Lorem-Ipsum-Dolor-2013'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# String#ellipsis
|
68
|
+
#
|
69
|
+
describe 'String#ellipsis' do
|
70
|
+
it "shoud not append ellipsis when String's length is less then 2" do
|
71
|
+
'l'.ellipsis.should eq 'l'
|
72
|
+
end
|
73
|
+
|
74
|
+
it "shoud not have the max_length value greater than text's length" do
|
75
|
+
'foo'.ellipsis(10).should eq 'foo'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should append ellipsis in the text's half length (default behaviour)" do
|
79
|
+
'lorem ipsum!'.ellipsis.should eq 'lorem...'
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should append ellipsis in the text's rounded half length when the number of characters is odd (default behaviour)" do
|
83
|
+
'lorem ipsum'.ellipsis.should eq 'lorem...'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should append the HTML encoded ellipsis in the text" do
|
87
|
+
'lorem ipsum'.ellipsis(5, html_encoded: true).should eq 'lorem…'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not append the HTML encoded ellipsis in the text when it's not required" do
|
91
|
+
'lorem ipsum'.ellipsis(5, html_encoded: false).should_not eq 'lorem…'
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should append ellipsis after a word' do
|
95
|
+
'lorem ipsum dolor'.ellipsis(14, after_a_word: true).should eq 'lorem ipsum...'
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should append the HTML encoded ellipsis after a word' do
|
99
|
+
'lorem ipsum dolor'.ellipsis(13, html_encoded: true, after_a_word: true).should eq 'lorem ipsum…'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# String#reverse_words
|
105
|
+
#
|
106
|
+
describe 'String#reverse_words' do
|
107
|
+
it 'should reverse a string by words' do
|
108
|
+
'lorem ipsum dolor'.reverse_words.should eq 'dolor ipsum lorem'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# String#count_words
|
114
|
+
#
|
115
|
+
describe 'String#count_words' do
|
116
|
+
it 'should count how many words there are in the string' do
|
117
|
+
'lorem ipsum dolor'.count_words.should eq 3
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should count how many words there are in the string limited by the max_length value (whitespace test)' do
|
121
|
+
'lorem ipsum dolor'.count_words(6).should eq 1
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should count how many words there are in the string limited by the max_length value (splitted word, test 1)' do
|
125
|
+
'lorem ipsum dolor'.count_words(7).should eq 1
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should count how many words there are in the string limited by the max_length value (splitted word, test 2)' do
|
129
|
+
'lorem ipsum dolor'.count_words(8).should eq 1
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should not condiser a non-word character (!) as a word' do
|
133
|
+
'lorem ipsum ! dolor'.count_words.should eq 3
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should not condiser a non-word character (!) as a word' do
|
137
|
+
'lorem ipsum ! dolor'.count_words(13).should eq 2
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# String#first_words
|
143
|
+
#
|
144
|
+
describe 'String#first_words' do
|
145
|
+
it 'should return all the words when the amount is not passed' do
|
146
|
+
'lorem ipsum dolor'.first_words.should eq ['lorem', 'ipsum', 'dolor']
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should return only the 2 first words (Array)' do
|
150
|
+
'lorem. ! ipsum dolor'.first_words(2).should eq ['lorem', 'ipsum']
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# String#last_words
|
156
|
+
#
|
157
|
+
describe 'String#last_words' do
|
158
|
+
it 'should return all the words when the amount is not passed' do
|
159
|
+
'lorem ipsum dolor'.last_words.should eq ['lorem', 'ipsum', 'dolor']
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should return only the 2 last words (Array)' do
|
163
|
+
'lorem. ! ipsum dolor'.first_words(2).should eq ['lorem', 'ipsum']
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# String#linkify
|
169
|
+
#
|
170
|
+
describe 'String#linkify' do
|
171
|
+
it "should replace all the URL's in the text with HTML link tags" do
|
172
|
+
str = 'Awesome site: http://foobar.com'
|
173
|
+
this = 'Awesome site: <a href="http://foobar.com">http://foobar.com</a>'
|
174
|
+
str.linkify.should eq this
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'can set the "class" HTML attribute to be applied on the link tag' do
|
178
|
+
str = 'Awesome site: http://foobar.com'
|
179
|
+
this = 'Awesome site: <a href="http://foobar.com" class="link">http://foobar.com</a>'
|
180
|
+
str.linkify(class: 'link').should eq this
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'can set the "target" HTML attribute to be applied on the link tag' do
|
184
|
+
str = 'Awesome site: http://foobar.com'
|
185
|
+
this = 'Awesome site: <a href="http://foobar.com" target="_blank">http://foobar.com</a>'
|
186
|
+
str.linkify(target: '_blank').should eq this
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'can set the class and target HTML attributes to be applied on the link tag' do
|
190
|
+
str = 'Awesome site: http://foobar.com'
|
191
|
+
this = 'Awesome site: <a href="http://foobar.com" class="link" target="_blank">http://foobar.com</a>'
|
192
|
+
str.linkify(class: 'link', target: '_blank').should eq this
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'can truncate the URL displayed whithin the link tag (Interger param)' do
|
196
|
+
str = 'Awesome site: http://foobar.com'
|
197
|
+
this = 'Awesome site: <a href="http://foobar.com">http://foo...</a>'
|
198
|
+
str.linkify(truncate: 10).should eq this
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'can truncate the URL displayed whithin the link tag (Hash param)' do
|
202
|
+
str = 'Awesome site: http://foobar.com'
|
203
|
+
this = 'Awesome site: <a href="http://foobar.com">http://foo…</a>'
|
204
|
+
str.linkify(truncate: { length: 10, html_encoded: true }).should eq this
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'can set HTML attributes and truncate the URL' do
|
208
|
+
str = 'Awesome site: http://foobar.com'
|
209
|
+
this = 'Awesome site: <a href="http://foobar.com" class="link">http://foo...</a>'
|
210
|
+
str.linkify(class: 'link', truncate: 10).should eq this
|
211
|
+
end
|
212
|
+
|
213
|
+
it "matches URL's without the presence of 'http://' but presenting 'www'" do
|
214
|
+
'www.foobar.com'.linkify.should eq '<a href="http://www.foobar.com">www.foobar.com</a>'
|
215
|
+
end
|
216
|
+
|
217
|
+
it "matches URL's without the presence of 'http://' and 'www'" do
|
218
|
+
'foobar.com'.linkify.should eq '<a href="http://foobar.com">foobar.com</a>'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
#
|
223
|
+
# String#tweetify
|
224
|
+
#
|
225
|
+
describe 'String#tweetify' do
|
226
|
+
it 'should match Twitter handles (@username) and replace them into HTML link tags' do
|
227
|
+
str = 'What about to follow @tiagopog?'
|
228
|
+
this = 'What about to follow <a href="https://twitter.com/tiagopog" target="_blank" class="tt-handle">@tiagopog</a>?'
|
229
|
+
str.tweetify.should eq this
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'should not match foo@bar as being a Twitter handle' do
|
233
|
+
str = 'foo@bar'
|
234
|
+
str.tweetify.should eq str
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should match hashtags (#hashtag) and replace them into HTML link tags' do
|
238
|
+
str = "Let's code! #rubyrocks"
|
239
|
+
this = "Let's code! <a href=\"https://twitter.com/search?q=%23rubyrocks\" target=\"_blank\" class=\"hashtag\">#rubyrocks</a>"
|
240
|
+
str.tweetify.should eq this
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should not match foo#bar as being a hashtag' do
|
244
|
+
str = 'foo#bar'
|
245
|
+
str.tweetify.should eq str
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should match URL's and replace them into HTML link tags" do
|
249
|
+
str = 'Tweet some cool link: http://foobar.com'
|
250
|
+
this = 'Tweet some cool link: <a href="http://foobar.com" class="link">http://foobar.com</a>'
|
251
|
+
str.tweetify.should eq this
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should match links, Twitter handles, hashtags and replace them into HTML link tags' do
|
255
|
+
str = 'Cool link from @tiagopog! http://foobar.com #rubyrocks'
|
256
|
+
this = 'Cool link from <a href="https://twitter.com/tiagopog" target="_blank" class="tt-handle">@tiagopog</a>! <a href="http://foobar.com" class="link">http://foobar.com</a> <a href="https://twitter.com/search?q=%23rubyrocks" target="_blank" class="hashtag">#rubyrocks</a>'
|
257
|
+
str.tweetify.should eq this
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'should match only Twitter handles' do
|
261
|
+
str = 'Cool link from @tiagopog! http://foobar.com #rubyrocks'
|
262
|
+
this = 'Cool link from <a href="https://twitter.com/tiagopog" target="_blank" class="tt-handle">@tiagopog</a>! http://foobar.com #rubyrocks'
|
263
|
+
str.tweetify(only: [:tt_handle]).should eq this
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should match only hashtags' do
|
267
|
+
str = 'Cool link from @tiagopog! http://foobar.com #rubyrocks'
|
268
|
+
this = 'Cool link from @tiagopog! http://foobar.com <a href="https://twitter.com/search?q=%23rubyrocks" target="_blank" class="hashtag">#rubyrocks</a>'
|
269
|
+
str.tweetify(only: [:hashtag]).should eq this
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should not match URL's, just hashtags and Twitter handles" do
|
273
|
+
str = 'Cool link from @tiagopog! http://foobar.com #rubyrocks'
|
274
|
+
this = 'Cool link from <a href="https://twitter.com/tiagopog" target="_blank" class="tt-handle">@tiagopog</a>! http://foobar.com <a href="https://twitter.com/search?q=%23rubyrocks" target="_blank" class="hashtag">#rubyrocks</a>'
|
275
|
+
str.tweetify(only: [:hashtag, :tt_handle]).should eq this
|
276
|
+
end
|
277
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'string_awesome/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'string_awesome'
|
8
|
+
spec.version = StringAwesome::VERSION
|
9
|
+
spec.authors = ['Tiago Guedes']
|
10
|
+
spec.email = ['tiagopog@gmail.com']
|
11
|
+
spec.description = %q{Awesome and easy-to-use extensions to Ruby String class.}
|
12
|
+
spec.summary = %q{Extensions for Ruby String class}
|
13
|
+
spec.homepage = 'https://github.com/tiagopog/string_awesome'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'activesupport', ['>= 3.0', '< 5.0']
|
22
|
+
spec.add_runtime_dependency 'sanitize', '~> 2.0'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'escape_utils', '~> 1.0'
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
27
|
+
spec.add_development_dependency 'rake'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: string_awesome
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tiago Guedes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
- - <
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- - <
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: sanitize
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: escape_utils
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: bundler
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.3'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ~>
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.3'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rake
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
description: Awesome and easy-to-use extensions to Ruby String class.
|
104
|
+
email:
|
105
|
+
- tiagopog@gmail.com
|
106
|
+
executables: []
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- .gitignore
|
111
|
+
- Gemfile
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- lib/string_awesome.rb
|
116
|
+
- lib/string_awesome/awesome_methods.rb
|
117
|
+
- lib/string_awesome/version.rb
|
118
|
+
- spec/awesome_methods_spec.rb
|
119
|
+
- spec/spec_helper.rb
|
120
|
+
- string_awesome.gemspec
|
121
|
+
homepage: https://github.com/tiagopog/string_awesome
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 2.1.5
|
142
|
+
signing_key:
|
143
|
+
specification_version: 4
|
144
|
+
summary: Extensions for Ruby String class
|
145
|
+
test_files:
|
146
|
+
- spec/awesome_methods_spec.rb
|
147
|
+
- spec/spec_helper.rb
|