diff options
Diffstat (limited to 'lib/rss/rss.rb')
-rw-r--r-- | lib/rss/rss.rb | 733 |
1 files changed, 515 insertions, 218 deletions
diff --git a/lib/rss/rss.rb b/lib/rss/rss.rb index a06985af94..d2e226c0fe 100644 --- a/lib/rss/rss.rb +++ b/lib/rss/rss.rb @@ -11,11 +11,19 @@ class Time (\.\d+)? (Z|[+-]\d\d:\d\d)?)? \s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8)) - datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i] - datetime << $7.to_f * 1000000 if $7 - if $8 - Time.utc(*datetime) - zone_offset($8) + 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 @@ -25,8 +33,15 @@ class Time end end - unless instance_methods.include?("w3cdtf") - alias w3cdtf iso8601 + 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 @@ -37,7 +52,7 @@ require "rss/xml-stylesheet" module RSS - VERSION = "0.1.6" + VERSION = "0.2.0" URI = "http://purl.org/rss/1.0/" @@ -136,17 +151,26 @@ module RSS super("required variables of #{@name} are not set: #{@variables.join(', ')}") end end - - module BaseModel + 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) + 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) - attr_accessor 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} @@ -164,7 +188,7 @@ EOC 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) + install_model(tag_name, uri, occurs, plural_name, true) def_children_accessor(name, plural_name) install_element(name, "s") do |n, elem_name| @@ -179,20 +203,26 @@ EOC end end - def install_text_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil) + def install_text_element(tag_name, uri, occurs, name=nil, type=nil, + disp_name=nil) name ||= tag_name disp_name ||= name self::ELEMENTS << name add_need_initialize_variable(name) install_model(tag_name, uri, occurs, name) - def_corresponded_attr_writer name, type, disp_name - convert_attr_reader name + def_corresponded_attr_writer(name, type, disp_name) + def_corresponded_attr_reader(name, type || :convert) install_element(name) do |n, elem_name| <<-EOC - if @#{n} + if respond_to?(:#{n}_content) + content = #{n}_content + else + content = @#{n} + end + if content rv = "\#{indent}<#{elem_name}>" - value = html_escape(@#{n}) + value = html_escape(content) if need_convert rv << convert(value) else @@ -252,26 +282,112 @@ EOC EOC end - def convert_attr_reader(*attrs) + 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 @converter - @converter.convert(@#{attr}) + if @#{attr} + #{attr}_without_inherit + elsif @parent + @parent.#{attr} else - @#{attr} + 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? or new_value.kind_of?(Time) + if new_value.nil? @#{name} = new_value + elsif new_value.kind_of?(Time) + @#{name} = new_value.dup else if @do_validate begin @@ -283,7 +399,9 @@ EOC @#{name} = nil if /\\A\\s*\\z/ !~ new_value.to_s begin - @#{name} = Time.parse(new_value) + unless Date._parse(new_value, false).empty? + @#{name} = Time.parse(new_value) + end rescue ArgumentError end end @@ -364,6 +482,68 @@ EOC 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} @@ -379,10 +559,12 @@ EOC end def #{accessor_name}=(*args) + receiver = self.class.name warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \ - "Don't use `#{accessor_name} = XXX'/`set_#{accessor_name}(XXX)'. " \ + "Don't use `\#{receiver}\##{accessor_name} = XXX'/" \ + "`\#{receiver}\#set_#{accessor_name}(XXX)'. " \ "Those APIs are not sense of Ruby. " \ - "Use `#{plural_name} << XXX' instead of them.") + "Use `\#{receiver}\##{plural_name} << XXX' instead of them.") if args.size == 1 @#{accessor_name}.push(args[0]) else @@ -394,10 +576,61 @@ EOC end end - class Element + 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 = " " @@ -408,32 +641,34 @@ EOC TO_ELEMENT_METHODS = [] NEED_INITIALIZE_VARIABLES = [] PLURAL_FORMS = {} - - class << self + class << self def must_call_validators - MUST_CALL_VALIDATORS + inherited_hash_reader("MUST_CALL_VALIDATORS") end def models - MODELS + inherited_array_reader("MODELS") end def get_attributes - GET_ATTRIBUTES + inherited_array_reader("GET_ATTRIBUTES") end def have_children_elements - HAVE_CHILDREN_ELEMENTS + inherited_array_reader("HAVE_CHILDREN_ELEMENTS") end def to_element_methods - TO_ELEMENT_METHODS + inherited_array_reader("TO_ELEMENT_METHODS") end def need_initialize_variables - NEED_INITIALIZE_VARIABLES + inherited_array_reader("NEED_INITIALIZE_VARIABLES") end def plural_forms - 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", []) @@ -443,105 +678,112 @@ EOC klass.const_set("NEED_INITIALIZE_VARIABLES", []) klass.const_set("PLURAL_FORMS", {}) - klass.module_eval(<<-EOC) - public - - @tag_name = name.split(/::/).last - @tag_name[0,1] = @tag_name[0,1].downcase - @have_content = false + 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 self.must_call_validators - super.merge(MUST_CALL_VALIDATORS) - end - def self.models - MODELS + super - end - def self.get_attributes - GET_ATTRIBUTES + super - end - def self.have_children_elements - HAVE_CHILDREN_ELEMENTS + super - end - def self.to_element_methods - TO_ELEMENT_METHODS + super - end - def self.need_initialize_variables - NEED_INITIALIZE_VARIABLES + super + 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 - def self.plural_forms - super.merge(PLURAL_FORMS) + 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 self.install_must_call_validator(prefix, uri) - MUST_CALL_VALIDATORS[uri] = prefix - end - - def self.install_model(tag, uri, occurs=nil, getter=nil) - getter ||= tag - if m = MODELS.find {|t, u, o, g| t == tag and u == uri} - m[2] = occurs - else - MODELS << [tag, uri, occurs, getter] - end + 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 self.install_get_attribute(name, uri, required=true, - type=nil, disp_name=nil, - element_name=nil) - disp_name ||= name - element_name ||= name - def_corresponded_attr_writer name, type, disp_name + 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 - if type == :boolean and /^is/ =~ name - alias_method "\#{$POSTMATCH}?", name - end - GET_ATTRIBUTES << [name, uri, required, element_name] - add_need_initialize_variable(disp_name) - end - - def self.def_corresponded_attr_writer(name, type=nil, disp_name=name) - case type - when :integer - integer_writer name, disp_name - when :positive_integer - positive_integer_writer name, disp_name - when :boolean - boolean_writer name, disp_name - when :w3cdtf, :rfc822, :rfc2822 - date_writer name, type, disp_name - else - attr_writer name - end end + end - def self.content_setup(type=nil) - def_corresponded_attr_writer "content", type - convert_attr_reader :content - @have_content = true - 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 self.have_content? - @have_content - end + def have_content? + @have_content + end - def self.add_have_children_element(variable_name, plural_name) - HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name] - end - - def self.add_to_element_method(method_name) - TO_ELEMENT_METHODS << method_name - end + def add_have_children_element(variable_name, plural_name) + self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name] + end - def self.add_need_initialize_variable(variable_name) - NEED_INITIALIZE_VARIABLES << variable_name - end - - def self.add_plural_form(singular, plural) - PLURAL_FORMS[singular] = plural - end - - EOC + 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 @@ -551,7 +793,11 @@ EOC def required_uri "" end - + + def need_parent? + false + end + def install_ns(prefix, uri) if self::NSPOOL.has_key?(prefix) raise OverlappedPrefixError.new(prefix) @@ -564,12 +810,16 @@ EOC end end - attr_accessor :do_validate + attr_accessor :parent, :do_validate - def initialize(do_validate=true, attrs={}) + 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) + initialize_variables(attrs || {}) end def tag_name @@ -598,10 +848,21 @@ EOC 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) @@ -609,20 +870,15 @@ EOC __validate(ignore_unknown_element, tags, false) end - def setup_maker(maker) - target = maker_target(maker) - unless target.nil? - setup_maker_attributes(target) - setup_maker_element(target) - setup_maker_elements(target) - end - end - def to_s(need_convert=true, indent='') if self.class.have_content? - return "" unless @content + return "" if !empty_content? and !content_is_set? rv = tag(indent) do |next_indent| - h(@content) + if empty_content? + "" + else + xmled_content + end end else rv = tag(indent) do |next_indent| @@ -635,6 +891,44 @@ EOC 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 = {} @@ -646,16 +940,16 @@ EOC if value __send__("#{variable_name}=", value) else - instance_eval("@#{variable_name} = nil") + instance_variable_set("@#{variable_name}", nil) end end initialize_have_children_elements - @content = "" if self.class.have_content? + @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_eval("@#{variable_name} = []") + instance_variable_set("@#{variable_name}", []) end end @@ -665,8 +959,10 @@ EOC 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) + start_tag = make_start_tag(indent, next_indent, attrs.dup) if block content = block.call(next_indent) @@ -681,6 +977,7 @@ EOC else content = content.reject{|x| x.empty?} if content.empty? + return "" if attrs.empty? end_tag = "/>" else start_tag << ">\n" @@ -722,56 +1019,6 @@ EOC '' end - def maker_target(maker) - nil - end - - def setup_maker_attributes(target) - end - - def setup_maker_element(target) - self.class.need_initialize_variables.each do |var| - value = __send__(var) - if value.respond_to?("setup_maker") and - !not_need_to_call_setup_maker_variables.include?(var) - value.setup_maker(target) - else - setter = "#{var}=" - if target.respond_to?(setter) - target.__send__(setter, value) - end - end - end - end - - def not_need_to_call_setup_maker_variables - [] - end - - def setup_maker_elements(parent) - self.class.have_children_elements.each do |name, plural_name| - if parent.respond_to?(plural_name) - target = parent.__send__(plural_name) - __send__(plural_name).each do |elem| - elem.setup_maker(target) - end - end - end - end - - def set_next_element(tag_name, next_element) - klass = next_element.class - prefix = "" - prefix << "#{klass.required_prefix}_" if klass.required_prefix - key = "#{prefix}#{tag_name}" - if self.class.plural_forms.has_key?(key) - ary = __send__("#{self.class.plural_forms[key]}") - ary << next_element - else - __send__("#{prefix}#{tag_name}=", next_element) - end - end - def children rv = [] self.class.models.each do |name, uri, occurs, getter| @@ -787,10 +1034,10 @@ EOC def _tags rv = [] - self.class.models.each do |name, uri, occurs, getter| + self.class.models.each do |name, uri, occurs, getter, plural| value = __send__(getter) next if value.nil? - if value.is_a?(Array) + if plural and value.is_a?(Array) rv.concat([[uri, name]] * value.size) else rv << [uri, name] @@ -817,7 +1064,7 @@ EOC must_call_validators.each do |uri, prefix| _validate(ignore_unknown_element, tags[uri], uri) meth = "#{prefix}_validate" - if respond_to?(meth, true) + if !prefix.empty? and respond_to?(meth, true) __send__(meth, ignore_unknown_element, tags[uri], uri) end end @@ -825,9 +1072,11 @@ EOC def validate_attribute _attrs.each do |a_name, required, alias_name| - if required and __send__(alias_name || a_name).nil? + 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 @@ -843,11 +1092,12 @@ EOC 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 "before" p tags p model end @@ -933,6 +1183,27 @@ EOC 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 = Base64.encode64(_content) if need_base64_encode? + h(_content) + end + end end module RootElementMixin @@ -940,16 +1211,23 @@ EOC include XMLStyleSheetMixin attr_reader :output_encoding - - def initialize(rss_version, version=nil, encoding=nil, standalone=nil) + attr_reader :feed_type, :feed_subtype, :feed_version + attr_accessor :version, :encoding, :standalone + def initialize(feed_version, version=nil, encoding=nil, standalone=nil) super() - @rss_version = rss_version + @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) @@ -964,25 +1242,48 @@ EOC xss.setup_maker(maker) end - setup_maker_elements(maker) + 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_xml(version=nil, &block) - if version.nil? or version == @rss_version + 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 - RSS::Maker.make(version) do |maker| - setup_maker(maker) - block.call(maker) if block - end.to_s + 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 = xmldecl + xml_stylesheet_pi - rv << super(indent, ns_declarations.merge(attrs), &block) - rv + rv = super(indent, ns_declarations.merge(attrs), &block) + return rv if rv.empty? + "#{xmldecl}#{xml_stylesheet_pi}#{rv}" end def xmldecl @@ -1003,13 +1304,9 @@ EOC end decls end - - def setup_maker_elements(maker) - channel.setup_maker(maker) if channel - image.setup_maker(maker) if image - textinput.setup_maker(maker) if textinput - super(maker) + + def maker_target(target) + target end end - end |