lib/atom/text.rb in atom-tools-1.0.0 vs lib/atom/text.rb in atom-tools-2.0.0

- old
+ new

@@ -16,23 +16,61 @@ # You should set this attribute appropriately after you set a Text # element (entry.content, entry.title or entry.summary). # # This content of this element can be retrieved in different formats, see #html and #xml class Text < Atom::Element - attrb :type + atom_attrb :type - def initialize value, name # :nodoc: - @content = value - @content ||= "" # in case of nil - self["type"] = "text" + include AttrEl - super name + on_parse_root do |e,x| + type = e.type + + if x.is_a? REXML::Element + if type == 'xhtml' + x = x.elements['div'] + raise Atom::ParseError, 'xhtml content needs div wrapper' unless x + + c = x.dup + else + c = x[0] ? x[0].value : nil + end + else + c = x.to_s + end + + e.instance_variable_set("@content", c) end - # convenient, but not overly useful. see #html instead. + on_build do |e,x| + c = e.instance_variable_get('@content') + + if c.respond_to? :parent + x << c.dup + elsif c + x.text = c.to_s + end + end + + def initialize value = nil + super() + + @content = if value.respond_to? :to_xml + value.to_xml[0] + elsif value + value + else + '' + end + end + + def type + @type ? @type : 'text' + end + def to_s - if self["type"] == "xhtml" + if type == 'xhtml' and @content and @content.name == 'div' @content.children.to_s else @content.to_s end end @@ -54,81 +92,59 @@ # as an array of REXML::Elements. # # If self["type"] is "html" and Hpricot is installed, it will # be converted to XHTML first. def xml + xml = REXML::Element.new 'div' + if self["type"] == "xhtml" - @content.children + @content.children.each { |child| xml << child } elsif self["type"] == "text" - [self.to_s] + xml.text = self.to_s elsif self["type"] == "html" begin require "hpricot" rescue raise "Turning HTML content into XML requires Hpricot." end fixed = Hpricot(self.to_s, :xhtml_strict => true) - REXML::Document.new("<div>#{fixed}</div>").root.children + xml = REXML::Document.new("<div>#{fixed}</div>").root else # XXX check that @type is an XML mimetype and parse it raise "I haven't implemented this yet" end + + xml end def inspect # :nodoc: "'#{to_s}'##{self['type']}" end - def []= key, value # :nodoc: - if key == "type" - unless valid_type? value - raise "atomTextConstruct type '#{value}' is meaningless" - end + def type= value + unless valid_type? value + raise Atom::ParseError, "atomTextConstruct type '#{value}' is meaningless" + end - if value == "xhtml" - begin - parse_xhtml_content - rescue REXML::ParseException - raise "#{@content.inspect} can't be parsed as XML" - end + @type = value + if @type == "xhtml" + begin + parse_xhtml_content + rescue REXML::ParseException + raise Atom::ParseError, "#{@content.inspect} can't be parsed as XML" end end - - super(key, value) end - def to_element # :nodoc: - e = super - - if self["type"] == "text" - e.attributes.delete "type" - end - - # this should be done via inheritance - c = convert_contents e - - if c.is_a? String - e.text = c - elsif c.is_a? REXML::Element - e << c.dup - else - raise RuntimeError, "atom:#{local_name} can't contain type #{@content.class}" - end - - e - end - private # converts @content based on the value of self["type"] def convert_contents e if self["type"] == "xhtml" @content - elsif self["type"] == "text" or self["type"].nil? - REXML::Text.normalize(@content.to_s) - elsif self["type"] == "html" - @content.to_s.gsub(/&/, "&amp;") + elsif self["type"] == "text" or self["type"].nil? or self["type"] == "html" + @content.to_s end end def valid_type? type ["text", "xhtml", "html"].member? type @@ -162,29 +178,24 @@ # Atom::Content behaves the same as an Atom::Text, but for two things: # # * the "type" attribute can be an arbitrary media type # * there is a "src" attribute which is an IRI that points to the content of the entry (in which case the content element will be empty) class Content < Atom::Text - attrb :src + is_atom_element :content - def html - if self["src"] - "" + atom_attrb :src + + def src= v + @content = nil + + if self.base + @src = (self.base.to_uri + v).to_s else - super + @src = v end end - def to_element - if self["src"] - element_super = Element.instance_method(:to_element) - return element_super.bind(self).call - end - - super - end - private def valid_type? type super or type.match(/\//) end @@ -200,6 +211,11 @@ end s end end + + class Title < Atom::Text; is_atom_element :title; end + class Subtitle < Atom::Text; is_atom_element :subtitle; end + class Summary < Atom::Text; is_atom_element :summary; end + class Rights < Atom::Text; is_atom_element :rights; end end