Class: Guileless::Parser

Inherits:
StateMachine show all
Includes:
ParseMethods, TagLibrary
Defined in:
lib/guileless/parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ParseMethods

#escape_ampersand, #parse_attribute_name, #parse_attribute_value, #parse_attribute_value_double_quote, #parse_attribute_value_single_quote, #parse_closing_tag, #parse_closing_tag_name, #parse_comment, #parse_left_angled_quote, #parse_linebreak, #parse_tag, #parse_tag_name, #parse_text, #start_tag

Methods included from TagLibrary

#block_level_tags, #closing, #html_tags, #paragraph_container_tags

Methods inherited from StateMachine

before_transition, #state, #transition, transitions

Constructor Details

#initialize(input) ⇒ Parser

Returns a new instance of Parser.



14
15
16
# File 'lib/guileless/parser.rb', line 14

def initialize(input)
  @input = input
end

Instance Attribute Details

#bufferObject (readonly)

Returns the value of attribute buffer.



6
7
8
# File 'lib/guileless/parser.rb', line 6

def buffer
  @buffer
end

#char_countObject (readonly)

Returns the value of attribute char_count.



6
7
8
# File 'lib/guileless/parser.rb', line 6

def char_count
  @char_count
end

#inputObject (readonly)

Returns the value of attribute input.



6
7
8
# File 'lib/guileless/parser.rb', line 6

def input
  @input
end

#streamObject (readonly)

Returns the value of attribute stream.



6
7
8
# File 'lib/guileless/parser.rb', line 6

def stream
  @stream
end

#tag_nameObject (readonly)

Returns the value of attribute tag_name.



6
7
8
# File 'lib/guileless/parser.rb', line 6

def tag_name
  @tag_name
end

#tag_stackObject (readonly)

Returns the value of attribute tag_stack.



6
7
8
# File 'lib/guileless/parser.rb', line 6

def tag_stack
  @tag_stack
end

Instance Method Details

#add_tag_to_stackObject



65
66
67
# File 'lib/guileless/parser.rb', line 65

def add_tag_to_stack
  @tag_stack << tag_name
end

#close_tagObject



69
70
71
# File 'lib/guileless/parser.rb', line 69

def close_tag
  unwind_tag_stack(tag_name)
end

#filtered_inputObject



87
88
89
90
91
# File 'lib/guileless/parser.rb', line 87

def filtered_input
  # Ignoring carriage return should be fine for now,
  # the output doesn't contain newlines.
  input.gsub(/\r/, '')
end

#finish_tagObject



59
60
61
62
63
# File 'lib/guileless/parser.rb', line 59

def finish_tag
  if block_level_tags.include?(tag_name)
    flush_buffer
  end
end

#flush_bufferObject



49
50
51
52
53
54
55
56
57
# File 'lib/guileless/parser.rb', line 49

def flush_buffer
  if wrap_in_paragraph?
    if buffer.buffered? && char_count > 0
      buffer.wrap("<p>", "</p>")
    end
  end
  @char_count = 0
  buffer.flush
end

#last_block_level_tagObject



79
80
81
# File 'lib/guileless/parser.rb', line 79

def last_block_level_tag
  tag_stack.reverse.select{|t| block_level_tags.include?(t) }.first
end

#parse!Object



23
24
25
26
27
# File 'lib/guileless/parser.rb', line 23

def parse!
  reset!
  read while !stream.empty?
  transition(:end)
end

#readObject



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/guileless/parser.rb', line 29

def read
  char = stream.fetch
  value, next_state = Array(self.send("parse_#{state}".to_sym, char))

  if value === nil
    buffer.add char
  elsif value
    buffer.add value
  end

  transition(next_state) if next_state
end

#reset!Object



93
94
95
96
97
98
99
100
# File 'lib/guileless/parser.rb', line 93

def reset!
  @char_count = 0
  @buffer = Guileless::OutputBuffer.new
  @stream = Guileless::InputStream.new(filtered_input)
  @tag_stack = []
  reset_tag_name
  @state = :text
end

#reset_tag_nameObject



83
84
85
# File 'lib/guileless/parser.rb', line 83

def reset_tag_name
  @tag_name = ""
end

#to_htmlObject



18
19
20
21
# File 'lib/guileless/parser.rb', line 18

def to_html
  parse!
  buffer.to_s
end

#unwind_tag_stack(tag) ⇒ Object



73
74
75
76
77
# File 'lib/guileless/parser.rb', line 73

def unwind_tag_stack(tag)
  if tag_stack.include?(tag)
    last_tag = tag_stack.pop while last_tag != tag
  end
end

#wrap_in_paragraph?Boolean

Returns:

  • (Boolean)


42
43
44
45
46
47
# File 'lib/guileless/parser.rb', line 42

def wrap_in_paragraph?
  state == :text &&
  char_count > 0 &&
  buffer.buffered? &&
  (!last_block_level_tag || paragraph_container_tags.include?(last_block_level_tag))
end