IPython notebooks in Pelican

Adding an obvious feature to Pelican.

IPython notebooks are an incredibly useful way to do reproducible research and illustrate chunks of code. Obviously you'd like to put some of them on the web. Surely there must be an easy way to include them in a Pelican-based website. So why hasn't anyone done it yet?

They have. In several different ways. Just none that I'm happy with.

This is how I made a reader for .ipynb files to include them in my website.

Other solutions

Google for possible solutions and you'll often get directed to liquid tags, a Pelican plugin for extended markup. Basically, it provides a tag for linking to and including IPython notebooks in articles. Liquid tags also need a bit of template hacking to get this inclusion to work. Which seems more difficult than it should be. I just want to drop the notebook in a directory and have Pelican render it.

Elsewhere, it's been suggested that notebooks be converted into another form (ReST) and are then dropped into Pelican. Also too hard and how do we handle images? Others have suggested converting the pages to HTML and then including them in Pelican.

Put then up on another site like Github or Wakari? Then I still have to write a page that points to them.

Daniel Rodriguez wrote a plugin that more or less does what I want. (Github repo here. The explanatory text doesn't quite match the repo, so obviously it's evolved some.) This is where I'll start hacking.

Note

This shouldn't be construed as criticism of any of the above solutions, which arguably are more flexible and may fit their creators needs better. But, being a lazy type, I'm willing to sacrifice power for simplicity. And thanks to Daniel for doing the heavy lifting of actually writing a ipynb reader.

Hacking the reader

The repo for my hacked and modified reader can be found at: https://github.com/agapow/pelican-ipynb

Appearance

Getting an included IPython notebook to look right is tricky. While you can just call on IPython to spit out the HTML for a page, that includes a whole mess of embbedded CSS styles. The Rodriguez reader injects it's own CSS to this end, but then this will interact with the CSS in your chosen Pelican theme and It. All. Gets. A. Bit. Complicated. In addition, the generated webpages looked different under Safari and Chrome for me.

There's no universal solution to this, it really depends on the Pelican theme you're using. But:

  • I rejigged the reader so the the custom CSS is added after the document CSS, not before
  • The !important directive may be useful in getting the right look.

Better figures

Notebooks include images as embedded data, encoded as Base64. Unfortunately the better_figures_and_images Pelican plugin can't handle these, at least not under Python 3. Nothing to do but disable the plugin.

Metadata

The Rodriguez plugin reads the notebook header for metadata, which you can edit in IPython. I made a few small changes, like mapping the name field to title, and looking at the first cell for a title. There's also an oddity where - depending on the source - metadata is not always processed. Fixed. (That code was a little suspicious anyway, as it deleted dictionary keys it was iterating over.)

Header levels

The headers in a normal Pelican document are sensibly set to the right level: H1, H2 etc. But the headers in an notebook are hardcoded in. Longer term, it would be sensible to rewrite them or trim off an initial header, but just be aware that if the notebook starts with a H1, you'll end with an article with two headers of the same level.

Caching

This is more of a general development tip, but when I was hacking on the reader, changes didn't seem to appear. I narrowed it down to using make devserver, which was puzzling until I realised that Pelican only recompiles content if it sees changes in the site content, theme or settings. Plugins are outside that loop. Flushing the cache directory fixed everything.