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,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