When nanoc meets IPython

pythonnanocipython

I was quite amazed by the power of IPython Notebook when I recapped my Machine Learning notes: it seamlessly integrates a Markdown editor, a TeX equation editor powered by MathJax and inline chart rendering from matplotlib. There is only one thing missing: how can I integrate the IPython notebook to my nanoc workflow?

The magic ipython nbconvert manages to convert the notebook.ipynb to a full- fledged HTML or just the HTML snippet, but it just blindly writes the output to the current working directory, that breaks the nanoc’s filter workflow. I poked around the IPython unittests and found the following code snippet to pipe the content via the stdin and stdout file descriptors.

import sys

from IPython.nbconvert import HTMLExporter
exportor = HTMLExporter(template_file="basic")
body, _ = exportor.from_file(sys.stdin)
sys.stdout.write(body)

The rest part is easy: with Open3.capture3 we can feed the stdin with the content, and return the captured stdout.

def run(content, params={})
  nbconvert = <<'END'
   // the above python code snippet ...
END

  o, e, s = Open3.capture3("python -c '#{nbconvert}'",
                           :stdin_data=>content.to_s)
  if !s.success?
    raise "nbconvert fails: #{e}"
  end
  o
end

The filtered content is self-contained: the ipython console block is highlighted with pygments’ instrumentation; the figure is embedded inline with data URL scheme. No external dependencies are dangling around. Here is an example how it may look with some personal touch.

For your convenience, the filter is wrapped up as nanoc-nbconvert gem. To use it, you need to install the following dependencies:

  • IPython 2.0.0-dev1
  • nodejs2
  • MathJax

Add nanoc-nbconvertin your Gemfile and lib/default.rb to install and auto load the gem:

require "nanoc-nbconvert"

Then you can reference :nbconvert filter in your Rules file.

Please consult the MathJax’s documentation for MathJax installation and configuration.


  1. the IPython-1.x branch is no longer actively developed, it depends on Pandoc for nbcovnert, and the rendering is inconsistent with the nbviwer occasionally, see #5316 for more details.
  2. the latest IPython prefers to use the Markdown.js to render the markdown cell for a consistent rendering as nbviewer. pandoc is no longer required for nbconvert, see #5316 for more details.