agio 0.5.0
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/.gemtest +0 -0
- data/.rspec +2 -0
- data/History.rdoc +3 -0
- data/License.rdoc +23 -0
- data/Manifest.txt +23 -0
- data/README.rdoc +97 -0
- data/Rakefile +35 -0
- data/agio.gemspec +53 -0
- data/bin/agio +17 -0
- data/lib/agio.rb +171 -0
- data/lib/agio/block.rb +132 -0
- data/lib/agio/bourse.rb +340 -0
- data/lib/agio/broker.rb +415 -0
- data/lib/agio/data.rb +90 -0
- data/lib/agio/flags.rb +317 -0
- data/lib/agio/html_element_description.rb +126 -0
- data/spec/block_spec.rb +168 -0
- data/spec/bourse_spec.rb +10 -0
- data/spec/broker_spec.rb +539 -0
- data/spec/data_spec.rb +341 -0
- data/spec/flags_spec.rb +473 -0
- data/spec/html_element_description_spec.rb +52 -0
- data/spec/pmh_spec.rb +31 -0
- data/spec/spec_helper.rb +308 -0
- metadata +216 -0
data/lib/agio/data.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
|
3
|
+
##
|
4
|
+
# A simple wrapper around string data in an HTML document.
|
5
|
+
class Agio::Data
|
6
|
+
def initialize(value)
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :value
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_str
|
17
|
+
value
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
%Q(#<#{self.class} #{value.inspect}>)
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Used mostly for testing.
|
26
|
+
def ==(other)
|
27
|
+
if other.kind_of? Agio::Data
|
28
|
+
self.class == other.class && value == other.value
|
29
|
+
else
|
30
|
+
value == other
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# A simple wrapper around CData in an HTML document.
|
37
|
+
class Agio::CData < Agio::Data; end
|
38
|
+
|
39
|
+
##
|
40
|
+
# A simple wrapper around the string contents of an HTML comment.
|
41
|
+
class Agio::Comment < Agio::Data; end
|
42
|
+
|
43
|
+
##
|
44
|
+
# A simple wrapper around the contents of an XML declaration in an
|
45
|
+
# XHTML document.
|
46
|
+
class Agio::XMLDecl
|
47
|
+
def initialize(options = {})
|
48
|
+
@version = options[:version]
|
49
|
+
@encoding = options[:encoding]
|
50
|
+
@standalone = options[:standalone]
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader :version, :encoding, :standalone
|
54
|
+
|
55
|
+
def to_a
|
56
|
+
[ version, encoding, standalone ]
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
s = %Q(<?xml )
|
61
|
+
s += %Q(version="#{version}" ) unless version.nil?
|
62
|
+
s += %Q(encoding="#{encoding}" ) unless encoding.nil?
|
63
|
+
s += %Q(standalone="#{!!standalone}" ) unless standalone.nil?
|
64
|
+
s += "?>"
|
65
|
+
s
|
66
|
+
end
|
67
|
+
|
68
|
+
def inspect
|
69
|
+
%Q(#<#{self.class} '#{to_s}'>)
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_str
|
73
|
+
to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
def ==(other)
|
77
|
+
case other
|
78
|
+
when String
|
79
|
+
to_s == other
|
80
|
+
when Array
|
81
|
+
to_a == other
|
82
|
+
when Agio::XMLDecl
|
83
|
+
to_s == other.to_s
|
84
|
+
else
|
85
|
+
false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# vim: ft=ruby
|
data/lib/agio/flags.rb
ADDED
@@ -0,0 +1,317 @@
|
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
|
3
|
+
##
|
4
|
+
# Meta-programming methods to help create and manage the flags used to help
|
5
|
+
# keep track of processing state for Agio.
|
6
|
+
module Agio::Flags
|
7
|
+
##
|
8
|
+
# When <tt>extend Agio::Flags</tt> is specified in a class, this will
|
9
|
+
# +extend+ the class methods with Agio::Flags::ClassMethods and +include+
|
10
|
+
# Agio::Flags.
|
11
|
+
def self.extend_object(object)
|
12
|
+
object.extend ClassMethods
|
13
|
+
object.__send__(:include, self)
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Resets the flags to their default state. If +with_public+ is +false+,
|
18
|
+
# the default, only the internal flags will be reset to their initial
|
19
|
+
# state. If +with_public+ is a +true+ value, flags that were initialized
|
20
|
+
# with <tt>:public => true</tt> will also be reset.
|
21
|
+
#
|
22
|
+
# Calls the initializer methods created by the flag methods in
|
23
|
+
# ClassMethods.
|
24
|
+
def reset_flags(with_public = false)
|
25
|
+
self.class.flag_inits.each { |init| __send__ init }
|
26
|
+
self.class.public_flag_inits.each { |init| __send__ init } if with_public
|
27
|
+
end
|
28
|
+
private :reset_flags
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Meta-programming methods to help create flags and accessor and test
|
33
|
+
# methods for those flags.
|
34
|
+
module Agio::Flags::ClassMethods
|
35
|
+
##
|
36
|
+
# Creates a flag. This method is the core method for building flags. Flags
|
37
|
+
# must have a name and may specify one of two options, <tt>:default</tt>
|
38
|
+
# or <tt>:public</tt>.
|
39
|
+
#
|
40
|
+
# flag_builder returns a Hash describing the flag.
|
41
|
+
#
|
42
|
+
# === Options
|
43
|
+
# :default:: The default value for the flag. If not specified, or
|
44
|
+
# not overridden by one of the type helper methods, the
|
45
|
+
# default will be +nil+. If the default is not an immediate
|
46
|
+
# value, the default should be specified in a Proc, as is done
|
47
|
+
# for Array flags: <tt>lambda { [] }</tt>.
|
48
|
+
# :public:: If +true+, indicates that the flag is internal and should
|
49
|
+
# not be exposed to the user. The default is that flags are
|
50
|
+
# private (e.g., <tt>:public => false</tt>).
|
51
|
+
#
|
52
|
+
# === Methods Defined
|
53
|
+
# Four methods are always defined by +flag_builder+ or a type helper
|
54
|
+
# method. The type helper methods mentioned below may override the default
|
55
|
+
# behaviours described below.
|
56
|
+
#
|
57
|
+
# [Init] "init_<em>name</em>". This is always private, and should
|
58
|
+
# only be called through Flags#reset_flags. Sets the value of
|
59
|
+
# the flag to the default value. If the default value returns
|
60
|
+
# to #call, it will be called to provide the default value.
|
61
|
+
# Uses the flag's Setter.
|
62
|
+
# [Getter] "name". Returns the value of the flag.
|
63
|
+
# [Setter] "set_<em>name</em>" if private or "<em>name</em>=" if
|
64
|
+
# public. Sets the flag to the provided value.
|
65
|
+
# [Tester] "<em>name</em>?" Returns +true+ or +false+ for the value
|
66
|
+
# with double negation (e.g., <tt>!!value</tt>).
|
67
|
+
#
|
68
|
+
# When calling flag_builder from a helper method, you can provide a block
|
69
|
+
# that will allow the customization of the Setter or the Tester. The other
|
70
|
+
# methods cannot be overridden.
|
71
|
+
#
|
72
|
+
# === Type Helper Methods
|
73
|
+
#
|
74
|
+
# There are five type helpers defined:
|
75
|
+
#
|
76
|
+
# [string_flag] Creates a flag that works with String values. The
|
77
|
+
# default value is +nil+, unless otherwise specified. If a
|
78
|
+
# non-nil value is provided, the default value will be
|
79
|
+
# wrapped in a Proc that will create a new String object
|
80
|
+
# for every reset. The Setter converts all values (except
|
81
|
+
# +nil+) to a String using #to_s. The Tester will return
|
82
|
+
# +false+ if the value is +nil+ or the String is empty.
|
83
|
+
# [boolean_flag] Creates a flag that works with Boolean values (+true+ or
|
84
|
+
# +false+). The default value for a boolean_flag is
|
85
|
+
# +false+, unless otherwise specified. The Setter converts
|
86
|
+
# all values to +true+ or +false+ through double negation
|
87
|
+
# (e.g., <tt>!!value</tt>). The Tester forces the instance
|
88
|
+
# variable to +true+ or +false+ through double negation.
|
89
|
+
# [integer_flag] Creates a flag that works with integer values. The
|
90
|
+
# default value for an integer_flag is zero, unless
|
91
|
+
# otherwise specified. The Setter converts all values to
|
92
|
+
# integer with #to_i. The Tester returns +true+ if the
|
93
|
+
# value is non-zero. Private integer flags also define two
|
94
|
+
# additional methods, incr_<em>name</em> and
|
95
|
+
# decr_<em>name</em>, that will increment or decrement the
|
96
|
+
# integer value by the value provided.
|
97
|
+
# [hash_flag] Creates a flag that works with Hash values. The default
|
98
|
+
# value is a lambda that creates an empty Hash. The Tester
|
99
|
+
# returns +false+ if the value is +nil+ or the Hash is
|
100
|
+
# empty.
|
101
|
+
# [array_flag] Creates a flag that works with Array values. The default
|
102
|
+
# value is a lambda that creates an empty Array. The
|
103
|
+
# Tester returns +false+ if the value is +nil+ or the
|
104
|
+
# Array is empty.
|
105
|
+
def flag_builder(name, options = {})
|
106
|
+
raise SyntaxError, "Flag #{name} already defined" if flags.has_key? name.to_sym
|
107
|
+
|
108
|
+
default = options[:default]
|
109
|
+
type = options[:type]
|
110
|
+
is_public = options[:public]
|
111
|
+
|
112
|
+
flag = {
|
113
|
+
:ivar => "@flag_#{name}",
|
114
|
+
:init => "init_#{name}".to_sym,
|
115
|
+
:getter => name.to_sym,
|
116
|
+
:setter => (is_public ? "#{name}=" : "set_#{name}").to_sym,
|
117
|
+
:tester => "#{name}?".to_sym,
|
118
|
+
:public => is_public,
|
119
|
+
:type => type,
|
120
|
+
:default => default,
|
121
|
+
}
|
122
|
+
|
123
|
+
# Define the flag initializer
|
124
|
+
define_method(flag[:init]) do
|
125
|
+
value = if default.respond_to? :call
|
126
|
+
default.call
|
127
|
+
else
|
128
|
+
default
|
129
|
+
end
|
130
|
+
__send__(flag[:setter], value)
|
131
|
+
end
|
132
|
+
private flag[:init]
|
133
|
+
|
134
|
+
if is_public
|
135
|
+
public_flag_inits << flag[:init]
|
136
|
+
else
|
137
|
+
flag_inits << flag[:init]
|
138
|
+
end
|
139
|
+
|
140
|
+
# Define the flag getter
|
141
|
+
define_method(flag[:getter]) do
|
142
|
+
instance_variable_get(flag[:ivar])
|
143
|
+
end
|
144
|
+
private flag[:getter] unless is_public
|
145
|
+
|
146
|
+
# Define the flag setter
|
147
|
+
defined = yield :setter, flag[:setter], flag[:ivar] if block_given?
|
148
|
+
|
149
|
+
unless defined
|
150
|
+
define_method(flag[:setter]) do |value|
|
151
|
+
instance_variable_set(flag[:ivar], value)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
private flag[:setter] unless is_public
|
155
|
+
|
156
|
+
# Define the flag tester
|
157
|
+
defined = yield :tester, flag[:tester], flag[:ivar] if block_given?
|
158
|
+
|
159
|
+
unless defined
|
160
|
+
define_method(flag[:tester]) do
|
161
|
+
!!instance_variable_get(ivar)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
private flag[:tester] unless is_public
|
165
|
+
|
166
|
+
flags[name.to_sym] = flag
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Defines a flag optimized for working with strings.
|
171
|
+
def string_flag(name, options = {})
|
172
|
+
options = { :default => nil }.merge(options).merge(:type => :string)
|
173
|
+
|
174
|
+
value = options[:default]
|
175
|
+
options[:default] = case value
|
176
|
+
when nil
|
177
|
+
nil
|
178
|
+
when String
|
179
|
+
lambda { value.dup }
|
180
|
+
else
|
181
|
+
lambda { value.to_s }
|
182
|
+
end
|
183
|
+
|
184
|
+
flag_builder(name, options) do |type, meth, ivar|
|
185
|
+
case type
|
186
|
+
when :setter
|
187
|
+
define_method(meth) do |value|
|
188
|
+
value = value.to_s unless value.nil?
|
189
|
+
instance_variable_set(ivar, value)
|
190
|
+
end
|
191
|
+
when :tester
|
192
|
+
define_method(meth) do
|
193
|
+
value = instance_variable_get(ivar)
|
194
|
+
!(value.nil? or value.empty?)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# Defines a flag optimized for working with Boolean (+true+ or +false+)
|
202
|
+
# values.
|
203
|
+
def boolean_flag(name, options = {})
|
204
|
+
options = { :default => false }.merge(options).merge(:type => :boolean)
|
205
|
+
flag_builder(name, options) do |type, meth, ivar|
|
206
|
+
case type
|
207
|
+
when :setter
|
208
|
+
define_method(meth) do |value|
|
209
|
+
instance_variable_set(ivar, !!value)
|
210
|
+
end
|
211
|
+
when :tester
|
212
|
+
define_method(meth) do
|
213
|
+
!!instance_variable_get(ivar)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
##
|
220
|
+
# Defines a flag optimized for working with integer values.
|
221
|
+
def integer_flag(name, options = {})
|
222
|
+
options = { :default => 0 }.merge(options).merge(:type => :integer)
|
223
|
+
|
224
|
+
flag = flag_builder(name, options) do |type, meth, ivar|
|
225
|
+
case type
|
226
|
+
when :setter
|
227
|
+
define_method(meth) do |value|
|
228
|
+
instance_variable_set(ivar, value.to_i)
|
229
|
+
end
|
230
|
+
when :tester
|
231
|
+
define_method(meth) do
|
232
|
+
instance_variable_get(ivar).nonzero?
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
unless flag[:public]
|
238
|
+
incr = "incr_#{name}".to_sym
|
239
|
+
define_method(incr) do |value|
|
240
|
+
value = instance_variable_get(flag[:ivar]) + value.to_i
|
241
|
+
instance_variable_set(flag[:ivar], value)
|
242
|
+
end
|
243
|
+
private incr
|
244
|
+
|
245
|
+
decr = "decr_#{name}".to_sym
|
246
|
+
define_method(decr) do |value|
|
247
|
+
value = instance_variable_get(flag[:ivar]) - value.to_i
|
248
|
+
instance_variable_set(flag[:ivar], value)
|
249
|
+
end
|
250
|
+
private decr
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# Defines a flag optimized for working with arrays.
|
256
|
+
def array_flag(name, options = {})
|
257
|
+
options = { :default => lambda { [] } }.merge(options)
|
258
|
+
options = options.merge(:type => :array)
|
259
|
+
flag_builder(name, options) do |type, meth, ivar|
|
260
|
+
case type
|
261
|
+
when :setter
|
262
|
+
define_method(meth) do |value|
|
263
|
+
value = [ value ] unless value.nil? or value.kind_of? Array
|
264
|
+
instance_variable_set(ivar, value)
|
265
|
+
end
|
266
|
+
when :tester
|
267
|
+
define_method(meth) do
|
268
|
+
value = instance_variable_get(ivar)
|
269
|
+
!(value.nil? or value.empty?)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# Defines a flag optimized for working with hashes.
|
277
|
+
def hash_flag(name, options = {})
|
278
|
+
options = { :default => lambda { {} } }.merge(options)
|
279
|
+
options = options.merge(:type => :hash)
|
280
|
+
flag_builder(name, options) do |type, meth, ivar|
|
281
|
+
case type
|
282
|
+
when :setter
|
283
|
+
define_method(meth) do |value|
|
284
|
+
raise ArgumentError unless value.nil? or value.kind_of? Hash
|
285
|
+
instance_variable_set(ivar, value)
|
286
|
+
end
|
287
|
+
when :tester
|
288
|
+
define_method(meth) do
|
289
|
+
value = instance_variable_get(ivar)
|
290
|
+
!(value.nil? or value.empty?)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
##
|
297
|
+
# An array of initializer method symbols created so that Flags#reset_flags
|
298
|
+
# can reset flags to their default values.
|
299
|
+
def flag_inits
|
300
|
+
@flag_inits ||= []
|
301
|
+
end
|
302
|
+
|
303
|
+
##
|
304
|
+
# An array of initializer method symbols created so that Flags#reset_flags
|
305
|
+
# does its work appropriately for public flags.
|
306
|
+
def public_flag_inits
|
307
|
+
@public_flag_inits ||= []
|
308
|
+
end
|
309
|
+
|
310
|
+
##
|
311
|
+
# The flags that have been defined.
|
312
|
+
def flags
|
313
|
+
@flags ||= {}
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# vim: ft=ruby
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Agio::HTMLElementDescription is a wrapper around
|
7
|
+
# Nokogiri::HTML::ElementDescription to work around a bug with LibXML2 prior
|
8
|
+
# to 2.7.7. In HTMLParser.c, the #define of INLINE didn't have commas,
|
9
|
+
# meaning that strings were concatenated instead of forming an
|
10
|
+
# array (e.g., what should have been <tt>[ "small", "em" ]</tt> ended up
|
11
|
+
# being <tt>[ "smallem" ]</tt>). This was fixed in libxml2 commit
|
12
|
+
# 4b41f15d... on 20 January 2010 by Eugene Pimenov.
|
13
|
+
#
|
14
|
+
# Nokogiri includes a DefaultDescription hash that contains the same basic
|
15
|
+
# information, so we will use that (with appropriate wrappers) if the
|
16
|
+
# version of LibXML2 is not sufficient to have this bug fixed.
|
17
|
+
class Agio::HTMLElementDescription
|
18
|
+
ver = Nokogiri::VERSION_INFO["libxml"]["loaded"]
|
19
|
+
ver = ver.split(%r{\.}).map { |e| e.to_i }
|
20
|
+
|
21
|
+
ok = ver[0] > 2
|
22
|
+
ok = ok || (ver[0] == 2 and ver[1] > 7)
|
23
|
+
ok = ok || (ver[0] == 2 and ver[1] == 7 and ver[2] >= 7)
|
24
|
+
|
25
|
+
if ok
|
26
|
+
def self.[](name)
|
27
|
+
Nokogiri::HTML::ElementDescription[name]
|
28
|
+
end
|
29
|
+
else
|
30
|
+
def self.[](name)
|
31
|
+
@cache ||= {}
|
32
|
+
|
33
|
+
name = name.downcase
|
34
|
+
desc = @cache[name]
|
35
|
+
|
36
|
+
if desc.nil?
|
37
|
+
desc = Nokogiri::HTML::ElementDescription::DefaultDescriptions[name]
|
38
|
+
desc = if desc.nil?
|
39
|
+
false
|
40
|
+
else
|
41
|
+
self.new(desc)
|
42
|
+
end
|
43
|
+
|
44
|
+
@cache[name] = desc
|
45
|
+
end
|
46
|
+
|
47
|
+
if desc
|
48
|
+
desc
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(desc)
|
56
|
+
@d = desc
|
57
|
+
@name = name.downcase
|
58
|
+
@d = Nokogiri::HTML::ElementDescription::DefaultDescriptions[@name]
|
59
|
+
end
|
60
|
+
|
61
|
+
def name
|
62
|
+
@d ? @d.name : @name
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
"#{name}: #{description}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
"#<#{self.class.name}: #{name} #{description}>"
|
71
|
+
end
|
72
|
+
|
73
|
+
def sub_elements
|
74
|
+
@d ? @d.subelts : []
|
75
|
+
end
|
76
|
+
|
77
|
+
def block?
|
78
|
+
!inline?
|
79
|
+
end
|
80
|
+
|
81
|
+
def inline?
|
82
|
+
@d ? @d.isinline : nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def empty?
|
86
|
+
@d ? @d.empty : nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def implied_start_tag?
|
90
|
+
@d ? @d.startTag : nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def implied_end_tag?
|
94
|
+
@d ? @d.endTag : nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def save_end_tag?
|
98
|
+
@d ? @d.saveEndTag : nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def deprecated?
|
102
|
+
@d ? @d.depr : nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def description
|
106
|
+
@d ? @d.desc : nil
|
107
|
+
end
|
108
|
+
|
109
|
+
def default_sub_element
|
110
|
+
@d ? @d.defaultsubelt : nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def optional_attributes
|
114
|
+
@d ? @d.attrs_opt : []
|
115
|
+
end
|
116
|
+
|
117
|
+
def deprecated_attributes
|
118
|
+
@d ? @d.attrs_depr : []
|
119
|
+
end
|
120
|
+
|
121
|
+
def required_attributes
|
122
|
+
@d ? @d.attrs_req : []
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# vim: ft=ruby
|