Recipy converter
Project description
gorps
The idea: The format is simple enough so that an editor can be used instead of a GUI and this script is intended to be a "mini pandoc" for recipes.
About the name: there is a famous (unconfirmed) quote due to Luther:
Warum rülpset und furzet ihr nicht, hat es euch nicht geschmacket?
Translation:
Why don't you burp and fart? Did it not taste good?
Gorps is the Swiss German word for burp (abuse of emoji 🗯 for the logo).
A typical recipe looks like:
title: Beans with Bacon a la Bud Spencer
description: Chuck Norris? Never heard about her!
instruction: |
Finely dice the onion and briefly sauté in hot oil together
with the bacon.
...
amount: 1
amount_unit: Pan
preparation_time: 900
cooking_time: 600
source: https://www.kabeleins.ch/sosiehtsaus/essen-trinken/rezepte/bohnen-mit-speck-nach-bud-spencer
link: https://www.kabeleins.ch/sosiehtsaus/essen-trinken/rezepte/bohnen-mit-speck-nach-bud-spencer
ingredients:
- name: Finely diced bacon
amount: 125
unit: g
- name: Clove of garlic
amount: 1
- name: Salami or Cabanossi
amount: 150
unit: g
- name: ...
notes: |
Bud gives a damn about cream, but if you prever, serve with cream!
tags:
category:
- Main course
An amount
of an ingredient can be
- A number:
- name: Clove of garlic amount: 1
- A fraction:
- name: Clove of garlic amount: 1/3
- A range:
- name: Clove of garlic amount: min: 2/3 max: 1
Ingredients can be grouped:
ingredients:
- name: Trimming
ingredients:
- name: ...
amount: ...
unit: ...
It is also possible to include an image:
image:
fmt: image/jpeg
data: !!binary |
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
Where the binary data is the base64 encoded binary data of the image.
An image /tmp/1x1.png
can be inserted into a recipe using
gorps set-image --pic=/tmp/1x1.png examples/recipes/yml/more-beans.yml
This will include the following in the yml file:
image:
fmt: image/png
data: !!binary |
...
where ...
is the base64 encoded content of the image file.
The image file can be encoded / decoded as follows:
# Encode:
base64 image.png > image.b64.txt
# Decode:
base64 -d image.b64.txt > image.png
An image also can be extracted from a recipe:
gorps extract-image -o /tmp/1x1.png examples/recipes/yml/more-beans.yml
Supported Formats:
Import:
Export:
- The above
yml
format - Markdown
svg
xml
(via templates, e.g. XSL-FO xml output)- openrecipes sqlite and xml (not installed by default)
html
graph LR
yml --> gorps{gorps} --> md & yml & svg & xml & html & or_xml[openrecipes xml] & or_sql[openrecipes sql]
xml --> fop{fop} --> pdf
html --> weasyprint{weasyprint} --> pdf
Install
Requirement: python >= 3.9.
pip install gorps
# or first clone / cd, then:
pip install .
With support for openrecipes:
pip install --install-option="--extras-require=openrecipes" gorps
# or first clone / cd, then:
pip install .[openrecipes]
Cooklang support
Import
Cooklang documents are imported as follows:
- Everything, except metadata (lines starting with
>>
), including comments is stored unchanged as theinstruction
field. The content type of theinstruction
is set to cooklang, so it can be properly formatted to other formats. - Tagged ingredients (
@
and{}
) and cookware (#
/{}
) are collected from theinstruction
field. - The title is taken from the file name.
- If an image with extension .jpg, .jpeg, .png is present in the same folder as the .cook file, it is loaded as the image of the recipe.
- Every field name of the
Ingredient
class appearing in the metadata, will be passed to theIngredient
instance. Exceptions:ingredients
,instruction
,title
,image
,instruction_content_type
,cookware
already are read in from outside the metadata. If one of the above mentioned keys are present in the metadata, the key / value will be stored in thetags
field of the recipe.nutrition_labels
: Keys for values in nutrition labels have to be specified prefixed bynutrition_labels.
, the values have to be of the formnumber unit
. Example:>> nutrition_labels.Energy Value: 150 kcal
preparation_time
/cooking_time
: The unit must be one ofh
,min
,sec
or the value must be formatted as##:##:##
(3:
).
- Support for multivalued metadata entries (e.g. categories):
Append
[]
to a key to put the value into a list. Example:
will be loaded as>> category[]: Main dishes >> category[]: Starters
recipe.tags.category = ["Main dishes", "Starters"]
.
Export
If a recipe has instruction content type cooklang (this is currently
only the case if it either has been imported from a .cook file or
from a .yml file where instruction_content_type=text/cooklang
),
the instruction
field is written without modification to the output
file followed by metadata. Otherwise all ingredient names / cookware
names appearing in the instruction as whole words (case insensitive)
will be marked up with cooklang tags. All ingredients / cookware not
found in the instructions will be appended to the cooklang file as a
list. Also here, metadata will be written at the end of the
file. Example:
Ingredients:
- @Finely diced bacon{125%g}
- @Clove of garlic{1}
...
Cookware:
- #Pan{}
...
>> description: Chuck Norris? Never heard about her!
...
Usage - Examples
svg
To export the folder examples/recipes/yml/` using a template examples/svg/template.svg:
gorps export --template=examples/svg/template.svg -o /tmp/out.svg examples/recipes/yml/
xml
In this advanced example, we compose the recipes from examples/recipes/yml/ to a menu card.
The template
examples/menu-card/xml-fo/template.fo.xml
is used. This specific template expects to be used together with the
--group-by
option (recipes should be grouped by category).
Also, we are specifying, that we only want to include the groups
Starters, Main courses and Dessert (--group
options).
With the --variable
option we pass to the template some other
required parameters, like logos for categories, fonts and more.
The example also shows, how to filter the source recipes by title
(--title
options).
gorps export \
--template examples/menu-card/xml-fo/template.fo.xml \
--group-by 'tags["category"]' \
--group Starters \
--group "Main courses" \
--group Dessert \
--variable-file examples/menu-card/xml-fo/variables.json \
--title "Beans with Bacon a la Bud Spencer" \
--title "More Beans" \
-o /tmp/menucard.fo.xml \
examples/recipes/yml/
The resulting fo.xml
can then be further processed by
Apache fop to a pdf:
cp -r examples/menucard/img /tmp
fop /tmp/menucard.fo.xml /tmp/menucard.pdf
Note: The resulting xml file will refer to the fonts Linux Libertine and Linux Biolinum which are part of the Libertine Open Fonts Project.
ℹ️ If you want to use custom fonts, you can specify a font config like this:
fop -c fonts.cfg /tmp/menucard.fo.xml /tmp/menucard.pdf
where fonts.cfg
looks like:
<?xml version="1.0"?>
<fop version="1.0">
<renderers>
<renderer mime="application/pdf">
<fonts>
<directory>/path/to/fonts</directory>
<auto-detect/>
</fonts>
</renderer>
</renderers>
</fop>
The template syntax is inspired by vue.js: Currently, the following directives are implemented:
- Text
Interpolation
<span>Title: {{ recipe.title }}</span>
- v-if
(Conditionally render an element based on the truthy-ness of the expression value)
<div v-if="recipe.ingredients"> {{ recipe.title }} </div>
- v-for
(Render the element block multiple times based on the source data)
<div v-for="recipe in recipes"> {{ recipe.title }} </div>
Tuple unpacking is also possible:<div v-for="group, recipes in groups.items()"> {{ group }}: {{ recipes[0].title }} </div>
- v-bind
(Dynamically bind one or more attributes to an element)
<!-- bind an attribute --> <a v-bind:href="recipe.link">Link</a> <!-- bind a dict of attributes --> <div v-bind="{ 'id': '1', 'class': 'X'}"></div>
<template>
on v-if and v-for
html
Menu card
This is a slight variant of the xml fo example from above.
This time, we use html as output format and make use of the
--grouped-titles
option, to manually group recipes by their titles.
Also, --filter-ingredient
is used, to remove "obvious" ingredients
from the ingredient list.
gorps export \
--template examples/menu-card/html/menucard.template.html \
-V title="Beans & Beans" \
--filter-ingredient Salt \
--filter-ingredient Pepper \
--grouped-titles examples/menu-card/html/grouped_titles.json \
-o /tmp/menucard.html \
examples/recipes/yml/
The resulting html can be further processed to a pdf by e.g. weasyprint:
cp -r examples/menucard/img examples/menucard/html/style.css /tmp
weasyprint /tmp/menucard.html /tmp/menucard.pdf
Note: see the comment about fonts from the xml fo example.
web
Here, we export a recipe to html, using the same template syntax as for xml:
gorps export \
--template examples/html/template.html \
-o /tmp/beans.html \
examples/recipes/yml/beans.yml
openrecipes
There are two possibilities: either direct export to the sqlite
database file or export to an .openrecipe
xml file.
sql
To sync to an openrecipes db on an android phone, first pull the db via adb:
adb root
adb pull /data/user/0/org.jschwab.openrecipes/files/database.db /tmp/
Then export all recipes to the sqlite db:
gorps export --fmt openrecipes -o /tmp/database.db examples/recipes/yml/
Finally, replace the db on the phone with the extended version:
adb push /tmp/database.db /data/user/0/org.jschwab.openrecipes/files/database.db
adb kill-server # terminate adb
openrecipe xml
gorps export --fmt openrecipes-xml -o /tmp/out/ examples/recipes/yml/
markdown
To export the folder examples/recipes/ to
individual .md
files in /tmp/out/
:
gorps export --fmt markdown -o /tmp/out/ examples/recipes/yml/
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file gorps-1.0.0.tar.gz
.
File metadata
- Download URL: gorps-1.0.0.tar.gz
- Upload date:
- Size: 56.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b96b02a83ad8d45cf48f29f7f621d01452aea0ad46095b3cd3c54adcf6a970a2 |
|
MD5 | 77e121df1a3d26af7ca0138d133953fe |
|
BLAKE2b-256 | cab32b186ee0011ef9dd8fdbc5fc6938eb06e3abbb7f4fdacb8d88907d050843 |
File details
Details for the file gorps-1.0.0-py3-none-any.whl
.
File metadata
- Download URL: gorps-1.0.0-py3-none-any.whl
- Upload date:
- Size: 38.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 172875a15c64d31bbdb20e1db3249ce5a05be03809a9c9f3811535f63e037f8c |
|
MD5 | 9fb77317eee8e8803ea5fb61c02c8707 |
|
BLAKE2b-256 | cfdbb80aa40c6c2b2a360b80179e088e86cc01944f77baf69bca0be0065df83d |