Fractal Feeds

There was an article on The Daily WTF blog recently, about a guy that created an ASCII art⁠1 rendering of the Mandelbrot set using nothing more than XSLT. My first thought, on reading that, was whether I could do something similar using an XML DTD; and instead of HTML, using an RSS or Atom feed as the final output.

Expanding Entities

Unfortunately, an XML DTD doesn’t even come close to being a real programming language, which makes things a little more difficult. You can do basic macro expansions, but that’s about it. However, for a simple fractal – say a Sierpinski triangle – that’s all we really need.

The general idea is too look for repeating patterns (a common occurrence in fractals), and replace those patterns with XML entities that can be reused. It’s not quite the same as programmatically generating the image, but it’s still more efficient than an uncompressed stream of pixels.

A Sierpinski triangle

Building Bitmaps

To make things a little more interesting, I figured I should also try and render the output as a bitmapped image, rather than simple ASCII art. In Atom feeds, binary content can be included directly inside an entry using base64 encoding – something that can easily be generated in a DTD.

If we choose a 24-bit Windows BMP as our target image format, each three-byte pixel is represented as a four-character base64 sequence. All that remains is for us to add a static string of characters on the front for the bitmap header (which is, fortunately, also a multiple of three bytes).

Although RSS doesn’t directly support binary content in a feed entry, we can achieve the same thing using a data URL as the src of a regular HTML img element. In the data URL scheme, the binary content is also base64 encoded,⁠2 so the process is essentially the same as with Atom.

Final Feeds

Here are the final feeds that I produced:

Each feed should contain a single entry with an image of a Sierpinski triangle. To obtain triangles of a different size (i.e. a different level of expansion), just change the level number at the end of the URL.

Level 1 (a single 4x4 pixel triangle) can be thought of as a kind of baseline test, since it doesn’t make use of a DTD. If a feed reader can’t display the images in the level 1 feeds, then it probably doesn’t support Atom binary content and/or the data URL scheme.

Level 10 is the upper limit – at higher levels, the images can become unmanageably large.

Conforming Clients

Snarfer is the only application I’m aware of that supports binary content in Atom, and it tops out at level 7. Higher levels trigger the detection of a potential billion laughs attack, and thus prevent the expansion of entities after a certain point.

As an aside: I suspect, eventually, the concept of inline binary content will need to be dropped from the Atom specification, before it can advance in the standards track.⁠3 Feed publishers have shown no interest in using it, and feed readers have little incentive to support it.

The RSS feeds, using data URLs, fared much better – largely thanks to the release of Internet Explorer 8 (most Windows clients use IE to render markup). I know of at least eight clients⁠4 that can render the level 5 feed successfully – even more can render the level 1 baseline test.

Unfortunately, at levels higher than 5, the images tend to be clipped or not shown at all. I suspect that may be due to a size limit on data URLs. There were a couple of clients that worked all the way up to level 10, but they were extremely slow at the topmost levels.

Closing Comments

While this exercise was largely for fun, I did discover a number of interesting facts along the way.

  1. With the release of IE8, data URLs are now quite widely supported in desktop feed readers (at least to some extent).
  2. About half of the clients tested supported XML DTDs. That’s not great, but considerably more than I would have expected.
  3. It’s been more than three years since RFC 4287 was published, and support for binary content in Atom is still essentially non-existent.
  4. The string w00t, when decoded via base64 into a 24-bit RGB colour, produces a very nice shade of blue.

Also, I have way too much time on my hands – yay for unemployment.

Footnotes

  1. Technically, High ASCII art, since it makes use of block characters from the old IBM PC code page.
  2. The data URL scheme actually allows a choice of regular hex encoding or base64, but for our purposes base64 obviously makes a whole lot more sense.
  3. Assuming I’ve understood the IETF standards process correctly, at least two independent implementations are required, covering all options and features of a specification.
  4. AmphetaDesk, BottomFeeder, FeedExplorer, GreatNews, JetBrains Omea Reader, Opera, RSS Bandit, and RSSOwl.