rbbcode 0.1.8 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sanitize-url', '>= 0.1.3'
4
+
5
+ # Add dependencies to develop your gem here.
6
+ # Include everything needed to run rake, tests, features, etc.
7
+ group :development do
8
+ gem 'rspec', '~> 2.3.0'
9
+ gem 'bluecloth'
10
+ gem 'yard', '~> 0.6.0'
11
+ gem 'bundler', '~> 1.0.0'
12
+ gem 'jeweler', '~> 1.5.2'
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2004-2008 David Heinemeier Hansson
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.
21
+
data/README.markdown CHANGED
@@ -1,12 +1,7 @@
1
- The gem is fixed!
2
- =================
3
-
4
- Due to a defective gemspec, at least one version (0.1.3) wasn't packaging the lib directory in the .gem file. This has been corrected in 0.1.4. Sorry for the delay in fixing this.
5
-
6
1
  About RbbCode
7
2
  =============
8
3
 
9
- RbbCode is a customizable Ruby library for parsing BB Code.
4
+ RbbCode is a customizable Ruby library for parsing BB Code originally developed by Jarret (https://github.com/jarrett/rbbcode).
10
5
 
11
6
  RbbCode validates and cleans input. It supports customizable schemas so you can set rules about what tags are allowed where. The default rules are designed to ensure valid HTML output.
12
7
 
@@ -75,6 +70,15 @@ As you can infer from the second example, RbbCode does not support attributes li
75
70
 
76
71
  RbbCode does not support all the tags listed on Wikpedia out of the box, and probably never will. However, you can easily add support for as many tags as you want.
77
72
 
73
+
74
+ BBCode Syntax Extensions
75
+ ========================
76
+
77
+ In order to support inline BBCode tags like smileys I added the following syntax:
78
+ [:tagname]
79
+
80
+ These tags do not need to be closed. For HTML generation the method html_from_tagname_tag(node) is called, as usual.
81
+
78
82
  XSS Prevention
79
83
  ==============
80
84
 
@@ -119,4 +123,4 @@ Installation
119
123
  If that doesn't work, it's probably because RbbCode is hosted on Gemcutter, and your computer doesn't know about Gemcutter yet. To fix that:
120
124
 
121
125
  gem install gemcutter
122
- gem tumble
126
+ gem tumble
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+
14
+ Jeweler::Tasks.new do |gem|
15
+ gem.name = 'rbbcode'
16
+ gem.homepage = "http://github.com/jarrett/rbbcode"
17
+ gem.license = "MIT"
18
+ gem.summary = 'Ruby BB Code parser'
19
+ gem.description = 'RbbCode is a customizable Ruby library for parsing BB Code. RbbCode validates and cleans input. It supports customizable schemas so you can set rules about what tags are allowed where. The default rules are designed to ensure valid HTML output.'
20
+ gem.email = "jarrett@jarrettcolby.com, aq1018@gmail.com"
21
+ gem.authors = ['Jarrett Colby', "aq1018@gmail.com"]
22
+ end
23
+ Jeweler::RubygemsDotOrgTasks.new
24
+
25
+ require 'rspec/core'
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new(:spec) do |spec|
28
+ spec.pattern = FileList['spec/**/*_spec.rb']
29
+ spec.rspec_opts = "--color --format progress"
30
+ end
31
+
32
+ task :default => :spec
33
+
34
+ require 'yard'
35
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.11
@@ -55,7 +55,7 @@ module RbbCode
55
55
  attributes.each do |attr, value|
56
56
  output << " #{attr}=\"#{value}\""
57
57
  end
58
- if contents.nil? or contents.empty?
58
+ if contents.nil? or contents.empty? and not tag_name == 'code'
59
59
  output << '/>'
60
60
  else
61
61
  output << ">#{contents}</#{tag_name}>"
@@ -87,4 +87,4 @@ module RbbCode
87
87
  DEFAULT_TAG_MAPPINGS[tag_name]
88
88
  end
89
89
  end
90
- end
90
+ end
@@ -29,4 +29,4 @@ module RbbCode
29
29
  [:schema, :tree_maker, :html_maker]
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -268,6 +268,7 @@ module RbbCode
268
268
  end
269
269
 
270
270
  def text_valid_in_context?(*ancestors)
271
+ ancestors.flatten!
271
272
  if @no_text.include?(ancestors[0].to_s)
272
273
  return false
273
274
  end
@@ -295,6 +296,8 @@ module RbbCode
295
296
  tag('img').may_not_be_nested
296
297
  tag('code').may_not_be_nested
297
298
  tag('code').is_preformatted
299
+ #tag('code').may_not_be_empty
300
+ tag('quote').may_not_be_empty
298
301
  tag('p').may_not_be_nested
299
302
  tag('*').must_be_child_of('list')
300
303
  tag('*').closes_twins
@@ -303,4 +306,4 @@ module RbbCode
303
306
  tag('list').may_not_contain_text
304
307
  end
305
308
  end
306
- end
309
+ end
@@ -56,6 +56,11 @@ module RbbCode
56
56
 
57
57
  class TagNode < Node
58
58
  def self.from_opening_bb_code(parent, bb_code)
59
+ # Remove colon if leave_tag
60
+ if bb_code[1,1] == ':'
61
+ bb_code = "[#{bb_code[2..-1]}"
62
+ end
63
+
59
64
  if equal_index = bb_code.index('=')
60
65
  tag_name = bb_code[1, equal_index - 1]
61
66
  value = bb_code[(equal_index + 1)..-2]
@@ -149,6 +154,7 @@ module RbbCode
149
154
  elsif child.tag_name == @schema.paragraph_tag_name
150
155
  # It's an empty paragraph tag
151
156
  true
157
+ #elsif not node.is_a?(RootNode) and @schema.block_level?(node.tag_name) and child.tag_name == @schema.line_break_tag_name and node.children.last == child
152
158
  elsif @schema.block_level?(node.tag_name) and child.tag_name == @schema.line_break_tag_name and node.children.last == child
153
159
  # It's a line break a the end of the block-level element
154
160
  true
@@ -192,8 +198,21 @@ module RbbCode
192
198
  # be temporarily split up as we append bytes onto the text nodes. But as of yet, I haven't found
193
199
  # a way that this could cause a problem. The bytes always come back together again. (It would be a problem
194
200
  # if we tried to count the characters for some reason, but we don't do that.)
195
- str.each_byte do |char_code|
196
- char = char_code.chr
201
+
202
+ # AQ: #each_byte doesn't work with ruby 1.9+, but luckily we have #each_char
203
+ split_method = :each_byte
204
+ split_method = :each_char if RUBY_VERSION.split('.')[1] > "8"
205
+
206
+ block = Proc.new do |char|
207
+ if split_method == :each_char
208
+ # ruby 1.9
209
+ char_code = char.ord
210
+ else
211
+ # ruby 1.8
212
+ char_code = char
213
+ char = char_code.chr
214
+ end
215
+
197
216
  case current_token_type
198
217
  when :unknown
199
218
  case char
@@ -275,6 +294,9 @@ module RbbCode
275
294
  when '/'
276
295
  current_token_type = :closing_tag
277
296
  current_token << '/'
297
+ when ':'
298
+ current_token_type = :leaf_tag
299
+ current_token << ':'
278
300
  else
279
301
  if tag_name_char?(char_code)
280
302
  current_token_type = :opening_tag
@@ -328,6 +350,21 @@ module RbbCode
328
350
  current_token_type = :text
329
351
  current_token << char
330
352
  end
353
+ when :leaf_tag
354
+ if tag_name_char?(char_code) or char == '='
355
+ current_token << char
356
+ elsif char == ']'
357
+ current_token << ']'
358
+ tag_node = TagNode.from_opening_bb_code(current_parent, current_token)
359
+
360
+ if @schema.tag(tag_node.tag_name).valid_in_context?(*ancestor_list(current_parent))
361
+ current_parent.children << tag_node
362
+ current_token_type = :unknown
363
+ current_token = ''
364
+ else
365
+ current_token_type = :text
366
+ end
367
+ end
331
368
  when :closing_tag
332
369
  if tag_name_char?(char_code)
333
370
  current_token << char
@@ -376,6 +413,9 @@ module RbbCode
376
413
  raise "Unknown token type in state machine: #{current_token_type}"
377
414
  end
378
415
  end
416
+
417
+ str.send(split_method, &block)
418
+
379
419
  # Handle whatever's left in the current token
380
420
  if current_token_type != :break and !current_token.empty?
381
421
  current_parent << TextNode.new(current_parent, current_token)
@@ -387,4 +427,4 @@ module RbbCode
387
427
  (char_code >= LOWER_A_CODE and char_code <= LOWER_Z_CODE) or (char_code >= UPPER_A_CODE and char_code <= UPPER_Z_CODE) or char_code.chr == '*'
388
428
  end
389
429
  end
390
- end
430
+ end
Binary file
data/rbbcode.gemspec ADDED
@@ -0,0 +1,82 @@
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{rbbcode}
8
+ s.version = "0.1.11"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jarrett Colby", "aq1018@gmail.com"]
12
+ s.date = %q{2011-02-19}
13
+ s.description = %q{RbbCode is a customizable Ruby library for parsing BB Code. RbbCode validates and cleans input. It supports customizable schemas so you can set rules about what tags are allowed where. The default rules are designed to ensure valid HTML output.}
14
+ s.email = %q{jarrett@jarrettcolby.com, aq1018@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "LICENSE.txt",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/rbbcode.rb",
27
+ "lib/rbbcode/html_maker.rb",
28
+ "lib/rbbcode/parser.rb",
29
+ "lib/rbbcode/schema.rb",
30
+ "lib/rbbcode/tree_maker.rb",
31
+ "pkg/rbbcode-0.1.8.gem",
32
+ "rbbcode.gemspec",
33
+ "spec/html_maker_spec.rb",
34
+ "spec/node_spec_helper.rb",
35
+ "spec/parser_spec.rb",
36
+ "spec/schema_spec.rb",
37
+ "spec/spec_helper.rb",
38
+ "spec/tree_maker_spec.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/jarrett/rbbcode}
41
+ s.licenses = ["MIT"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.7}
44
+ s.summary = %q{Ruby BB Code parser}
45
+ s.test_files = [
46
+ "spec/html_maker_spec.rb",
47
+ "spec/node_spec_helper.rb",
48
+ "spec/parser_spec.rb",
49
+ "spec/schema_spec.rb",
50
+ "spec/spec_helper.rb",
51
+ "spec/tree_maker_spec.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<sanitize-url>, [">= 0.1.3"])
60
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
61
+ s.add_development_dependency(%q<bluecloth>, [">= 0"])
62
+ s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
63
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
64
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
65
+ else
66
+ s.add_dependency(%q<sanitize-url>, [">= 0.1.3"])
67
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
68
+ s.add_dependency(%q<bluecloth>, [">= 0"])
69
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
70
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
71
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
72
+ end
73
+ else
74
+ s.add_dependency(%q<sanitize-url>, [">= 0.1.3"])
75
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
76
+ s.add_dependency(%q<bluecloth>, [">= 0"])
77
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
78
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
79
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
80
+ end
81
+ end
82
+
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
4
  require File.expand_path(File.dirname(__FILE__) + '/node_spec_helper')
3
5
 
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module RbbCode
2
4
  class RootNode
3
5
  def == (other_node)
data/spec/parser_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  $KCODE = 'u'
2
3
 
3
4
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
@@ -8,110 +9,155 @@ describe RbbCode::Parser do
8
9
  @parser = RbbCode::Parser.new
9
10
  end
10
11
 
11
- it 'should create paragraphs and line breaks' do
12
- bb_code = "This is one paragraph.\n\nThis is another paragraph."
13
- @parser.parse(bb_code).should == '<p>This is one paragraph.</p><p>This is another paragraph.</p>'
14
- bb_code = "This is one line.\nThis is another line."
15
- @parser.parse(bb_code).should == '<p>This is one line.<br/>This is another line.</p>'
16
- end
17
-
18
- it 'should turn [b] to <strong>' do
19
- @parser.parse('This is [b]bold[/b] text').should == '<p>This is <strong>bold</strong> text</p>'
20
- end
21
-
22
- it 'should turn [i] to <em> by default' do
23
- @parser.parse('This is [i]italic[/i] text').should == '<p>This is <em>italic</em> text</p>'
24
- end
25
-
26
- it 'should turn [u] to <u>' do
27
- @parser.parse('This is [u]underlined[/u] text').should == '<p>This is <u>underlined</u> text</p>'
28
- end
29
-
30
- it 'should turn [url]http://google.com[/url] to a link' do
31
- @parser.parse('Visit [url]http://google.com[/url] now').should == '<p>Visit <a href="http://google.com">http://google.com</a> now</p>'
32
- end
33
-
34
- it 'should turn [url=http://google.com]Google[/url] to a link' do
35
- @parser.parse('Visit [url=http://google.com]Google[/url] now').should == '<p>Visit <a href="http://google.com">Google</a> now</p>'
36
- end
37
-
38
- it 'should turn [img] to <img>' do
39
- @parser.parse('[img]http://example.com/image.jpg[/img]').should == '<p><img src="http://example.com/image.jpg" alt=""/></p>'
40
- end
41
-
42
- it 'should parse nested tags' do
43
- @parser.parse('[b][i]This is bold-italic[/i][/b]').should == '<p><strong><em>This is bold-italic</em></strong></p>'
44
- end
45
-
46
- it 'should not put <p> tags around <ul> tags' do
47
- @parser.parse("Text.\n\n[list]\n[*]Foo[/*]\n[*]Bar[/*]\n[/list]\n\nMore text.").should == '<p>Text.</p><ul><li>Foo</li><li>Bar</li></ul><p>More text.</p>'
48
- end
49
-
50
- it 'should ignore forbidden or unrecognized tags' do
51
- @parser.parse('There is [foo]no such thing[/foo] as a foo tag').should == '<p>There is no such thing as a foo tag</p>'
52
- end
12
+ it 'should create paragraphs and line breaks' do
13
+ bb_code = "This is one paragraph.\n\nThis is another paragraph."
14
+ @parser.parse(bb_code).should == '<p>This is one paragraph.</p><p>This is another paragraph.</p>'
15
+ bb_code = "This is one line.\nThis is another line."
16
+ @parser.parse(bb_code).should == '<p>This is one line.<br/>This is another line.</p>'
17
+ end
18
+
19
+ it 'should turn [b] to <strong>' do
20
+ @parser.parse('This is [b]bold[/b] text').should == '<p>This is <strong>bold</strong> text</p>'
21
+ end
22
+
23
+ it 'should turn [i] to <em> by default' do
24
+ @parser.parse('This is [i]italic[/i] text').should == '<p>This is <em>italic</em> text</p>'
25
+ end
26
+
27
+ it 'should turn [u] to <u>' do
28
+ @parser.parse('This is [u]underlined[/u] text').should == '<p>This is <u>underlined</u> text</p>'
29
+ end
30
+
31
+ it 'should turn [url]http://google.com[/url] to a link' do
32
+ @parser.parse('Visit [url]http://google.com[/url] now').should == '<p>Visit <a href="http://google.com">http://google.com</a> now</p>'
33
+ end
34
+
35
+ it 'should turn [url=http://google.com]Google[/url] to a link' do
36
+ @parser.parse('Visit [url=http://google.com]Google[/url] now').should == '<p>Visit <a href="http://google.com">Google</a> now</p>'
37
+ end
38
+
39
+ it 'should turn [img] to <img>' do
40
+ @parser.parse('[img]http://example.com/image.jpg[/img]').should == '<p><img src="http://example.com/image.jpg" alt=""/></p>'
41
+ end
42
+
43
+ it 'should parse nested tags' do
44
+ @parser.parse('[b][i]This is bold-italic[/i][/b]').should == '<p><strong><em>This is bold-italic</em></strong></p>'
45
+ end
46
+
47
+ it 'should not put <p> tags around <ul> tags' do
48
+ @parser.parse("Text.\n\n[list]\n[*]Foo[/*]\n[*]Bar[/*]\n[/list]\n\nMore text.").should == '<p>Text.</p><ul><li>Foo</li><li>Bar</li></ul><p>More text.</p>'
49
+ end
50
+
51
+ it 'should ignore forbidden or unrecognized tags' do
52
+ @parser.parse('There is [foo]no such thing[/foo] as a foo tag').should == '<p>There is no such thing as a foo tag</p>'
53
+ end
54
+
55
+ it 'should recover gracefully from malformed or improperly matched tags' do
56
+ @parser.parse('This [i/]tag[/i] is malformed').should == '<p>This [i/]tag is malformed</p>'
57
+ @parser.parse('This [i]]tag[/i] is malformed').should == '<p>This <em>]tag</em> is malformed</p>'
58
+ @parser.parse('This [i]tag[[/i] is malformed').should == '<p>This <em>tag[</em> is malformed</p>'
59
+ @parser.parse('This [i]tag[//i] is malformed').should == '<p>This <em>tag[//i] is malformed</em></p>'
60
+ @parser.parse('This [[i]tag[/i] is malformed').should == '<p>This [<em>tag</em> is malformed</p>'
61
+ @parser.parse('This [i]tag[/i]] is malformed').should == '<p>This <em>tag</em>] is malformed</p>'
62
+ @parser.parse('This [i]i tag[i] is not properly matched').should == '<p>This <em>i tag is not properly matched</em></p>'
63
+ @parser.parse('This i tag[/i] is not properly matched').should == '<p>This i tag is not properly matched</p>'
64
+ end
65
+
66
+ it 'should escape < and >' do
67
+ @parser.parse('This is [i]italic[/i], but this it not <i>italic</i>.').should == '<p>This is <em>italic</em>, but this it not &lt;i&gt;italic&lt;/i&gt;.</p>'
68
+ end
69
+
70
+ it 'should work when the string begins with a tag' do
71
+ @parser.parse('[b]This is bold[/b]').should == '<p><strong>This is bold</strong></p>'
72
+ end
73
+
74
+ it 'should handle UTF8' do
75
+ @parser.parse("Here's some UTF-8: [i]א[/i]. And here's some ASCII text.").should == "<p>Here's some UTF-8: <em>א</em>. And here's some ASCII text.</p>"
76
+ end
77
+
78
+ # Bugs reported and fixed:
79
+
80
+ it 'should not leave an open <em> tag when parsing "foo [i][/i] bar"' do
81
+ # Thanks to Vizakenjack for finding this. It creates an empty <em> tag. Browsers don't like this, so we need to replace it.
82
+ @parser.parse('foo [i][/i] bar').should match(/<p>foo +bar<\/p>/)
83
+ end
84
+
85
+ it 'should not raise when parsing "Are you a real phan yet?\r\n\r\n[ ] Yes\r\n[X] No"' do
86
+ # Thanks to sblackstone for finding this.
87
+ @parser.parse("Are you a real phan yet?\r\n\r\n[ ] Yes\r\n[X] No")
88
+ end
89
+
90
+ it 'should support images inside links' do
91
+ # Thanks to Vizakenjack for finding this.
92
+ @parser.parse('[url=http://www.google.com][img]http://www.123.com/123.png[/img][/url]').should ==
93
+ '<p><a href="http://www.google.com"><img src="http://www.123.com/123.png" alt=""/></a></p>'
94
+ end
95
+
96
+ it 'can parse phpBB-style [*] tags' do
97
+ # Thanks to motiv for finding this
98
+ @parser.parse("[list]\n[*]one\n[*]two\n[/list]"
99
+ ).should == '<ul><li>one</li><li>two</li></ul>'
100
+ end
101
+
102
+ context 'parsing [code] tags' do
103
+ # Thanks to fatalerrorx for finding these
104
+ it 'wraps the <code> tags in <pre> tags' do
105
+ @parser.parse('The [code]some code[/code] should be preformatted').should == '<p>The <pre><code>some code</code></pre> should be preformatted</p>'
106
+ end
107
+
108
+ it 'leaves line breaks inside untouched' do
109
+ @parser.parse("Two lines of code:\n\n[code]line 1\n\nline 2[/code]\n\nAnd some more text.").should ==
110
+ "<p>Two lines of code:</p><p><pre><code>line 1\n\nline 2</code></pre></p><p>And some more text.</p>"
111
+ end
112
+
113
+ it 'treats tags other than the closing tag as literals' do
114
+ @parser.parse('[code]This is [b]bold[/b] text[/code]').should == '<p><pre><code>This is [b]bold[/b] text</code></pre></p>'
115
+ end
116
+ end
117
+
118
+ # Leave tag support
119
+
120
+ it 'should parse allowed leaf tags' do
121
+ schema = RbbCode::Schema.new
122
+ schema.allow_tag(:br)
123
+ html_maker = CustomHtmlMaker.new
124
+ @parser = RbbCode::Parser.new(:schema => schema, :html_maker => html_maker)
125
+
126
+ @parser.parse('This text should contain a [:br] HTML tag').should == '<p>This text should contain a <br /> HTML tag</p>'
127
+ end
128
+
129
+ # Bug from original version
130
+ it 'should not parse multiple not closing tags' do
131
+ schema = RbbCode::Schema.new
132
+ schema.allow_tag(:Qsmiley)
133
+ html_maker = CustomHtmlMaker.new
134
+ @parser = RbbCode::Parser.new(:schema => schema, :html_maker => html_maker)
135
+
136
+ @parser.parse('Two smileys: 1) [Qsmiley] and 2) [Qsmiley]').should_not == '<p>Two smileys: 1) <smiley /> and 2) <smiley /></p>'
137
+ end
138
+
139
+ it 'should parse multiple allowed leaf tags' do
140
+ schema = RbbCode::Schema.new
141
+ schema.allow_tag(:br)
142
+ html_maker = CustomHtmlMaker.new
143
+ @parser = RbbCode::Parser.new(:schema => schema, :html_maker => html_maker)
144
+
145
+ @parser.parse('This text should contain a [:br] HTML tag and another one [:br]').should == '<p>This text should contain a <br /> HTML tag and another one <br /></p>'
146
+ end
147
+
148
+ it 'should parse unknown leaf tags as text' do
149
+ @parser.parse('This text should contain a [:pseudo] BBCode tag').should == '<p>This text should contain a [:pseudo] BBCode tag</p>'
150
+ end
151
+
152
+ # Bugs
153
+
154
+ it 'should omit empty quotes' do
155
+ @parser.parse("[quote][/quote]").should == ""
156
+ end
157
+
158
+ it 'should parse empty codes' do
159
+ @parser.parse("[code][/code]").should == "<p><pre><code></code></pre></p>"
160
+ end
53
161
 
54
- it 'should recover gracefully from malformed or improperly matched tags' do
55
- @parser.parse('This [i/]tag[/i] is malformed').should == '<p>This [i/]tag is malformed</p>'
56
- @parser.parse('This [i]]tag[/i] is malformed').should == '<p>This <em>]tag</em> is malformed</p>'
57
- @parser.parse('This [i]tag[[/i] is malformed').should == '<p>This <em>tag[</em> is malformed</p>'
58
- @parser.parse('This [i]tag[//i] is malformed').should == '<p>This <em>tag[//i] is malformed</em></p>'
59
- @parser.parse('This [[i]tag[/i] is malformed').should == '<p>This [<em>tag</em> is malformed</p>'
60
- @parser.parse('This [i]tag[/i]] is malformed').should == '<p>This <em>tag</em>] is malformed</p>'
61
- @parser.parse('This [i]i tag[i] is not properly matched').should == '<p>This <em>i tag is not properly matched</em></p>'
62
- @parser.parse('This i tag[/i] is not properly matched').should == '<p>This i tag is not properly matched</p>'
63
- end
64
-
65
- it 'should escape < and >' do
66
- @parser.parse('This is [i]italic[/i], but this it not <i>italic</i>.').should == '<p>This is <em>italic</em>, but this it not &lt;i&gt;italic&lt;/i&gt;.</p>'
67
- end
68
-
69
- it 'should work when the string begins with a tag' do
70
- @parser.parse('[b]This is bold[/b]').should == '<p><strong>This is bold</strong></p>'
71
- end
72
-
73
- it 'should handle UTF8' do
74
- @parser.parse("Here's some UTF-8: [i]א[/i]. And here's some ASCII text.").should == "<p>Here's some UTF-8: <em>א</em>. And here's some ASCII text.</p>"
75
- end
76
-
77
- # Bugs reported and fixed:
78
-
79
- it 'should not leave an open <em> tag when parsing "foo [i][/i] bar"' do
80
- # Thanks to Vizakenjack for finding this. It creates an empty <em> tag. Browsers don't like this, so we need to replace it.
81
- @parser.parse('foo [i][/i] bar').should match(/<p>foo +bar<\/p>/)
82
- end
83
-
84
- it 'should not raise when parsing "Are you a real phan yet?\r\n\r\n[ ] Yes\r\n[X] No"' do
85
- # Thanks to sblackstone for finding this.
86
- @parser.parse("Are you a real phan yet?\r\n\r\n[ ] Yes\r\n[X] No")
87
- end
88
-
89
- it 'should support images inside links' do
90
- # Thanks to Vizakenjack for finding this.
91
- @parser.parse('[url=http://www.google.com][img]http://www.123.com/123.png[/img][/url]').should ==
92
- '<p><a href="http://www.google.com"><img src="http://www.123.com/123.png" alt=""/></a></p>'
93
- end
94
-
95
- it 'can parse phpBB-style [*] tags' do
96
- # Thanks to motiv for finding this
97
- @parser.parse("[list]\n[*]one\n[*]two\n[/list]"
98
- ).should == '<ul><li>one</li><li>two</li></ul>'
99
- end
100
-
101
- context 'parsing [code] tags' do
102
- # Thanks to fatalerrorx for finding these
103
- it 'wraps the <code> tags in <pre> tags' do
104
- @parser.parse('The [code]some code[/code] should be preformatted').should == '<p>The <pre><code>some code</code></pre> should be preformatted</p>'
105
- end
106
-
107
- it 'leaves line breaks inside untouched' do
108
- @parser.parse("Two lines of code:\n\n[code]line 1\n\nline 2[/code]\n\nAnd some more text.").should ==
109
- "<p>Two lines of code:</p><p><pre><code>line 1\n\nline 2</code></pre></p><p>And some more text.</p>"
110
- end
111
-
112
- it 'treats tags other than the closing tag as literals' do
113
- @parser.parse('[code]This is [b]bold[/b] text[/code]').should == '<p><pre><code>This is [b]bold[/b] text</code></pre></p>'
114
- end
115
- end
116
162
  end
117
- end
163
+ end
data/spec/schema_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
4
 
3
5
  describe RbbCode::Schema do
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,17 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
- require 'spec'
3
+ require 'rspec'
4
4
 
5
- #def puts(foo)
6
- # raise 'puts called'
7
- #end
5
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/rbbcode')
8
6
 
9
- require File.expand_path(File.dirname(__FILE__) + '/../lib/rbbcode')
7
+ class CustomHtmlMaker < RbbCode::HtmlMaker
8
+
9
+ def html_from_br_tag(node)
10
+ '<br />'
11
+ end
12
+
13
+ def html_from_Qsmiley_tag(node)
14
+ '<smiley />'
15
+ end
16
+
17
+ end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
3
  require File.expand_path(File.dirname(__FILE__) + '/node_spec_helper')
3
4
  require 'pp'
@@ -119,4 +120,4 @@ describe RbbCode::TreeMaker do
119
120
  end
120
121
  end
121
122
  end
122
- end
123
+ end
metadata CHANGED
@@ -1,92 +1,178 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbcode
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 13
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 1
8
- - 8
9
- version: 0.1.8
9
+ - 11
10
+ version: 0.1.11
10
11
  platform: ruby
11
12
  authors:
12
13
  - Jarrett Colby
14
+ - aq1018@gmail.com
13
15
  autorequire:
14
16
  bindir: bin
15
17
  cert_chain: []
16
18
 
17
- date: 2010-03-20 00:00:00 -05:00
19
+ date: 2011-02-19 00:00:00 -06:00
18
20
  default_executable:
19
21
  dependencies:
20
22
  - !ruby/object:Gem::Dependency
21
- name: rspec
23
+ type: :runtime
22
24
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
25
+ name: sanitize-url
26
+ version_requirements: &id001 !ruby/object:Gem::Requirement
27
+ none: false
24
28
  requirements:
25
29
  - - ">="
26
30
  - !ruby/object:Gem::Version
31
+ hash: 29
27
32
  segments:
33
+ - 0
28
34
  - 1
29
35
  - 3
30
- - 0
31
- version: 1.3.0
36
+ version: 0.1.3
37
+ requirement: *id001
38
+ - !ruby/object:Gem::Dependency
32
39
  type: :development
33
- version_requirements: *id001
40
+ prerelease: false
41
+ name: rspec
42
+ version_requirements: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 2
50
+ - 3
51
+ - 0
52
+ version: 2.3.0
53
+ requirement: *id002
34
54
  - !ruby/object:Gem::Dependency
35
- name: sanitize-url
55
+ type: :development
36
56
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
57
+ name: bluecloth
58
+ version_requirements: &id003 !ruby/object:Gem::Requirement
59
+ none: false
38
60
  requirements:
39
61
  - - ">="
40
62
  - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ requirement: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ type: :development
70
+ prerelease: false
71
+ name: yard
72
+ version_requirements: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ hash: 7
78
+ segments:
79
+ - 0
80
+ - 6
81
+ - 0
82
+ version: 0.6.0
83
+ requirement: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ type: :development
86
+ prerelease: false
87
+ name: bundler
88
+ version_requirements: &id005 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ hash: 23
41
94
  segments:
95
+ - 1
96
+ - 0
42
97
  - 0
98
+ version: 1.0.0
99
+ requirement: *id005
100
+ - !ruby/object:Gem::Dependency
101
+ type: :development
102
+ prerelease: false
103
+ name: jeweler
104
+ version_requirements: &id006 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ hash: 7
110
+ segments:
43
111
  - 1
44
- - 3
45
- version: 0.1.3
46
- type: :runtime
47
- version_requirements: *id002
112
+ - 5
113
+ - 2
114
+ version: 1.5.2
115
+ requirement: *id006
48
116
  description: RbbCode is a customizable Ruby library for parsing BB Code. RbbCode validates and cleans input. It supports customizable schemas so you can set rules about what tags are allowed where. The default rules are designed to ensure valid HTML output.
49
- email: jarrett@jarrettcolby.com
117
+ email: jarrett@jarrettcolby.com, aq1018@gmail.com
50
118
  executables: []
51
119
 
52
120
  extensions: []
53
121
 
54
122
  extra_rdoc_files:
123
+ - LICENSE.txt
55
124
  - README.markdown
56
125
  files:
126
+ - .document
127
+ - Gemfile
128
+ - LICENSE.txt
129
+ - README.markdown
130
+ - Rakefile
131
+ - VERSION
57
132
  - lib/rbbcode.rb
58
133
  - lib/rbbcode/html_maker.rb
59
134
  - lib/rbbcode/parser.rb
60
135
  - lib/rbbcode/schema.rb
61
136
  - lib/rbbcode/tree_maker.rb
62
- - README.markdown
137
+ - pkg/rbbcode-0.1.8.gem
138
+ - rbbcode.gemspec
139
+ - spec/html_maker_spec.rb
140
+ - spec/node_spec_helper.rb
141
+ - spec/parser_spec.rb
142
+ - spec/schema_spec.rb
143
+ - spec/spec_helper.rb
144
+ - spec/tree_maker_spec.rb
63
145
  has_rdoc: true
64
146
  homepage: http://github.com/jarrett/rbbcode
65
- licenses: []
66
-
147
+ licenses:
148
+ - MIT
67
149
  post_install_message:
68
- rdoc_options:
69
- - --charset=UTF-8
150
+ rdoc_options: []
151
+
70
152
  require_paths:
71
153
  - lib
72
154
  required_ruby_version: !ruby/object:Gem::Requirement
155
+ none: false
73
156
  requirements:
74
157
  - - ">="
75
158
  - !ruby/object:Gem::Version
159
+ hash: 3
76
160
  segments:
77
161
  - 0
78
162
  version: "0"
79
163
  required_rubygems_version: !ruby/object:Gem::Requirement
164
+ none: false
80
165
  requirements:
81
166
  - - ">="
82
167
  - !ruby/object:Gem::Version
168
+ hash: 3
83
169
  segments:
84
170
  - 0
85
171
  version: "0"
86
172
  requirements: []
87
173
 
88
174
  rubyforge_project:
89
- rubygems_version: 1.3.6
175
+ rubygems_version: 1.3.7
90
176
  signing_key:
91
177
  specification_version: 3
92
178
  summary: Ruby BB Code parser