th-bbcode 0.5.0 → 0.6.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.
- data/README.md +11 -0
- data/lib/bbcode.rb +28 -0
- data/lib/bbcode/abstract_handler.rb +19 -0
- data/lib/bbcode/base.rb +8 -6
- data/lib/bbcode/handler.rb +1 -1
- data/lib/bbcode/helpers.rb +9 -1
- data/lib/bbcode/parser.rb +7 -9
- data/lib/bbcode/tokenizer.rb +10 -10
- data/lib/bbcode/version.rb +1 -1
- data/spec/lib/bbcode/base_spec.rb +0 -4
- data/spec/lib/bbcode/helpers_spec.rb +2 -2
- data/spec/lib/bbcode/tokenizer_spec.rb +3 -6
- data/spec/spec_helper.rb +12 -0
- metadata +11 -10
data/README.md
CHANGED
@@ -104,6 +104,17 @@ are no longer replaced automatically: You need to escape them in your handler
|
|
104
104
|
callback yourself. Failing to do so might expose your website to XSS
|
105
105
|
vulnerabilities.
|
106
106
|
|
107
|
+
Using another parser or tokenizer:
|
108
|
+
----------------------------------
|
109
|
+
Although this bbcode parser gem was primary designed for converting bbcode to
|
110
|
+
HTML, it is possible to use another parser or tokenizer while still using the
|
111
|
+
same handlers.
|
112
|
+
|
113
|
+
Using another tokenizer allows you to parse anything as if it were to be
|
114
|
+
bbcode. This feature is still in development, but a nice example is my own
|
115
|
+
ycode gem. This gem can be found here:
|
116
|
+
`https://github.com/tobyhinloopen/y-code`
|
117
|
+
|
107
118
|
Todo:
|
108
119
|
-----
|
109
120
|
* An easier way to handle text around bbcode tags to, for example, add smileys
|
data/lib/bbcode.rb
CHANGED
@@ -4,6 +4,7 @@ require 'action_view/helpers/tag_helper'
|
|
4
4
|
require 'cgi'
|
5
5
|
require "bbcode/version"
|
6
6
|
require "bbcode/tokenizer"
|
7
|
+
require "bbcode/abstract_handler"
|
7
8
|
require "bbcode/parser"
|
8
9
|
require "bbcode/handler"
|
9
10
|
require "bbcode/html_handler"
|
@@ -14,4 +15,31 @@ include ActionView::Helpers::TagHelper
|
|
14
15
|
|
15
16
|
module Bbcode
|
16
17
|
String.send :include, Bbcode::Helpers
|
18
|
+
|
19
|
+
def self.handlers
|
20
|
+
@@handlers ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.handler(name)
|
24
|
+
handlers[name]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.register_handler(name, handler)
|
28
|
+
handlers[name] = handler
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.parsers
|
32
|
+
@@parsers ||= {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.parser(name)
|
36
|
+
parser = parsers[name]
|
37
|
+
parser.respond_to?(:call) ? parser.call : parser
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.register_parser(name, parser = nil, &parser_factory)
|
41
|
+
parsers[name] = (parser || parser_factory)
|
42
|
+
end
|
43
|
+
|
44
|
+
register_parser(:bbcode){ Parser.new(Tokenizer.new) }
|
17
45
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bbcode
|
2
|
+
class AbstractHandler
|
3
|
+
def start_element(tagname, attributes = {}, source = nil); end
|
4
|
+
def end_element(tagname, source = nil); end
|
5
|
+
def text(text); end
|
6
|
+
def interrupt_element(tagname); end
|
7
|
+
def continue_element(tagname); end
|
8
|
+
|
9
|
+
def restart_element(tagname, attributes = {}, source = nil)
|
10
|
+
end_element tagname
|
11
|
+
start_element tagname, attributes, source
|
12
|
+
end
|
13
|
+
|
14
|
+
def void_element(tagname, attributes = {}, source = nil)
|
15
|
+
start_element tagname, attributes, source
|
16
|
+
end_element tagname
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/bbcode/base.rb
CHANGED
@@ -4,22 +4,24 @@ module Bbcode
|
|
4
4
|
|
5
5
|
attr_reader :locals
|
6
6
|
|
7
|
-
def initialize(
|
7
|
+
def initialize(parser, string)
|
8
|
+
@parser = parser
|
8
9
|
@string = string
|
9
10
|
end
|
10
11
|
|
11
|
-
def to(
|
12
|
-
handler =
|
13
|
-
raise "Handler #{handler} isn't registered" if handler.
|
12
|
+
def to(handler_name, locals = {})
|
13
|
+
handler = Bbcode.handler handler_name
|
14
|
+
raise "Handler #{handler} isn't registered." if handler.nil?
|
14
15
|
handler.locals = locals.with_indifferent_access
|
15
|
-
|
16
|
+
@parser.parse @string, handler
|
16
17
|
result = handler.get_document.content.to_s
|
17
18
|
handler.clear
|
18
19
|
result
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.register_handler(name, handler)
|
22
|
-
|
23
|
+
puts "WARNING: Bbcode::Base.register_handler is deprecated. Use Bbcode.register_handler instead."
|
24
|
+
Bbcode.register_handler(name, handler)
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
data/lib/bbcode/handler.rb
CHANGED
data/lib/bbcode/helpers.rb
CHANGED
data/lib/bbcode/parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Bbcode
|
2
2
|
# Attempts to pair a stream of tokens created by a tokenizer
|
3
|
-
class Parser
|
3
|
+
class Parser < AbstractHandler
|
4
4
|
attr_accessor :tokenizer
|
5
5
|
|
6
6
|
def initialize( tokenizer = nil )
|
@@ -14,12 +14,12 @@ module Bbcode
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def text( text )
|
17
|
-
@handler.
|
17
|
+
@handler.text text
|
18
18
|
end
|
19
19
|
|
20
20
|
def start_element( tagname, attributes, source )
|
21
21
|
@tags_stack << tagname
|
22
|
-
@handler.
|
22
|
+
@handler.start_element tagname, attributes, source
|
23
23
|
end
|
24
24
|
|
25
25
|
def end_element( tagname, source )
|
@@ -29,22 +29,20 @@ module Bbcode
|
|
29
29
|
@interruption_stack = []
|
30
30
|
while @tags_stack.last != tagname do
|
31
31
|
@interruption_stack << @tags_stack.last
|
32
|
-
@handler.
|
32
|
+
@handler.interrupt_element @tags_stack.pop
|
33
33
|
end
|
34
34
|
|
35
|
-
@handler.
|
35
|
+
@handler.end_element @tags_stack.pop, source
|
36
36
|
|
37
37
|
while !@interruption_stack.empty? do
|
38
38
|
@tags_stack << @interruption_stack.last
|
39
|
-
@handler.
|
39
|
+
@handler.continue_element @interruption_stack.pop
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def parse( document, handler )
|
44
44
|
@handler = handler
|
45
|
-
@tokenizer.tokenize document
|
46
|
-
self.send *args if [:start_element, :end_element, :text].include?(args.first)
|
47
|
-
end
|
45
|
+
@tokenizer.tokenize document, self
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
data/lib/bbcode/tokenizer.rb
CHANGED
@@ -25,14 +25,14 @@ module Bbcode
|
|
25
25
|
# Parses the document as BBCode-formatted text and calls block with bbcode
|
26
26
|
# events.
|
27
27
|
#
|
28
|
-
# The
|
29
|
-
# -
|
28
|
+
# The handler will have the following methods called:
|
29
|
+
# - .text text
|
30
30
|
# A text-event with an additional parameter containing the actual text.
|
31
|
-
# -
|
31
|
+
# - .start_element element_name, element_arguments
|
32
32
|
# An element-event with 2 additional parameters: The element name as a
|
33
33
|
# symbol and the element attributes as a hash. This events indicate the
|
34
34
|
# start of the element.
|
35
|
-
# -
|
35
|
+
# - .end_element element_name
|
36
36
|
# An element-event indicating the end of an element. Optionally, the
|
37
37
|
# element_name is added as a parameter. If no parameter is present, it is
|
38
38
|
# assumed to be the last started element.
|
@@ -44,12 +44,12 @@ module Bbcode
|
|
44
44
|
# Also note that :text events are not guaranteed to match the whole text.
|
45
45
|
# In some cases, the text might be separated to multiple :text events, even
|
46
46
|
# though there are no nodes in between.
|
47
|
-
def tokenize(
|
47
|
+
def tokenize(document, handler)
|
48
48
|
while !(match = BBCODE_TAG_PATTERN.match(document)).nil?
|
49
49
|
offset = match.begin(0)
|
50
50
|
elem_source = match[0]
|
51
51
|
|
52
|
-
handler.
|
52
|
+
handler.text document[0...offset] unless offset == 0
|
53
53
|
|
54
54
|
elem_is_closing_tag = match[1]=='/'
|
55
55
|
elem_name = (match[2].length > 0 && match[2].to_sym) || nil
|
@@ -57,18 +57,18 @@ module Bbcode
|
|
57
57
|
|
58
58
|
if (elem_is_closing_tag && !elem_attr_string) || (!elem_is_closing_tag && elem_name)
|
59
59
|
if !elem_is_closing_tag
|
60
|
-
handler.
|
60
|
+
handler.start_element elem_name, parse_attributes_string(elem_attr_string), elem_source
|
61
61
|
else
|
62
|
-
handler.
|
62
|
+
handler.end_element elem_name, elem_source
|
63
63
|
end
|
64
64
|
else
|
65
|
-
handler.
|
65
|
+
handler.text elem_source
|
66
66
|
end
|
67
67
|
|
68
68
|
document = document[(offset+elem_source.length)..-1]
|
69
69
|
end
|
70
70
|
|
71
|
-
handler.
|
71
|
+
handler.text document unless document.length == 0
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
data/lib/bbcode/version.rb
CHANGED
@@ -19,8 +19,8 @@ quote_handler.register_element_handlers handler.element_handlers.merge({
|
|
19
19
|
:quote => ->(element){ "[...]" }
|
20
20
|
})
|
21
21
|
|
22
|
-
Bbcode
|
23
|
-
Bbcode
|
22
|
+
Bbcode.register_handler :html, handler
|
23
|
+
Bbcode.register_handler :text, Bbcode::Handler.new
|
24
24
|
|
25
25
|
describe Bbcode::Helpers do
|
26
26
|
it "should enable a string to use a registered helper" do
|
@@ -2,12 +2,9 @@ require 'spec_helper.rb'
|
|
2
2
|
|
3
3
|
def get_tokenizer_results(string, strip_source = true)
|
4
4
|
tokenizer = Bbcode::Tokenizer.new
|
5
|
-
|
6
|
-
tokenizer.tokenize string
|
7
|
-
|
8
|
-
results.push args
|
9
|
-
end
|
10
|
-
results
|
5
|
+
handler = DummyHandler.new strip_source
|
6
|
+
tokenizer.tokenize string, handler
|
7
|
+
handler.stack
|
11
8
|
end
|
12
9
|
|
13
10
|
describe Bbcode::Tokenizer do
|
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,18 @@ require 'bundler/setup'
|
|
3
3
|
|
4
4
|
require 'bbcode'
|
5
5
|
|
6
|
+
class DummyHandler
|
7
|
+
attr_accessor :stack
|
8
|
+
|
9
|
+
def initialize(strip_source)
|
10
|
+
@strip_source = strip_source
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(*args)
|
14
|
+
(@stack ||= []) << args.tap{ |args| args.pop if @strip_source && args.first.to_s.end_with?("element") }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
RSpec.configure do |config|
|
7
19
|
# some (optional) config here
|
8
20
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: th-bbcode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-03-14 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70359577113220 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70359577113220
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &70359577112800 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70359577112800
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: actionpack
|
38
|
-
requirement: &
|
38
|
+
requirement: &70359577112380 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70359577112380
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: i18n
|
49
|
-
requirement: &
|
49
|
+
requirement: &70359577111960 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70359577111960
|
58
58
|
description: Gem for parsing bbcode-formatted strings to HTML or any other formatting
|
59
59
|
you like (or don't like).
|
60
60
|
email:
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- Rakefile
|
70
70
|
- bbcode.gemspec
|
71
71
|
- lib/bbcode.rb
|
72
|
+
- lib/bbcode/abstract_handler.rb
|
72
73
|
- lib/bbcode/base.rb
|
73
74
|
- lib/bbcode/element.rb
|
74
75
|
- lib/bbcode/handler.rb
|