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 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
@@ -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!('<', '&lt;')
25
+ text.gsub!('>', '&gt;')
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
@@ -0,0 +1,3 @@
1
+ module RubyBbcode
2
+ VERSION = "0.0.2"
3
+ 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,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the rails application
5
+ Dummy::Application.initialize!
@@ -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>&lt;i&gt;foobar&lt;/i&gt;</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 &lt; 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 &gt; 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
@@ -0,0 +1,7 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+ require "rails/test_help"
6
+
7
+ Rails.backtrace_cleaner.remove_silencers!
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