eimxml 0.0.2 → 0.0.3.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 +24 -95
- data/Rakefile.utirake +374 -0
- data/lib/eim_xml.rb +95 -220
- data/lib/eim_xml/dsl.rb +105 -0
- data/lib/eim_xml/formatter.rb +123 -0
- data/lib/eim_xml/formatter/element_wrapper.rb +7 -0
- data/lib/eim_xml/parser.rb +12 -40
- data/lib/eim_xml/xhtml.rb +84 -56
- data/lib/eim_xml/xhtml/dsl.rb +18 -0
- data/{test → spec}/assertions_test.rb +1 -0
- data/spec/dsl_spec.rb +217 -0
- data/spec/eim_xml_spec.rb +441 -0
- data/spec/formatter_spec.rb +260 -0
- data/spec/parser_spec.rb +102 -0
- data/spec/xhtml_spec.rb +524 -0
- metadata +52 -38
- data/README +0 -58
- data/test/eim_xml_test.rb +0 -648
- data/test/parser_test.rb +0 -102
- data/test/xhtml_test.rb +0 -340
data/lib/eim_xml.rb
CHANGED
@@ -4,99 +4,21 @@
|
|
4
4
|
# You can redistribute it and/or modify it under GPL2.
|
5
5
|
#
|
6
6
|
|
7
|
+
warn "*"*60 << "\n" << <<EOT << "*"*60
|
8
|
+
[DEPRECATION]
|
9
|
+
"eimxml" gem is deprecated.
|
10
|
+
Please use "eim_xml" gem instead.
|
11
|
+
EOT
|
12
|
+
|
7
13
|
module EimXML
|
8
14
|
XML_DECLARATION = %[<?xml version="1.0"?>]
|
9
15
|
|
10
|
-
class BaseDSL
|
11
|
-
def initialize
|
12
|
-
@container = nil
|
13
|
-
yield(self) if block_given?
|
14
|
-
end
|
15
|
-
|
16
|
-
def add(v)
|
17
|
-
@container.add(v)
|
18
|
-
end
|
19
|
-
alias << add
|
20
|
-
|
21
|
-
def self.register(*args)
|
22
|
-
args.each do |klass, name|
|
23
|
-
name ||= klass.name.downcase[/(?:.*\:\:)?(.*)$/, 1]
|
24
|
-
l = __LINE__+1
|
25
|
-
src = "def #{name}(*arg, &proc)\n" <<
|
26
|
-
"e = #{klass}.new(*arg)\n" <<
|
27
|
-
"@container << e if @container\n" <<
|
28
|
-
"if proc\n" <<
|
29
|
-
"oc = @container\n" <<
|
30
|
-
"@container = e\n" <<
|
31
|
-
"begin\n" <<
|
32
|
-
"instance_eval(&proc)\n" <<
|
33
|
-
"ensure\n" <<
|
34
|
-
"@container = oc\n" <<
|
35
|
-
"end\n" <<
|
36
|
-
"end\n" <<
|
37
|
-
"e\n" <<
|
38
|
-
"end"
|
39
|
-
eval(src, binding, __FILE__, l)
|
40
|
-
|
41
|
-
l = __LINE__+1
|
42
|
-
src = "def self.#{name}(*arg, &proc)\n" <<
|
43
|
-
"new.#{name}(*arg, &proc)\n" <<
|
44
|
-
"end"
|
45
|
-
eval(src, binding, __FILE__, l)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class DSL < BaseDSL
|
51
|
-
end
|
52
|
-
|
53
|
-
class OpenDSL
|
54
|
-
def self.register_base(dsl, binding, *args)
|
55
|
-
args.each do |klass, name|
|
56
|
-
name ||= klass.name.downcase[/(?:.*\:\:)?(.*)$/, 1]
|
57
|
-
src = "def #{name}(*arg)\n" <<
|
58
|
-
"e=#{klass}.new(*arg)\n" <<
|
59
|
-
"oc=@container\n" <<
|
60
|
-
"oc << e if oc.is_a?(Element)\n" <<
|
61
|
-
"@container = e\n" <<
|
62
|
-
"begin\n" <<
|
63
|
-
"yield(self) if block_given?\n" <<
|
64
|
-
"e\n" <<
|
65
|
-
"ensure\n" <<
|
66
|
-
"@container = oc\n" <<
|
67
|
-
"end\n" <<
|
68
|
-
"end\n"
|
69
|
-
eval(src, binding, __FILE__, __LINE__-12)
|
70
|
-
|
71
|
-
src = "def self.#{name}(*arg, &proc)\n" <<
|
72
|
-
"self.new.#{name}(*arg, &proc)\n" <<
|
73
|
-
"end"
|
74
|
-
eval(src, binding, __FILE__, __LINE__-3)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.register(*args)
|
79
|
-
register_base(self, binding, *args)
|
80
|
-
end
|
81
|
-
|
82
|
-
attr_reader :container
|
83
|
-
def initialize
|
84
|
-
@container = nil
|
85
|
-
yield(self) if block_given?
|
86
|
-
end
|
87
|
-
|
88
|
-
def add(v)
|
89
|
-
@container.add(v)
|
90
|
-
end
|
91
|
-
alias :<< :add
|
92
|
-
end
|
93
|
-
|
94
16
|
class PCString
|
95
|
-
attr_reader :encoded_string
|
17
|
+
attr_reader :encoded_string, :src
|
96
18
|
alias to_s encoded_string
|
97
19
|
|
98
20
|
def self.encode(s)
|
99
|
-
s.gsub(/[&\"\'<>]/) do |m|
|
21
|
+
s.to_s.gsub(/[&\"\'<>]/) do |m|
|
100
22
|
case m
|
101
23
|
when "&"
|
102
24
|
"&"
|
@@ -112,46 +34,33 @@ module EimXML
|
|
112
34
|
end
|
113
35
|
end
|
114
36
|
|
37
|
+
def self.[](obj)
|
38
|
+
obj.is_a?(PCString) ? obj : PCString.new(obj)
|
39
|
+
end
|
40
|
+
|
115
41
|
def initialize(s, encoded=false)
|
42
|
+
@src = s
|
116
43
|
@encoded_string = encoded ? s : PCString.encode(s)
|
117
44
|
end
|
118
45
|
|
119
46
|
def ==(other)
|
120
|
-
other.is_a?(PCString) ? @encoded_string==other.encoded_string :
|
47
|
+
other.is_a?(PCString) ? @encoded_string==other.encoded_string : self==PCString.new(other)
|
121
48
|
end
|
122
49
|
|
123
|
-
def
|
124
|
-
|
50
|
+
def write_to(out="")
|
51
|
+
out << encoded_string
|
125
52
|
end
|
126
53
|
end
|
127
54
|
|
128
|
-
class
|
129
|
-
def initialize(
|
130
|
-
|
131
|
-
|
132
|
-
super(src)
|
133
|
-
when Hash
|
134
|
-
src.each_key do |k|
|
135
|
-
store(k, src[k])
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def update(src)
|
141
|
-
src = self.class.new(src) unless src.is_a?(self.class)
|
142
|
-
super(src)
|
143
|
-
end
|
144
|
-
alias :merge! :update
|
145
|
-
|
146
|
-
def merge(src)
|
147
|
-
super(self.class.new(src))
|
55
|
+
class Comment
|
56
|
+
def initialize(text)
|
57
|
+
raise ArgumentError, "Can not include '--'" if text =~ /--/
|
58
|
+
@text = text
|
148
59
|
end
|
149
60
|
|
150
|
-
def
|
151
|
-
|
61
|
+
def write_to(out="")
|
62
|
+
out << "<!-- #{@text} -->"
|
152
63
|
end
|
153
|
-
|
154
|
-
alias :[]= :store
|
155
64
|
end
|
156
65
|
|
157
66
|
class Element
|
@@ -159,13 +68,14 @@ module EimXML
|
|
159
68
|
|
160
69
|
NEST = " "
|
161
70
|
|
162
|
-
def initialize(name, attributes=
|
71
|
+
def initialize(name, attributes={})
|
163
72
|
@name = name.to_sym
|
164
|
-
@attributes =
|
73
|
+
@attributes = Hash.new
|
165
74
|
@contents = Array.new
|
166
|
-
@hold_space = false
|
167
75
|
|
168
|
-
|
76
|
+
attributes.each do |k, v|
|
77
|
+
@attributes[k.to_sym] = v
|
78
|
+
end
|
169
79
|
|
170
80
|
yield(self) if block_given?
|
171
81
|
end
|
@@ -175,20 +85,6 @@ module EimXML
|
|
175
85
|
end
|
176
86
|
protected :name=
|
177
87
|
|
178
|
-
def hold_space
|
179
|
-
@hold_space = true
|
180
|
-
self
|
181
|
-
end
|
182
|
-
|
183
|
-
def unhold_space
|
184
|
-
@hold_space = false
|
185
|
-
self
|
186
|
-
end
|
187
|
-
|
188
|
-
def hold_space?
|
189
|
-
@hold_space
|
190
|
-
end
|
191
|
-
|
192
88
|
def add(v)
|
193
89
|
case v
|
194
90
|
when nil
|
@@ -201,58 +97,42 @@ module EimXML
|
|
201
97
|
end
|
202
98
|
alias << add
|
203
99
|
|
204
|
-
def
|
205
|
-
|
206
|
-
hold_space = @hold_space || (nest_level<0)
|
207
|
-
nest = nest_level<0 ? "" : NEST*nest_level
|
208
|
-
head = is_head ? nest : ""
|
209
|
-
lf = hold_space ? "" : "\n"
|
210
|
-
|
211
|
-
attributes = ""
|
100
|
+
def name_and_attributes(out="")
|
101
|
+
out << "#{@name}"
|
212
102
|
@attributes.each do |k, v|
|
213
|
-
|
214
|
-
|
215
|
-
end
|
216
|
-
|
217
|
-
case @contents.size
|
218
|
-
when 0
|
219
|
-
dst << "#{head}<#{@name}#{attributes} />"
|
220
|
-
when 1
|
221
|
-
dst << "#{head}<#{@name}#{attributes}>"
|
222
|
-
content_to_xml(dst, @contents[0], nest_level, false)
|
223
|
-
dst << "</#{@name}>"
|
224
|
-
else
|
225
|
-
dst << "#{head}<#{@name}#{attributes}>#{lf}"
|
226
|
-
@contents.each {|i| content_to_xml(dst, i, nest_level<0 ? -1 : nest_level+1, !hold_space) << lf}
|
227
|
-
dst << "#{@hold_space ? "" : nest}</#{@name}>"
|
103
|
+
next unless v
|
104
|
+
out << " #{k}='#{PCString===v ? v : PCString.encode(v.to_s)}'"
|
228
105
|
end
|
229
106
|
end
|
230
107
|
|
231
|
-
def
|
232
|
-
|
233
|
-
|
108
|
+
def write_to(out = "")
|
109
|
+
out << "<"
|
110
|
+
name_and_attributes(out)
|
234
111
|
|
235
|
-
|
236
|
-
|
237
|
-
end
|
238
|
-
alias :inspect :to_s
|
239
|
-
|
240
|
-
def content_to_xml(dst, c, nest_level, is_head)
|
241
|
-
case
|
242
|
-
when c.respond_to?(:to_xml_with_indent)
|
243
|
-
c.to_xml_with_indent(dst, nest_level, is_head)
|
244
|
-
when c.respond_to?(:to_xml)
|
245
|
-
dst << (is_head && nest_level>=0 ? NEST*nest_level : "")
|
246
|
-
c.to_xml(dst)
|
112
|
+
if @contents.empty?
|
113
|
+
out << " />"
|
247
114
|
else
|
248
|
-
|
115
|
+
out << ">"
|
116
|
+
@contents.each do |c|
|
117
|
+
case c
|
118
|
+
when Element
|
119
|
+
c.write_to(out)
|
120
|
+
when PCString
|
121
|
+
out << c.to_s
|
122
|
+
else
|
123
|
+
out << PCString.encode(c.to_s)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
out << "</#{@name}>"
|
249
127
|
end
|
128
|
+
out
|
250
129
|
end
|
251
|
-
|
130
|
+
alias :to_s :write_to
|
131
|
+
alias :inspect :to_s
|
252
132
|
|
253
133
|
def ==(xml)
|
254
134
|
return false unless xml.is_a?(Element)
|
255
|
-
|
135
|
+
@name==xml.name && @attributes==xml.attributes && @contents==xml.contents
|
256
136
|
end
|
257
137
|
|
258
138
|
def add_attribute(key, value)
|
@@ -272,70 +152,65 @@ module EimXML
|
|
272
152
|
@attributes.delete(key.to_sym)
|
273
153
|
end
|
274
154
|
|
275
|
-
def
|
276
|
-
|
277
|
-
|
278
|
-
return is_a?(name)
|
279
|
-
when Element
|
280
|
-
return match?(name.name, name.attributes)
|
281
|
-
when Array
|
282
|
-
return match?(name[0], name[1])
|
283
|
-
end
|
155
|
+
def pcstring_contents
|
156
|
+
@contents.select{|c| c.is_a?(String)||c.is_a?(PCString)}.map{|c| c.is_a?(String) ? PCString.new(c) : c}
|
157
|
+
end
|
284
158
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
159
|
+
def match(obj, attr=nil)
|
160
|
+
return match(Element.new(obj, attr)) if attr
|
161
|
+
return obj=~@name.to_s if obj.is_a?(Regexp)
|
162
|
+
return @name==obj if obj.is_a?(Symbol)
|
163
|
+
return is_a?(obj) if obj.is_a?(Module)
|
290
164
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
165
|
+
raise ArgumentError unless obj.is_a?(Element)
|
166
|
+
|
167
|
+
return false unless @name==obj.name
|
168
|
+
|
169
|
+
obj.attributes.all? do |k, v|
|
170
|
+
(v.nil? && !@attributes.include?(k)) ||
|
171
|
+
(@attributes.include?(k) && (v.is_a?(Regexp) ? v =~ @attributes[k] : PCString[v] == PCString[@attributes[k]]))
|
172
|
+
end and obj.contents.all? do |i|
|
173
|
+
case i
|
174
|
+
when Element
|
175
|
+
has_element?(i)
|
176
|
+
when String
|
177
|
+
pcstring_contents.include?(PCString.new(i))
|
178
|
+
when PCString
|
179
|
+
pcstring_contents.include?(i)
|
180
|
+
when Regexp
|
181
|
+
@contents.any?{|c| c.is_a?(String) and i=~c}
|
182
|
+
end
|
305
183
|
end
|
306
184
|
end
|
307
|
-
alias :=~ :match
|
185
|
+
alias :=~ :match
|
186
|
+
|
187
|
+
def has?(obj, attr=nil)
|
188
|
+
return has?(Element.new(obj, attr)) if attr
|
308
189
|
|
309
|
-
def has?(name, attrs=nil, find_deep=true)
|
310
|
-
return true if match?(name, attrs)
|
311
190
|
@contents.any? do |i|
|
312
191
|
if i.is_a?(Element)
|
313
|
-
|
314
|
-
i=~[name, attrs] || i.has?(name, attrs, find_deep)
|
315
|
-
else
|
316
|
-
i=~[name, attrs]
|
317
|
-
end
|
192
|
+
i.match(obj) || i.has?(obj)
|
318
193
|
else
|
319
|
-
|
194
|
+
obj.is_a?(Module) && i.is_a?(obj)
|
320
195
|
end
|
321
196
|
end
|
322
197
|
end
|
323
198
|
alias has_element? has?
|
199
|
+
alias include? has?
|
324
200
|
|
325
|
-
def find(
|
326
|
-
|
327
|
-
|
201
|
+
def find(obj, dst=Element.new(:found))
|
202
|
+
return find(Element.new(obj, dst)) if dst.is_a?(Hash)
|
203
|
+
|
204
|
+
dst << self if match(obj)
|
328
205
|
@contents.each do |i|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
206
|
+
case
|
207
|
+
when i.is_a?(Element)
|
208
|
+
i.find(obj, dst)
|
209
|
+
when obj.is_a?(Module) && i.is_a?(obj)
|
210
|
+
dst << i
|
333
211
|
end
|
334
212
|
end
|
335
|
-
|
213
|
+
dst
|
336
214
|
end
|
337
215
|
end
|
338
|
-
|
339
|
-
DSL.register Element
|
340
|
-
OpenDSL.register Element
|
341
216
|
end
|
data/lib/eim_xml/dsl.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Easy IMplementation of XML
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006,2008, KURODA Hiraku <hiraku@hinet.mydns.jp>
|
4
|
+
# You can redistribute it and/or modify it under GPL2.
|
5
|
+
#
|
6
|
+
|
7
|
+
require "eim_xml"
|
8
|
+
|
9
|
+
module EimXML
|
10
|
+
class BaseDSL
|
11
|
+
def add(v)
|
12
|
+
@_container << v
|
13
|
+
end
|
14
|
+
alias << add
|
15
|
+
|
16
|
+
def import_variables(src)
|
17
|
+
src.instance_variables.each do |v|
|
18
|
+
instance_variable_set(v, src.instance_variable_get(v)) unless v=~/\A@_[^_]/
|
19
|
+
end
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def _build(klass, *arg, &proc)
|
24
|
+
e = klass.new(*arg)
|
25
|
+
@_container << e if @_container
|
26
|
+
if proc
|
27
|
+
oc = @_container
|
28
|
+
@_container = e
|
29
|
+
begin
|
30
|
+
instance_eval(&proc)
|
31
|
+
ensure
|
32
|
+
@_container = oc
|
33
|
+
end
|
34
|
+
end
|
35
|
+
e
|
36
|
+
end
|
37
|
+
private :_build
|
38
|
+
|
39
|
+
def _push(container)
|
40
|
+
oc = @_container
|
41
|
+
@_container = container
|
42
|
+
begin
|
43
|
+
yield if block_given?
|
44
|
+
container
|
45
|
+
ensure
|
46
|
+
@_container = oc
|
47
|
+
end
|
48
|
+
end
|
49
|
+
private :_push
|
50
|
+
|
51
|
+
def self.register(*args)
|
52
|
+
args.each do |klass, name|
|
53
|
+
name ||= klass.name.downcase[/(?:.*\:\:)?(.*)$/, 1]
|
54
|
+
eval("def #{name}(*a, &p);_build(#{klass}, *a, &p);end", binding)
|
55
|
+
eval("def self.#{name}(*a, &p);new.#{name}(*a, &p);end", binding)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class DSL < BaseDSL
|
61
|
+
end
|
62
|
+
|
63
|
+
class OpenDSL
|
64
|
+
def _build(klass, *arg, &proc)
|
65
|
+
e = klass.new(*arg)
|
66
|
+
oc = @_container
|
67
|
+
oc << e if oc.is_a?(Element)
|
68
|
+
@_container = e
|
69
|
+
begin
|
70
|
+
proc.call(self) if proc
|
71
|
+
e
|
72
|
+
ensure
|
73
|
+
@_container = oc
|
74
|
+
end
|
75
|
+
end
|
76
|
+
private :_build
|
77
|
+
|
78
|
+
def self.register_base(dsl, binding, *args)
|
79
|
+
args.each do |klass, name|
|
80
|
+
name ||= klass.name.downcase[/(?:.*\:\:)?(.*)$/, 1]
|
81
|
+
eval("def #{name}(*a, &p);_build(#{klass}, *a, &p);end", binding)
|
82
|
+
eval("def self.#{name}(*a, &p);self.new.#{name}(*a, &p);end", binding)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.register(*args)
|
87
|
+
register_base(self, binding, *args)
|
88
|
+
end
|
89
|
+
|
90
|
+
def initialize
|
91
|
+
@_container = nil
|
92
|
+
yield(self) if block_given?
|
93
|
+
end
|
94
|
+
|
95
|
+
def add(v)
|
96
|
+
@_container.add(v)
|
97
|
+
end
|
98
|
+
alias :<< :add
|
99
|
+
|
100
|
+
def container; @_container; end
|
101
|
+
end
|
102
|
+
|
103
|
+
DSL.register Element, Comment
|
104
|
+
OpenDSL.register Element, Comment
|
105
|
+
end
|