require "atom/element" module XHTML NS = "http://www.w3.org/1999/xhtml" end module Atom # An Atom::Element representing a text construct. # It has a single attribute, "type", which specifies how to interpret # the element's content. Different types are: # # text:: a plain string, without any markup (default) # html:: a chunk of HTML # xhtml:: a chunk of *well-formed* XHTML # # 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 atom_attrb :type include AttrEl on_parse_root do |e,x| type = e.type if x.is_a? REXML::Element if type == 'xhtml' x = e.get_elem x, XHTML::NS, 'div' raise Atom::ParseError, 'xhtml content needs div wrapper' unless x c = x.dup unless x.prefix.empty? # content has a namespace prefix, strip prefixes from it and all # XHTML children REXML::XPath.each(c, './/xhtml:*', 'xhtml' => XHTML::NS) do |x| x.name = x.name end end else c = x[0] ? x[0].value : nil end else c = x.to_s end e.instance_variable_set("@content", c) end 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 type == 'xhtml' and @content and @content.name == 'div' @content.children.to_s else @content.to_s end end # returns a string suitable for dumping into an HTML document. # (or nil if that's impossible) # # if you're storing the content of a Text construct, you probably # want this representation. def html if self["type"] == "xhtml" or self["type"] == "html" to_s elsif self["type"] == "text" REXML::Text.new(to_s).to_s end end # attempts to parse the content of this element as XML and return it # 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.each { |child| xml << child } elsif self["type"] == "text" 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) xml = REXML::Document.new("