1# frozen_string_literal: false
2require_relative "utils"
3
4module RSS
5
6  module XMLStyleSheetMixin
7    attr_accessor :xml_stylesheets
8    def initialize(*args)
9      super
10      @xml_stylesheets = []
11    end
12
13    private
14    def xml_stylesheet_pi
15      xsss = @xml_stylesheets.collect do |xss|
16        pi = xss.to_s
17        pi = nil if /\A\s*\z/ =~ pi
18        pi
19      end.compact
20      xsss.push("") unless xsss.empty?
21      xsss.join("\n")
22    end
23  end
24
25  class XMLStyleSheet
26
27    include Utils
28
29    ATTRIBUTES = %w(href type title media charset alternate)
30
31    GUESS_TABLE = {
32      "xsl" => "text/xsl",
33      "css" => "text/css",
34    }
35
36    attr_accessor(*ATTRIBUTES)
37    attr_accessor(:do_validate)
38    def initialize(*attrs)
39      if attrs.size == 1 and
40          (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array))
41        attrs = attrs.first
42      end
43      @do_validate = true
44      ATTRIBUTES.each do |attr|
45        __send__("#{attr}=", nil)
46      end
47      vars = ATTRIBUTES.dup
48      vars.unshift(:do_validate)
49      attrs.each do |name, value|
50        if vars.include?(name.to_s)
51          __send__("#{name}=", value)
52        end
53      end
54    end
55
56    def to_s
57      rv = ""
58      if @href
59        rv << %Q[<?xml-stylesheet]
60        ATTRIBUTES.each do |name|
61          if __send__(name)
62            rv << %Q[ #{name}="#{h __send__(name)}"]
63          end
64        end
65        rv << %Q[?>]
66      end
67      rv
68    end
69
70    remove_method(:href=)
71    def href=(value)
72      @href = value
73      if @href and @type.nil?
74        @type = guess_type(@href)
75      end
76      @href
77    end
78
79    remove_method(:alternate=)
80    def alternate=(value)
81      if value.nil? or /\A(?:yes|no)\z/ =~ value
82        @alternate = value
83      else
84        if @do_validate
85          args = ["?xml-stylesheet?", %Q[alternate="#{value}"]]
86          raise NotAvailableValueError.new(*args)
87        end
88      end
89      @alternate
90    end
91
92    def setup_maker(maker)
93      xss = maker.xml_stylesheets.new_xml_stylesheet
94      ATTRIBUTES.each do |attr|
95        xss.__send__("#{attr}=", __send__(attr))
96      end
97    end
98
99    private
100    def guess_type(filename)
101      /\.([^.]+)$/ =~ filename
102      GUESS_TABLE[$1]
103    end
104
105  end
106end
107