I've been hearing great things about blogging with IPython notebooks from folks like Jake Vanderplas and Fernando Perez, so I thought I'd give it a try myself. Jake has put together some great tools for dropping notebooks into blog posts built using Pelican, and documented them in a blog post. So I figured getting a notebook into a blogpost would take a few minutes--half an hour, max.
Several hours later, I had a working example. Needless to say, getting this working was more involved than I had expected. I gather this is because IPython, the notebook converter (nbconvert), and the Pelican plugins are all somewhat in flux--meaning that tools that worked together a few weeks ago might be incompatible today. Once IPython hits 1.0 in a few weeks, hopefully these issues will be resolved.
Until then, here's a quick guide to setting up a Pelican blog with IPython notebooks, using the software available at this moment. To make things really simple, this guide will use Jake Vanderplas's blog, the source for which is available on his GitHub.
I assume you'll use a virtual environment for your blog. I use Doug Hellman's virtual environment wrapper library, but the standard virtual environment package or pythonbrew are fine too. First things first: create a new environment and install the required packages.
sudo pip install tornado pyzmq ipython pelican markdown
Next, clone the Pythonic Perambulations blog:
git clone https://github.com/jakevdp/PythonicPerambulations.git
And the Octopress theme for Pelican, written by Maurizio Sambati:
git clone https://github.com/duilio/pelican-octopress-theme.git
We'll also need Jake Vanderplas's liquid tags plugin for Pelican. The plugin is in the liquid_tags branch of Jake's fork of the pelican-plugins repo, so we need to check it out after cloning the repo.
git clone https://github.com/jakevdp/pelican-plugins.git
(cd pelican-plugins && git checkout liquid_tags)
We also need nbconvert to convert IPython notebooks to Markdown. To get this set up, clone the nbconvert repo, then add the nbconvert/utils and nbconvert/nbconvert1 directories to your pythonpath:
git clone https://github.com/ipython/nbconvert.git
We're almost done. Rendering IPython Notebooks requires a file called style.min.css, which the liquid tags plugin expects to live in .../site-packages/IPython/frontend/html/notebook/static/css. That file actually doesn't exist in the virtual environment at this point, but we can get a copy from the IPython repo on GitHub. To do this, we can clone the repo and copy the css file to the location where the plugin expects it to be:
git clone https://github.com/ipython/ipython.git
cp ipython/IPython/html/static/style/style.min.css /path/to/venv/lib/python2.7/site-packages/IPython/frontend/html/notebook/static/css
Next, we'll create a directory for the Pelican output:
And update the paths in the Pelican configuration file, pelicanconf.py. Since we cloned jakevdp's blog, we'll also need to change the AUTHOR, SITENAME, and a bunch of other parameters in this file, but that can wait.
THEME = '/path/to/octopress/pelican/theme'
PLUGIN_PATH = '/path/to/forked/pelican/plugins'
Now everything should work. Let's see if it does:
(cd output && python -m SimpleHTTPServer)
Browse to localhost:8000
And to prove that this works--at least using the current versions of the Pelican plugin, IPython, nbconvert, etc., as of this exact moment--here's a notebook:
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!