radius 0.5.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,139 @@
1
+ module Radius
2
+ #
3
+ # A context contains the tag definitions which are available for use in a template.
4
+ # See the QUICKSTART for a detailed explaination its
5
+ # usage.
6
+ #
7
+ class Context
8
+ # A hash of tag definition blocks that define tags accessible on a Context.
9
+ attr_accessor :definitions # :nodoc:
10
+ attr_accessor :globals # :nodoc:
11
+
12
+ # Creates a new Context object.
13
+ def initialize(&block)
14
+ @definitions = {}
15
+ @tag_binding_stack = []
16
+ @globals = DelegatingOpenStruct.new
17
+ with(&block) if block_given?
18
+ end
19
+
20
+ # Yeild an instance of self for tag definitions:
21
+ #
22
+ # context.with do |c|
23
+ # c.define_tag 'test' do
24
+ # 'test'
25
+ # end
26
+ # end
27
+ #
28
+ def with
29
+ yield self
30
+ self
31
+ end
32
+
33
+ # Creates a tag definition on a context. Several options are available to you
34
+ # when creating a tag:
35
+ #
36
+ # +for+:: Specifies an object that the tag is in reference to. This is
37
+ # applicable when a block is not passed to the tag, or when the
38
+ # +expose+ option is also used.
39
+ #
40
+ # +expose+:: Specifies that child tags should be set for each of the methods
41
+ # contained in this option. May be either a single symbol/string or
42
+ # an array of symbols/strings.
43
+ #
44
+ # +attributes+:: Specifies whether or not attributes should be exposed
45
+ # automatically. Useful for ActiveRecord objects. Boolean. Defaults
46
+ # to +true+.
47
+ #
48
+ def define_tag(name, options = {}, &block)
49
+ type = Utility.impartial_hash_delete(options, :type).to_s
50
+ klass = Utility.constantize('Radius::TagDefinitions::' + Utility.camelize(type) + 'TagFactory') rescue raise(ArgumentError.new("Undefined type `#{type}' in options hash"))
51
+ klass.new(self).define_tag(name, options, &block)
52
+ end
53
+
54
+ # Returns the value of a rendered tag. Used internally by Parser#parse.
55
+ def render_tag(name, attributes = {}, &block)
56
+ if name =~ /^(.+?):(.+)$/
57
+ render_tag($1) { render_tag($2, attributes, &block) }
58
+ else
59
+ tag_definition_block = @definitions[qualified_tag_name(name.to_s)]
60
+ if tag_definition_block
61
+ stack(name, attributes, block) do |tag|
62
+ tag_definition_block.call(tag).to_s
63
+ end
64
+ else
65
+ tag_missing(name, attributes, &block)
66
+ end
67
+ end
68
+ end
69
+
70
+ # Like method_missing for objects, but fired when a tag is undefined.
71
+ # Override in your own Context to change what happens when a tag is
72
+ # undefined. By default this method raises an UndefinedTagError.
73
+ def tag_missing(name, attributes, &block)
74
+ raise UndefinedTagError.new(name)
75
+ end
76
+
77
+ # Returns the state of the current render stack. Useful from inside
78
+ # a tag definition. Normally just use TagBinding#nesting.
79
+ def current_nesting
80
+ @tag_binding_stack.collect { |tag| tag.name }.join(':')
81
+ end
82
+
83
+ private
84
+
85
+ # A convienence method for managing the various parts of the
86
+ # tag binding stack.
87
+ def stack(name, attributes, block)
88
+ previous = @tag_binding_stack.last
89
+ previous_locals = previous.nil? ? @globals : previous.locals
90
+ locals = DelegatingOpenStruct.new(previous_locals)
91
+ binding = TagBinding.new(self, locals, name, attributes, block)
92
+ @tag_binding_stack.push(binding)
93
+ result = yield(binding)
94
+ @tag_binding_stack.pop
95
+ result
96
+ end
97
+
98
+ # Returns a fully qualified tag name based on state of the
99
+ # tag binding stack.
100
+ def qualified_tag_name(name)
101
+ nesting_parts = @tag_binding_stack.collect { |tag| tag.name }
102
+ nesting_parts << name unless nesting_parts.last == name
103
+ specific_name = nesting_parts.join(':') # specific_name always has the highest specificity
104
+ unless @definitions.has_key? specific_name
105
+ possible_matches = @definitions.keys.grep(/(^|:)#{name}$/)
106
+ specificity = possible_matches.inject({}) { |hash, tag| hash[numeric_specificity(tag, nesting_parts)] = tag; hash }
107
+ max = specificity.keys.max
108
+ if max != 0
109
+ specificity[max]
110
+ else
111
+ name
112
+ end
113
+ else
114
+ specific_name
115
+ end
116
+ end
117
+
118
+ # Returns the specificity for +tag_name+ at nesting defined
119
+ # by +nesting_parts+ as a number.
120
+ def numeric_specificity(tag_name, nesting_parts)
121
+ nesting_parts = nesting_parts.dup
122
+ name_parts = tag_name.split(':')
123
+ specificity = 0
124
+ value = 1
125
+ if nesting_parts.last == name_parts.last
126
+ while nesting_parts.size > 0
127
+ if nesting_parts.last == name_parts.last
128
+ specificity += value
129
+ name_parts.pop
130
+ end
131
+ nesting_parts.pop
132
+ value *= 0.1
133
+ end
134
+ specificity = 0 if (name_parts.size > 0)
135
+ end
136
+ specificity
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,31 @@
1
+ module Radius
2
+ class DelegatingOpenStruct # :nodoc:
3
+ attr_accessor :object
4
+
5
+ def initialize(object = nil)
6
+ @object = object
7
+ @hash = {}
8
+ end
9
+
10
+ def method_missing(method, *args, &block)
11
+ symbol = (method.to_s =~ /^(.*?)=$/) ? $1.intern : method
12
+ if (0..1).include?(args.size)
13
+ if args.size == 1
14
+ @hash[symbol] = args.first
15
+ else
16
+ if @hash.has_key?(symbol)
17
+ @hash[symbol]
18
+ else
19
+ unless object.nil?
20
+ @object.send(method, *args, &block)
21
+ else
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ else
27
+ super
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,43 @@
1
+ module Radius
2
+ # Abstract base class for all parsing errors.
3
+ class ParseError < StandardError
4
+ end
5
+
6
+ # Occurs when the Parser expects an end tag for one tag and finds the end tag for another.
7
+ class WrongEndTagError < ParseError
8
+ def initialize(expected_tag, got_tag, stack)
9
+ stack_message = " with stack #{stack.inspect}" if stack
10
+ super("wrong end tag `#{got_tag}' found for start tag `#{expected_tag}'#{stack_message}")
11
+ end
12
+ end
13
+
14
+ # Occurs when Parser cannot find an end tag for a given tag in a template or when
15
+ # tags are miss-matched in a template.
16
+ class MissingEndTagError < ParseError
17
+ # Create a new MissingEndTagError object for +tag_name+.
18
+ def initialize(tag_name, stack)
19
+ stack_message = " with stack #{stack.inspect}" if stack
20
+ super("end tag not found for start tag `#{tag_name}'#{stack_message}")
21
+ end
22
+ end
23
+
24
+ # Occurs when Context#render_tag cannot find the specified tag on a Context.
25
+ class UndefinedTagError < ParseError
26
+ # Create a new UndefinedTagError object for +tag_name+.
27
+ def initialize(tag_name)
28
+ super("undefined tag `#{tag_name}'")
29
+ end
30
+ end
31
+
32
+ class TastelessTagError < ParseError #:nodoc:
33
+ def initialize(tag, stack)
34
+ super("internal error with tasteless tag #{tag.inspect} and stack #{stack.inspect}")
35
+ end
36
+ end
37
+
38
+ class UndefinedFlavorError < ParseError #:nodoc:
39
+ def initialize(tag, stack)
40
+ super("internal error with unknown flavored tag #{tag.inspect} and stack #{stack.inspect}")
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ module Radius
2
+ class ParseTag # :nodoc:
3
+ def initialize(&b)
4
+ @block = b
5
+ end
6
+
7
+ def on_parse(&b)
8
+ @block = b
9
+ end
10
+
11
+ def to_s
12
+ @block.call(self)
13
+ end
14
+ end
15
+
16
+ class ParseContainerTag < ParseTag # :nodoc:
17
+ attr_accessor :name, :attributes, :contents
18
+
19
+ def initialize(name = "", attributes = {}, contents = [], &b)
20
+ @name, @attributes, @contents = name, attributes, contents
21
+ super(&b)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,65 @@
1
+ module Radius
2
+ #
3
+ # The Radius parser. Initialize a parser with a Context object that
4
+ # defines how tags should be expanded. See the QUICKSTART[link:files/QUICKSTART.html]
5
+ # for a detailed explaination of its usage.
6
+ #
7
+ class Parser
8
+ # The Context object used to expand template tags.
9
+ attr_accessor :context
10
+
11
+ # The string that prefixes all tags that are expanded by a parser
12
+ # (the part in the tag name before the first colon).
13
+ attr_accessor :tag_prefix
14
+
15
+ # Creates a new parser object initialized with a Context.
16
+ def initialize(context = Context.new, options = {})
17
+ if context.kind_of?(Hash) and options.empty?
18
+ options = context
19
+ context = options[:context] || options['context'] || Context.new
20
+ end
21
+ options = Utility.symbolize_keys(options)
22
+ @context = context
23
+ @tag_prefix = options[:tag_prefix] || 'radius'
24
+ end
25
+
26
+ # Parses string for tags, expands them, and returns the result.
27
+ def parse(string)
28
+ @stack = [ParseContainerTag.new { |t| t.contents.to_s }]
29
+ tokenize(string)
30
+ stack_up
31
+ @stack.last.to_s
32
+ end
33
+
34
+ protected
35
+ # Convert the string into a list of text blocks and scanners (tokens)
36
+ def tokenize(string)
37
+ @tokens = Scanner::operate(tag_prefix, string)
38
+ end
39
+
40
+ def stack_up
41
+ @tokens.each do |t|
42
+ if t.is_a? String
43
+ @stack.last.contents << t
44
+ next
45
+ end
46
+ case t[:flavor]
47
+ when :open
48
+ @stack.push(ParseContainerTag.new(t[:name], t[:attrs]))
49
+ when :self
50
+ @stack.last.contents << ParseTag.new {@context.render_tag(t[:name], t[:attrs])}
51
+ when :close
52
+ popped = @stack.pop
53
+ raise WrongEndTagError.new(popped.name, t[:name], @stack) if popped.name != t[:name]
54
+ popped.on_parse { |b| @context.render_tag(popped.name, popped.attributes) { b.contents.to_s } }
55
+ @stack.last.contents << popped
56
+ when :tasteless
57
+ raise TastelessTagError.new(t, @stack)
58
+ else
59
+ raise UndefinedFlavorError.new(t, @stack)
60
+ end
61
+ end
62
+ raise MissingEndTagError.new(@stack.last.name, @stack) if @stack.length != 1
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,700 @@
1
+
2
+ # line 1 "scan.rl"
3
+
4
+ # line 83 "scan.rl"
5
+
6
+
7
+ module Radius
8
+ class Scanner
9
+ def self.operate(prefix, data)
10
+ buf = ""
11
+ csel = ""
12
+ @prematch = ''
13
+ @starttag = nil
14
+ @attrs = {}
15
+ @flavor = :tasteless
16
+ @cursor = 0
17
+ @tagstart = 0
18
+ @nodes = ['']
19
+ remainder = data.dup
20
+
21
+ until remainder.length == 0
22
+ p = perform_parse(prefix, remainder)
23
+ remainder = remainder[p..-1]
24
+ end
25
+
26
+ return @nodes
27
+ end
28
+
29
+ private
30
+ def self.perform_parse(prefix, data)
31
+ stack = []
32
+ p = 0
33
+ ts = 0
34
+ te = 0
35
+ act = 0
36
+ eof = data.length
37
+
38
+ @prefix = prefix
39
+
40
+ # line 41 "scan.rb"
41
+ class << self
42
+ attr_accessor :_parser_actions
43
+ private :_parser_actions, :_parser_actions=
44
+ end
45
+ self._parser_actions = [
46
+ 0, 1, 0, 1, 1, 1, 2, 1,
47
+ 3, 1, 4, 1, 5, 1, 6, 1,
48
+ 7, 1, 8, 1, 9, 1, 13, 1,
49
+ 14, 1, 18, 1, 20, 1, 21, 1,
50
+ 22, 2, 4, 5, 2, 5, 6, 2,
51
+ 8, 4, 2, 8, 9, 2, 9, 8,
52
+ 2, 10, 19, 2, 11, 19, 2, 12,
53
+ 19, 2, 15, 16, 2, 15, 17, 3,
54
+ 4, 5, 6, 3, 8, 4, 5, 3,
55
+ 15, 5, 16, 4, 8, 4, 5, 6,
56
+ 4, 15, 4, 5, 16, 5, 15, 8,
57
+ 4, 5, 16
58
+ ]
59
+
60
+ class << self
61
+ attr_accessor :_parser_key_offsets
62
+ private :_parser_key_offsets, :_parser_key_offsets=
63
+ end
64
+ self._parser_key_offsets = [
65
+ 0, 0, 11, 21, 34, 47, 61, 65,
66
+ 70, 72, 74, 87, 100, 101, 103, 118,
67
+ 133, 149, 155, 161, 176, 179, 182, 185,
68
+ 200, 202, 204, 219, 235, 241, 247, 250,
69
+ 253, 269, 285, 302, 309, 315, 331, 335,
70
+ 351, 366, 369, 371, 381, 392, 402, 416,
71
+ 420, 420, 421, 430, 430, 430, 432, 434,
72
+ 437, 440, 442, 444
73
+ ]
74
+
75
+ class << self
76
+ attr_accessor :_parser_trans_keys
77
+ private :_parser_trans_keys, :_parser_trans_keys=
78
+ end
79
+ self._parser_trans_keys = [
80
+ 58, 63, 95, 45, 46, 48, 57, 65,
81
+ 90, 97, 122, 63, 95, 45, 46, 48,
82
+ 58, 65, 90, 97, 122, 32, 47, 62,
83
+ 63, 95, 9, 13, 45, 58, 65, 90,
84
+ 97, 122, 32, 47, 62, 63, 95, 9,
85
+ 13, 45, 58, 65, 90, 97, 122, 32,
86
+ 61, 63, 95, 9, 13, 45, 46, 48,
87
+ 58, 65, 90, 97, 122, 32, 61, 9,
88
+ 13, 32, 34, 39, 9, 13, 34, 92,
89
+ 34, 92, 32, 47, 62, 63, 95, 9,
90
+ 13, 45, 58, 65, 90, 97, 122, 32,
91
+ 47, 62, 63, 95, 9, 13, 45, 58,
92
+ 65, 90, 97, 122, 62, 34, 92, 32,
93
+ 34, 47, 62, 63, 92, 95, 9, 13,
94
+ 45, 58, 65, 90, 97, 122, 32, 34,
95
+ 47, 62, 63, 92, 95, 9, 13, 45,
96
+ 58, 65, 90, 97, 122, 32, 34, 61,
97
+ 63, 92, 95, 9, 13, 45, 46, 48,
98
+ 58, 65, 90, 97, 122, 32, 34, 61,
99
+ 92, 9, 13, 32, 34, 39, 92, 9,
100
+ 13, 32, 34, 47, 62, 63, 92, 95,
101
+ 9, 13, 45, 58, 65, 90, 97, 122,
102
+ 34, 62, 92, 34, 39, 92, 34, 39,
103
+ 92, 32, 39, 47, 62, 63, 92, 95,
104
+ 9, 13, 45, 58, 65, 90, 97, 122,
105
+ 39, 92, 39, 92, 32, 39, 47, 62,
106
+ 63, 92, 95, 9, 13, 45, 58, 65,
107
+ 90, 97, 122, 32, 39, 61, 63, 92,
108
+ 95, 9, 13, 45, 46, 48, 58, 65,
109
+ 90, 97, 122, 32, 39, 61, 92, 9,
110
+ 13, 32, 34, 39, 92, 9, 13, 34,
111
+ 39, 92, 34, 39, 92, 32, 34, 39,
112
+ 47, 62, 63, 92, 95, 9, 13, 45,
113
+ 58, 65, 90, 97, 122, 32, 34, 39,
114
+ 47, 62, 63, 92, 95, 9, 13, 45,
115
+ 58, 65, 90, 97, 122, 32, 34, 39,
116
+ 61, 63, 92, 95, 9, 13, 45, 46,
117
+ 48, 58, 65, 90, 97, 122, 32, 34,
118
+ 39, 61, 92, 9, 13, 32, 34, 39,
119
+ 92, 9, 13, 32, 34, 39, 47, 62,
120
+ 63, 92, 95, 9, 13, 45, 58, 65,
121
+ 90, 97, 122, 34, 39, 62, 92, 32,
122
+ 34, 39, 47, 62, 63, 92, 95, 9,
123
+ 13, 45, 58, 65, 90, 97, 122, 32,
124
+ 39, 47, 62, 63, 92, 95, 9, 13,
125
+ 45, 58, 65, 90, 97, 122, 39, 62,
126
+ 92, 39, 92, 63, 95, 45, 46, 48,
127
+ 57, 65, 90, 97, 122, 58, 63, 95,
128
+ 45, 46, 48, 57, 65, 90, 97, 122,
129
+ 63, 95, 45, 46, 48, 58, 65, 90,
130
+ 97, 122, 32, 62, 63, 95, 9, 13,
131
+ 45, 46, 48, 58, 65, 90, 97, 122,
132
+ 32, 62, 9, 13, 60, 47, 63, 95,
133
+ 45, 57, 65, 90, 97, 122, 34, 92,
134
+ 34, 92, 34, 39, 92, 34, 39, 92,
135
+ 39, 92, 39, 92, 0
136
+ ]
137
+
138
+ class << self
139
+ attr_accessor :_parser_single_lengths
140
+ private :_parser_single_lengths, :_parser_single_lengths=
141
+ end
142
+ self._parser_single_lengths = [
143
+ 0, 3, 2, 5, 5, 4, 2, 3,
144
+ 2, 2, 5, 5, 1, 2, 7, 7,
145
+ 6, 4, 4, 7, 3, 3, 3, 7,
146
+ 2, 2, 7, 6, 4, 4, 3, 3,
147
+ 8, 8, 7, 5, 4, 8, 4, 8,
148
+ 7, 3, 2, 2, 3, 2, 4, 2,
149
+ 0, 1, 3, 0, 0, 2, 2, 3,
150
+ 3, 2, 2, 0
151
+ ]
152
+
153
+ class << self
154
+ attr_accessor :_parser_range_lengths
155
+ private :_parser_range_lengths, :_parser_range_lengths=
156
+ end
157
+ self._parser_range_lengths = [
158
+ 0, 4, 4, 4, 4, 5, 1, 1,
159
+ 0, 0, 4, 4, 0, 0, 4, 4,
160
+ 5, 1, 1, 4, 0, 0, 0, 4,
161
+ 0, 0, 4, 5, 1, 1, 0, 0,
162
+ 4, 4, 5, 1, 1, 4, 0, 4,
163
+ 4, 0, 0, 4, 4, 4, 5, 1,
164
+ 0, 0, 3, 0, 0, 0, 0, 0,
165
+ 0, 0, 0, 0
166
+ ]
167
+
168
+ class << self
169
+ attr_accessor :_parser_index_offsets
170
+ private :_parser_index_offsets, :_parser_index_offsets=
171
+ end
172
+ self._parser_index_offsets = [
173
+ 0, 0, 8, 15, 25, 35, 45, 49,
174
+ 54, 57, 60, 70, 80, 82, 85, 97,
175
+ 109, 121, 127, 133, 145, 149, 153, 157,
176
+ 169, 172, 175, 187, 199, 205, 211, 215,
177
+ 219, 232, 245, 258, 265, 271, 284, 289,
178
+ 302, 314, 318, 321, 328, 336, 343, 353,
179
+ 357, 358, 360, 367, 368, 369, 372, 375,
180
+ 379, 383, 386, 389
181
+ ]
182
+
183
+ class << self
184
+ attr_accessor :_parser_indicies
185
+ private :_parser_indicies, :_parser_indicies=
186
+ end
187
+ self._parser_indicies = [
188
+ 2, 1, 1, 1, 1, 1, 1, 0,
189
+ 3, 3, 3, 3, 3, 3, 0, 4,
190
+ 6, 7, 5, 5, 4, 5, 5, 5,
191
+ 0, 8, 10, 11, 9, 9, 8, 9,
192
+ 9, 9, 0, 13, 15, 14, 14, 13,
193
+ 14, 14, 14, 14, 12, 16, 17, 16,
194
+ 12, 17, 18, 19, 17, 12, 21, 22,
195
+ 20, 24, 25, 23, 26, 28, 29, 27,
196
+ 27, 26, 27, 27, 27, 12, 30, 32,
197
+ 33, 31, 31, 30, 31, 31, 31, 12,
198
+ 34, 12, 35, 25, 23, 36, 24, 38,
199
+ 39, 37, 25, 37, 36, 37, 37, 37,
200
+ 23, 40, 24, 42, 43, 41, 25, 41,
201
+ 40, 41, 41, 41, 23, 44, 24, 46,
202
+ 45, 25, 45, 44, 45, 45, 45, 45,
203
+ 23, 47, 24, 48, 25, 47, 23, 48,
204
+ 49, 50, 25, 48, 23, 51, 21, 53,
205
+ 54, 52, 22, 52, 51, 52, 52, 52,
206
+ 20, 24, 55, 25, 23, 57, 58, 59,
207
+ 56, 61, 35, 62, 60, 64, 24, 66,
208
+ 67, 65, 68, 65, 64, 65, 65, 65,
209
+ 63, 24, 68, 63, 61, 68, 63, 69,
210
+ 24, 71, 72, 70, 68, 70, 69, 70,
211
+ 70, 70, 63, 73, 24, 75, 74, 68,
212
+ 74, 73, 74, 74, 74, 74, 63, 76,
213
+ 24, 77, 68, 76, 63, 77, 78, 79,
214
+ 68, 77, 63, 80, 58, 59, 56, 81,
215
+ 81, 62, 60, 82, 61, 35, 84, 85,
216
+ 83, 62, 83, 82, 83, 83, 83, 60,
217
+ 86, 61, 35, 88, 89, 87, 62, 87,
218
+ 86, 87, 87, 87, 60, 90, 61, 35,
219
+ 92, 91, 62, 91, 90, 91, 91, 91,
220
+ 91, 60, 93, 61, 35, 94, 62, 93,
221
+ 60, 94, 95, 96, 62, 94, 60, 97,
222
+ 80, 58, 99, 100, 98, 59, 98, 97,
223
+ 98, 98, 98, 56, 61, 35, 101, 62,
224
+ 60, 97, 57, 58, 99, 100, 98, 59,
225
+ 98, 97, 98, 98, 98, 56, 103, 21,
226
+ 105, 106, 104, 107, 104, 103, 104, 104,
227
+ 104, 102, 24, 108, 68, 63, 21, 107,
228
+ 102, 109, 109, 109, 109, 109, 109, 0,
229
+ 111, 110, 110, 110, 110, 110, 110, 0,
230
+ 112, 112, 112, 112, 112, 112, 0, 113,
231
+ 115, 114, 114, 113, 114, 114, 114, 114,
232
+ 0, 116, 117, 116, 0, 118, 120, 119,
233
+ 123, 122, 122, 122, 122, 122, 121, 124,
234
+ 125, 24, 25, 23, 24, 25, 23, 61,
235
+ 35, 62, 60, 61, 35, 62, 60, 24,
236
+ 68, 63, 24, 68, 63, 126, 0
237
+ ]
238
+
239
+ class << self
240
+ attr_accessor :_parser_trans_targs
241
+ private :_parser_trans_targs, :_parser_trans_targs=
242
+ end
243
+ self._parser_trans_targs = [
244
+ 49, 1, 2, 3, 4, 3, 12, 52,
245
+ 4, 5, 12, 52, 49, 6, 5, 7,
246
+ 6, 7, 8, 42, 9, 10, 13, 9,
247
+ 10, 13, 11, 5, 12, 52, 11, 5,
248
+ 12, 52, 51, 14, 15, 16, 20, 54,
249
+ 15, 16, 20, 54, 17, 16, 18, 17,
250
+ 18, 19, 21, 15, 16, 20, 54, 53,
251
+ 22, 23, 14, 31, 22, 23, 31, 24,
252
+ 26, 27, 41, 58, 25, 26, 27, 41,
253
+ 58, 28, 27, 29, 28, 29, 30, 40,
254
+ 23, 32, 33, 34, 38, 56, 33, 34,
255
+ 38, 56, 35, 34, 36, 35, 36, 37,
256
+ 39, 33, 34, 38, 56, 55, 24, 26,
257
+ 27, 41, 58, 25, 57, 44, 44, 45,
258
+ 46, 47, 46, 59, 47, 59, 0, 49,
259
+ 50, 49, 1, 43, 49, 49, 49
260
+ ]
261
+
262
+ class << self
263
+ attr_accessor :_parser_trans_actions
264
+ private :_parser_trans_actions, :_parser_trans_actions=
265
+ end
266
+ self._parser_trans_actions = [
267
+ 29, 0, 3, 5, 7, 0, 7, 7,
268
+ 0, 13, 0, 0, 31, 15, 0, 15,
269
+ 0, 0, 0, 0, 17, 42, 17, 0,
270
+ 19, 0, 9, 63, 33, 33, 0, 36,
271
+ 11, 11, 0, 19, 9, 63, 33, 80,
272
+ 0, 36, 11, 71, 15, 0, 15, 0,
273
+ 0, 19, 0, 39, 75, 67, 85, 57,
274
+ 17, 45, 42, 17, 0, 19, 0, 0,
275
+ 9, 63, 33, 80, 0, 0, 36, 11,
276
+ 71, 15, 0, 15, 0, 0, 0, 19,
277
+ 42, 19, 9, 63, 33, 80, 0, 36,
278
+ 11, 71, 15, 0, 15, 0, 0, 19,
279
+ 19, 39, 75, 67, 85, 57, 17, 39,
280
+ 75, 67, 85, 17, 57, 1, 0, 3,
281
+ 5, 7, 0, 7, 0, 0, 0, 25,
282
+ 60, 27, 1, 0, 51, 48, 54
283
+ ]
284
+
285
+ class << self
286
+ attr_accessor :_parser_to_state_actions
287
+ private :_parser_to_state_actions, :_parser_to_state_actions=
288
+ end
289
+ self._parser_to_state_actions = [
290
+ 0, 0, 0, 0, 0, 0, 0, 0,
291
+ 0, 0, 0, 0, 0, 0, 0, 0,
292
+ 0, 0, 0, 0, 0, 0, 0, 0,
293
+ 0, 0, 0, 0, 0, 0, 0, 0,
294
+ 0, 0, 0, 0, 0, 0, 0, 0,
295
+ 0, 0, 0, 0, 0, 0, 0, 0,
296
+ 21, 21, 0, 0, 0, 0, 0, 0,
297
+ 0, 0, 0, 0
298
+ ]
299
+
300
+ class << self
301
+ attr_accessor :_parser_from_state_actions
302
+ private :_parser_from_state_actions, :_parser_from_state_actions=
303
+ end
304
+ self._parser_from_state_actions = [
305
+ 0, 0, 0, 0, 0, 0, 0, 0,
306
+ 0, 0, 0, 0, 0, 0, 0, 0,
307
+ 0, 0, 0, 0, 0, 0, 0, 0,
308
+ 0, 0, 0, 0, 0, 0, 0, 0,
309
+ 0, 0, 0, 0, 0, 0, 0, 0,
310
+ 0, 0, 0, 0, 0, 0, 0, 0,
311
+ 0, 23, 0, 0, 0, 0, 0, 0,
312
+ 0, 0, 0, 0
313
+ ]
314
+
315
+ class << self
316
+ attr_accessor :_parser_eof_trans
317
+ private :_parser_eof_trans, :_parser_eof_trans=
318
+ end
319
+ self._parser_eof_trans = [
320
+ 0, 1, 1, 1, 1, 13, 13, 13,
321
+ 13, 13, 13, 13, 13, 13, 13, 13,
322
+ 13, 13, 13, 13, 13, 13, 13, 13,
323
+ 13, 13, 13, 13, 13, 13, 13, 13,
324
+ 13, 13, 13, 13, 13, 13, 13, 13,
325
+ 13, 13, 13, 1, 1, 1, 1, 1,
326
+ 0, 0, 122, 125, 126, 125, 126, 125,
327
+ 126, 125, 126, 127
328
+ ]
329
+
330
+ class << self
331
+ attr_accessor :parser_start
332
+ end
333
+ self.parser_start = 49;
334
+ class << self
335
+ attr_accessor :parser_first_final
336
+ end
337
+ self.parser_first_final = 49;
338
+ class << self
339
+ attr_accessor :parser_error
340
+ end
341
+ self.parser_error = 0;
342
+
343
+ class << self
344
+ attr_accessor :parser_en_Closeout
345
+ end
346
+ self.parser_en_Closeout = 48;
347
+ class << self
348
+ attr_accessor :parser_en_main
349
+ end
350
+ self.parser_en_main = 49;
351
+
352
+
353
+ # line 118 "scan.rl"
354
+
355
+ # line 356 "scan.rb"
356
+ begin
357
+ p ||= 0
358
+ pe ||= data.length
359
+ cs = parser_start
360
+ ts = nil
361
+ te = nil
362
+ act = 0
363
+ end
364
+
365
+ # line 119 "scan.rl"
366
+
367
+ # line 368 "scan.rb"
368
+ begin
369
+ _klen, _trans, _keys, _acts, _nacts = nil
370
+ _goto_level = 0
371
+ _resume = 10
372
+ _eof_trans = 15
373
+ _again = 20
374
+ _test_eof = 30
375
+ _out = 40
376
+ while true
377
+ _trigger_goto = false
378
+ if _goto_level <= 0
379
+ if p == pe
380
+ _goto_level = _test_eof
381
+ next
382
+ end
383
+ if cs == 0
384
+ _goto_level = _out
385
+ next
386
+ end
387
+ end
388
+ if _goto_level <= _resume
389
+ _acts = _parser_from_state_actions[cs]
390
+ _nacts = _parser_actions[_acts]
391
+ _acts += 1
392
+ while _nacts > 0
393
+ _nacts -= 1
394
+ _acts += 1
395
+ case _parser_actions[_acts - 1]
396
+ when 14 then
397
+ # line 1 "scan.rl"
398
+ begin
399
+ ts = p
400
+ end
401
+ # line 1 "scan.rl"
402
+ # line 403 "scan.rb"
403
+ end # from state action switch
404
+ end
405
+ if _trigger_goto
406
+ next
407
+ end
408
+ _keys = _parser_key_offsets[cs]
409
+ _trans = _parser_index_offsets[cs]
410
+ _klen = _parser_single_lengths[cs]
411
+ _break_match = false
412
+
413
+ begin
414
+ if _klen > 0
415
+ _lower = _keys
416
+ _upper = _keys + _klen - 1
417
+
418
+ loop do
419
+ break if _upper < _lower
420
+ _mid = _lower + ( (_upper - _lower) >> 1 )
421
+
422
+ if data[p] < _parser_trans_keys[_mid]
423
+ _upper = _mid - 1
424
+ elsif data[p] > _parser_trans_keys[_mid]
425
+ _lower = _mid + 1
426
+ else
427
+ _trans += (_mid - _keys)
428
+ _break_match = true
429
+ break
430
+ end
431
+ end # loop
432
+ break if _break_match
433
+ _keys += _klen
434
+ _trans += _klen
435
+ end
436
+ _klen = _parser_range_lengths[cs]
437
+ if _klen > 0
438
+ _lower = _keys
439
+ _upper = _keys + (_klen << 1) - 2
440
+ loop do
441
+ break if _upper < _lower
442
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1)
443
+ if data[p] < _parser_trans_keys[_mid]
444
+ _upper = _mid - 2
445
+ elsif data[p] > _parser_trans_keys[_mid+1]
446
+ _lower = _mid + 2
447
+ else
448
+ _trans += ((_mid - _keys) >> 1)
449
+ _break_match = true
450
+ break
451
+ end
452
+ end # loop
453
+ break if _break_match
454
+ _trans += _klen
455
+ end
456
+ end while false
457
+ _trans = _parser_indicies[_trans]
458
+ end
459
+ if _goto_level <= _eof_trans
460
+ cs = _parser_trans_targs[_trans]
461
+ if _parser_trans_actions[_trans] != 0
462
+ _acts = _parser_trans_actions[_trans]
463
+ _nacts = _parser_actions[_acts]
464
+ _acts += 1
465
+ while _nacts > 0
466
+ _nacts -= 1
467
+ _acts += 1
468
+ case _parser_actions[_acts - 1]
469
+ when 0 then
470
+ # line 5 "scan.rl"
471
+ begin
472
+ mark_pfx = p end
473
+ # line 5 "scan.rl"
474
+ when 1 then
475
+ # line 6 "scan.rl"
476
+ begin
477
+
478
+ if data[mark_pfx..p-1] != @prefix
479
+ @nodes.last << data[mark_pfx-1..p]
480
+ begin
481
+ p += 1
482
+ _trigger_goto = true
483
+ _goto_level = _out
484
+ break
485
+ end
486
+
487
+ end
488
+ end
489
+ # line 6 "scan.rl"
490
+ when 2 then
491
+ # line 12 "scan.rl"
492
+ begin
493
+ mark_stg = p end
494
+ # line 12 "scan.rl"
495
+ when 3 then
496
+ # line 13 "scan.rl"
497
+ begin
498
+ @starttag = data[mark_stg..p-1] end
499
+ # line 13 "scan.rl"
500
+ when 4 then
501
+ # line 14 "scan.rl"
502
+ begin
503
+ mark_attr = p end
504
+ # line 14 "scan.rl"
505
+ when 5 then
506
+ # line 15 "scan.rl"
507
+ begin
508
+
509
+ @attrs[@nat] = @vat
510
+ end
511
+ # line 15 "scan.rl"
512
+ when 6 then
513
+ # line 24 "scan.rl"
514
+ begin
515
+ mark_nat = p end
516
+ # line 24 "scan.rl"
517
+ when 7 then
518
+ # line 25 "scan.rl"
519
+ begin
520
+ @nat = data[mark_nat..p-1] end
521
+ # line 25 "scan.rl"
522
+ when 8 then
523
+ # line 26 "scan.rl"
524
+ begin
525
+ mark_vat = p end
526
+ # line 26 "scan.rl"
527
+ when 9 then
528
+ # line 27 "scan.rl"
529
+ begin
530
+ @vat = data[mark_vat..p-1] end
531
+ # line 27 "scan.rl"
532
+ when 10 then
533
+ # line 29 "scan.rl"
534
+ begin
535
+ @flavor = :open end
536
+ # line 29 "scan.rl"
537
+ when 11 then
538
+ # line 30 "scan.rl"
539
+ begin
540
+ @flavor = :self end
541
+ # line 30 "scan.rl"
542
+ when 12 then
543
+ # line 31 "scan.rl"
544
+ begin
545
+ @flavor = :close end
546
+ # line 31 "scan.rl"
547
+ when 15 then
548
+ # line 1 "scan.rl"
549
+ begin
550
+ te = p+1
551
+ end
552
+ # line 1 "scan.rl"
553
+ when 16 then
554
+ # line 69 "scan.rl"
555
+ begin
556
+ act = 1; end
557
+ # line 69 "scan.rl"
558
+ when 17 then
559
+ # line 78 "scan.rl"
560
+ begin
561
+ act = 2; end
562
+ # line 78 "scan.rl"
563
+ when 18 then
564
+ # line 78 "scan.rl"
565
+ begin
566
+ te = p+1
567
+ begin
568
+ @nodes.last << data[p]
569
+ @tagstart = p
570
+ end
571
+ end
572
+ # line 78 "scan.rl"
573
+ when 19 then
574
+ # line 69 "scan.rl"
575
+ begin
576
+ te = p
577
+ p = p - 1; begin
578
+ tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs}
579
+ @prefix = nil
580
+ @name = nil
581
+ @flavor = :tasteless
582
+ @attrs = {}
583
+ @nodes << tag << ''
584
+ begin
585
+ p += 1
586
+ _trigger_goto = true
587
+ _goto_level = _out
588
+ break
589
+ end
590
+
591
+ end
592
+ end
593
+ # line 69 "scan.rl"
594
+ when 20 then
595
+ # line 78 "scan.rl"
596
+ begin
597
+ te = p
598
+ p = p - 1; begin
599
+ @nodes.last << data[p]
600
+ @tagstart = p
601
+ end
602
+ end
603
+ # line 78 "scan.rl"
604
+ when 21 then
605
+ # line 78 "scan.rl"
606
+ begin
607
+ begin p = ((te))-1; end
608
+ begin
609
+ @nodes.last << data[p]
610
+ @tagstart = p
611
+ end
612
+ end
613
+ # line 78 "scan.rl"
614
+ when 22 then
615
+ # line 1 "scan.rl"
616
+ begin
617
+ case act
618
+ when 1 then
619
+ begin begin p = ((te))-1; end
620
+
621
+ tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs}
622
+ @prefix = nil
623
+ @name = nil
624
+ @flavor = :tasteless
625
+ @attrs = {}
626
+ @nodes << tag << ''
627
+ begin
628
+ p += 1
629
+ _trigger_goto = true
630
+ _goto_level = _out
631
+ break
632
+ end
633
+
634
+ end
635
+ when 2 then
636
+ begin begin p = ((te))-1; end
637
+
638
+ @nodes.last << data[p]
639
+ @tagstart = p
640
+ end
641
+ end
642
+ end
643
+ # line 1 "scan.rl"
644
+ # line 645 "scan.rb"
645
+ end # action switch
646
+ end
647
+ end
648
+ if _trigger_goto
649
+ next
650
+ end
651
+ end
652
+ if _goto_level <= _again
653
+ _acts = _parser_to_state_actions[cs]
654
+ _nacts = _parser_actions[_acts]
655
+ _acts += 1
656
+ while _nacts > 0
657
+ _nacts -= 1
658
+ _acts += 1
659
+ case _parser_actions[_acts - 1]
660
+ when 13 then
661
+ # line 1 "scan.rl"
662
+ begin
663
+ ts = nil; end
664
+ # line 1 "scan.rl"
665
+ # line 666 "scan.rb"
666
+ end # to state action switch
667
+ end
668
+ if _trigger_goto
669
+ next
670
+ end
671
+ if cs == 0
672
+ _goto_level = _out
673
+ next
674
+ end
675
+ p += 1
676
+ if p != pe
677
+ _goto_level = _resume
678
+ next
679
+ end
680
+ end
681
+ if _goto_level <= _test_eof
682
+ if p == eof
683
+ if _parser_eof_trans[cs] > 0
684
+ _trans = _parser_eof_trans[cs] - 1;
685
+ _goto_level = _eof_trans
686
+ next;
687
+ end
688
+ end
689
+ end
690
+ if _goto_level <= _out
691
+ break
692
+ end
693
+ end
694
+ end
695
+
696
+ # line 120 "scan.rl"
697
+ return p
698
+ end
699
+ end
700
+ end