rubysl-rss 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,749 @@
1
+ require 'base64'
2
+ require 'rss/parser'
3
+
4
+ module RSS
5
+ module Atom
6
+ URI = "http://www.w3.org/2005/Atom"
7
+ XHTML_URI = "http://www.w3.org/1999/xhtml"
8
+
9
+ module CommonModel
10
+ NSPOOL = {}
11
+ ELEMENTS = []
12
+
13
+ def self.append_features(klass)
14
+ super
15
+ klass.install_must_call_validator("atom", URI)
16
+ [
17
+ ["lang", :xml],
18
+ ["base", :xml],
19
+ ].each do |name, uri, required|
20
+ klass.install_get_attribute(name, uri, required, [nil, :inherit])
21
+ end
22
+ klass.class_eval do
23
+ class << self
24
+ def required_uri
25
+ URI
26
+ end
27
+
28
+ def need_parent?
29
+ true
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ module ContentModel
37
+ module ClassMethods
38
+ def content_type
39
+ @content_type ||= nil
40
+ end
41
+ end
42
+
43
+ class << self
44
+ def append_features(klass)
45
+ super
46
+ klass.extend(ClassMethods)
47
+ klass.content_setup(klass.content_type, klass.tag_name)
48
+ end
49
+ end
50
+
51
+ def maker_target(target)
52
+ target
53
+ end
54
+
55
+ private
56
+ def setup_maker_element_writer
57
+ "#{self.class.name.split(/::/).last.downcase}="
58
+ end
59
+
60
+ def setup_maker_element(target)
61
+ target.__send__(setup_maker_element_writer, content)
62
+ super
63
+ end
64
+ end
65
+
66
+ module URIContentModel
67
+ class << self
68
+ def append_features(klass)
69
+ super
70
+ klass.class_eval do
71
+ @content_type = [nil, :uri]
72
+ include(ContentModel)
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ module TextConstruct
79
+ def self.append_features(klass)
80
+ super
81
+ klass.class_eval do
82
+ [
83
+ ["type", ""],
84
+ ].each do |name, uri, required|
85
+ install_get_attribute(name, uri, required, :text_type)
86
+ end
87
+
88
+ content_setup
89
+ add_need_initialize_variable("xhtml")
90
+
91
+ class << self
92
+ def xml_getter
93
+ "xhtml"
94
+ end
95
+
96
+ def xml_setter
97
+ "xhtml="
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ attr_writer :xhtml
104
+ def xhtml
105
+ return @xhtml if @xhtml.nil?
106
+ if @xhtml.is_a?(XML::Element) and
107
+ [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
108
+ return @xhtml
109
+ end
110
+
111
+ children = @xhtml
112
+ children = [children] unless children.is_a?(Array)
113
+ XML::Element.new("div", nil, XHTML_URI,
114
+ {"xmlns" => XHTML_URI}, children)
115
+ end
116
+
117
+ def have_xml_content?
118
+ @type == "xhtml"
119
+ end
120
+
121
+ def atom_validate(ignore_unknown_element, tags, uri)
122
+ if have_xml_content?
123
+ if @xhtml.nil?
124
+ raise MissingTagError.new("div", tag_name)
125
+ end
126
+ unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
127
+ raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name)
128
+ end
129
+ end
130
+ end
131
+
132
+ private
133
+ def maker_target(target)
134
+ target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}
135
+ end
136
+
137
+ def setup_maker_attributes(target)
138
+ target.type = type
139
+ target.content = content
140
+ target.xml_content = @xhtml
141
+ end
142
+ end
143
+
144
+ module PersonConstruct
145
+ def self.append_features(klass)
146
+ super
147
+ klass.class_eval do
148
+ [
149
+ ["name", nil],
150
+ ["uri", "?"],
151
+ ["email", "?"],
152
+ ].each do |tag, occurs|
153
+ install_have_attribute_element(tag, URI, occurs, nil, :content)
154
+ end
155
+ end
156
+ end
157
+
158
+ def maker_target(target)
159
+ target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
160
+ end
161
+
162
+ class Name < RSS::Element
163
+ include CommonModel
164
+ include ContentModel
165
+ end
166
+
167
+ class Uri < RSS::Element
168
+ include CommonModel
169
+ include URIContentModel
170
+ end
171
+
172
+ class Email < RSS::Element
173
+ include CommonModel
174
+ include ContentModel
175
+ end
176
+ end
177
+
178
+ module DateConstruct
179
+ def self.append_features(klass)
180
+ super
181
+ klass.class_eval do
182
+ @content_type = :w3cdtf
183
+ include(ContentModel)
184
+ end
185
+ end
186
+
187
+ def atom_validate(ignore_unknown_element, tags, uri)
188
+ raise NotAvailableValueError.new(tag_name, "") if content.nil?
189
+ end
190
+ end
191
+
192
+ module DuplicateLinkChecker
193
+ def validate_duplicate_links(links)
194
+ link_infos = {}
195
+ links.each do |link|
196
+ rel = link.rel || "alternate"
197
+ next unless rel == "alternate"
198
+ key = [link.hreflang, link.type]
199
+ if link_infos.has_key?(key)
200
+ raise TooMuchTagError.new("link", tag_name)
201
+ end
202
+ link_infos[key] = true
203
+ end
204
+ end
205
+ end
206
+
207
+ class Feed < RSS::Element
208
+ include RootElementMixin
209
+ include CommonModel
210
+ include DuplicateLinkChecker
211
+
212
+ install_ns('', URI)
213
+
214
+ [
215
+ ["author", "*", :children],
216
+ ["category", "*", :children, "categories"],
217
+ ["contributor", "*", :children],
218
+ ["generator", "?"],
219
+ ["icon", "?", nil, :content],
220
+ ["id", nil, nil, :content],
221
+ ["link", "*", :children],
222
+ ["logo", "?"],
223
+ ["rights", "?"],
224
+ ["subtitle", "?", nil, :content],
225
+ ["title", nil, nil, :content],
226
+ ["updated", nil, nil, :content],
227
+ ["entry", "*", :children, "entries"],
228
+ ].each do |tag, occurs, type, *args|
229
+ type ||= :child
230
+ __send__("install_have_#{type}_element",
231
+ tag, URI, occurs, tag, *args)
232
+ end
233
+
234
+ def initialize(version=nil, encoding=nil, standalone=nil)
235
+ super("1.0", version, encoding, standalone)
236
+ @feed_type = "atom"
237
+ @feed_subtype = "feed"
238
+ end
239
+
240
+ alias_method :items, :entries
241
+
242
+ def have_author?
243
+ authors.any? {|author| !author.to_s.empty?} or
244
+ entries.any? {|entry| entry.have_author?(false)}
245
+ end
246
+
247
+ private
248
+ def atom_validate(ignore_unknown_element, tags, uri)
249
+ unless have_author?
250
+ raise MissingTagError.new("author", tag_name)
251
+ end
252
+ validate_duplicate_links(links)
253
+ end
254
+
255
+ def have_required_elements?
256
+ super and have_author?
257
+ end
258
+
259
+ def maker_target(maker)
260
+ maker.channel
261
+ end
262
+
263
+ def setup_maker_element(channel)
264
+ prev_dc_dates = channel.dc_dates.to_a.dup
265
+ super
266
+ channel.about = id.content if id
267
+ channel.dc_dates.replace(prev_dc_dates)
268
+ end
269
+
270
+ def setup_maker_elements(channel)
271
+ super
272
+ items = channel.maker.items
273
+ entries.each do |entry|
274
+ entry.setup_maker(items)
275
+ end
276
+ end
277
+
278
+ class Author < RSS::Element
279
+ include CommonModel
280
+ include PersonConstruct
281
+ end
282
+
283
+ class Category < RSS::Element
284
+ include CommonModel
285
+
286
+ [
287
+ ["term", "", true],
288
+ ["scheme", "", false, [nil, :uri]],
289
+ ["label", ""],
290
+ ].each do |name, uri, required, type|
291
+ install_get_attribute(name, uri, required, type)
292
+ end
293
+
294
+ private
295
+ def maker_target(target)
296
+ target.new_category
297
+ end
298
+ end
299
+
300
+ class Contributor < RSS::Element
301
+ include CommonModel
302
+ include PersonConstruct
303
+ end
304
+
305
+ class Generator < RSS::Element
306
+ include CommonModel
307
+ include ContentModel
308
+
309
+ [
310
+ ["uri", "", false, [nil, :uri]],
311
+ ["version", ""],
312
+ ].each do |name, uri, required, type|
313
+ install_get_attribute(name, uri, required, type)
314
+ end
315
+
316
+ private
317
+ def setup_maker_attributes(target)
318
+ target.generator do |generator|
319
+ generator.uri = uri if uri
320
+ generator.version = version if version
321
+ end
322
+ end
323
+ end
324
+
325
+ class Icon < RSS::Element
326
+ include CommonModel
327
+ include URIContentModel
328
+ end
329
+
330
+ class Id < RSS::Element
331
+ include CommonModel
332
+ include URIContentModel
333
+ end
334
+
335
+ class Link < RSS::Element
336
+ include CommonModel
337
+
338
+ [
339
+ ["href", "", true, [nil, :uri]],
340
+ ["rel", ""],
341
+ ["type", ""],
342
+ ["hreflang", ""],
343
+ ["title", ""],
344
+ ["length", ""],
345
+ ].each do |name, uri, required, type|
346
+ install_get_attribute(name, uri, required, type)
347
+ end
348
+
349
+ private
350
+ def maker_target(target)
351
+ target.new_link
352
+ end
353
+ end
354
+
355
+ class Logo < RSS::Element
356
+ include CommonModel
357
+ include URIContentModel
358
+
359
+ def maker_target(target)
360
+ target.maker.image
361
+ end
362
+
363
+ private
364
+ def setup_maker_element_writer
365
+ "url="
366
+ end
367
+ end
368
+
369
+ class Rights < RSS::Element
370
+ include CommonModel
371
+ include TextConstruct
372
+ end
373
+
374
+ class Subtitle < RSS::Element
375
+ include CommonModel
376
+ include TextConstruct
377
+ end
378
+
379
+ class Title < RSS::Element
380
+ include CommonModel
381
+ include TextConstruct
382
+ end
383
+
384
+ class Updated < RSS::Element
385
+ include CommonModel
386
+ include DateConstruct
387
+ end
388
+
389
+ class Entry < RSS::Element
390
+ include CommonModel
391
+ include DuplicateLinkChecker
392
+
393
+ [
394
+ ["author", "*", :children],
395
+ ["category", "*", :children, "categories"],
396
+ ["content", "?", :child],
397
+ ["contributor", "*", :children],
398
+ ["id", nil, nil, :content],
399
+ ["link", "*", :children],
400
+ ["published", "?", :child, :content],
401
+ ["rights", "?", :child],
402
+ ["source", "?"],
403
+ ["summary", "?", :child],
404
+ ["title", nil],
405
+ ["updated", nil, :child, :content],
406
+ ].each do |tag, occurs, type, *args|
407
+ type ||= :attribute
408
+ __send__("install_have_#{type}_element",
409
+ tag, URI, occurs, tag, *args)
410
+ end
411
+
412
+ def have_author?(check_parent=true)
413
+ authors.any? {|author| !author.to_s.empty?} or
414
+ (check_parent and @parent and @parent.have_author?) or
415
+ (source and source.have_author?)
416
+ end
417
+
418
+ private
419
+ def atom_validate(ignore_unknown_element, tags, uri)
420
+ unless have_author?
421
+ raise MissingTagError.new("author", tag_name)
422
+ end
423
+ validate_duplicate_links(links)
424
+ end
425
+
426
+ def have_required_elements?
427
+ super and have_author?
428
+ end
429
+
430
+ def maker_target(items)
431
+ if items.respond_to?("items")
432
+ # For backward compatibility
433
+ items = items.items
434
+ end
435
+ items.new_item
436
+ end
437
+
438
+ Author = Feed::Author
439
+ Category = Feed::Category
440
+
441
+ class Content < RSS::Element
442
+ include CommonModel
443
+
444
+ class << self
445
+ def xml_setter
446
+ "xml="
447
+ end
448
+
449
+ def xml_getter
450
+ "xml"
451
+ end
452
+ end
453
+
454
+ [
455
+ ["type", ""],
456
+ ["src", "", false, [nil, :uri]],
457
+ ].each do |name, uri, required, type|
458
+ install_get_attribute(name, uri, required, type)
459
+ end
460
+
461
+ content_setup
462
+ add_need_initialize_variable("xml")
463
+
464
+ attr_writer :xml
465
+ def have_xml_content?
466
+ inline_xhtml? or inline_other_xml?
467
+ end
468
+
469
+ def xml
470
+ return @xml unless inline_xhtml?
471
+ return @xml if @xml.nil?
472
+ if @xml.is_a?(XML::Element) and
473
+ [@xml.name, @xml.uri] == ["div", XHTML_URI]
474
+ return @xml
475
+ end
476
+
477
+ children = @xml
478
+ children = [children] unless children.is_a?(Array)
479
+ XML::Element.new("div", nil, XHTML_URI,
480
+ {"xmlns" => XHTML_URI}, children)
481
+ end
482
+
483
+ def xhtml
484
+ if inline_xhtml?
485
+ xml
486
+ else
487
+ nil
488
+ end
489
+ end
490
+
491
+ def atom_validate(ignore_unknown_element, tags, uri)
492
+ if out_of_line?
493
+ raise MissingAttributeError.new(tag_name, "type") if @type.nil?
494
+ unless (content.nil? or content.empty?)
495
+ raise NotAvailableValueError.new(tag_name, content)
496
+ end
497
+ elsif inline_xhtml?
498
+ if @xml.nil?
499
+ raise MissingTagError.new("div", tag_name)
500
+ end
501
+ unless @xml.name == "div" and @xml.uri == XHTML_URI
502
+ raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name)
503
+ end
504
+ end
505
+ end
506
+
507
+ def inline_text?
508
+ !out_of_line? and [nil, "text", "html"].include?(@type)
509
+ end
510
+
511
+ def inline_html?
512
+ return false if out_of_line?
513
+ @type == "html" or mime_split == ["text", "html"]
514
+ end
515
+
516
+ def inline_xhtml?
517
+ !out_of_line? and @type == "xhtml"
518
+ end
519
+
520
+ def inline_other?
521
+ return false if out_of_line?
522
+ media_type, subtype = mime_split
523
+ return false if media_type.nil? or subtype.nil?
524
+ true
525
+ end
526
+
527
+ def inline_other_text?
528
+ return false unless inline_other?
529
+ return false if inline_other_xml?
530
+
531
+ media_type, subtype = mime_split
532
+ return true if "text" == media_type.downcase
533
+ false
534
+ end
535
+
536
+ def inline_other_xml?
537
+ return false unless inline_other?
538
+
539
+ media_type, subtype = mime_split
540
+ normalized_mime_type = "#{media_type}/#{subtype}".downcase
541
+ if /(?:\+xml|^xml)$/ =~ subtype or
542
+ %w(text/xml-external-parsed-entity
543
+ application/xml-external-parsed-entity
544
+ application/xml-dtd).find {|x| x == normalized_mime_type}
545
+ return true
546
+ end
547
+ false
548
+ end
549
+
550
+ def inline_other_base64?
551
+ inline_other? and !inline_other_text? and !inline_other_xml?
552
+ end
553
+
554
+ def out_of_line?
555
+ not @src.nil?
556
+ end
557
+
558
+ def mime_split
559
+ media_type = subtype = nil
560
+ if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/i =~ @type.to_s
561
+ media_type = $1.downcase
562
+ subtype = $2.downcase
563
+ end
564
+ [media_type, subtype]
565
+ end
566
+
567
+ def need_base64_encode?
568
+ inline_other_base64?
569
+ end
570
+
571
+ private
572
+ def empty_content?
573
+ out_of_line? or super
574
+ end
575
+ end
576
+
577
+ Contributor = Feed::Contributor
578
+ Id = Feed::Id
579
+ Link = Feed::Link
580
+
581
+ class Published < RSS::Element
582
+ include CommonModel
583
+ include DateConstruct
584
+ end
585
+
586
+ Rights = Feed::Rights
587
+
588
+ class Source < RSS::Element
589
+ include CommonModel
590
+
591
+ [
592
+ ["author", "*", :children],
593
+ ["category", "*", :children, "categories"],
594
+ ["contributor", "*", :children],
595
+ ["generator", "?"],
596
+ ["icon", "?"],
597
+ ["id", "?", nil, :content],
598
+ ["link", "*", :children],
599
+ ["logo", "?"],
600
+ ["rights", "?"],
601
+ ["subtitle", "?"],
602
+ ["title", "?"],
603
+ ["updated", "?", nil, :content],
604
+ ].each do |tag, occurs, type, *args|
605
+ type ||= :attribute
606
+ __send__("install_have_#{type}_element",
607
+ tag, URI, occurs, tag, *args)
608
+ end
609
+
610
+ def have_author?
611
+ !author.to_s.empty?
612
+ end
613
+
614
+ Author = Feed::Author
615
+ Category = Feed::Category
616
+ Contributor = Feed::Contributor
617
+ Generator = Feed::Generator
618
+ Icon = Feed::Icon
619
+ Id = Feed::Id
620
+ Link = Feed::Link
621
+ Logo = Feed::Logo
622
+ Rights = Feed::Rights
623
+ Subtitle = Feed::Subtitle
624
+ Title = Feed::Title
625
+ Updated = Feed::Updated
626
+ end
627
+
628
+ class Summary < RSS::Element
629
+ include CommonModel
630
+ include TextConstruct
631
+ end
632
+
633
+ Title = Feed::Title
634
+ Updated = Feed::Updated
635
+ end
636
+ end
637
+
638
+ class Entry < RSS::Element
639
+ include RootElementMixin
640
+ include CommonModel
641
+ include DuplicateLinkChecker
642
+
643
+ [
644
+ ["author", "*", :children],
645
+ ["category", "*", :children, "categories"],
646
+ ["content", "?"],
647
+ ["contributor", "*", :children],
648
+ ["id", nil, nil, :content],
649
+ ["link", "*", :children],
650
+ ["published", "?", :child, :content],
651
+ ["rights", "?"],
652
+ ["source", "?"],
653
+ ["summary", "?"],
654
+ ["title", nil],
655
+ ["updated", nil, nil, :content],
656
+ ].each do |tag, occurs, type, *args|
657
+ type ||= :attribute
658
+ __send__("install_have_#{type}_element",
659
+ tag, URI, occurs, tag, *args)
660
+ end
661
+
662
+ def initialize(version=nil, encoding=nil, standalone=nil)
663
+ super("1.0", version, encoding, standalone)
664
+ @feed_type = "atom"
665
+ @feed_subtype = "entry"
666
+ end
667
+
668
+ def items
669
+ [self]
670
+ end
671
+
672
+ def setup_maker(maker)
673
+ maker = maker.maker if maker.respond_to?("maker")
674
+ super(maker)
675
+ end
676
+
677
+ def have_author?
678
+ authors.any? {|author| !author.to_s.empty?} or
679
+ (source and source.have_author?)
680
+ end
681
+
682
+ private
683
+ def atom_validate(ignore_unknown_element, tags, uri)
684
+ unless have_author?
685
+ raise MissingTagError.new("author", tag_name)
686
+ end
687
+ validate_duplicate_links(links)
688
+ end
689
+
690
+ def have_required_elements?
691
+ super and have_author?
692
+ end
693
+
694
+ def maker_target(maker)
695
+ maker.items.new_item
696
+ end
697
+
698
+ Author = Feed::Entry::Author
699
+ Category = Feed::Entry::Category
700
+ Content = Feed::Entry::Content
701
+ Contributor = Feed::Entry::Contributor
702
+ Id = Feed::Entry::Id
703
+ Link = Feed::Entry::Link
704
+ Published = Feed::Entry::Published
705
+ Rights = Feed::Entry::Rights
706
+ Source = Feed::Entry::Source
707
+ Summary = Feed::Entry::Summary
708
+ Title = Feed::Entry::Title
709
+ Updated = Feed::Entry::Updated
710
+ end
711
+ end
712
+
713
+ Atom::CommonModel::ELEMENTS.each do |name|
714
+ BaseListener.install_get_text_element(Atom::URI, name, "#{name}=")
715
+ end
716
+
717
+ module ListenerMixin
718
+ private
719
+ def initial_start_feed(tag_name, prefix, attrs, ns)
720
+ check_ns(tag_name, prefix, ns, Atom::URI)
721
+
722
+ @rss = Atom::Feed.new(@version, @encoding, @standalone)
723
+ @rss.do_validate = @do_validate
724
+ @rss.xml_stylesheets = @xml_stylesheets
725
+ @rss.lang = attrs["xml:lang"]
726
+ @rss.base = attrs["xml:base"]
727
+ @last_element = @rss
728
+ pr = Proc.new do |text, tags|
729
+ @rss.validate_for_stream(tags) if @do_validate
730
+ end
731
+ @proc_stack.push(pr)
732
+ end
733
+
734
+ def initial_start_entry(tag_name, prefix, attrs, ns)
735
+ check_ns(tag_name, prefix, ns, Atom::URI)
736
+
737
+ @rss = Atom::Entry.new(@version, @encoding, @standalone)
738
+ @rss.do_validate = @do_validate
739
+ @rss.xml_stylesheets = @xml_stylesheets
740
+ @rss.lang = attrs["xml:lang"]
741
+ @rss.base = attrs["xml:base"]
742
+ @last_element = @rss
743
+ pr = Proc.new do |text, tags|
744
+ @rss.validate_for_stream(tags) if @do_validate
745
+ end
746
+ @proc_stack.push(pr)
747
+ end
748
+ end
749
+ end