# RSS 3.0 Jokey but Useful Spec *created Aug 21, 2018 - updated Oct 23, 2018* From **2002** by Aaron Swartz * [The Road to RSS 3.0](http://www.aaronsw.com/weblog/000574) * [RSS 3.0 spec](http://www.aaronsw.com/2002/rss30) * [example RSS 3.0 file from 2003](http://www.patandkat.com/pat/weblog/rss3.txt) From Aaron's September 2002 post: > There’s been a lot of talk in the community about how RSS 2.0 is too complicated. I haven’t heard any objections, so I’m going to move ahead with the following changes that will result in RSS 3.0. > > 1. Remove XML. XML is just too complicated and is against the spirit of RSS, which is Really Simple Syndication. I don’t want people to have to buy one of these 200 page XML books to understand RSS. And XML sucks up bandwidth like nobody’s business. Instead, we’ll go back to [RFC822-style](https://www.w3.org/Protocols/rfc822/) fields. There are lots of available parsers for those. > > 2. Remove namespaces. Namespaces are just a waste of time. If people want to add an element to RSS, then just send it to me and I’ll add it to my list of all elements in use. This system is easy to use and doesn’t result in any wasteful URIs all over the place. > > 3. HTML forbidden. No one needs HTML. Email has been just fine for years before Microsoft introduce their stupid rich HTML extensions. HTML is for those loser newbies. Any intelligent Internet user deals in plain text. > > We also have a cool icon: ![rss3 logo](http://www.aaronsw.com/2002/rss30logo) From RFC822: > Once a field has been unfolded, it may be viewed as being composed of a field-name followed by a colon (":"), followed by a field-body, and terminated by a carriage-return/line-feed. The field-name must be composed of printable ASCII characters (i.e., characters that have values between 33. and 126., decimal, except colon). The field-body may be composed of any ASCII characters, except CR or LF. (While CR and/or LF may be present in the actual text, they are removed by the action of unfolding the field.) --- August 2018 IndieWeb chat: > 10:49 Zegnat The things you sometimes learn randomly: RSS 3.0 stopped being XML based. > > 10:57 [kevinmarks] That was a parody > > 10:58 [kevinmarks] RSS was at 0.92 or so, and the RDF fans did an iteration, made it RDF, and called it 1.0 > > 10:59 [kevinmarks] Dave Winer didn't like the RDF version, so did a few changes from 0.92 and called it 2.0 > > 11:00 [kevinmarks] Aaron Swartz then parodied Winer's post and made up RSS 3.0 as plaintext (which is ironically closer to json feed) > > 11:00 Zegnat Oh, I know. I had just never seen aaronsw’s RSS 3.0 reply to the whole thing ;) > > 11:01 Zegnat Very close to YAMLFeed > > 11:01 [kevinmarks] Feedparser has 3.0 support, because Mark Pilgrim knows how to overdo a joke > > 11:02 sknebel clearly YAMLfeed needs an update to be compatible with RSS 3.0 then > > 11:02 sknebel or a backcompat mode > > 11:03 Zegnat RSS 3.0 uses an empty line as item separator, it seems. I don’t think we can make that work with YAML parsers > > 11:05 Zegnat I was actually looking into the RSS spec to see if it had link-elements that could be used to advertise webmention endpoints. > > 11:05 Zegnat Didn’t mean to unleash RSS 3.0 on the world again :P --- YAMLFeed was proposed by some on IndieWeb users in 2017, also as a joke. > YAMLFeed is an attempt to ensure there is always a format war; since JSONFeed claims to be more readable, writable and easier to parse, than RSS, we present YAMLFeed: even more easier to read and write. Example YAMLFeed file: JSON Feed was released to the public in the spring of 2017, and it's not a joke. Several feed readers support consuming JSON Feed. --- What I like in a feed: * items * title or opening text of post * url or link to the post * date post was created JSON Feed spec for each item: { "content_text": "July 2018 Notes about Toledo Area Breweries", "url": "http://sora.soupmode.com/2018/07/13/july-2018-notes-about-toledo-area-breweries.html", "id": "http://sora.soupmode.com/2018/07/13/july-2018-notes-about-toledo-area-breweries.html", "date_published": "2018-07-19T12:49:49Z" }, RSS 3.0 spec for each item: title: July 2018 Notes about Toledo Area Breweries link: http://sora.soupmode.com/2018/07/13/july-2018-notes-about-toledo-area-breweries.html created: 2018-07-19T12:49:49Z YAMLFeed spec for each item: content: "July 2018 Notes about Toledo Area Breweries" published: 2018-07-19T12:49:49Z url: "http://sora.soupmode.com/2018/07/13/july-2018-notes-about-toledo-area-breweries.html" All three are easy to read for humans. JSON contains more punctuation marks, such as the curly braces, quotes, and commas. The jokey YAMLFeed contains a little more punctuation than the jokey RSS 3.0 spec. But the advantage of YAML is that probably all programming languages have YAML libraries ready to parse the format. local io = require "io" local lyaml = require "lyaml" local utils = require "utils" -- my module local filename = "/home/munger/yamlfeed/feed.yml" local f = assert(io.open(filename, "r")) local yaml_text = f:read("a") f:close() -- convert string to lua table local t = lyaml.load(yaml_text) utils.table_print(t) -- data dump --- Site info for me: * site title * site description * homepage link * feed link * author * name * email * link to about page RSS 3.0 spec: title: Vertical Hold description: Welcome to the Z-list. link: http://www.patandkat.com/pat/weblog/ language: en-us creator: pberry@piratehaven.org rights: Copyright 2003 Patrick Berry last-modified: 2003-10-09T21:01:39-08:00 generator: http://www.movabletype.org/?v=2.64 errorsto: pberry@piratehaven.org JSON Feed: "author": { "name": "Sora" }, "title": "Sora Test Site", "version": "https://jsonfeed.org/version/1", "feed_url": "http://sora.soupmode.com/feed.json", "description": "Static Site Generator Built with Lua", "home_page_url": "http://sora.soupmode.com" YAMLFeed: site: author: avatar: 'http://vanderven.se/martijn/martijn.jpg' email: martijn@vanderven.se name: 'Martijn van der Ven' url: 'http://vanderven.se/martijn/' title: 'Martijn’s feed' url: 'https://licit.li/' ### Parsing code samples Sample RSS3 file with a few items. title: Vertical Hold description: Welcome to the Z-list. link: http://www.patandkat.com/pat/weblog/ language: en-us creator: pberry@piratehaven.org rights: Copyright 2003 Patrick Berry last-modified: 2003-10-09T21:01:39-08:00 generator: http://www.movabletype.org/?v=2.64 errorsto: pberry@piratehaven.org title: Hillary Clinton on TDS link: http://www.patandkat.com/pat/weblog/archives/2003/10/09/003424.php#003424 description: Hillary Clinton Daily Show Quicktime clips are up thanks to Lisa Rein. subject: Politics date: 2003-10-09T21:01:39-08:00 title: Pre-emtive Excuses link: http://www.patandkat.com/pat/weblog/archives/2003/10/09/003423.php#003423 description: Arnold continues to try and lower expectations and prepare for the coming fight with the California State Legislature. Good luck Arnold. You'll need a double dose for sure. subject: Politics date: 2003-10-09T19:38:02-08:00 title: Welcome to "Your Wrong Night" link: http://www.patandkat.com/pat/weblog/archives/2003/10/09/003421.php#003421 description: Watch Fox News if you like being wrong all the time. subject: No Comment. date: 2003-10-09T08:59:33-08:00 Parsing the RSS3 file. local io = require "io" local rex = require "rex_pcre" function table_print (tt, indent, done) done = done or {} indent = indent or 0 if type(tt) == "table" then for key, value in pairs (tt) do io.write(string.rep (" ", indent)) -- indent it if type (value) == "table" and not done [value] then done [value] = true io.write(string.format("[%s] => table\n", tostring (key))); io.write(string.rep (" ", indent+4)) -- indent it io.write("(\n"); table_print (value, indent + 7, done) io.write(string.rep (" ", indent+4)) -- indent it io.write(")\n"); else io.write(string.format("[%s] => %s\n", tostring (key), tostring(value))) end end else io.write(tt .. "\n") end end function split(str, pat) local t = {} -- NOTE: use {n = 0} in Lua-5.0 local fpat = "(.-)" .. pat local last_end = 1 local s, e, cap = str:find(fpat, 1) while s do if s ~= 1 or cap ~= "" then table.insert(t,cap) end last_end = e+1 s, e, cap = str:find(fpat, last_end) end if last_end <= #str then cap = str:sub(last_end) table.insert(t, cap) end return t end ------------------------------- local filename = "/home/munger/rss3/rss3.txt" local f = assert(io.open(filename, "r")) local rss3_text = f:read("a") f:close() local blocks = split(rss3_text, "\n\n") local feed = {} local items_array = {} local site_hash = {} for i=1,#blocks do local tmp_hash = {} for n, v in rex.gmatch(blocks[i], "(\\w+): (.*)", "", nil) do tmp_hash[n] = v end if i > 1 then table.insert(items_array, tmp_hash) else feed.site = tmp_hash end end feed.items = items_array table_print(feed) --- Parse the YAML feed. local io = require "io" local lyaml = require "lyaml" function table_print (tt, indent, done) done = done or {} indent = indent or 0 if type(tt) == "table" then for key, value in pairs (tt) do io.write(string.rep (" ", indent)) -- indent it if type (value) == "table" and not done [value] then done [value] = true io.write(string.format("[%s] => table\n", tostring (key))); io.write(string.rep (" ", indent+4)) -- indent it io.write("(\n"); table_print (value, indent + 7, done) io.write(string.rep (" ", indent+4)) -- indent it io.write(")\n"); else io.write(string.format("[%s] => %s\n", tostring (key), tostring(value))) end end else io.write(tt .. "\n") end end ------------------------------- local filename = "/home/munger/yamlfeed/feed.yml" local f = assert(io.open(filename, "r")) local yaml_text = f:read("a") f:close() -- convert string to lua table local t = lyaml.load(yaml_text) table_print(t) ### My sample RSS3 file Based upon my Sora SSG app, written in Lua, and the JSON Feed file it produces. title: Sora Test Site description: Static Site Generator Built with Lua link: http://sora.soupmode.com language: en-us generator: Sora v1.0 creator: nick@adams.book Nick Adams created: 2018-10-18T15:35:04Z rights: Copyright 2018 Nick Adams uri: http://sora.soupmode.com/rss3.txt errorsto: nick@adams.book title: Test Code Blocks 2 link: http://sora.soupmode.com/test-code-blocks-2.html created: 2018-10-18T15:34:58Z title: Hurricane Michael Communications Status Report for October 17, 2018 link: http://sora.soupmode.com/2018/10/17/hurricane-michael-communications-status-report-for-october-17-2018.html created: 2018-10-18T14:20:22Z title: Web Article with a Modified Old-School Look link: http://sora.soupmode.com/2018/10/15/web-article-with-a-modified-oldschool-look.html created: 2018-10-15T17:20:04Z title: test post made on thu, oct 4, 2018 at 6:07 p.m. from my chromebook user lyn link: http://sora.soupmode.com/test-post-made-on-thu-oct-4-2018-at-6-07-pm-from-my-chromebook-user-lyn.html created: 2018-10-04T22:12:05Z title: Test Dark Theme link: http://sora.soupmode.com/test-dark-theme.html created: 2018-09-27T13:53:02Z [home](/home.md)