C0 code coverage information

Generated on Tue Apr 10 20:52:45 +0200 2007 with rcov 0.8.0


Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
Name Total lines Lines of code Total coverage Code coverage
lib/xspf.rb 491 331
98.4% 
97.6% 
  1 #--
  2 # =============================================================================
  3 # Copyright (c) 2006 Pau Garcia i Quiles (pgquiles@elpauer.org)
  4 # All rights reserved.
  5 #
  6 # This library may be used only as allowed by either the Ruby license (or, by
  7 # association with the Ruby license, the GPL). See the "doc" subdirectory of
  8 # the XSPF distribution for the texts of these licenses.
  9 # -----------------------------------------------------------------------------
 10 # XSPF for Ruby website : http://xspf.rubyforge.org
 11 # =============================================================================
 12 #++
 13 
 14 require 'rexml/document'
 15 
 16 begin
 17   require 'xml/xslt_lib' # For ruby-xslt 0.9.3 or newer
 18 rescue LoadError => e
 19   begin
 20     require 'xml/xslt' # For ruby-xslt 0.9.2 or older
 21   rescue LoadError => e
 22     puts "You need to install ruby-xslt to use ruby-xspf"
 23     exit
 24   end
 25 end
 26 
 27 # :include: USAGE
 28 # :main: USAGE
 29 
 30 module MetaGen #:nodoc:
 31 
 32   # define the method
 33   def self.add_method(klass, meth_name, body, meth_rdoc)
 34     code = <<-CODE
 35     # #{meth_rdoc}
 36     def #{meth_name.downcase}
 37       @#{meth_name}
 38     end
 39     
 40     def #{meth_name.downcase}=(value)
 41       @#{meth_name.downcase} = value
 42     end
 43 
 44     private
 45     def parse_#{meth_name.downcase}
 46       begin
 47         #{body}
 48       rescue NoMethodError
 49         return nil
 50       end
 51     end
 52     CODE
 53     
 54     klass.module_eval(code)
 55  
 56     # hook to write klass + name attrib to a file
 57     if $META_RDOC
 58       open($META_RDOC, 'a+') do |f|
 59         f.puts("class #{klass}\n #{code}\n end")
 60       end
 61     end
 62     
 63   end
 64 
 65   # output in different formats
 66   # FIXME Only works in parse mode, not in generation mode. 
 67   def self.add_output_format(klass, format, meth_rdoc)
 68     xslt_path = "'#{File.join( File.dirname(__FILE__), %Q{xspf2#{format}.xsl} )}'"
 69     code = <<-CODE
 70       # #{meth_rdoc}
 71       def to_#{format}
 72         xslt = XML::XSLT.new
 73         xslt.xml = self.to_xml
 74         xslt.xsl = REXML::Document.new( File.new( #{xslt_path} ) )
 75         xslt.serve
 76       end
 77     CODE
 78     
 79     klass.module_eval(code)
 80    
 81     if $META_RDOC
 82       open($META_RDOC, 'a+') do |f|
 83         f.puts("class #{klass}\n #{code}\n end")
 84       end
 85     end
 86 
 87   end
 88   
 89 end
 90 
 91 class XSPF
 92 
 93   attr_reader :xspf
 94 
 95   #:stopdoc:
 96   ATTRIBUTES = %w{ version encoding }
 97   VERSION_RDOC = 'Version for the XML document or _nil_ if not defined'
 98   ENCODING_RDOC = 'Encoding of the XML document or _nil_ if not defined'
 99   
100   OUTPUT_FORMATS = %w{ m3u html smil rdf soundblox }
101   M3U_RDOC = 'Creates a .m3u playlist from the XSPF document. This method makes use of the official XSPF to M3U XSLT transformation by Lucas Gonze.'
102   HTML_RDOC = 'Outputs the playlist as an HTML page. This method makes use of the official XSPF to HTML XSLT transformation by Lucas Gonze.'
103   SMIL_RDOC = 'Creates a .smil playlist from the XSPF document. This method makes use of the official XSPF to SMIL XSLT transformation by Lucas Gonze.'
104   SOUNDBLOX_RDOC = 'Creates a SoundBlox playlist from the XSPF document. This method makes use of the official XSPF to SoundBlox XSLT tranformation by Lucas Gonze.'
105   RDF_RDOC = 'Creates a RDF feed from the XSPF document. This method makes use of the XSPF to RDF XSLT transformation by Libby Miller.'
106 
107   ATTRIBUTES.each do |attrib|
108     MetaGen.add_method(self, attrib, "@xspf.#{attrib}", eval(attrib.upcase + '_RDOC').to_s )
109   end
110 
111   OUTPUT_FORMATS.each do |format|
112     MetaGen.add_output_format(self, format, eval(format.upcase + '_RDOC').to_s )
113   end
114 
115   #:startdoc:
116   
117   # Creates a XSPF object from a file or string (parse mode) or from a hash or nil (generation mode).
118   #
119   # Possible keys in the hash: :version, :encoding
120   def initialize(source = nil)
121     if ( source.nil? || source.instance_of?(Hash) ) then
122         @version = if source.nil? || !source.has_key?(:version)
123                      '1.0'
124                    else
125                      source[:version]
126                    end
127         @encoding = if source.nil? || !source.has_key?(:encoding)
128                       'UTF-8'
129                     else
130                       source[:encoding]
131                     end
132         @playlist = nil
133         @playlist = if !source.nil? && source.has_key?(:playlist) then
134                         if source[:playlist].instance_of?(XSPF::Playlist)
135                             source[:playlist]
136                         else
137                           raise(TypeError, 'You must pass a file/string (parsing mode) or a hash/nothing (generator mode) as argument to XSPF#new')
138                         end
139                     end
140 
141     elsif ( source.instance_of?(File) || source.instance_of?(String) ) then
142         @xspf = REXML::Document.new(source)
143         ATTRIBUTES.each do |attrib|
144           eval('@' + attrib + '= parse_' + attrib)
145         end
146 
147         @playlist = XSPF::Playlist.new(self)
148         
149     else
150       raise(TypeError, 'You must pass a file/string (parsing mode) or a hash/nothing (generator mode) as argument to XSPF#new')
151     end
152   end
153 
154   # A XSPF::Playlist object
155   def playlist
156     @playlist
157   end
158 
159   def playlist=(value)
160     raise(TypeError, 'The playlist must be an instance of XSPF::Playlist') unless value.instance_of?(XSPF::Playlist)
161     @playlist = value
162   end
163 
164   # Exports the XSPF object to XML
165   def to_xml
166     xml = REXML::Document.new
167     xml << REXML::XMLDecl.new(@version, @encoding)
168     xml << REXML::Document.new(@playlist.to_xml) unless @playlist.nil?
169     xml.to_s
170   end
171 
172   # The <playlist> section of the XSPF document (outputs XML code). This method is only used while parsing.
173   protected
174   def playlist_xml
175     @xspf.root
176   end
177 
178 end
179 
180 class XSPF::Playlist < XSPF
181 
182   attr_reader :playlist
183 
184   #:stopdoc:
185   ATTRIBUTES = %w{ xmlns version }
186   ELEMENTS = %w{ title creator annotation info location identifier image date license attribution extension }
187   ATTRIBUTE_AND_ELEMENT = %w{ link meta }
188   ATTRIBUTION_CHILD_ELEMENTS = %w{ location identifier }
189   EXTENSION_CHILD_ELEMENTS = %w{ application content }
190   
191   XMLNS_RDOC = 'The XML namespace. It must be http://xspf.org/ns/0/ for a valid XSPF document.'
192   XMLNS_DEFAULT = 'http://xspf.org/ns/0/'
193   VERSION_RDOC = 'The XSPF version. It may be 0 or 1, although 1 is strongly advised.'
194   VERSION_DEFAULT = '1'
195   TITLE_RDOC = 'A human-readable title for the playlist. xspf:playlist elements MAY contain exactly one.'
196   CREATOR_RDOC = 'Human-readable name of the entity (author, authors, group, company, etc) that authored the playlist. XSPF::Playlist objects MAY contain exactly one.'
197   ANNOTATION_RDOC = 'A human-readable comment on the playlist. This is character data, not HTML, and it may not contain markup. XSPF::Playlist objects elements MAY contain exactly one.'
198   INFO_RDOC = 'URL of a web page to find out more about this playlist. Likely to be homepage of the author, and would be used to find out more about the author and to find more playlists by the author. XSPF::Playlist objects MAY contain exactly one.'
199   LOCATION_RDOC = 'Source URL for this playlist. XSPF::Playlist objects MAY contain exactly one.'
200   IDENTIFIER_RDOC = 'Canonical ID for this playlist. Likely to be a hash or other location-independent name. MUST be a legal URN. XSPF::Playlist objects MAY contain exactly one.'
201   IMAGE_RDOC = 'URL of an image to display if XSPF::Playlist#image return nil. XSPF::Playlist objects MAY contain exactly one.'
202   DATE_RDOC = 'Creation date (not last-modified date) of the playlist, formatted as a XML schema dateTime. XSPF::Playlist objects MAY contain exactly one.'
203   LICENSE_RDOC = 'URL of a resource that describes the license under which this playlist was released. XSPF::Playlist objects MAY contain zero or one license element.'
204   ATTRIBUTION_RDOC = 'An ordered list of URIs. The purpose is to satisfy licenses allowing modification but requiring attribution. If you modify such a playlist, move its XSPF::Playlist#location or XSPF::Playlist#identifier element to the top of the items in the XSPF::Playlist#attribution element. XSPF::Playlist objects MAY contain exactly one attribution element. Please note that currently XSPF for Ruby does not parse the contents of XSPF::Playlist#attribution.'
205   EXTENSION_RDOC = 'The extension element allows non-XSPF XML to be included in XSPF documents without breaking XSPF validation. The purpose is to allow nested XML, which the meta and link elements do not. XSPF::Playlist objects MAY contain zero or more extension elements but currently XSPF for Ruby returns only the first one.'
206   LINK_REL_RDOC = 'The link element allows non-XSPF web resources to be included in XSPF documents without breaking XSPF validation. A valid _link_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Playlist#link_rel and XSPF::Playlist#link_content respectively. XSPF::Playlist objects MAY contain zero or more link elements, but currently XSPF for Ruby returns only the first one.'
207   LINK_CONTENT_RDOC = 'The link element allows non-XSPF web resources to be included in XSPF documents without breaking XSPF validation. A valid _link_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Playlist#link_rel and XSPF::Playlist#link_content respectively. XSPF::Playlist objects MAY contain zero or more meta elements, but currently XSPF for Ruby returns only the first one.'
208   META_REL_RDOC = 'The meta element allows non-XSPF metadata to be included in XSPF documents without breaking XSPF validation. A valid _meta_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Playlist#meta_rel and XSPF::Playlist#meta_content respectively. XSPF::Playlist objects MAY contain zero or more meta elements, but currently XSPF for Ruby returns only the first one.'
209   META_CONTENT_RDOC = 'The meta element allows non-XSPF metadata to be included in XSPF documents without breaking XSPF validation. A valid _meta_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Playlist#meta_rel and XSPF::Playlist#meta_content respectively. XSPF::Playlist objects MAY contain zero or more meta elements, but currently XSPF for Ruby returns only the first one.'
210   
211 # FIXME Currently we only return the first "link"
212 # FIXME Currently we only return the first "meta"
213 # FIXME Currently we only return the first "extension"
214 # TODO Parse "attribution"
215 # TODO Parse "extension"
216 
217   # Returns the value of the attribute or nil if the attribute is not present
218   ATTRIBUTES.each do |attrib|
219     MetaGen.add_method( self, attrib, "@playlist.root.attributes['#{attrib}']", eval(attrib.upcase + '_RDOC').to_s )
220   end
221 
222   ELEMENTS.each do |element|
223     MetaGen.add_method( self, element, "@playlist.elements['#{element}'].text", eval(element.upcase + '_RDOC').to_s )
224   end
225 
226   ATTRIBUTE_AND_ELEMENT.each do |ae|
227     MetaGen.add_method( self, "#{ae}_content", "@playlist.elements['#{ae}'].text", eval(ae.upcase + '_CONTENT_RDOC').to_s )
228     MetaGen.add_method( self, "#{ae}_rel", "@playlist.elements['#{ae}'].attributes['rel']", eval(ae.upcase + '_REL_RDOC').to_s )
229   end
230 
231   #:startdoc:
232   
233   # Creates a XSPF::Playlist from a XSPF document (parse mode) or from a hash of values (generation mode)
234   #
235   # Possible keys in the hash: :xmlns, :version, :title, :creator, :annotation, :info, :location, :identifier, :image, :date, :license, :attribution, :extension, :link_rel, :link_content, :meta_rel, :meta_content
236   def initialize(source = nil)
237 
238     if ( source.instance_of?(Hash) || source.nil? ) then
239 
240       ATTRIBUTES.each do |attrib|
241         add_instance_variable(source, attrib)
242       end
243 
244       ELEMENTS.each do |element|
245         add_instance_variable(source, element)
246       end
247 
248       ATTRIBUTE_AND_ELEMENT.each do |ae|
249         add_instance_variable(source, "#{ae}_content" )
250         add_instance_variable(source, "#{ae}_rel" )
251       end
252 
253       @tracklist = if ( !source.nil? && source.has_key?(:tracklist) && source[:tracklist].instance_of?(XSPF::Tracklist) )
254                       source[:tracklist]
255                     else
256                       nil
257                     end
258 
259     elsif source.instance_of?(XSPF) then
260 
261       @playlist = source.playlist_xml
262 
263       ATTRIBUTES.each do |attrib|
264         eval('@' + attrib.downcase + '= parse_' + attrib.downcase)
265       end
266   
267       ELEMENTS.each do |element|
268         eval('@' + element.downcase + '= parse_' + element.downcase)
269       end
270 
271       ATTRIBUTE_AND_ELEMENT.each do |ae|
272         eval('@' + ae.downcase + '_content = parse_' + ae.downcase + '_content')
273         eval('@' + ae.downcase + '_rel = parse_' + ae.downcase + '_rel')
274       end
275 
276       @tracklist = XSPF::Tracklist.new(self)
277 
278     else
279       raise(TypeError, 'You must pass a XSPF object (parsing mode) or a hash (generator mode) as argument to XSPF::Playlist#new')
280     end
281     
282   end
283 
284   # A XSPF::Tracklist object
285   def tracklist
286     @tracklist
287   end
288 
289   def tracklist=(value)
290     raise(TypeError, 'The tracklist must be an instance of XSPF::Tracklist') unless value.instance_of?(XSPF::Tracklist)
291     @tracklist = value
292   end
293 
294   alias :<< :tracklist=
295 
296   # Exports the XSPF::Playlist to XML (only the <playlist> section)
297   def to_xml
298   
299     xml = REXML::Element.new('playlist')
300 
301     ATTRIBUTES.each do |attrib|
302       # TODO Sure there is a nicer way to do evaluate this condition...
303       unless eval('@' + attrib.downcase + '.nil?')
304         xml.attributes[attrib] = eval('@' + attrib.downcase)
305       end 
306     end
307     
308     ELEMENTS.each do |element|
309       # TODO Sure there is a nicer way to do evaluate this condition...
310       unless eval('@' + element.downcase + '.nil?')
311         el = REXML::Element.new(element)
312         el.add_text( eval('@' + element.downcase) )
313         xml.add_element(el)
314       end 
315     end
316 
317     ATTRIBUTE_AND_ELEMENT.each do |ae|
318       # TODO Sure there is a nicer way to do evaluate this condition...
319       unless eval('@' + ae.downcase + '_rel.nil? && @'+ ae.downcase + '_content.nil?')
320         el = REXML::Element.new(ae.downcase)
321         el.add_attribute('rel', eval('@' + ae.downcase + '_rel') )
322         el.add_text( eval('@' + ae.downcase + '_content') )
323         xml.add_element(el)
324       end 
325     end
326 
327     xml << REXML::Document.new(@tracklist.to_xml)
328     
329     xml.to_s
330   
331   end
332   
333   # The <trackList> section of the XSPF document (outputs XML code). This method is only used while parsing.
334   protected
335   def tracklist_xml  
336     @playlist.elements['trackList']
337   end
338 
339   private
340   def add_instance_variable(hash, var)
341 
342     if !hash.nil? && hash.has_key?(var.downcase.to_sym)
343       eval('@' + var.downcase + ' = \'' + hash[var.downcase.to_sym] + '\'')
344     else
345       eval('@' + var.downcase + ' = defined?(' + var.upcase + '_DEFAULT) ? ' + var.upcase + '_DEFAULT : nil')
346     end
347 
348   end
349 
350 end
351 
352 class XSPF::Tracklist < XSPF::Playlist
353 
354   attr_reader :tracklist
355 
356   # Creates a XSPF::Tracklist from a XSPF::Playlist (parse mode) or without parameters (generation mode)
357   def initialize(playlist=nil)
358     if (playlist.instance_of?(Hash) || playlist.nil?) then
359       @tracklist = ''
360       @tracks = []
361     else
362       @tracklist = playlist.tracklist_xml
363       @tracks = @tracklist.elements.collect { |track| XSPF::Track.new(track) }
364     end
365   end
366 
367   # Returns an array XSPF::Track objects
368   def tracks
369     @tracks
370   end
371 
372   # Adds a new XSPF::Track to the XSPF::Tracklist
373   def <<(track)
374     @tracks << track
375   end
376 
377   # Exports the XSPF::Tracklist to XML (only the <trackList> section)
378   def to_xml
379     xml = REXML::Element.new('trackList')
380     @tracks.each { |t| xml << REXML::Document.new(t.to_xml) }
381     xml.to_s
382   end
383 
384 end
385 
386 class XSPF::Track
387 
388   attr_reader :track
389 
390   #:stopdoc:
391   ELEMENTS = %w{ location identifier title creator annotation info image album trackNum duration extension }
392   ATTRIBUTE_AND_ELEMENT = %w{ link meta }
393   
394   LOCATION_RDOC = 'URL of resource to be rendered. Probably an audio resource, but MAY be any type of resource with a well-known duration, such as video, a SMIL document, or an XSPF document. The duration of the resource defined in this element defines the duration of rendering. XSPF::Track objects MAY contain zero or more location elements, but a user-agent MUST NOT render more than one of the named resources. Currently, XSPF for Ruby returns only the first location.'
395   IDENTIFIER_RDOC = 'Canonical ID for this resource. Likely to be a hash or other location-independent name, such as a MusicBrainz identifier or isbn URN (if there existed isbn numbers for audio). MUST be a legal URN. XSPF::Track objects elements MAY contain zero or more identifier elements, but currently XSPF for Ruby returns only the first one.'
396   TITLE_RDOC = 'Human-readable name of the track that authored the resource which defines the duration of track rendering. This value is primarily for fuzzy lookups, though a user-agent may display it. XSPF::Track objects MAY contain exactly one.'
397   CREATOR_RDOC = 'Human-readable name of the entity (author, authors, group, company, etc) that authored the resource which defines the duration of track rendering. This value is primarily for fuzzy lookups, though a user-agent may display it. XSPF::Track objects MAY contain exactly one.'
398   ANNOTATION_RDOC = 'A human-readable comment on the track. This is character data, not HTML, and it may not contain markup. XSPF::Track objects MAY contain exactly one.'
399   INFO_RDOC = 'URL of a place where this resource can be bought or more info can be found.'
400   IMAGE_RDOC = 'URL of an image to display for the duration of the track. XSPF::Track objects MAY contain exactly one.'
401   ALBUM_RDOC = 'Human-readable name of the collection from which the resource which defines the duration of track rendering comes. For a song originally published as a part of a CD or LP, this would be the title of the original release. This value is primarily for fuzzy lookups, though a user-agent may display it. XSPF::Track objects MAY contain exactly one.'
402   TRACKNUM_RDOC = 'Integer with value greater than zero giving the ordinal position of the media on the XSPF::Track#album. This value is primarily for fuzzy lookups, though a user-agent may display it. XSPF::Track objects MAY contain exactly one. It MUST be a valid XML Schema nonNegativeInteger.'
403   DURATION_RDOC = 'The time to render a resource, in milliseconds. It MUST be a valid XML Schema nonNegativeInteger. This value is only a hint -- different XSPF generators will generate slightly different values. A user-agent MUST NOT use this value to determine the rendering duration, since the data will likely be low quality. XSPF::Track objects MAY contain exactly one duration element.'
404   EXTENSION_RDOC = 'The extension element allows non-XSPF XML to be included in XSPF documents without breaking XSPF validation. The purpose is to allow nested XML, which the meta and link elements do not. XSPF::Track objects MAY contain zero or more extension elements, but currently XSPF for Ruby returns only the first one.'
405   LINK_REL_RDOC = 'The link element allows non-XSPF web resources to be included in XSPF documents without breaking XSPF validation. A valid _link_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Track#link_rel and XSPF::Track#link_content respectively. XSPF::Track objects MAY contain zero or more link elements, but currently XSPF for Ruby returns only the first one.'
406   LINK_CONTENT_RDOC = 'The link element allows non-XSPF web resources to be included in XSPF documents without breaking XSPF validation. A valid _link_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Track#link_rel and XSPF::Track#link_content respectively. XSPF::Track objects MAY contain zero or more meta elements, but currently XSPF for Ruby returns only the first one.'
407   META_REL_RDOC = 'The meta element allows non-XSPF metadata to be included in XSPF documents without breaking XSPF validation. A valid _meta_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Track#meta_rel and XSPF::Track#meta_content respectively. XSPF::Track objects MAY contain zero or more meta elements, but currently XSPF for Ruby returns only the first one.'
408   META_CONTENT_RDOC = 'The meta element allows non-XSPF metadata to be included in XSPF documents without breaking XSPF validation. A valid _meta_ element has a _rel_ attribute and a _content_ element, obtained with XSPF::Track#meta_rel and XSPF::Track#meta_content respectively. XSPF::Track objects MAY contain zero or more meta elements, but currently XSPF for Ruby returns only the first one.'
409 
410   ELEMENTS.each do |element|
411     MetaGen.add_method( self, element, "@track.elements['#{element}'].text", eval(element.upcase + '_RDOC').to_s )
412   end
413 
414   ATTRIBUTE_AND_ELEMENT.each do |ae|
415     MetaGen.add_method( self, "#{ae}_content", "@track.elements['#{ae}'].text", eval(ae.upcase + '_CONTENT_RDOC').to_s )
416     MetaGen.add_method( self, "#{ae}_rel", "@track.elements['#{ae}'].attributes['rel']", eval(ae.upcase + '_REL_RDOC').to_s )
417   end
418 
419   # :startdoc:
420   
421   # Creates a XSPF::Track object from a <track> section of the XSPF document or from a hash of values
422   #
423   # Possible keys in the hash in generation mode: :location, :identifier, :title, :creator, :annotation, :info, :image, :album, :tracknum, :duration, :extension, :link_rel, :link_content, :meta_rel, :meta_content)
424   def initialize(tr)
425     
426     if tr.instance_of?(Hash)
427 
428       ELEMENTS.each do |element|
429         add_instance_variable(tr, element.downcase)
430       end
431 
432       ATTRIBUTE_AND_ELEMENT.each do |ae|
433         add_instance_variable(tr, "#{ae.downcase}_content" )
434         add_instance_variable(tr, "#{ae.downcase}_rel" )
435       end
436       
437     else
438       @track = tr
439 
440       ELEMENTS.each do |element|
441         eval('@' + element.downcase + '= parse_' + element.downcase)
442       end
443 
444       ATTRIBUTE_AND_ELEMENT.each do |ae|
445         eval('@' + ae.downcase + '_content = parse_' + ae.downcase + '_content')
446         eval('@' + ae.downcase + '_rel = parse_' + ae.downcase + '_rel')
447       end
448     end
449     
450   end
451 
452   # Exports the XSPF::Track to XML (only the <track> section)
453   def to_xml
454 
455     xml = REXML::Element.new('track')
456     
457     ELEMENTS.each do |element|
458       # TODO Sure there is a nicer way to do evaluate this condition...
459       unless eval('@' + element.downcase + '.nil?')
460         el = REXML::Element.new(element)
461         el.add_text( eval('@' + element.downcase) )
462         xml.add_element(el)
463       end 
464     end
465 
466     ATTRIBUTE_AND_ELEMENT.each do |ae|
467       # TODO Sure there is a nicer way to do evaluate this condition...
468       unless eval('@' + ae.downcase + '_rel.nil? && @'+ ae.downcase + '_content.nil?')
469         el = REXML::Element.new(ae.downcase)
470         el.add_attribute('rel', eval('@' + ae.downcase + '_rel') )
471         el.add_text( eval('@' + ae.downcase + '_content') )
472         xml.add_element(el)
473       end 
474     end
475 
476     xml.to_s
477     
478   end
479   
480   private
481   def add_instance_variable(hash, var)
482     
483     if hash.has_key?(var.downcase.to_sym)
484       eval('@' + var.downcase + ' = \'' + hash[var.downcase.to_sym] + '\'')
485     else
486       eval('@' + var.downcase + ' = defined?(' + var.upcase + '_DEFAULT) ? ' + var.upcase + '_DEFAULT : nil')
487     end
488   
489   end
490 
491 end

Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.

Valid XHTML 1.0! Valid CSS!