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 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
@@ -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
@@ -4,22 +4,24 @@ module Bbcode
4
4
 
5
5
  attr_reader :locals
6
6
 
7
- def initialize(string, locals = {})
7
+ def initialize(parser, string)
8
+ @parser = parser
8
9
  @string = string
9
10
  end
10
11
 
11
- def to(handler, locals = {})
12
- handler = @@handlers[handler]
13
- raise "Handler #{handler} isn't registered" if handler.blank?
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
- Parser.new(Tokenizer.new).parse @string, handler
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
- @@handlers[name] = handler
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
@@ -1,7 +1,7 @@
1
1
  require "bbcode/handler_element"
2
2
 
3
3
  module Bbcode
4
- class Handler
4
+ class Handler < AbstractHandler
5
5
  attr_accessor :element_handlers, :locals
6
6
 
7
7
  def initialize( element_handlers = nil )
@@ -1,7 +1,15 @@
1
1
  module Bbcode
2
2
  module Helpers
3
+ def parse_with(parser)
4
+ Base.new parser, self.to_s
5
+ end
6
+
7
+ def as(parser_name)
8
+ parse_with Bbcode.parser parser_name
9
+ end
10
+
3
11
  def as_bbcode
4
- Base.new self.to_s
12
+ as :bbcode
5
13
  end
6
14
  end
7
15
  end
@@ -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.send :text, text
17
+ @handler.text text
18
18
  end
19
19
 
20
20
  def start_element( tagname, attributes, source )
21
21
  @tags_stack << tagname
22
- @handler.send :start_element, tagname, attributes, source
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.send :interrupt_element, @tags_stack.pop
32
+ @handler.interrupt_element @tags_stack.pop
33
33
  end
34
34
 
35
- @handler.send :end_element, @tags_stack.pop, source
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.send :continue_element, @interruption_stack.pop
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 do |*args|
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
@@ -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 block is called with the following events:
29
- # - :text, text
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
- # - :start_element, element_name, element_arguments
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
- # - :end_element, element_name
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( document, &handler )
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.call :text, document[0...offset] unless offset == 0
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.call :start_element, elem_name, parse_attributes_string(elem_attr_string), elem_source
60
+ handler.start_element elem_name, parse_attributes_string(elem_attr_string), elem_source
61
61
  else
62
- handler.call :end_element, elem_name, elem_source
62
+ handler.end_element elem_name, elem_source
63
63
  end
64
64
  else
65
- handler.call :text, elem_source
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.call :text, document unless document.length == 0
71
+ handler.text document unless document.length == 0
72
72
  end
73
73
  end
74
74
  end
@@ -1,3 +1,3 @@
1
1
  module Bbcode
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,8 +1,4 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe Bbcode::Base do
4
- it "should enable a handler to be registered and used" do
5
- Bbcode::Base.register_handler :test, Bbcode::Handler.new
6
- Bbcode::Base.new("test").to(:test).should eql("test")
7
- end
8
4
  end
@@ -19,8 +19,8 @@ quote_handler.register_element_handlers handler.element_handlers.merge({
19
19
  :quote => ->(element){ "[...]" }
20
20
  })
21
21
 
22
- Bbcode::Base.register_handler :html, handler
23
- Bbcode::Base.register_handler :text, Bbcode::Handler.new()
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
- results = []
6
- tokenizer.tokenize string do |*args|
7
- args.pop if strip_source && [:end_element, :start_element].include?(args.first) # pop the source
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
@@ -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.5.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-02-26 00:00:00.000000000Z
12
+ date: 2012-03-14 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70094233269240 !ruby/object:Gem::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: *70094233269240
24
+ version_requirements: *70359577113220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70094233268820 !ruby/object:Gem::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: *70094233268820
35
+ version_requirements: *70359577112800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: actionpack
38
- requirement: &70094233268400 !ruby/object:Gem::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: *70094233268400
46
+ version_requirements: *70359577112380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: i18n
49
- requirement: &70094233267980 !ruby/object:Gem::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: *70094233267980
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