RSS 3.0 Jokey but Useful Spec

created Aug 21, 2018 - updated Oct 23, 2018

From 2002 by Aaron Swartz

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

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: https://chat.indieweb.org/2018-08-19

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 montag4511 joined the channel

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.

https://indieweb.org/YAMLFeed

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: https://licit.li/feed.yaml

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.

https://jsonfeed.org


What I like in a feed:

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:

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.

http://sora.soupmode.com/feed.json

http://sora.soupmode.com/rss3.txt

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 - info - search - #