2 def html; CGI.unescapeHTML self end
3 def cdata; sub /^\s*<\!\[CDATA\[(.*?)\]\]>\s*$/m,'\1'end
4 def guess; send (case self
17 match(/<(rdf|rss|feed)([^>]+)/i)[2].scan(/xmlns:?([a-z]+)?=["']?([^'">\s]+)/){|m|x[m[0]]=m[1]}
20 scan(%r{<(rss:|atom:)?(item|entry)([\s][^>]*)?>(.*?)</\1?\2>}mi){|m|
23 u = m[2] && (u=m[2].match /about=["']?([^'">\s]+)/) && u[1] ||
24 m[3] && (((u=m[3].match /<(gu)?id[^>]*>([^<]+)/) || (u=m[3].match /<(link)>([^<]+)/)) && u[2])
25 yield u,E::Type,(E::SIOC+'Post').E
27 u.split(/:\/*/,2)[-1].split(/[\/\-,]/)[0].do{|s|
29 yield u,E::SIOC+'name',s.split('.')[-2]}
32 m[3].scan(%r{<(link|enclosure|media)([^>]+)>}mi){|e|
34 E::Atom+'/link/'+((r=e[1].match(/rel=['"]?([^'">\s]+)/)) ? r[1] : e[0]), # p
35 e[1].match(/(href|url|src)=['"]?([^'">\s]+)/)[2].E)} # o
38 m[3].scan(%r{<([a-z]+:)?([a-z]+)([\s][^>]*)?>(.*?)</\1?\2>}mi){|e|
40 (x[e[0]&&e[0].chop]||E::RSS)+e[1], # p
41 e[3].extend(FeedParse).guess}} # o
48 Feed = (E RSS+'channel')
51 def feedList; (E Type).po Feed end
52 def feeds; feedList.map &:getFeed end
55 def feeds; (nokogiri.css 'link[rel=alternate]').map{|u|E u.attr :href} end
56 def addFeed; self[Type] = Feed end
57 def delFeed; self[Type,Feed,''] end
58 def getFeed; addJSON :feed,[Date,To] end
62 dateNorm :feedSIOCize,:feedRaw,&f
70 read.extend(FeedParse).parse &f
73 # tripleStream -> tripleStream
77 { Purl+'dc/elements/1.1/creator' => Creator,
78 Purl+'dc/elements/1.1/subject' => SIOC+'subject',
79 Atom+'author' => Creator,
80 RSS+'description' => Content,
81 RSS+'encoded' => Content,
82 RSSm+'content/encoded' => Content,
83 Atom+'content' => Content,
85 Atom+'title' => Title,