Intro

My cooking recipe collection has been with the Paprika Recipe Manager for quite some time. I’m a card-carrying member of the digital hoarder club, so the recipe collection has grown tremendously. The honest truth though is that I only cook a tiny subset of this collection on a regular basis and only seldom venture beyond that comfort zone. I’m definitely not a good cook.

The Paprika Recipe Manager app is really nice. I have it on all my devices, it syncs well, it has a nice presentation of the recipes. The browser feature is its secret killer feature: you find a recipe on the web, let the built-in Paprika browser load the page and extract the recipe from the page contents. It correctly populates the ingredients list, the step-by-step guide, the icon and title, etc.

But now that we have LLMs there is this desire to free the recipes from their “proprietary” storage (*, more on the format later), store them as plain text and expose them to our LLM of choice. In theory this would allow us to interact with a recipe using plain language and the LLM will transform and present it as we wish. For example: change the units, replace a particular ingredient for another, find alternatives satisfying certain dietary restrictions, doing the scaling up or down according to the number of people we want to serve. I’m saying in theory. We will see how well this works in practice.

The first step though is to extract the recipes from Paprika Recipe Manager and convert them to some form of plain text recipes.

.paprikarecipes

The proprietary storage mentioned in the Intro comes with an asterisk, and this is a big kudos to the Paprika Recipe Manager people and lucky for us: the format is not really that proprietary, at least when you export the recipes as .paprikarecipes files. It turns out, these .paprikarecipes files are just zip files. Inside them each recipe again is a zip file of JSON data and some image data, either embedded as base64 data or as a separate zip file. So all in all very amenable to processing by a script.

This covers the source, but what about the destination.

Cooklang

For the destination format of our conversion I made a geeky choice: cooklang. It’s a pretty straightforward plain text markup format. I think an example will suffice to convey the idea:

---
title: "Peach Strudel"
---

@sliced fresh peaches{1 1/2%cup}
@cinnamon{1/2%tsp}
@sugar{1%tbsp}
@flour{1%tbsp}
@1/4 chopped walnuts{}
@brown sugar{2%tbsp}
@bread crumbs{1%tbsp}
@white sugar{1%tbsp}
@1 puff pastry{}
@1 egg{}

Peach Strudel Ingredients

I'm going to use:

   * 1 1/2 cup sliced fresh peaches
   * 1/2 tsp cinnamon
   * 1 tbsp sugar
   * 1 tbsp flour

We're going to mix that up. Again, you can do this with apples, pears, etc. It also usually contains some dried fruit. So I'm going to add a 1/4 cup of raisins.

Strudel Filling Ingredients

The filling of a strudel has two parts; this is the fruit part, and the other part is this sugar mixture. So combine:

   * 1/4 chopped walnuts
   * 2 tbsp brown sugar
   * 1 tbsp bread crumbs
   * 1 tbsp white sugar

Give that a mix.

Prepare the Premade Strudel Pastry

And there is the pastry - and why this is so easy - we're going to use a sheet of frozen supermarket puff pastry. Put it on a well floured board, with a little more flour over the top. With your rolling pin, we're going to make a rectangle shape. Notice the seams are going in the same direction as we are rolling. We're going to get this about 1/8 inch thick - and a little longer than it is wide. 

Don't worry if the ends fray a little bit, as long as the sides are straight. When we roll it you won't see any of that. It will also have a nice side (smoother) and a not so nice side. We're going to do an egg wash, which is one egg and a splash of water.

Assemble the Strudel

With the less attractive side facing up, and the smoother side facing down - egg wash that really well. Put the sugar mixture down on just 2/3rd of the dough. Put the fruit on the bottom 1/3, and leave about a 2 inch space at the bottom and sides.

Fold the Strudel

The folding is very simple. Start by bringing up the first 2 inches - kind of pinch the bottom a little. Roll it over once, that's the second third - pinch in the sides a bit to keep it all together. And then the last fold, and we're going to have a nice completed strudel package. The fold is always down of course.

Bake the Strudel

We're going to place that on our baking sheet, I'm going to use a silicon mat, but you can use parchment paper - these do tend to leak a bit from the fruit. We're going to cut a slice in the top about every inch to give it that signature strudel look, and to vent the air and steam. Paint it very well with egg wash. We're going to put that in a 375°F oven for about 40-45 minutes, until it's browned, beautiful and looks like this.

Please forgive my obsession with Strudel.

Conversion

We have the source, the destination and we have Antigravity. The result is cookcc, a pretty straightforward Go script that given a .paprikarecipes file, executes the conversion and saves the .cook files in an output directory.

What can we do with these .cook files ? A future post will experiment with exposing them to Gemini (that’s just the LLM I pay for). But for now we can install cookcli and then view the files in a nice web UI:

brew install cookcli
cd recipe_collection_output_dir
cook server --open

web UI