diff options
Diffstat (limited to 'trunk/lib/rss')
42 files changed, 0 insertions, 9269 deletions
diff --git a/trunk/lib/rss/0.9.rb b/trunk/lib/rss/0.9.rb deleted file mode 100644 index 7b24e7596d..0000000000 --- a/trunk/lib/rss/0.9.rb +++ /dev/null @@ -1,428 +0,0 @@ -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 - - %w(channel).each do |name| - install_have_child_element(name, "", nil) - end - - attr_writer :feed_version - alias_method(:rss_version, :feed_version) - alias_method(:rss_version=, :feed_version=) - - def initialize(feed_version, version=nil, encoding=nil, standalone=nil) - super - @feed_type = "rss" - 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 - image.setup_maker(maker) if image - textinput.setup_maker(maker) if textinput - end - - private - def _attrs - [ - ["version", true, "feed_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 initial_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 - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate - end - @proc_stack.push(pr) - end - - end - -end diff --git a/trunk/lib/rss/1.0.rb b/trunk/lib/rss/1.0.rb deleted file mode 100644 index f04e61c5eb..0000000000 --- a/trunk/lib/rss/1.0.rb +++ /dev/null @@ -1,452 +0,0 @@ -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 - - alias_method(:rss_version, :feed_version) - def initialize(version=nil, encoding=nil, standalone=nil) - super('1.0', version, encoding, standalone) - @feed_type = "rss" - 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 initial_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 - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate - end - @proc_stack.push(pr) - end - end - -end diff --git a/trunk/lib/rss/2.0.rb b/trunk/lib/rss/2.0.rb deleted file mode 100644 index 3798da4eb7..0000000000 --- a/trunk/lib/rss/2.0.rb +++ /dev/null @@ -1,111 +0,0 @@ -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/trunk/lib/rss/atom.rb b/trunk/lib/rss/atom.rb deleted file mode 100644 index 10282a8743..0000000000 --- a/trunk/lib/rss/atom.rb +++ /dev/null @@ -1,748 +0,0 @@ -require 'rss/parser' - -module RSS - module Atom - URI = "http://www.w3.org/2005/Atom" - XHTML_URI = "http://www.w3.org/1999/xhtml" - - module CommonModel - NSPOOL = {} - ELEMENTS = [] - - def self.append_features(klass) - super - klass.install_must_call_validator("atom", URI) - [ - ["lang", :xml], - ["base", :xml], - ].each do |name, uri, required| - klass.install_get_attribute(name, uri, required, [nil, :inherit]) - end - klass.class_eval do - class << self - def required_uri - URI - end - - def need_parent? - true - end - end - end - end - end - - module ContentModel - module ClassMethods - def content_type - @content_type ||= nil - end - end - - class << self - def append_features(klass) - super - klass.extend(ClassMethods) - klass.content_setup(klass.content_type, klass.tag_name) - end - end - - def maker_target(target) - target - end - - private - def setup_maker_element_writer - "#{self.class.name.split(/::/).last.downcase}=" - end - - def setup_maker_element(target) - target.__send__(setup_maker_element_writer, content) - super - end - end - - module URIContentModel - class << self - def append_features(klass) - super - klass.class_eval do - @content_type = [nil, :uri] - include(ContentModel) - end - end - end - end - - module TextConstruct - def self.append_features(klass) - super - klass.class_eval do - [ - ["type", ""], - ].each do |name, uri, required| - install_get_attribute(name, uri, required, :text_type) - end - - content_setup - add_need_initialize_variable("xhtml") - - class << self - def xml_getter - "xhtml" - end - - def xml_setter - "xhtml=" - end - end - end - end - - attr_writer :xhtml - def xhtml - return @xhtml if @xhtml.nil? - if @xhtml.is_a?(XML::Element) and - [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI] - return @xhtml - end - - children = @xhtml - children = [children] unless children.is_a?(Array) - XML::Element.new("div", nil, XHTML_URI, - {"xmlns" => XHTML_URI}, children) - end - - def have_xml_content? - @type == "xhtml" - end - - def atom_validate(ignore_unknown_element, tags, uri) - if have_xml_content? - if @xhtml.nil? - raise MissingTagError.new("div", tag_name) - end - unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI] - raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name) - end - end - end - - private - def maker_target(target) - target.__send__(self.class.name.split(/::/).last.downcase) {|x| x} - end - - def setup_maker_attributes(target) - target.type = type - target.content = content - target.xml_content = @xhtml - end - end - - module PersonConstruct - def self.append_features(klass) - super - klass.class_eval do - [ - ["name", nil], - ["uri", "?"], - ["email", "?"], - ].each do |tag, occurs| - install_have_attribute_element(tag, URI, occurs, nil, :content) - end - end - end - - def maker_target(target) - target.__send__("new_#{self.class.name.split(/::/).last.downcase}") - end - - class Name < RSS::Element - include CommonModel - include ContentModel - end - - class Uri < RSS::Element - include CommonModel - include URIContentModel - end - - class Email < RSS::Element - include CommonModel - include ContentModel - end - end - - module DateConstruct - def self.append_features(klass) - super - klass.class_eval do - @content_type = :w3cdtf - include(ContentModel) - end - end - - def atom_validate(ignore_unknown_element, tags, uri) - raise NotAvailableValueError.new(tag_name, "") if content.nil? - end - end - - module DuplicateLinkChecker - def validate_duplicate_links(links) - link_infos = {} - links.each do |link| - rel = link.rel || "alternate" - next unless rel == "alternate" - key = [link.hreflang, link.type] - if link_infos.has_key?(key) - raise TooMuchTagError.new("link", tag_name) - end - link_infos[key] = true - end - end - end - - class Feed < RSS::Element - include RootElementMixin - include CommonModel - include DuplicateLinkChecker - - install_ns('', URI) - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["contributor", "*", :children], - ["generator", "?"], - ["icon", "?", nil, :content], - ["id", nil, nil, :content], - ["link", "*", :children], - ["logo", "?"], - ["rights", "?"], - ["subtitle", "?", nil, :content], - ["title", nil, nil, :content], - ["updated", nil, nil, :content], - ["entry", "*", :children, "entries"], - ].each do |tag, occurs, type, *args| - type ||= :child - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - def initialize(version=nil, encoding=nil, standalone=nil) - super("1.0", version, encoding, standalone) - @feed_type = "atom" - @feed_subtype = "feed" - end - - alias_method :items, :entries - - def have_author? - authors.any? {|author| !author.to_s.empty?} or - entries.any? {|entry| entry.have_author?(false)} - end - - private - def atom_validate(ignore_unknown_element, tags, uri) - unless have_author? - raise MissingTagError.new("author", tag_name) - end - validate_duplicate_links(links) - end - - def have_required_elements? - super and have_author? - end - - def maker_target(maker) - maker.channel - end - - def setup_maker_element(channel) - prev_dc_dates = channel.dc_dates.to_a.dup - super - channel.about = id.content if id - channel.dc_dates.replace(prev_dc_dates) - end - - def setup_maker_elements(channel) - super - items = channel.maker.items - entries.each do |entry| - entry.setup_maker(items) - end - end - - class Author < RSS::Element - include CommonModel - include PersonConstruct - end - - class Category < RSS::Element - include CommonModel - - [ - ["term", "", true], - ["scheme", "", false, [nil, :uri]], - ["label", ""], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - private - def maker_target(target) - target.new_category - end - end - - class Contributor < RSS::Element - include CommonModel - include PersonConstruct - end - - class Generator < RSS::Element - include CommonModel - include ContentModel - - [ - ["uri", "", false, [nil, :uri]], - ["version", ""], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - private - def setup_maker_attributes(target) - target.generator do |generator| - generator.uri = uri if uri - generator.version = version if version - end - end - end - - class Icon < RSS::Element - include CommonModel - include URIContentModel - end - - class Id < RSS::Element - include CommonModel - include URIContentModel - end - - class Link < RSS::Element - include CommonModel - - [ - ["href", "", true, [nil, :uri]], - ["rel", ""], - ["type", ""], - ["hreflang", ""], - ["title", ""], - ["length", ""], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - private - def maker_target(target) - target.new_link - end - end - - class Logo < RSS::Element - include CommonModel - include URIContentModel - - def maker_target(target) - target.maker.image - end - - private - def setup_maker_element_writer - "url=" - end - end - - class Rights < RSS::Element - include CommonModel - include TextConstruct - end - - class Subtitle < RSS::Element - include CommonModel - include TextConstruct - end - - class Title < RSS::Element - include CommonModel - include TextConstruct - end - - class Updated < RSS::Element - include CommonModel - include DateConstruct - end - - class Entry < RSS::Element - include CommonModel - include DuplicateLinkChecker - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["content", "?", :child], - ["contributor", "*", :children], - ["id", nil, nil, :content], - ["link", "*", :children], - ["published", "?", :child, :content], - ["rights", "?", :child], - ["source", "?"], - ["summary", "?", :child], - ["title", nil], - ["updated", nil, :child, :content], - ].each do |tag, occurs, type, *args| - type ||= :attribute - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - def have_author?(check_parent=true) - authors.any? {|author| !author.to_s.empty?} or - (check_parent and @parent and @parent.have_author?) or - (source and source.have_author?) - end - - private - def atom_validate(ignore_unknown_element, tags, uri) - unless have_author? - raise MissingTagError.new("author", tag_name) - end - validate_duplicate_links(links) - end - - def have_required_elements? - super and have_author? - end - - def maker_target(items) - if items.respond_to?("items") - # For backward compatibility - items = items.items - end - items.new_item - end - - Author = Feed::Author - Category = Feed::Category - - class Content < RSS::Element - include CommonModel - - class << self - def xml_setter - "xml=" - end - - def xml_getter - "xml" - end - end - - [ - ["type", ""], - ["src", "", false, [nil, :uri]], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - content_setup - add_need_initialize_variable("xml") - - attr_writer :xml - def have_xml_content? - inline_xhtml? or inline_other_xml? - end - - def xml - return @xml unless inline_xhtml? - return @xml if @xml.nil? - if @xml.is_a?(XML::Element) and - [@xml.name, @xml.uri] == ["div", XHTML_URI] - return @xml - end - - children = @xml - children = [children] unless children.is_a?(Array) - XML::Element.new("div", nil, XHTML_URI, - {"xmlns" => XHTML_URI}, children) - end - - def xhtml - if inline_xhtml? - xml - else - nil - end - end - - def atom_validate(ignore_unknown_element, tags, uri) - if out_of_line? - raise MissingAttributeError.new(tag_name, "type") if @type.nil? - unless (content.nil? or content.empty?) - raise NotAvailableValueError.new(tag_name, content) - end - elsif inline_xhtml? - if @xml.nil? - raise MissingTagError.new("div", tag_name) - end - unless @xml.name == "div" and @xml.uri == XHTML_URI - raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name) - end - end - end - - def inline_text? - !out_of_line? and [nil, "text", "html"].include?(@type) - end - - def inline_html? - return false if out_of_line? - @type == "html" or mime_split == ["text", "html"] - end - - def inline_xhtml? - !out_of_line? and @type == "xhtml" - end - - def inline_other? - return false if out_of_line? - media_type, subtype = mime_split - return false if media_type.nil? or subtype.nil? - true - end - - def inline_other_text? - return false unless inline_other? - return false if inline_other_xml? - - media_type, subtype = mime_split - return true if "text" == media_type.downcase - false - end - - def inline_other_xml? - return false unless inline_other? - - media_type, subtype = mime_split - normalized_mime_type = "#{media_type}/#{subtype}".downcase - if /(?:\+xml|^xml)$/ =~ subtype or - %w(text/xml-external-parsed-entity - application/xml-external-parsed-entity - application/xml-dtd).find {|x| x == normalized_mime_type} - return true - end - false - end - - def inline_other_base64? - inline_other? and !inline_other_text? and !inline_other_xml? - end - - def out_of_line? - not @src.nil? - end - - def mime_split - media_type = subtype = nil - if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/i =~ @type.to_s - media_type = $1.downcase - subtype = $2.downcase - end - [media_type, subtype] - end - - def need_base64_encode? - inline_other_base64? - end - - private - def empty_content? - out_of_line? or super - end - end - - Contributor = Feed::Contributor - Id = Feed::Id - Link = Feed::Link - - class Published < RSS::Element - include CommonModel - include DateConstruct - end - - Rights = Feed::Rights - - class Source < RSS::Element - include CommonModel - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["contributor", "*", :children], - ["generator", "?"], - ["icon", "?"], - ["id", "?", nil, :content], - ["link", "*", :children], - ["logo", "?"], - ["rights", "?"], - ["subtitle", "?"], - ["title", "?"], - ["updated", "?", nil, :content], - ].each do |tag, occurs, type, *args| - type ||= :attribute - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - def have_author? - !author.to_s.empty? - end - - Author = Feed::Author - Category = Feed::Category - Contributor = Feed::Contributor - Generator = Feed::Generator - Icon = Feed::Icon - Id = Feed::Id - Link = Feed::Link - Logo = Feed::Logo - Rights = Feed::Rights - Subtitle = Feed::Subtitle - Title = Feed::Title - Updated = Feed::Updated - end - - class Summary < RSS::Element - include CommonModel - include TextConstruct - end - - Title = Feed::Title - Updated = Feed::Updated - end - end - - class Entry < RSS::Element - include RootElementMixin - include CommonModel - include DuplicateLinkChecker - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["content", "?"], - ["contributor", "*", :children], - ["id", nil, nil, :content], - ["link", "*", :children], - ["published", "?", :child, :content], - ["rights", "?"], - ["source", "?"], - ["summary", "?"], - ["title", nil], - ["updated", nil, nil, :content], - ].each do |tag, occurs, type, *args| - type ||= :attribute - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - def initialize(version=nil, encoding=nil, standalone=nil) - super("1.0", version, encoding, standalone) - @feed_type = "atom" - @feed_subtype = "entry" - end - - def items - [self] - end - - def setup_maker(maker) - maker = maker.maker if maker.respond_to?("maker") - super(maker) - end - - def have_author? - authors.any? {|author| !author.to_s.empty?} or - (source and source.have_author?) - end - - private - def atom_validate(ignore_unknown_element, tags, uri) - unless have_author? - raise MissingTagError.new("author", tag_name) - end - validate_duplicate_links(links) - end - - def have_required_elements? - super and have_author? - end - - def maker_target(maker) - maker.items.new_item - end - - Author = Feed::Entry::Author - Category = Feed::Entry::Category - Content = Feed::Entry::Content - Contributor = Feed::Entry::Contributor - Id = Feed::Entry::Id - Link = Feed::Entry::Link - Published = Feed::Entry::Published - Rights = Feed::Entry::Rights - Source = Feed::Entry::Source - Summary = Feed::Entry::Summary - Title = Feed::Entry::Title - Updated = Feed::Entry::Updated - end - end - - Atom::CommonModel::ELEMENTS.each do |name| - BaseListener.install_get_text_element(Atom::URI, name, "#{name}=") - end - - module ListenerMixin - private - def initial_start_feed(tag_name, prefix, attrs, ns) - check_ns(tag_name, prefix, ns, Atom::URI) - - @rss = Atom::Feed.new(@version, @encoding, @standalone) - @rss.do_validate = @do_validate - @rss.xml_stylesheets = @xml_stylesheets - @rss.lang = attrs["xml:lang"] - @rss.base = attrs["xml:base"] - @last_element = @rss - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags) if @do_validate - end - @proc_stack.push(pr) - end - - def initial_start_entry(tag_name, prefix, attrs, ns) - check_ns(tag_name, prefix, ns, Atom::URI) - - @rss = Atom::Entry.new(@version, @encoding, @standalone) - @rss.do_validate = @do_validate - @rss.xml_stylesheets = @xml_stylesheets - @rss.lang = attrs["xml:lang"] - @rss.base = attrs["xml:base"] - @last_element = @rss - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags) if @do_validate - end - @proc_stack.push(pr) - end - end -end diff --git a/trunk/lib/rss/content.rb b/trunk/lib/rss/content.rb deleted file mode 100644 index b12ee918aa..0000000000 --- a/trunk/lib/rss/content.rb +++ /dev/null @@ -1,31 +0,0 @@ -require "rss/rss" - -module RSS - CONTENT_PREFIX = 'content' - CONTENT_URI = "http://purl.org/rss/1.0/modules/content/" - - module ContentModel - extend BaseModel - - ELEMENTS = ["#{CONTENT_PREFIX}_encoded"] - - def self.append_features(klass) - super - - klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI) - ELEMENTS.each do |full_name| - name = full_name[(CONTENT_PREFIX.size + 1)..-1] - klass.install_text_element(name, CONTENT_URI, "?", full_name) - end - end - end - - prefix_size = CONTENT_PREFIX.size + 1 - ContentModel::ELEMENTS.each do |full_name| - name = full_name[prefix_size..-1] - BaseListener.install_get_text_element(CONTENT_URI, name, full_name) - end -end - -require 'rss/content/1.0' -require 'rss/content/2.0' diff --git a/trunk/lib/rss/content/1.0.rb b/trunk/lib/rss/content/1.0.rb deleted file mode 100644 index e7c0c19685..0000000000 --- a/trunk/lib/rss/content/1.0.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'rss/1.0' -require 'rss/content' - -module RSS - RDF.install_ns(CONTENT_PREFIX, CONTENT_URI) - - class RDF - class Item; include ContentModel; end - end -end diff --git a/trunk/lib/rss/content/2.0.rb b/trunk/lib/rss/content/2.0.rb deleted file mode 100644 index 8671b5b1a6..0000000000 --- a/trunk/lib/rss/content/2.0.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "rss/2.0" -require "rss/content" - -module RSS - Rss.install_ns(CONTENT_PREFIX, CONTENT_URI) - - class Rss - class Channel - class Item; include ContentModel; end - end - end -end diff --git a/trunk/lib/rss/converter.rb b/trunk/lib/rss/converter.rb deleted file mode 100644 index 415a319188..0000000000 --- a/trunk/lib/rss/converter.rb +++ /dev/null @@ -1,162 +0,0 @@ -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' - if NKF.const_defined?(:UTF8) - def_convert(1) do |value| - "NKF.nkf(#{nkf_arg.dump}, #{value})" - end - else - def_iconv_convert(to_enc, from_enc, 1) - 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/trunk/lib/rss/dublincore.rb b/trunk/lib/rss/dublincore.rb deleted file mode 100644 index 7ba239f8f1..0000000000 --- a/trunk/lib/rss/dublincore.rb +++ /dev/null @@ -1,161 +0,0 @@ -require "rss/rss" - -module RSS - DC_PREFIX = 'dc' - DC_URI = "http://purl.org/dc/elements/1.1/" - - 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)) - if method_defined?(:date) - alias date_without_#{DC_PREFIX}_date= date= - - def date=(value) - self.date_without_#{DC_PREFIX}_date = value - self.#{DC_PREFIX}_date = value - end - else - alias date #{DC_PREFIX}_date - alias date= #{DC_PREFIX}_date= - end - - # For backward compatibility - alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list - 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" => "rights_list" - } - - 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| - tag_name = "#{DC_PREFIX}:#{name}" - 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}, #{tag_name.dump}) - - alias_method(:value=, :content=) - end - EOC - end - end - - # For backward compatibility - DublincoreModel = DublinCoreModel - - 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 - -require 'rss/dublincore/1.0' -require 'rss/dublincore/2.0' -require 'rss/dublincore/atom' diff --git a/trunk/lib/rss/dublincore/1.0.rb b/trunk/lib/rss/dublincore/1.0.rb deleted file mode 100644 index e193c6d2c2..0000000000 --- a/trunk/lib/rss/dublincore/1.0.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "rss/1.0" -require "rss/dublincore" - -module RSS - RDF.install_ns(DC_PREFIX, DC_URI) - - class RDF - class Channel; include DublinCoreModel; end - class Image; include DublinCoreModel; end - class Item; include DublinCoreModel; end - class Textinput; include DublinCoreModel; end - end -end diff --git a/trunk/lib/rss/dublincore/2.0.rb b/trunk/lib/rss/dublincore/2.0.rb deleted file mode 100644 index 82ed1888c5..0000000000 --- a/trunk/lib/rss/dublincore/2.0.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "rss/2.0" -require "rss/dublincore" - -module RSS - Rss.install_ns(DC_PREFIX, DC_URI) - - class Rss - class Channel - include DublinCoreModel - class Item; include DublinCoreModel; end - end - end -end diff --git a/trunk/lib/rss/dublincore/atom.rb b/trunk/lib/rss/dublincore/atom.rb deleted file mode 100644 index e78df4821b..0000000000 --- a/trunk/lib/rss/dublincore/atom.rb +++ /dev/null @@ -1,17 +0,0 @@ -require "rss/atom" -require "rss/dublincore" - -module RSS - module Atom - Feed.install_ns(DC_PREFIX, DC_URI) - - class Feed - include DublinCoreModel - class Entry; include DublinCoreModel; end - end - - class Entry - include DublinCoreModel - end - end -end diff --git a/trunk/lib/rss/image.rb b/trunk/lib/rss/image.rb deleted file mode 100644 index c4714aea12..0000000000 --- a/trunk/lib/rss/image.rb +++ /dev/null @@ -1,193 +0,0 @@ -require 'rss/1.0' -require 'rss/dublincore' - -module RSS - - IMAGE_PREFIX = 'image' - IMAGE_URI = 'http://purl.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 :set_size, :size= - private :set_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 - set_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/trunk/lib/rss/itunes.rb b/trunk/lib/rss/itunes.rb deleted file mode 100644 index f95ca7aa2e..0000000000 --- a/trunk/lib/rss/itunes.rb +++ /dev/null @@ -1,410 +0,0 @@ -require 'rss/2.0' - -module RSS - ITUNES_PREFIX = 'itunes' - ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd' - - Rss.install_ns(ITUNES_PREFIX, ITUNES_URI) - - module ITunesModelUtils - include Utils - - def def_class_accessor(klass, name, type, *args) - normalized_name = name.gsub(/-/, "_") - full_name = "#{ITUNES_PREFIX}_#{normalized_name}" - klass_name = "ITunes#{Utils.to_class_name(normalized_name)}" - - case type - when :element, :attribute - klass::ELEMENTS << full_name - def_element_class_accessor(klass, name, full_name, klass_name, *args) - when :elements - klass::ELEMENTS << full_name - def_elements_class_accessor(klass, name, full_name, klass_name, *args) - else - klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI) - klass.install_text_element(normalized_name, ITUNES_URI, "?", - full_name, type, name) - end - end - - def def_element_class_accessor(klass, name, full_name, klass_name, - recommended_attribute_name=nil) - klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name) - end - - def def_elements_class_accessor(klass, name, full_name, klass_name, - plural_name, recommended_attribute_name=nil) - full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}" - klass.install_have_children_element(name, ITUNES_PREFIX, "*", - full_name, full_plural_name) - end - end - - module ITunesBaseModel - extend ITunesModelUtils - - ELEMENTS = [] - - ELEMENT_INFOS = [["author"], - ["block", :yes_other], - ["explicit", :yes_clean_other], - ["keywords", :csv], - ["subtitle"], - ["summary"]] - end - - module ITunesChannelModel - extend BaseModel - extend ITunesModelUtils - include ITunesBaseModel - - ELEMENTS = [] - - class << self - def append_features(klass) - super - - return if klass.instance_of?(Module) - ELEMENT_INFOS.each do |name, type, *additional_infos| - def_class_accessor(klass, name, type, *additional_infos) - end - end - end - - ELEMENT_INFOS = [ - ["category", :elements, "categories", "text"], - ["image", :attribute, "href"], - ["owner", :element], - ["new-feed-url"], - ] + ITunesBaseModel::ELEMENT_INFOS - - class ITunesCategory < Element - include RSS09 - - @tag_name = "category" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - end - - [ - ["text", "", true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required) - end - - ITunesCategory = self - install_have_children_element("category", ITUNES_URI, "*", - "#{ITUNES_PREFIX}_category", - "#{ITUNES_PREFIX}_categories") - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.text = args[0] - end - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def maker_target(categories) - if text or !itunes_categories.empty? - categories.new_category - else - nil - end - end - - def setup_maker_attributes(category) - category.text = text if text - end - - def setup_maker_elements(category) - super(category) - itunes_categories.each do |sub_category| - sub_category.setup_maker(category) - end - end - end - - class ITunesImage < Element - include RSS09 - - @tag_name = "image" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - end - - [ - ["href", "", 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.href = args[0] - end - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def maker_target(target) - if href - target.itunes_image {|image| image} - else - nil - end - end - - def setup_maker_attributes(image) - image.href = href - end - end - - class ITunesOwner < Element - include RSS09 - - @tag_name = "owner" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - end - - install_must_call_validator(ITUNES_PREFIX, ITUNES_URI) - [ - ["name"], - ["email"], - ].each do |name,| - ITunesBaseModel::ELEMENT_INFOS << name - install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}") - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.itunes_name = args[0] - self.itunes_email = args[1] - end - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def maker_target(target) - target.itunes_owner - end - - def setup_maker_element(owner) - super(owner) - owner.itunes_name = itunes_name - owner.itunes_email = itunes_email - end - end - end - - module ITunesItemModel - extend BaseModel - extend ITunesModelUtils - include ITunesBaseModel - - class << self - def append_features(klass) - super - - return if klass.instance_of?(Module) - ELEMENT_INFOS.each do |name, type| - def_class_accessor(klass, name, type) - end - end - end - - ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS + - [["duration", :element, "content"]] - - class ITunesDuration < Element - include RSS09 - - @tag_name = "duration" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - - def parse(duration, do_validate=true) - if do_validate and /\A(?: - \d?\d:[0-5]\d:[0-5]\d| - [0-5]?\d:[0-5]\d - )\z/x !~ duration - raise ArgumentError, - "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " + - duration.inspect - end - - components = duration.split(':') - components[3..-1] = nil if components.size > 3 - - components.unshift("00") until components.size == 3 - - components.collect do |component| - component.to_i - end - end - - def construct(hour, minute, second) - components = [minute, second] - if components.include?(nil) - nil - else - components.unshift(hour) if hour and hour > 0 - components.collect do |component| - "%02d" % component - end.join(":") - end - end - end - - content_setup - alias_method(:value, :content) - remove_method(:content=) - - attr_reader :hour, :minute, :second - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - args = args[0] if args.size == 1 and args[0].is_a?(Array) - if args.size == 1 - self.content = args[0] - elsif args.size > 3 - raise ArgumentError, - "must be (do_validate, params), (content), " + - "(minute, second), ([minute, second]), " + - "(hour, minute, second) or ([hour, minute, second]): " + - args.inspect - else - @second, @minute, @hour = args.reverse - update_content - end - end - end - - def content=(value) - if value.nil? - @content = nil - elsif value.is_a?(self.class) - self.content = value.content - else - begin - @hour, @minute, @second = self.class.parse(value, @do_validate) - rescue ArgumentError - raise NotAvailableValueError.new(tag_name, value) - end - @content = value - end - end - alias_method(:value=, :content=) - - def hour=(hour) - @hour = @do_validate ? Integer(hour) : hour.to_i - update_content - hour - end - - def minute=(minute) - @minute = @do_validate ? Integer(minute) : minute.to_i - update_content - minute - end - - def second=(second) - @second = @do_validate ? Integer(second) : second.to_i - update_content - second - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def update_content - @content = self.class.construct(hour, minute, second) - end - - def maker_target(target) - if @content - target.itunes_duration {|duration| duration} - else - nil - end - end - - def setup_maker_element(duration) - super(duration) - duration.content = @content - end - end - end - - class Rss - class Channel - include ITunesChannelModel - class Item; include ITunesItemModel; end - end - end - - element_infos = - ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS - element_infos.each do |name, type| - case type - when :element, :elements, :attribute - class_name = Utils.to_class_name(name) - BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}") - else - accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}" - BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base) - end - end -end diff --git a/trunk/lib/rss/maker.rb b/trunk/lib/rss/maker.rb deleted file mode 100644 index bcba1aaff3..0000000000 --- a/trunk/lib/rss/maker.rb +++ /dev/null @@ -1,44 +0,0 @@ -require "rss/rss" - -module RSS - module Maker - MAKERS = {} - - class << self - def make(version, &block) - m = maker(version) - raise UnsupportedMakerVersionError.new(version) if m.nil? - m[:maker].make(m[:version], &block) - end - - def maker(version) - MAKERS[version] - end - - def add_maker(version, normalized_version, maker) - MAKERS[version] = {:maker => maker, :version => normalized_version} - end - - def versions - MAKERS.keys.uniq.sort - end - - def makers - MAKERS.values.collect {|info| info[:maker]}.uniq - end - end - end -end - -require "rss/maker/1.0" -require "rss/maker/2.0" -require "rss/maker/feed" -require "rss/maker/entry" -require "rss/maker/content" -require "rss/maker/dublincore" -require "rss/maker/slash" -require "rss/maker/syndication" -require "rss/maker/taxonomy" -require "rss/maker/trackback" -require "rss/maker/image" -require "rss/maker/itunes" diff --git a/trunk/lib/rss/maker/0.9.rb b/trunk/lib/rss/maker/0.9.rb deleted file mode 100644 index 72b14dc977..0000000000 --- a/trunk/lib/rss/maker/0.9.rb +++ /dev/null @@ -1,467 +0,0 @@ -require "rss/0.9" - -require "rss/maker/base" - -module RSS - module Maker - - class RSS09 < RSSBase - - def initialize(feed_version="0.92") - super - @feed_type = "rss" - end - - private - def make_feed - Rss.new(@feed_version, @version, @encoding, @standalone) - end - - def setup_elements(rss) - setup_channel(rss) - end - - class Channel < ChannelBase - def to_feed(rss) - channel = Rss::Channel.new - set = setup_values(channel) - _not_set_required_variables = not_set_required_variables - if _not_set_required_variables.empty? - rss.channel = channel - set_parent(channel, rss) - setup_items(rss) - setup_image(rss) - setup_textinput(rss) - setup_other_elements(rss, channel) - rss - else - raise NotSetError.new("maker.channel", _not_set_required_variables) - end - end - - private - def setup_items(rss) - @maker.items.to_feed(rss) - end - - def setup_image(rss) - @maker.image.to_feed(rss) - end - - def setup_textinput(rss) - @maker.textinput.to_feed(rss) - end - - def variables - super + ["pubDate"] - end - - def required_variable_names - %w(link language) - end - - def not_set_required_variables - vars = super - vars << "description" unless description {|d| d.have_required_values?} - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - class SkipDays < SkipDaysBase - def to_feed(rss, channel) - unless @days.empty? - skipDays = Rss::Channel::SkipDays.new - channel.skipDays = skipDays - set_parent(skipDays, channel) - @days.each do |day| - day.to_feed(rss, skipDays.days) - end - end - end - - class Day < DayBase - def to_feed(rss, days) - day = Rss::Channel::SkipDays::Day.new - set = setup_values(day) - if set - days << day - set_parent(day, days) - setup_other_elements(rss, day) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class SkipHours < SkipHoursBase - def to_feed(rss, channel) - unless @hours.empty? - skipHours = Rss::Channel::SkipHours.new - channel.skipHours = skipHours - set_parent(skipHours, channel) - @hours.each do |hour| - hour.to_feed(rss, skipHours.hours) - end - end - end - - class Hour < HourBase - def to_feed(rss, hours) - hour = Rss::Channel::SkipHours::Hour.new - set = setup_values(hour) - if set - hours << hour - set_parent(hour, hours) - setup_other_elements(rss, hour) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class Cloud < CloudBase - def to_feed(*args) - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Links < LinksBase - def to_feed(rss, channel) - return if @links.empty? - @links.first.to_feed(rss, channel) - end - - class Link < LinkBase - def to_feed(rss, channel) - if have_required_values? - channel.link = href - else - raise NotSetError.new("maker.channel.link", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - end - - class Authors < AuthorsBase - def to_feed(rss, channel) - end - - class Author < AuthorBase - def to_feed(rss, channel) - end - end - end - - class Contributors < ContributorsBase - def to_feed(rss, channel) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(rss, channel) - end - end - - class Copyright < CopyrightBase - def to_feed(rss, channel) - channel.copyright = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Description < DescriptionBase - def to_feed(rss, channel) - channel.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Title < TitleBase - def to_feed(rss, channel) - channel.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - - class Image < ImageBase - def to_feed(rss) - image = Rss::Channel::Image.new - set = setup_values(image) - if set - image.link = link - rss.channel.image = image - set_parent(image, rss.channel) - setup_other_elements(rss, image) - elsif required_element? - raise NotSetError.new("maker.image", not_set_required_variables) - end - end - - private - def required_variable_names - %w(url title link) - end - - def required_element? - true - end - end - - class Items < ItemsBase - def to_feed(rss) - if rss.channel - normalize.each do |item| - item.to_feed(rss) - end - setup_other_elements(rss, rss.items) - end - end - - class Item < ItemBase - def to_feed(rss) - item = Rss::Channel::Item.new - set = setup_values(item) - _not_set_required_variables = not_set_required_variables - if _not_set_required_variables.empty? - rss.items << item - set_parent(item, rss.channel) - setup_other_elements(rss, item) - elsif variable_is_set? - raise NotSetError.new("maker.items", _not_set_required_variables) - end - end - - private - def required_variable_names - [] - end - - def not_set_required_variables - vars = super - if @maker.feed_version == "0.91" - vars << "title" unless title {|t| t.have_required_values?} - vars << "link" unless link {|l| l.have_required_values?} - end - vars - end - - class Guid < GuidBase - def to_feed(*args) - end - end - - class Enclosure < EnclosureBase - def to_feed(*args) - end - end - - class Source < SourceBase - def to_feed(*args) - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Contributors < ContributorsBase - def to_feed(*args) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(*args) - end - end - - class Icon < IconBase - def to_feed(*args) - end - end - - class Links < LinksBase - def to_feed(*args) - end - - class Link < LinkBase - end - end - - class Logo < LogoBase - def to_feed(*args) - end - end - - class Rights < RightsBase - def to_feed(*args) - end - end - - class Subtitle < SubtitleBase - def to_feed(*args) - end - end - - class Title < TitleBase - def to_feed(*args) - end - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Links < LinksBase - def to_feed(rss, item) - return if @links.empty? - @links.first.to_feed(rss, item) - end - - class Link < LinkBase - def to_feed(rss, item) - if have_required_values? - item.link = href - else - raise NotSetError.new("maker.link", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - end - - class Contributors < ContributorsBase - def to_feed(rss, item) - end - - class Contributor < ContributorBase - end - end - - class Rights < RightsBase - def to_feed(rss, item) - end - end - - class Description < DescriptionBase - def to_feed(rss, item) - item.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Content < ContentBase - def to_feed(rss, item) - end - end - - class Title < TitleBase - def to_feed(rss, item) - item.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - end - - class Textinput < TextinputBase - def to_feed(rss) - textInput = Rss::Channel::TextInput.new - set = setup_values(textInput) - if set - rss.channel.textInput = textInput - set_parent(textInput, rss.channel) - setup_other_elements(rss, textInput) - end - end - - private - def required_variable_names - %w(title description name link) - end - end - end - - add_maker("0.9", "0.92", RSS09) - add_maker("0.91", "0.91", RSS09) - add_maker("0.92", "0.92", RSS09) - add_maker("rss0.91", "0.91", RSS09) - add_maker("rss0.92", "0.92", RSS09) - end -end diff --git a/trunk/lib/rss/maker/1.0.rb b/trunk/lib/rss/maker/1.0.rb deleted file mode 100644 index a1e2594f70..0000000000 --- a/trunk/lib/rss/maker/1.0.rb +++ /dev/null @@ -1,434 +0,0 @@ -require "rss/1.0" - -require "rss/maker/base" - -module RSS - module Maker - - class RSS10 < RSSBase - - def initialize(feed_version="1.0") - super - @feed_type = "rss" - end - - private - def make_feed - 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_feed(rss) - set_default_values do - _not_set_required_variables = not_set_required_variables - if _not_set_required_variables.empty? - channel = RDF::Channel.new(@about) - set = setup_values(channel) - channel.dc_dates.clear - rss.channel = channel - set_parent(channel, rss) - setup_items(rss) - setup_image(rss) - setup_textinput(rss) - setup_other_elements(rss, channel) - else - raise NotSetError.new("maker.channel", _not_set_required_variables) - end - end - end - - private - def setup_items(rss) - items = RDF::Channel::Items.new - seq = items.Seq - set_parent(items, seq) - target_items = @maker.items.normalize - raise NotSetError.new("maker", ["items"]) if target_items.empty? - target_items.each do |item| - li = RDF::Channel::Items::Seq::Li.new(item.link) - seq.lis << li - set_parent(li, seq) - end - rss.channel.items = items - set_parent(rss.channel, items) - end - - def setup_image(rss) - if @maker.image.have_required_values? - image = RDF::Channel::Image.new(@maker.image.url) - rss.channel.image = image - set_parent(image, rss.channel) - end - end - - def setup_textinput(rss) - if @maker.textinput.have_required_values? - textinput = RDF::Channel::Textinput.new(@maker.textinput.link) - rss.channel.textinput = textinput - set_parent(textinput, rss.channel) - end - end - - def required_variable_names - %w(about link) - end - - def not_set_required_variables - vars = super - vars << "description" unless description {|d| d.have_required_values?} - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - class SkipDays < SkipDaysBase - def to_feed(*args) - end - - class Day < DayBase - end - end - - class SkipHours < SkipHoursBase - def to_feed(*args) - end - - class Hour < HourBase - end - end - - class Cloud < CloudBase - def to_feed(*args) - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Links < LinksBase - def to_feed(rss, channel) - return if @links.empty? - @links.first.to_feed(rss, channel) - end - - class Link < LinkBase - def to_feed(rss, channel) - if have_required_values? - channel.link = href - else - raise NotSetError.new("maker.channel.link", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - end - - class Authors < AuthorsBase - def to_feed(rss, channel) - end - - class Author < AuthorBase - def to_feed(rss, channel) - end - end - end - - class Contributors < ContributorsBase - def to_feed(rss, channel) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(rss, channel) - end - end - - class Copyright < CopyrightBase - def to_feed(rss, channel) - end - end - - class Description < DescriptionBase - def to_feed(rss, channel) - channel.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Title < TitleBase - def to_feed(rss, channel) - channel.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - - class Image < ImageBase - def to_feed(rss) - if @url - image = RDF::Image.new(@url) - set = setup_values(image) - if set - rss.image = image - set_parent(image, rss) - setup_other_elements(rss, image) - end - end - end - - def have_required_values? - super and @maker.channel.have_required_values? - end - - private - def variables - super + ["link"] - end - - def required_variable_names - %w(url title link) - end - end - - class Items < ItemsBase - def to_feed(rss) - if rss.channel - normalize.each do |item| - item.to_feed(rss) - end - setup_other_elements(rss, rss.items) - end - end - - class Item < ItemBase - def to_feed(rss) - set_default_values do - item = RDF::Item.new(link) - set = setup_values(item) - if set - item.dc_dates.clear - rss.items << item - set_parent(item, rss) - setup_other_elements(rss, item) - elsif !have_required_values? - raise NotSetError.new("maker.item", not_set_required_variables) - end - end - end - - private - def required_variable_names - %w(link) - end - - def variables - super + %w(link) - end - - def not_set_required_variables - set_default_values do - vars = super - vars << "title" unless title {|t| t.have_required_values?} - vars - end - end - - class Guid < GuidBase - def to_feed(*args) - end - end - - class Enclosure < EnclosureBase - def to_feed(*args) - end - end - - class Source < SourceBase - def to_feed(*args) - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Contributors < ContributorsBase - def to_feed(*args) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(*args) - end - end - - class Icon < IconBase - def to_feed(*args) - end - end - - class Links < LinksBase - def to_feed(*args) - end - - class Link < LinkBase - end - end - - class Logo < LogoBase - def to_feed(*args) - end - end - - class Rights < RightsBase - def to_feed(*args) - end - end - - class Subtitle < SubtitleBase - def to_feed(*args) - end - end - - class Title < TitleBase - def to_feed(*args) - end - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Links < LinksBase - def to_feed(*args) - end - - class Link < LinkBase - end - end - - class Contributors < ContributorsBase - def to_feed(rss, item) - end - - class Contributor < ContributorBase - end - end - - class Rights < RightsBase - def to_feed(rss, item) - end - end - - class Description < DescriptionBase - def to_feed(rss, item) - item.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Content < ContentBase - def to_feed(rss, item) - end - end - - class Title < TitleBase - def to_feed(rss, item) - item.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - end - - class Textinput < TextinputBase - def to_feed(rss) - if @link - textinput = RDF::Textinput.new(@link) - set = setup_values(textinput) - if set - rss.textinput = textinput - set_parent(textinput, rss) - setup_other_elements(rss, textinput) - end - end - end - - def have_required_values? - super and @maker.channel.have_required_values? - end - - private - def required_variable_names - %w(title description name link) - end - end - end - - add_maker("1.0", "1.0", RSS10) - add_maker("rss1.0", "1.0", RSS10) - end -end diff --git a/trunk/lib/rss/maker/2.0.rb b/trunk/lib/rss/maker/2.0.rb deleted file mode 100644 index 67d68126ac..0000000000 --- a/trunk/lib/rss/maker/2.0.rb +++ /dev/null @@ -1,223 +0,0 @@ -require "rss/2.0" - -require "rss/maker/0.9" - -module RSS - module Maker - - class RSS20 < RSS09 - - def initialize(feed_version="2.0") - super - end - - class Channel < RSS09::Channel - - private - def required_variable_names - %w(link) - 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_feed(rss, channel) - cloud = Rss::Channel::Cloud.new - set = setup_values(cloud) - if set - channel.cloud = cloud - set_parent(cloud, channel) - setup_other_elements(rss, cloud) - end - end - - private - def required_variable_names - %w(domain port path registerProcedure protocol) - end - end - - class Categories < RSS09::Channel::Categories - def to_feed(rss, channel) - @categories.each do |category| - category.to_feed(rss, channel) - end - end - - class Category < RSS09::Channel::Categories::Category - def to_feed(rss, channel) - category = Rss::Channel::Category.new - set = setup_values(category) - if set - channel.categories << category - set_parent(category, channel) - setup_other_elements(rss, category) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class Generator < GeneratorBase - def to_feed(rss, channel) - channel.generator = content - end - - private - def required_variable_names - %w(content) - end - end - end - - class Image < RSS09::Image - private - def required_element? - false - end - end - - class Items < RSS09::Items - class Item < RSS09::Items::Item - private - def required_variable_names - [] - end - - def not_set_required_variables - vars = super - if !title {|t| t.have_required_values?} and - !description {|d| d.have_required_values?} - vars << "title or description" - end - vars - end - - def variables - super + ["pubDate"] - end - - class Guid < RSS09::Items::Item::Guid - def to_feed(rss, item) - guid = Rss::Channel::Item::Guid.new - set = setup_values(guid) - if set - item.guid = guid - set_parent(guid, item) - setup_other_elements(rss, guid) - end - end - - private - def required_variable_names - %w(content) - end - end - - class Enclosure < RSS09::Items::Item::Enclosure - def to_feed(rss, item) - enclosure = Rss::Channel::Item::Enclosure.new - set = setup_values(enclosure) - if set - item.enclosure = enclosure - set_parent(enclosure, item) - setup_other_elements(rss, enclosure) - end - end - - private - def required_variable_names - %w(url length type) - end - end - - class Source < RSS09::Items::Item::Source - def to_feed(rss, item) - source = Rss::Channel::Item::Source.new - set = setup_values(source) - if set - item.source = source - set_parent(source, item) - setup_other_elements(rss, source) - end - end - - private - def required_variable_names - %w(url content) - end - - class Links < RSS09::Items::Item::Source::Links - def to_feed(rss, source) - return if @links.empty? - @links.first.to_feed(rss, source) - end - - class Link < RSS09::Items::Item::Source::Links::Link - def to_feed(rss, source) - source.url = href - end - end - end - end - - class Categories < RSS09::Items::Item::Categories - def to_feed(rss, item) - @categories.each do |category| - category.to_feed(rss, item) - end - end - - class Category < RSS09::Items::Item::Categories::Category - def to_feed(rss, item) - category = Rss::Channel::Item::Category.new - set = setup_values(category) - if set - item.categories << category - set_parent(category, item) - setup_other_elements(rss) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class Authors < RSS09::Items::Item::Authors - def to_feed(rss, item) - return if @authors.empty? - @authors.first.to_feed(rss, item) - end - - class Author < RSS09::Items::Item::Authors::Author - def to_feed(rss, item) - item.author = name - end - end - end - end - end - - class Textinput < RSS09::Textinput - end - end - - add_maker("2.0", "2.0", RSS20) - add_maker("rss2.0", "2.0", RSS20) - end -end diff --git a/trunk/lib/rss/maker/atom.rb b/trunk/lib/rss/maker/atom.rb deleted file mode 100644 index fd3198cd9e..0000000000 --- a/trunk/lib/rss/maker/atom.rb +++ /dev/null @@ -1,172 +0,0 @@ -require "rss/atom" - -require "rss/maker/base" - -module RSS - module Maker - module AtomPersons - module_function - def def_atom_persons(klass, name, maker_name, plural=nil) - plural ||= "#{name}s" - klass_name = Utils.to_class_name(name) - plural_klass_name = Utils.to_class_name(plural) - - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{plural_klass_name} < #{plural_klass_name}Base - class #{klass_name} < #{klass_name}Base - def to_feed(feed, current) - #{name} = feed.class::#{klass_name}.new - set = setup_values(#{name}) - unless set - raise NotSetError.new(#{maker_name.dump}, - not_set_required_variables) - end - current.#{plural} << #{name} - set_parent(#{name}, current) - setup_other_elements(#{name}) - end - - private - def required_variable_names - %w(name) - end - end - end -EOC - end - end - - module AtomTextConstruct - class << self - def def_atom_text_construct(klass, name, maker_name, klass_name=nil, - atom_klass_name=nil) - klass_name ||= Utils.to_class_name(name) - atom_klass_name ||= Utils.to_class_name(name) - - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{klass_name} < #{klass_name}Base - include #{self.name} - def to_feed(feed, current) - #{name} = current.class::#{atom_klass_name}.new - if setup_values(#{name}) - current.#{name} = #{name} - set_parent(#{name}, current) - setup_other_elements(feed) - elsif variable_is_set? - raise NotSetError.new(#{maker_name.dump}, - not_set_required_variables) - end - end - end - EOC - end - end - - private - def required_variable_names - if type == "xhtml" - %w(xml_content) - else - %w(content) - end - end - - def variables - if type == "xhtml" - super + %w(xhtml) - else - super - end - end - end - - module AtomCategory - def to_feed(feed, current) - category = feed.class::Category.new - set = setup_values(category) - if set - current.categories << category - set_parent(category, current) - setup_other_elements(feed) - else - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(term) - end - - def variables - super + ["term", "scheme"] - end - end - - module AtomLink - def to_feed(feed, current) - link = feed.class::Link.new - set = setup_values(link) - if set - current.links << link - set_parent(link, current) - setup_other_elements(feed) - else - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - - module AtomGenerator - def to_feed(feed, current) - generator = current.class::Generator.new - if setup_values(generator) - current.generator = generator - set_parent(generator, current) - setup_other_elements(feed) - elsif variable_is_set? - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(content) - end - end - - module AtomLogo - def to_feed(feed, current) - logo = current.class::Logo.new - class << logo - alias_method(:uri=, :content=) - end - set = setup_values(logo) - class << logo - remove_method(:uri=) - end - if set - current.logo = logo - set_parent(logo, current) - setup_other_elements(feed) - elsif variable_is_set? - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(uri) - end - end - end -end diff --git a/trunk/lib/rss/maker/base.rb b/trunk/lib/rss/maker/base.rb deleted file mode 100644 index 2262a764ec..0000000000 --- a/trunk/lib/rss/maker/base.rb +++ /dev/null @@ -1,880 +0,0 @@ -require 'forwardable' - -require 'rss/rss' - -module RSS - module Maker - class Base - extend Utils::InheritedReader - - OTHER_ELEMENTS = [] - NEED_INITIALIZE_VARIABLES = [] - - class << self - def other_elements - inherited_array_reader("OTHER_ELEMENTS") - end - def need_initialize_variables - inherited_array_reader("NEED_INITIALIZE_VARIABLES") - end - - def inherited_base - ::RSS::Maker::Base - end - - def inherited(subclass) - subclass.const_set("OTHER_ELEMENTS", []) - subclass.const_set("NEED_INITIALIZE_VARIABLES", []) - end - - def add_other_element(variable_name) - self::OTHER_ELEMENTS << variable_name - end - - def add_need_initialize_variable(variable_name, init_value=nil, - &init_block) - init_value ||= init_block - self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value] - end - - def def_array_element(name, plural=nil, klass_name=nil) - include Enumerable - extend Forwardable - - plural ||= "#{name}s" - klass_name ||= Utils.to_class_name(name) - def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last) - def_delegators("@#{plural}", :push, :pop, :shift, :unshift) - def_delegators("@#{plural}", :each, :size, :empty?, :clear) - - add_need_initialize_variable(plural) {[]} - - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def new_#{name} - #{name} = self.class::#{klass_name}.new(@maker) - @#{plural} << #{name} - if block_given? - yield #{name} - else - #{name} - end - end - alias new_child new_#{name} - - def to_feed(*args) - @#{plural}.each do |#{name}| - #{name}.to_feed(*args) - end - end - - def replace(elements) - @#{plural}.replace(elements.to_a) - end - EOC - end - - def def_classed_element_without_accessor(name, class_name=nil) - class_name ||= Utils.to_class_name(name) - add_other_element(name) - add_need_initialize_variable(name) do |object| - object.send("make_#{name}") - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - private - def setup_#{name}(feed, current) - @#{name}.to_feed(feed, current) - end - - def make_#{name} - self.class::#{class_name}.new(@maker) - end - EOC - end - - def def_classed_element(name, class_name=nil, attribute_name=nil) - def_classed_element_without_accessor(name, class_name) - if attribute_name - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name} - if block_given? - yield(@#{name}) - else - @#{name}.#{attribute_name} - end - end - - def #{name}=(new_value) - @#{name}.#{attribute_name} = new_value - end - EOC - else - attr_reader name - end - end - - def def_classed_elements(name, attribute, plural_class_name=nil, - plural_name=nil, new_name=nil) - plural_name ||= "#{name}s" - new_name ||= name - def_classed_element(plural_name, plural_class_name) - local_variable_name = "_#{name}" - new_value_variable_name = "new_value" - additional_setup_code = nil - if block_given? - additional_setup_code = yield(local_variable_name, - new_value_variable_name) - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name} - #{local_variable_name} = #{plural_name}.first - #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil - end - - def #{name}=(#{new_value_variable_name}) - #{local_variable_name} = - #{plural_name}.first || #{plural_name}.new_#{new_name} - #{additional_setup_code} - #{local_variable_name}.#{attribute} = #{new_value_variable_name} - end - EOC - end - - def def_other_element(name) - attr_accessor name - def_other_element_without_accessor(name) - end - - def def_other_element_without_accessor(name) - add_need_initialize_variable(name) - add_other_element(name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def setup_#{name}(feed, current) - if !@#{name}.nil? and current.respond_to?(:#{name}=) - current.#{name} = @#{name} - end - end - EOC - end - - def def_csv_element(name, type=nil) - def_other_element_without_accessor(name) - attr_reader(name) - converter = "" - if type == :integer - converter = "{|v| Integer(v)}" - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(value) - @#{name} = Utils::CSV.parse(value)#{converter} - end - EOC - end - end - - attr_reader :maker - def initialize(maker) - @maker = maker - @default_values_are_set = false - initialize_variables - end - - def have_required_values? - not_set_required_variables.empty? - end - - def variable_is_set? - variables.any? {|var| not __send__(var).nil?} - end - - private - def initialize_variables - self.class.need_initialize_variables.each do |variable_name, init_value| - if init_value.nil? - value = nil - else - if init_value.respond_to?(:call) - value = init_value.call(self) - elsif init_value.is_a?(String) - # just for backward compatibility - value = instance_eval(init_value, __FILE__, __LINE__) - else - value = init_value - end - end - instance_variable_set("@#{variable_name}", value) - end - end - - def setup_other_elements(feed, current=nil) - current ||= current_element(feed) - self.class.other_elements.each do |element| - __send__("setup_#{element}", feed, current) - end - end - - def current_element(feed) - feed - end - - def set_default_values(&block) - return yield if @default_values_are_set - - begin - @default_values_are_set = true - _set_default_values(&block) - ensure - @default_values_are_set = false - end - end - - def _set_default_values(&block) - yield - 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 set_parent(target, parent) - target.parent = parent if target.class.need_parent? - end - - def variables - self.class.need_initialize_variables.find_all do |name, init| - # init == "nil" is just for backward compatibility - init.nil? or init == "nil" - end.collect do |name, init| - name - end - 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 - - module AtomPersonConstructBase - def self.append_features(klass) - super - - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) - %w(name uri email).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - EOC - end - end - - module AtomTextConstructBase - module EnsureXMLContent - class << self - def included(base) - super - base.class_eval do - %w(type content xml_content).each do |element| - attr_reader element - attr_writer element if element != "xml_content" - add_need_initialize_variable(element) - end - - alias_method(:xhtml, :xml_content) - end - end - end - - def ensure_xml_content(content) - xhtml_uri = ::RSS::Atom::XHTML_URI - unless content.is_a?(RSS::XML::Element) and - ["div", xhtml_uri] == [content.name, content.uri] - children = content - children = [children] unless content.is_a?(Array) - children = set_xhtml_uri_as_default_uri(children) - content = RSS::XML::Element.new("div", nil, xhtml_uri, - {"xmlns" => xhtml_uri}, - children) - end - content - end - - def xml_content=(content) - @xml_content = ensure_xml_content(content) - end - - def xhtml=(content) - self.xml_content = content - end - - private - def set_xhtml_uri_as_default_uri(children) - children.collect do |child| - if child.is_a?(RSS::XML::Element) and - child.prefix.nil? and child.uri.nil? - RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI, - child.attributes.dup, - set_xhtml_uri_as_default_uri(child.children)) - else - child - end - end - end - end - - def self.append_features(klass) - super - - klass.class_eval do - include EnsureXMLContent - end - end - end - - module SetupDefaultDate - private - def _set_default_values(&block) - keep = { - :date => date, - :dc_dates => dc_dates.to_a.dup, - } - _date = date - if _date and !dc_dates.any? {|dc_date| dc_date.value == _date} - dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self) - dc_date.value = _date.dup - dc_dates.unshift(dc_date) - end - self.date ||= self.dc_date - super(&block) - ensure - date = keep[:date] - dc_dates.replace(keep[:dc_dates]) - end - end - - class RSSBase < Base - class << self - def make(version, &block) - new(version).make(&block) - end - end - - %w(xml_stylesheets channel image items textinput).each do |element| - attr_reader element - add_need_initialize_variable(element) do |object| - object.send("make_#{element}") - end - module_eval(<<-EOC, __FILE__, __LINE__) - private - def setup_#{element}(feed) - @#{element}.to_feed(feed) - end - - def make_#{element} - self.class::#{Utils.to_class_name(element)}.new(self) - end - EOC - end - - attr_reader :feed_version - alias_method(:rss_version, :feed_version) - attr_accessor :version, :encoding, :standalone - - def initialize(feed_version) - super(self) - @feed_type = nil - @feed_subtype = nil - @feed_version = feed_version - @version = "1.0" - @encoding = "UTF-8" - @standalone = nil - end - - def make - yield(self) - to_feed - end - - def to_feed - feed = make_feed - setup_xml_stylesheets(feed) - setup_elements(feed) - setup_other_elements(feed) - feed.validate - feed - end - - private - remove_method :make_xml_stylesheets - def make_xml_stylesheets - XMLStyleSheets.new(self) - end - end - - class XMLStyleSheets < Base - def_array_element("xml_stylesheet", nil, "XMLStyleSheet") - - class XMLStyleSheet < Base - - ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute| - attr_accessor attribute - add_need_initialize_variable(attribute) - end - - def to_feed(feed) - xss = ::RSS::XMLStyleSheet.new - guess_type_if_need(xss) - set = setup_values(xss) - if set - feed.xml_stylesheets << xss - end - end - - private - def guess_type_if_need(xss) - if @type.nil? - xss.href = @href - @type = xss.type - end - end - - def required_variable_names - %w(href type) - end - end - end - - class ChannelBase < Base - include SetupDefaultDate - - %w(cloud categories skipDays skipHours).each do |name| - def_classed_element(name) - end - - %w(generator copyright description title).each do |name| - def_classed_element(name, nil, "content") - end - - [ - ["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}], - ["author", "name"], - ["contributor", "name"], - ].each do |name, attribute, additional_setup_maker| - def_classed_elements(name, attribute, &additional_setup_maker) - end - - %w(id about language - managingEditor webMaster rating docs date - lastBuildDate ttl).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - def pubDate - date - end - - def pubDate=(date) - self.date = date - end - - def updated - date - end - - def updated=(date) - self.date = date - end - - alias_method(:rights, :copyright) - alias_method(:rights=, :copyright=) - - alias_method(:subtitle, :description) - alias_method(:subtitle=, :description=) - - def icon - image_favicon.about - end - - def icon=(url) - image_favicon.about = url - end - - def logo - maker.image.url - end - - def logo=(url) - maker.image.url = url - end - - class SkipDaysBase < Base - def_array_element("day") - - class DayBase < Base - %w(content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end - - class SkipHoursBase < Base - def_array_element("hour") - - class HourBase < Base - %w(content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end - - class CloudBase < Base - %w(domain port path registerProcedure protocol).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class CategoriesBase < Base - def_array_element("category", "categories") - - class CategoryBase < Base - %w(domain content label).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - alias_method(:term, :domain) - alias_method(:term=, :domain=) - alias_method(:scheme, :content) - alias_method(:scheme=, :content=) - end - end - - class LinksBase < Base - def_array_element("link") - - class LinkBase < Base - %w(href rel type hreflang title length).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end - - class AuthorsBase < Base - def_array_element("author") - - class AuthorBase < Base - include AtomPersonConstructBase - end - end - - class ContributorsBase < Base - def_array_element("contributor") - - class ContributorBase < Base - include AtomPersonConstructBase - end - end - - class GeneratorBase < Base - %w(uri version content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class CopyrightBase < Base - include AtomTextConstructBase - end - - class DescriptionBase < Base - include AtomTextConstructBase - end - - class TitleBase < Base - include AtomTextConstructBase - end - end - - class ImageBase < 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 - end - - class ItemsBase < Base - def_array_element("item") - - 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 - - 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 < Base - include SetupDefaultDate - - %w(guid enclosure source categories content).each do |name| - def_classed_element(name) - end - - %w(rights description title).each do |name| - def_classed_element(name, nil, "content") - end - - [ - ["author", "name"], - ["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}], - ["contributor", "name"], - ].each do |name, attribute| - def_classed_elements(name, attribute) - end - - %w(date comments id published).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - def pubDate - date - end - - def pubDate=(date) - self.date = date - end - - def updated - date - end - - def updated=(date) - self.date = date - end - - alias_method(:summary, :description) - alias_method(:summary=, :description=) - - def <=>(other) - _date = date || dc_date - _other_date = other.date || other.dc_date - if _date and _other_date - _date <=> _other_date - elsif _date - 1 - elsif _other_date - -1 - else - 0 - end - end - - class GuidBase < Base - %w(isPermaLink content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class EnclosureBase < Base - %w(url length type).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class SourceBase < Base - %w(authors categories contributors generator icon - logo rights subtitle title).each do |name| - def_classed_element(name) - end - - [ - ["link", "href"], - ].each do |name, attribute| - def_classed_elements(name, attribute) - end - - %w(id content date).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - alias_method(:url, :link) - alias_method(:url=, :link=) - - def updated - date - end - - def updated=(date) - self.date = date - end - - private - AuthorsBase = ChannelBase::AuthorsBase - CategoriesBase = ChannelBase::CategoriesBase - ContributorsBase = ChannelBase::ContributorsBase - GeneratorBase = ChannelBase::GeneratorBase - - class IconBase < Base - %w(url).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - LinksBase = ChannelBase::LinksBase - - class LogoBase < Base - %w(uri).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class RightsBase < Base - include AtomTextConstructBase - end - - class SubtitleBase < Base - include AtomTextConstructBase - end - - class TitleBase < Base - include AtomTextConstructBase - end - end - - CategoriesBase = ChannelBase::CategoriesBase - AuthorsBase = ChannelBase::AuthorsBase - LinksBase = ChannelBase::LinksBase - ContributorsBase = ChannelBase::ContributorsBase - - class RightsBase < Base - include AtomTextConstructBase - end - - class DescriptionBase < Base - include AtomTextConstructBase - end - - class ContentBase < Base - include AtomTextConstructBase::EnsureXMLContent - - %w(src).each do |element| - attr_accessor(element) - add_need_initialize_variable(element) - end - - def xml_content=(content) - content = ensure_xml_content(content) if inline_xhtml? - @xml_content = content - end - - alias_method(:xml, :xml_content) - alias_method(:xml=, :xml_content=) - - def inline_text? - [nil, "text", "html"].include?(@type) - end - - def inline_html? - @type == "html" - end - - def inline_xhtml? - @type == "xhtml" - end - - def inline_other? - !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type) - end - - def inline_other_text? - return false if @type.nil? or out_of_line? - /\Atext\//i.match(@type) ? true : false - end - - def inline_other_xml? - return false if @type.nil? or out_of_line? - /[\+\/]xml\z/i.match(@type) ? true : false - end - - def inline_other_base64? - return false if @type.nil? or out_of_line? - @type.include?("/") and !inline_other_text? and !inline_other_xml? - end - - def out_of_line? - not @src.nil? and @content.nil? - end - end - - class TitleBase < Base - include AtomTextConstructBase - end - end - end - - class TextinputBase < Base - %w(title description name link).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end -end diff --git a/trunk/lib/rss/maker/content.rb b/trunk/lib/rss/maker/content.rb deleted file mode 100644 index 46c4911f73..0000000000 --- a/trunk/lib/rss/maker/content.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rss/content' -require 'rss/maker/1.0' -require 'rss/maker/2.0' - -module RSS - module Maker - module ContentModel - def self.append_features(klass) - super - - ::RSS::ContentModel::ELEMENTS.each do |name| - klass.def_other_element(name) - end - end - end - - class ItemsBase - class ItemBase; include ContentModel; end - end - end -end diff --git a/trunk/lib/rss/maker/dublincore.rb b/trunk/lib/rss/maker/dublincore.rb deleted file mode 100644 index ff4813fe19..0000000000 --- a/trunk/lib/rss/maker/dublincore.rb +++ /dev/null @@ -1,124 +0,0 @@ -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.def_classed_elements(full_name, "value", plural_klass_name, - full_plural_name, name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def new_#{full_name}(value=nil) - _#{full_name} = #{full_plural_name}.new_#{name} - _#{full_name}.value = value - if block_given? - yield _#{full_name} - else - _#{full_name} - end - end - EOC - end - - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - # For backward compatibility - alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list - EOC - end - - ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| - plural_name ||= "#{name}s" - full_name ||= "#{DC_PREFIX}_#{name}" - full_plural_name ||= "#{DC_PREFIX}_#{plural_name}" - klass_name = Utils.to_class_name(name) - full_klass_name = "DublinCore#{klass_name}" - plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{plural_klass_name}Base < Base - def_array_element(#{name.dump}, #{full_plural_name.dump}, - #{full_klass_name.dump}) - - class #{full_klass_name}Base < Base - attr_accessor :value - add_need_initialize_variable("value") - alias_method(:content, :value) - alias_method(:content=, :value=) - - def have_required_values? - @value - end - - def to_feed(feed, current) - if value and current.respond_to?(:#{full_name}) - new_item = current.class::#{full_klass_name}.new(value) - current.#{full_plural_name} << new_item - end - end - end - #{klass_name}Base = #{full_klass_name}Base - 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) - full_klass_name = "DublinCore#{klass_name}" - plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{plural_klass_name} < #{plural_klass_name}Base - class #{full_klass_name} < #{full_klass_name}Base - end - #{klass_name} = #{full_klass_name} - end -EOC - end - end - end - - class ChannelBase - include DublinCoreModel - end - - class ImageBase; include DublinCoreModel; end - class ItemsBase - class ItemBase - include DublinCoreModel - end - end - class TextinputBase; include DublinCoreModel; end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - 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 - EOC - end - end -end diff --git a/trunk/lib/rss/maker/entry.rb b/trunk/lib/rss/maker/entry.rb deleted file mode 100644 index edaa31ec06..0000000000 --- a/trunk/lib/rss/maker/entry.rb +++ /dev/null @@ -1,163 +0,0 @@ -require "rss/maker/atom" -require "rss/maker/feed" - -module RSS - module Maker - module Atom - class Entry < RSSBase - def initialize(feed_version="1.0") - super - @feed_type = "atom" - @feed_subtype = "entry" - end - - private - def make_feed - ::RSS::Atom::Entry.new(@version, @encoding, @standalone) - end - - def setup_elements(entry) - setup_items(entry) - end - - class Channel < ChannelBase - class SkipDays < SkipDaysBase - class Day < DayBase - end - end - - class SkipHours < SkipHoursBase - class Hour < HourBase - end - end - - class Cloud < CloudBase - end - - Categories = Feed::Channel::Categories - Links = Feed::Channel::Links - Authors = Feed::Channel::Authors - Contributors = Feed::Channel::Contributors - - class Generator < GeneratorBase - include AtomGenerator - - def self.not_set_name - "maker.channel.generator" - end - end - - Copyright = Feed::Channel::Copyright - - class Description < DescriptionBase - end - - Title = Feed::Channel::Title - end - - class Image < ImageBase - end - - class Items < ItemsBase - def to_feed(entry) - (normalize.first || Item.new(@maker)).to_feed(entry) - end - - class Item < ItemBase - def to_feed(entry) - set_default_values do - setup_values(entry) - entry.dc_dates.clear - setup_other_elements(entry) - unless have_required_values? - raise NotSetError.new("maker.item", not_set_required_variables) - end - end - end - - private - def required_variable_names - %w(id updated) - end - - def variables - super + ["updated"] - end - - def variable_is_set? - super or !authors.empty? - end - - def not_set_required_variables - set_default_values do - vars = super - if authors.all? {|author| !author.have_required_values?} - vars << "author" - end - vars << "title" unless title {|t| t.have_required_values?} - vars - end - end - - def _set_default_values(&block) - keep = { - :authors => authors.to_a.dup, - :contributors => contributors.to_a.dup, - :categories => categories.to_a.dup, - :id => id, - :links => links.to_a.dup, - :rights => @rights, - :title => @title, - :updated => updated, - } - authors.replace(@maker.channel.authors) if keep[:authors].empty? - if keep[:contributors].empty? - contributors.replace(@maker.channel.contributors) - end - if keep[:categories].empty? - categories.replace(@maker.channel.categories) - end - self.id ||= link || @maker.channel.id - links.replace(@maker.channel.links) if keep[:links].empty? - unless keep[:rights].variable_is_set? - @maker.channel.rights {|r| @rights = r} - end - unless keep[:title].variable_is_set? - @maker.channel.title {|t| @title = t} - end - self.updated ||= @maker.channel.updated - super(&block) - ensure - authors.replace(keep[:authors]) - contributors.replace(keep[:contributors]) - categories.replace(keep[:categories]) - links.replace(keep[:links]) - self.id = keep[:id] - @rights = keep[:rights] - @title = keep[:title] - self.updated = keep[:prev_updated] - end - - Guid = Feed::Items::Item::Guid - Enclosure = Feed::Items::Item::Enclosure - Source = Feed::Items::Item::Source - Categories = Feed::Items::Item::Categories - Authors = Feed::Items::Item::Authors - Contributors = Feed::Items::Item::Contributors - Links = Feed::Items::Item::Links - Rights = Feed::Items::Item::Rights - Description = Feed::Items::Item::Description - Title = Feed::Items::Item::Title - Content = Feed::Items::Item::Content - end - end - - class Textinput < TextinputBase - end - end - end - - add_maker("atom:entry", "1.0", Atom::Entry) - add_maker("atom1.0:entry", "1.0", Atom::Entry) - end -end diff --git a/trunk/lib/rss/maker/feed.rb b/trunk/lib/rss/maker/feed.rb deleted file mode 100644 index 3a30ad4287..0000000000 --- a/trunk/lib/rss/maker/feed.rb +++ /dev/null @@ -1,429 +0,0 @@ -require "rss/maker/atom" - -module RSS - module Maker - module Atom - class Feed < RSSBase - def initialize(feed_version="1.0") - super - @feed_type = "atom" - @feed_subtype = "feed" - end - - private - def make_feed - ::RSS::Atom::Feed.new(@version, @encoding, @standalone) - end - - def setup_elements(feed) - setup_channel(feed) - setup_image(feed) - setup_items(feed) - end - - class Channel < ChannelBase - def to_feed(feed) - set_default_values do - setup_values(feed) - feed.dc_dates.clear - setup_other_elements(feed) - if image_favicon.about - icon = feed.class::Icon.new - icon.content = image_favicon.about - feed.icon = icon - end - unless have_required_values? - raise NotSetError.new("maker.channel", - not_set_required_variables) - end - end - end - - def have_required_values? - super and - (!authors.empty? or - @maker.items.any? {|item| !item.authors.empty?}) - end - - private - def required_variable_names - %w(id updated) - end - - def variables - super + %w(id updated) - end - - def variable_is_set? - super or !authors.empty? - end - - def not_set_required_variables - vars = super - if authors.empty? and - @maker.items.all? {|item| item.author.to_s.empty?} - vars << "author" - end - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - def _set_default_values(&block) - keep = { - :id => id, - :updated => updated, - } - self.id ||= about - self.updated ||= dc_date - super(&block) - ensure - self.id = keep[:id] - self.updated = keep[:updated] - end - - class SkipDays < SkipDaysBase - def to_feed(*args) - end - - class Day < DayBase - end - end - - class SkipHours < SkipHoursBase - def to_feed(*args) - end - - class Hour < HourBase - end - end - - class Cloud < CloudBase - def to_feed(*args) - end - end - - class Categories < CategoriesBase - class Category < CategoryBase - include AtomCategory - - def self.not_set_name - "maker.channel.category" - end - end - end - - class Links < LinksBase - class Link < LinkBase - include AtomLink - - def self.not_set_name - "maker.channel.link" - end - end - end - - AtomPersons.def_atom_persons(self, "author", "maker.channel.author") - AtomPersons.def_atom_persons(self, "contributor", - "maker.channel.contributor") - - class Generator < GeneratorBase - include AtomGenerator - - def self.not_set_name - "maker.channel.generator" - end - end - - AtomTextConstruct.def_atom_text_construct(self, "rights", - "maker.channel.copyright", - "Copyright") - AtomTextConstruct.def_atom_text_construct(self, "subtitle", - "maker.channel.description", - "Description") - AtomTextConstruct.def_atom_text_construct(self, "title", - "maker.channel.title") - end - - class Image < ImageBase - def to_feed(feed) - logo = feed.class::Logo.new - class << logo - alias_method(:url=, :content=) - end - set = setup_values(logo) - class << logo - remove_method(:url=) - end - if set - feed.logo = logo - set_parent(logo, feed) - setup_other_elements(feed, logo) - elsif variable_is_set? - raise NotSetError.new("maker.image", not_set_required_variables) - end - end - - private - def required_variable_names - %w(url) - end - end - - class Items < ItemsBase - def to_feed(feed) - normalize.each do |item| - item.to_feed(feed) - end - setup_other_elements(feed, feed.entries) - end - - class Item < ItemBase - def to_feed(feed) - set_default_values do - entry = feed.class::Entry.new - set = setup_values(entry) - setup_other_elements(feed, entry) - if set - feed.entries << entry - set_parent(entry, feed) - elsif variable_is_set? - raise NotSetError.new("maker.item", not_set_required_variables) - end - end - end - - def have_required_values? - set_default_values do - super and title {|t| t.have_required_values?} - end - end - - private - def required_variable_names - %w(id updated) - end - - def variables - super + ["updated"] - end - - def not_set_required_variables - vars = super - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - def _set_default_values(&block) - keep = { - :id => id, - :updated => updated, - } - self.id ||= link - self.updated ||= dc_date - super(&block) - ensure - self.id = keep[:id] - self.updated = keep[:updated] - end - - class Guid < GuidBase - def to_feed(feed, current) - end - end - - class Enclosure < EnclosureBase - def to_feed(feed, current) - end - end - - class Source < SourceBase - def to_feed(feed, current) - source = current.class::Source.new - setup_values(source) - current.source = source - set_parent(source, current) - setup_other_elements(feed, source) - current.source = nil if source.to_s == "<source/>" - end - - private - def required_variable_names - [] - end - - def variables - super + ["updated"] - end - - AtomPersons.def_atom_persons(self, "author", - "maker.item.source.author") - AtomPersons.def_atom_persons(self, "contributor", - "maker.item.source.contributor") - - class Categories < CategoriesBase - class Category < CategoryBase - include AtomCategory - - def self.not_set_name - "maker.item.source.category" - end - end - end - - class Generator < GeneratorBase - include AtomGenerator - - def self.not_set_name - "maker.item.source.generator" - end - end - - class Icon < IconBase - def to_feed(feed, current) - icon = current.class::Icon.new - class << icon - alias_method(:url=, :content=) - end - set = setup_values(icon) - class << icon - remove_method(:url=) - end - if set - current.icon = icon - set_parent(icon, current) - setup_other_elements(feed, icon) - elsif variable_is_set? - raise NotSetError.new("maker.item.source.icon", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(url) - end - end - - class Links < LinksBase - class Link < LinkBase - include AtomLink - - def self.not_set_name - "maker.item.source.link" - end - end - end - - class Logo < LogoBase - include AtomLogo - - def self.not_set_name - "maker.item.source.logo" - end - end - - maker_name_base = "maker.item.source." - maker_name = "#{maker_name_base}rights" - AtomTextConstruct.def_atom_text_construct(self, "rights", - maker_name) - maker_name = "#{maker_name_base}subtitle" - AtomTextConstruct.def_atom_text_construct(self, "subtitle", - maker_name) - maker_name = "#{maker_name_base}title" - AtomTextConstruct.def_atom_text_construct(self, "title", - maker_name) - end - - class Categories < CategoriesBase - class Category < CategoryBase - include AtomCategory - - def self.not_set_name - "maker.item.category" - end - end - end - - AtomPersons.def_atom_persons(self, "author", "maker.item.author") - AtomPersons.def_atom_persons(self, "contributor", - "maker.item.contributor") - - class Links < LinksBase - class Link < LinkBase - include AtomLink - - def self.not_set_name - "maker.item.link" - end - end - end - - AtomTextConstruct.def_atom_text_construct(self, "rights", - "maker.item.rights") - AtomTextConstruct.def_atom_text_construct(self, "summary", - "maker.item.description", - "Description") - AtomTextConstruct.def_atom_text_construct(self, "title", - "maker.item.title") - - class Content < ContentBase - def to_feed(feed, current) - content = current.class::Content.new - if setup_values(content) - content.src = nil if content.src and content.content - current.content = content - set_parent(content, current) - setup_other_elements(feed, content) - elsif variable_is_set? - raise NotSetError.new("maker.item.content", - not_set_required_variables) - end - end - - alias_method(:xml, :xml_content) - - private - def required_variable_names - if out_of_line? - %w(type) - elsif xml_type? - %w(xml_content) - else - %w(content) - end - end - - def variables - if out_of_line? - super - elsif xml_type? - super + %w(xml) - else - super - end - end - - def xml_type? - _type = type - return false if _type.nil? - _type == "xhtml" or - /(?:\+xml|\/xml)$/i =~ _type or - %w(text/xml-external-parsed-entity - application/xml-external-parsed-entity - application/xml-dtd).include?(_type.downcase) - end - end - end - end - - class Textinput < TextinputBase - end - end - end - - add_maker("atom", "1.0", Atom::Feed) - add_maker("atom:feed", "1.0", Atom::Feed) - add_maker("atom1.0", "1.0", Atom::Feed) - add_maker("atom1.0:feed", "1.0", Atom::Feed) - end -end diff --git a/trunk/lib/rss/maker/image.rb b/trunk/lib/rss/maker/image.rb deleted file mode 100644 index b95cf4c714..0000000000 --- a/trunk/lib/rss/maker/image.rb +++ /dev/null @@ -1,111 +0,0 @@ -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.def_classed_element(name) - end - - def self.install_image_item(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class ImageItem < ImageItemBase - DublinCoreModel.install_dublin_core(self) - end -EOC - end - - class ImageItemBase < 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 - - def to_feed(feed, current) - if current.respond_to?(:image_item=) and have_required_values? - item = current.class::ImageItem.new - setup_values(item) - setup_other_elements(item) - current.image_item = item - end - end - end - end - - module ImageFaviconModel - def self.append_features(klass) - super - - name = "#{RSS::IMAGE_PREFIX}_favicon" - klass.def_classed_element(name) - end - - def self.install_image_favicon(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class ImageFavicon < ImageFaviconBase - DublinCoreModel.install_dublin_core(self) - end - EOC - end - - class ImageFaviconBase < 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 - - def to_feed(feed, current) - if current.respond_to?(:image_favicon=) and have_required_values? - favicon = current.class::ImageFavicon.new - setup_values(favicon) - setup_other_elements(favicon) - current.image_favicon = favicon - end - end - end - end - - class ChannelBase; include Maker::ImageFaviconModel; end - - class ItemsBase - class ItemBase; include Maker::ImageItemModel; end - end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class Channel - ImageFaviconModel.install_image_favicon(self) - end - - class Items - class Item - ImageItemModel.install_image_item(self) - end - end - EOC - end - end -end diff --git a/trunk/lib/rss/maker/itunes.rb b/trunk/lib/rss/maker/itunes.rb deleted file mode 100644 index 8b7420da3c..0000000000 --- a/trunk/lib/rss/maker/itunes.rb +++ /dev/null @@ -1,242 +0,0 @@ -require 'rss/itunes' -require 'rss/maker/2.0' - -module RSS - module Maker - module ITunesBaseModel - def def_class_accessor(klass, name, type, *args) - name = name.gsub(/-/, "_").gsub(/^itunes_/, '') - full_name = "#{RSS::ITUNES_PREFIX}_#{name}" - case type - when nil - klass.def_other_element(full_name) - when :yes_other - def_yes_other_accessor(klass, full_name) - when :yes_clean_other - def_yes_clean_other_accessor(klass, full_name) - when :csv - def_csv_accessor(klass, full_name) - when :element, :attribute - recommended_attribute_name, = *args - klass_name = "ITunes#{Utils.to_class_name(name)}" - klass.def_classed_element(full_name, klass_name, - recommended_attribute_name) - when :elements - plural_name, recommended_attribute_name = args - plural_name ||= "#{name}s" - full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}" - klass_name = "ITunes#{Utils.to_class_name(name)}" - plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}" - def_elements_class_accessor(klass, name, full_name, full_plural_name, - klass_name, plural_klass_name, - recommended_attribute_name) - end - end - - def def_yes_other_accessor(klass, full_name) - klass.def_other_element(full_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{full_name}? - Utils::YesOther.parse(@#{full_name}) - end - EOC - end - - def def_yes_clean_other_accessor(klass, full_name) - klass.def_other_element(full_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{full_name}? - Utils::YesCleanOther.parse(#{full_name}) - end - EOC - end - - def def_csv_accessor(klass, full_name) - klass.def_csv_element(full_name) - end - - def def_elements_class_accessor(klass, name, full_name, full_plural_name, - klass_name, plural_klass_name, - recommended_attribute_name=nil) - if recommended_attribute_name - klass.def_classed_elements(full_name, recommended_attribute_name, - plural_klass_name, full_plural_name) - else - klass.def_classed_element(full_plural_name, plural_klass_name) - end - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def new_#{full_name}(text=nil) - #{full_name} = @#{full_plural_name}.new_#{name} - #{full_name}.text = text - if block_given? - yield #{full_name} - else - #{full_name} - end - end - EOC - end - end - - module ITunesChannelModel - extend ITunesBaseModel - - class << self - def append_features(klass) - super - - ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args| - def_class_accessor(klass, name, type, *args) - end - end - end - - class ITunesCategoriesBase < Base - def_array_element("category", "itunes_categories", - "ITunesCategory") - class ITunesCategoryBase < Base - attr_accessor :text - add_need_initialize_variable("text") - def_array_element("category", "itunes_categories", - "ITunesCategory") - - def have_required_values? - text - end - - alias_method :to_feed_for_categories, :to_feed - def to_feed(feed, current) - if text and current.respond_to?(:itunes_category) - new_item = current.class::ITunesCategory.new(text) - to_feed_for_categories(feed, new_item) - current.itunes_categories << new_item - end - end - end - end - - class ITunesImageBase < Base - add_need_initialize_variable("href") - attr_accessor("href") - - def to_feed(feed, current) - if @href and current.respond_to?(:itunes_image) - current.itunes_image ||= current.class::ITunesImage.new - current.itunes_image.href = @href - end - end - end - - class ITunesOwnerBase < Base - %w(itunes_name itunes_email).each do |name| - add_need_initialize_variable(name) - attr_accessor(name) - end - - def to_feed(feed, current) - if current.respond_to?(:itunes_owner=) - _not_set_required_variables = not_set_required_variables - if (required_variable_names - _not_set_required_variables).empty? - return - end - - unless have_required_values? - raise NotSetError.new("maker.channel.itunes_owner", - _not_set_required_variables) - end - current.itunes_owner ||= current.class::ITunesOwner.new - current.itunes_owner.itunes_name = @itunes_name - current.itunes_owner.itunes_email = @itunes_email - end - end - - private - def required_variable_names - %w(itunes_name itunes_email) - end - end - end - - module ITunesItemModel - extend ITunesBaseModel - - class << self - def append_features(klass) - super - - ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args| - def_class_accessor(klass, name, type, *args) - end - end - end - - class ITunesDurationBase < Base - attr_reader :content - add_need_initialize_variable("content") - - %w(hour minute second).each do |name| - attr_reader(name) - add_need_initialize_variable(name, 0) - end - - def content=(content) - if content.nil? - @hour, @minute, @second, @content = nil - else - @hour, @minute, @second = - ::RSS::ITunesItemModel::ITunesDuration.parse(content) - @content = content - end - end - - def hour=(hour) - @hour = Integer(hour) - update_content - end - - def minute=(minute) - @minute = Integer(minute) - update_content - end - - def second=(second) - @second = Integer(second) - update_content - end - - def to_feed(feed, current) - if @content and current.respond_to?(:itunes_duration=) - current.itunes_duration ||= current.class::ITunesDuration.new - current.itunes_duration.content = @content - end - end - - private - def update_content - components = [@hour, @minute, @second] - @content = - ::RSS::ITunesItemModel::ITunesDuration.construct(*components) - end - end - end - - class ChannelBase - include Maker::ITunesChannelModel - class ITunesCategories < ITunesCategoriesBase - class ITunesCategory < ITunesCategoryBase - ITunesCategory = self - end - end - - class ITunesImage < ITunesImageBase; end - class ITunesOwner < ITunesOwnerBase; end - end - - class ItemsBase - class ItemBase - include Maker::ITunesItemModel - class ITunesDuration < ITunesDurationBase; end - end - end - end -end diff --git a/trunk/lib/rss/maker/slash.rb b/trunk/lib/rss/maker/slash.rb deleted file mode 100644 index 27adef3832..0000000000 --- a/trunk/lib/rss/maker/slash.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'rss/slash' -require 'rss/maker/1.0' - -module RSS - module Maker - module SlashModel - def self.append_features(klass) - super - - ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type| - full_name = "#{RSS::SLASH_PREFIX}_#{name}" - case type - when :csv_integer - klass.def_csv_element(full_name, :integer) - else - klass.def_other_element(full_name) - end - end - - klass.module_eval do - alias_method(:slash_hit_parades, :slash_hit_parade) - alias_method(:slash_hit_parades=, :slash_hit_parade=) - end - end - end - - class ItemsBase - class ItemBase - include SlashModel - end - end - end -end diff --git a/trunk/lib/rss/maker/syndication.rb b/trunk/lib/rss/maker/syndication.rb deleted file mode 100644 index b81230457c..0000000000 --- a/trunk/lib/rss/maker/syndication.rb +++ /dev/null @@ -1,18 +0,0 @@ -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 |name| - klass.def_other_element(name) - end - end - end - - class ChannelBase; include SyndicationModel; end - end -end diff --git a/trunk/lib/rss/maker/taxonomy.rb b/trunk/lib/rss/maker/taxonomy.rb deleted file mode 100644 index 211603840f..0000000000 --- a/trunk/lib/rss/maker/taxonomy.rb +++ /dev/null @@ -1,118 +0,0 @@ -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.def_classed_element("#{RSS::TAXO_PREFIX}_topics", - "TaxonomyTopics") - end - - def self.install_taxo_topics(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class TaxonomyTopics < TaxonomyTopicsBase - def to_feed(feed, 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 < Base - attr_reader :resources - def_array_element("resource") - remove_method :new_resource - end - end - - module TaxonomyTopicModel - def self.append_features(klass) - super - - class_name = "TaxonomyTopics" - klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name) - end - - def self.install_taxo_topic(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class TaxonomyTopics < TaxonomyTopicsBase - class TaxonomyTopic < TaxonomyTopicBase - DublinCoreModel.install_dublin_core(self) - TaxonomyTopicsModel.install_taxo_topics(self) - - def to_feed(feed, current) - if current.respond_to?(:taxo_topics) - topic = current.class::TaxonomyTopic.new(value) - topic.taxo_link = value - taxo_topics.to_feed(feed, topic) if taxo_topics - current.taxo_topics << topic - setup_other_elements(feed, topic) - end - end - end - end -EOC - end - - class TaxonomyTopicsBase < Base - def_array_element("topic", nil, "TaxonomyTopic") - alias_method(:new_taxo_topic, :new_topic) # For backward compatibility - - class TaxonomyTopicBase < 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 - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - TaxonomyTopicModel.install_taxo_topic(self) - - class Channel - TaxonomyTopicsModel.install_taxo_topics(self) - end - - class Items - class Item - TaxonomyTopicsModel.install_taxo_topics(self) - end - end - EOC - end - end -end diff --git a/trunk/lib/rss/maker/trackback.rb b/trunk/lib/rss/maker/trackback.rb deleted file mode 100644 index 278fe53ebe..0000000000 --- a/trunk/lib/rss/maker/trackback.rb +++ /dev/null @@ -1,61 +0,0 @@ -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 - - klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping") - klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value", - "TrackBackAbouts") - end - - class TrackBackAboutsBase < Base - def_array_element("about", nil, "TrackBackAbout") - - class TrackBackAboutBase < 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 - - def to_feed(feed, current) - if current.respond_to?(:trackback_abouts) and have_required_values? - about = current.class::TrackBackAbout.new - setup_values(about) - setup_other_elements(about) - current.trackback_abouts << about - end - end - end - end - end - - class ItemsBase - class ItemBase; include TrackBackModel; end - end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class Items - class Item - class TrackBackAbouts < TrackBackAboutsBase - class TrackBackAbout < TrackBackAboutBase - end - end - end - end - EOC - end - end -end diff --git a/trunk/lib/rss/parser.rb b/trunk/lib/rss/parser.rb deleted file mode 100644 index 9b28f0fa8a..0000000000 --- a/trunk/lib/rss/parser.rb +++ /dev/null @@ -1,551 +0,0 @@ -require "forwardable" -require "open-uri" - -require "rss/rss" -require "rss/xml" - -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.parse(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 - - @@accessor_bases = {} - @@registered_uris = {} - @@class_names = {} - - # return the setter for the uri, tag_name pair, or nil. - def setter(uri, tag_name) - _getter = getter(uri, tag_name) - if _getter - "#{_getter}=" - else - nil - end - end - - def getter(uri, tag_name) - (@@accessor_bases[uri] || {})[tag_name] - end - - # return the tag_names for setters associated with uri - def available_tags(uri) - (@@accessor_bases[uri] || {}).keys - 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) - name = (@@class_names[uri] || {})[tag_name] - return name if name - - tag_name = tag_name.gsub(/[_\-]([a-z]?)/) {$1.upcase} - tag_name[0, 1].upcase + tag_name[1..-1] - end - - def install_get_text_element(uri, name, accessor_base) - install_accessor_base(uri, name, accessor_base) - def_get_text_element(uri, name, *get_file_and_line_from_caller(1)) - end - - def raise_for_undefined_entity? - true - end - - private - # set the accessor for the uri, tag_name pair - def install_accessor_base(uri, tag_name, accessor_base) - @@accessor_bases[uri] ||= {} - @@accessor_bases[uri][tag_name] = accessor_base.chomp("=") - end - - def def_get_text_element(uri, element_name, file, line) - register_uri(uri, element_name) - method_name = "start_#{element_name}" - unless private_method_defined?(method_name) - define_method(method_name) do |name, prefix, attrs, ns| - uri = _ns(ns, prefix) - if self.class.uri_registered?(uri, element_name) - start_get_text_element(name, prefix, ns, uri) - else - start_else_element(name, prefix, attrs, ns) - end - end - private(method_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 = [{"xml" => :xml}] - @tag_stack = [[]] - @text_stack = [''] - @proc_stack = [] - @last_element = nil - @version = @encoding = @standalone = nil - @xml_stylesheets = [] - @xml_child_mode = false - @xml_element = nil - @last_xml_element = nil - 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 @xml_child_mode - previous = @last_xml_element - element_attrs = attributes.dup - unless previous - ns.each do |ns_prefix, value| - next if ns_prefix == "xml" - key = ns_prefix.empty? ? "xmlns" : "xmlns:#{ns_prefix}" - element_attrs[key] ||= value - end - end - next_element = XML::Element.new(local, - prefix.empty? ? nil : prefix, - _ns(ns, prefix), - element_attrs) - previous << next_element if previous - @last_xml_element = next_element - pr = Proc.new do |text, tags| - if previous - @last_xml_element = previous - else - @xml_element = @last_xml_element - @last_xml_element = nil - end - end - @proc_stack.push(pr) - else - if @rss.nil? and respond_to?("initial_start_#{local}", true) - __send__("initial_start_#{local}", local, prefix, attrs, ns.dup) - elsif respond_to?("start_#{local}", true) - __send__("start_#{local}", local, prefix, attrs, ns.dup) - else - start_else_element(local, prefix, attrs, ns.dup) - end - 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) - if @xml_child_mode - @last_xml_element << data if @last_xml_element - else - @text_stack.last << data - end - 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 known_class?(current_class, 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 - - if Module.method(:const_defined?).arity == -1 - def known_class?(target_class, class_name) - class_name and - (target_class.const_defined?(class_name, false) or - target_class.constants.include?(class_name.to_sym)) - end - else - def known_class?(target_class, class_name) - class_name and - (target_class.const_defined?(class_name) or - target_class.constants.include?(class_name)) - 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) - unless _ns(ns, prefix) == require_uri - if @do_validate - raise NSError.new(tag_name, prefix, require_uri) - else - # Force bind required URI with prefix - @ns_stack.last[prefix] = require_uri - end - end - end - - def start_get_text_element(tag_name, prefix, ns, required_uri) - pr = Proc.new do |text, tags| - setter = self.class.setter(required_uri, tag_name) - if @last_element.respond_to?(setter) - if @do_validate - getter = self.class.getter(required_uri, tag_name) - if @last_element.__send__(getter) - raise TooMuchTagError.new(tag_name, @last_element.tag_name) - end - end - @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 - @proc_stack.push(pr) - end - - def start_have_something_element(tag_name, prefix, attrs, ns, klass) - check_ns(tag_name, prefix, ns, klass.required_uri) - attributes = collect_attributes(tag_name, prefix, attrs, ns, klass) - @proc_stack.push(setup_next_element(tag_name, klass, attributes)) - end - - def collect_attributes(tag_name, prefix, attrs, ns, klass) - 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 - attributes - end - - def setup_next_element(tag_name, klass, attributes) - previous = @last_element - next_element = klass.new(@do_validate, attributes) - previous.set_next_element(tag_name, next_element) - @last_element = next_element - @last_element.parent = previous if klass.need_parent? - @xml_child_mode = @last_element.have_xml_content? - - Proc.new do |text, tags| - p(@last_element.class) if DEBUG - if @xml_child_mode - @last_element.content = @xml_element.to_s - xml_setter = @last_element.class.xml_setter - @last_element.__send__(xml_setter, @xml_element) - @xml_element = nil - @xml_child_mode = false - else - if klass.have_content? - if @last_element.need_base64_encode? - text = text.lstrip.unpack("m").first - end - @last_element.content = text - end - end - if @do_validate - @last_element.validate_for_stream(tags, @ignore_unknown_element) - end - @last_element = previous - end - 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/trunk/lib/rss/rexmlparser.rb b/trunk/lib/rss/rexmlparser.rb deleted file mode 100644 index 4dabf59199..0000000000 --- a/trunk/lib/rss/rexmlparser.rb +++ /dev/null @@ -1,54 +0,0 @@ -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/trunk/lib/rss/rss.rb b/trunk/lib/rss/rss.rb deleted file mode 100644 index 4b943ec55b..0000000000 --- a/trunk/lib/rss/rss.rb +++ /dev/null @@ -1,1313 +0,0 @@ -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] - usec = 0 - usec = $7.to_f * 1000000 if $7 - zone = $8 - if zone - off = zone_offset(zone, datetime[0]) - datetime = apply_offset(*(datetime + [off])) - datetime << usec - time = Time.utc(*datetime) - time.localtime unless zone_utc?(zone) - time - else - datetime << usec - Time.local(*datetime) - end - else - raise ArgumentError.new("invalid date: #{date.inspect}") - end - end - end - end - - unless method_defined?(:w3cdtf) - def w3cdtf - if usec.zero? - fraction_digits = 0 - else - fraction_digits = Math.log10(usec.to_s.sub(/0*$/, '').to_i).floor + 1 - end - xmlschema(fraction_digits) - end - end -end - - -require "English" -require "rss/utils" -require "rss/converter" -require "rss/xml-stylesheet" - -module RSS - - VERSION = "0.2.5" - - 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 - - class UnsupportedMakerVersionError < Error - attr_reader :version - def initialize(version) - @version = version - super("Maker doesn't support version: #{@version}") - end - end - - module BaseModel - include Utils - - def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil) - name ||= tag_name - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - writer_type, reader_type = type - def_corresponded_attr_writer name, writer_type - def_corresponded_attr_reader name, reader_type - 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, true) - - 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 unless self::ELEMENTS.include?(name) - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - def_corresponded_attr_writer(name, type, disp_name) - def_corresponded_attr_reader(name, type || :convert) - install_element(name) do |n, elem_name| - <<-EOC - if respond_to?(:#{n}_content) - content = #{n}_content - else - content = @#{n} - end - if content - rv = "\#{indent}<#{elem_name}>" - value = html_escape(content) - 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 inherit_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}_without_inherit - convert(@#{attr}) - end - - def #{attr} - if @#{attr} - #{attr}_without_inherit - elsif @parent - @parent.#{attr} - else - nil - end - end -EOC - end - end - - def uri_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}_without_base - convert(@#{attr}) - end - - def #{attr} - value = #{attr}_without_base - return nil if value.nil? - if /\\A[a-z][a-z0-9+.\\-]*:/i =~ value - value - else - "\#{base}\#{value}" - end - end -EOC - end - 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} - convert(@#{attr}) - end -EOC - end - end - - def yes_clean_other_attr_reader(*attrs) - attrs.each do |attr| - attr = attr.id2name if attr.kind_of?(Integer) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader(:#{attr}) - def #{attr}? - YesCleanOther.parse(@#{attr}) - end - EOC - end - end - - def yes_other_attr_reader(*attrs) - attrs.each do |attr| - attr = attr.id2name if attr.kind_of?(Integer) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader(:#{attr}) - def #{attr}? - Utils::YesOther.parse(@#{attr}) - end - EOC - end - end - - def csv_attr_reader(*attrs) - separator = nil - if attrs.last.is_a?(Hash) - options = attrs.pop - separator = options[:separator] - end - separator ||= ", " - attrs.each do |attr| - attr = attr.id2name if attr.kind_of?(Integer) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader(:#{attr}) - def #{attr}_content - if @#{attr}.nil? - @#{attr} - else - @#{attr}.join(#{separator.dump}) - 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? - @#{name} = new_value - elsif new_value.kind_of?(Time) - @#{name} = new_value.dup - 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 - unless Date._parse(new_value, false).empty? - @#{name} = Time.parse(new_value) - end - 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 text_type_writer(name, disp_name=name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if @do_validate and - !["text", "html", "xhtml", nil].include?(new_value) - raise NotAvailableValueError.new('#{disp_name}', new_value) - end - @#{name} = new_value - end -EOC - end - - def content_writer(name, disp_name=name) - klass_name = "self.class::#{Utils.to_class_name(name)}" - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if new_value.is_a?(#{klass_name}) - @#{name} = new_value - else - @#{name} = #{klass_name}.new - @#{name}.content = new_value - end - end -EOC - end - - def yes_clean_other_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(value) - value = (value ? "yes" : "no") if [true, false].include?(value) - @#{name} = value - end - EOC - end - - def yes_other_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(new_value) - if [true, false].include?(new_value) - new_value = new_value ? "yes" : "no" - end - @#{name} = new_value - end - EOC - end - - def csv_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(new_value) - @#{name} = Utils::CSV.parse(new_value) - end - EOC - end - - def csv_integer_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(new_value) - @#{name} = Utils::CSV.parse(new_value) {|v| Integer(v)} - 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) - receiver = self.class.name - warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \ - "Don't use `\#{receiver}\##{accessor_name} = XXX'/" \ - "`\#{receiver}\#set_#{accessor_name}(XXX)'. " \ - "Those APIs are not sense of Ruby. " \ - "Use `\#{receiver}\##{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 - - module SetupMaker - 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 - - private - 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) - next if value.nil? - 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 - end - - class Element - extend BaseModel - include Utils - extend Utils::InheritedReader - include SetupMaker - - INDENT = " " - - MUST_CALL_VALIDATORS = {} - MODELS = [] - GET_ATTRIBUTES = [] - HAVE_CHILDREN_ELEMENTS = [] - TO_ELEMENT_METHODS = [] - NEED_INITIALIZE_VARIABLES = [] - PLURAL_FORMS = {} - - class << self - def must_call_validators - inherited_hash_reader("MUST_CALL_VALIDATORS") - end - def models - inherited_array_reader("MODELS") - end - def get_attributes - inherited_array_reader("GET_ATTRIBUTES") - end - def have_children_elements - inherited_array_reader("HAVE_CHILDREN_ELEMENTS") - end - def to_element_methods - inherited_array_reader("TO_ELEMENT_METHODS") - end - def need_initialize_variables - inherited_array_reader("NEED_INITIALIZE_VARIABLES") - end - def plural_forms - inherited_hash_reader("PLURAL_FORMS") - end - - def inherited_base - ::RSS::Element - 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", {}) - - tag_name = klass.name.split(/::/).last - tag_name[0, 1] = tag_name[0, 1].downcase - klass.instance_variable_set("@tag_name", tag_name) - klass.instance_variable_set("@have_content", false) - end - - def install_must_call_validator(prefix, uri) - self::MUST_CALL_VALIDATORS[uri] = prefix - end - - def install_model(tag, uri, occurs=nil, getter=nil, plural=false) - getter ||= tag - if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri} - m[2] = occurs - else - self::MODELS << [tag, uri, occurs, getter, plural] - end - end - - def install_get_attribute(name, uri, required=true, - type=nil, disp_name=nil, - element_name=nil) - disp_name ||= name - element_name ||= name - writer_type, reader_type = type - def_corresponded_attr_writer name, writer_type, disp_name - def_corresponded_attr_reader name, reader_type - if type == :boolean and /^is/ =~ name - alias_method "#{$POSTMATCH}?", name - end - self::GET_ATTRIBUTES << [name, uri, required, element_name] - add_need_initialize_variable(disp_name) - end - - def def_corresponded_attr_writer(name, type=nil, disp_name=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 - when :text_type - text_type_writer name, disp_name - when :content - content_writer name, disp_name - when :yes_clean_other - yes_clean_other_writer name, disp_name - when :yes_other - yes_other_writer name, disp_name - when :csv - csv_writer name - when :csv_integer - csv_integer_writer name - else - attr_writer name - end - end - - def def_corresponded_attr_reader(name, type=nil) - case type - when :inherit - inherit_convert_attr_reader name - when :uri - uri_convert_attr_reader name - when :yes_clean_other - yes_clean_other_attr_reader name - when :yes_other - yes_other_attr_reader name - when :csv - csv_attr_reader name - when :csv_integer - csv_attr_reader name, :separator => "," - else - convert_attr_reader name - end - end - - def content_setup(type=nil, disp_name=nil) - writer_type, reader_type = type - def_corresponded_attr_writer :content, writer_type, disp_name - def_corresponded_attr_reader :content, reader_type - @have_content = true - end - - def have_content? - @have_content - end - - def add_have_children_element(variable_name, plural_name) - self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name] - end - - def add_to_element_method(method_name) - self::TO_ELEMENT_METHODS << method_name - end - - def add_need_initialize_variable(variable_name) - self::NEED_INITIALIZE_VARIABLES << variable_name - end - - def add_plural_form(singular, plural) - self::PLURAL_FORMS[singular] = plural - end - - def required_prefix - nil - end - - def required_uri - "" - end - - def need_parent? - false - 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 :parent, :do_validate - - def initialize(do_validate=true, attrs=nil) - @parent = nil - @converter = nil - if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array)) - do_validate, attrs = true, do_validate - end - @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 valid?(ignore_unknown_element=true) - validate(ignore_unknown_element) - true - rescue RSS::Error - false - end - - def validate(ignore_unknown_element=true) - do_validate = @do_validate - @do_validate = true - validate_attribute - __validate(ignore_unknown_element) - ensure - @do_validate = do_validate - end - - def validate_for_stream(tags, ignore_unknown_element=true) - validate_attribute - __validate(ignore_unknown_element, tags, false) - end - - def to_s(need_convert=true, indent='') - if self.class.have_content? - return "" if !empty_content? and !content_is_set? - rv = tag(indent) do |next_indent| - if empty_content? - "" - else - xmled_content - end - 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 - - def have_xml_content? - false - end - - def need_base64_encode? - false - 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.gsub(/-/, '_')}" - if self.class.plural_forms.has_key?(key) - ary = __send__("#{self.class.plural_forms[key]}") - ary << next_element - else - __send__("#{key}=", next_element) - end - end - - protected - def have_required_elements? - self.class::MODELS.all? do |tag, uri, occurs, getter| - if occurs.nil? or occurs == "+" - child = __send__(getter) - if child.is_a?(Array) - children = child - children.any? {|c| c.have_required_elements?} - else - !child.to_s.empty? - end - else - true - end - end - 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_variable_set("@#{variable_name}", nil) - end - end - initialize_have_children_elements - @content = normalized_attrs["content"] if self.class.have_content? - end - - def initialize_have_children_elements - self.class.have_children_elements.each do |variable_name, plural_name| - instance_variable_set("@#{variable_name}", []) - end - end - - def tag(indent, additional_attrs={}, &block) - next_indent = indent + INDENT - - attrs = collect_attrs - return "" if attrs.nil? - - return "" unless have_required_elements? - - attrs.update(additional_attrs) - start_tag = make_start_tag(indent, next_indent, attrs.dup) - - 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? - return "" if attrs.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 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, plural| - value = __send__(getter) - next if value.nil? - if plural and 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 !prefix.empty? and 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| - value = instance_variable_get("@#{alias_name || a_name}") - if required and value.nil? - raise MissingAttributeError.new(tag_name, a_name) - end - __send__("#{alias_name || a_name}=", value) - 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 - - _tags = tags.dup if tags - 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 - - def empty_content? - false - end - - def content_is_set? - if have_xml_content? - __send__(self.class.xml_getter) - else - content - end - end - - def xmled_content - if have_xml_content? - __send__(self.class.xml_getter).to_s - else - _content = content - _content = [_content].pack("m").delete("\n") if need_base64_encode? - h(_content) - end - end - end - - module RootElementMixin - - include XMLStyleSheetMixin - - attr_reader :output_encoding - attr_reader :feed_type, :feed_subtype, :feed_version - attr_accessor :version, :encoding, :standalone - def initialize(feed_version, version=nil, encoding=nil, standalone=nil) - super() - @feed_type = nil - @feed_subtype = nil - @feed_version = feed_version - @version = version || '1.0' - @encoding = encoding - @standalone = standalone - @output_encoding = nil - end - - def feed_info - [@feed_type, @feed_version, @feed_subtype] - 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 - - super - end - - def to_feed(type, &block) - Maker.make(type) do |maker| - setup_maker(maker) - block.call(maker) if block - end - end - - def to_rss(type, &block) - to_feed("rss#{type}", &block) - end - - def to_atom(type, &block) - to_feed("atom:#{type}", &block) - end - - def to_xml(type=nil, &block) - if type.nil? or same_feed_type?(type) - to_s - else - to_feed(type, &block).to_s - end - end - - private - def same_feed_type?(type) - if /^(atom|rss)?(\d+\.\d+)?(?::(.+))?$/i =~ type - feed_type = ($1 || @feed_type).downcase - feed_version = $2 || @feed_version - feed_subtype = $3 || @feed_subtype - [feed_type, feed_version, feed_subtype] == feed_info - else - false - end - end - - def tag(indent, attrs={}, &block) - rv = super(indent, ns_declarations.merge(attrs), &block) - return rv if rv.empty? - "#{xmldecl}#{xml_stylesheet_pi}#{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 maker_target(target) - target - end - end -end diff --git a/trunk/lib/rss/slash.rb b/trunk/lib/rss/slash.rb deleted file mode 100644 index f102413b46..0000000000 --- a/trunk/lib/rss/slash.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'rss/1.0' - -module RSS - SLASH_PREFIX = 'slash' - SLASH_URI = "http://purl.org/rss/1.0/modules/slash/" - - RDF.install_ns(SLASH_PREFIX, SLASH_URI) - - module SlashModel - extend BaseModel - - ELEMENT_INFOS = \ - [ - ["section"], - ["department"], - ["comments", :positive_integer], - ["hit_parade", :csv_integer], - ] - - class << self - def append_features(klass) - super - - return if klass.instance_of?(Module) - klass.install_must_call_validator(SLASH_PREFIX, SLASH_URI) - ELEMENT_INFOS.each do |name, type, *additional_infos| - full_name = "#{SLASH_PREFIX}_#{name}" - klass.install_text_element(full_name, SLASH_URI, "?", - full_name, type, name) - end - - klass.module_eval do - alias_method(:slash_hit_parades, :slash_hit_parade) - undef_method(:slash_hit_parade) - alias_method(:slash_hit_parade, :slash_hit_parade_content) - end - end - end - end - - class RDF - class Item; include SlashModel; end - end - - SlashModel::ELEMENT_INFOS.each do |name, type| - accessor_base = "#{SLASH_PREFIX}_#{name}" - BaseListener.install_get_text_element(SLASH_URI, name, accessor_base) - end -end diff --git a/trunk/lib/rss/syndication.rb b/trunk/lib/rss/syndication.rb deleted file mode 100644 index 3eb15429f6..0000000000 --- a/trunk/lib/rss/syndication.rb +++ /dev/null @@ -1,67 +0,0 @@ -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', - "#{SY_PREFIX}:#{name}") - end - end - - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - 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 - EOC - 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/trunk/lib/rss/taxonomy.rb b/trunk/lib/rss/taxonomy.rb deleted file mode 100644 index 276f63b05d..0000000000 --- a/trunk/lib/rss/taxonomy.rb +++ /dev/null @@ -1,145 +0,0 @@ -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/trunk/lib/rss/trackback.rb b/trunk/lib/rss/trackback.rb deleted file mode 100644 index ee2491f332..0000000000 --- a/trunk/lib/rss/trackback.rb +++ /dev/null @@ -1,288 +0,0 @@ -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/trunk/lib/rss/utils.rb b/trunk/lib/rss/utils.rb deleted file mode 100644 index 0e4001e1f3..0000000000 --- a/trunk/lib/rss/utils.rb +++ /dev/null @@ -1,111 +0,0 @@ -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(':') - line = line.to_i - line += 1 if i.zero? - [file, line] - end - - # escape '&', '"', '<' and '>' for use in HTML. - def html_escape(s) - s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<") - 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 - - module YesCleanOther - module_function - def parse(value) - if [true, false, nil].include?(value) - value - else - case value.to_s - when /\Ayes\z/i - true - when /\Aclean\z/i - false - else - nil - end - end - end - end - - module YesOther - module_function - def parse(value) - if [true, false].include?(value) - value - else - /\Ayes\z/i.match(value.to_s) ? true : false - end - end - end - - module CSV - module_function - def parse(value, &block) - if value.is_a?(String) - value = value.strip.split(/\s*,\s*/) - value = value.collect(&block) if block_given? - value - else - value - end - end - end - - module InheritedReader - def inherited_reader(constant_name) - base_class = inherited_base - result = base_class.const_get(constant_name) - found_base_class = false - ancestors.reverse_each do |klass| - if found_base_class - if klass.const_defined?(constant_name) - result = yield(result, klass.const_get(constant_name)) - end - else - found_base_class = klass == base_class - end - end - result - end - - def inherited_array_reader(constant_name) - inherited_reader(constant_name) do |result, current| - current + result - end - end - - def inherited_hash_reader(constant_name) - inherited_reader(constant_name) do |result, current| - result.merge(current) - end - end - end - end -end diff --git a/trunk/lib/rss/xml-stylesheet.rb b/trunk/lib/rss/xml-stylesheet.rb deleted file mode 100644 index 559d6bcd56..0000000000 --- a/trunk/lib/rss/xml-stylesheet.rb +++ /dev/null @@ -1,105 +0,0 @@ -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) - if attrs.size == 1 and - (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array)) - attrs = attrs.first - end - @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/trunk/lib/rss/xml.rb b/trunk/lib/rss/xml.rb deleted file mode 100644 index 1ae878b772..0000000000 --- a/trunk/lib/rss/xml.rb +++ /dev/null @@ -1,71 +0,0 @@ -require "rss/utils" - -module RSS - module XML - class Element - include Enumerable - - attr_reader :name, :prefix, :uri, :attributes, :children - def initialize(name, prefix=nil, uri=nil, attributes={}, children=[]) - @name = name - @prefix = prefix - @uri = uri - @attributes = attributes - if children.is_a?(String) or !children.respond_to?(:each) - @children = [children] - else - @children = children - end - end - - def [](name) - @attributes[name] - end - - def []=(name, value) - @attributes[name] = value - end - - def <<(child) - @children << child - end - - def each(&block) - @children.each(&block) - end - - def ==(other) - other.kind_of?(self.class) and - @name == other.name and - @uri == other.uri and - @attributes == other.attributes and - @children == other.children - end - - def to_s - rv = "<#{full_name}" - attributes.each do |key, value| - rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\"" - end - if children.empty? - rv << "/>" - else - rv << ">" - children.each do |child| - rv << child.to_s - end - rv << "</#{full_name}>" - end - rv - end - - def full_name - if @prefix - "#{@prefix}:#{@name}" - else - @name - end - end - end - end -end diff --git a/trunk/lib/rss/xmlparser.rb b/trunk/lib/rss/xmlparser.rb deleted file mode 100644 index 3dfe7d461a..0000000000 --- a/trunk/lib/rss/xmlparser.rb +++ /dev/null @@ -1,93 +0,0 @@ -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/trunk/lib/rss/xmlscanner.rb b/trunk/lib/rss/xmlscanner.rb deleted file mode 100644 index 61b9fa6bf4..0000000000 --- a/trunk/lib/rss/xmlscanner.rb +++ /dev/null @@ -1,121 +0,0 @@ -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 |