Wednesday, December 24, 2014

Convert several IPython Notebooks to one huge PDF

The IPython Notebook is a neat interactive document. It mixes headings, formatted text (markdown), formulas, images/pictures and interactive code. This is very neat for creating well-documented code examples.

To make ordinary publishing possible, nbconvert converts this interactive json-based file format to ordinary static HTML or LaTeX. The nbviewer website is a well known example for such a repository of HTML-notebooks.

Converting to LaTeX is also very handy, because then you can compile them to static PDF files -- e.g. think of a proper report or article.

So far I know, each input document is converted to only one output document. For one of my projects, I wanted to merge a whole bunch of IPython Notebooks to one (very large) PDF document! To achieve this, I've looked into the various *.tplx template file and started to build on top of them two new templates: partial and master. As the names suggest, partial is the template for each partial document, and master is essentially empty, but combines all partial documents in an orderly fashion.

You can see this here: github:haraldschilly/python-fuer-mathematiker

In particular:
  • partial.tplx: This removes all the preamble and heading stuff and sets the document class to the wonderful subfiles LaTeX class.
  • master.tplx: This template contains the default header definitions (inherited from IPython's base template), adds some tweaks of my own (font family, margins, title, and subfiles master class) and an embedded Python script to magically gather all documents!
How it works: First, all partial IPython Notebook files are converted to LaTeX using the partial template. Then, the master.tplx contains a small embedded Python script, which iterates through all partial LaTeX files. They are named numerically as --chaptername. This script inserts all those subdocuments and if there is an  increments in the major-number, it inserts a \chapter{...} heading.

To orchestrate all this, a usual Makefile checks for dependencies and finally uses latexmk with the --shell-escape switch (which is necessary to run the embedded Python). Works like a charm!

I hope this is helpful for some of you.