Skip to main content

Recipy converter

Project description

gorps

Conversion tool around a yml cooking recipe format.

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.

A typical recipe looks like:

title: Beans with Bacon a la Bud Spencer
description: Chuck Norris? Never heard about her!
instruction: |
  Finely dice the onions 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/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/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]

Usage - Examples

svg

To export the folder examples/recipes/` using a template examples/svg/template.svg:

gorps export --template=examples/svg/template.svg -o /tmp/out.svg examples/recipes/

xml

In this advanced example, we compose the recipes from examples/recipes 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/

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/

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/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

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

markdown

To export the folder examples/recipes/ to individual .md files in /tmp/out/:

gorps export --fmt markdown -o /tmp/out/ examples/recipes/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gorps-0.9.0.tar.gz (42.5 kB view hashes)

Uploaded Source

Built Distribution

gorps-0.9.0-py3-none-any.whl (42.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page