bkerley-radius 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.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/radius'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('radius', Radius::VERSION) do |p|
7
+ p.developer('John W. Long', 'me@johnwlong.com')
8
+ p.author = [
9
+ "John W. Long (me@johnwlong.com)",
10
+ "David Chelimsky (dchelimsky@gmail.com)",
11
+ "Bryce Kerley (bkerley@brycekerley.net)"
12
+ ]
13
+ p.changes = p.paragraphs_of("CHANGELOG", 1..2).join("\n\n")
14
+ p.rubyforge_name = p.name # TODO this is default value
15
+ # p.extra_deps = [
16
+ # ['activesupport','>= 2.0.2'],
17
+ # ]
18
+ p.extra_dev_deps = [
19
+ ['newgem', ">= #{::Newgem::VERSION}"]
20
+ ]
21
+
22
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
23
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
24
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
25
+ p.rsync_args = '-av --delete --ignore-errors'
26
+ p.test_globs = "test/**/*_test.rb"
27
+ end
28
+
29
+ require 'newgem/tasks' # load /tasks/*.rake
30
+ Dir['tasks/**/*.rake'].each { |t| load t }
31
+
32
+ # TODO - want other tests/tasks run by default? Add them to the list
33
+ # task :default => [:spec, :features]
data/lib/radius.rb ADDED
@@ -0,0 +1,7 @@
1
+ dir = File.join(File.dirname(__FILE__), 'radius')
2
+ require_files = %w{error tagdefs dostruct tagbinding context parsetag parser/scan parser util}
3
+ require_files.each {|f| require File.join(dir, f)}
4
+
5
+ module Radius
6
+ VERSION = '0.6.1'
7
+ end
@@ -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[link:files/QUICKSTART.html] 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 = Util.impartial_hash_delete(options, :type).to_s
50
+ klass = Util.constantize('Radius::TagDefinitions::' + Util.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,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 = Util.symbolize_keys(options)
22
+ @context = context
23
+ @tag_prefix = options[:tag_prefix]
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,688 @@
1
+ # line 1 "scan.rl"
2
+ # line 82 "scan.rl"
3
+
4
+
5
+ module Radius
6
+ class Scanner
7
+ def self.operate(prefix, data)
8
+ buf = ""
9
+ csel = ""
10
+ @prematch = ''
11
+ @starttag = nil
12
+ @attrs = {}
13
+ @flavor = :tasteless
14
+ @cursor = 0
15
+ @tagstart = 0
16
+ @nodes = ['']
17
+ remainder = data.dup
18
+
19
+ until remainder.length == 0
20
+ p = perform_parse(prefix, remainder)
21
+ remainder = remainder[p..-1]
22
+ end
23
+
24
+ return @nodes
25
+ end
26
+
27
+ private
28
+ def self.perform_parse(prefix, data)
29
+ stack = []
30
+ p = 0
31
+ ts = 0
32
+ te = 0
33
+ act = 0
34
+ eof = data.length
35
+
36
+ @prefix = prefix
37
+
38
+ # line 39 "scan.rb"
39
+ class << self
40
+ attr_accessor :_parser_actions
41
+ private :_parser_actions, :_parser_actions=
42
+ end
43
+ self._parser_actions = [
44
+ 0, 1, 0, 1, 1, 1, 2, 1,
45
+ 3, 1, 4, 1, 5, 1, 6, 1,
46
+ 7, 1, 8, 1, 9, 1, 13, 1,
47
+ 14, 1, 18, 1, 20, 1, 21, 1,
48
+ 22, 2, 4, 5, 2, 5, 6, 2,
49
+ 8, 4, 2, 8, 9, 2, 9, 8,
50
+ 2, 10, 19, 2, 11, 19, 2, 12,
51
+ 19, 2, 15, 16, 2, 15, 17, 3,
52
+ 4, 5, 6, 3, 8, 4, 5, 3,
53
+ 15, 5, 16, 4, 8, 4, 5, 6,
54
+ 4, 15, 4, 5, 16, 5, 15, 8,
55
+ 4, 5, 16
56
+ ]
57
+
58
+ class << self
59
+ attr_accessor :_parser_key_offsets
60
+ private :_parser_key_offsets, :_parser_key_offsets=
61
+ end
62
+ self._parser_key_offsets = [
63
+ 0, 0, 11, 21, 34, 47, 61, 65,
64
+ 70, 72, 74, 87, 100, 101, 103, 118,
65
+ 133, 149, 155, 161, 176, 179, 182, 185,
66
+ 200, 202, 204, 219, 235, 241, 247, 250,
67
+ 253, 269, 285, 302, 309, 315, 331, 335,
68
+ 351, 366, 369, 371, 381, 392, 402, 416,
69
+ 420, 420, 421, 430, 430, 430, 432, 434,
70
+ 437, 440, 442, 444
71
+ ]
72
+
73
+ class << self
74
+ attr_accessor :_parser_trans_keys
75
+ private :_parser_trans_keys, :_parser_trans_keys=
76
+ end
77
+ self._parser_trans_keys = [
78
+ 58, 63, 95, 45, 46, 48, 57, 65,
79
+ 90, 97, 122, 63, 95, 45, 46, 48,
80
+ 58, 65, 90, 97, 122, 32, 47, 62,
81
+ 63, 95, 9, 13, 45, 58, 65, 90,
82
+ 97, 122, 32, 47, 62, 63, 95, 9,
83
+ 13, 45, 58, 65, 90, 97, 122, 32,
84
+ 61, 63, 95, 9, 13, 45, 46, 48,
85
+ 58, 65, 90, 97, 122, 32, 61, 9,
86
+ 13, 32, 34, 39, 9, 13, 34, 92,
87
+ 34, 92, 32, 47, 62, 63, 95, 9,
88
+ 13, 45, 58, 65, 90, 97, 122, 32,
89
+ 47, 62, 63, 95, 9, 13, 45, 58,
90
+ 65, 90, 97, 122, 62, 34, 92, 32,
91
+ 34, 47, 62, 63, 92, 95, 9, 13,
92
+ 45, 58, 65, 90, 97, 122, 32, 34,
93
+ 47, 62, 63, 92, 95, 9, 13, 45,
94
+ 58, 65, 90, 97, 122, 32, 34, 61,
95
+ 63, 92, 95, 9, 13, 45, 46, 48,
96
+ 58, 65, 90, 97, 122, 32, 34, 61,
97
+ 92, 9, 13, 32, 34, 39, 92, 9,
98
+ 13, 32, 34, 47, 62, 63, 92, 95,
99
+ 9, 13, 45, 58, 65, 90, 97, 122,
100
+ 34, 62, 92, 34, 39, 92, 34, 39,
101
+ 92, 32, 39, 47, 62, 63, 92, 95,
102
+ 9, 13, 45, 58, 65, 90, 97, 122,
103
+ 39, 92, 39, 92, 32, 39, 47, 62,
104
+ 63, 92, 95, 9, 13, 45, 58, 65,
105
+ 90, 97, 122, 32, 39, 61, 63, 92,
106
+ 95, 9, 13, 45, 46, 48, 58, 65,
107
+ 90, 97, 122, 32, 39, 61, 92, 9,
108
+ 13, 32, 34, 39, 92, 9, 13, 34,
109
+ 39, 92, 34, 39, 92, 32, 34, 39,
110
+ 47, 62, 63, 92, 95, 9, 13, 45,
111
+ 58, 65, 90, 97, 122, 32, 34, 39,
112
+ 47, 62, 63, 92, 95, 9, 13, 45,
113
+ 58, 65, 90, 97, 122, 32, 34, 39,
114
+ 61, 63, 92, 95, 9, 13, 45, 46,
115
+ 48, 58, 65, 90, 97, 122, 32, 34,
116
+ 39, 61, 92, 9, 13, 32, 34, 39,
117
+ 92, 9, 13, 32, 34, 39, 47, 62,
118
+ 63, 92, 95, 9, 13, 45, 58, 65,
119
+ 90, 97, 122, 34, 39, 62, 92, 32,
120
+ 34, 39, 47, 62, 63, 92, 95, 9,
121
+ 13, 45, 58, 65, 90, 97, 122, 32,
122
+ 39, 47, 62, 63, 92, 95, 9, 13,
123
+ 45, 58, 65, 90, 97, 122, 39, 62,
124
+ 92, 39, 92, 63, 95, 45, 46, 48,
125
+ 57, 65, 90, 97, 122, 58, 63, 95,
126
+ 45, 46, 48, 57, 65, 90, 97, 122,
127
+ 63, 95, 45, 46, 48, 58, 65, 90,
128
+ 97, 122, 32, 62, 63, 95, 9, 13,
129
+ 45, 46, 48, 58, 65, 90, 97, 122,
130
+ 32, 62, 9, 13, 60, 47, 63, 95,
131
+ 45, 57, 65, 90, 97, 122, 34, 92,
132
+ 34, 92, 34, 39, 92, 34, 39, 92,
133
+ 39, 92, 39, 92, 0
134
+ ]
135
+
136
+ class << self
137
+ attr_accessor :_parser_single_lengths
138
+ private :_parser_single_lengths, :_parser_single_lengths=
139
+ end
140
+ self._parser_single_lengths = [
141
+ 0, 3, 2, 5, 5, 4, 2, 3,
142
+ 2, 2, 5, 5, 1, 2, 7, 7,
143
+ 6, 4, 4, 7, 3, 3, 3, 7,
144
+ 2, 2, 7, 6, 4, 4, 3, 3,
145
+ 8, 8, 7, 5, 4, 8, 4, 8,
146
+ 7, 3, 2, 2, 3, 2, 4, 2,
147
+ 0, 1, 3, 0, 0, 2, 2, 3,
148
+ 3, 2, 2, 0
149
+ ]
150
+
151
+ class << self
152
+ attr_accessor :_parser_range_lengths
153
+ private :_parser_range_lengths, :_parser_range_lengths=
154
+ end
155
+ self._parser_range_lengths = [
156
+ 0, 4, 4, 4, 4, 5, 1, 1,
157
+ 0, 0, 4, 4, 0, 0, 4, 4,
158
+ 5, 1, 1, 4, 0, 0, 0, 4,
159
+ 0, 0, 4, 5, 1, 1, 0, 0,
160
+ 4, 4, 5, 1, 1, 4, 0, 4,
161
+ 4, 0, 0, 4, 4, 4, 5, 1,
162
+ 0, 0, 3, 0, 0, 0, 0, 0,
163
+ 0, 0, 0, 0
164
+ ]
165
+
166
+ class << self
167
+ attr_accessor :_parser_index_offsets
168
+ private :_parser_index_offsets, :_parser_index_offsets=
169
+ end
170
+ self._parser_index_offsets = [
171
+ 0, 0, 8, 15, 25, 35, 45, 49,
172
+ 54, 57, 60, 70, 80, 82, 85, 97,
173
+ 109, 121, 127, 133, 145, 149, 153, 157,
174
+ 169, 172, 175, 187, 199, 205, 211, 215,
175
+ 219, 232, 245, 258, 265, 271, 284, 289,
176
+ 302, 314, 318, 321, 328, 336, 343, 353,
177
+ 357, 358, 360, 367, 368, 369, 372, 375,
178
+ 379, 383, 386, 389
179
+ ]
180
+
181
+ class << self
182
+ attr_accessor :_parser_indicies
183
+ private :_parser_indicies, :_parser_indicies=
184
+ end
185
+ self._parser_indicies = [
186
+ 2, 1, 1, 1, 1, 1, 1, 0,
187
+ 3, 3, 3, 3, 3, 3, 0, 4,
188
+ 6, 7, 5, 5, 4, 5, 5, 5,
189
+ 0, 8, 10, 11, 9, 9, 8, 9,
190
+ 9, 9, 0, 13, 15, 14, 14, 13,
191
+ 14, 14, 14, 14, 12, 16, 17, 16,
192
+ 12, 17, 18, 19, 17, 12, 21, 22,
193
+ 20, 24, 25, 23, 26, 28, 29, 27,
194
+ 27, 26, 27, 27, 27, 12, 30, 32,
195
+ 33, 31, 31, 30, 31, 31, 31, 12,
196
+ 34, 12, 35, 25, 23, 36, 24, 38,
197
+ 39, 37, 25, 37, 36, 37, 37, 37,
198
+ 23, 40, 24, 42, 43, 41, 25, 41,
199
+ 40, 41, 41, 41, 23, 44, 24, 46,
200
+ 45, 25, 45, 44, 45, 45, 45, 45,
201
+ 23, 47, 24, 48, 25, 47, 23, 48,
202
+ 49, 50, 25, 48, 23, 51, 21, 53,
203
+ 54, 52, 22, 52, 51, 52, 52, 52,
204
+ 20, 24, 55, 25, 23, 57, 58, 59,
205
+ 56, 61, 35, 62, 60, 64, 24, 66,
206
+ 67, 65, 68, 65, 64, 65, 65, 65,
207
+ 63, 24, 68, 63, 61, 68, 63, 69,
208
+ 24, 71, 72, 70, 68, 70, 69, 70,
209
+ 70, 70, 63, 73, 24, 75, 74, 68,
210
+ 74, 73, 74, 74, 74, 74, 63, 76,
211
+ 24, 77, 68, 76, 63, 77, 78, 79,
212
+ 68, 77, 63, 80, 58, 59, 56, 81,
213
+ 81, 62, 60, 82, 61, 35, 84, 85,
214
+ 83, 62, 83, 82, 83, 83, 83, 60,
215
+ 86, 61, 35, 88, 89, 87, 62, 87,
216
+ 86, 87, 87, 87, 60, 90, 61, 35,
217
+ 92, 91, 62, 91, 90, 91, 91, 91,
218
+ 91, 60, 93, 61, 35, 94, 62, 93,
219
+ 60, 94, 95, 96, 62, 94, 60, 97,
220
+ 80, 58, 99, 100, 98, 59, 98, 97,
221
+ 98, 98, 98, 56, 61, 35, 101, 62,
222
+ 60, 97, 57, 58, 99, 100, 98, 59,
223
+ 98, 97, 98, 98, 98, 56, 103, 21,
224
+ 105, 106, 104, 107, 104, 103, 104, 104,
225
+ 104, 102, 24, 108, 68, 63, 21, 107,
226
+ 102, 109, 109, 109, 109, 109, 109, 0,
227
+ 111, 110, 110, 110, 110, 110, 110, 0,
228
+ 112, 112, 112, 112, 112, 112, 0, 113,
229
+ 115, 114, 114, 113, 114, 114, 114, 114,
230
+ 0, 116, 117, 116, 0, 118, 120, 119,
231
+ 123, 122, 122, 122, 122, 122, 121, 124,
232
+ 125, 24, 25, 23, 24, 25, 23, 61,
233
+ 35, 62, 60, 61, 35, 62, 60, 24,
234
+ 68, 63, 24, 68, 63, 126, 0
235
+ ]
236
+
237
+ class << self
238
+ attr_accessor :_parser_trans_targs
239
+ private :_parser_trans_targs, :_parser_trans_targs=
240
+ end
241
+ self._parser_trans_targs = [
242
+ 49, 1, 2, 3, 4, 3, 12, 52,
243
+ 4, 5, 12, 52, 49, 6, 5, 7,
244
+ 6, 7, 8, 42, 9, 10, 13, 9,
245
+ 10, 13, 11, 5, 12, 52, 11, 5,
246
+ 12, 52, 51, 14, 15, 16, 20, 54,
247
+ 15, 16, 20, 54, 17, 16, 18, 17,
248
+ 18, 19, 21, 15, 16, 20, 54, 53,
249
+ 22, 23, 14, 31, 22, 23, 31, 24,
250
+ 26, 27, 41, 58, 25, 26, 27, 41,
251
+ 58, 28, 27, 29, 28, 29, 30, 40,
252
+ 23, 32, 33, 34, 38, 56, 33, 34,
253
+ 38, 56, 35, 34, 36, 35, 36, 37,
254
+ 39, 33, 34, 38, 56, 55, 24, 26,
255
+ 27, 41, 58, 25, 57, 44, 44, 45,
256
+ 46, 47, 46, 59, 47, 59, 0, 49,
257
+ 50, 49, 1, 43, 49, 49, 49
258
+ ]
259
+
260
+ class << self
261
+ attr_accessor :_parser_trans_actions
262
+ private :_parser_trans_actions, :_parser_trans_actions=
263
+ end
264
+ self._parser_trans_actions = [
265
+ 29, 0, 3, 5, 7, 0, 7, 7,
266
+ 0, 13, 0, 0, 31, 15, 0, 15,
267
+ 0, 0, 0, 0, 17, 42, 17, 0,
268
+ 19, 0, 9, 63, 33, 33, 0, 36,
269
+ 11, 11, 0, 19, 9, 63, 33, 80,
270
+ 0, 36, 11, 71, 15, 0, 15, 0,
271
+ 0, 19, 0, 39, 75, 67, 85, 57,
272
+ 17, 45, 42, 17, 0, 19, 0, 0,
273
+ 9, 63, 33, 80, 0, 0, 36, 11,
274
+ 71, 15, 0, 15, 0, 0, 0, 19,
275
+ 42, 19, 9, 63, 33, 80, 0, 36,
276
+ 11, 71, 15, 0, 15, 0, 0, 19,
277
+ 19, 39, 75, 67, 85, 57, 17, 39,
278
+ 75, 67, 85, 17, 57, 1, 0, 3,
279
+ 5, 7, 0, 7, 0, 0, 0, 25,
280
+ 60, 27, 1, 0, 51, 48, 54
281
+ ]
282
+
283
+ class << self
284
+ attr_accessor :_parser_to_state_actions
285
+ private :_parser_to_state_actions, :_parser_to_state_actions=
286
+ end
287
+ self._parser_to_state_actions = [
288
+ 0, 0, 0, 0, 0, 0, 0, 0,
289
+ 0, 0, 0, 0, 0, 0, 0, 0,
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
+ 21, 21, 0, 0, 0, 0, 0, 0,
295
+ 0, 0, 0, 0
296
+ ]
297
+
298
+ class << self
299
+ attr_accessor :_parser_from_state_actions
300
+ private :_parser_from_state_actions, :_parser_from_state_actions=
301
+ end
302
+ self._parser_from_state_actions = [
303
+ 0, 0, 0, 0, 0, 0, 0, 0,
304
+ 0, 0, 0, 0, 0, 0, 0, 0,
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, 23, 0, 0, 0, 0, 0, 0,
310
+ 0, 0, 0, 0
311
+ ]
312
+
313
+ class << self
314
+ attr_accessor :_parser_eof_trans
315
+ private :_parser_eof_trans, :_parser_eof_trans=
316
+ end
317
+ self._parser_eof_trans = [
318
+ 0, 1, 1, 1, 1, 13, 13, 13,
319
+ 13, 13, 13, 13, 13, 13, 13, 13,
320
+ 13, 13, 13, 13, 13, 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, 1, 1, 1, 1, 1,
324
+ 0, 0, 122, 125, 126, 125, 126, 125,
325
+ 126, 125, 126, 127
326
+ ]
327
+
328
+ class << self
329
+ attr_accessor :parser_start
330
+ end
331
+ self.parser_start = 49;
332
+ class << self
333
+ attr_accessor :parser_first_final
334
+ end
335
+ self.parser_first_final = 49;
336
+ class << self
337
+ attr_accessor :parser_error
338
+ end
339
+ self.parser_error = 0;
340
+
341
+ class << self
342
+ attr_accessor :parser_en_Closeout
343
+ end
344
+ self.parser_en_Closeout = 48;
345
+ class << self
346
+ attr_accessor :parser_en_main
347
+ end
348
+ self.parser_en_main = 49;
349
+
350
+ # line 117 "scan.rl"
351
+
352
+ # line 353 "scan.rb"
353
+ begin
354
+ p ||= 0
355
+ pe ||= data.length
356
+ cs = parser_start
357
+ ts = nil
358
+ te = nil
359
+ act = 0
360
+ end
361
+ # line 118 "scan.rl"
362
+
363
+ # line 364 "scan.rb"
364
+ begin
365
+ _klen, _trans, _keys, _acts, _nacts = nil
366
+ _goto_level = 0
367
+ _resume = 10
368
+ _eof_trans = 15
369
+ _again = 20
370
+ _test_eof = 30
371
+ _out = 40
372
+ while true
373
+ _trigger_goto = false
374
+ if _goto_level <= 0
375
+ if p == pe
376
+ _goto_level = _test_eof
377
+ next
378
+ end
379
+ if cs == 0
380
+ _goto_level = _out
381
+ next
382
+ end
383
+ end
384
+ if _goto_level <= _resume
385
+ _acts = _parser_from_state_actions[cs]
386
+ _nacts = _parser_actions[_acts]
387
+ _acts += 1
388
+ while _nacts > 0
389
+ _nacts -= 1
390
+ _acts += 1
391
+ case _parser_actions[_acts - 1]
392
+ when 14 then
393
+ # line 1 "scan.rl"
394
+ begin
395
+ ts = p
396
+ end
397
+ # line 1 "scan.rl"
398
+ # line 399 "scan.rb"
399
+ end # from state action switch
400
+ end
401
+ if _trigger_goto
402
+ next
403
+ end
404
+ _keys = _parser_key_offsets[cs]
405
+ _trans = _parser_index_offsets[cs]
406
+ _klen = _parser_single_lengths[cs]
407
+ _break_match = false
408
+
409
+ begin
410
+ if _klen > 0
411
+ _lower = _keys
412
+ _upper = _keys + _klen - 1
413
+
414
+ loop do
415
+ break if _upper < _lower
416
+ _mid = _lower + ( (_upper - _lower) >> 1 )
417
+
418
+ if data[p] < _parser_trans_keys[_mid]
419
+ _upper = _mid - 1
420
+ elsif data[p] > _parser_trans_keys[_mid]
421
+ _lower = _mid + 1
422
+ else
423
+ _trans += (_mid - _keys)
424
+ _break_match = true
425
+ break
426
+ end
427
+ end # loop
428
+ break if _break_match
429
+ _keys += _klen
430
+ _trans += _klen
431
+ end
432
+ _klen = _parser_range_lengths[cs]
433
+ if _klen > 0
434
+ _lower = _keys
435
+ _upper = _keys + (_klen << 1) - 2
436
+ loop do
437
+ break if _upper < _lower
438
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1)
439
+ if data[p] < _parser_trans_keys[_mid]
440
+ _upper = _mid - 2
441
+ elsif data[p] > _parser_trans_keys[_mid+1]
442
+ _lower = _mid + 2
443
+ else
444
+ _trans += ((_mid - _keys) >> 1)
445
+ _break_match = true
446
+ break
447
+ end
448
+ end # loop
449
+ break if _break_match
450
+ _trans += _klen
451
+ end
452
+ end while false
453
+ _trans = _parser_indicies[_trans]
454
+ end
455
+ if _goto_level <= _eof_trans
456
+ cs = _parser_trans_targs[_trans]
457
+ if _parser_trans_actions[_trans] != 0
458
+ _acts = _parser_trans_actions[_trans]
459
+ _nacts = _parser_actions[_acts]
460
+ _acts += 1
461
+ while _nacts > 0
462
+ _nacts -= 1
463
+ _acts += 1
464
+ case _parser_actions[_acts - 1]
465
+ when 0 then
466
+ # line 5 "scan.rl"
467
+ begin
468
+ mark_pfx = p end
469
+ # line 5 "scan.rl"
470
+ when 1 then
471
+ # line 6 "scan.rl"
472
+ begin
473
+
474
+ if data[mark_pfx..p-1] != @prefix
475
+ cs = 48;
476
+ end
477
+ end
478
+ # line 6 "scan.rl"
479
+ when 2 then
480
+ # line 11 "scan.rl"
481
+ begin
482
+ mark_stg = p end
483
+ # line 11 "scan.rl"
484
+ when 3 then
485
+ # line 12 "scan.rl"
486
+ begin
487
+ @starttag = data[mark_stg..p-1] end
488
+ # line 12 "scan.rl"
489
+ when 4 then
490
+ # line 13 "scan.rl"
491
+ begin
492
+ mark_attr = p end
493
+ # line 13 "scan.rl"
494
+ when 5 then
495
+ # line 14 "scan.rl"
496
+ begin
497
+
498
+ @attrs[@nat] = @vat
499
+ end
500
+ # line 14 "scan.rl"
501
+ when 6 then
502
+ # line 23 "scan.rl"
503
+ begin
504
+ mark_nat = p end
505
+ # line 23 "scan.rl"
506
+ when 7 then
507
+ # line 24 "scan.rl"
508
+ begin
509
+ @nat = data[mark_nat..p-1] end
510
+ # line 24 "scan.rl"
511
+ when 8 then
512
+ # line 25 "scan.rl"
513
+ begin
514
+ mark_vat = p end
515
+ # line 25 "scan.rl"
516
+ when 9 then
517
+ # line 26 "scan.rl"
518
+ begin
519
+ @vat = data[mark_vat..p-1] end
520
+ # line 26 "scan.rl"
521
+ when 10 then
522
+ # line 28 "scan.rl"
523
+ begin
524
+ @flavor = :open end
525
+ # line 28 "scan.rl"
526
+ when 11 then
527
+ # line 29 "scan.rl"
528
+ begin
529
+ @flavor = :self end
530
+ # line 29 "scan.rl"
531
+ when 12 then
532
+ # line 30 "scan.rl"
533
+ begin
534
+ @flavor = :close end
535
+ # line 30 "scan.rl"
536
+ when 15 then
537
+ # line 1 "scan.rl"
538
+ begin
539
+ te = p+1
540
+ end
541
+ # line 1 "scan.rl"
542
+ when 16 then
543
+ # line 68 "scan.rl"
544
+ begin
545
+ act = 1; end
546
+ # line 68 "scan.rl"
547
+ when 17 then
548
+ # line 77 "scan.rl"
549
+ begin
550
+ act = 2; end
551
+ # line 77 "scan.rl"
552
+ when 18 then
553
+ # line 77 "scan.rl"
554
+ begin
555
+ te = p+1
556
+ begin
557
+ @nodes.last << data[p]
558
+ @tagstart = p
559
+ end
560
+ end
561
+ # line 77 "scan.rl"
562
+ when 19 then
563
+ # line 68 "scan.rl"
564
+ begin
565
+ te = p
566
+ p = p - 1; begin
567
+ tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs}
568
+ @prefix = nil
569
+ @name = nil
570
+ @flavor = :tasteless
571
+ @attrs = {}
572
+ @nodes << tag << ''
573
+ begin
574
+ p += 1
575
+ _trigger_goto = true
576
+ _goto_level = _out
577
+ break
578
+ end
579
+
580
+ end
581
+ end
582
+ # line 68 "scan.rl"
583
+ when 20 then
584
+ # line 77 "scan.rl"
585
+ begin
586
+ te = p
587
+ p = p - 1; begin
588
+ @nodes.last << data[p]
589
+ @tagstart = p
590
+ end
591
+ end
592
+ # line 77 "scan.rl"
593
+ when 21 then
594
+ # line 77 "scan.rl"
595
+ begin
596
+ begin p = ((te))-1; end
597
+ begin
598
+ @nodes.last << data[p]
599
+ @tagstart = p
600
+ end
601
+ end
602
+ # line 77 "scan.rl"
603
+ when 22 then
604
+ # line 1 "scan.rl"
605
+ begin
606
+ case act
607
+ when 1 then
608
+ begin begin p = ((te))-1; end
609
+
610
+ tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs}
611
+ @prefix = nil
612
+ @name = nil
613
+ @flavor = :tasteless
614
+ @attrs = {}
615
+ @nodes << tag << ''
616
+ begin
617
+ p += 1
618
+ _trigger_goto = true
619
+ _goto_level = _out
620
+ break
621
+ end
622
+
623
+ end
624
+ when 2 then
625
+ begin begin p = ((te))-1; end
626
+
627
+ @nodes.last << data[p]
628
+ @tagstart = p
629
+ end
630
+ end
631
+ end
632
+ # line 1 "scan.rl"
633
+ # line 634 "scan.rb"
634
+ end # action switch
635
+ end
636
+ end
637
+ if _trigger_goto
638
+ next
639
+ end
640
+ end
641
+ if _goto_level <= _again
642
+ _acts = _parser_to_state_actions[cs]
643
+ _nacts = _parser_actions[_acts]
644
+ _acts += 1
645
+ while _nacts > 0
646
+ _nacts -= 1
647
+ _acts += 1
648
+ case _parser_actions[_acts - 1]
649
+ when 13 then
650
+ # line 1 "scan.rl"
651
+ begin
652
+ ts = nil; end
653
+ # line 1 "scan.rl"
654
+ # line 655 "scan.rb"
655
+ end # to state action switch
656
+ end
657
+ if _trigger_goto
658
+ next
659
+ end
660
+ if cs == 0
661
+ _goto_level = _out
662
+ next
663
+ end
664
+ p += 1
665
+ if p != pe
666
+ _goto_level = _resume
667
+ next
668
+ end
669
+ end
670
+ if _goto_level <= _test_eof
671
+ if p == eof
672
+ if _parser_eof_trans[cs] > 0
673
+ _trans = _parser_eof_trans[cs] - 1;
674
+ _goto_level = _eof_trans
675
+ next;
676
+ end
677
+ end
678
+ end
679
+ if _goto_level <= _out
680
+ break
681
+ end
682
+ end
683
+ end
684
+ # line 119 "scan.rl"
685
+ return p
686
+ end
687
+ end
688
+ end