71 lines
2.7 KiB
Markdown
71 lines
2.7 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. 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](https://tilde.town/~gamerdonkey/recipes/lemony_olive_oil_zucchini_bread.html),
|
|
and I worked around the issue by adding an instruction to set the ingredients
|
|
aside and use them later.
|