eimxml 0.0.2 → 0.0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  "&amp;"
@@ -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 : false
47
+ other.is_a?(PCString) ? @encoded_string==other.encoded_string : self==PCString.new(other)
121
48
  end
122
49
 
123
- def to_xml(dst=String.new)
124
- dst << encoded_string
50
+ def write_to(out="")
51
+ out << encoded_string
125
52
  end
126
53
  end
127
54
 
128
- class SymbolKeyHash < Hash
129
- def initialize(src=nil)
130
- case src
131
- when self.class
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 store(k, v)
151
- super(k.to_sym, v)
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=nil)
71
+ def initialize(name, attributes={})
163
72
  @name = name.to_sym
164
- @attributes = SymbolKeyHash.new
73
+ @attributes = Hash.new
165
74
  @contents = Array.new
166
- @hold_space = false
167
75
 
168
- @attributes.update(attributes) if attributes
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 to_xml_with_indent(dst=String.new, nest_level=0, is_head=true)
205
- nest_level = -1 if @hold_space
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
- v = k.to_s unless v
214
- attributes << " #{k}='#{PCString===v ? v : PCString.encode(v.to_s)}'"
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 to_xml(dst=String.new)
232
- to_xml_with_indent(dst)
233
- end
108
+ def write_to(out = "")
109
+ out << "<"
110
+ name_and_attributes(out)
234
111
 
235
- def to_s
236
- to_xml
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
- dst << (is_head && nest_level>=0 ? NEST*nest_level : "") << PCString.encode(c.to_s)
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
- private :content_to_xml
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
- (@name==xml.name && @attributes==xml.attributes && @contents==xml.contents && @hold_space==xml.hold_space?)
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 match?(name, attrs=nil)
276
- case name
277
- when Module
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
- if name.is_a?(Regexp)
286
- return false unless name=~@name.to_s
287
- else
288
- return false unless @name==name
289
- end
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
- (attrs||[]).all? do |k, v|
292
- if k.is_a?(Regexp)
293
- @attributes.any? do |sk, sv|
294
- next false unless k===sk.to_s
295
- v===sv
296
- end
297
- else
298
- ak = @attributes[k]
299
- if (ak.is_a?(String) or ak.is_a?(Symbol)) and (v.is_a?(String) or v.is_a?(Symbol))
300
- ak.to_s == v.to_s
301
- else
302
- v===@attributes[k]
303
- end
304
- end
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
- if find_deep
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
- name.is_a?(Module) && i.is_a?(name)
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(name, attrs=nil)
326
- r = []
327
- r << self if match?(name, attrs)
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
- if i.is_a?(Element)
330
- r.concat(i.find(name, attrs))
331
- else
332
- r << i if name.is_a?(Module) && i.is_a?(name)
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
- r
213
+ dst
336
214
  end
337
215
  end
338
-
339
- DSL.register Element
340
- OpenDSL.register Element
341
216
  end
@@ -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