Recipes for Engineers
Store recipes in a nerdy JSON tree format and use that to generate Cooking for Engineers-style tabular recipe cards in HTML.
I used these scripts to create my recipes
site here on town. Fun fact: you can
replace the html
with json
in the URLs to get my recipes in their raw JSON
format.
Requirements
Requires the anytree Python library.
Main Scripts
create_recipe_json.py
This is a fairly naive script that walks you through the process of turning a recipe into a tree structure. You add ingredients and then add tasks to perform on the ingredients. The results of those tasks can have further tasks applied to them, until you finally end up with your finished product.
The tree you build has a structure like this, with the last step at the root:
shake and grill for 20 more mins
+-- grill for 20 mins
+-- wrap in foil
+-- season to taste
|-- salt and pepper
|-- dice
| |-- rosemary
| |-- thyme
| +-- basil
+-- lightly coat
|-- olive oil
+-- chop into quarters
+-- red potatoes
Leaves are raw ingredients, other nodes are tasks. A recipe can have multiple tree roots. Once you are done adding ingredients and tasks, all trees are written to a JSON file based on the name you give to the recipe.
recipes2html.py
WARNING: These scripts do not sanitize most inputs! Fields parsed from the JSON can have HTML which will be rendered in the browser. This was very convenient for me but a terrible idea for security. DO NOT RUN THIS CODE ON JSON YOU DID NOT CREATE YOURSELF!
This script takes an argument pointing to a directory of recipe JSON files, in
the format created by the create_recipe_json.py
script. It then does a
recursive depth-first search on each tree in that file to generate an HTML
file with a traditional recipe and a tabular-style recipe card. It also takes
an optional argument pointing to a file and, if given, the contents of that
file will be inserted into the header section of the generated index.html
.
Known Issues
- A single node cannot have multiple tasks done on it (nerdy reason: because a node cannot have two parents). So this cannot perfectly represent, for example, mixing cinnamon and sugar, then splitting that mixture up and doing separate subsequent operations with the two batches. This has come up once in my zucchini bread recipe, and I worked around the issue by adding an instruction to set the ingredients aside and use them later.