rss 0.2.7

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 (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +88 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/lib/rss.rb +92 -0
  11. data/lib/rss/0.9.rb +462 -0
  12. data/lib/rss/1.0.rb +485 -0
  13. data/lib/rss/2.0.rb +143 -0
  14. data/lib/rss/atom.rb +1025 -0
  15. data/lib/rss/content.rb +34 -0
  16. data/lib/rss/content/1.0.rb +10 -0
  17. data/lib/rss/content/2.0.rb +12 -0
  18. data/lib/rss/converter.rb +171 -0
  19. data/lib/rss/dublincore.rb +164 -0
  20. data/lib/rss/dublincore/1.0.rb +13 -0
  21. data/lib/rss/dublincore/2.0.rb +13 -0
  22. data/lib/rss/dublincore/atom.rb +17 -0
  23. data/lib/rss/image.rb +198 -0
  24. data/lib/rss/itunes.rb +413 -0
  25. data/lib/rss/maker.rb +79 -0
  26. data/lib/rss/maker/0.9.rb +509 -0
  27. data/lib/rss/maker/1.0.rb +436 -0
  28. data/lib/rss/maker/2.0.rb +224 -0
  29. data/lib/rss/maker/atom.rb +173 -0
  30. data/lib/rss/maker/base.rb +945 -0
  31. data/lib/rss/maker/content.rb +22 -0
  32. data/lib/rss/maker/dublincore.rb +122 -0
  33. data/lib/rss/maker/entry.rb +164 -0
  34. data/lib/rss/maker/feed.rb +427 -0
  35. data/lib/rss/maker/image.rb +112 -0
  36. data/lib/rss/maker/itunes.rb +243 -0
  37. data/lib/rss/maker/slash.rb +34 -0
  38. data/lib/rss/maker/syndication.rb +19 -0
  39. data/lib/rss/maker/taxonomy.rb +119 -0
  40. data/lib/rss/maker/trackback.rb +62 -0
  41. data/lib/rss/parser.rb +589 -0
  42. data/lib/rss/rexmlparser.rb +50 -0
  43. data/lib/rss/rss.rb +1346 -0
  44. data/lib/rss/slash.rb +52 -0
  45. data/lib/rss/syndication.rb +69 -0
  46. data/lib/rss/taxonomy.rb +148 -0
  47. data/lib/rss/trackback.rb +291 -0
  48. data/lib/rss/utils.rb +200 -0
  49. data/lib/rss/xml-stylesheet.rb +106 -0
  50. data/lib/rss/xml.rb +72 -0
  51. data/lib/rss/xmlparser.rb +95 -0
  52. data/lib/rss/xmlscanner.rb +122 -0
  53. data/rss.gemspec +38 -0
  54. metadata +138 -0
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: false
2
+ require_relative '../content'
3
+ require_relative '1.0'
4
+ require_relative '2.0'
5
+
6
+ module RSS
7
+ module Maker
8
+ module ContentModel
9
+ def self.append_features(klass)
10
+ super
11
+
12
+ ::RSS::ContentModel::ELEMENTS.each do |name|
13
+ klass.def_other_element(name)
14
+ end
15
+ end
16
+ end
17
+
18
+ class ItemsBase
19
+ class ItemBase; include ContentModel; end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: false
2
+ require_relative '../dublincore'
3
+ require_relative '1.0'
4
+
5
+ module RSS
6
+ module Maker
7
+ module DublinCoreModel
8
+ def self.append_features(klass)
9
+ super
10
+
11
+ ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
12
+ plural_name ||= "#{name}s"
13
+ full_name = "#{RSS::DC_PREFIX}_#{name}"
14
+ full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}"
15
+ plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
16
+ klass.def_classed_elements(full_name, "value", plural_klass_name,
17
+ full_plural_name, name)
18
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
19
+ def new_#{full_name}(value=nil)
20
+ _#{full_name} = #{full_plural_name}.new_#{name}
21
+ _#{full_name}.value = value
22
+ if block_given?
23
+ yield _#{full_name}
24
+ else
25
+ _#{full_name}
26
+ end
27
+ end
28
+ EOC
29
+ end
30
+
31
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
32
+ # For backward compatibility
33
+ alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
34
+ EOC
35
+ end
36
+
37
+ ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
38
+ plural_name ||= "#{name}s"
39
+ full_name ||= "#{DC_PREFIX}_#{name}"
40
+ full_plural_name ||= "#{DC_PREFIX}_#{plural_name}"
41
+ klass_name = Utils.to_class_name(name)
42
+ full_klass_name = "DublinCore#{klass_name}"
43
+ plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
44
+ module_eval(<<-EOC, __FILE__, __LINE__ + 1)
45
+ class #{plural_klass_name}Base < Base
46
+ def_array_element(#{name.dump}, #{full_plural_name.dump},
47
+ #{full_klass_name.dump})
48
+
49
+ class #{full_klass_name}Base < Base
50
+ attr_accessor :value
51
+ add_need_initialize_variable("value")
52
+ alias_method(:content, :value)
53
+ alias_method(:content=, :value=)
54
+
55
+ def have_required_values?
56
+ @value
57
+ end
58
+
59
+ def to_feed(feed, current)
60
+ if value and current.respond_to?(:#{full_name})
61
+ new_item = current.class::#{full_klass_name}.new(value)
62
+ current.#{full_plural_name} << new_item
63
+ end
64
+ end
65
+ end
66
+ #{klass_name}Base = #{full_klass_name}Base
67
+ end
68
+ EOC
69
+ end
70
+
71
+ def self.install_dublin_core(klass)
72
+ ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
73
+ plural_name ||= "#{name}s"
74
+ klass_name = Utils.to_class_name(name)
75
+ full_klass_name = "DublinCore#{klass_name}"
76
+ plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
77
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
78
+ class #{plural_klass_name} < #{plural_klass_name}Base
79
+ class #{full_klass_name} < #{full_klass_name}Base
80
+ end
81
+ #{klass_name} = #{full_klass_name}
82
+ end
83
+ EOC
84
+ end
85
+ end
86
+ end
87
+
88
+ class ChannelBase
89
+ include DublinCoreModel
90
+ end
91
+
92
+ class ImageBase; include DublinCoreModel; end
93
+ class ItemsBase
94
+ class ItemBase
95
+ include DublinCoreModel
96
+ end
97
+ end
98
+ class TextinputBase; include DublinCoreModel; end
99
+
100
+ makers.each do |maker|
101
+ maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
102
+ class Channel
103
+ DublinCoreModel.install_dublin_core(self)
104
+ end
105
+
106
+ class Image
107
+ DublinCoreModel.install_dublin_core(self)
108
+ end
109
+
110
+ class Items
111
+ class Item
112
+ DublinCoreModel.install_dublin_core(self)
113
+ end
114
+ end
115
+
116
+ class Textinput
117
+ DublinCoreModel.install_dublin_core(self)
118
+ end
119
+ EOC
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: false
2
+ require_relative "atom"
3
+ require_relative "feed"
4
+
5
+ module RSS
6
+ module Maker
7
+ module Atom
8
+ class Entry < RSSBase
9
+ def initialize(feed_version="1.0")
10
+ super
11
+ @feed_type = "atom"
12
+ @feed_subtype = "entry"
13
+ end
14
+
15
+ private
16
+ def make_feed
17
+ ::RSS::Atom::Entry.new(@version, @encoding, @standalone)
18
+ end
19
+
20
+ def setup_elements(entry)
21
+ setup_items(entry)
22
+ end
23
+
24
+ class Channel < ChannelBase
25
+ class SkipDays < SkipDaysBase
26
+ class Day < DayBase
27
+ end
28
+ end
29
+
30
+ class SkipHours < SkipHoursBase
31
+ class Hour < HourBase
32
+ end
33
+ end
34
+
35
+ class Cloud < CloudBase
36
+ end
37
+
38
+ Categories = Feed::Channel::Categories
39
+ Links = Feed::Channel::Links
40
+ Authors = Feed::Channel::Authors
41
+ Contributors = Feed::Channel::Contributors
42
+
43
+ class Generator < GeneratorBase
44
+ include AtomGenerator
45
+
46
+ def self.not_set_name
47
+ "maker.channel.generator"
48
+ end
49
+ end
50
+
51
+ Copyright = Feed::Channel::Copyright
52
+
53
+ class Description < DescriptionBase
54
+ end
55
+
56
+ Title = Feed::Channel::Title
57
+ end
58
+
59
+ class Image < ImageBase
60
+ end
61
+
62
+ class Items < ItemsBase
63
+ def to_feed(entry)
64
+ (normalize.first || Item.new(@maker)).to_feed(entry)
65
+ end
66
+
67
+ class Item < ItemBase
68
+ def to_feed(entry)
69
+ set_default_values do
70
+ setup_values(entry)
71
+ entry.dc_dates.clear
72
+ setup_other_elements(entry)
73
+ unless have_required_values?
74
+ raise NotSetError.new("maker.item", not_set_required_variables)
75
+ end
76
+ end
77
+ end
78
+
79
+ private
80
+ def required_variable_names
81
+ %w(id updated)
82
+ end
83
+
84
+ def variables
85
+ super + ["updated"]
86
+ end
87
+
88
+ def variable_is_set?
89
+ super or !authors.empty?
90
+ end
91
+
92
+ def not_set_required_variables
93
+ set_default_values do
94
+ vars = super
95
+ if authors.all? {|author| !author.have_required_values?}
96
+ vars << "author"
97
+ end
98
+ vars << "title" unless title {|t| t.have_required_values?}
99
+ vars
100
+ end
101
+ end
102
+
103
+ def _set_default_values
104
+ keep = {
105
+ :authors => authors.to_a.dup,
106
+ :contributors => contributors.to_a.dup,
107
+ :categories => categories.to_a.dup,
108
+ :id => id,
109
+ :links => links.to_a.dup,
110
+ :rights => @rights,
111
+ :title => @title,
112
+ :updated => updated,
113
+ }
114
+ authors.replace(@maker.channel.authors) if keep[:authors].empty?
115
+ if keep[:contributors].empty?
116
+ contributors.replace(@maker.channel.contributors)
117
+ end
118
+ if keep[:categories].empty?
119
+ categories.replace(@maker.channel.categories)
120
+ end
121
+ self.id ||= link || @maker.channel.id
122
+ links.replace(@maker.channel.links) if keep[:links].empty?
123
+ unless keep[:rights].variable_is_set?
124
+ @maker.channel.rights {|r| @rights = r}
125
+ end
126
+ unless keep[:title].variable_is_set?
127
+ @maker.channel.title {|t| @title = t}
128
+ end
129
+ self.updated ||= @maker.channel.updated
130
+ super
131
+ ensure
132
+ authors.replace(keep[:authors])
133
+ contributors.replace(keep[:contributors])
134
+ categories.replace(keep[:categories])
135
+ links.replace(keep[:links])
136
+ self.id = keep[:id]
137
+ @rights = keep[:rights]
138
+ @title = keep[:title]
139
+ self.updated = keep[:updated]
140
+ end
141
+
142
+ Guid = Feed::Items::Item::Guid
143
+ Enclosure = Feed::Items::Item::Enclosure
144
+ Source = Feed::Items::Item::Source
145
+ Categories = Feed::Items::Item::Categories
146
+ Authors = Feed::Items::Item::Authors
147
+ Contributors = Feed::Items::Item::Contributors
148
+ Links = Feed::Items::Item::Links
149
+ Rights = Feed::Items::Item::Rights
150
+ Description = Feed::Items::Item::Description
151
+ Title = Feed::Items::Item::Title
152
+ Content = Feed::Items::Item::Content
153
+ end
154
+ end
155
+
156
+ class Textinput < TextinputBase
157
+ end
158
+ end
159
+ end
160
+
161
+ add_maker("atom:entry", "1.0", Atom::Entry)
162
+ add_maker("atom1.0:entry", "1.0", Atom::Entry)
163
+ end
164
+ end
@@ -0,0 +1,427 @@
1
+ # frozen_string_literal: false
2
+ require_relative "atom"
3
+
4
+ module RSS
5
+ module Maker
6
+ module Atom
7
+ class Feed < RSSBase
8
+ def initialize(feed_version="1.0")
9
+ super
10
+ @feed_type = "atom"
11
+ @feed_subtype = "feed"
12
+ end
13
+
14
+ private
15
+ def make_feed
16
+ ::RSS::Atom::Feed.new(@version, @encoding, @standalone)
17
+ end
18
+
19
+ def setup_elements(feed)
20
+ setup_channel(feed)
21
+ setup_image(feed)
22
+ setup_items(feed)
23
+ end
24
+
25
+ class Channel < ChannelBase
26
+ include SetupDefaultLanguage
27
+
28
+ def to_feed(feed)
29
+ set_default_values do
30
+ setup_values(feed)
31
+ feed.dc_dates.clear
32
+ setup_other_elements(feed)
33
+ if image_favicon.about
34
+ icon = feed.class::Icon.new
35
+ icon.content = image_favicon.about
36
+ feed.icon = icon
37
+ end
38
+ unless have_required_values?
39
+ raise NotSetError.new("maker.channel",
40
+ not_set_required_variables)
41
+ end
42
+ end
43
+ end
44
+
45
+ def have_required_values?
46
+ super and
47
+ (!authors.empty? or
48
+ @maker.items.any? {|item| !item.authors.empty?})
49
+ end
50
+
51
+ private
52
+ def required_variable_names
53
+ %w(id updated)
54
+ end
55
+
56
+ def variables
57
+ super + %w(id updated)
58
+ end
59
+
60
+ def variable_is_set?
61
+ super or !authors.empty?
62
+ end
63
+
64
+ def not_set_required_variables
65
+ vars = super
66
+ if authors.empty? and
67
+ @maker.items.all? {|item| item.author.to_s.empty?}
68
+ vars << "author"
69
+ end
70
+ vars << "title" unless title {|t| t.have_required_values?}
71
+ vars
72
+ end
73
+
74
+ def _set_default_values(&block)
75
+ keep = {
76
+ :id => id,
77
+ }
78
+ self.id ||= about
79
+ super(&block)
80
+ ensure
81
+ self.id = keep[:id]
82
+ end
83
+
84
+ class SkipDays < SkipDaysBase
85
+ def to_feed(*args)
86
+ end
87
+
88
+ class Day < DayBase
89
+ end
90
+ end
91
+
92
+ class SkipHours < SkipHoursBase
93
+ def to_feed(*args)
94
+ end
95
+
96
+ class Hour < HourBase
97
+ end
98
+ end
99
+
100
+ class Cloud < CloudBase
101
+ def to_feed(*args)
102
+ end
103
+ end
104
+
105
+ class Categories < CategoriesBase
106
+ class Category < CategoryBase
107
+ include AtomCategory
108
+
109
+ def self.not_set_name
110
+ "maker.channel.category"
111
+ end
112
+ end
113
+ end
114
+
115
+ class Links < LinksBase
116
+ class Link < LinkBase
117
+ include AtomLink
118
+
119
+ def self.not_set_name
120
+ "maker.channel.link"
121
+ end
122
+ end
123
+ end
124
+
125
+ AtomPersons.def_atom_persons(self, "author", "maker.channel.author")
126
+ AtomPersons.def_atom_persons(self, "contributor",
127
+ "maker.channel.contributor")
128
+
129
+ class Generator < GeneratorBase
130
+ include AtomGenerator
131
+
132
+ def self.not_set_name
133
+ "maker.channel.generator"
134
+ end
135
+ end
136
+
137
+ AtomTextConstruct.def_atom_text_construct(self, "rights",
138
+ "maker.channel.copyright",
139
+ "Copyright")
140
+ AtomTextConstruct.def_atom_text_construct(self, "subtitle",
141
+ "maker.channel.description",
142
+ "Description")
143
+ AtomTextConstruct.def_atom_text_construct(self, "title",
144
+ "maker.channel.title")
145
+ end
146
+
147
+ class Image < ImageBase
148
+ def to_feed(feed)
149
+ logo = feed.class::Logo.new
150
+ class << logo
151
+ alias_method(:url=, :content=)
152
+ end
153
+ set = setup_values(logo)
154
+ class << logo
155
+ remove_method(:url=)
156
+ end
157
+ if set
158
+ feed.logo = logo
159
+ set_parent(logo, feed)
160
+ setup_other_elements(feed, logo)
161
+ elsif variable_is_set?
162
+ raise NotSetError.new("maker.image", not_set_required_variables)
163
+ end
164
+ end
165
+
166
+ private
167
+ def required_variable_names
168
+ %w(url)
169
+ end
170
+ end
171
+
172
+ class Items < ItemsBase
173
+ def to_feed(feed)
174
+ normalize.each do |item|
175
+ item.to_feed(feed)
176
+ end
177
+ setup_other_elements(feed, feed.entries)
178
+ end
179
+
180
+ class Item < ItemBase
181
+ def to_feed(feed)
182
+ set_default_values do
183
+ entry = feed.class::Entry.new
184
+ set = setup_values(entry)
185
+ entry.dc_dates.clear
186
+ setup_other_elements(feed, entry)
187
+ if set
188
+ feed.entries << entry
189
+ set_parent(entry, feed)
190
+ elsif variable_is_set?
191
+ raise NotSetError.new("maker.item", not_set_required_variables)
192
+ end
193
+ end
194
+ end
195
+
196
+ def have_required_values?
197
+ set_default_values do
198
+ super and title {|t| t.have_required_values?}
199
+ end
200
+ end
201
+
202
+ private
203
+ def required_variable_names
204
+ %w(id updated)
205
+ end
206
+
207
+ def variables
208
+ super + ["updated"]
209
+ end
210
+
211
+ def not_set_required_variables
212
+ vars = super
213
+ vars << "title" unless title {|t| t.have_required_values?}
214
+ vars
215
+ end
216
+
217
+ def _set_default_values(&block)
218
+ keep = {
219
+ :id => id,
220
+ }
221
+ self.id ||= link
222
+ super(&block)
223
+ ensure
224
+ self.id = keep[:id]
225
+ end
226
+
227
+ class Guid < GuidBase
228
+ def to_feed(feed, current)
229
+ end
230
+ end
231
+
232
+ class Enclosure < EnclosureBase
233
+ def to_feed(feed, current)
234
+ end
235
+ end
236
+
237
+ class Source < SourceBase
238
+ def to_feed(feed, current)
239
+ source = current.class::Source.new
240
+ setup_values(source)
241
+ current.source = source
242
+ set_parent(source, current)
243
+ setup_other_elements(feed, source)
244
+ current.source = nil if source.to_s == "<source/>"
245
+ end
246
+
247
+ private
248
+ def required_variable_names
249
+ []
250
+ end
251
+
252
+ def variables
253
+ super + ["updated"]
254
+ end
255
+
256
+ AtomPersons.def_atom_persons(self, "author",
257
+ "maker.item.source.author")
258
+ AtomPersons.def_atom_persons(self, "contributor",
259
+ "maker.item.source.contributor")
260
+
261
+ class Categories < CategoriesBase
262
+ class Category < CategoryBase
263
+ include AtomCategory
264
+
265
+ def self.not_set_name
266
+ "maker.item.source.category"
267
+ end
268
+ end
269
+ end
270
+
271
+ class Generator < GeneratorBase
272
+ include AtomGenerator
273
+
274
+ def self.not_set_name
275
+ "maker.item.source.generator"
276
+ end
277
+ end
278
+
279
+ class Icon < IconBase
280
+ def to_feed(feed, current)
281
+ icon = current.class::Icon.new
282
+ class << icon
283
+ alias_method(:url=, :content=)
284
+ end
285
+ set = setup_values(icon)
286
+ class << icon
287
+ remove_method(:url=)
288
+ end
289
+ if set
290
+ current.icon = icon
291
+ set_parent(icon, current)
292
+ setup_other_elements(feed, icon)
293
+ elsif variable_is_set?
294
+ raise NotSetError.new("maker.item.source.icon",
295
+ not_set_required_variables)
296
+ end
297
+ end
298
+
299
+ private
300
+ def required_variable_names
301
+ %w(url)
302
+ end
303
+ end
304
+
305
+ class Links < LinksBase
306
+ class Link < LinkBase
307
+ include AtomLink
308
+
309
+ def self.not_set_name
310
+ "maker.item.source.link"
311
+ end
312
+ end
313
+ end
314
+
315
+ class Logo < LogoBase
316
+ include AtomLogo
317
+
318
+ def self.not_set_name
319
+ "maker.item.source.logo"
320
+ end
321
+ end
322
+
323
+ maker_name_base = "maker.item.source."
324
+ maker_name = "#{maker_name_base}rights"
325
+ AtomTextConstruct.def_atom_text_construct(self, "rights",
326
+ maker_name)
327
+ maker_name = "#{maker_name_base}subtitle"
328
+ AtomTextConstruct.def_atom_text_construct(self, "subtitle",
329
+ maker_name)
330
+ maker_name = "#{maker_name_base}title"
331
+ AtomTextConstruct.def_atom_text_construct(self, "title",
332
+ maker_name)
333
+ end
334
+
335
+ class Categories < CategoriesBase
336
+ class Category < CategoryBase
337
+ include AtomCategory
338
+
339
+ def self.not_set_name
340
+ "maker.item.category"
341
+ end
342
+ end
343
+ end
344
+
345
+ AtomPersons.def_atom_persons(self, "author", "maker.item.author")
346
+ AtomPersons.def_atom_persons(self, "contributor",
347
+ "maker.item.contributor")
348
+
349
+ class Links < LinksBase
350
+ class Link < LinkBase
351
+ include AtomLink
352
+
353
+ def self.not_set_name
354
+ "maker.item.link"
355
+ end
356
+ end
357
+ end
358
+
359
+ AtomTextConstruct.def_atom_text_construct(self, "rights",
360
+ "maker.item.rights")
361
+ AtomTextConstruct.def_atom_text_construct(self, "summary",
362
+ "maker.item.description",
363
+ "Description")
364
+ AtomTextConstruct.def_atom_text_construct(self, "title",
365
+ "maker.item.title")
366
+
367
+ class Content < ContentBase
368
+ def to_feed(feed, current)
369
+ content = current.class::Content.new
370
+ if setup_values(content)
371
+ content.src = nil if content.src and content.content
372
+ current.content = content
373
+ set_parent(content, current)
374
+ setup_other_elements(feed, content)
375
+ elsif variable_is_set?
376
+ raise NotSetError.new("maker.item.content",
377
+ not_set_required_variables)
378
+ end
379
+ end
380
+
381
+ alias_method(:xml, :xml_content)
382
+
383
+ private
384
+ def required_variable_names
385
+ if out_of_line?
386
+ %w(type)
387
+ elsif xml_type?
388
+ %w(xml_content)
389
+ else
390
+ %w(content)
391
+ end
392
+ end
393
+
394
+ def variables
395
+ if out_of_line?
396
+ super
397
+ elsif xml_type?
398
+ super + %w(xml)
399
+ else
400
+ super
401
+ end
402
+ end
403
+
404
+ def xml_type?
405
+ _type = type
406
+ return false if _type.nil?
407
+ _type == "xhtml" or
408
+ /(?:\+xml|\/xml)$/i =~ _type or
409
+ %w(text/xml-external-parsed-entity
410
+ application/xml-external-parsed-entity
411
+ application/xml-dtd).include?(_type.downcase)
412
+ end
413
+ end
414
+ end
415
+ end
416
+
417
+ class Textinput < TextinputBase
418
+ end
419
+ end
420
+ end
421
+
422
+ add_maker("atom", "1.0", Atom::Feed)
423
+ add_maker("atom:feed", "1.0", Atom::Feed)
424
+ add_maker("atom1.0", "1.0", Atom::Feed)
425
+ add_maker("atom1.0:feed", "1.0", Atom::Feed)
426
+ end
427
+ end