ruby-bbcode 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.textile +29 -0
- data/Rakefile +37 -0
- data/lib/ruby-bbcode.rb +214 -0
- data/lib/ruby-bbcode/version.rb +3 -0
- data/lib/tags/tags.rb +95 -0
- data/test/dummy/config/application.rb +14 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/ruby_bbcode_test.rb +197 -0
- data/test/test_helper.rb +7 -0
- metadata +82 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 [name of plugin creator]
|
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.textile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
h1. Ruby-BBcode
|
2
|
+
|
3
|
+
This plugin adds support for "BBCode":http:/www.bbcode.org/ to Ruby. The BBCode is parsed by a parser before converted to HTML, allowing to convert nested BBCode tags in strings to their correct HTML equivalent. The parser also checks whether the BBCode is valid and gives errors for incorrect BBCode texts.
|
4
|
+
|
5
|
+
The parser recognizes all "official tags":http://www.bbcode.org/reference.php and allows to easily extend this set with custom tags.
|
6
|
+
|
7
|
+
h2. Example
|
8
|
+
|
9
|
+
<pre><code>'This is [b]bold[/b] and this is [i]italic[/i].'.bbcode_to_html
|
10
|
+
=> 'This is <strong>bold</strong> and this is <em>italic</em>.'</code></pre>
|
11
|
+
|
12
|
+
h2. Installing
|
13
|
+
|
14
|
+
Add the folling line to the Gemfile in your Rails application:
|
15
|
+
<pre><code>gem 'ruby-bbcode', :git => 'git://github.com/veger/ruby-bbcode.git'</code></pre>
|
16
|
+
Run
|
17
|
+
<pre><code>bundle install</code></pre>
|
18
|
+
|
19
|
+
And the gem is available in you application
|
20
|
+
|
21
|
+
_Note_: Do not forget to restart your server!
|
22
|
+
|
23
|
+
h2. Acknowledgements
|
24
|
+
|
25
|
+
Some of the ideas and the tests came from "bb-ruby":http://github.com/cpjolicoeur/bb-ruby of Craig P Jolicoeur
|
26
|
+
|
27
|
+
h2. License
|
28
|
+
|
29
|
+
MIT License. See the included MIT-LICENCE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'RubyBbcode'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task :default => :test
|
data/lib/ruby-bbcode.rb
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'tags/tags'
|
2
|
+
|
3
|
+
module RubyBBCode
|
4
|
+
include BBCode::Tags
|
5
|
+
|
6
|
+
@@to_sentence_bbcode_tags = {:words_connector => "], [",
|
7
|
+
:two_words_connector => "] and [",
|
8
|
+
:last_word_connector => "] and ["}
|
9
|
+
|
10
|
+
def self.to_html(text, escape_html = true, additional_tags = {}, method = :disable, *tags)
|
11
|
+
# We cannot convert to HTML if the BBCode is not valid!
|
12
|
+
text = text.clone
|
13
|
+
use_tags = @@tags.merge(additional_tags)
|
14
|
+
|
15
|
+
if method == :disable then
|
16
|
+
tags.each { |t| use_tags.delete(t) }
|
17
|
+
else
|
18
|
+
new_use_tags = {}
|
19
|
+
tags.each { |t| new_use_tags[t] = use_tags[t] if use_tags.key?(t) }
|
20
|
+
use_tags = new_use_tags
|
21
|
+
end
|
22
|
+
|
23
|
+
if escape_html
|
24
|
+
text.gsub!('<', '<')
|
25
|
+
text.gsub!('>', '>')
|
26
|
+
end
|
27
|
+
text.gsub!("\r\n", "\n")
|
28
|
+
text.gsub!("\n", "<br />\n")
|
29
|
+
|
30
|
+
valid = parse(text, use_tags)
|
31
|
+
raise valid.join(', ') if valid != true
|
32
|
+
|
33
|
+
bbtree_to_html(@bbtree[:nodes], use_tags)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.is_valid?(text, additional_tags = {})
|
37
|
+
parse(text, @@tags.merge(additional_tags));
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.tag_list
|
41
|
+
@@tags
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
def self.parse(text, tags = {})
|
46
|
+
tags = @@tags if tags == {}
|
47
|
+
tags_list = []
|
48
|
+
@bbtree = {:nodes => []}
|
49
|
+
bbtree_depth = 0
|
50
|
+
bbtree_current_node = @bbtree
|
51
|
+
text.scan(/((\[ (\/)? (\w+) ((=[^\[\]]+) | (\s\w+=\w+)* | ([^\]]*))? \]) | ([^\[]+))/ix) do |tag_info|
|
52
|
+
ti = find_tag_info(tag_info)
|
53
|
+
|
54
|
+
if ti[:is_tag] and !tags.include?(ti[:tag].to_sym)
|
55
|
+
# Handle as text from now on!
|
56
|
+
ti[:is_tag] = false
|
57
|
+
ti[:text] = ti[:complete_match]
|
58
|
+
end
|
59
|
+
|
60
|
+
if !ti[:is_tag] or !ti[:closing_tag]
|
61
|
+
if ti[:is_tag]
|
62
|
+
tag = tags[ti[:tag].to_sym]
|
63
|
+
unless tag[:only_in].nil? or (tags_list.length > 0 and tag[:only_in].include?(tags_list.last.to_sym))
|
64
|
+
# Tag does to be put in the last opened tag
|
65
|
+
err = "[#{ti[:tag]}] can only be used in [#{tag[:only_in].to_sentence(@@to_sentence_bbcode_tags)}]"
|
66
|
+
err += ", so using it in a [#{tags_list.last}] tag is not allowed" if tags_list.length > 0
|
67
|
+
return [err]
|
68
|
+
end
|
69
|
+
|
70
|
+
if tag[:allow_tag_param] and ti[:params][:tag_param] != nil
|
71
|
+
# Test if matches
|
72
|
+
return [tag[:tag_param_description].gsub('%param%', ti[:params][:tag_param])] if ti[:params][:tag_param].match(tag[:tag_param]).nil?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
if tags_list.length > 0 and tags[tags_list.last.to_sym][:only_allow] != nil
|
77
|
+
# Check if the found tag is allowed
|
78
|
+
last_tag = tags[tags_list.last.to_sym]
|
79
|
+
allowed_tags = last_tag[:only_allow]
|
80
|
+
if (!ti[:is_tag] and last_tag[:require_between] != true) or (ti[:is_tag] and (allowed_tags.include?(ti[:tag].to_sym) == false))
|
81
|
+
# Last opened tag does not allow tag
|
82
|
+
err = "[#{tags_list.last}] can only contain [#{allowed_tags.to_sentence(@@to_sentence_bbcode_tags)}] tags, so "
|
83
|
+
err += "[#{ti[:tag]}]" if ti[:is_tag]
|
84
|
+
err += "\"#{ti[:text]}\"" unless ti[:is_tag]
|
85
|
+
err += ' is not allowed'
|
86
|
+
return [err]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Validation of tag succeeded, add to tags_list and/or bbtree
|
91
|
+
if ti[:is_tag]
|
92
|
+
tag = tags[ti[:tag].to_sym]
|
93
|
+
tags_list.push ti[:tag]
|
94
|
+
element = {:is_tag => true, :tag => ti[:tag].to_sym, :nodes => [] }
|
95
|
+
element[:params] = {:tag_param => ti[:params][:tag_param]} if tag[:allow_tag_param] and ti[:params][:tag_param] != nil
|
96
|
+
else
|
97
|
+
element = {:is_tag => false, :text => ti[:text] }
|
98
|
+
if bbtree_depth > 0
|
99
|
+
tag = tags[bbtree_current_node[:tag]]
|
100
|
+
if tag[:require_between] == true
|
101
|
+
bbtree_current_node[:between] = ti[:text]
|
102
|
+
if tag[:allow_tag_param] and tag[:allow_tag_param_between] and (bbtree_current_node[:params] == nil or bbtree_current_node[:params][:tag_param] == nil)
|
103
|
+
# Did not specify tag_param, so use between.
|
104
|
+
# Check if valid
|
105
|
+
return [tag[:tag_param_description].gsub('%param%', ti[:text])] if ti[:text].match(tag[:tag_param]).nil?
|
106
|
+
# Store as tag_param
|
107
|
+
bbtree_current_node[:params] = {:tag_param => ti[:text]}
|
108
|
+
end
|
109
|
+
element = nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
bbtree_current_node[:nodes] << element unless element == nil
|
114
|
+
if ti[:is_tag]
|
115
|
+
# Advance to next level (the node we just added)
|
116
|
+
bbtree_current_node = element
|
117
|
+
bbtree_depth += 1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
if ti[:is_tag] and ti[:closing_tag]
|
122
|
+
if ti[:is_tag]
|
123
|
+
tag = tags[ti[:tag].to_sym]
|
124
|
+
return ["Closing tag [/#{ti[:tag]}] does match [#{tags_list.last}]"] if tags_list.last != ti[:tag]
|
125
|
+
return ["No text between [#{ti[:tag]}] and [/#{ti[:tag]}] tags."] if tag[:require_between] == true and bbtree_current_node[:between].blank?
|
126
|
+
tags_list.pop
|
127
|
+
|
128
|
+
# Find parent node (kinda hard since no link to parent node is available...)
|
129
|
+
bbtree_depth -= 1
|
130
|
+
bbtree_current_node = @bbtree
|
131
|
+
bbtree_depth.times { bbtree_current_node = bbtree_current_node[:nodes].last }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
return ["[#{tags_list.to_sentence((@@to_sentence_bbcode_tags))}] not closed"] if tags_list.length > 0
|
136
|
+
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.find_tag_info(tag_info)
|
141
|
+
ti = {}
|
142
|
+
ti[:complete_match] = tag_info[0]
|
143
|
+
ti[:is_tag] = (tag_info[0].start_with? '[')
|
144
|
+
if ti[:is_tag]
|
145
|
+
ti[:closing_tag] = (tag_info[2] == '/')
|
146
|
+
ti[:tag] = tag_info[3]
|
147
|
+
ti[:params] = {}
|
148
|
+
if tag_info[4][0] == ?=
|
149
|
+
ti[:params][:tag_param] = tag_info[4][1..-1]
|
150
|
+
elsif tag_info[4][0] == ?\s
|
151
|
+
#TODO: Find params
|
152
|
+
end
|
153
|
+
else
|
154
|
+
# Plain text
|
155
|
+
ti[:text] = tag_info[8]
|
156
|
+
end
|
157
|
+
ti
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.bbtree_to_html(node_list, tags = {})
|
161
|
+
tags = @@tags if tags == {}
|
162
|
+
text = ""
|
163
|
+
node_list.each do |node|
|
164
|
+
if node[:is_tag]
|
165
|
+
tag = tags[node[:tag]]
|
166
|
+
t = tag[:html_open].dup
|
167
|
+
t.gsub!('%between%', node[:between]) if tag[:require_between]
|
168
|
+
if tag[:allow_tag_param]
|
169
|
+
if node[:params] and !node[:params][:tag_param].blank?
|
170
|
+
match_array = node[:params][:tag_param].scan(tag[:tag_param])[0]
|
171
|
+
index = 0
|
172
|
+
match_array.each do |match|
|
173
|
+
if index < tag[:tag_param_tokens].length
|
174
|
+
t.gsub!("%#{tag[:tag_param_tokens][index][:token].to_s}%", tag[:tag_param_tokens][index][:prefix].to_s+match+tag[:tag_param_tokens][index][:postfix].to_s)
|
175
|
+
index += 1
|
176
|
+
end
|
177
|
+
end
|
178
|
+
else
|
179
|
+
# Remove unused tokens
|
180
|
+
tag[:tag_param_tokens].each do |token|
|
181
|
+
t.gsub!("%#{token[:token]}%", '')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
text += t
|
187
|
+
text += bbtree_to_html(node[:nodes], tags) if node[:nodes].length > 0
|
188
|
+
t = tag[:html_close]
|
189
|
+
t.gsub!('%between%', node[:between]) if tag[:require_between]
|
190
|
+
text += t
|
191
|
+
else
|
192
|
+
text += node[:text] unless node[:text].nil?
|
193
|
+
end
|
194
|
+
end
|
195
|
+
text
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
String.class_eval do
|
200
|
+
# Convert a string with BBCode markup into its corresponding HTML markup
|
201
|
+
def bbcode_to_html(escape_html = true, additional_tags = {}, method = :disable, *tags)
|
202
|
+
RubyBBCode.to_html(self, escape_html, additional_tags, method, *tags)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Replace the BBCode content of a string with its corresponding HTML markup
|
206
|
+
def bbcode_to_html!(escape_html = true, additional_tags = {}, method = :disable, *tags)
|
207
|
+
self.replace(RubyBBCode.to_html(self, escape_html, additional_tags, method, *tags))
|
208
|
+
end
|
209
|
+
|
210
|
+
# Check if string contains valid BBCode. Returns true when valid, else returns array with error(s)
|
211
|
+
def is_valid_bbcode?
|
212
|
+
RubyBBCode.is_valid?(self)
|
213
|
+
end
|
214
|
+
end
|
data/lib/tags/tags.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module BBCode
|
2
|
+
module Tags
|
3
|
+
# tagname => tag, HTML open tag, HTML close tag, description, example
|
4
|
+
@@tags = {
|
5
|
+
:b => {
|
6
|
+
:html_open => '<strong>', :html_close => '</strong>',
|
7
|
+
:description => 'Make text bold',
|
8
|
+
:example => 'This is [b]bold[/b].'},
|
9
|
+
:i => {
|
10
|
+
:html_open => '<em>', :html_close => '</em>',
|
11
|
+
:description => 'Make text italic',
|
12
|
+
:example => 'This is [i]italic[/i].'},
|
13
|
+
:u => {
|
14
|
+
:html_open => '<u>', :html_close => '</u>',
|
15
|
+
:description => 'Underline text',
|
16
|
+
:example => 'This is [u]underlined[/u].'},
|
17
|
+
:s => {
|
18
|
+
:html_open => '<span style="text-decoration:line-through;">', :html_close => '</span>',
|
19
|
+
:description => 'Strike-through text',
|
20
|
+
:example => 'This is [s]wrong[/s] good.'},
|
21
|
+
:center => {
|
22
|
+
:html_open => '<div style="text-align:center;">', :html_close => '</div>',
|
23
|
+
:description => 'Center a text',
|
24
|
+
:example => '[center]This is centered[/center].'},
|
25
|
+
:ul => {
|
26
|
+
:html_open => '<ul>', :html_close => '</ul>',
|
27
|
+
:description => 'Unordered list',
|
28
|
+
:example => '[ul][li]List item[/li][li]Another list item[/li][/ul].',
|
29
|
+
:only_allow => [ :li ]},
|
30
|
+
:ol => {
|
31
|
+
:html_open => '<ol>', :html_close => '</ol>',
|
32
|
+
:description => 'Ordered list',
|
33
|
+
:example => '[ol][li]List item[/li][li]Another list item[/li][/ol].',
|
34
|
+
:only_allow => [ :li ]},
|
35
|
+
:li => {
|
36
|
+
:html_open => '<li>', :html_close => '</li>',
|
37
|
+
:description => 'List item',
|
38
|
+
:example => '[ul][li]List item[/li][li]Another list item[/li][/ul].',
|
39
|
+
:only_in => [ :ul, :ol ]},
|
40
|
+
:img => {
|
41
|
+
:html_open => '<img src="%between%" %width%%height%alt="" />', :html_close => '',
|
42
|
+
:description => 'Image',
|
43
|
+
:example => '[img]http://www.google.com/intl/en_ALL/images/logo.gif[/img].',
|
44
|
+
:only_allow => [],
|
45
|
+
:require_between => true,
|
46
|
+
:allow_tag_param => true, :allow_tag_param_between => false,
|
47
|
+
:tag_param => /^(\d*)x(\d*)$/,
|
48
|
+
:tag_param_tokens => [{:token => :width, :prefix => 'width="', :postfix => '" ' },
|
49
|
+
{ :token => :height, :prefix => 'height="', :postfix => '" ' } ],
|
50
|
+
:tag_param_description => 'The image parameters \'%param%\' are incorrect, <width>x<height> excepted'},
|
51
|
+
:url => {
|
52
|
+
:html_open => '<a href="%url%">%between%', :html_close => '</a>',
|
53
|
+
:description => 'Link to another page',
|
54
|
+
:example => '[url]http://www.google.com/[/url].',
|
55
|
+
:only_allow => [],
|
56
|
+
:require_between => true,
|
57
|
+
:allow_tag_param => true, :allow_tag_param_between => true,
|
58
|
+
:tag_param => /^((((http|https|ftp):\/\/)|\/).+)$/, :tag_param_tokens => [{ :token => :url }],
|
59
|
+
:tag_param_description => 'The URL should start with http:// https://, ftp:// or /, instead of \'%param%\'' },
|
60
|
+
:quote => {
|
61
|
+
:html_open => '<div class="quote">%author%', :html_close => '</div>',
|
62
|
+
:description => 'Quote another person',
|
63
|
+
:example => '[quote]BBCode is great[/quote]',
|
64
|
+
:allow_tag_param => true, :allow_tag_param_between => false,
|
65
|
+
:tag_param => /(.*)/,
|
66
|
+
:tag_param_tokens => [{:token => :author, :prefix => '<strong>', :postfix => ' wrote:</strong>'}]},
|
67
|
+
:size => {
|
68
|
+
:html_open => '<span style="font-size: %size%px;">', :html_close => '</span>',
|
69
|
+
:description => 'Change the size of the text',
|
70
|
+
:example => '[size=32]This is 32px[/size]',
|
71
|
+
:allow_tag_param => true, :allow_tag_param_between => false,
|
72
|
+
:tag_param => /(\d*)/,
|
73
|
+
:tag_param_tokens => [{:token => :size}]},
|
74
|
+
:color => {
|
75
|
+
:html_open => '<span style="color: %color%;">', :html_close => '</span>',
|
76
|
+
:description => 'Change the color of the text',
|
77
|
+
:example => '[color=red]This is red[/color]',
|
78
|
+
:allow_tag_param => true, :allow_tag_param_between => false,
|
79
|
+
:tag_param => /(([a-z]+)|(#[0-9a-f]{6}))/i,
|
80
|
+
:tag_param_tokens => [{:token => :color}]},
|
81
|
+
:youtube => {
|
82
|
+
:html_open => '<object width="400" height="325"><param name="movie" value="http://www.youtube.com/v/%between%"></param><embed src="http://www.youtube.com/v/%between%" type="application/x-shockwave-flash" width="400" height="325"></embed></object>', :html_close => '',
|
83
|
+
:description => 'Youtube video',
|
84
|
+
:example => '[youtube]E4Fbk52Mk1w[/youtube]',
|
85
|
+
:only_allow => [],
|
86
|
+
:require_between => true},
|
87
|
+
:gvideo => {
|
88
|
+
:html_open => '<embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=%between%&hl=en" style="width:400px; height:325px;" type="application/x-shockwave-flash"></embed>', :html_close => '',
|
89
|
+
:description => 'Google video',
|
90
|
+
:example => '[gvideo]397259729324681206[/gvideo]',
|
91
|
+
:only_allow => [],
|
92
|
+
:require_between => true},
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require 'rails/all'
|
4
|
+
|
5
|
+
Bundler.require
|
6
|
+
require "ruby-bbcode"
|
7
|
+
|
8
|
+
module Dummy
|
9
|
+
class Application < Rails::Application
|
10
|
+
# Configure the default encoding used in templates for Ruby 1.9.
|
11
|
+
config.encoding = "utf-8"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
Dummy::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb
|
3
|
+
|
4
|
+
# The test environment is used exclusively to run your application's
|
5
|
+
# test suite. You never need to work with it otherwise. Remember that
|
6
|
+
# your test database is "scratch space" for the test suite and is wiped
|
7
|
+
# and recreated between test runs. Don't rely on the data there!
|
8
|
+
config.cache_classes = true
|
9
|
+
|
10
|
+
# Configure static asset server for tests with Cache-Control for performance
|
11
|
+
config.serve_static_assets = true
|
12
|
+
config.static_cache_control = "public, max-age=3600"
|
13
|
+
|
14
|
+
# Log error messages when you accidentally call methods on nil
|
15
|
+
config.whiny_nils = true
|
16
|
+
|
17
|
+
# Show full error reports and disable caching
|
18
|
+
config.consider_all_requests_local = true
|
19
|
+
config.action_controller.perform_caching = false
|
20
|
+
|
21
|
+
# Raise exceptions instead of rendering exception templates
|
22
|
+
config.action_dispatch.show_exceptions = false
|
23
|
+
|
24
|
+
# Disable request forgery protection in test environment
|
25
|
+
config.action_controller.allow_forgery_protection = false
|
26
|
+
|
27
|
+
# Tell Action Mailer not to deliver emails to the real world.
|
28
|
+
# The :test delivery method accumulates sent emails in the
|
29
|
+
# ActionMailer::Base.deliveries array.
|
30
|
+
config.action_mailer.delivery_method = :test
|
31
|
+
|
32
|
+
# Use SQL instead of Active Record's schema dumper when creating the test database.
|
33
|
+
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
34
|
+
# like if you have constraints or database-specific column types
|
35
|
+
# config.active_record.schema_format = :sql
|
36
|
+
|
37
|
+
# Print deprecation notices to the stderr
|
38
|
+
config.active_support.deprecation = :stderr
|
39
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RubyBbcodeTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_strong
|
6
|
+
assert_equal '<strong>simple</strong>', '[b]simple[/b]'.bbcode_to_html
|
7
|
+
assert_equal "<strong>line 1<br />\nline 2</strong>", "[b]line 1\nline 2[/b]".bbcode_to_html
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_em
|
11
|
+
assert_equal '<em>simple</em>', '[i]simple[/i]'.bbcode_to_html
|
12
|
+
assert_equal "<em>line 1<br />\nline 2</em>", "[i]line 1\nline 2[/i]".bbcode_to_html
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_u
|
16
|
+
assert_equal '<u>simple</u>', '[u]simple[/u]'.bbcode_to_html
|
17
|
+
assert_equal "<u>line 1<br />\nline 2</u>", "[u]line 1\nline 2[/u]".bbcode_to_html
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_strikethrough
|
21
|
+
assert_equal '<span style="text-decoration:line-through;">simple</span>', '[s]simple[/s]'.bbcode_to_html
|
22
|
+
assert_equal "<span style=\"text-decoration:line-through;\">line 1<br />\nline 2</span>", "[s]line 1\nline 2[/s]".bbcode_to_html
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_size
|
26
|
+
assert_equal '<span style="font-size: 32px;">32px Text</span>', '[size=32]32px Text[/size]'.bbcode_to_html
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_color
|
30
|
+
assert_equal '<span style="color: red;">Red Text</span>', '[color=red]Red Text[/color]'.bbcode_to_html
|
31
|
+
assert_equal '<span style="color: #ff0023;">Hex Color Text</span>', '[color=#ff0023]Hex Color Text[/color]'.bbcode_to_html
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_center
|
35
|
+
assert_equal '<div style="text-align:center;">centered</div>', '[center]centered[/center]'.bbcode_to_html
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_ordered_list
|
39
|
+
assert_equal '<ol><li>item 1</li><li>item 2</li></ol>', '[ol][li]item 1[/li][li]item 2[/li][/ol]'.bbcode_to_html
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unordered_list
|
43
|
+
assert_equal '<ul><li>item 1</li><li>item 2</li></ul>', '[ul][li]item 1[/li][li]item 2[/li][/ul]'.bbcode_to_html
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_two_lists
|
47
|
+
assert_equal '<ul><li>item1</li><li>item2</li></ul><ul><li>item1</li><li>item2</li></ul>',
|
48
|
+
'[ul][li]item1[/li][li]item2[/li][/ul][ul][li]item1[/li][li]item2[/li][/ul]'.bbcode_to_html
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_illegal_items
|
52
|
+
assert_raise RuntimeError do
|
53
|
+
'[li]Illegal item[/li]'.bbcode_to_html
|
54
|
+
end
|
55
|
+
assert_equal ['[li] can only be used in [ul] and [ol]'],
|
56
|
+
'[li]Illegal item[/li]'.is_valid_bbcode?
|
57
|
+
assert_raise RuntimeError do
|
58
|
+
'[b][li]Illegal item[/li][/b]'.bbcode_to_html
|
59
|
+
end
|
60
|
+
|
61
|
+
assert_equal ['[li] can only be used in [ul] and [ol], so using it in a [b] tag is not allowed'],
|
62
|
+
'[b][li]Illegal item[/li][/b]'.is_valid_bbcode?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_illegal_list_contents
|
66
|
+
assert_raise RuntimeError do
|
67
|
+
'[ul]Illegal list[/ul]'.bbcode_to_html
|
68
|
+
end
|
69
|
+
assert_equal ['[ul] can only contain [li] tags, so "Illegal list" is not allowed'],
|
70
|
+
'[ul]Illegal list[/ul]'.is_valid_bbcode?
|
71
|
+
assert_raise RuntimeError do
|
72
|
+
'[ul][b]Illegal list[/b][/ul]'.bbcode_to_html
|
73
|
+
end
|
74
|
+
assert_equal ['[ul] can only contain [li] tags, so [b] is not allowed'],
|
75
|
+
'[ul][b]Illegal list[/b][/ul][/b]'.is_valid_bbcode?
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_illegal_list_contents_text_between_list_items
|
79
|
+
assert_raise RuntimeError do
|
80
|
+
'[ul][li]item[/li]Illegal list[/ul]'.bbcode_to_html
|
81
|
+
end
|
82
|
+
assert_equal ['[ul] can only contain [li] tags, so "Illegal text" is not allowed'],
|
83
|
+
'[ul][li]item[/li]Illegal text[/ul]'.is_valid_bbcode?
|
84
|
+
assert_raise RuntimeError do
|
85
|
+
'[ul][li]item[/li]Illegal list[li]item[/li][/ul]'.bbcode_to_html
|
86
|
+
end
|
87
|
+
assert_equal ['[ul] can only contain [li] tags, so "Illegal text" is not allowed'],
|
88
|
+
'[ul][li]item[/li]Illegal text[li]item[/li][/ul]'.is_valid_bbcode?
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_quote
|
92
|
+
assert_equal '<div class="quote">quoting</div>', '[quote]quoting[/quote]'.bbcode_to_html
|
93
|
+
assert_equal '<div class="quote"><strong>someone wrote:</strong>quoting</div>', '[quote=someone]quoting[/quote]'.bbcode_to_html
|
94
|
+
assert_equal '<div class="quote"><strong>Kitten wrote:</strong><div class="quote"><strong>creatiu wrote:</strong>f1</div>f2</div>',
|
95
|
+
'[quote=Kitten][quote=creatiu]f1[/quote]f2[/quote]'.bbcode_to_html
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_link
|
99
|
+
assert_equal '<a href="http://www.google.com">http://www.google.com</a>', '[url]http://www.google.com[/url]'.bbcode_to_html
|
100
|
+
assert_equal '<a href="http://google.com">Google</a>', '[url=http://google.com]Google[/url]'.bbcode_to_html
|
101
|
+
assert_equal '<a href="/index.html">Home</a>', '[url=/index.html]Home[/url]'.bbcode_to_html
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_illegal_link
|
105
|
+
assert_raise RuntimeError do
|
106
|
+
# Link within same domain must start with a /
|
107
|
+
'[url=index.html]Home[/url]'.bbcode_to_html
|
108
|
+
end
|
109
|
+
assert_raise RuntimeError do
|
110
|
+
# Link within same domain must start with a / and a link to another domain with http://, https:// or ftp://
|
111
|
+
'[url=www.google.com]Google[/url]'.bbcode_to_html
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_image
|
116
|
+
assert_equal '<img src="http://www.ruby-lang.org/images/logo.gif" alt="" />',
|
117
|
+
'[img]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_to_html
|
118
|
+
assert_equal '<img src="http://www.ruby-lang.org/images/logo.gif" width="95" height="96" alt="" />',
|
119
|
+
'[img=95x96]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_to_html
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_youtube
|
123
|
+
assert_equal '<object width="400" height="325"><param name="movie" value="http://www.youtube.com/v/E4Fbk52Mk1w"></param><embed src="http://www.youtube.com/v/E4Fbk52Mk1w" type="application/x-shockwave-flash" width="400" height="325"></embed></object>' ,
|
124
|
+
'[youtube]E4Fbk52Mk1w[/youtube]'.bbcode_to_html
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_google_video
|
128
|
+
assert_equal '<embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=397259729324681206&hl=en" style="width:400px; height:325px;" type="application/x-shockwave-flash"></embed>',
|
129
|
+
'[gvideo]397259729324681206[/gvideo]'.bbcode_to_html
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_html_escaping
|
133
|
+
assert_equal '<strong><i>foobar</i></strong>', '[b]<i>foobar</i>[/b]'.bbcode_to_html
|
134
|
+
assert_equal '<strong><i>foobar</i></strong>', '[b]<i>foobar</i>[/b]'.bbcode_to_html(false)
|
135
|
+
assert_equal '1 is < 2', '1 is < 2'.bbcode_to_html
|
136
|
+
assert_equal '1 is < 2', '1 is < 2'.bbcode_to_html(false)
|
137
|
+
assert_equal '2 is > 1', '2 is > 1'.bbcode_to_html
|
138
|
+
assert_equal '2 is > 1', '2 is > 1'.bbcode_to_html(false)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_disable_tags
|
142
|
+
assert_equal "[b]foobar[/b]", "[b]foobar[/b]".bbcode_to_html(true, {}, :disable, :b)
|
143
|
+
assert_equal "[b]<em>foobar</em>[/b]", "[b][i]foobar[/i][/b]".bbcode_to_html(true, {}, :disable, :b)
|
144
|
+
assert_equal "[b][i]foobar[/i][/b]", "[b][i]foobar[/i][/b]".bbcode_to_html(true, {}, :disable, :b, :i)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_enable_tags
|
148
|
+
assert_equal "<strong>foobar</strong>" , "[b]foobar[/b]".bbcode_to_html(true, {}, :enable, :b)
|
149
|
+
assert_equal "<strong>[i]foobar[/i]</strong>", "[b][i]foobar[/i][/b]".bbcode_to_html(true, {}, :enable, :b)
|
150
|
+
assert_equal "<strong><em>foobar</em></strong>", "[b][i]foobar[/i][/b]".bbcode_to_html(true, {}, :enable, :b, :i)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_to_html_bang_method
|
154
|
+
foo = "[b]foobar[/b]"
|
155
|
+
assert_equal "<strong>foobar</strong>", foo.bbcode_to_html!
|
156
|
+
assert_equal "<strong>foobar</strong>", foo
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_self_tag_list
|
160
|
+
assert_equal 15, RubyBBCode.tag_list.size
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_addition_of_tags
|
164
|
+
mydef = {
|
165
|
+
:test => {
|
166
|
+
:html_open => '<test>', :html_close => '</test>',
|
167
|
+
:description => 'This is a test',
|
168
|
+
:example => '[test]Test here[/test]'}
|
169
|
+
}
|
170
|
+
assert_equal 'pre <test>Test here</test> post', 'pre [test]Test here[/test] post'.bbcode_to_html(true, mydef)
|
171
|
+
assert_equal 'pre <strong><test>Test here</test></strong> post', 'pre [b][test]Test here[/test][/b] post'.bbcode_to_html(true, mydef)
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_multiple_tag_test
|
175
|
+
assert_equal "<strong>bold</strong><em>italic</em><u>underline</u><div class=\"quote\">quote</div><a href=\"https://test.com\">link</a>",
|
176
|
+
"[b]bold[/b][i]italic[/i][u]underline[/u][quote]quote[/quote][url=https://test.com]link[/url]".bbcode_to_html
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_no_ending_tag
|
180
|
+
assert_raise RuntimeError do
|
181
|
+
"this [b]should not be bold".bbcode_to_html
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_no_start_tag
|
186
|
+
assert_raise RuntimeError do
|
187
|
+
"this should not be bold[/b]".bbcode_to_html
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_different_start_and_ending_tags
|
192
|
+
assert_raise RuntimeError do
|
193
|
+
"this [b]should not do formatting[/i]".bbcode_to_html
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-bbcode
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Maarten Bezemer
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-19 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Convert BBCode to HTML and check whether the BBCode is valid.
|
22
|
+
email:
|
23
|
+
- maarten.bezemer@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- lib/tags/tags.rb
|
32
|
+
- lib/ruby-bbcode/version.rb
|
33
|
+
- lib/ruby-bbcode.rb
|
34
|
+
- MIT-LICENSE
|
35
|
+
- Rakefile
|
36
|
+
- README.textile
|
37
|
+
- test/ruby_bbcode_test.rb
|
38
|
+
- test/dummy/config/environments/test.rb
|
39
|
+
- test/dummy/config/application.rb
|
40
|
+
- test/dummy/config/boot.rb
|
41
|
+
- test/dummy/config/environment.rb
|
42
|
+
- test/test_helper.rb
|
43
|
+
homepage: http://github.com/veger/ruby-bbcode
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.7.2
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: ruby-bbcode-0.0.2
|
76
|
+
test_files:
|
77
|
+
- test/ruby_bbcode_test.rb
|
78
|
+
- test/dummy/config/environments/test.rb
|
79
|
+
- test/dummy/config/application.rb
|
80
|
+
- test/dummy/config/boot.rb
|
81
|
+
- test/dummy/config/environment.rb
|
82
|
+
- test/test_helper.rb
|