PyCook

A few months ago, I went on a quest to better digitize and collect a bunch of the recipes I use on a regular basis. Like most people, I’ve got a 3-ring binder of stuff I’ve printed from the internet, a box with the usual 4x6 cards, most of which are hand-written, and a stack of cookbooks. I wanted something that could be both digital and physical and which would make recipes easier to share. I also wanted whatever storage system I developed to be something stupid simple. If there’s one thing I’ve learned about myself over the years it’s that if I make something too hard, I’ll never get around to it.

This led to a few requirements:

  1. A simple human-writable file format

  2. Recipes organized as individual files in a Git repo

  3. A simple tool to convert to a web page and print formats

  4. That tool should be able to produce 4x6 cards

Enter PyCook. It does pretty much exactly what the above says and not much more. The file format is based on YAML and, IMO, is beautiful to look at all by itself and very easy to remember how to type:

name: Swedish Meatballs
from: Grandma Ekstrand

ingredients:
  - 1 [lb] Ground beef (80%)
  - 1/4 [lb] Ground pork
  - 1 [tsp] Salt
  - 1 [tsp] Sugar
  - 1 Egg, beaten
  - 1 [tbsp] Catsup
  - 1 Onion, grated
  - 1 [cup] Bread crumbs
  - 1 [cup] Milk

instructions:
  - Soak crumbs in milk

  - Mix all together well

  - Make into 1/2 -- 3/4 [in] balls and brown in a pan on the stove
    (you don't need to cook them through; just brown)

  - Heat in a casserole dish in the oven until cooked through.

Over Christmas this year, I got my mom and a couple siblings together to put together a list of family favorite recipes. The format is simple enough that my non-technical mother was able to help type up recipes and they needed very little editing before PyCook would consume them. To me, that’s a pretty good indicator that the file format is simple enough. 😁

The one bit of smarts it does have is around quantities and units. One thing that constantly annoys me with recipes is the inconsistency with abbreviations of units. Take tablespoons, for instance. I’ve seen it abbreviated “T” (as opposed to “t” for teaspoon), “tbsp”, or “tblsp”, sometimes with a “.” after the abbreviation and sometimes not. To handle this, I have a tiny macro language where units have standard abbreviations and are placed in brackets. This is then substituted with the correct abbreviation to let me change them all in one go if I ever want to. It’s also capable of handling plurals properly so when you type [cup] it will turn into either “cup” or “cups” depending on the associated number. It also has smarts to detect “1/4” and turn that into vulgar fraction character “¼” for HTML output or a nice LaTeX fraction when doing PDF output.

That brings me to the PDF generator. One of my requirements was the ability to produce 4x6 cards that I could use while cooking instead of having an electronic device near all those fluids. I started with the LaTeX template I got from my friend Steve Schulteis for making a PDF cookbook and adapted them to 4x6 cards, one recipe per card. And the results look pretty nice, I think

Meatballs recipe as a 4x6 card

It’s even able to nicely paginate the 4x6 cards into a double-sided 8.5x11 PDF which prints onto Avery 5389 templates.

Other output formats include an 8.5x11 PDF cookbook with as many recipes per page as will fit and an HTML web version generated using Sphinx which is searchable and has a nice index.

P.S. Yes, that’s a real Swedish meatball recipe and it makes way better meatballs than the ones from IKEA.