rbbcode 0.1.11 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,117 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module RbbCode
4
- class RootNode
5
- def == (other_node)
6
- self.class == other_node.class and self.children == other_node.children
7
- end
8
-
9
- def print_tree(indent = 0)
10
- output = ''
11
- indent.times { output << " " }
12
- output << 'ROOT'
13
- children.each do |child|
14
- output << "\n" << child.print_tree(indent + 1)
15
- end
16
- output << "\n/ROOT"
17
- output
18
- end
19
- end
20
-
21
- class TagNode
22
- def == (other_node)
23
- self.class == other_node.class and self.tag_name == other_node.tag_name and self.value == other_node.value and self.children == other_node.children
24
- end
25
-
26
- def print_tree(indent = 0)
27
- output = ''
28
- indent.times { output << " " }
29
- if value.nil?
30
- output << "[#{tag_name}]"
31
- else
32
- output << "[#{tag_name}=#{value}]"
33
- end
34
- children.each do |child|
35
- output << "\n" << child.print_tree(indent + 1)
36
- end
37
- output << "\n"
38
- indent.times { output << " " }
39
- output << "[/#{tag_name}]"
40
- output
41
- end
42
- end
43
-
44
- class TextNode
45
- def == (other_node)
46
- self.class == other_node.class and self.text == other_node.text
47
- end
48
-
49
- def print_tree(indent = 0)
50
- output = ''
51
- indent.times { output << " " }
52
- output << '"' << text << '"'
53
- end
54
- end
55
- end
56
-
57
- class NodeBuilder
58
- include RbbCode
59
-
60
- def self.build(&block)
61
- builder = new
62
- builder.instance_eval(&block)
63
- builder.root
64
- end
65
-
66
- attr_reader :root
67
-
68
- protected
69
-
70
- def << (node)
71
- @current_parent.children << node
72
- end
73
-
74
- def initialize
75
- @root = RootNode.new
76
- @current_parent = @root
77
- end
78
-
79
- def text(contents, &block)
80
- self << TextNode.new(@current_parent, contents)
81
- end
82
-
83
- def tag(tag_name, value = nil, preformatted = false, &block)
84
- tag_node = TagNode.new(@current_parent, tag_name, value)
85
- tag_node.preformat! if preformatted
86
- self << tag_node
87
- original_parent = @current_parent
88
- @current_parent = tag_node
89
- instance_eval(&block)
90
- @current_parent = original_parent
91
- end
92
- end
93
-
94
- module NodeMatchers
95
- class MatchNode
96
- def initialize(expected_tree)
97
- @expected_tree = expected_tree
98
- end
99
-
100
- def matches?(target)
101
- @target = target
102
- @target == @expected_tree
103
- end
104
-
105
- def failure_message
106
- "Expected:\n\n#{@expected_tree.print_tree}\n\nbut got:\n\n#{@target.print_tree}"
107
- end
108
-
109
- def negative_failure_message
110
- "Expected anything other than:\n\n#{@expected_tree.print_tree}"
111
- end
112
- end
113
-
114
- def match_node(expected_node)
115
- MatchNode.new(expected_node)
116
- end
117
- end
data/spec/parser_spec.rb DELETED
@@ -1,163 +0,0 @@
1
- # coding: utf-8
2
- $KCODE = 'u'
3
-
4
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
5
-
6
- describe RbbCode::Parser do
7
- context '#parse' do
8
- before :each do
9
- @parser = RbbCode::Parser.new
10
- end
11
-
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
161
-
162
- end
163
- end
data/spec/schema_spec.rb DELETED
@@ -1,100 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
-
5
- describe RbbCode::Schema do
6
- before :each do
7
- @schema = RbbCode::Schema.new
8
- @schema.clear
9
- @schema.allow_tags(*RbbCode::DEFAULT_ALLOWED_TAGS)
10
- end
11
-
12
- it 'should allow the default tags at the top level' do
13
- schema = RbbCode::Schema.new
14
- [
15
- 'b',
16
- 'i',
17
- 'u',
18
- 'url',
19
- 'img',
20
- 'code',
21
- 'quote',
22
- 'list'
23
- ].each do |tag|
24
- schema.tag(tag).valid_in_context?().should == true
25
- end
26
- end
27
-
28
- it 'should not allow unknown tags' do
29
- @schema.tag('foo').valid_in_context?().should == false
30
- end
31
-
32
- it 'should return a new SchemaTag object when tag is called' do
33
- @schema.tag('b').should be_a(RbbCode::SchemaTag)
34
- end
35
-
36
- it 'should not allow nesting a tag when may_not_be_nested is called on it' do
37
- @schema.tag('b').may_not_be_nested
38
- @schema.tag('b').valid_in_context?('b').should == false
39
- end
40
-
41
- it 'should allow nesting a tag when may_be_nested is called on it' do
42
- @schema.tag('b').may_not_be_nested
43
- @schema.tag('b').may_be_nested
44
- @schema.tag('b').valid_in_context?('b').should == true
45
- end
46
-
47
- it 'should not allow a tag to descend from another when forbidden by may_not_descend_from' do
48
- @schema.tag('b').may_not_descend_from('u')
49
- @schema.tag('b').valid_in_context?('u').should == false
50
- end
51
-
52
- it 'should allow a tag to descend from another when permitted by may_descend_from' do
53
- @schema.tag('b').may_not_descend_from('u')
54
- @schema.tag('b').may_descend_from('u')
55
- @schema.tag('b').valid_in_context?('u').should == true
56
- end
57
-
58
- it 'should not allow a tag to descend from anything other than the tags specified in must_be_child_of' do
59
- @schema.tag('b').must_be_child_of('u', 'quote')
60
- @schema.tag('b').valid_in_context?('i').should == false
61
- @schema.tag('b').valid_in_context?('u').should == true
62
- @schema.tag('b').valid_in_context?('quote').should == true
63
- end
64
-
65
- it 'should allow a tag to descend from the one specified in must_be_child_of' do
66
- @schema.tag('b').may_not_descend_from('u')
67
- @schema.tag('b').must_be_child_of('u')
68
- @schema.tag('b').valid_in_context?('u').should == true
69
- end
70
-
71
- it 'should not require a tag to be a child of another when need_not_be_child_of is called' do
72
- @schema.tag('b').must_be_child_of('u')
73
- @schema.tag('b').need_not_be_child_of('u')
74
- @schema.tag('b').valid_in_context?('i').should == true
75
- end
76
-
77
- it 'should allow only the specified tag as a child when may_only_be_parent_of is called' do
78
- @schema.tag('list').may_only_be_parent_of('*')
79
- @schema.tag('*').valid_in_context?('list').should == true
80
- @schema.tag('u').valid_in_context?('list').should == false
81
- @schema.tag('u').valid_in_context?('*', 'list').should == true
82
- end
83
-
84
- it 'should not allow text inside a tag when may_not_contain_text is called' do
85
- @schema.tag('list').may_not_contain_text
86
- @schema.text.valid_in_context?('list').should == false
87
- end
88
-
89
- it 'should allow text inside a tag when may_contain_text is called' do
90
- @schema.tag('list').may_not_contain_text
91
- @schema.tag('list').may_contain_text
92
- @schema.text.valid_in_context?('list').should == true
93
- end
94
-
95
- it 'should not allow text or children when must_be_empty is called' do
96
- @schema.tag('br').must_be_empty
97
- @schema.text.valid_in_context?('br').should == false
98
- @schema.tag('b').valid_in_context?('br').should == false
99
- end
100
- end
data/spec/spec_helper.rb DELETED
@@ -1,17 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'rspec'
4
-
5
- require File.expand_path(File.dirname(__FILE__) + '/../lib/rbbcode')
6
-
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,123 +0,0 @@
1
- # encoding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
- require File.expand_path(File.dirname(__FILE__) + '/node_spec_helper')
4
- require 'pp'
5
-
6
- describe RbbCode::TreeMaker do
7
- include NodeMatchers
8
-
9
- context '#make_tree' do
10
- def expect_tree(str, &block)
11
- expected = NodeBuilder.build(&block)
12
- @tree_maker.make_tree(str).should match_node(expected)
13
- end
14
-
15
- before :each do
16
- @schema = RbbCode::Schema.new
17
- @tree_maker = RbbCode::TreeMaker.new(@schema)
18
- end
19
-
20
- it 'makes a tree from a string with one tag' do
21
- str = 'This is [b]bold[/b] text'
22
-
23
- expect_tree(str) do
24
- tag('p') do
25
- text 'This is '
26
- tag('b') { text 'bold' }
27
- text ' text'
28
- end
29
- end
30
- end
31
-
32
- it 'ignores tags that are invalid in their context' do
33
- @schema.tag('u').may_not_descend_from('b')
34
-
35
- str = 'This is [b]bold and [u]underlined[/u][/b] text'
36
-
37
- expect_tree(str) do
38
- tag('p') do
39
- text 'This is '
40
- tag('b') do
41
- text 'bold and '
42
- text 'underlined'
43
- end
44
- text ' text'
45
- end
46
- end
47
- end
48
-
49
- it 'creates paragraph tags' do
50
- str = "This is a paragraph.\n\nThis is another."
51
-
52
- expect_tree(str) do
53
- tag('p') do
54
- text 'This is a paragraph.'
55
- end
56
- tag('p') do
57
- text 'This is another.'
58
- end
59
- end
60
- end
61
-
62
- it 'does not put block-level elements inside paragraph tags' do
63
- str = "This is a list:\n\n[list]\n\n[*]Foo[/i]\n\n[/list]\n\nwith some text after it"
64
-
65
- expect_tree(str) do
66
- tag('p') do
67
- text 'This is a list:'
68
- end
69
- tag('list') do
70
- tag('*') { text 'Foo' }
71
- end
72
- tag('p') do
73
- text 'with some text after it'
74
- end
75
- end
76
- end
77
-
78
- it 'does not insert br tags in the midst of block-level elements' do
79
- str = "List:\n[list]\n[*]Foo[/*]\n[*]Bar[/*]\n[/list]\nText after list"
80
-
81
- expect_tree(str) do
82
- tag('p') do
83
- text 'List:'
84
- end
85
- tag('list') do
86
- tag('*') { text 'Foo' }
87
- tag('*') { text 'Bar' }
88
- end
89
- tag('p') do
90
- text 'Text after list'
91
- end
92
- end
93
- end
94
-
95
- it 'stores tag values' do
96
- str = 'This is a [url=http://google.com]link[/url]'
97
-
98
- expect_tree(str) do
99
- tag('p') do
100
- text 'This is a '
101
- tag('url', 'http://google.com') do
102
- text 'link'
103
- end
104
- end
105
- end
106
- end
107
-
108
- it 'auto-closes twins when the schema says it should' do
109
- str = "[list]\n[*]One\n[*]Two\n[/list]"
110
-
111
- expect_tree(str) do
112
- tag('list') do
113
- tag('*') do
114
- text 'One'
115
- end
116
- tag('*') do
117
- text 'Two'
118
- end
119
- end
120
- end
121
- end
122
- end
123
- end