string_master 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +55 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +39 -0
- data/Rakefile +44 -0
- data/VERSION +1 -0
- data/config/languages_syntax_list +158 -0
- data/lib/string_master/string_master.rb +142 -0
- data/lib/string_master/string_master_proxy.rb +26 -0
- data/lib/string_master.rb +2 -0
- data/spec/lib/string_master/string_master_proxy_spec.rb +13 -0
- data/spec/lib/string_master/string_master_spec.rb +82 -0
- data/spec/spec_helper.rb +4 -0
- data/string_master.gemspec +67 -0
- metadata +124 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
abstract (1.0.0)
|
5
|
+
actionpack (3.0.9)
|
6
|
+
activemodel (= 3.0.9)
|
7
|
+
activesupport (= 3.0.9)
|
8
|
+
builder (~> 2.1.2)
|
9
|
+
erubis (~> 2.6.6)
|
10
|
+
i18n (~> 0.5.0)
|
11
|
+
rack (~> 1.2.1)
|
12
|
+
rack-mount (~> 0.6.14)
|
13
|
+
rack-test (~> 0.5.7)
|
14
|
+
tzinfo (~> 0.3.23)
|
15
|
+
activemodel (3.0.9)
|
16
|
+
activesupport (= 3.0.9)
|
17
|
+
builder (~> 2.1.2)
|
18
|
+
i18n (~> 0.5.0)
|
19
|
+
activesupport (3.0.9)
|
20
|
+
builder (2.1.2)
|
21
|
+
diff-lcs (1.1.2)
|
22
|
+
erubis (2.6.6)
|
23
|
+
abstract (>= 1.0.0)
|
24
|
+
git (1.2.5)
|
25
|
+
i18n (0.5.0)
|
26
|
+
jeweler (1.6.2)
|
27
|
+
bundler (~> 1.0)
|
28
|
+
git (>= 1.2.5)
|
29
|
+
rake
|
30
|
+
rack (1.2.3)
|
31
|
+
rack-mount (0.6.14)
|
32
|
+
rack (>= 1.0.0)
|
33
|
+
rack-test (0.5.7)
|
34
|
+
rack (>= 1.0)
|
35
|
+
rake (0.9.2)
|
36
|
+
rcov (0.9.9)
|
37
|
+
rspec (2.6.0)
|
38
|
+
rspec-core (~> 2.6.0)
|
39
|
+
rspec-expectations (~> 2.6.0)
|
40
|
+
rspec-mocks (~> 2.6.0)
|
41
|
+
rspec-core (2.6.4)
|
42
|
+
rspec-expectations (2.6.0)
|
43
|
+
diff-lcs (~> 1.1.2)
|
44
|
+
rspec-mocks (2.6.0)
|
45
|
+
tzinfo (0.3.28)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
actionpack
|
52
|
+
bundler
|
53
|
+
jeweler
|
54
|
+
rcov
|
55
|
+
rspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Roman Snitko
|
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.markdown
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
StringMaster
|
2
|
+
======
|
3
|
+
|
4
|
+
*Most common string manipulations for a webapp*
|
5
|
+
|
6
|
+
Why bother?
|
7
|
+
-----------------------
|
8
|
+
Because every time I create a new webapp, I think about how I should process user-generated content. Should convert urls to links and images? Should I allow certain tags? Should I convert all new lines to <br/> tags? Well, now all that is as simple as calling a single method.
|
9
|
+
|
10
|
+
INSTALLATION
|
11
|
+
------------
|
12
|
+
|
13
|
+
1. gem install string_master
|
14
|
+
2. gem install ultraviolet (optional, if you want code highliting feature, only works in ruby 1.8.x)
|
15
|
+
|
16
|
+
Usage
|
17
|
+
---------------
|
18
|
+
|
19
|
+
Say you got this string
|
20
|
+
|
21
|
+
s = "Hello, glorious owner of the website\nI hope <you> like my message"
|
22
|
+
|
23
|
+
Oh my god, what am I going to do with it?
|
24
|
+
|
25
|
+
# try this
|
26
|
+
s.prep.newlines_to_br.html_escape
|
27
|
+
# which is equivalent to this (block notation)
|
28
|
+
s.prep { |s| s.newlines_to_br; s.html_escape }
|
29
|
+
|
30
|
+
|
31
|
+
Result:
|
32
|
+
|
33
|
+
Hello, glorious owner of the website\nI hope <you> like my message
|
34
|
+
|
35
|
+
Fuck yeah.
|
36
|
+
|
37
|
+
More
|
38
|
+
---------------
|
39
|
+
Please read RDoc to see all of the available methods of StringMaster class: http://rdoc.info/github/snitko/string_master/master/StringMaster
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "string_master"
|
18
|
+
gem.homepage = "http://github.com/snitko/string_master"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Most common string manipulations for a webapp}
|
21
|
+
gem.description = %Q{Because every time I create a new webapp, I think about how I should process user-generated content. Should convert urls to links and images? Should I allow certain tags? Should I convert all new lines to *br* tags? Well, now all that is as simple as calling a single method.}
|
22
|
+
gem.email = "roman.snitko@gmail.com"
|
23
|
+
gem.authors = ["Roman Snitko"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
require 'rdoc/task'
|
37
|
+
Rake::RDocTask.new do |rdoc|
|
38
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
39
|
+
|
40
|
+
rdoc.rdoc_dir = 'rdoc'
|
41
|
+
rdoc.title = "string_master #{version}"
|
42
|
+
rdoc.rdoc_files.include('README*')
|
43
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
44
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,158 @@
|
|
1
|
+
actionscript
|
2
|
+
active4d
|
3
|
+
active4d_html
|
4
|
+
active4d_ini
|
5
|
+
active4d_library
|
6
|
+
ada
|
7
|
+
antlr
|
8
|
+
apache
|
9
|
+
applescript
|
10
|
+
asp
|
11
|
+
asp_vb.net
|
12
|
+
bibtex
|
13
|
+
blog_html
|
14
|
+
blog_markdown
|
15
|
+
blog_text
|
16
|
+
blog_textile
|
17
|
+
build
|
18
|
+
bulletin_board
|
19
|
+
c
|
20
|
+
c++
|
21
|
+
cake
|
22
|
+
camlp4
|
23
|
+
cm
|
24
|
+
coldfusion
|
25
|
+
context_free
|
26
|
+
cs
|
27
|
+
css
|
28
|
+
css_experimental
|
29
|
+
csv
|
30
|
+
d
|
31
|
+
diff
|
32
|
+
dokuwiki
|
33
|
+
dot
|
34
|
+
doxygen
|
35
|
+
dylan
|
36
|
+
eiffel
|
37
|
+
erlang
|
38
|
+
f-script
|
39
|
+
fortran
|
40
|
+
fxscript
|
41
|
+
greasemonkey
|
42
|
+
gri
|
43
|
+
groovy
|
44
|
+
gtd
|
45
|
+
gtdalt
|
46
|
+
haml
|
47
|
+
haskell
|
48
|
+
html
|
49
|
+
html-asp
|
50
|
+
html_django
|
51
|
+
html_for_asp.net
|
52
|
+
html_mason
|
53
|
+
html_rails
|
54
|
+
html_tcl
|
55
|
+
icalendar
|
56
|
+
inform
|
57
|
+
ini
|
58
|
+
installer_distribution_script
|
59
|
+
io
|
60
|
+
java
|
61
|
+
javaproperties
|
62
|
+
javascript
|
63
|
+
javascript_+_prototype
|
64
|
+
javascript_+_prototype_bracketed
|
65
|
+
jquery_javascript
|
66
|
+
json
|
67
|
+
languagedefinition
|
68
|
+
latex
|
69
|
+
latex_beamer
|
70
|
+
latex_log
|
71
|
+
latex_memoir
|
72
|
+
lexflex
|
73
|
+
lighttpd
|
74
|
+
lilypond
|
75
|
+
lisp
|
76
|
+
literate_haskell
|
77
|
+
logo
|
78
|
+
logtalk
|
79
|
+
lua
|
80
|
+
m
|
81
|
+
macports_portfile
|
82
|
+
mail
|
83
|
+
makefile
|
84
|
+
man
|
85
|
+
markdown
|
86
|
+
mediawiki
|
87
|
+
mel
|
88
|
+
mips
|
89
|
+
mod_perl
|
90
|
+
modula-3
|
91
|
+
moinmoin
|
92
|
+
mootools
|
93
|
+
movable_type
|
94
|
+
multimarkdown
|
95
|
+
objective-c
|
96
|
+
objective-c++
|
97
|
+
ocaml
|
98
|
+
ocamllex
|
99
|
+
ocamlyacc
|
100
|
+
opengl
|
101
|
+
pascal
|
102
|
+
perl
|
103
|
+
php
|
104
|
+
plain_text
|
105
|
+
pmwiki
|
106
|
+
postscript
|
107
|
+
processing
|
108
|
+
prolog
|
109
|
+
property_list
|
110
|
+
python
|
111
|
+
python_django
|
112
|
+
qmake_project
|
113
|
+
qt_c++
|
114
|
+
quake3_config
|
115
|
+
r
|
116
|
+
r_console
|
117
|
+
ragel
|
118
|
+
rd_r_documentation
|
119
|
+
regexp
|
120
|
+
regular_expressions_oniguruma
|
121
|
+
regular_expressions_python
|
122
|
+
release_notes
|
123
|
+
remind
|
124
|
+
restructuredtext
|
125
|
+
rez
|
126
|
+
ruby
|
127
|
+
ruby_experimental
|
128
|
+
ruby_on_rails
|
129
|
+
s5
|
130
|
+
scheme
|
131
|
+
scilab
|
132
|
+
setext
|
133
|
+
shell-unix-generic
|
134
|
+
slate
|
135
|
+
smarty
|
136
|
+
sql
|
137
|
+
sql_rails
|
138
|
+
ssh-config
|
139
|
+
standard_ml
|
140
|
+
strings_file
|
141
|
+
subversion_commit_message
|
142
|
+
sweave
|
143
|
+
swig
|
144
|
+
tcl
|
145
|
+
template_toolkit
|
146
|
+
tex
|
147
|
+
tex_math
|
148
|
+
textile
|
149
|
+
tsv
|
150
|
+
twiki
|
151
|
+
txt2tags
|
152
|
+
vectorscript
|
153
|
+
xhtml_1.0
|
154
|
+
xml
|
155
|
+
xml_strict
|
156
|
+
xsl
|
157
|
+
yaml
|
158
|
+
yui_javascript
|
@@ -0,0 +1,142 @@
|
|
1
|
+
class StringMaster
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "action_view"
|
5
|
+
|
6
|
+
include ERB::Util
|
7
|
+
include ActionView::Helpers
|
8
|
+
|
9
|
+
attr_reader(:modified_string)
|
10
|
+
alias :string :modified_string
|
11
|
+
|
12
|
+
def initialize(string)
|
13
|
+
@initial_string = string
|
14
|
+
@modified_string = string
|
15
|
+
yield(self) if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
# Closes all unclosed tags that need to be closed (i.e. skips <img>, <br> etc.)
|
19
|
+
def close_tags
|
20
|
+
text = @modified_string
|
21
|
+
|
22
|
+
open_tags = []
|
23
|
+
text.scan(/<([a-zA-Z0-9]+?)(\s[^>]*)?>/).each { |t| open_tags.unshift(t[0]) }
|
24
|
+
text.scan(/<\/\s*?([a-zA-Z0-9]+)\s*?>/).each { |t| open_tags.slice!(open_tags.index(t[0])) unless open_tags.index(t[0]).nil? }
|
25
|
+
open_tags.each { |t| text += "</#{t}>" unless %w(img br hr).include?(t.to_s) }
|
26
|
+
|
27
|
+
@modified_string = text
|
28
|
+
return self
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# escapes all tags except the ones, that are listed in :except option
|
33
|
+
def html_escape(options={})
|
34
|
+
except = options[:except] || %w()
|
35
|
+
close_tags
|
36
|
+
@modified_string.gsub!(/<\/?([a-zA-Z0-9]*?)(\s[^>]*)?>/) do |tag|
|
37
|
+
if except.include?($1)
|
38
|
+
# Really sanitizes attributes only here
|
39
|
+
sanitize(tag, :tags => except, :attributes => %w(href src lang))
|
40
|
+
else
|
41
|
+
h(tag)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
# Creates <img> tags for all urls that look like images.
|
48
|
+
def urls_to_images(options = {})
|
49
|
+
wrap_with = options[:wrap_with] || ['','']
|
50
|
+
html_options = options[:html_options] || ''
|
51
|
+
@modified_string.gsub!(
|
52
|
+
/(\s|^|\A|\n|\t|\r)(http:\/\/.*?\.(jpg|jpeg|png|gif|JPG|JPEG|PNG|GIF))([,.])?(\s|$|\n|\Z|\t|\r)/,
|
53
|
+
"#{wrap_with[0]}<img src=\"\\2\" alt=\"\" #{html_options}/>\\5#{wrap_with[1]}"
|
54
|
+
)
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Creates <a> tags for all urls.
|
59
|
+
# IMPORTANT: make sure you've used #urls_to_images method first
|
60
|
+
# if you wanted all images urls to become <img> tags.
|
61
|
+
def urls_to_links(options = {})
|
62
|
+
wrap_with = options[:wrap_with] || ['','']
|
63
|
+
html_options = options[:html_options] || ''
|
64
|
+
@modified_string.gsub!(
|
65
|
+
/(\s|^|\A|\n|\t|\r)(http:\/\/.*?)([,.])?(\s|$|\n|\Z|\t|\r|<)/,
|
66
|
+
'\1<a href="\2" ' + html_options + '>\2</a>\3\4'
|
67
|
+
)
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Highlights code using 'uv' library.
|
72
|
+
# Make sure you have ultraviolet gem installed.
|
73
|
+
def highlight_code(options={})
|
74
|
+
begin
|
75
|
+
require 'uv'
|
76
|
+
rescue LoadError
|
77
|
+
raise LoadError, "Gem 'ultraviolet' is required to highlight code. Please install the gem. Note that it fails to build native extensions with ruby 1.9.x so it's only possible to use it with ruby 1.8.x\n\n "
|
78
|
+
end
|
79
|
+
|
80
|
+
wrap_with = options[:wrap_with] || ['','']
|
81
|
+
text = @modified_string
|
82
|
+
|
83
|
+
languages_syntax_list = File.readlines(
|
84
|
+
File.expand_path(File.dirname(__FILE__) + '/../config/languages_syntax_list')
|
85
|
+
).map { |l| l.chomp }
|
86
|
+
|
87
|
+
text.gsub!(/<code(\s*?lang=["']?(.*?)["']?)?>(.*?)<\/code>/) do
|
88
|
+
if languages_syntax_list.include?($2)
|
89
|
+
lang = $2
|
90
|
+
else
|
91
|
+
lang = 'ruby'
|
92
|
+
end
|
93
|
+
unless $3.blank?
|
94
|
+
result = Uv.parse($3.gsub('<br/>', "\n").gsub('<', '<').gsub('>', '>').gsub('"', '"'), 'xhtml', lang, false, 'active4d')
|
95
|
+
"#{wrap_with[0].gsub('$lang', lang)}#{result}#{wrap_with[1]}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# TODO: split string longer than 80 characters
|
100
|
+
|
101
|
+
@modified_string = text
|
102
|
+
self
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
# Breaks words that are longer than 'length'
|
107
|
+
def break_long_words(length=75, &block)
|
108
|
+
@modified_string.gsub!(/<a [^>]+>|<img [^>]+>|([^\s^\n^\^^\A^\t^\r<]{#{length},}?)|<\/a>/) do |s|
|
109
|
+
if $1
|
110
|
+
ns = block_given? ? yield($1) : $1
|
111
|
+
last_pos, result_string = 0, ''
|
112
|
+
while string = ns[last_pos..(last_pos + length)]
|
113
|
+
result_string += string + ' '
|
114
|
+
last_pos += (length + 1)
|
115
|
+
end
|
116
|
+
result_string
|
117
|
+
else
|
118
|
+
s
|
119
|
+
end
|
120
|
+
end
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
# Cuts a string starting at 'cut_at' if the string is longer than 'length'.
|
125
|
+
# Appends characters (if specified in :append) to the end of the cut string.
|
126
|
+
def cut(length, cut_at, options = {})
|
127
|
+
append = options[:append] || ''
|
128
|
+
@modified_string.size > (length) ? @modified_string = @modified_string.mb_chars[0...cut_at] + '...' : @modified_message
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
def newlines_to_br
|
133
|
+
@modified_string.gsub!("\n", "<br/>")
|
134
|
+
self
|
135
|
+
end
|
136
|
+
|
137
|
+
def to_s
|
138
|
+
modified_string.html_safe
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module StringMasterProxy
|
2
|
+
|
3
|
+
# This should be used on a String to get access to
|
4
|
+
# StringMaster's methods. Two notations are available:
|
5
|
+
# - Block notation:
|
6
|
+
# String#prep { |s| s.cut(...); s.break_long_words }
|
7
|
+
# - Chained methods notation
|
8
|
+
# String#prep.cut(...).break_long_words(...)
|
9
|
+
#
|
10
|
+
# Beware that in (1) a String object is returned, while in (2) a StringMaster object is returned
|
11
|
+
# (although StringMaster has a #to_s method).
|
12
|
+
def prep
|
13
|
+
if block_given?
|
14
|
+
@string_master ||= StringMaster.new(self)
|
15
|
+
self.replace yield(@string_master).to_s
|
16
|
+
self
|
17
|
+
else
|
18
|
+
StringMaster.new(self)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class String
|
25
|
+
include StringMasterProxy
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
it "acts as proxy for StringMaster using #prep method" do
|
6
|
+
"<b>This</b> is quite a long text".prep do |s|
|
7
|
+
s.cut(11, 7, :append => '...')
|
8
|
+
s.html_escape
|
9
|
+
end.should == "<b>This...</b>"
|
10
|
+
"<b>This</b> is quite a long text".prep.cut(11, 7, :append => '...').html_escape == "<b>This...</b>"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StringMaster do
|
4
|
+
|
5
|
+
it "closes unclosed tags" do
|
6
|
+
parser = StringMaster.new("<b>Hello,<i>world</b>")
|
7
|
+
parser.close_tags.string.should == '<b>Hello,<i>world</b></i>'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "escapes html except for some of the allowed tags" do
|
11
|
+
parser = StringMaster.new('<img src="#" style="border: solid 1px green;"><b>Hello</b>')
|
12
|
+
parser.html_escape(:except => %w(img)).string.should == '<img src="#"><b>Hello</b>'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "makes images of urls that end with .jpg and other image extensions" do
|
16
|
+
parser = StringMaster.new('Hello, this is my photo http://image.com/image.jpg, yeah baby')
|
17
|
+
parser.urls_to_images(:wrap_with => ['<p>', '</p>'], :html_options => 'class="ico"').string.should ==
|
18
|
+
'Hello, this is my photo<p><img src="http://image.com/image.jpg" alt="" class="ico"/> </p>yeah baby'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "makes links of urls" do
|
22
|
+
# example 1
|
23
|
+
parser = StringMaster.new('Hello, this is my homepage http://url.com, yeah baby')
|
24
|
+
parser.urls_to_links.string.should ==
|
25
|
+
'Hello, this is my homepage <a href="http://url.com" >http://url.com</a>, yeah baby'
|
26
|
+
|
27
|
+
# example 2
|
28
|
+
parser = StringMaster.new("http://localhost:3000/\nhttp://localhost:3000/")
|
29
|
+
parser.urls_to_links.string.should ==
|
30
|
+
"<a href=\"http://localhost:3000/\" >http://localhost:3000/</a>\n<a href=\"http://localhost:3000/\" >http://localhost:3000/</a>"
|
31
|
+
|
32
|
+
# example 3
|
33
|
+
parser = StringMaster.new('http://gyazo.com/a4c16e7a6009f40f29248ad4fed41bd3.png<br>')
|
34
|
+
parser.urls_to_links.string.should == '<a href="http://gyazo.com/a4c16e7a6009f40f29248ad4fed41bd3.png" >http://gyazo.com/a4c16e7a6009f40f29248ad4fed41bd3.png</a><br>'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "highlights code" do
|
38
|
+
begin
|
39
|
+
require 'uv'
|
40
|
+
parser = StringMaster.new('<code>print "hello, world!"</code>')
|
41
|
+
parser.highlight_code.string.should == '<pre class="active4d">print <span class="String"><span class="String">"</span>hello, world!<span class="String">"</span></span>' + "\n</pre>"
|
42
|
+
rescue LoadError
|
43
|
+
pending "This test is skipped because 'ultraviolet' gem is not installed. If you wish to highlight code in a string, install this gem manually. Note that it fails to build native extensions with ruby 1.9.x so it's only possible to use it with ruby 1.8.x"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
it "breaks long words" do
|
49
|
+
long_string = 'l'; 1.upto(80) { |i| long_string << "o" }; long_string << "ng"
|
50
|
+
parser = StringMaster.new(long_string)
|
51
|
+
# fix extra space at the end of the line
|
52
|
+
parser.break_long_words.string.should == "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo oooooong"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "handles 'a' tags when attempt to break long words" do
|
56
|
+
long_string = '<a href="loooooong>loooooong</a>'
|
57
|
+
parser = StringMaster.new(long_string)
|
58
|
+
parser.break_long_words(5).string.should == '<a href="loooooong>loooo oong</a>'
|
59
|
+
end
|
60
|
+
|
61
|
+
it "handles 'img' tags when attempt to break long words" do
|
62
|
+
long_string = '<img src="image.gif" alt="looooooooooooongalt"/>'
|
63
|
+
parser = StringMaster.new(long_string)
|
64
|
+
parser.break_long_words(5).string.should == '<img src="image.gif" alt="looooooooooooongalt"/>'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "cuts too long string and appends (if specified) characters to its end" do
|
68
|
+
parser = StringMaster.new("This is quite a long text")
|
69
|
+
parser.cut(11, 7, :append => '...').string.should == "This is..."
|
70
|
+
end
|
71
|
+
|
72
|
+
it "allows to use block notation" do
|
73
|
+
parser = StringMaster.new('http://images.com/image.jpg <b>Hello http://url.com </b>') do |p|
|
74
|
+
p.urls_to_images.urls_to_links(:html_options => 'target="_blank"')
|
75
|
+
end
|
76
|
+
parser.string.should ==
|
77
|
+
"<img src=\"http://images.com/image.jpg\" alt=\"\" /> <b>Hello <a href=\"http://url.com\" target=\"_blank\">http://url.com</a> </b>"
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{string_master}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = [%q{Roman Snitko}]
|
12
|
+
s.date = %q{2011-06-20}
|
13
|
+
s.description = %q{Because every time I create a new webapp, I think about how I should process user-generated content. Should convert urls to links and images? Should I allow certain tags? Should I convert all new lines to *br* tags? Well, now all that is as simple as calling a single method.}
|
14
|
+
s.email = %q{roman.snitko@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.markdown",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"config/languages_syntax_list",
|
29
|
+
"lib/string_master.rb",
|
30
|
+
"lib/string_master/string_master.rb",
|
31
|
+
"lib/string_master/string_master_proxy.rb",
|
32
|
+
"spec/lib/string_master/string_master_proxy_spec.rb",
|
33
|
+
"spec/lib/string_master/string_master_spec.rb",
|
34
|
+
"spec/spec_helper.rb",
|
35
|
+
"string_master.gemspec"
|
36
|
+
]
|
37
|
+
s.homepage = %q{http://github.com/snitko/string_master}
|
38
|
+
s.licenses = [%q{MIT}]
|
39
|
+
s.require_paths = [%q{lib}]
|
40
|
+
s.rubygems_version = %q{1.8.5}
|
41
|
+
s.summary = %q{Most common string manipulations for a webapp}
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_runtime_dependency(%q<actionpack>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<actionpack>, [">= 0"])
|
54
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
55
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
56
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
57
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<actionpack>, [">= 0"])
|
61
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
62
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
64
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: string_master
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Roman Snitko
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-06-20 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: actionpack
|
16
|
+
requirement: &29018580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *29018580
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bundler
|
27
|
+
requirement: &28880380 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *28880380
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: jeweler
|
38
|
+
requirement: &28879880 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *28879880
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rcov
|
49
|
+
requirement: &28879360 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *28879360
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec
|
60
|
+
requirement: &28878880 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *28878880
|
69
|
+
description: Because every time I create a new webapp, I think about how I should
|
70
|
+
process user-generated content. Should convert urls to links and images? Should
|
71
|
+
I allow certain tags? Should I convert all new lines to *br* tags? Well, now all
|
72
|
+
that is as simple as calling a single method.
|
73
|
+
email: roman.snitko@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files:
|
77
|
+
- LICENSE.txt
|
78
|
+
- README.markdown
|
79
|
+
files:
|
80
|
+
- .document
|
81
|
+
- .rspec
|
82
|
+
- Gemfile
|
83
|
+
- Gemfile.lock
|
84
|
+
- LICENSE.txt
|
85
|
+
- README.markdown
|
86
|
+
- Rakefile
|
87
|
+
- VERSION
|
88
|
+
- config/languages_syntax_list
|
89
|
+
- lib/string_master.rb
|
90
|
+
- lib/string_master/string_master.rb
|
91
|
+
- lib/string_master/string_master_proxy.rb
|
92
|
+
- spec/lib/string_master/string_master_proxy_spec.rb
|
93
|
+
- spec/lib/string_master/string_master_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
- string_master.gemspec
|
96
|
+
homepage: http://github.com/snitko/string_master
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
hash: 1089321753322408665
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.8.5
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Most common string manipulations for a webapp
|
124
|
+
test_files: []
|