Class: RubyBBCode::TagSifter

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-bbcode/tag_sifter.rb

Overview

TagSifter is in charge of building up the BBTree with nodes as it parses through the supplied text such as

"[b]I'm bold and the next word is [i]ITALIC[/i][b]"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text_to_parse, dictionary, escape_html = true) ⇒ TagSifter

Returns a new instance of TagSifter.



10
11
12
13
14
15
16
17
# File 'lib/ruby-bbcode/tag_sifter.rb', line 10

def initialize(text_to_parse, dictionary, escape_html = true)
  @text = escape_html ? text_to_parse.gsub('<', '&lt;').gsub('>', '&gt;').gsub('"', "&quot;") : text_to_parse

  @dictionary = dictionary # dictionary containing all allowed/defined tags
  @bbtree = BBTree.new({:nodes => TagCollection.new})
  @ti = nil
  @errors = []
end

Instance Attribute Details

#bbtreeObject (readonly)

Returns the value of attribute bbtree.



8
9
10
# File 'lib/ruby-bbcode/tag_sifter.rb', line 8

def bbtree
  @bbtree
end

#errorsObject (readonly)

Returns the value of attribute errors.



8
9
10
# File 'lib/ruby-bbcode/tag_sifter.rb', line 8

def errors
  @errors
end

Instance Method Details

#process_textObject

BBTree#process_text is responsible for parsing the actual BBCode text and converting it into a ‘syntax tree’ of nodes, each node represeting either a tag type or content for a tag once this tree is built, the to_html method can be invoked where the tree is finally converted into HTML syntax.



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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ruby-bbcode/tag_sifter.rb', line 27

def process_text
  regex_string = '((\[ (\/)? ( \* | (\w+)) ((=[^\[\]]+) | (\s\w+=\w+)* | ([^\]]*))? \]) | ([^\[]+))'
  @text.scan(/#{regex_string}/ix) do |tag_info|
    @ti = TagInfo.new(tag_info, @dictionary)

    # if the tag isn't in the @dictionary list, then treat it as text
    @ti.handle_tag_as_text if @ti.element_is_tag? and !@ti.tag_in_dictionary?

    validate_element

    case @ti.type
    when :opening_tag
      element = {:is_tag => true, :tag => @ti[:tag], :definition => @ti.definition, :errors => @ti[:errors], :nodes => TagCollection.new }
      element[:invalid_quick_param] = true if @ti.invalid_quick_param?
      element[:params] = get_formatted_element_params

      @bbtree.retrogress_bbtree if self_closing_tag_reached_a_closer?

      @bbtree.build_up_new_tag(element)

      @bbtree.escalate_bbtree(element)
    when :text
      tag_def = @bbtree.current_node.definition
      if tag_def and tag_def[:multi_tag] == true
        set_multi_tag_to_actual_tag
        tag_def = @bbtree.current_node.definition
      end

      if within_open_tag? and tag_def[:require_between]
        between = get_formatted_between
        @bbtree.current_node[:between] = between
        if use_text_as_parameter?
          value_array = tag_def[:quick_param_format].nil? ? true : between.scan(tag_def[:quick_param_format])[0]
          if value_array.nil?
            if @ti[:invalid_quick_param].nil?
              # Add text element (with error(s))
              add_element = true

              # ...and clear between, as this would result in two 'between' texts
              @bbtree.current_node[:between] = ""
            end
          else
            # Between text can be used as (first) parameter
            @bbtree.current_node[:params][tag_def[:param_tokens][0][:token]] = between
          end
        end
        # Don't add this text node, as it is used as between (and might be used as first param)
        next unless add_element
      end

      create_text_element
    when :closing_tag
      if @ti[:wrong_closing]
        # Convert into text, so it
        @ti.handle_tag_as_text
        create_text_element
      else
        @bbtree.retrogress_bbtree if parent_of_self_closing_tag? and within_open_tag?
        @bbtree.retrogress_bbtree
      end
    end
  end # end of scan loop

  validate_all_tags_closed_off
  validate_stack_level_too_deep_potential
end

#valid?Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/ruby-bbcode/tag_sifter.rb', line 19

def valid?
  @errors.empty?
end