Class: XRT::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/xrt/parser.rb

Instance Method Summary collapse

Constructor Details

#initialize(source = '') ⇒ Parser

Returns a new instance of Parser.



5
6
7
# File 'lib/xrt/parser.rb', line 5

def initialize(source='')
  @source = source
end

Instance Method Details

#documentObject



9
10
11
12
13
14
15
16
# File 'lib/xrt/parser.rb', line 9

def document
  doc = XRT::Statement::Document.new

  tokenized = self.tokens

  parse_contents(tokenized, doc)
  doc
end

#parse_contents(tokenized, node) ⇒ Object

read tokens from tokenized tokens push contents to (container) node returns parsed container node return when tokenized is empty, or node is closed



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
53
54
55
56
57
# File 'lib/xrt/parser.rb', line 22

def parse_contents(tokenized, node)
  while tokenized.length > 0
    statement = XRT::Statement::Factory.new_from_content(tokenized.shift)

    case statement
    when XRT::Statement::Tag
      parse_contents(tokenized, statement)
      if statement.tag_opening?
        statement = XRT::Statement::TagPair.new(statement)
        parse_contents(tokenized, statement)
        node << statement
        next
      elsif statement.tag_closing?
        statement = XRT::Statement::TagPairEnd.new(statement)
        node << statement
        break
      else
        node << statement
        next
      end
    end

    case statement
    when XRT::Statement::Block
      parse_contents(tokenized, statement)
      node << statement
    when XRT::Statement::End
      node << statement
      break
    else
      node << statement
    end
  end

  node
end

#read_directive(source) ⇒ Object



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

def read_directive source
  return nil unless source[0...2] == '[%'

  buffer = ''
  while source[0...2] != '%]'
    buffer << source.slice!(0)
  end
  buffer << source.slice!(0, 2)
  buffer
end

#read_tag_end(source) ⇒ Object



128
129
130
131
# File 'lib/xrt/parser.rb', line 128

def read_tag_end source
  return nil unless source[0] == '>'
  source.slice!(0)
end

#read_tag_start(source) ⇒ Object



123
124
125
126
# File 'lib/xrt/parser.rb', line 123

def read_tag_start source
  return nil unless source[0] == '<'
  source.slice!(0)
end

#read_text(source) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/xrt/parser.rb', line 104

def read_text source
  return nil if source[0...2] == '[%'
  return nil if source[0] == '<'
  return nil if source[0] == '>'

  buffer = ''
  while true
    return buffer if source[0...2] == '[%'
    return buffer if source[0] == '<'
    return buffer if source[0] == '>'
    break if source.length < 2
    buffer << source.slice!(0)
  end

  buffer << source.slice!(0, source.length)

  buffer
end

#split_whitespace(text) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/xrt/parser.rb', line 80

def split_whitespace(text)
  prefix, suffix=nil
  text.sub!(/\A(\s+)/) {|matched|
    prefix = matched
    ''
  }
  text.sub!(/(\s+)\Z/) {|matched|
    suffix = matched
    ''
  }
  [prefix, text, suffix].compact.delete_if{|s| s.empty?}
end

#tokensObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/xrt/parser.rb', line 59

def tokens
  reading = @source.dup
  result = []

  while reading.length > 0
    if got = read_directive(reading)
      result << got
    elsif got = read_tag_start(reading)
      result << got
    elsif got = read_tag_end(reading)
      result << got
    elsif got = read_text(reading)
      result.concat(split_whitespace(got))
    else
      raise "failed to parse #{@source}"
    end
  end

  result
end