radius 0.5.1 → 0.6.1

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.
@@ -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