75 lines
2.8 KiB
Markdown

# Recipes for Engineers
Store recipes in a nerdy JSON tree format and use that to generate [Cooking for
Engineers](https://www.cookingforengineers.com)-style tabular recipe cards in
HTML.
I used these scripts to create my [recipes
site](https://tilde.town/~gamerdonkey/recipes/) 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](https://anytree.readthedocs.io/en/latest/).
## 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. It has you list out ingredients, and then add
tasks to perform on those ingredients.
You can add ingredients and then add tasks to perform on those ingredients.
The results of those tasks can have more tasks applied to them, until you 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
output to a JSON file based on the name you give to the recipe.
### `recipes2html.py`
***WARNING: These scripts do not sanitize most inputs!*** Parts of the JSON can
have HTML which will be rendered out in the browser, which 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](https://tilde.town/~gamerdonkey/recipes/lemony_olive_oil_zucchini_bread.html),
and I worked around the issue by just adding an instruction to set the
ingredients aside and use them later.