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 +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +21 -0
- data/README.markdown +11 -7
- data/Rakefile +35 -0
- data/VERSION +1 -0
- data/lib/rbbcode/html_maker.rb +2 -2
- data/lib/rbbcode/parser.rb +1 -1
- data/lib/rbbcode/schema.rb +4 -1
- data/lib/rbbcode/tree_maker.rb +43 -3
- data/pkg/rbbcode-0.1.8.gem +0 -0
- data/rbbcode.gemspec +82 -0
- data/spec/html_maker_spec.rb +2 -0
- data/spec/node_spec_helper.rb +2 -0
- data/spec/parser_spec.rb +151 -105
- data/spec/schema_spec.rb +2 -0
- data/spec/spec_helper.rb +13 -5
- data/spec/tree_maker_spec.rb +2 -1
- metadata +107 -21
data/.document
ADDED
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
|
data/lib/rbbcode/html_maker.rb
CHANGED
@@ -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
|
data/lib/rbbcode/parser.rb
CHANGED
data/lib/rbbcode/schema.rb
CHANGED
@@ -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
|
data/lib/rbbcode/tree_maker.rb
CHANGED
@@ -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
|
-
|
196
|
-
|
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
|
+
|
data/spec/html_maker_spec.rb
CHANGED
data/spec/node_spec_helper.rb
CHANGED
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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 <i>italic</i>.</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 <i>italic</i>.</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
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'test/unit'
|
3
|
-
require '
|
3
|
+
require 'rspec'
|
4
4
|
|
5
|
-
|
6
|
-
# raise 'puts called'
|
7
|
-
#end
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/rbbcode')
|
8
6
|
|
9
|
-
|
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
|
data/spec/tree_maker_spec.rb
CHANGED
@@ -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
|
-
-
|
9
|
-
version: 0.1.
|
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:
|
19
|
+
date: 2011-02-19 00:00:00 -06:00
|
18
20
|
default_executable:
|
19
21
|
dependencies:
|
20
22
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
23
|
+
type: :runtime
|
22
24
|
prerelease: false
|
23
|
-
|
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
|
-
|
31
|
-
|
36
|
+
version: 0.1.3
|
37
|
+
requirement: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
32
39
|
type: :development
|
33
|
-
|
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
|
-
|
55
|
+
type: :development
|
36
56
|
prerelease: false
|
37
|
-
|
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
|
-
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
-
|
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
|
-
|
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.
|
175
|
+
rubygems_version: 1.3.7
|
90
176
|
signing_key:
|
91
177
|
specification_version: 3
|
92
178
|
summary: Ruby BB Code parser
|