ratom 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,11 @@
1
- == 0.3.2 2008-04-09
1
+ == 0.3.3 2008-04-09
2
+
3
+ * Better serialization of namespaced elements. ratom will now generate prefixes for namespaces and write them as
4
+ attributes on the root element.
5
+ * Extensions read as attributes are now written as attributes.
6
+ * When programmatically setting an extension value you can tell ratom to write it as an attribute using:
7
+
8
+ entry['http://example.org', 'extattr'].as_attribute = true
2
9
 
3
10
  * Add support for atom:category.
4
11
  * Support extension attributes using the same mechanism as extension elements.
@@ -40,8 +40,20 @@ module Atom # :nodoc:
40
40
  @simple_extensions = {}
41
41
  end
42
42
 
43
+ if @simple_extension_attributes.nil?
44
+ @simple_extension_attributes = {}
45
+ end
46
+
43
47
  key = "{#{ns},#{localname}}"
44
- (@simple_extensions[key] or @simple_extensions[key] = [])
48
+ (@simple_extensions[key] or @simple_extensions[key] = ValueProxy.new)
49
+ end
50
+
51
+ class ValueProxy < DelegateClass(Array)
52
+ attr_accessor :as_attribute
53
+ def initialize
54
+ super([])
55
+ @as_attribute = false
56
+ end
45
57
  end
46
58
  end
47
59
 
@@ -170,9 +182,8 @@ module Atom # :nodoc:
170
182
  parse(xml, :once => true)
171
183
  end
172
184
 
173
- def to_xml(nodeonly = true, name = 'content', namespace = nil)
174
- node = XML::Node.new(name)
175
- node['xmlns'] = namespace
185
+ def to_xml(nodeonly = true, name = 'content', namespace = nil, namespace_map = Atom::Xml::NamespaceMap.new)
186
+ node = XML::Node.new("#{namespace_map.get(Atom::NAMESPACE)}:#{name}")
176
187
  node << self.to_s
177
188
  node
178
189
  end
@@ -196,7 +207,7 @@ module Atom # :nodoc:
196
207
  end
197
208
  end
198
209
 
199
- def to_xml(nodeonly = true, name = 'content', namespace = nil) # :nodoc:
210
+ def to_xml(nodeonly = true, name = 'content', namespace = nil, namespace_map = Atom::Xml::NamespaceMap.new) # :nodoc:
200
211
  require 'iconv'
201
212
  # Convert from utf-8 to utf-8 as a way of making sure the content is UTF-8.
202
213
  #
@@ -206,10 +217,9 @@ module Atom # :nodoc:
206
217
  # to try and recitfy the situation.
207
218
  #
208
219
  begin
209
- node = XML::Node.new(name)
210
- node << Iconv.iconv('utf-8', 'utf-8', self.to_s)
220
+ node = XML::Node.new("#{namespace_map.get(Atom::NAMESPACE)}:#{name}")
221
+ node << Iconv.iconv('utf-8', 'utf-8', self.to_s, namespace_map = nil)
211
222
  node['type'] = 'html'
212
- node['xmlns'] = namespace
213
223
  node['xml:lang'] = self.xml_lang
214
224
  node
215
225
  rescue Iconv::IllegalSequence => e
@@ -240,13 +250,12 @@ module Atom # :nodoc:
240
250
  while xml.read == 1 && xml.depth > starting_depth; end
241
251
  end
242
252
 
243
- def to_xml(nodeonly = true, name = 'content', namespace = nil)
244
- node = XML::Node.new(name)
253
+ def to_xml(nodeonly = true, name = 'content', namespace = nil, namespace_map = Atom::Xml::NamespaceMap.new)
254
+ node = XML::Node.new("#{namespace_map.get(Atom::NAMESPACE)}:#{name}")
245
255
  node['type'] = 'xhtml'
246
256
  node['xml:lang'] = self.xml_lang
247
- node['xmlns'] = namespace
248
257
 
249
- div = XML::Node.new('div')
258
+ div = XML::Node.new('div')
250
259
  div['xmlns'] = XHTML
251
260
  div
252
261
 
@@ -2,7 +2,7 @@ module Atom #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -31,6 +31,27 @@ end
31
31
 
32
32
  module Atom
33
33
  module Xml # :nodoc:
34
+ class NamespaceMap
35
+ def initialize
36
+ @i = 0
37
+ @map = {}
38
+ end
39
+
40
+ def get(ns)
41
+ if ns == Atom::NAMESPACE
42
+ @map[ns] = "atom"
43
+ elsif ns == Atom::Pub::NAMESPACE
44
+ @map[ns] = "app"
45
+ else
46
+ @map[ns] or @map[ns] = "ns#{@i += 1}"
47
+ end
48
+ end
49
+
50
+ def each(&block)
51
+ @map.each(&block)
52
+ end
53
+ end
54
+
34
55
  module Parseable # :nodoc:
35
56
  def parse(xml, options = {})
36
57
  starting_depth = xml.depth
@@ -45,6 +66,7 @@ module Atom
45
66
  # Support attribute names with namespace prefixes
46
67
  self.send("#{xml.name.sub(/:/, '_')}=", xml.value)
47
68
  elsif self.respond_to?(:simple_extensions)
69
+ self[xml.namespace_uri, xml.local_name].as_attribute = true
48
70
  self[xml.namespace_uri, xml.local_name] << xml.value
49
71
  end
50
72
  end
@@ -87,14 +109,15 @@ module Atom
87
109
  end
88
110
  end
89
111
 
90
- def to_xml(nodeonly = false, root_name = self.class.name.demodulize.downcase, namespace = nil)
112
+ def to_xml(nodeonly = false, root_name = self.class.name.demodulize.downcase, namespace = nil, namespace_map = nil)
113
+ namespace_map = NamespaceMap.new if namespace_map.nil?
91
114
  node = XML::Node.new(root_name)
92
115
  node['xmlns'] = self.class.namespace unless nodeonly || !self.class.respond_to?(:namespace)
93
116
 
94
117
  self.class.element_specs.values.select {|s| s.single? }.each do |spec|
95
118
  if attribute = self.send(spec.attribute)
96
119
  if attribute.respond_to?(:to_xml)
97
- node << attribute.to_xml(true, spec.name, spec.options[:namespace])
120
+ node << attribute.to_xml(true, spec.name, spec.options[:namespace], namespace_map)
98
121
  else
99
122
  n = XML::Node.new(spec.name)
100
123
  n['xmlns'] = spec.options[:namespace]
@@ -107,7 +130,7 @@ module Atom
107
130
  self.class.element_specs.values.select {|s| !s.single? }.each do |spec|
108
131
  self.send(spec.attribute).each do |attribute|
109
132
  if attribute.respond_to?(:to_xml)
110
- node << attribute.to_xml(true, spec.name.singularize)
133
+ node << attribute.to_xml(true, spec.name.singularize, nil, namespace_map)
111
134
  else
112
135
  n = XML::Node.new(spec.name.singularize)
113
136
  n['xmlns'] = spec.options[:namespace]
@@ -129,10 +152,13 @@ module Atom
129
152
  self.simple_extensions.each do |name, value_array|
130
153
  if name =~ /\{(.*),(.*)\}/
131
154
  value_array.each do |value|
132
- ext = XML::Node.new($2)
133
- ext['xmlns'] = $1
134
- ext << value
135
- node << ext
155
+ if value_array.as_attribute
156
+ node["#{namespace_map.get($1)}:#{$2}"] = value
157
+ else
158
+ ext = XML::Node.new("#{namespace_map.get($1)}:#{$2}")
159
+ ext << value
160
+ node << ext
161
+ end
136
162
  end
137
163
  else
138
164
  STDERR.print "Couldn't split #{name}"
@@ -141,6 +167,10 @@ module Atom
141
167
  end
142
168
 
143
169
  unless nodeonly
170
+ namespace_map.each do |ns, prefix|
171
+ node["xmlns:#{prefix}"] = ns
172
+ end
173
+
144
174
  doc = XML::Document.new
145
175
  doc.root = node
146
176
  doc.to_s
@@ -152,8 +152,7 @@ describe Atom::Pub do
152
152
  end
153
153
 
154
154
  it "should put title in Atom namespace" do
155
- # TODO fix this to use a prefix?
156
- @xml.should match(%r{title xmlns="#{Atom::NAMESPACE}"})
155
+ @xml.should match(%r{atom:title})
157
156
  end
158
157
 
159
158
  it_should_behave_like 'parser of spec/app/service.xml'
@@ -974,6 +974,10 @@ describe Atom do
974
974
  @entry.categories.first["http://example.org/example", "attribute"].first.should == "extension"
975
975
  end
976
976
 
977
+ it "should write a simple extension attribute as an attribute" do
978
+ @entry.categories.first.to_xml(true)['ns1:attribute'].should == 'extension'
979
+ end
980
+
977
981
  it "should read an extension with the same local name as an Atom element" do
978
982
  @feed['http://example.org/example', 'title'].should == ['Extension Title']
979
983
  end
@@ -1105,7 +1109,7 @@ describe Atom do
1105
1109
 
1106
1110
  describe Atom::Content::Html do
1107
1111
  it "should escape ampersands in entities" do
1108
- Atom::Content::Html.new("&nbsp;").to_xml.to_s.should == "<content type=\"html\">&amp;nbsp;</content>"
1112
+ Atom::Content::Html.new("&nbsp;").to_xml.to_s.should == "<atom:content type=\"html\">&amp;nbsp;</atom:content>"
1109
1113
  end
1110
1114
  end
1111
1115
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peerworks