rubysl-rss 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/lib/rss.rb +1 -0
  9. data/lib/rss/0.9.rb +428 -0
  10. data/lib/rss/1.0.rb +452 -0
  11. data/lib/rss/2.0.rb +111 -0
  12. data/lib/rss/atom.rb +749 -0
  13. data/lib/rss/content.rb +31 -0
  14. data/lib/rss/content/1.0.rb +10 -0
  15. data/lib/rss/content/2.0.rb +12 -0
  16. data/lib/rss/converter.rb +162 -0
  17. data/lib/rss/dublincore.rb +161 -0
  18. data/lib/rss/dublincore/1.0.rb +13 -0
  19. data/lib/rss/dublincore/2.0.rb +13 -0
  20. data/lib/rss/dublincore/atom.rb +17 -0
  21. data/lib/rss/image.rb +193 -0
  22. data/lib/rss/itunes.rb +410 -0
  23. data/lib/rss/maker.rb +44 -0
  24. data/lib/rss/maker/0.9.rb +467 -0
  25. data/lib/rss/maker/1.0.rb +434 -0
  26. data/lib/rss/maker/2.0.rb +223 -0
  27. data/lib/rss/maker/atom.rb +172 -0
  28. data/lib/rss/maker/base.rb +868 -0
  29. data/lib/rss/maker/content.rb +21 -0
  30. data/lib/rss/maker/dublincore.rb +124 -0
  31. data/lib/rss/maker/entry.rb +163 -0
  32. data/lib/rss/maker/feed.rb +429 -0
  33. data/lib/rss/maker/image.rb +111 -0
  34. data/lib/rss/maker/itunes.rb +242 -0
  35. data/lib/rss/maker/slash.rb +33 -0
  36. data/lib/rss/maker/syndication.rb +18 -0
  37. data/lib/rss/maker/taxonomy.rb +118 -0
  38. data/lib/rss/maker/trackback.rb +61 -0
  39. data/lib/rss/parser.rb +541 -0
  40. data/lib/rss/rexmlparser.rb +54 -0
  41. data/lib/rss/rss.rb +1312 -0
  42. data/lib/rss/slash.rb +49 -0
  43. data/lib/rss/syndication.rb +67 -0
  44. data/lib/rss/taxonomy.rb +145 -0
  45. data/lib/rss/trackback.rb +288 -0
  46. data/lib/rss/utils.rb +111 -0
  47. data/lib/rss/xml-stylesheet.rb +105 -0
  48. data/lib/rss/xml.rb +71 -0
  49. data/lib/rss/xmlparser.rb +93 -0
  50. data/lib/rss/xmlscanner.rb +121 -0
  51. data/lib/rubysl/rss.rb +2 -0
  52. data/lib/rubysl/rss/rss.rb +19 -0
  53. data/lib/rubysl/rss/version.rb +5 -0
  54. data/rubysl-rss.gemspec +23 -0
  55. metadata +153 -0
