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