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(/&/, "&")
+ 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