ratom 0.3.2 → 0.3.3

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