Sample book spread Sample book spread – no InDesign required!


At the Getty, I'm building a platform (working title: Octavo) for publishing digital art books. The goal is to generate multiple book formats (web, PDF, EPUB, print on demand) from a single set of text files. The backbone of the project is the Middleman static site generator.

Middleman handles the web-based version of the book out of the box. In order to create the alternate formats, I knew that I'd need to write an extension.

I had always assumed that writing an extension for Middleman would be fairly complicated, but the process was surprisingly straight-forward and only took a few hours. This extension is a short program that does the following:

Development Process

Middleman's extension documentation includes discussion of several different callbacks—places where you can hook into the build process to run custom code. I wasn't sure what actions needed to go where, so I relied on good-old trial and error to get a sense of which methods and objects were available at any given moment in the program's lifecycle. The middleman console command was invaluable. Some points worth remembering:


This extension assumes the Prince PDF generator is being used (it has the best output of any command-line tool by far). However, you could swap out the command in the after_build callback to use any other program which can take a list of files as input.

Creating a good print stylesheet is also highly recommended.


First, you must require the extension in config.rb. Default place for it to live is in extensions/. Then, define a template for the printed versions of any dynamic pages (this setup assumes that dynamic pages are being used, and that the data lives in data/catalogue/). Using a separate template means that interactive elements can be replaced with things that make sense in a printed format (plain img elements instead of dynamic JS-enhanced versions, etc).

The extension will automatically run when the middleman build command is given, and a PDF will appear in the /pdf folder when generation is complete.

Next Steps

This is a basic (but working) implementation of an automatic web-to-PDF conversion. While this works, a lot of custom code for templates and styling was still needed in order to get decent output. My ultimate goal is to simplify the interface and provide some good defaults, and then package the end result as a gem. That way, you could just add it to your Gemfile and add a few lines of configuration and the rest would be handled automatically.

This is something I’m hoping to include as part of our Octavo platform for digital publishing at some point in 2016.

Questions? Suggestions? Let me know on twitter!

Complete Code

Available on Github here.