string_awesome 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|