summaryrefslogtreecommitdiff
path: root/ruby_1_8_5/lib/rss
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_1_8_5/lib/rss')
-rw-r--r--ruby_1_8_5/lib/rss/0.9.rb423
-rw-r--r--ruby_1_8_5/lib/rss/1.0.rb451
-rw-r--r--ruby_1_8_5/lib/rss/2.0.rb111
-rw-r--r--ruby_1_8_5/lib/rss/content.rb38
-rw-r--r--ruby_1_8_5/lib/rss/converter.rb158
-rw-r--r--ruby_1_8_5/lib/rss/dublincore.rb154
-rw-r--r--ruby_1_8_5/lib/rss/image.rb193
-rw-r--r--ruby_1_8_5/lib/rss/maker.rb37
-rw-r--r--ruby_1_8_5/lib/rss/maker/0.9.rb224
-rw-r--r--ruby_1_8_5/lib/rss/maker/1.0.rb204
-rw-r--r--ruby_1_8_5/lib/rss/maker/2.0.rb168
-rw-r--r--ruby_1_8_5/lib/rss/maker/base.rb546
-rw-r--r--ruby_1_8_5/lib/rss/maker/content.rb29
-rw-r--r--ruby_1_8_5/lib/rss/maker/dublincore.rb169
-rw-r--r--ruby_1_8_5/lib/rss/maker/image.rb145
-rw-r--r--ruby_1_8_5/lib/rss/maker/syndication.rb27
-rw-r--r--ruby_1_8_5/lib/rss/maker/taxonomy.rb182
-rw-r--r--ruby_1_8_5/lib/rss/maker/trackback.rb130
-rw-r--r--ruby_1_8_5/lib/rss/parser.rb476
-rw-r--r--ruby_1_8_5/lib/rss/rexmlparser.rb54
-rw-r--r--ruby_1_8_5/lib/rss/rss.rb1015
-rw-r--r--ruby_1_8_5/lib/rss/syndication.rb64
-rw-r--r--ruby_1_8_5/lib/rss/taxonomy.rb145
-rw-r--r--ruby_1_8_5/lib/rss/trackback.rb288
-rw-r--r--ruby_1_8_5/lib/rss/utils.rb37
-rw-r--r--ruby_1_8_5/lib/rss/xml-stylesheet.rb101
-rw-r--r--ruby_1_8_5/lib/rss/xmlparser.rb93
-rw-r--r--ruby_1_8_5/lib/rss/xmlscanner.rb121
28 files changed, 5783 insertions, 0 deletions
diff --git a/ruby_1_8_5/lib/rss/0.9.rb b/ruby_1_8_5/lib/rss/0.9.rb
new file mode 100644
index 0000000000..eb2d828102
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/0.9.rb
@@ -0,0 +1,423 @@
+require "rss/parser"
+
+module RSS
+
+ module RSS09
+ NSPOOL = {}
+ ELEMENTS = []
+
+ def self.append_features(klass)
+ super
+
+ klass.install_must_call_validator('', "")
+ end
+ end
+
+ class Rss < Element
+
+ include RSS09
+ include RootElementMixin
+ include XMLStyleSheetMixin
+
+ %w(channel).each do |name|
+ install_have_child_element(name, "", nil)
+ end
+
+ attr_accessor :rss_version, :version, :encoding, :standalone
+
+ def initialize(rss_version, version=nil, encoding=nil, standalone=nil)
+ super
+ end
+
+ def items
+ if @channel
+ @channel.items
+ else
+ []
+ end
+ end
+
+ def image
+ if @channel
+ @channel.image
+ else
+ nil
+ end
+ end
+
+ def textinput
+ if @channel
+ @channel.textInput
+ else
+ nil
+ end
+ end
+
+ def setup_maker_elements(maker)
+ super
+ items.each do |item|
+ item.setup_maker(maker.items)
+ end
+ end
+
+ private
+ def _attrs
+ [
+ ["version", true, "rss_version"],
+ ]
+ end
+
+ class Channel < Element
+
+ include RSS09
+
+ [
+ ["title", nil, :text],
+ ["link", nil, :text],
+ ["description", nil, :text],
+ ["language", nil, :text],
+ ["copyright", "?", :text],
+ ["managingEditor", "?", :text],
+ ["webMaster", "?", :text],
+ ["rating", "?", :text],
+ ["pubDate", "?", :date, :rfc822],
+ ["lastBuildDate", "?", :date, :rfc822],
+ ["docs", "?", :text],
+ ["cloud", "?", :have_attribute],
+ ["skipDays", "?", :have_child],
+ ["skipHours", "?", :have_child],
+ ["image", nil, :have_child],
+ ["item", "*", :have_children],
+ ["textInput", "?", :have_child],
+ ].each do |name, occurs, type, *args|
+ __send__("install_#{type}_element", name, "", occurs, name, *args)
+ end
+ alias date pubDate
+ alias date= pubDate=
+
+ private
+ def maker_target(maker)
+ maker.channel
+ end
+
+ def setup_maker_elements(channel)
+ super
+ [
+ [skipDays, "day"],
+ [skipHours, "hour"],
+ ].each do |skip, key|
+ if skip
+ skip.__send__("#{key}s").each do |val|
+ target_skips = channel.__send__("skip#{key.capitalize}s")
+ new_target = target_skips.__send__("new_#{key}")
+ new_target.content = val.content
+ end
+ end
+ end
+ end
+
+ def not_need_to_call_setup_maker_variables
+ %w(image textInput)
+ end
+
+ class SkipDays < Element
+ include RSS09
+
+ [
+ ["day", "*"]
+ ].each do |name, occurs|
+ install_have_children_element(name, "", occurs)
+ end
+
+ class Day < Element
+ include RSS09
+
+ content_setup
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
+ end
+
+ end
+
+ end
+
+ class SkipHours < Element
+ include RSS09
+
+ [
+ ["hour", "*"]
+ ].each do |name, occurs|
+ install_have_children_element(name, "", occurs)
+ end
+
+ class Hour < Element
+ include RSS09
+
+ content_setup(:integer)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
+ end
+ end
+
+ end
+
+ class Image < Element
+
+ include RSS09
+
+ %w(url title link).each do |name|
+ install_text_element(name, "", nil)
+ end
+ [
+ ["width", :integer],
+ ["height", :integer],
+ ["description"],
+ ].each do |name, type|
+ install_text_element(name, "", "?", name, type)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.url = args[0]
+ self.title = args[1]
+ self.link = args[2]
+ self.width = args[3]
+ self.height = args[4]
+ self.description = args[5]
+ end
+ end
+
+ private
+ def maker_target(maker)
+ maker.image
+ end
+ end
+
+ class Cloud < Element
+
+ include RSS09
+
+ [
+ ["domain", "", true],
+ ["port", "", true, :integer],
+ ["path", "", true],
+ ["registerProcedure", "", true],
+ ["protocol", "", true],
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.domain = args[0]
+ self.port = args[1]
+ self.path = args[2]
+ self.registerProcedure = args[3]
+ self.protocol = args[4]
+ end
+ end
+ end
+
+ class Item < Element
+
+ include RSS09
+
+ [
+ ["title", '?', :text],
+ ["link", '?', :text],
+ ["description", '?', :text],
+ ["category", '*', :have_children, "categories"],
+ ["source", '?', :have_child],
+ ["enclosure", '?', :have_child],
+ ].each do |tag, occurs, type, *args|
+ __send__("install_#{type}_element", tag, "", occurs, tag, *args)
+ end
+
+ private
+ def maker_target(items)
+ if items.respond_to?("items")
+ # For backward compatibility
+ items = items.items
+ end
+ items.new_item
+ end
+
+ def setup_maker_element(item)
+ super
+ @enclosure.setup_maker(item) if @enclosure
+ @source.setup_maker(item) if @source
+ end
+
+ class Source < Element
+
+ include RSS09
+
+ [
+ ["url", "", true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required)
+ end
+
+ content_setup
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.url = args[0]
+ self.content = args[1]
+ end
+ end
+
+ private
+ def maker_target(item)
+ item.source
+ end
+
+ def setup_maker_attributes(source)
+ source.url = url
+ source.content = content
+ end
+ end
+
+ class Enclosure < Element
+
+ include RSS09
+
+ [
+ ["url", "", true],
+ ["length", "", true, :integer],
+ ["type", "", true],
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.url = args[0]
+ self.length = args[1]
+ self.type = args[2]
+ end
+ end
+
+ private
+ def maker_target(item)
+ item.enclosure
+ end
+
+ def setup_maker_attributes(enclosure)
+ enclosure.url = url
+ enclosure.length = length
+ enclosure.type = type
+ end
+ end
+
+ class Category < Element
+
+ include RSS09
+
+ [
+ ["domain", "", false]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required)
+ end
+
+ content_setup
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.domain = args[0]
+ self.content = args[1]
+ end
+ end
+
+ private
+ def maker_target(item)
+ item.new_category
+ end
+
+ def setup_maker_attributes(category)
+ category.domain = domain
+ category.content = content
+ end
+
+ end
+
+ end
+
+ class TextInput < Element
+
+ include RSS09
+
+ %w(title description name link).each do |name|
+ install_text_element(name, "", nil)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.title = args[0]
+ self.description = args[1]
+ self.name = args[2]
+ self.link = args[3]
+ end
+ end
+
+ private
+ def maker_target(maker)
+ maker.textinput
+ end
+ end
+
+ end
+
+ end
+
+ RSS09::ELEMENTS.each do |name|
+ BaseListener.install_get_text_element("", name, "#{name}=")
+ end
+
+ module ListenerMixin
+ private
+ def start_rss(tag_name, prefix, attrs, ns)
+ check_ns(tag_name, prefix, ns, "")
+
+ @rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
+ @rss.do_validate = @do_validate
+ @rss.xml_stylesheets = @xml_stylesheets
+ @last_element = @rss
+ @proc_stack.push Proc.new { |text, tags|
+ @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
+ }
+ end
+
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/1.0.rb b/ruby_1_8_5/lib/rss/1.0.rb
new file mode 100644
index 0000000000..a945434fbf
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/1.0.rb
@@ -0,0 +1,451 @@
+require "rss/parser"
+
+module RSS
+
+ module RSS10
+ NSPOOL = {}
+ ELEMENTS = []
+
+ def self.append_features(klass)
+ super
+
+ klass.install_must_call_validator('', ::RSS::URI)
+ end
+
+ end
+
+ class RDF < Element
+
+ include RSS10
+ include RootElementMixin
+
+ class << self
+
+ def required_uri
+ URI
+ end
+
+ end
+
+ @tag_name = 'RDF'
+
+ PREFIX = 'rdf'
+ URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+
+ install_ns('', ::RSS::URI)
+ install_ns(PREFIX, URI)
+
+ [
+ ["channel", nil],
+ ["image", "?"],
+ ["item", "+", :children],
+ ["textinput", "?"],
+ ].each do |tag, occurs, type|
+ type ||= :child
+ __send__("install_have_#{type}_element", tag, ::RSS::URI, occurs)
+ end
+
+ attr_accessor :rss_version, :version, :encoding, :standalone
+
+ def initialize(version=nil, encoding=nil, standalone=nil)
+ super('1.0', version, encoding, standalone)
+ end
+
+ def full_name
+ tag_name_with_prefix(PREFIX)
+ end
+
+ class Li < Element
+
+ include RSS10
+
+ class << self
+ def required_uri
+ URI
+ end
+ end
+
+ [
+ ["resource", [URI, ""], true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(PREFIX)
+ end
+ end
+
+ class Seq < Element
+
+ include RSS10
+
+ Li = ::RSS::RDF::Li
+
+ class << self
+ def required_uri
+ URI
+ end
+ end
+
+ @tag_name = 'Seq'
+
+ install_have_children_element("li", URI, "*")
+ install_must_call_validator('rdf', ::RSS::RDF::URI)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ @li = args[0] if args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(PREFIX)
+ end
+
+ def setup_maker(target)
+ lis.each do |li|
+ target << li.resource
+ end
+ end
+ end
+
+ class Bag < Element
+
+ include RSS10
+
+ Li = ::RSS::RDF::Li
+
+ class << self
+ def required_uri
+ URI
+ end
+ end
+
+ @tag_name = 'Bag'
+
+ install_have_children_element("li", URI, "*")
+ install_must_call_validator('rdf', URI)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ @li = args[0] if args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(PREFIX)
+ end
+
+ def setup_maker(target)
+ lis.each do |li|
+ target << li.resource
+ end
+ end
+ end
+
+ class Channel < Element
+
+ include RSS10
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+ [
+ ["about", URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
+ end
+
+ [
+ ['title', nil, :text],
+ ['link', nil, :text],
+ ['description', nil, :text],
+ ['image', '?', :have_child],
+ ['items', nil, :have_child],
+ ['textinput', '?', :have_child],
+ ].each do |tag, occurs, type|
+ __send__("install_#{type}_element", tag, ::RSS::URI, occurs)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ end
+ end
+
+ private
+ def maker_target(maker)
+ maker.channel
+ end
+
+ def setup_maker_attributes(channel)
+ channel.about = about
+ end
+
+ class Image < Element
+
+ include RSS10
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+ [
+ ["resource", URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
+ end
+ end
+
+ class Textinput < Element
+
+ include RSS10
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+ [
+ ["resource", URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
+ end
+ end
+
+ class Items < Element
+
+ include RSS10
+
+ Seq = ::RSS::RDF::Seq
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+ install_have_child_element("Seq", URI, nil)
+ install_must_call_validator('rdf', URI)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.Seq = args[0]
+ end
+ self.Seq ||= Seq.new
+ end
+
+ def resources
+ if @Seq
+ @Seq.lis.collect do |li|
+ li.resource
+ end
+ else
+ []
+ end
+ end
+ end
+ end
+
+ class Image < Element
+
+ include RSS10
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+ [
+ ["about", URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
+ end
+
+ %w(title url link).each do |name|
+ install_text_element(name, ::RSS::URI, nil)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ end
+ end
+
+ private
+ def maker_target(maker)
+ maker.image
+ end
+ end
+
+ class Item < Element
+
+ include RSS10
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+
+ [
+ ["about", URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
+ end
+
+ [
+ ["title", nil],
+ ["link", nil],
+ ["description", "?"],
+ ].each do |tag, occurs|
+ install_text_element(tag, ::RSS::URI, occurs)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ end
+ end
+
+ private
+ def maker_target(items)
+ if items.respond_to?("items")
+ # For backward compatibility
+ items = items.items
+ end
+ items.new_item
+ end
+ end
+
+ class Textinput < Element
+
+ include RSS10
+
+ class << self
+
+ def required_uri
+ ::RSS::URI
+ end
+
+ end
+
+ [
+ ["about", URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
+ end
+
+ %w(title description name link).each do |name|
+ install_text_element(name, ::RSS::URI, nil)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ end
+ end
+
+ private
+ def maker_target(maker)
+ maker.textinput
+ end
+ end
+
+ end
+
+ RSS10::ELEMENTS.each do |name|
+ BaseListener.install_get_text_element(URI, name, "#{name}=")
+ end
+
+ module ListenerMixin
+ private
+ def start_RDF(tag_name, prefix, attrs, ns)
+ check_ns(tag_name, prefix, ns, RDF::URI)
+
+ @rss = RDF.new(@version, @encoding, @standalone)
+ @rss.do_validate = @do_validate
+ @rss.xml_stylesheets = @xml_stylesheets
+ @last_element = @rss
+ @proc_stack.push Proc.new { |text, tags|
+ @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
+ }
+ end
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/2.0.rb b/ruby_1_8_5/lib/rss/2.0.rb
new file mode 100644
index 0000000000..44bdb4f1ae
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/2.0.rb
@@ -0,0 +1,111 @@
+require "rss/0.9"
+
+module RSS
+
+ class Rss
+
+ class Channel
+
+ [
+ ["generator"],
+ ["ttl", :integer],
+ ].each do |name, type|
+ install_text_element(name, "", "?", name, type)
+ end
+
+ [
+ %w(category categories),
+ ].each do |name, plural_name|
+ install_have_children_element(name, "", "*", name, plural_name)
+ end
+
+ [
+ ["image", "?"],
+ ["language", "?"],
+ ].each do |name, occurs|
+ install_model(name, "", occurs)
+ end
+
+ Category = Item::Category
+
+ class Item
+
+ [
+ ["comments", "?"],
+ ["author", "?"],
+ ].each do |name, occurs|
+ install_text_element(name, "", occurs)
+ end
+
+ [
+ ["pubDate", '?'],
+ ].each do |name, occurs|
+ install_date_element(name, "", occurs, name, 'rfc822')
+ end
+ alias date pubDate
+ alias date= pubDate=
+
+ [
+ ["guid", '?'],
+ ].each do |name, occurs|
+ install_have_child_element(name, "", occurs)
+ end
+
+ private
+ alias _setup_maker_element setup_maker_element
+ def setup_maker_element(item)
+ _setup_maker_element(item)
+ @guid.setup_maker(item) if @guid
+ end
+
+ class Guid < Element
+
+ include RSS09
+
+ [
+ ["isPermaLink", "", false, :boolean]
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ content_setup
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.isPermaLink = args[0]
+ self.content = args[1]
+ end
+ end
+
+ alias_method :_PermaLink?, :PermaLink?
+ private :_PermaLink?
+ def PermaLink?
+ perma = _PermaLink?
+ perma or perma.nil?
+ end
+
+ private
+ def maker_target(item)
+ item.guid
+ end
+
+ def setup_maker_attributes(guid)
+ guid.isPermaLink = isPermaLink
+ guid.content = content
+ end
+ end
+
+ end
+
+ end
+
+ end
+
+ RSS09::ELEMENTS.each do |name|
+ BaseListener.install_get_text_element("", name, "#{name}=")
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/content.rb b/ruby_1_8_5/lib/rss/content.rb
new file mode 100644
index 0000000000..1b13f39fcf
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/content.rb
@@ -0,0 +1,38 @@
+require "rss/1.0"
+
+module RSS
+
+ CONTENT_PREFIX = 'content'
+ CONTENT_URI = "http://purl.org/rss/1.0/modules/content/"
+
+ RDF.install_ns(CONTENT_PREFIX, CONTENT_URI)
+
+ module ContentModel
+
+ extend BaseModel
+
+ ELEMENTS = []
+
+ def self.append_features(klass)
+ super
+
+ klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
+ %w(encoded).each do |name|
+ klass.install_text_element(name, CONTENT_URI, "?",
+ "#{CONTENT_PREFIX}_#{name}")
+ end
+ end
+ end
+
+ class RDF
+ class Item; include ContentModel; end
+ end
+
+ prefix_size = CONTENT_PREFIX.size + 1
+ ContentModel::ELEMENTS.uniq!
+ ContentModel::ELEMENTS.each do |full_name|
+ name = full_name[prefix_size..-1]
+ BaseListener.install_get_text_element(CONTENT_URI, name, "#{full_name}=")
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/converter.rb b/ruby_1_8_5/lib/rss/converter.rb
new file mode 100644
index 0000000000..d928c48223
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/converter.rb
@@ -0,0 +1,158 @@
+require "rss/utils"
+
+module RSS
+
+ class Converter
+
+ include Utils
+
+ def initialize(to_enc, from_enc=nil)
+ normalized_to_enc = to_enc.downcase.gsub(/-/, '_')
+ from_enc ||= 'utf-8'
+ normalized_from_enc = from_enc.downcase.gsub(/-/, '_')
+ if normalized_to_enc == normalized_from_enc
+ def_same_enc()
+ else
+ def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}"
+ if respond_to?(def_diff_enc)
+ __send__(def_diff_enc)
+ else
+ def_else_enc(to_enc, from_enc)
+ end
+ end
+ end
+
+ def convert(value)
+ value
+ end
+
+ def def_convert(depth=0)
+ instance_eval(<<-EOC, *get_file_and_line_from_caller(depth))
+ def convert(value)
+ if value.kind_of?(String)
+ #{yield('value')}
+ else
+ value
+ end
+ end
+ EOC
+ end
+
+ def def_iconv_convert(to_enc, from_enc, depth=0)
+ begin
+ require "iconv"
+ @iconv = Iconv.new(to_enc, from_enc)
+ def_convert(depth+1) do |value|
+ <<-EOC
+ begin
+ @iconv.iconv(#{value})
+ rescue Iconv::Failure
+ raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
+ end
+ EOC
+ end
+ rescue LoadError, ArgumentError, SystemCallError
+ raise UnknownConversionMethodError.new(to_enc, from_enc)
+ end
+ end
+
+ def def_else_enc(to_enc, from_enc)
+ def_iconv_convert(to_enc, from_enc, 0)
+ end
+
+ def def_same_enc()
+ def_convert do |value|
+ value
+ end
+ end
+
+ def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)
+ begin
+ require "uconv"
+ def_convert(1) do |value|
+ <<-EOC
+ begin
+ Uconv.#{meth}(#{value})
+ rescue Uconv::Error
+ raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
+ end
+ EOC
+ end
+ rescue LoadError
+ require 'nkf'
+ def_convert(1) do |value|
+ "NKF.nkf(#{nkf_arg.dump}, #{value})"
+ end
+ end
+ end
+
+ def def_to_euc_jp_from_utf_8
+ def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')
+ end
+
+ def def_to_utf_8_from_euc_jp
+ def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')
+ end
+
+ def def_to_shift_jis_from_utf_8
+ def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')
+ end
+
+ def def_to_utf_8_from_shift_jis
+ def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')
+ end
+
+ def def_to_euc_jp_from_shift_jis
+ require "nkf"
+ def_convert do |value|
+ "NKF.nkf('-Se', #{value})"
+ end
+ end
+
+ def def_to_shift_jis_from_euc_jp
+ require "nkf"
+ def_convert do |value|
+ "NKF.nkf('-Es', #{value})"
+ end
+ end
+
+ def def_to_euc_jp_from_iso_2022_jp
+ require "nkf"
+ def_convert do |value|
+ "NKF.nkf('-Je', #{value})"
+ end
+ end
+
+ def def_to_iso_2022_jp_from_euc_jp
+ require "nkf"
+ def_convert do |value|
+ "NKF.nkf('-Ej', #{value})"
+ end
+ end
+
+ def def_to_utf_8_from_iso_8859_1
+ def_convert do |value|
+ "#{value}.unpack('C*').pack('U*')"
+ end
+ end
+
+ def def_to_iso_8859_1_from_utf_8
+ def_convert do |value|
+ <<-EOC
+ array_utf8 = #{value}.unpack('U*')
+ array_enc = []
+ array_utf8.each do |num|
+ if num <= 0xFF
+ array_enc << num
+ else
+ array_enc.concat "&\#\#{num};".unpack('C*')
+ end
+ end
+ array_enc.pack('C*')
+ EOC
+ end
+ end
+
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/dublincore.rb b/ruby_1_8_5/lib/rss/dublincore.rb
new file mode 100644
index 0000000000..8a4afd4dd9
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/dublincore.rb
@@ -0,0 +1,154 @@
+require "rss/1.0"
+
+module RSS
+
+ DC_PREFIX = 'dc'
+ DC_URI = "http://purl.org/dc/elements/1.1/"
+
+ RDF.install_ns(DC_PREFIX, DC_URI)
+
+ module BaseDublinCoreModel
+ def append_features(klass)
+ super
+
+ return if klass.instance_of?(Module)
+ DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
+ plural = plural_name || "#{name}s"
+ full_name = "#{DC_PREFIX}_#{name}"
+ full_plural_name = "#{DC_PREFIX}_#{plural}"
+ klass_name = "DublinCore#{Utils.to_class_name(name)}"
+ klass.install_must_call_validator(DC_PREFIX, DC_URI)
+ klass.install_have_children_element(name, DC_URI, "*",
+ full_name, full_plural_name)
+ klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
+ remove_method :#{full_name}
+ remove_method :#{full_name}=
+ remove_method :set_#{full_name}
+
+ def #{full_name}
+ @#{full_name}.first and @#{full_name}.first.value
+ end
+
+ def #{full_name}=(new_value)
+ @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)
+ end
+ alias set_#{full_name} #{full_name}=
+ EOC
+ end
+ klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
+ alias date #{DC_PREFIX}_date
+ alias date= #{DC_PREFIX}_date=
+ EOC
+ end
+ end
+
+ module DublinCoreModel
+
+ extend BaseModel
+ extend BaseDublinCoreModel
+
+ TEXT_ELEMENTS = {
+ "title" => nil,
+ "description" => nil,
+ "creator" => nil,
+ "subject" => nil,
+ "publisher" => nil,
+ "contributor" => nil,
+ "type" => nil,
+ "format" => nil,
+ "identifier" => nil,
+ "source" => nil,
+ "language" => nil,
+ "relation" => nil,
+ "coverage" => nil,
+ "rights" => "rightses" # FIXME
+ }
+
+ DATE_ELEMENTS = {
+ "date" => "w3cdtf",
+ }
+
+ ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a
+ DublinCoreModel::DATE_ELEMENTS.each do |name, |
+ ELEMENT_NAME_INFOS << [name, nil]
+ end
+
+ ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys
+
+ ELEMENTS.each do |name, plural_name|
+ module_eval(<<-EOC, *get_file_and_line_from_caller(0))
+ class DublinCore#{Utils.to_class_name(name)} < Element
+ include RSS10
+
+ content_setup
+
+ class << self
+ def required_prefix
+ DC_PREFIX
+ end
+
+ def required_uri
+ DC_URI
+ end
+ end
+
+ @tag_name = #{name.dump}
+
+ alias_method(:value, :content)
+ alias_method(:value=, :content=)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(DC_PREFIX)
+ end
+
+ def maker_target(target)
+ target.new_#{name}
+ end
+
+ def setup_maker_attributes(#{name})
+ #{name}.content = content
+ end
+ end
+ EOC
+ end
+
+ DATE_ELEMENTS.each do |name, type|
+ module_eval(<<-EOC, *get_file_and_line_from_caller(0))
+ class DublinCore#{Utils.to_class_name(name)} < Element
+ remove_method(:content=)
+ remove_method(:value=)
+
+ date_writer("content", #{type.dump}, #{name.dump})
+
+ alias_method(:value=, :content=)
+ end
+ EOC
+ end
+ end
+
+ # For backward compatibility
+ DublincoreModel = DublinCoreModel
+
+ class RDF
+ class Channel; include DublinCoreModel; end
+ class Image; include DublinCoreModel; end
+ class Item; include DublinCoreModel; end
+ class Textinput; include DublinCoreModel; end
+ end
+
+ DublinCoreModel::ELEMENTS.each do |name|
+ class_name = Utils.to_class_name(name)
+ BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}")
+ end
+
+ DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"}
+end
diff --git a/ruby_1_8_5/lib/rss/image.rb b/ruby_1_8_5/lib/rss/image.rb
new file mode 100644
index 0000000000..a9e9e9094e
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/image.rb
@@ -0,0 +1,193 @@
+require 'rss/1.0'
+require 'rss/dublincore'
+
+module RSS
+
+ IMAGE_PREFIX = 'image'
+ IMAGE_URI = 'http://web.resource.org/rss/1.0/modules/image/'
+
+ RDF.install_ns(IMAGE_PREFIX, IMAGE_URI)
+
+ IMAGE_ELEMENTS = []
+
+ %w(item favicon).each do |name|
+ class_name = Utils.to_class_name(name)
+ BaseListener.install_class_name(IMAGE_URI, name, "Image#{class_name}")
+ IMAGE_ELEMENTS << "#{IMAGE_PREFIX}_#{name}"
+ end
+
+ module ImageModelUtils
+ def validate_one_tag_name(ignore_unknown_element, name, tags)
+ if !ignore_unknown_element
+ invalid = tags.find {|tag| tag != name}
+ raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
+ end
+ raise TooMuchTagError.new(name, tag_name) if tags.size > 1
+ end
+ end
+
+ module ImageItemModel
+ include ImageModelUtils
+ extend BaseModel
+
+ def self.append_features(klass)
+ super
+
+ klass.install_have_child_element("item", IMAGE_URI, "?",
+ "#{IMAGE_PREFIX}_item")
+ klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
+ end
+
+ class ImageItem < Element
+ include RSS10
+ include DublinCoreModel
+
+ @tag_name = "item"
+
+ class << self
+ def required_prefix
+ IMAGE_PREFIX
+ end
+
+ def required_uri
+ IMAGE_URI
+ end
+ end
+
+ install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
+
+ [
+ ["about", ::RSS::RDF::URI, true],
+ ["resource", ::RSS::RDF::URI, false],
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{::RSS::RDF::PREFIX}:#{name}")
+ end
+
+ %w(width height).each do |tag|
+ full_name = "#{IMAGE_PREFIX}_#{tag}"
+ disp_name = "#{IMAGE_PREFIX}:#{tag}"
+ install_text_element(tag, IMAGE_URI, "?",
+ full_name, :integer, disp_name)
+ BaseListener.install_get_text_element(IMAGE_URI, tag, "#{full_name}=")
+ end
+
+ alias width= image_width=
+ alias width image_width
+ alias height= image_height=
+ alias height image_height
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ self.resource = args[1]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(IMAGE_PREFIX)
+ end
+
+ private
+ def maker_target(target)
+ target.image_item
+ end
+
+ def setup_maker_attributes(item)
+ item.about = self.about
+ item.resource = self.resource
+ end
+ end
+ end
+
+ module ImageFaviconModel
+ include ImageModelUtils
+ extend BaseModel
+
+ def self.append_features(klass)
+ super
+
+ unless klass.class == Module
+ klass.install_have_child_element("favicon", IMAGE_URI, "?",
+ "#{IMAGE_PREFIX}_favicon")
+ klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
+ end
+ end
+
+ class ImageFavicon < Element
+ include RSS10
+ include DublinCoreModel
+
+ @tag_name = "favicon"
+
+ class << self
+ def required_prefix
+ IMAGE_PREFIX
+ end
+
+ def required_uri
+ IMAGE_URI
+ end
+ end
+
+ [
+ ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX],
+ ["size", IMAGE_URI, true, IMAGE_PREFIX],
+ ].each do |name, uri, required, prefix|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{prefix}:#{name}")
+ end
+
+ AVAILABLE_SIZES = %w(small medium large)
+ alias_method :_size=, :size=
+ private :_size=
+ def size=(new_value)
+ if @do_validate and !new_value.nil?
+ new_value = new_value.strip
+ unless AVAILABLE_SIZES.include?(new_value)
+ attr_name = "#{IMAGE_PREFIX}:size"
+ raise NotAvailableValueError.new(full_name, new_value, attr_name)
+ end
+ end
+ __send__(:_size=, new_value)
+ end
+
+ alias image_size= size=
+ alias image_size size
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ self.size = args[1]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(IMAGE_PREFIX)
+ end
+
+ private
+ def maker_target(target)
+ target.image_favicon
+ end
+
+ def setup_maker_attributes(favicon)
+ favicon.about = self.about
+ favicon.size = self.size
+ end
+ end
+
+ end
+
+ class RDF
+ class Channel; include ImageFaviconModel; end
+ class Item; include ImageItemModel; end
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/maker.rb b/ruby_1_8_5/lib/rss/maker.rb
new file mode 100644
index 0000000000..9ed799ac7f
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker.rb
@@ -0,0 +1,37 @@
+require "rss/rss"
+
+module RSS
+
+ module Maker
+
+ MAKERS = {}
+
+ class << self
+ def make(version, &block)
+ maker(version).make(&block)
+ end
+
+ def maker(version)
+ MAKERS[version]
+ end
+
+ def add_maker(version, maker)
+ MAKERS[version] = maker
+ end
+
+ def filename_to_version(filename)
+ File.basename(filename, ".*")
+ end
+ end
+ end
+
+end
+
+require "rss/maker/1.0"
+require "rss/maker/2.0"
+require "rss/maker/content"
+require "rss/maker/dublincore"
+require "rss/maker/syndication"
+require "rss/maker/taxonomy"
+require "rss/maker/trackback"
+require "rss/maker/image"
diff --git a/ruby_1_8_5/lib/rss/maker/0.9.rb b/ruby_1_8_5/lib/rss/maker/0.9.rb
new file mode 100644
index 0000000000..b82585fb96
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/0.9.rb
@@ -0,0 +1,224 @@
+require "rss/0.9"
+
+require "rss/maker/base"
+
+module RSS
+ module Maker
+
+ class RSS09 < RSSBase
+
+ def initialize(rss_version="0.91")
+ super
+ end
+
+ private
+ def make_rss
+ Rss.new(@rss_version, @version, @encoding, @standalone)
+ end
+
+ def setup_elements(rss)
+ setup_channel(rss)
+ end
+
+ class Channel < ChannelBase
+
+ def to_rss(rss)
+ channel = Rss::Channel.new
+ set = setup_values(channel)
+ if set
+ rss.channel = channel
+ setup_items(rss)
+ setup_image(rss)
+ setup_textinput(rss)
+ setup_other_elements(rss)
+ if rss.channel.image
+ rss
+ else
+ nil
+ end
+ elsif variable_is_set?
+ raise NotSetError.new("maker.channel", not_set_required_variables)
+ end
+ end
+
+ def have_required_values?
+ @title and @link and @description and @language
+ end
+
+ private
+ def setup_items(rss)
+ @maker.items.to_rss(rss)
+ end
+
+ def setup_image(rss)
+ @maker.image.to_rss(rss)
+ end
+
+ def setup_textinput(rss)
+ @maker.textinput.to_rss(rss)
+ end
+
+ def variables
+ super + ["pubDate"]
+ end
+
+ def required_variable_names
+ %w(title link description language)
+ end
+
+ class SkipDays < SkipDaysBase
+ def to_rss(rss, channel)
+ unless @days.empty?
+ skipDays = Rss::Channel::SkipDays.new
+ channel.skipDays = skipDays
+ @days.each do |day|
+ day.to_rss(rss, skipDays.days)
+ end
+ end
+ end
+
+ class Day < DayBase
+ def to_rss(rss, days)
+ day = Rss::Channel::SkipDays::Day.new
+ set = setup_values(day)
+ if set
+ days << day
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @content
+ end
+ end
+ end
+
+ class SkipHours < SkipHoursBase
+ def to_rss(rss, channel)
+ unless @hours.empty?
+ skipHours = Rss::Channel::SkipHours.new
+ channel.skipHours = skipHours
+ @hours.each do |hour|
+ hour.to_rss(rss, skipHours.hours)
+ end
+ end
+ end
+
+ class Hour < HourBase
+ def to_rss(rss, hours)
+ hour = Rss::Channel::SkipHours::Hour.new
+ set = setup_values(hour)
+ if set
+ hours << hour
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @content
+ end
+ end
+ end
+
+ class Cloud < CloudBase
+ def to_rss(*args)
+ end
+ end
+
+ class Categories < CategoriesBase
+ def to_rss(*args)
+ end
+
+ class Category < CategoryBase
+ end
+ end
+ end
+
+ class Image < ImageBase
+ def to_rss(rss)
+ image = Rss::Channel::Image.new
+ set = setup_values(image)
+ if set
+ image.link = link
+ rss.channel.image = image
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @url and @title and link
+ end
+ end
+
+ class Items < ItemsBase
+ def to_rss(rss)
+ if rss.channel
+ normalize.each do |item|
+ item.to_rss(rss)
+ end
+ setup_other_elements(rss)
+ end
+ end
+
+ class Item < ItemBase
+ def to_rss(rss)
+ item = Rss::Channel::Item.new
+ set = setup_values(item)
+ if set
+ rss.items << item
+ setup_other_elements(rss)
+ end
+ end
+
+ private
+ def have_required_values?
+ @title and @link
+ end
+
+ class Guid < GuidBase
+ def to_rss(*args)
+ end
+ end
+
+ class Enclosure < EnclosureBase
+ def to_rss(*args)
+ end
+ end
+
+ class Source < SourceBase
+ def to_rss(*args)
+ end
+ end
+
+ class Categories < CategoriesBase
+ def to_rss(*args)
+ end
+
+ class Category < CategoryBase
+ end
+ end
+
+ end
+ end
+
+ class Textinput < TextinputBase
+ def to_rss(rss)
+ textInput = Rss::Channel::TextInput.new
+ set = setup_values(textInput)
+ if set
+ rss.channel.textInput = textInput
+ setup_other_elements(rss)
+ end
+ end
+
+ private
+ def have_required_values?
+ @title and @description and @name and @link
+ end
+ end
+ end
+
+ add_maker(filename_to_version(__FILE__), RSS09)
+ add_maker(filename_to_version(__FILE__) + "1", RSS09)
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/1.0.rb b/ruby_1_8_5/lib/rss/maker/1.0.rb
new file mode 100644
index 0000000000..3e6542a007
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/1.0.rb
@@ -0,0 +1,204 @@
+require "rss/1.0"
+
+require "rss/maker/base"
+
+module RSS
+ module Maker
+
+ class RSS10 < RSSBase
+
+ def initialize
+ super("1.0")
+ end
+
+ private
+ def make_rss
+ RDF.new(@version, @encoding, @standalone)
+ end
+
+ def setup_elements(rss)
+ setup_channel(rss)
+ setup_image(rss)
+ setup_items(rss)
+ setup_textinput(rss)
+ end
+
+ class Channel < ChannelBase
+
+ def to_rss(rss)
+ set = false
+ if @about
+ channel = RDF::Channel.new(@about)
+ set = setup_values(channel)
+ if set
+ channel.dc_dates.clear
+ rss.channel = channel
+ setup_items(rss)
+ setup_image(rss)
+ setup_textinput(rss)
+ setup_other_elements(rss)
+ end
+ end
+
+ if (!@about or !set) and variable_is_set?
+ raise NotSetError.new("maker.channel", not_set_required_variables)
+ end
+ end
+
+ def have_required_values?
+ @about and @title and @link and @description
+ end
+
+ private
+ def setup_items(rss)
+ items = RDF::Channel::Items.new
+ seq = items.Seq
+ @maker.items.normalize.each do |item|
+ seq.lis << RDF::Channel::Items::Seq::Li.new(item.link)
+ end
+ rss.channel.items = items
+ end
+
+ def setup_image(rss)
+ if @maker.image.have_required_values?
+ rss.channel.image = RDF::Channel::Image.new(@maker.image.url)
+ end
+ end
+
+ def setup_textinput(rss)
+ if @maker.textinput.have_required_values?
+ textinput = RDF::Channel::Textinput.new(@maker.textinput.link)
+ rss.channel.textinput = textinput
+ end
+ end
+
+ def required_variable_names
+ %w(about title link description)
+ end
+
+ class SkipDays < SkipDaysBase
+ def to_rss(*args)
+ end
+
+ class Day < DayBase
+ end
+ end
+
+ class SkipHours < SkipHoursBase
+ def to_rss(*args)
+ end
+
+ class Hour < HourBase
+ end
+ end
+
+ class Cloud < CloudBase
+ def to_rss(*args)
+ end
+ end
+
+ class Categories < CategoriesBase
+ def to_rss(*args)
+ end
+
+ class Category < CategoryBase
+ end
+ end
+ end
+
+ class Image < ImageBase
+ def to_rss(rss)
+ if @url
+ image = RDF::Image.new(@url)
+ set = setup_values(image)
+ if set
+ rss.image = image
+ setup_other_elements(rss)
+ end
+ end
+ end
+
+ def have_required_values?
+ @url and @title and link and @maker.channel.have_required_values?
+ end
+
+ private
+ def variables
+ super + ["link"]
+ end
+ end
+
+ class Items < ItemsBase
+ def to_rss(rss)
+ if rss.channel
+ normalize.each do |item|
+ item.to_rss(rss)
+ end
+ setup_other_elements(rss)
+ end
+ end
+
+ class Item < ItemBase
+ def to_rss(rss)
+ if @link
+ item = RDF::Item.new(@link)
+ set = setup_values(item)
+ if set
+ item.dc_dates.clear
+ rss.items << item
+ setup_other_elements(rss)
+ end
+ end
+ end
+
+ def have_required_values?
+ @title and @link
+ end
+
+ class Guid < GuidBase
+ def to_rss(*args)
+ end
+ end
+
+ class Enclosure < EnclosureBase
+ def to_rss(*args)
+ end
+ end
+
+ class Source < SourceBase
+ def to_rss(*args)
+ end
+ end
+
+ class Categories < CategoriesBase
+ def to_rss(*args)
+ end
+
+ class Category < CategoryBase
+ end
+ end
+ end
+ end
+
+ class Textinput < TextinputBase
+ def to_rss(rss)
+ if @link
+ textinput = RDF::Textinput.new(@link)
+ set = setup_values(textinput)
+ if set
+ rss.textinput = textinput
+ setup_other_elements(rss)
+ end
+ end
+ end
+
+ def have_required_values?
+ @title and @description and @name and @link and
+ @maker.channel.have_required_values?
+ end
+ end
+ end
+
+ add_maker(filename_to_version(__FILE__), RSS10)
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/2.0.rb b/ruby_1_8_5/lib/rss/maker/2.0.rb
new file mode 100644
index 0000000000..a958661614
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/2.0.rb
@@ -0,0 +1,168 @@
+require "rss/2.0"
+
+require "rss/maker/0.9"
+
+module RSS
+ module Maker
+
+ class RSS20 < RSS09
+
+ def initialize(rss_version="2.0")
+ super
+ end
+
+ class Channel < RSS09::Channel
+
+ def have_required_values?
+ @title and @link and @description
+ end
+
+ def required_variable_names
+ %w(title link description)
+ end
+
+ class SkipDays < RSS09::Channel::SkipDays
+ class Day < RSS09::Channel::SkipDays::Day
+ end
+ end
+
+ class SkipHours < RSS09::Channel::SkipHours
+ class Hour < RSS09::Channel::SkipHours::Hour
+ end
+ end
+
+ class Cloud < RSS09::Channel::Cloud
+ def to_rss(rss, channel)
+ cloud = Rss::Channel::Cloud.new
+ set = setup_values(cloud)
+ if set
+ channel.cloud = cloud
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @domain and @port and @path and
+ @registerProcedure and @protocol
+ end
+ end
+
+ class Categories < RSS09::Channel::Categories
+ def to_rss(rss, channel)
+ @categories.each do |category|
+ category.to_rss(rss, channel)
+ end
+ end
+
+ class Category < RSS09::Channel::Categories::Category
+ def to_rss(rss, channel)
+ category = Rss::Channel::Category.new
+ set = setup_values(category)
+ if set
+ channel.categories << category
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @content
+ end
+ end
+ end
+
+ end
+
+ class Image < RSS09::Image
+ end
+
+ class Items < RSS09::Items
+
+ class Item < RSS09::Items::Item
+
+ def have_required_values?
+ @title or @description
+ end
+
+ private
+ def variables
+ super + ["pubDate"]
+ end
+
+ class Guid < RSS09::Items::Item::Guid
+ def to_rss(rss, item)
+ guid = Rss::Channel::Item::Guid.new
+ set = setup_values(guid)
+ if set
+ item.guid = guid
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @content
+ end
+ end
+
+ class Enclosure < RSS09::Items::Item::Enclosure
+ def to_rss(rss, item)
+ enclosure = Rss::Channel::Item::Enclosure.new
+ set = setup_values(enclosure)
+ if set
+ item.enclosure = enclosure
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @url and @length and @type
+ end
+ end
+
+ class Source < RSS09::Items::Item::Source
+ def to_rss(rss, item)
+ source = Rss::Channel::Item::Source.new
+ set = setup_values(source)
+ if set
+ item.source = source
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @url and @content
+ end
+ end
+
+ class Categories < RSS09::Items::Item::Categories
+ def to_rss(rss, item)
+ @categories.each do |category|
+ category.to_rss(rss, item)
+ end
+ end
+
+ class Category < RSS09::Items::Item::Categories::Category
+ def to_rss(rss, item)
+ category = Rss::Channel::Item::Category.new
+ set = setup_values(category)
+ if set
+ item.categories << category
+ setup_other_elements(rss)
+ end
+ end
+
+ def have_required_values?
+ @content
+ end
+ end
+ end
+ end
+
+ end
+
+ class Textinput < RSS09::Textinput
+ end
+ end
+
+ add_maker(filename_to_version(__FILE__), RSS20)
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/base.rb b/ruby_1_8_5/lib/rss/maker/base.rb
new file mode 100644
index 0000000000..2327dd98e4
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/base.rb
@@ -0,0 +1,546 @@
+require 'forwardable'
+
+require 'rss/rss'
+
+module RSS
+ module Maker
+
+ module Base
+
+ def self.append_features(klass)
+ super
+
+ klass.module_eval(<<-EOC, __FILE__, __LINE__)
+
+ OTHER_ELEMENTS = []
+ NEED_INITIALIZE_VARIABLES = []
+
+ def self.inherited(subclass)
+ subclass.const_set("OTHER_ELEMENTS", [])
+ subclass.const_set("NEED_INITIALIZE_VARIABLES", [])
+
+ subclass.module_eval(<<-EOEOC, __FILE__, __LINE__)
+ def self.other_elements
+ OTHER_ELEMENTS + super
+ end
+
+ def self.need_initialize_variables
+ NEED_INITIALIZE_VARIABLES + super
+ end
+ EOEOC
+ end
+
+ def self.add_other_element(variable_name)
+ OTHER_ELEMENTS << variable_name
+ end
+
+ def self.other_elements
+ OTHER_ELEMENTS
+ end
+
+ def self.add_need_initialize_variable(variable_name, init_value="nil")
+ NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
+ end
+
+ def self.need_initialize_variables
+ NEED_INITIALIZE_VARIABLES
+ end
+
+ def self.def_array_element(name)
+ include Enumerable
+ extend Forwardable
+
+ def_delegators("@\#{name}", :<<, :[], :[]=, :first, :last)
+ def_delegators("@\#{name}", :push, :pop, :shift, :unshift)
+ def_delegators("@\#{name}", :each, :size)
+
+ add_need_initialize_variable(name, "[]")
+ end
+ EOC
+ end
+
+ def initialize(maker)
+ @maker = maker
+ initialize_variables
+ end
+
+ def have_required_values?
+ true
+ end
+
+ private
+ def initialize_variables
+ self.class.need_initialize_variables.each do |variable_name, init_value|
+ instance_eval("@#{variable_name} = #{init_value}", __FILE__, __LINE__)
+ end
+ end
+
+ def setup_other_elements(rss)
+ self.class.other_elements.each do |element|
+ __send__("setup_#{element}", rss, current_element(rss))
+ end
+ end
+
+ def current_element(rss)
+ rss
+ end
+
+ def setup_values(target)
+ set = false
+ if have_required_values?
+ variables.each do |var|
+ setter = "#{var}="
+ if target.respond_to?(setter)
+ value = __send__(var)
+ if value
+ target.__send__(setter, value)
+ set = true
+ end
+ end
+ end
+ end
+ set
+ end
+
+ def variables
+ self.class.need_initialize_variables.find_all do |name, init|
+ "nil" == init
+ end.collect do |name, init|
+ name
+ end
+ end
+
+ def variable_is_set?
+ variables.find {|var| !__send__(var).nil?}
+ end
+
+ def not_set_required_variables
+ required_variable_names.find_all do |var|
+ __send__(var).nil?
+ end
+ end
+
+ def required_variables_are_set?
+ required_variable_names.each do |var|
+ return false if __send__(var).nil?
+ end
+ true
+ end
+
+ end
+
+ class RSSBase
+ include Base
+
+ class << self
+ def make(&block)
+ new.make(&block)
+ end
+ end
+
+ %w(xml_stylesheets channel image items textinput).each do |element|
+ attr_reader element
+ add_need_initialize_variable(element, "make_#{element}")
+ module_eval(<<-EOC, __FILE__, __LINE__)
+ private
+ def setup_#{element}(rss)
+ @#{element}.to_rss(rss)
+ end
+
+ def make_#{element}
+ self.class::#{Utils.to_class_name(element)}.new(self)
+ end
+EOC
+ end
+
+ attr_reader :rss_version
+ attr_accessor :version, :encoding, :standalone
+
+ def initialize(rss_version)
+ super(self)
+ @rss_version = rss_version
+ @version = "1.0"
+ @encoding = "UTF-8"
+ @standalone = nil
+ end
+
+ def make
+ if block_given?
+ yield(self)
+ to_rss
+ else
+ nil
+ end
+ end
+
+ def to_rss
+ rss = make_rss
+ setup_xml_stylesheets(rss)
+ setup_elements(rss)
+ setup_other_elements(rss)
+ if rss.channel
+ rss
+ else
+ nil
+ end
+ end
+
+ private
+ remove_method :make_xml_stylesheets
+ def make_xml_stylesheets
+ XMLStyleSheets.new(self)
+ end
+
+ end
+
+ class XMLStyleSheets
+ include Base
+
+ def_array_element("xml_stylesheets")
+
+ def to_rss(rss)
+ @xml_stylesheets.each do |xss|
+ xss.to_rss(rss)
+ end
+ end
+
+ def new_xml_stylesheet
+ xss = XMLStyleSheet.new(@maker)
+ @xml_stylesheets << xss
+ if block_given?
+ yield xss
+ else
+ xss
+ end
+ end
+
+ class XMLStyleSheet
+ include Base
+
+ ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute|
+ attr_accessor attribute
+ add_need_initialize_variable(attribute)
+ end
+
+ def to_rss(rss)
+ xss = ::RSS::XMLStyleSheet.new
+ guess_type_if_need(xss)
+ set = setup_values(xss)
+ if set
+ rss.xml_stylesheets << xss
+ end
+ end
+
+ def have_required_values?
+ @href and @type
+ end
+
+ private
+ def guess_type_if_need(xss)
+ if @type.nil?
+ xss.href = @href
+ @type = xss.type
+ end
+ end
+ end
+ end
+
+ class ChannelBase
+ include Base
+
+ %w(cloud categories skipDays skipHours).each do |element|
+ attr_reader element
+ add_other_element(element)
+ add_need_initialize_variable(element, "make_#{element}")
+ module_eval(<<-EOC, __FILE__, __LINE__)
+ private
+ def setup_#{element}(rss, current)
+ @#{element}.to_rss(rss, current)
+ end
+
+ def make_#{element}
+ self.class::#{Utils.to_class_name(element)}.new(@maker)
+ end
+EOC
+ end
+
+ %w(about title link description language copyright
+ managingEditor webMaster rating docs date
+ lastBuildDate generator ttl).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ alias_method(:pubDate, :date)
+ alias_method(:pubDate=, :date=)
+
+ def current_element(rss)
+ rss.channel
+ end
+
+ class SkipDaysBase
+ include Base
+
+ def_array_element("days")
+
+ def new_day
+ day = self.class::Day.new(@maker)
+ @days << day
+ if block_given?
+ yield day
+ else
+ day
+ end
+ end
+
+ def current_element(rss)
+ rss.channel.skipDays
+ end
+
+ class DayBase
+ include Base
+
+ %w(content).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ def current_element(rss)
+ rss.channel.skipDays.last
+ end
+
+ end
+ end
+
+ class SkipHoursBase
+ include Base
+
+ def_array_element("hours")
+
+ def new_hour
+ hour = self.class::Hour.new(@maker)
+ @hours << hour
+ if block_given?
+ yield hour
+ else
+ hour
+ end
+ end
+
+ def current_element(rss)
+ rss.channel.skipHours
+ end
+
+ class HourBase
+ include Base
+
+ %w(content).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ def current_element(rss)
+ rss.channel.skipHours.last
+ end
+
+ end
+ end
+
+ class CloudBase
+ include Base
+
+ %w(domain port path registerProcedure protocol).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ def current_element(rss)
+ rss.channel.cloud
+ end
+
+ end
+
+ class CategoriesBase
+ include Base
+
+ def_array_element("categories")
+
+ def new_category
+ category = self.class::Category.new(@maker)
+ @categories << category
+ if block_given?
+ yield category
+ else
+ category
+ end
+ end
+
+ class CategoryBase
+ include Base
+
+ %w(domain content).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+ end
+ end
+
+ class ImageBase
+ include Base
+
+ %w(title url width height description).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ def link
+ @maker.channel.link
+ end
+
+ def current_element(rss)
+ rss.image
+ end
+ end
+
+ class ItemsBase
+ include Base
+
+ def_array_element("items")
+
+ attr_accessor :do_sort, :max_size
+
+ def initialize(maker)
+ super
+ @do_sort = false
+ @max_size = -1
+ end
+
+ def normalize
+ if @max_size >= 0
+ sort_if_need[0...@max_size]
+ else
+ sort_if_need[0..@max_size]
+ end
+ end
+
+ def current_element(rss)
+ rss.items
+ end
+
+ def new_item
+ item = self.class::Item.new(@maker)
+ @items << item
+ if block_given?
+ yield item
+ else
+ item
+ end
+ end
+
+ private
+ def sort_if_need
+ if @do_sort.respond_to?(:call)
+ @items.sort do |x, y|
+ @do_sort.call(x, y)
+ end
+ elsif @do_sort
+ @items.sort do |x, y|
+ y <=> x
+ end
+ else
+ @items
+ end
+ end
+
+ class ItemBase
+ include Base
+
+ %w(guid enclosure source categories).each do |element|
+ attr_reader element
+ add_other_element(element)
+ add_need_initialize_variable(element, "make_#{element}")
+ module_eval(<<-EOC, __FILE__, __LINE__)
+ private
+ def setup_#{element}(rss, current)
+ @#{element}.to_rss(rss, current)
+ end
+
+ def make_#{element}
+ self.class::#{Utils.to_class_name(element)}.new(@maker)
+ end
+EOC
+ end
+
+ %w(title link description date author comments).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ alias_method(:pubDate, :date)
+ alias_method(:pubDate=, :date=)
+
+ def <=>(other)
+ if date and other.date
+ date <=> other.date
+ elsif date
+ 1
+ elsif other.date
+ -1
+ else
+ 0
+ end
+ end
+
+ def current_element(rss)
+ rss.items.last
+ end
+
+ class GuidBase
+ include Base
+
+ %w(isPermaLink content).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+
+ class EnclosureBase
+ include Base
+
+ %w(url length type).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+
+ class SourceBase
+ include Base
+
+ %w(url content).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+
+ CategoriesBase = ChannelBase::CategoriesBase
+
+ end
+ end
+
+ class TextinputBase
+ include Base
+
+ %w(title description name link).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+
+ def current_element(rss)
+ rss.textinput
+ end
+
+ end
+
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/content.rb b/ruby_1_8_5/lib/rss/maker/content.rb
new file mode 100644
index 0000000000..18590d0cf8
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/content.rb
@@ -0,0 +1,29 @@
+require 'rss/content'
+require 'rss/maker/1.0'
+
+module RSS
+ module Maker
+ module ContentModel
+ def self.append_features(klass)
+ super
+
+ ::RSS::ContentModel::ELEMENTS.each do |element|
+ klass.add_need_initialize_variable(element)
+ klass.add_other_element(element)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_accessor :#{element}
+ def setup_#{element}(rss, current)
+ if #{element} and current.respond_to?(:#{element}=)
+ current.#{element} = @#{element} if @#{element}
+ end
+ end
+ EOC
+ end
+ end
+ end
+
+ class ItemsBase
+ class ItemBase; include ContentModel; end
+ end
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/dublincore.rb b/ruby_1_8_5/lib/rss/maker/dublincore.rb
new file mode 100644
index 0000000000..0cf1255e82
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/dublincore.rb
@@ -0,0 +1,169 @@
+require 'rss/dublincore'
+require 'rss/maker/1.0'
+
+module RSS
+ module Maker
+ module DublinCoreModel
+ def self.append_features(klass)
+ super
+
+ ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
+ plural_name ||= "#{name}s"
+ full_name = "#{RSS::DC_PREFIX}_#{name}"
+ full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}"
+ klass_name = Utils.to_class_name(name)
+ plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
+ full_plural_klass_name = "self.class::#{plural_klass_name}"
+ full_klass_name = "#{full_plural_klass_name}::#{klass_name}"
+ klass.add_need_initialize_variable(full_plural_name,
+ "make_#{full_plural_name}")
+ klass.add_other_element(full_plural_name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_accessor :#{full_plural_name}
+ def make_#{full_plural_name}
+ #{full_plural_klass_name}.new(@maker)
+ end
+
+ def setup_#{full_plural_name}(rss, current)
+ @#{full_plural_name}.to_rss(rss, current)
+ end
+
+ def #{full_name}
+ @#{full_plural_name}[0] and @#{full_plural_name}[0].value
+ end
+
+ def #{full_name}=(new_value)
+ @#{full_plural_name}[0] = #{full_klass_name}.new(self)
+ @#{full_plural_name}[0].value = new_value
+ end
+EOC
+ end
+ end
+
+ ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
+ plural_name ||= "#{name}s"
+ klass_name = Utils.to_class_name(name)
+ plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
+ module_eval(<<-EOC, __FILE__, __LINE__)
+ class #{plural_klass_name}Base
+ include Base
+
+ def_array_element(#{plural_name.dump})
+
+ def new_#{name}
+ #{name} = self.class::#{klass_name}.new(self)
+ @#{plural_name} << #{name}
+ if block_given?
+ yield #{name}
+ else
+ #{name}
+ end
+ end
+
+ def to_rss(rss, current)
+ @#{plural_name}.each do |#{name}|
+ #{name}.to_rss(rss, current)
+ end
+ end
+
+ class #{klass_name}Base
+ include Base
+
+ attr_accessor :value
+ add_need_initialize_variable("value")
+ alias_method(:content, :value)
+ alias_method(:content=, :value=)
+
+ def have_required_values?
+ @value
+ end
+ end
+ end
+ EOC
+ end
+
+ def self.install_dublin_core(klass)
+ ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
+ plural_name ||= "#{name}s"
+ klass_name = Utils.to_class_name(name)
+ plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
+ full_klass_name = "DublinCore#{klass_name}"
+ klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1))
+ class #{plural_klass_name} < #{plural_klass_name}Base
+ class #{klass_name} < #{klass_name}Base
+ def to_rss(rss, current)
+ if value and current.respond_to?(:dc_#{name})
+ new_item = current.class::#{full_klass_name}.new(value)
+ current.dc_#{plural_name} << new_item
+ end
+ end
+ end
+ end
+EOC
+ end
+ end
+ end
+
+ class ChannelBase
+ include DublinCoreModel
+
+ remove_method(:date)
+ remove_method(:date=)
+ alias_method(:date, :dc_date)
+ alias_method(:date=, :dc_date=)
+ end
+
+ class ImageBase; include DublinCoreModel; end
+ class ItemsBase
+ class ItemBase
+ include DublinCoreModel
+
+ remove_method(:date)
+ remove_method(:date=)
+ alias_method(:date, :dc_date)
+ alias_method(:date=, :dc_date=)
+ end
+ end
+ class TextinputBase; include DublinCoreModel; end
+
+ class RSS10
+ class Channel
+ DublinCoreModel.install_dublin_core(self)
+ end
+
+ class Image
+ DublinCoreModel.install_dublin_core(self)
+ end
+
+ class Items
+ class Item
+ DublinCoreModel.install_dublin_core(self)
+ end
+ end
+
+ class Textinput
+ DublinCoreModel.install_dublin_core(self)
+ end
+ end
+
+ class RSS09
+ class Channel
+ DublinCoreModel.install_dublin_core(self)
+ end
+
+ class Image
+ DublinCoreModel.install_dublin_core(self)
+ end
+
+ class Items
+ class Item
+ DublinCoreModel.install_dublin_core(self)
+ end
+ end
+
+ class Textinput
+ DublinCoreModel.install_dublin_core(self)
+ end
+ end
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/image.rb b/ruby_1_8_5/lib/rss/maker/image.rb
new file mode 100644
index 0000000000..ed51c8ecba
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/image.rb
@@ -0,0 +1,145 @@
+require 'rss/image'
+require 'rss/maker/1.0'
+require 'rss/maker/dublincore'
+
+module RSS
+ module Maker
+ module ImageItemModel
+ def self.append_features(klass)
+ super
+
+ name = "#{RSS::IMAGE_PREFIX}_item"
+ klass.add_need_initialize_variable(name, "make_#{name}")
+ klass.add_other_element(name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_reader :#{name}
+ def setup_#{name}(rss, current)
+ if @#{name}
+ @#{name}.to_rss(rss, current)
+ end
+ end
+
+ def make_#{name}
+ self.class::#{Utils.to_class_name(name)}.new(@maker)
+ end
+EOC
+ end
+
+ class ImageItemBase
+ include Base
+ include Maker::DublinCoreModel
+
+ attr_accessor :about, :resource, :image_width, :image_height
+ add_need_initialize_variable("about")
+ add_need_initialize_variable("resource")
+ add_need_initialize_variable("image_width")
+ add_need_initialize_variable("image_height")
+ alias width= image_width=
+ alias width image_width
+ alias height= image_height=
+ alias height image_height
+
+ def have_required_values?
+ @about
+ end
+ end
+ end
+
+ module ImageFaviconModel
+ def self.append_features(klass)
+ super
+
+ name = "#{RSS::IMAGE_PREFIX}_favicon"
+ klass.add_need_initialize_variable(name, "make_#{name}")
+ klass.add_other_element(name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_reader :#{name}
+ def setup_#{name}(rss, current)
+ if @#{name}
+ @#{name}.to_rss(rss, current)
+ end
+ end
+
+ def make_#{name}
+ self.class::#{Utils.to_class_name(name)}.new(@maker)
+ end
+EOC
+ end
+
+ class ImageFaviconBase
+ include Base
+ include Maker::DublinCoreModel
+
+ attr_accessor :about, :image_size
+ add_need_initialize_variable("about")
+ add_need_initialize_variable("image_size")
+ alias size image_size
+ alias size= image_size=
+
+ def have_required_values?
+ @about and @image_size
+ end
+ end
+ end
+
+ class ChannelBase; include Maker::ImageFaviconModel; end
+
+ class ItemsBase
+ class ItemBase; include Maker::ImageItemModel; end
+ end
+
+ class RSS10
+ class Items
+ class Item
+ class ImageItem < ImageItemBase
+ DublinCoreModel.install_dublin_core(self)
+ def to_rss(rss, current)
+ if @about
+ item = ::RSS::ImageItemModel::ImageItem.new(@about, @resource)
+ setup_values(item)
+ setup_other_elements(item)
+ current.image_item = item
+ end
+ end
+ end
+ end
+ end
+
+ class Channel
+ class ImageFavicon < ImageFaviconBase
+ DublinCoreModel.install_dublin_core(self)
+ def to_rss(rss, current)
+ if @about and @image_size
+ args = [@about, @image_size]
+ favicon = ::RSS::ImageFaviconModel::ImageFavicon.new(*args)
+ setup_values(favicon)
+ setup_other_elements(favicon)
+ current.image_favicon = favicon
+ end
+ end
+ end
+ end
+ end
+
+ class RSS09
+ class Items
+ class Item
+ class ImageItem < ImageItemBase
+ DublinCoreModel.install_dublin_core(self)
+ def to_rss(*args)
+ end
+ end
+ end
+ end
+
+ class Channel
+ class ImageFavicon < ImageFaviconBase
+ DublinCoreModel.install_dublin_core(self)
+ def to_rss(*args)
+ end
+ end
+ end
+ end
+
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/syndication.rb b/ruby_1_8_5/lib/rss/maker/syndication.rb
new file mode 100644
index 0000000000..3717086257
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/syndication.rb
@@ -0,0 +1,27 @@
+require 'rss/syndication'
+require 'rss/maker/1.0'
+
+module RSS
+ module Maker
+ module SyndicationModel
+ def self.append_features(klass)
+ super
+
+ ::RSS::SyndicationModel::ELEMENTS.each do |element|
+ klass.add_need_initialize_variable(element)
+ klass.add_other_element(element)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_accessor :#{element}
+ def setup_#{element}(rss, current)
+ if #{element} and current.respond_to?(:#{element}=)
+ current.#{element} = @#{element} if @#{element}
+ end
+ end
+ EOC
+ end
+ end
+ end
+
+ class ChannelBase; include SyndicationModel; end
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/taxonomy.rb b/ruby_1_8_5/lib/rss/maker/taxonomy.rb
new file mode 100644
index 0000000000..f272996581
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/taxonomy.rb
@@ -0,0 +1,182 @@
+require 'rss/taxonomy'
+require 'rss/maker/1.0'
+require 'rss/maker/dublincore'
+
+module RSS
+ module Maker
+ module TaxonomyTopicsModel
+ def self.append_features(klass)
+ super
+
+ klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics")
+ klass.add_other_element("taxo_topics")
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ attr_reader :taxo_topics
+ def make_taxo_topics
+ self.class::TaxonomyTopics.new(@maker)
+ end
+
+ def setup_taxo_topics(rss, current)
+ @taxo_topics.to_rss(rss, current)
+ end
+EOC
+ end
+
+ def self.install_taxo_topics(klass)
+ klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1))
+ class TaxonomyTopics < TaxonomyTopicsBase
+ def to_rss(rss, current)
+ if current.respond_to?(:taxo_topics)
+ topics = current.class::TaxonomyTopics.new
+ bag = topics.Bag
+ @resources.each do |resource|
+ bag.lis << RDF::Bag::Li.new(resource)
+ end
+ current.taxo_topics = topics
+ end
+ end
+ end
+EOC
+ end
+
+ class TaxonomyTopicsBase
+ include Base
+
+ attr_reader :resources
+ def_array_element("resources")
+ end
+ end
+
+ module TaxonomyTopicModel
+ def self.append_features(klass)
+ super
+
+ klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics")
+ klass.add_other_element("taxo_topics")
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ attr_reader :taxo_topics
+ def make_taxo_topics
+ self.class::TaxonomyTopics.new(@maker)
+ end
+
+ def setup_taxo_topics(rss, current)
+ @taxo_topics.to_rss(rss, current)
+ end
+
+ def taxo_topic
+ @taxo_topics[0] and @taxo_topics[0].value
+ end
+
+ def taxo_topic=(new_value)
+ @taxo_topic[0] = self.class::TaxonomyTopic.new(self)
+ @taxo_topic[0].value = new_value
+ end
+EOC
+ end
+
+ def self.install_taxo_topic(klass)
+ klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1))
+ class TaxonomyTopics < TaxonomyTopicsBase
+ class TaxonomyTopic < TaxonomyTopicBase
+ DublinCoreModel.install_dublin_core(self)
+ TaxonomyTopicsModel.install_taxo_topics(self)
+
+ def to_rss(rss, current)
+ if current.respond_to?(:taxo_topics)
+ topic = current.class::TaxonomyTopic.new(value)
+ topic.taxo_link = value
+ taxo_topics.to_rss(rss, topic) if taxo_topics
+ current.taxo_topics << topic
+ setup_other_elements(rss)
+ end
+ end
+
+ def current_element(rss)
+ super.taxo_topics.last
+ end
+ end
+ end
+EOC
+ end
+
+ class TaxonomyTopicsBase
+ include Base
+
+ def_array_element("taxo_topics")
+
+ def new_taxo_topic
+ taxo_topic = self.class::TaxonomyTopic.new(self)
+ @taxo_topics << taxo_topic
+ if block_given?
+ yield taxo_topic
+ else
+ taxo_topic
+ end
+ end
+
+ def to_rss(rss, current)
+ @taxo_topics.each do |taxo_topic|
+ taxo_topic.to_rss(rss, current)
+ end
+ end
+
+ class TaxonomyTopicBase
+ include Base
+ include DublinCoreModel
+ include TaxonomyTopicsModel
+
+ attr_accessor :value
+ add_need_initialize_variable("value")
+ alias_method(:taxo_link, :value)
+ alias_method(:taxo_link=, :value=)
+
+ def have_required_values?
+ @value
+ end
+ end
+ end
+ end
+
+ class RSSBase
+ include TaxonomyTopicModel
+ end
+
+ class ChannelBase
+ include TaxonomyTopicsModel
+ end
+
+ class ItemsBase
+ class ItemBase
+ include TaxonomyTopicsModel
+ end
+ end
+
+ class RSS10
+ TaxonomyTopicModel.install_taxo_topic(self)
+
+ class Channel
+ TaxonomyTopicsModel.install_taxo_topics(self)
+ end
+
+ class Items
+ class Item
+ TaxonomyTopicsModel.install_taxo_topics(self)
+ end
+ end
+ end
+
+ class RSS09
+ TaxonomyTopicModel.install_taxo_topic(self)
+
+ class Channel
+ TaxonomyTopicsModel.install_taxo_topics(self)
+ end
+
+ class Items
+ class Item
+ TaxonomyTopicsModel.install_taxo_topics(self)
+ end
+ end
+ end
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/maker/trackback.rb b/ruby_1_8_5/lib/rss/maker/trackback.rb
new file mode 100644
index 0000000000..4ae6164f68
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/maker/trackback.rb
@@ -0,0 +1,130 @@
+require 'rss/trackback'
+require 'rss/maker/1.0'
+require 'rss/maker/2.0'
+
+module RSS
+ module Maker
+ module TrackBackModel
+ def self.append_features(klass)
+ super
+
+ name = "#{RSS::TRACKBACK_PREFIX}_ping"
+ klass.add_need_initialize_variable(name)
+ klass.add_other_element(name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_accessor :#{name}
+ def setup_#{name}(rss, current)
+ if #{name} and current.respond_to?(:#{name}=)
+ current.#{name} = #{name}
+ end
+ end
+ EOC
+
+ name = "#{RSS::TRACKBACK_PREFIX}_abouts"
+ klass.add_need_initialize_variable(name, "make_#{name}")
+ klass.add_other_element(name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ attr_accessor :#{name}
+ def make_#{name}
+ self.class::TrackBackAbouts.new(self)
+ end
+
+ def setup_#{name}(rss, current)
+ @#{name}.to_rss(rss, current)
+ end
+ EOC
+ end
+
+ class TrackBackAboutsBase
+ include Base
+
+ def_array_element("abouts")
+
+ def new_about
+ about = self.class::TrackBackAbout.new(@maker)
+ @abouts << about
+ if block_given?
+ yield about
+ else
+ about
+ end
+ end
+
+ def to_rss(rss, current)
+ @abouts.each do |about|
+ about.to_rss(rss, current)
+ end
+ end
+
+ class TrackBackAboutBase
+ include Base
+
+ attr_accessor :value
+ add_need_initialize_variable("value")
+
+ alias_method(:resource, :value)
+ alias_method(:resource=, :value=)
+ alias_method(:content, :value)
+ alias_method(:content=, :value=)
+
+ def have_required_values?
+ @value
+ end
+
+ end
+ end
+ end
+
+ class ItemsBase
+ class ItemBase; include TrackBackModel; end
+ end
+
+ class RSS10
+ class Items
+ class Item
+ class TrackBackAbouts < TrackBackAboutsBase
+ class TrackBackAbout < TrackBackAboutBase
+ def to_rss(rss, current)
+ if resource
+ about = ::RSS::TrackBackModel10::TrackBackAbout.new(resource)
+ current.trackback_abouts << about
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ class RSS09
+ class Items
+ class Item
+ class TrackBackAbouts < TrackBackAboutsBase
+ def to_rss(*args)
+ end
+ class TrackBackAbout < TrackBackAboutBase
+ end
+ end
+ end
+ end
+ end
+
+ class RSS20
+ class Items
+ class Item
+ class TrackBackAbouts < TrackBackAboutsBase
+ class TrackBackAbout < TrackBackAboutBase
+ def to_rss(rss, current)
+ if content
+ about = ::RSS::TrackBackModel20::TrackBackAbout.new(content)
+ current.trackback_abouts << about
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/parser.rb b/ruby_1_8_5/lib/rss/parser.rb
new file mode 100644
index 0000000000..033bc123aa
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/parser.rb
@@ -0,0 +1,476 @@
+require "forwardable"
+require "open-uri"
+
+require "rss/rss"
+
+module RSS
+
+ class NotWellFormedError < Error
+ attr_reader :line, :element
+
+ # Create a new NotWellFormedError for an error at +line+
+ # in +element+. If a block is given the return value of
+ # the block ends up in the error message.
+ def initialize(line=nil, element=nil)
+ message = "This is not well formed XML"
+ if element or line
+ message << "\nerror occurred"
+ message << " in #{element}" if element
+ message << " at about #{line} line" if line
+ end
+ message << "\n#{yield}" if block_given?
+ super(message)
+ end
+ end
+
+ class XMLParserNotFound < Error
+ def initialize
+ super("available XML parser was not found in " <<
+ "#{AVAILABLE_PARSER_LIBRARIES.inspect}.")
+ end
+ end
+
+ class NotValidXMLParser < Error
+ def initialize(parser)
+ super("#{parser} is not an available XML parser. " <<
+ "Available XML parser"<<
+ (AVAILABLE_PARSERS.size > 1 ? "s are ": " is ") <<
+ "#{AVAILABLE_PARSERS.inspect}.")
+ end
+ end
+
+ class NSError < InvalidRSSError
+ attr_reader :tag, :prefix, :uri
+ def initialize(tag, prefix, require_uri)
+ @tag, @prefix, @uri = tag, prefix, require_uri
+ super("prefix <#{prefix}> doesn't associate uri " <<
+ "<#{require_uri}> in tag <#{tag}>")
+ end
+ end
+
+ class Parser
+
+ extend Forwardable
+
+ class << self
+
+ @@default_parser = nil
+
+ def default_parser
+ @@default_parser || AVAILABLE_PARSERS.first
+ end
+
+ # Set @@default_parser to new_value if it is one of the
+ # available parsers. Else raise NotValidXMLParser error.
+ def default_parser=(new_value)
+ if AVAILABLE_PARSERS.include?(new_value)
+ @@default_parser = new_value
+ else
+ raise NotValidXMLParser.new(new_value)
+ end
+ end
+
+ def parse(rss, do_validate=true, ignore_unknown_element=true,
+ parser_class=default_parser)
+ parser = new(rss, parser_class)
+ parser.do_validate = do_validate
+ parser.ignore_unknown_element = ignore_unknown_element
+ parser.parse
+ end
+ end
+
+ def_delegators(:@parser, :parse, :rss,
+ :ignore_unknown_element,
+ :ignore_unknown_element=, :do_validate,
+ :do_validate=)
+
+ def initialize(rss, parser_class=self.class.default_parser)
+ @parser = parser_class.new(normalize_rss(rss))
+ end
+
+ private
+
+ # Try to get the XML associated with +rss+.
+ # Return +rss+ if it already looks like XML, or treat it as a URI,
+ # or a file to get the XML,
+ def normalize_rss(rss)
+ return rss if maybe_xml?(rss)
+
+ uri = to_uri(rss)
+
+ if uri.respond_to?(:read)
+ uri.read
+ elsif !rss.tainted? and File.readable?(rss)
+ File.open(rss) {|f| f.read}
+ else
+ rss
+ end
+ end
+
+ # maybe_xml? tests if source is a string that looks like XML.
+ def maybe_xml?(source)
+ source.is_a?(String) and /</ =~ source
+ end
+
+ # Attempt to convert rss to a URI, but just return it if
+ # there's a ::URI::Error
+ def to_uri(rss)
+ return rss if rss.is_a?(::URI::Generic)
+
+ begin
+ URI(rss)
+ rescue ::URI::Error
+ rss
+ end
+ end
+ end
+
+ class BaseParser
+
+ class << self
+ def raise_for_undefined_entity?
+ listener.raise_for_undefined_entity?
+ end
+ end
+
+ def initialize(rss)
+ @listener = self.class.listener.new
+ @rss = rss
+ end
+
+ def rss
+ @listener.rss
+ end
+
+ def ignore_unknown_element
+ @listener.ignore_unknown_element
+ end
+
+ def ignore_unknown_element=(new_value)
+ @listener.ignore_unknown_element = new_value
+ end
+
+ def do_validate
+ @listener.do_validate
+ end
+
+ def do_validate=(new_value)
+ @listener.do_validate = new_value
+ end
+
+ def parse
+ if @listener.rss.nil?
+ _parse
+ end
+ @listener.rss
+ end
+
+ end
+
+ class BaseListener
+
+ extend Utils
+
+ class << self
+
+ @@setters = {}
+ @@registered_uris = {}
+ @@class_names = {}
+
+ # return the setter for the uri, tag_name pair, or nil.
+ def setter(uri, tag_name)
+ begin
+ @@setters[uri][tag_name]
+ rescue NameError
+ nil
+ end
+ end
+
+
+ # return the tag_names for setters associated with uri
+ def available_tags(uri)
+ begin
+ @@setters[uri].keys
+ rescue NameError
+ []
+ end
+ end
+
+ # register uri against this name.
+ def register_uri(uri, name)
+ @@registered_uris[name] ||= {}
+ @@registered_uris[name][uri] = nil
+ end
+
+ # test if this uri is registered against this name
+ def uri_registered?(uri, name)
+ @@registered_uris[name].has_key?(uri)
+ end
+
+ # record class_name for the supplied uri and tag_name
+ def install_class_name(uri, tag_name, class_name)
+ @@class_names[uri] ||= {}
+ @@class_names[uri][tag_name] = class_name
+ end
+
+ # retrieve class_name for the supplied uri and tag_name
+ # If it doesn't exist, capitalize the tag_name
+ def class_name(uri, tag_name)
+ begin
+ @@class_names[uri][tag_name]
+ rescue NameError
+ tag_name[0,1].upcase + tag_name[1..-1]
+ end
+ end
+
+ def install_get_text_element(uri, name, setter)
+ install_setter(uri, name, setter)
+ def_get_text_element(uri, name, *get_file_and_line_from_caller(1))
+ end
+
+ def raise_for_undefined_entity?
+ true
+ end
+
+ private
+ # set the setter for the uri, tag_name pair
+ def install_setter(uri, tag_name, setter)
+ @@setters[uri] ||= {}
+ @@setters[uri][tag_name] = setter
+ end
+
+ def def_get_text_element(uri, name, file, line)
+ register_uri(uri, name)
+ unless private_instance_methods(false).include?("start_#{name}")
+ module_eval(<<-EOT, file, line)
+ def start_#{name}(name, prefix, attrs, ns)
+ uri = _ns(ns, prefix)
+ if self.class.uri_registered?(uri, #{name.inspect})
+ start_get_text_element(name, prefix, ns, uri)
+ else
+ start_else_element(name, prefix, attrs, ns)
+ end
+ end
+ EOT
+ __send__("private", "start_#{name}")
+ end
+ end
+
+ end
+
+ end
+
+ module ListenerMixin
+
+ attr_reader :rss
+
+ attr_accessor :ignore_unknown_element
+ attr_accessor :do_validate
+
+ def initialize
+ @rss = nil
+ @ignore_unknown_element = true
+ @do_validate = true
+ @ns_stack = [{}]
+ @tag_stack = [[]]
+ @text_stack = ['']
+ @proc_stack = []
+ @last_element = nil
+ @version = @encoding = @standalone = nil
+ @xml_stylesheets = []
+ end
+
+ # set instance vars for version, encoding, standalone
+ def xmldecl(version, encoding, standalone)
+ @version, @encoding, @standalone = version, encoding, standalone
+ end
+
+ def instruction(name, content)
+ if name == "xml-stylesheet"
+ params = parse_pi_content(content)
+ if params.has_key?("href")
+ @xml_stylesheets << XMLStyleSheet.new(*params)
+ end
+ end
+ end
+
+ def tag_start(name, attributes)
+ @text_stack.push('')
+
+ ns = @ns_stack.last.dup
+ attrs = {}
+ attributes.each do |n, v|
+ if /\Axmlns(?:\z|:)/ =~ n
+ ns[$POSTMATCH] = v
+ else
+ attrs[n] = v
+ end
+ end
+ @ns_stack.push(ns)
+
+ prefix, local = split_name(name)
+ @tag_stack.last.push([_ns(ns, prefix), local])
+ @tag_stack.push([])
+ if respond_to?("start_#{local}", true)
+ __send__("start_#{local}", local, prefix, attrs, ns.dup)
+ else
+ start_else_element(local, prefix, attrs, ns.dup)
+ end
+ end
+
+ def tag_end(name)
+ if DEBUG
+ p "end tag #{name}"
+ p @tag_stack
+ end
+ text = @text_stack.pop
+ tags = @tag_stack.pop
+ pr = @proc_stack.pop
+ pr.call(text, tags) unless pr.nil?
+ @ns_stack.pop
+ end
+
+ def text(data)
+ @text_stack.last << data
+ end
+
+ private
+ def _ns(ns, prefix)
+ ns.fetch(prefix, "")
+ end
+
+ CONTENT_PATTERN = /\s*([^=]+)=(["'])([^\2]+?)\2/
+ # Extract the first name="value" pair from content.
+ # Works with single quotes according to the constant
+ # CONTENT_PATTERN. Return a Hash.
+ def parse_pi_content(content)
+ params = {}
+ content.scan(CONTENT_PATTERN) do |name, quote, value|
+ params[name] = value
+ end
+ params
+ end
+
+ def start_else_element(local, prefix, attrs, ns)
+ class_name = self.class.class_name(_ns(ns, prefix), local)
+ current_class = @last_element.class
+ if current_class.constants.include?(class_name)
+ next_class = current_class.const_get(class_name)
+ start_have_something_element(local, prefix, attrs, ns, next_class)
+ else
+ if !@do_validate or @ignore_unknown_element
+ @proc_stack.push(nil)
+ else
+ parent = "ROOT ELEMENT???"
+ if current_class.tag_name
+ parent = current_class.tag_name
+ end
+ raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)
+ end
+ end
+ end
+
+ NAMESPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/
+ def split_name(name)
+ name =~ NAMESPLIT
+ [$1 || '', $2]
+ end
+
+ def check_ns(tag_name, prefix, ns, require_uri)
+ if @do_validate
+ if _ns(ns, prefix) == require_uri
+ #ns.delete(prefix)
+ else
+ raise NSError.new(tag_name, prefix, require_uri)
+ end
+ end
+ end
+
+ def start_get_text_element(tag_name, prefix, ns, required_uri)
+ @proc_stack.push Proc.new {|text, tags|
+ setter = self.class.setter(required_uri, tag_name)
+ if @last_element.respond_to?(setter)
+ @last_element.__send__(setter, text.to_s)
+ else
+ if @do_validate and !@ignore_unknown_element
+ raise NotExpectedTagError.new(tag_name, _ns(ns, prefix),
+ @last_element.tag_name)
+ end
+ end
+ }
+ end
+
+ def start_have_something_element(tag_name, prefix, attrs, ns, klass)
+
+ check_ns(tag_name, prefix, ns, klass.required_uri)
+
+ attributes = {}
+ klass.get_attributes.each do |a_name, a_uri, required, element_name|
+
+ if a_uri.is_a?(String) or !a_uri.respond_to?(:include?)
+ a_uri = [a_uri]
+ end
+ unless a_uri == [""]
+ for prefix, uri in ns
+ if a_uri.include?(uri)
+ val = attrs["#{prefix}:#{a_name}"]
+ break if val
+ end
+ end
+ end
+ if val.nil? and a_uri.include?("")
+ val = attrs[a_name]
+ end
+
+ if @do_validate and required and val.nil?
+ unless a_uri.include?("")
+ for prefix, uri in ns
+ if a_uri.include?(uri)
+ a_name = "#{prefix}:#{a_name}"
+ end
+ end
+ end
+ raise MissingAttributeError.new(tag_name, a_name)
+ end
+
+ attributes[a_name] = val
+ end
+
+ previous = @last_element
+ next_element = klass.new(@do_validate, attributes)
+ previous.instance_eval {set_next_element(tag_name, next_element)}
+ @last_element = next_element
+ @proc_stack.push Proc.new { |text, tags|
+ p(@last_element.class) if DEBUG
+ @last_element.content = text if klass.have_content?
+ if @do_validate
+ @last_element.validate_for_stream(tags, @ignore_unknown_element)
+ end
+ @last_element = previous
+ }
+ end
+
+ end
+
+ unless const_defined? :AVAILABLE_PARSER_LIBRARIES
+ AVAILABLE_PARSER_LIBRARIES = [
+ ["rss/xmlparser", :XMLParserParser],
+ ["rss/xmlscanner", :XMLScanParser],
+ ["rss/rexmlparser", :REXMLParser],
+ ]
+ end
+
+ AVAILABLE_PARSERS = []
+
+ AVAILABLE_PARSER_LIBRARIES.each do |lib, parser|
+ begin
+ require lib
+ AVAILABLE_PARSERS.push(const_get(parser))
+ rescue LoadError
+ end
+ end
+
+ if AVAILABLE_PARSERS.empty?
+ raise XMLParserNotFound
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/rexmlparser.rb b/ruby_1_8_5/lib/rss/rexmlparser.rb
new file mode 100644
index 0000000000..4dabf59199
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/rexmlparser.rb
@@ -0,0 +1,54 @@
+require "rexml/document"
+require "rexml/streamlistener"
+
+/\A(\d+)\.(\d+)(?:\.\d+)+\z/ =~ REXML::Version
+if ([$1.to_i, $2.to_i] <=> [2, 5]) < 0
+ raise LoadError, "needs REXML 2.5 or later (#{REXML::Version})"
+end
+
+module RSS
+
+ class REXMLParser < BaseParser
+
+ class << self
+ def listener
+ REXMLListener
+ end
+ end
+
+ private
+ def _parse
+ begin
+ REXML::Document.parse_stream(@rss, @listener)
+ rescue RuntimeError => e
+ raise NotWellFormedError.new{e.message}
+ rescue REXML::ParseException => e
+ context = e.context
+ line = context[0] if context
+ raise NotWellFormedError.new(line){e.message}
+ end
+ end
+
+ end
+
+ class REXMLListener < BaseListener
+
+ include REXML::StreamListener
+ include ListenerMixin
+
+ class << self
+ def raise_for_undefined_entity?
+ false
+ end
+ end
+
+ def xmldecl(version, encoding, standalone)
+ super(version, encoding, standalone == "yes")
+ # Encoding is converted to UTF-8 when REXML parse XML.
+ @encoding = 'UTF-8'
+ end
+
+ alias_method(:cdata, :text)
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/rss.rb b/ruby_1_8_5/lib/rss/rss.rb
new file mode 100644
index 0000000000..a06985af94
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/rss.rb
@@ -0,0 +1,1015 @@
+require "time"
+
+class Time
+ class << self
+ unless respond_to?(:w3cdtf)
+ def w3cdtf(date)
+ if /\A\s*
+ (-?\d+)-(\d\d)-(\d\d)
+ (?:T
+ (\d\d):(\d\d)(?::(\d\d))?
+ (\.\d+)?
+ (Z|[+-]\d\d:\d\d)?)?
+ \s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8))
+ datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
+ datetime << $7.to_f * 1000000 if $7
+ if $8
+ Time.utc(*datetime) - zone_offset($8)
+ else
+ Time.local(*datetime)
+ end
+ else
+ raise ArgumentError.new("invalid date: #{date.inspect}")
+ end
+ end
+ end
+ end
+
+ unless instance_methods.include?("w3cdtf")
+ alias w3cdtf iso8601
+ end
+end
+
+require "English"
+require "rss/utils"
+require "rss/converter"
+require "rss/xml-stylesheet"
+
+module RSS
+
+ VERSION = "0.1.6"
+
+ URI = "http://purl.org/rss/1.0/"
+
+ DEBUG = false
+
+ class Error < StandardError; end
+
+ class OverlappedPrefixError < Error
+ attr_reader :prefix
+ def initialize(prefix)
+ @prefix = prefix
+ end
+ end
+
+ class InvalidRSSError < Error; end
+
+ class MissingTagError < InvalidRSSError
+ attr_reader :tag, :parent
+ def initialize(tag, parent)
+ @tag, @parent = tag, parent
+ super("tag <#{tag}> is missing in tag <#{parent}>")
+ end
+ end
+
+ class TooMuchTagError < InvalidRSSError
+ attr_reader :tag, :parent
+ def initialize(tag, parent)
+ @tag, @parent = tag, parent
+ super("tag <#{tag}> is too much in tag <#{parent}>")
+ end
+ end
+
+ class MissingAttributeError < InvalidRSSError
+ attr_reader :tag, :attribute
+ def initialize(tag, attribute)
+ @tag, @attribute = tag, attribute
+ super("attribute <#{attribute}> is missing in tag <#{tag}>")
+ end
+ end
+
+ class UnknownTagError < InvalidRSSError
+ attr_reader :tag, :uri
+ def initialize(tag, uri)
+ @tag, @uri = tag, uri
+ super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>")
+ end
+ end
+
+ class NotExpectedTagError < InvalidRSSError
+ attr_reader :tag, :uri, :parent
+ def initialize(tag, uri, parent)
+ @tag, @uri, @parent = tag, uri, parent
+ super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>")
+ end
+ end
+ # For backward compatibility :X
+ NotExceptedTagError = NotExpectedTagError
+
+ class NotAvailableValueError < InvalidRSSError
+ attr_reader :tag, :value, :attribute
+ def initialize(tag, value, attribute=nil)
+ @tag, @value, @attribute = tag, value, attribute
+ message = "value <#{value}> of "
+ message << "attribute <#{attribute}> of " if attribute
+ message << "tag <#{tag}> is not available."
+ super(message)
+ end
+ end
+
+ class UnknownConversionMethodError < Error
+ attr_reader :to, :from
+ def initialize(to, from)
+ @to = to
+ @from = from
+ super("can't convert to #{to} from #{from}.")
+ end
+ end
+ # for backward compatibility
+ UnknownConvertMethod = UnknownConversionMethodError
+
+ class ConversionError < Error
+ attr_reader :string, :to, :from
+ def initialize(string, to, from)
+ @string = string
+ @to = to
+ @from = from
+ super("can't convert #{@string} to #{to} from #{from}.")
+ end
+ end
+
+ class NotSetError < Error
+ attr_reader :name, :variables
+ def initialize(name, variables)
+ @name = name
+ @variables = variables
+ super("required variables of #{@name} are not set: #{@variables.join(', ')}")
+ end
+ end
+
+ module BaseModel
+
+ include Utils
+
+ def install_have_child_element(tag_name, uri, occurs, name=nil)
+ name ||= tag_name
+ add_need_initialize_variable(name)
+ install_model(tag_name, uri, occurs, name)
+
+ attr_accessor name
+ install_element(name) do |n, elem_name|
+ <<-EOC
+ if @#{n}
+ "\#{@#{n}.to_s(need_convert, indent)}"
+ else
+ ''
+ end
+EOC
+ end
+ end
+ alias_method(:install_have_attribute_element, :install_have_child_element)
+
+ def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil)
+ name ||= tag_name
+ plural_name ||= "#{name}s"
+ add_have_children_element(name, plural_name)
+ add_plural_form(name, plural_name)
+ install_model(tag_name, uri, occurs, plural_name)
+
+ def_children_accessor(name, plural_name)
+ install_element(name, "s") do |n, elem_name|
+ <<-EOC
+ rv = []
+ @#{n}.each do |x|
+ value = "\#{x.to_s(need_convert, indent)}"
+ rv << value if /\\A\\s*\\z/ !~ value
+ end
+ rv.join("\n")
+EOC
+ end
+ end
+
+ def install_text_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
+ name ||= tag_name
+ disp_name ||= name
+ self::ELEMENTS << name
+ add_need_initialize_variable(name)
+ install_model(tag_name, uri, occurs, name)
+
+ def_corresponded_attr_writer name, type, disp_name
+ convert_attr_reader name
+ install_element(name) do |n, elem_name|
+ <<-EOC
+ if @#{n}
+ rv = "\#{indent}<#{elem_name}>"
+ value = html_escape(@#{n})
+ if need_convert
+ rv << convert(value)
+ else
+ rv << value
+ end
+ rv << "</#{elem_name}>"
+ rv
+ else
+ ''
+ end
+EOC
+ end
+ end
+
+ def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
+ name ||= tag_name
+ type ||= :w3cdtf
+ disp_name ||= name
+ self::ELEMENTS << name
+ add_need_initialize_variable(name)
+ install_model(tag_name, uri, occurs, name)
+
+ # accessor
+ convert_attr_reader name
+ date_writer(name, type, disp_name)
+
+ install_element(name) do |n, elem_name|
+ <<-EOC
+ if @#{n}
+ rv = "\#{indent}<#{elem_name}>"
+ value = html_escape(@#{n}.#{type})
+ if need_convert
+ rv << convert(value)
+ else
+ rv << value
+ end
+ rv << "</#{elem_name}>"
+ rv
+ else
+ ''
+ end
+EOC
+ end
+
+ end
+
+ private
+ def install_element(name, postfix="")
+ elem_name = name.sub('_', ':')
+ method_name = "#{name}_element#{postfix}"
+ add_to_element_method(method_name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{method_name}(need_convert=true, indent='')
+ #{yield(name, elem_name)}
+ end
+ private :#{method_name}
+EOC
+ end
+
+ def convert_attr_reader(*attrs)
+ attrs.each do |attr|
+ attr = attr.id2name if attr.kind_of?(Integer)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{attr}
+ if @converter
+ @converter.convert(@#{attr})
+ else
+ @#{attr}
+ end
+ end
+EOC
+ end
+ end
+
+ def date_writer(name, type, disp_name=name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{name}=(new_value)
+ if new_value.nil? or new_value.kind_of?(Time)
+ @#{name} = new_value
+ else
+ if @do_validate
+ begin
+ @#{name} = Time.__send__('#{type}', new_value)
+ rescue ArgumentError
+ raise NotAvailableValueError.new('#{disp_name}', new_value)
+ end
+ else
+ @#{name} = nil
+ if /\\A\\s*\\z/ !~ new_value.to_s
+ begin
+ @#{name} = Time.parse(new_value)
+ rescue ArgumentError
+ end
+ end
+ end
+ end
+
+ # Is it need?
+ if @#{name}
+ class << @#{name}
+ undef_method(:to_s)
+ alias_method(:to_s, :#{type})
+ end
+ end
+
+ end
+EOC
+ end
+
+ def integer_writer(name, disp_name=name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{name}=(new_value)
+ if new_value.nil?
+ @#{name} = new_value
+ else
+ if @do_validate
+ begin
+ @#{name} = Integer(new_value)
+ rescue ArgumentError
+ raise NotAvailableValueError.new('#{disp_name}', new_value)
+ end
+ else
+ @#{name} = new_value.to_i
+ end
+ end
+ end
+EOC
+ end
+
+ def positive_integer_writer(name, disp_name=name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{name}=(new_value)
+ if new_value.nil?
+ @#{name} = new_value
+ else
+ if @do_validate
+ begin
+ tmp = Integer(new_value)
+ raise ArgumentError if tmp <= 0
+ @#{name} = tmp
+ rescue ArgumentError
+ raise NotAvailableValueError.new('#{disp_name}', new_value)
+ end
+ else
+ @#{name} = new_value.to_i
+ end
+ end
+ end
+EOC
+ end
+
+ def boolean_writer(name, disp_name=name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{name}=(new_value)
+ if new_value.nil?
+ @#{name} = new_value
+ else
+ if @do_validate and
+ ![true, false, "true", "false"].include?(new_value)
+ raise NotAvailableValueError.new('#{disp_name}', new_value)
+ end
+ if [true, false].include?(new_value)
+ @#{name} = new_value
+ else
+ @#{name} = new_value == "true"
+ end
+ end
+ end
+EOC
+ end
+
+ def def_children_accessor(accessor_name, plural_name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{plural_name}
+ @#{accessor_name}
+ end
+
+ def #{accessor_name}(*args)
+ if args.empty?
+ @#{accessor_name}.first
+ else
+ @#{accessor_name}[*args]
+ end
+ end
+
+ def #{accessor_name}=(*args)
+ warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \
+ "Don't use `#{accessor_name} = XXX'/`set_#{accessor_name}(XXX)'. " \
+ "Those APIs are not sense of Ruby. " \
+ "Use `#{plural_name} << XXX' instead of them.")
+ if args.size == 1
+ @#{accessor_name}.push(args[0])
+ else
+ @#{accessor_name}.__send__("[]=", *args)
+ end
+ end
+ alias_method(:set_#{accessor_name}, :#{accessor_name}=)
+EOC
+ end
+ end
+
+ class Element
+
+ extend BaseModel
+ include Utils
+
+ INDENT = " "
+
+ MUST_CALL_VALIDATORS = {}
+ MODELS = []
+ GET_ATTRIBUTES = []
+ HAVE_CHILDREN_ELEMENTS = []
+ TO_ELEMENT_METHODS = []
+ NEED_INITIALIZE_VARIABLES = []
+ PLURAL_FORMS = {}
+
+ class << self
+
+ def must_call_validators
+ MUST_CALL_VALIDATORS
+ end
+ def models
+ MODELS
+ end
+ def get_attributes
+ GET_ATTRIBUTES
+ end
+ def have_children_elements
+ HAVE_CHILDREN_ELEMENTS
+ end
+ def to_element_methods
+ TO_ELEMENT_METHODS
+ end
+ def need_initialize_variables
+ NEED_INITIALIZE_VARIABLES
+ end
+ def plural_forms
+ PLURAL_FORMS
+ end
+
+
+ def inherited(klass)
+ klass.const_set("MUST_CALL_VALIDATORS", {})
+ klass.const_set("MODELS", [])
+ klass.const_set("GET_ATTRIBUTES", [])
+ klass.const_set("HAVE_CHILDREN_ELEMENTS", [])
+ klass.const_set("TO_ELEMENT_METHODS", [])
+ klass.const_set("NEED_INITIALIZE_VARIABLES", [])
+ klass.const_set("PLURAL_FORMS", {})
+
+ klass.module_eval(<<-EOC)
+ public
+
+ @tag_name = name.split(/::/).last
+ @tag_name[0,1] = @tag_name[0,1].downcase
+ @have_content = false
+
+ def self.must_call_validators
+ super.merge(MUST_CALL_VALIDATORS)
+ end
+ def self.models
+ MODELS + super
+ end
+ def self.get_attributes
+ GET_ATTRIBUTES + super
+ end
+ def self.have_children_elements
+ HAVE_CHILDREN_ELEMENTS + super
+ end
+ def self.to_element_methods
+ TO_ELEMENT_METHODS + super
+ end
+ def self.need_initialize_variables
+ NEED_INITIALIZE_VARIABLES + super
+ end
+ def self.plural_forms
+ super.merge(PLURAL_FORMS)
+ end
+
+
+ def self.install_must_call_validator(prefix, uri)
+ MUST_CALL_VALIDATORS[uri] = prefix
+ end
+
+ def self.install_model(tag, uri, occurs=nil, getter=nil)
+ getter ||= tag
+ if m = MODELS.find {|t, u, o, g| t == tag and u == uri}
+ m[2] = occurs
+ else
+ MODELS << [tag, uri, occurs, getter]
+ end
+ end
+
+ def self.install_get_attribute(name, uri, required=true,
+ type=nil, disp_name=nil,
+ element_name=nil)
+ disp_name ||= name
+ element_name ||= name
+ def_corresponded_attr_writer name, type, disp_name
+ convert_attr_reader name
+ if type == :boolean and /^is/ =~ name
+ alias_method "\#{$POSTMATCH}?", name
+ end
+ GET_ATTRIBUTES << [name, uri, required, element_name]
+ add_need_initialize_variable(disp_name)
+ end
+
+ def self.def_corresponded_attr_writer(name, type=nil, disp_name=name)
+ case type
+ when :integer
+ integer_writer name, disp_name
+ when :positive_integer
+ positive_integer_writer name, disp_name
+ when :boolean
+ boolean_writer name, disp_name
+ when :w3cdtf, :rfc822, :rfc2822
+ date_writer name, type, disp_name
+ else
+ attr_writer name
+ end
+ end
+
+ def self.content_setup(type=nil)
+ def_corresponded_attr_writer "content", type
+ convert_attr_reader :content
+ @have_content = true
+ end
+
+ def self.have_content?
+ @have_content
+ end
+
+ def self.add_have_children_element(variable_name, plural_name)
+ HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
+ end
+
+ def self.add_to_element_method(method_name)
+ TO_ELEMENT_METHODS << method_name
+ end
+
+ def self.add_need_initialize_variable(variable_name)
+ NEED_INITIALIZE_VARIABLES << variable_name
+ end
+
+ def self.add_plural_form(singular, plural)
+ PLURAL_FORMS[singular] = plural
+ end
+
+ EOC
+ end
+
+ def required_prefix
+ nil
+ end
+
+ def required_uri
+ ""
+ end
+
+ def install_ns(prefix, uri)
+ if self::NSPOOL.has_key?(prefix)
+ raise OverlappedPrefixError.new(prefix)
+ end
+ self::NSPOOL[prefix] = uri
+ end
+
+ def tag_name
+ @tag_name
+ end
+ end
+
+ attr_accessor :do_validate
+
+ def initialize(do_validate=true, attrs={})
+ @converter = nil
+ @do_validate = do_validate
+ initialize_variables(attrs)
+ end
+
+ def tag_name
+ self.class.tag_name
+ end
+
+ def full_name
+ tag_name
+ end
+
+ def converter=(converter)
+ @converter = converter
+ targets = children.dup
+ self.class.have_children_elements.each do |variable_name, plural_name|
+ targets.concat(__send__(plural_name))
+ end
+ targets.each do |target|
+ target.converter = converter unless target.nil?
+ end
+ end
+
+ def convert(value)
+ if @converter
+ @converter.convert(value)
+ else
+ value
+ end
+ end
+
+ def validate(ignore_unknown_element=true)
+ validate_attribute
+ __validate(ignore_unknown_element)
+ end
+
+ def validate_for_stream(tags, ignore_unknown_element=true)
+ validate_attribute
+ __validate(ignore_unknown_element, tags, false)
+ end
+
+ def setup_maker(maker)
+ target = maker_target(maker)
+ unless target.nil?
+ setup_maker_attributes(target)
+ setup_maker_element(target)
+ setup_maker_elements(target)
+ end
+ end
+
+ def to_s(need_convert=true, indent='')
+ if self.class.have_content?
+ return "" unless @content
+ rv = tag(indent) do |next_indent|
+ h(@content)
+ end
+ else
+ rv = tag(indent) do |next_indent|
+ self.class.to_element_methods.collect do |method_name|
+ __send__(method_name, false, next_indent)
+ end
+ end
+ end
+ rv = convert(rv) if need_convert
+ rv
+ end
+
+ private
+ def initialize_variables(attrs)
+ normalized_attrs = {}
+ attrs.each do |key, value|
+ normalized_attrs[key.to_s] = value
+ end
+ self.class.need_initialize_variables.each do |variable_name|
+ value = normalized_attrs[variable_name.to_s]
+ if value
+ __send__("#{variable_name}=", value)
+ else
+ instance_eval("@#{variable_name} = nil")
+ end
+ end
+ initialize_have_children_elements
+ @content = "" if self.class.have_content?
+ end
+
+ def initialize_have_children_elements
+ self.class.have_children_elements.each do |variable_name, plural_name|
+ instance_eval("@#{variable_name} = []")
+ end
+ end
+
+ def tag(indent, additional_attrs={}, &block)
+ next_indent = indent + INDENT
+
+ attrs = collect_attrs
+ return "" if attrs.nil?
+
+ attrs.update(additional_attrs)
+ start_tag = make_start_tag(indent, next_indent, attrs)
+
+ if block
+ content = block.call(next_indent)
+ else
+ content = []
+ end
+
+ if content.is_a?(String)
+ content = [content]
+ start_tag << ">"
+ end_tag = "</#{full_name}>"
+ else
+ content = content.reject{|x| x.empty?}
+ if content.empty?
+ end_tag = "/>"
+ else
+ start_tag << ">\n"
+ end_tag = "\n#{indent}</#{full_name}>"
+ end
+ end
+
+ start_tag + content.join("\n") + end_tag
+ end
+
+ def make_start_tag(indent, next_indent, attrs)
+ start_tag = ["#{indent}<#{full_name}"]
+ unless attrs.empty?
+ start_tag << attrs.collect do |key, value|
+ %Q[#{h key}="#{h value}"]
+ end.join("\n#{next_indent}")
+ end
+ start_tag.join(" ")
+ end
+
+ def collect_attrs
+ attrs = {}
+ _attrs.each do |name, required, alias_name|
+ value = __send__(alias_name || name)
+ return nil if required and value.nil?
+ next if value.nil?
+ return nil if attrs.has_key?(name)
+ attrs[name] = value
+ end
+ attrs
+ end
+
+ def tag_name_with_prefix(prefix)
+ "#{prefix}:#{tag_name}"
+ end
+
+ # For backward compatibility
+ def calc_indent
+ ''
+ end
+
+ def maker_target(maker)
+ nil
+ end
+
+ def setup_maker_attributes(target)
+ end
+
+ def setup_maker_element(target)
+ self.class.need_initialize_variables.each do |var|
+ value = __send__(var)
+ if value.respond_to?("setup_maker") and
+ !not_need_to_call_setup_maker_variables.include?(var)
+ value.setup_maker(target)
+ else
+ setter = "#{var}="
+ if target.respond_to?(setter)
+ target.__send__(setter, value)
+ end
+ end
+ end
+ end
+
+ def not_need_to_call_setup_maker_variables
+ []
+ end
+
+ def setup_maker_elements(parent)
+ self.class.have_children_elements.each do |name, plural_name|
+ if parent.respond_to?(plural_name)
+ target = parent.__send__(plural_name)
+ __send__(plural_name).each do |elem|
+ elem.setup_maker(target)
+ end
+ end
+ end
+ end
+
+ def set_next_element(tag_name, next_element)
+ klass = next_element.class
+ prefix = ""
+ prefix << "#{klass.required_prefix}_" if klass.required_prefix
+ key = "#{prefix}#{tag_name}"
+ if self.class.plural_forms.has_key?(key)
+ ary = __send__("#{self.class.plural_forms[key]}")
+ ary << next_element
+ else
+ __send__("#{prefix}#{tag_name}=", next_element)
+ end
+ end
+
+ def children
+ rv = []
+ self.class.models.each do |name, uri, occurs, getter|
+ value = __send__(getter)
+ next if value.nil?
+ value = [value] unless value.is_a?(Array)
+ value.each do |v|
+ rv << v if v.is_a?(Element)
+ end
+ end
+ rv
+ end
+
+ def _tags
+ rv = []
+ self.class.models.each do |name, uri, occurs, getter|
+ value = __send__(getter)
+ next if value.nil?
+ if value.is_a?(Array)
+ rv.concat([[uri, name]] * value.size)
+ else
+ rv << [uri, name]
+ end
+ end
+ rv
+ end
+
+ def _attrs
+ self.class.get_attributes.collect do |name, uri, required, element_name|
+ [element_name, required, name]
+ end
+ end
+
+ def __validate(ignore_unknown_element, tags=_tags, recursive=true)
+ if recursive
+ children.compact.each do |child|
+ child.validate
+ end
+ end
+ must_call_validators = self.class.must_call_validators
+ tags = tag_filter(tags.dup)
+ p tags if DEBUG
+ must_call_validators.each do |uri, prefix|
+ _validate(ignore_unknown_element, tags[uri], uri)
+ meth = "#{prefix}_validate"
+ if respond_to?(meth, true)
+ __send__(meth, ignore_unknown_element, tags[uri], uri)
+ end
+ end
+ end
+
+ def validate_attribute
+ _attrs.each do |a_name, required, alias_name|
+ if required and __send__(alias_name || a_name).nil?
+ raise MissingAttributeError.new(tag_name, a_name)
+ end
+ end
+ end
+
+ def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
+ count = 1
+ do_redo = false
+ not_shift = false
+ tag = nil
+ models = models.find_all {|model| model[1] == uri}
+ element_names = models.collect {|model| model[0]}
+ if tags
+ tags_size = tags.size
+ tags = tags.sort_by {|x| element_names.index(x) || tags_size}
+ end
+
+ models.each_with_index do |model, i|
+ name, model_uri, occurs, getter = model
+
+ if DEBUG
+ p "before"
+ p tags
+ p model
+ end
+
+ if not_shift
+ not_shift = false
+ elsif tags
+ tag = tags.shift
+ end
+
+ if DEBUG
+ p "mid"
+ p count
+ end
+
+ case occurs
+ when '?'
+ if count > 2
+ raise TooMuchTagError.new(name, tag_name)
+ else
+ if name == tag
+ do_redo = true
+ else
+ not_shift = true
+ end
+ end
+ when '*'
+ if name == tag
+ do_redo = true
+ else
+ not_shift = true
+ end
+ when '+'
+ if name == tag
+ do_redo = true
+ else
+ if count > 1
+ not_shift = true
+ else
+ raise MissingTagError.new(name, tag_name)
+ end
+ end
+ else
+ if name == tag
+ if models[i+1] and models[i+1][0] != name and
+ tags and tags.first == name
+ raise TooMuchTagError.new(name, tag_name)
+ end
+ else
+ raise MissingTagError.new(name, tag_name)
+ end
+ end
+
+ if DEBUG
+ p "after"
+ p not_shift
+ p do_redo
+ p tag
+ end
+
+ if do_redo
+ do_redo = false
+ count += 1
+ redo
+ else
+ count = 1
+ end
+
+ end
+
+ if !ignore_unknown_element and !tags.nil? and !tags.empty?
+ raise NotExpectedTagError.new(tags.first, uri, tag_name)
+ end
+
+ end
+
+ def tag_filter(tags)
+ rv = {}
+ tags.each do |tag|
+ rv[tag[0]] = [] unless rv.has_key?(tag[0])
+ rv[tag[0]].push(tag[1])
+ end
+ rv
+ end
+
+ end
+
+ module RootElementMixin
+
+ include XMLStyleSheetMixin
+
+ attr_reader :output_encoding
+
+ def initialize(rss_version, version=nil, encoding=nil, standalone=nil)
+ super()
+ @rss_version = rss_version
+ @version = version || '1.0'
+ @encoding = encoding
+ @standalone = standalone
+ @output_encoding = nil
+ end
+
+ def output_encoding=(enc)
+ @output_encoding = enc
+ self.converter = Converter.new(@output_encoding, @encoding)
+ end
+
+ def setup_maker(maker)
+ maker.version = version
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ xml_stylesheets.each do |xss|
+ xss.setup_maker(maker)
+ end
+
+ setup_maker_elements(maker)
+ end
+
+ def to_xml(version=nil, &block)
+ if version.nil? or version == @rss_version
+ to_s
+ else
+ RSS::Maker.make(version) do |maker|
+ setup_maker(maker)
+ block.call(maker) if block
+ end.to_s
+ end
+ end
+
+ private
+ def tag(indent, attrs={}, &block)
+ rv = xmldecl + xml_stylesheet_pi
+ rv << super(indent, ns_declarations.merge(attrs), &block)
+ rv
+ end
+
+ def xmldecl
+ rv = %Q[<?xml version="#{@version}"]
+ if @output_encoding or @encoding
+ rv << %Q[ encoding="#{@output_encoding or @encoding}"]
+ end
+ rv << %Q[ standalone="yes"] if @standalone
+ rv << "?>\n"
+ rv
+ end
+
+ def ns_declarations
+ decls = {}
+ self.class::NSPOOL.collect do |prefix, uri|
+ prefix = ":#{prefix}" unless prefix.empty?
+ decls["xmlns#{prefix}"] = uri
+ end
+ decls
+ end
+
+ def setup_maker_elements(maker)
+ channel.setup_maker(maker) if channel
+ image.setup_maker(maker) if image
+ textinput.setup_maker(maker) if textinput
+ super(maker)
+ end
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/syndication.rb b/ruby_1_8_5/lib/rss/syndication.rb
new file mode 100644
index 0000000000..93d35c89a7
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/syndication.rb
@@ -0,0 +1,64 @@
+require "rss/1.0"
+
+module RSS
+
+ SY_PREFIX = 'sy'
+ SY_URI = "http://purl.org/rss/1.0/modules/syndication/"
+
+ RDF.install_ns(SY_PREFIX, SY_URI)
+
+ module SyndicationModel
+
+ extend BaseModel
+
+ ELEMENTS = []
+
+ def self.append_features(klass)
+ super
+
+ klass.install_must_call_validator(SY_PREFIX, SY_URI)
+ klass.module_eval do
+ [
+ ["updatePeriod"],
+ ["updateFrequency", :positive_integer]
+ ].each do |name, type|
+ install_text_element(name, SY_URI, "?",
+ "#{SY_PREFIX}_#{name}", type,
+ "#{SY_PREFIX}:#{name}")
+ end
+
+ %w(updateBase).each do |name|
+ install_date_element(name, SY_URI, "?",
+ "#{SY_PREFIX}_#{name}", 'w3cdtf', name)
+ end
+
+ alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)
+ def sy_updatePeriod=(new_value)
+ new_value = new_value.strip
+ validate_sy_updatePeriod(new_value) if @do_validate
+ self._sy_updatePeriod = new_value
+ end
+ end
+ end
+
+ private
+ SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly)
+ def validate_sy_updatePeriod(value)
+ unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value)
+ raise NotAvailableValueError.new("updatePeriod", value)
+ end
+ end
+ end
+
+ class RDF
+ class Channel; include SyndicationModel; end
+ end
+
+ prefix_size = SY_PREFIX.size + 1
+ SyndicationModel::ELEMENTS.uniq!
+ SyndicationModel::ELEMENTS.each do |full_name|
+ name = full_name[prefix_size..-1]
+ BaseListener.install_get_text_element(SY_URI, name, "#{full_name}=")
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/taxonomy.rb b/ruby_1_8_5/lib/rss/taxonomy.rb
new file mode 100644
index 0000000000..8caa25e2a4
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/taxonomy.rb
@@ -0,0 +1,145 @@
+require "rss/1.0"
+require "rss/dublincore"
+
+module RSS
+
+ TAXO_PREFIX = "taxo"
+ TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/"
+
+ RDF.install_ns(TAXO_PREFIX, TAXO_URI)
+
+ TAXO_ELEMENTS = []
+
+ %w(link).each do |name|
+ full_name = "#{TAXO_PREFIX}_#{name}"
+ BaseListener.install_get_text_element(TAXO_URI, name, "#{full_name}=")
+ TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
+ end
+
+ %w(topic topics).each do |name|
+ class_name = Utils.to_class_name(name)
+ BaseListener.install_class_name(TAXO_URI, name, "Taxonomy#{class_name}")
+ TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
+ end
+
+ module TaxonomyTopicsModel
+ extend BaseModel
+
+ def self.append_features(klass)
+ super
+
+ klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI)
+ %w(topics).each do |name|
+ klass.install_have_child_element(name, TAXO_URI, "?",
+ "#{TAXO_PREFIX}_#{name}")
+ end
+ end
+
+ class TaxonomyTopics < Element
+ include RSS10
+
+ Bag = ::RSS::RDF::Bag
+
+ class << self
+ def required_prefix
+ TAXO_PREFIX
+ end
+
+ def required_uri
+ TAXO_URI
+ end
+ end
+
+ @tag_name = "topics"
+
+ install_have_child_element("Bag", RDF::URI, nil)
+ install_must_call_validator('rdf', RDF::URI)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.Bag = args[0]
+ end
+ self.Bag ||= Bag.new
+ end
+
+ def full_name
+ tag_name_with_prefix(TAXO_PREFIX)
+ end
+
+ def maker_target(target)
+ target.taxo_topics
+ end
+
+ def resources
+ if @Bag
+ @Bag.lis.collect do |li|
+ li.resource
+ end
+ else
+ []
+ end
+ end
+ end
+ end
+
+ module TaxonomyTopicModel
+ extend BaseModel
+
+ def self.append_features(klass)
+ super
+ var_name = "#{TAXO_PREFIX}_topic"
+ klass.install_have_children_element("topic", TAXO_URI, "*", var_name)
+ end
+
+ class TaxonomyTopic < Element
+ include RSS10
+
+ include DublinCoreModel
+ include TaxonomyTopicsModel
+
+ class << self
+ def required_prefix
+ TAXO_PREFIX
+ end
+
+ def required_uri
+ TAXO_URI
+ end
+ end
+
+ @tag_name = "topic"
+
+ install_get_attribute("about", ::RSS::RDF::URI, true, nil, nil,
+ "#{RDF::PREFIX}:about")
+ install_text_element("link", TAXO_URI, "?", "#{TAXO_PREFIX}_link")
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(TAXO_PREFIX)
+ end
+
+ def maker_target(target)
+ target.new_taxo_topic
+ end
+ end
+ end
+
+ class RDF
+ include TaxonomyTopicModel
+ class Channel
+ include TaxonomyTopicsModel
+ end
+ class Item; include TaxonomyTopicsModel; end
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/trackback.rb b/ruby_1_8_5/lib/rss/trackback.rb
new file mode 100644
index 0000000000..ee2491f332
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/trackback.rb
@@ -0,0 +1,288 @@
+require 'rss/1.0'
+require 'rss/2.0'
+
+module RSS
+
+ TRACKBACK_PREFIX = 'trackback'
+ TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/'
+
+ RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
+ Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
+
+ module TrackBackUtils
+ private
+ def trackback_validate(ignore_unknown_element, tags, uri)
+ return if tags.nil?
+ if tags.find {|tag| tag == "about"} and
+ !tags.find {|tag| tag == "ping"}
+ raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name)
+ end
+ end
+ end
+
+ module BaseTrackBackModel
+
+ ELEMENTS = %w(ping about)
+
+ def append_features(klass)
+ super
+
+ unless klass.class == Module
+ klass.module_eval {include TrackBackUtils}
+
+ klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI)
+ %w(ping).each do |name|
+ var_name = "#{TRACKBACK_PREFIX}_#{name}"
+ klass_name = "TrackBack#{Utils.to_class_name(name)}"
+ klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__)
+ remove_method :#{var_name}
+ def #{var_name}
+ @#{var_name} and @#{var_name}.value
+ end
+
+ remove_method :#{var_name}=
+ def #{var_name}=(value)
+ @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value)
+ end
+ EOC
+ end
+
+ [%w(about s)].each do |name, postfix|
+ var_name = "#{TRACKBACK_PREFIX}_#{name}"
+ klass_name = "TrackBack#{Utils.to_class_name(name)}"
+ klass.install_have_children_element(name, TRACKBACK_URI, "*",
+ var_name)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__)
+ remove_method :#{var_name}
+ def #{var_name}(*args)
+ if args.empty?
+ @#{var_name}.first and @#{var_name}.first.value
+ else
+ ret = @#{var_name}.__send__("[]", *args)
+ if ret.is_a?(Array)
+ ret.collect {|x| x.value}
+ else
+ ret.value
+ end
+ end
+ end
+
+ remove_method :#{var_name}=
+ remove_method :set_#{var_name}
+ def #{var_name}=(*args)
+ if args.size == 1
+ item = Utils.new_with_value_if_need(#{klass_name}, args[0])
+ @#{var_name}.push(item)
+ else
+ new_val = args.last
+ if new_val.is_a?(Array)
+ new_val = new_value.collect do |val|
+ Utils.new_with_value_if_need(#{klass_name}, val)
+ end
+ else
+ new_val = Utils.new_with_value_if_need(#{klass_name}, new_val)
+ end
+ @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val]))
+ end
+ end
+ alias set_#{var_name} #{var_name}=
+ EOC
+ end
+ end
+ end
+ end
+
+ module TrackBackModel10
+ extend BaseModel
+ extend BaseTrackBackModel
+
+ class TrackBackPing < Element
+ include RSS10
+
+ class << self
+
+ def required_prefix
+ TRACKBACK_PREFIX
+ end
+
+ def required_uri
+ TRACKBACK_URI
+ end
+
+ end
+
+ @tag_name = "ping"
+
+ [
+ ["resource", ::RSS::RDF::URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{::RSS::RDF::PREFIX}:#{name}")
+ end
+
+ alias_method(:value, :resource)
+ alias_method(:value=, :resource=)
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(TRACKBACK_PREFIX)
+ end
+ end
+
+ class TrackBackAbout < Element
+ include RSS10
+
+ class << self
+
+ def required_prefix
+ TRACKBACK_PREFIX
+ end
+
+ def required_uri
+ TRACKBACK_URI
+ end
+
+ end
+
+ @tag_name = "about"
+
+ [
+ ["resource", ::RSS::RDF::URI, true]
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{::RSS::RDF::PREFIX}:#{name}")
+ end
+
+ alias_method(:value, :resource)
+ alias_method(:value=, :resource=)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(TRACKBACK_PREFIX)
+ end
+
+ private
+ def maker_target(abouts)
+ abouts.new_about
+ end
+
+ def setup_maker_attributes(about)
+ about.resource = self.resource
+ end
+
+ end
+ end
+
+ module TrackBackModel20
+ extend BaseModel
+ extend BaseTrackBackModel
+
+ class TrackBackPing < Element
+ include RSS09
+
+ @tag_name = "ping"
+
+ content_setup
+
+ class << self
+
+ def required_prefix
+ TRACKBACK_PREFIX
+ end
+
+ def required_uri
+ TRACKBACK_URI
+ end
+
+ end
+
+ alias_method(:value, :content)
+ alias_method(:value=, :content=)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(TRACKBACK_PREFIX)
+ end
+
+ end
+
+ class TrackBackAbout < Element
+ include RSS09
+
+ @tag_name = "about"
+
+ content_setup
+
+ class << self
+
+ def required_prefix
+ TRACKBACK_PREFIX
+ end
+
+ def required_uri
+ TRACKBACK_URI
+ end
+
+ end
+
+ alias_method(:value, :content)
+ alias_method(:value=, :content=)
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
+ end
+
+ def full_name
+ tag_name_with_prefix(TRACKBACK_PREFIX)
+ end
+
+ end
+ end
+
+ class RDF
+ class Item; include TrackBackModel10; end
+ end
+
+ class Rss
+ class Channel
+ class Item; include TrackBackModel20; end
+ end
+ end
+
+ BaseTrackBackModel::ELEMENTS.each do |name|
+ class_name = Utils.to_class_name(name)
+ BaseListener.install_class_name(TRACKBACK_URI, name,
+ "TrackBack#{class_name}")
+ end
+
+ BaseTrackBackModel::ELEMENTS.collect! {|name| "#{TRACKBACK_PREFIX}_#{name}"}
+end
diff --git a/ruby_1_8_5/lib/rss/utils.rb b/ruby_1_8_5/lib/rss/utils.rb
new file mode 100644
index 0000000000..b242a72292
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/utils.rb
@@ -0,0 +1,37 @@
+module RSS
+ module Utils
+ module_function
+
+ # Convert a name_with_underscores to CamelCase.
+ def to_class_name(name)
+ name.split(/_/).collect do |part|
+ "#{part[0, 1].upcase}#{part[1..-1]}"
+ end.join("")
+ end
+
+ def get_file_and_line_from_caller(i=0)
+ file, line, = caller[i].split(':')
+ [file, line.to_i]
+ end
+
+ # escape '&', '"', '<' and '>' for use in HTML.
+ def html_escape(s)
+ s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
+ end
+ alias h html_escape
+
+ # If +value+ is an instance of class +klass+, return it, else
+ # create a new instance of +klass+ with value +value+.
+ def new_with_value_if_need(klass, value)
+ if value.is_a?(klass)
+ value
+ else
+ klass.new(value)
+ end
+ end
+
+ def element_initialize_arguments?(args)
+ [true, false].include?(args[0]) and args[1].is_a?(Hash)
+ end
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/xml-stylesheet.rb b/ruby_1_8_5/lib/rss/xml-stylesheet.rb
new file mode 100644
index 0000000000..66e3161dd0
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/xml-stylesheet.rb
@@ -0,0 +1,101 @@
+require "rss/utils"
+
+module RSS
+
+ module XMLStyleSheetMixin
+ attr_accessor :xml_stylesheets
+ def initialize(*args)
+ super
+ @xml_stylesheets = []
+ end
+
+ private
+ def xml_stylesheet_pi
+ xsss = @xml_stylesheets.collect do |xss|
+ pi = xss.to_s
+ pi = nil if /\A\s*\z/ =~ pi
+ pi
+ end.compact
+ xsss.push("") unless xsss.empty?
+ xsss.join("\n")
+ end
+ end
+
+ class XMLStyleSheet
+
+ include Utils
+
+ ATTRIBUTES = %w(href type title media charset alternate)
+
+ GUESS_TABLE = {
+ "xsl" => "text/xsl",
+ "css" => "text/css",
+ }
+
+ attr_accessor(*ATTRIBUTES)
+ attr_accessor(:do_validate)
+ def initialize(*attrs)
+ @do_validate = true
+ ATTRIBUTES.each do |attr|
+ __send__("#{attr}=", nil)
+ end
+ vars = ATTRIBUTES.dup
+ vars.unshift(:do_validate)
+ attrs.each do |name, value|
+ if vars.include?(name.to_s)
+ __send__("#{name}=", value)
+ end
+ end
+ end
+
+ def to_s
+ rv = ""
+ if @href
+ rv << %Q[<?xml-stylesheet]
+ ATTRIBUTES.each do |name|
+ if __send__(name)
+ rv << %Q[ #{name}="#{h __send__(name)}"]
+ end
+ end
+ rv << %Q[?>]
+ end
+ rv
+ end
+
+ remove_method(:href=)
+ def href=(value)
+ @href = value
+ if @href and @type.nil?
+ @type = guess_type(@href)
+ end
+ @href
+ end
+
+ remove_method(:alternate=)
+ def alternate=(value)
+ if value.nil? or /\A(?:yes|no)\z/ =~ value
+ @alternate = value
+ else
+ if @do_validate
+ args = ["?xml-stylesheet?", %Q[alternate="#{value}"]]
+ raise NotAvailableValueError.new(*args)
+ end
+ end
+ @alternate
+ end
+
+ def setup_maker(maker)
+ xss = maker.xml_stylesheets.new_xml_stylesheet
+ ATTRIBUTES.each do |attr|
+ xss.__send__("#{attr}=", __send__(attr))
+ end
+ end
+
+ private
+ def guess_type(filename)
+ /\.([^.]+)$/ =~ filename
+ GUESS_TABLE[$1]
+ end
+
+ end
+end
diff --git a/ruby_1_8_5/lib/rss/xmlparser.rb b/ruby_1_8_5/lib/rss/xmlparser.rb
new file mode 100644
index 0000000000..3dfe7d461a
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/xmlparser.rb
@@ -0,0 +1,93 @@
+begin
+ require "xml/parser"
+rescue LoadError
+ require "xmlparser"
+end
+
+begin
+ require "xml/encoding-ja"
+rescue LoadError
+ require "xmlencoding-ja"
+ if defined?(Kconv)
+ module XMLEncoding_ja
+ class SJISHandler
+ include Kconv
+ end
+ end
+ end
+end
+
+module XML
+ class Parser
+ unless defined?(Error)
+ Error = ::XMLParserError
+ end
+ end
+end
+
+module RSS
+
+ class REXMLLikeXMLParser < ::XML::Parser
+
+ include ::XML::Encoding_ja
+
+ def listener=(listener)
+ @listener = listener
+ end
+
+ def startElement(name, attrs)
+ @listener.tag_start(name, attrs)
+ end
+
+ def endElement(name)
+ @listener.tag_end(name)
+ end
+
+ def character(data)
+ @listener.text(data)
+ end
+
+ def xmlDecl(version, encoding, standalone)
+ @listener.xmldecl(version, encoding, standalone == 1)
+ end
+
+ def processingInstruction(target, content)
+ @listener.instruction(target, content)
+ end
+
+ end
+
+ class XMLParserParser < BaseParser
+
+ class << self
+ def listener
+ XMLParserListener
+ end
+ end
+
+ private
+ def _parse
+ begin
+ parser = REXMLLikeXMLParser.new
+ parser.listener = @listener
+ parser.parse(@rss)
+ rescue ::XML::Parser::Error => e
+ raise NotWellFormedError.new(parser.line){e.message}
+ end
+ end
+
+ end
+
+ class XMLParserListener < BaseListener
+
+ include ListenerMixin
+
+ def xmldecl(version, encoding, standalone)
+ super
+ # Encoding is converted to UTF-8 when XMLParser parses XML.
+ @encoding = 'UTF-8'
+ end
+
+ end
+
+end
diff --git a/ruby_1_8_5/lib/rss/xmlscanner.rb b/ruby_1_8_5/lib/rss/xmlscanner.rb
new file mode 100644
index 0000000000..61b9fa6bf4
--- /dev/null
+++ b/ruby_1_8_5/lib/rss/xmlscanner.rb
@@ -0,0 +1,121 @@
+require 'xmlscan/scanner'
+require 'stringio'
+
+module RSS
+
+ class XMLScanParser < BaseParser
+
+ class << self
+ def listener
+ XMLScanListener
+ end
+ end
+
+ private
+ def _parse
+ begin
+ if @rss.is_a?(String)
+ input = StringIO.new(@rss)
+ else
+ input = @rss
+ end
+ scanner = XMLScan::XMLScanner.new(@listener)
+ scanner.parse(input)
+ rescue XMLScan::Error => e
+ lineno = e.lineno || scanner.lineno || input.lineno
+ raise NotWellFormedError.new(lineno){e.message}
+ end
+ end
+
+ end
+
+ class XMLScanListener < BaseListener
+
+ include XMLScan::Visitor
+ include ListenerMixin
+
+ ENTITIES = {
+ 'lt' => '<',
+ 'gt' => '>',
+ 'amp' => '&',
+ 'quot' => '"',
+ 'apos' => '\''
+ }
+
+ def on_xmldecl_version(str)
+ @version = str
+ end
+
+ def on_xmldecl_encoding(str)
+ @encoding = str
+ end
+
+ def on_xmldecl_standalone(str)
+ @standalone = str
+ end
+
+ def on_xmldecl_end
+ xmldecl(@version, @encoding, @standalone == "yes")
+ end
+
+ alias_method(:on_pi, :instruction)
+ alias_method(:on_chardata, :text)
+ alias_method(:on_cdata, :text)
+
+ def on_etag(name)
+ tag_end(name)
+ end
+
+ def on_entityref(ref)
+ text(entity(ref))
+ end
+
+ def on_charref(code)
+ text([code].pack('U'))
+ end
+
+ alias_method(:on_charref_hex, :on_charref)
+
+ def on_stag(name)
+ @attrs = {}
+ end
+
+ def on_attribute(name)
+ @attrs[name] = @current_attr = ''
+ end
+
+ def on_attr_value(str)
+ @current_attr << str
+ end
+
+ def on_attr_entityref(ref)
+ @current_attr << entity(ref)
+ end
+
+ def on_attr_charref(code)
+ @current_attr << [code].pack('U')
+ end
+
+ alias_method(:on_attr_charref_hex, :on_attr_charref)
+
+ def on_stag_end(name)
+ tag_start(name, @attrs)
+ end
+
+ def on_stag_end_empty(name)
+ tag_start(name, @attrs)
+ tag_end(name)
+ end
+
+ private
+ def entity(ref)
+ ent = ENTITIES[ref]
+ if ent
+ ent
+ else
+ wellformed_error("undefined entity: #{ref}")
+ end
+ end
+ end
+
+end