@@ -0,0 +1,111 @@
1
+ module RSS
2
+ module Utils
3
+ module_function
4
+
5
+ # Convert a name_with_underscores to CamelCase.
6
+ def to_class_name(name)
7
+ name.split(/[_\-]/).collect do |part|
8
+ "#{part[0, 1].upcase}#{part[1..-1]}"
9
+ end.join("")
10
+ end
11
+
12
+ def get_file_and_line_from_caller(i=0)
13
+ file, line, = caller[i].split(':')
14
+ line = line.to_i
15
+ line += 1 if i.zero?
16
+ [file, line]
17
+ end
18
+
19
+ # escape '&', '"', '<' and '>' for use in HTML.
20
+ def html_escape(s)
21
+ s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
22
+ end
23
+ alias h html_escape
24
+
25
+ # If +value+ is an instance of class +klass+, return it, else
26
+ # create a new instance of +klass+ with value +value+.
27
+ def new_with_value_if_need(klass, value)
28
+ if value.is_a?(klass)
29
+ value
30
+ else
31
+ klass.new(value)
32
+ end
33
+ end
34
+
35
+ def element_initialize_arguments?(args)
36
+ [true, false].include?(args[0]) and args[1].is_a?(Hash)
37
+ end
38
+
39
+ module YesCleanOther
40
+ module_function
41
+ def parse(value)
42
+ if [true, false, nil].include?(value)
43
+ value
44
+ else
45
+ case value.to_s
46
+ when /\Ayes\z/i
47
+ true
48
+ when /\Aclean\z/i
49
+ false
50
+ else
51
+ nil
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ module YesOther
58
+ module_function
59
+ def parse(value)
60
+ if [true, false].include?(value)
61
+ value
62
+ else
63
+ /\Ayes\z/i.match(value.to_s) ? true : false
64
+ end
65
+ end
66
+ end
67
+
68
+ module CSV
69
+ module_function
70
+ def parse(value, &block)
71
+ if value.is_a?(String)
72
+ value = value.strip.split(/\s*,\s*/)
73
+ value = value.collect(&block) if block_given?
74
+ value
75
+ else
76
+ value
77
+ end
78
+ end
79
+ end
80
+
81
+ module InheritedReader
82
+ def inherited_reader(constant_name)
83
+ base_class = inherited_base
84
+ result = base_class.const_get(constant_name)
85
+ found_base_class = false
86
+ ancestors.reverse_each do |klass|
87
+ if found_base_class
88
+ if klass.const_defined?(constant_name)
89
+ result = yield(result, klass.const_get(constant_name))
90
+ end
91
+ else
92
+ found_base_class = klass == base_class
93
+ end
94
+ end
95
+ result
96
+ end
97
+
98
+ def inherited_array_reader(constant_name)
99
+ inherited_reader(constant_name) do |result, current|
100
+ current + result
101
+ end
102
+ end
103
+
104
+ def inherited_hash_reader(constant_name)
105
+ inherited_reader(constant_name) do |result, current|
106
+ result.merge(current)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,105 @@
1
+ require "rss/utils"
2
+
3
+ module RSS
4
+
5
+ module XMLStyleSheetMixin
6
+ attr_accessor :xml_stylesheets
7
+ def initialize(*args)
8
+ super
9
+ @xml_stylesheets = []
10
+ end
11
+
12
+ private
13
+ def xml_stylesheet_pi
14
+ xsss = @xml_stylesheets.collect do |xss|
15
+ pi = xss.to_s
16
+ pi = nil if /\A\s*\z/ =~ pi
17
+ pi
18
+ end.compact
19
+ xsss.push("") unless xsss.empty?
20
+ xsss.join("\n")
21
+ end
22
+ end
23
+
24
+ class XMLStyleSheet
25
+
26
+ include Utils
27
+
28
+ ATTRIBUTES = %w(href type title media charset alternate)
29
+
30
+ GUESS_TABLE = {
31
+ "xsl" => "text/xsl",
32
+ "css" => "text/css",
33
+ }
34
+
35
+ attr_accessor(*ATTRIBUTES)
36
+ attr_accessor(:do_validate)
37
+ def initialize(*attrs)
38
+ if attrs.size == 1 and
39
+ (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array))
40
+ attrs = attrs.first
41
+ end
42
+ @do_validate = true
43
+ ATTRIBUTES.each do |attr|
44
+ __send__("#{attr}=", nil)
45
+ end
46
+ vars = ATTRIBUTES.dup
47
+ vars.unshift(:do_validate)
48
+ attrs.each do |name, value|
49
+ if vars.include?(name.to_s)
50
+ __send__("#{name}=", value)
51
+ end
52
+ end
53
+ end
54
+
55
+ def to_s
56
+ rv = ""
57
+ if @href
58
+ rv << %Q[<?xml-stylesheet]
59
+ ATTRIBUTES.each do |name|
60
+ if __send__(name)
61
+ rv << %Q[ #{name}="#{h __send__(name)}"]
62
+ end
63
+ end
64
+ rv << %Q[?>]
65
+ end
66
+ rv
67
+ end
68
+
69
+ remove_method(:href=)
70
+ def href=(value)
71
+ @href = value
72
+ if @href and @type.nil?
73
+ @type = guess_type(@href)
74
+ end
75
+ @href
76
+ end
77
+
78
+ remove_method(:alternate=)
79
+ def alternate=(value)
80
+ if value.nil? or /\A(?:yes|no)\z/ =~ value
81
+ @alternate = value
82
+ else
83
+ if @do_validate
84
+ args = ["?xml-stylesheet?", %Q[alternate="#{value}"]]
85
+ raise NotAvailableValueError.new(*args)
86
+ end
87
+ end
88
+ @alternate
89
+ end
90
+
91
+ def setup_maker(maker)
92
+ xss = maker.xml_stylesheets.new_xml_stylesheet
93
+ ATTRIBUTES.each do |attr|
94
+ xss.__send__("#{attr}=", __send__(attr))
95
+ end
96
+ end
97
+
98
+ private
99
+ def guess_type(filename)
100
+ /\.([^.]+)$/ =~ filename
101
+ GUESS_TABLE[$1]
102
+ end
103
+
104
+ end
105
+ end
@@ -0,0 +1,71 @@
1
+ require "rss/utils"
2
+
3
+ module RSS
4
+ module XML
5
+ class Element
6
+ include Enumerable
7
+
8
+ attr_reader :name, :prefix, :uri, :attributes, :children
9
+ def initialize(name, prefix=nil, uri=nil, attributes={}, children=[])
10
+ @name = name
11
+ @prefix = prefix
12
+ @uri = uri
13
+ @attributes = attributes
14
+ if children.is_a?(String) or !children.respond_to?(:each)
15
+ @children = [children]
16
+ else
17
+ @children = children
18
+ end
19
+ end
20
+
21
+ def [](name)
22
+ @attributes[name]
23
+ end
24
+
25
+ def []=(name, value)
26
+ @attributes[name] = value
27
+ end
28
+
29
+ def <<(child)
30
+ @children << child
31
+ end
32
+
33
+ def each(&block)
34
+ @children.each(&block)
35
+ end
36
+
37
+ def ==(other)
38
+ other.kind_of?(self.class) and
39
+ @name == other.name and
40
+ @uri == other.uri and
41
+ @attributes == other.attributes and
42
+ @children == other.children
43
+ end
44
+
45
+ def to_s
46
+ rv = "<#{full_name}"
47
+ attributes.each do |key, value|
48
+ rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\""
49
+ end
50
+ if children.empty?
51
+ rv << "/>"
52
+ else
53
+ rv << ">"
54
+ children.each do |child|
55
+ rv << child.to_s
56
+ end
57
+ rv << "</#{full_name}>"
58
+ end
59
+ rv
60
+ end
61
+
62
+ def full_name
63
+ if @prefix
64
+ "#{@prefix}:#{@name}"
65
+ else
66
+ @name
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,93 @@
1
+ begin
2
+ require "xml/parser"
3
+ rescue LoadError
4
+ require "xmlparser"
5
+ end
6
+
7
+ begin
8
+ require "xml/encoding-ja"
9
+ rescue LoadError
10
+ require "xmlencoding-ja"
11
+ if defined?(Kconv)
12
+ module XMLEncoding_ja
13
+ class SJISHandler
14
+ include Kconv
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module XML
21
+ class Parser
22
+ unless defined?(Error)
23
+ Error = ::XMLParserError
24
+ end
25
+ end
26
+ end
27
+
28
+ module RSS
29
+
30
+ class REXMLLikeXMLParser < ::XML::Parser
31
+
32
+ include ::XML::Encoding_ja
33
+
34
+ def listener=(listener)
35
+ @listener = listener
36
+ end
37
+
38
+ def startElement(name, attrs)
39
+ @listener.tag_start(name, attrs)
40
+ end
41
+
42
+ def endElement(name)
43
+ @listener.tag_end(name)
44
+ end
45
+
46
+ def character(data)
47
+ @listener.text(data)
48
+ end
49
+
50
+ def xmlDecl(version, encoding, standalone)
51
+ @listener.xmldecl(version, encoding, standalone == 1)
52
+ end
53
+
54
+ def processingInstruction(target, content)
55
+ @listener.instruction(target, content)
56
+ end
57
+
58
+ end
59
+
60
+ class XMLParserParser < BaseParser
61
+
62
+ class << self
63
+ def listener
64
+ XMLParserListener
65
+ end
66
+ end
67
+
68
+ private
69
+ def _parse
70
+ begin
71
+ parser = REXMLLikeXMLParser.new
72
+ parser.listener = @listener
73
+ parser.parse(@rss)
74
+ rescue ::XML::Parser::Error => e
75
+ raise NotWellFormedError.new(parser.line){e.message}
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ class XMLParserListener < BaseListener
82
+
83
+ include ListenerMixin
84
+
85
+ def xmldecl(version, encoding, standalone)
86
+ super
87
+ # Encoding is converted to UTF-8 when XMLParser parses XML.
88
+ @encoding = 'UTF-8'
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,121 @@
1
+ require 'xmlscan/scanner'
2
+ require 'stringio'
3
+
4
+ module RSS
5
+
6
+ class XMLScanParser < BaseParser
7
+
8
+ class << self
9
+ def listener
10
+ XMLScanListener
11
+ end
12
+ end
13
+
14
+ private
15
+ def _parse
16
+ begin
17
+ if @rss.is_a?(String)
18
+ input = StringIO.new(@rss)
19
+ else
20
+ input = @rss
21
+ end
22
+ scanner = XMLScan::XMLScanner.new(@listener)
23
+ scanner.parse(input)
24
+ rescue XMLScan::Error => e
25
+ lineno = e.lineno || scanner.lineno || input.lineno
26
+ raise NotWellFormedError.new(lineno){e.message}
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ class XMLScanListener < BaseListener
33
+
34
+ include XMLScan::Visitor
35
+ include ListenerMixin
36
+
37
+ ENTITIES = {
38
+ 'lt' => '<',
39
+ 'gt' => '>',
40
+ 'amp' => '&',
41
+ 'quot' => '"',
42
+ 'apos' => '\''
43
+ }
44
+
45
+ def on_xmldecl_version(str)
46
+ @version = str
47
+ end
48
+
49
+ def on_xmldecl_encoding(str)
50
+ @encoding = str
51
+ end
52
+
53
+ def on_xmldecl_standalone(str)
54
+ @standalone = str
55
+ end
56
+
57
+ def on_xmldecl_end
58
+ xmldecl(@version, @encoding, @standalone == "yes")
59
+ end
60
+
61
+ alias_method(:on_pi, :instruction)
62
+ alias_method(:on_chardata, :text)
63
+ alias_method(:on_cdata, :text)
64
+
65
+ def on_etag(name)
66
+ tag_end(name)
67
+ end
68
+
69
+ def on_entityref(ref)
70
+ text(entity(ref))
71
+ end
72
+
73
+ def on_charref(code)
74
+ text([code].pack('U'))
75
+ end
76
+
77
+ alias_method(:on_charref_hex, :on_charref)
78
+
79
+ def on_stag(name)
80
+ @attrs = {}
81
+ end
82
+
83
+ def on_attribute(name)
84
+ @attrs[name] = @current_attr = ''
85
+ end
86
+
87
+ def on_attr_value(str)
88
+ @current_attr << str
89
+ end
90
+
91
+ def on_attr_entityref(ref)
92
+ @current_attr << entity(ref)
93
+ end
94
+
95
+ def on_attr_charref(code)
96
+ @current_attr << [code].pack('U')
97
+ end
98
+
99
+ alias_method(:on_attr_charref_hex, :on_attr_charref)
100
+
101
+ def on_stag_end(name)
102
+ tag_start(name, @attrs)
103
+ end
104
+
105
+ def on_stag_end_empty(name)
106
+ tag_start(name, @attrs)
107
+ tag_end(name)
108
+ end
109
+
110
+ private
111
+ def entity(ref)
112
+ ent = ENTITIES[ref]
113
+ if ent
114
+ ent
115
+ else
116
+ wellformed_error("undefined entity: #{ref}")
117
+ end
118
+ end
119
+ end
120
+
121
+ end