Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
3e46ae89b0 |
26 changed files with 446 additions and 94 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ recipes
|
||||||
venv
|
venv
|
||||||
.mypy_cache
|
.mypy_cache
|
||||||
.vscode
|
.vscode
|
||||||
|
docs/book
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
when:
|
|
||||||
- event: push
|
|
||||||
branch: main
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: publish
|
|
||||||
image: woodpeckerci/plugin-docker-buildx
|
|
||||||
settings:
|
|
||||||
platforms: linux/amd64,linux/arm64/v8
|
|
||||||
repo: git.comfy.city/emi/comfy-recipes
|
|
||||||
registry: git.comfy.city
|
|
||||||
tags: latest
|
|
||||||
username: ${CI_REPO_OWNER}
|
|
||||||
password:
|
|
||||||
from_secret: registry_token
|
|
15
Dockerfile
15
Dockerfile
|
@ -1,11 +1,12 @@
|
||||||
FROM python:3.13-alpine AS build
|
FROM alpine:3.18 AS build
|
||||||
COPY . /build
|
COPY . /build
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
RUN pip install build hatchling && \
|
RUN apk add --no-cache python3 py3-build py3-hatchling && \
|
||||||
python3 -m build .
|
python3 -m build .
|
||||||
|
|
||||||
FROM python:3.13-alpine
|
FROM alpine:3.18
|
||||||
COPY --from=build /build/dist/ /mnt
|
COPY --from=build /build/dist/comfy-recipes-*-py3-none-any.whl /
|
||||||
RUN pip install /mnt/comfy_recipes-*-py3-none-any.whl && \
|
RUN apk add --no-cache python3 py3-pip && \
|
||||||
rm -r /mnt
|
pip install /comfy-recipes-*-py3-none-any.whl && \
|
||||||
ENTRYPOINT ["/usr/local/bin/recipes-cli"]
|
apk del py3-pip
|
||||||
|
ENTRYPOINT ["/usr/bin/recipes-cli"]
|
||||||
|
|
16
README.md
16
README.md
|
@ -4,13 +4,7 @@ Comfy Recipes is a simple application that renders your recipes into HTML.
|
||||||
|
|
||||||
Documentation is available at <https://comfy.city/comfy-recipes/docs>
|
Documentation is available at <https://comfy.city/comfy-recipes/docs>
|
||||||
|
|
||||||
## Running
|
## Building the python package
|
||||||
```sh
|
|
||||||
docker run -v ./recipes:/recipes git.comfy.city/Emi/comfy-recipes:latest build /recipes
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
|
||||||
### Building the python package
|
|
||||||
Make sure you have hatchling and build modules installed.
|
Make sure you have hatchling and build modules installed.
|
||||||
```sh
|
```sh
|
||||||
python3 -m build
|
python3 -m build
|
||||||
|
@ -21,17 +15,17 @@ The package can now be installed with
|
||||||
pip install dist/comfy-recipes-*-py3-none-any.whl
|
pip install dist/comfy-recipes-*-py3-none-any.whl
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building the docker container
|
## Building the docker container
|
||||||
```sh
|
```sh
|
||||||
docker buildx build -t git.comfy.city/Emi/comfy-recipes:local .
|
docker build -t codeberg.org/comfy.city/comfy-recipes .
|
||||||
```
|
```
|
||||||
|
|
||||||
The container can now be ran
|
The container can now be ran
|
||||||
```sh
|
```sh
|
||||||
docker run -v ./recipes:/recipes git.comfy.city/Emi/comfy-recipes:local build /recipes
|
docker run --rm codeberg.org/comfy.city/comfy-recipes
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building the documentation
|
## Building the documentation
|
||||||
```sh
|
```sh
|
||||||
cd docs
|
cd docs
|
||||||
mdbook build
|
mdbook build
|
||||||
|
|
|
@ -197,20 +197,19 @@ class IngredientInstance(Element):
|
||||||
def from_dict(cls, ctx: Context, dct: str | Dict[str, Any]) -> Self:
|
def from_dict(cls, ctx: Context, dct: str | Dict[str, Any]) -> Self:
|
||||||
if isinstance(dct, str):
|
if isinstance(dct, str):
|
||||||
string = dct.strip()
|
string = dct.strip()
|
||||||
p = re.compile(r"^(?:([0-9\.]+) ([a-zA-Z]+) )+([\w ]+)(?: \((.*)\))?$")
|
p = re.compile(r"^(?:([0-9\.]+) ([a-zA-Z]+) )?([\w ]+)(?: \((.*)\))?$")
|
||||||
match = p.match(string)
|
match = p.match(string)
|
||||||
|
if match is None:
|
||||||
amount = float(1)
|
raise RuntimeError(
|
||||||
unit = ctx.default_unit
|
"ingredient {string} regex not matched, it should be in the format [amount(num) unit(string, one word)] name(string, any number of words) [(note(string))]"
|
||||||
name = string
|
)
|
||||||
note = None
|
|
||||||
if match is not None:
|
|
||||||
amount = float(match.group(1))
|
amount = float(match.group(1))
|
||||||
unitstr = match.group(2)
|
unitstr = match.group(2)
|
||||||
|
unit = ctx.default_unit
|
||||||
if unit is not None:
|
if unit is not None:
|
||||||
unitx = ctx.units.get(unitstr)
|
unitx = ctx.units.get(unitstr)
|
||||||
if unitx is None:
|
if unitx is None:
|
||||||
ctx.issues.error(issues.ISSUE_UNKNOWN_UNIT, f"unknown unit {unitstr}")
|
ctx.issues.error(issues.ISSUE_UNKNOWN_UNIT, "unknown unit {unitstr}")
|
||||||
else:
|
else:
|
||||||
unit = unitx
|
unit = unitx
|
||||||
name = match.group(3)
|
name = match.group(3)
|
||||||
|
@ -290,7 +289,7 @@ class Recipe(Element):
|
||||||
source: Optional[SafeHTML],
|
source: Optional[SafeHTML],
|
||||||
ingredients: List[IngredientInstance],
|
ingredients: List[IngredientInstance],
|
||||||
subrecipes: List["Recipe"],
|
subrecipes: List["Recipe"],
|
||||||
price: Optional["MultiPriceDB"],
|
price: Optional["PriceDB"],
|
||||||
stepsections: List[StepSection],
|
stepsections: List[StepSection],
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(ctx)
|
super().__init__(ctx)
|
||||||
|
@ -318,7 +317,7 @@ class Recipe(Element):
|
||||||
rp = Recipe.from_dict(ctx, partdct)
|
rp = Recipe.from_dict(ctx, partdct)
|
||||||
subrecipes.append(rp)
|
subrecipes.append(rp)
|
||||||
|
|
||||||
price: Optional[MultiPriceDB] = None
|
price: Optional[PriceDB] = None
|
||||||
pricex: float = 0
|
pricex: float = 0
|
||||||
ingswithprice = 0
|
ingswithprice = 0
|
||||||
ingswithoutprice = 0
|
ingswithoutprice = 0
|
||||||
|
@ -336,22 +335,16 @@ class Recipe(Element):
|
||||||
# we don't know how to convert currencies yet
|
# we don't know how to convert currencies yet
|
||||||
currency = None
|
currency = None
|
||||||
break
|
break
|
||||||
if currency is None or len(ingredients) == 0:
|
if currency is None or ingswithoutprice != 0 or len(ingredients) == 0:
|
||||||
price = None
|
price = None
|
||||||
else:
|
else:
|
||||||
pricedb = PriceDB(
|
price = PriceDB(
|
||||||
ctx=ctx,
|
ctx=ctx,
|
||||||
price=pricex,
|
price=pricex,
|
||||||
amount=1,
|
amount=1,
|
||||||
unit=ctx.default_unit,
|
unit=ctx.default_unit,
|
||||||
currency=currency,
|
currency=currency,
|
||||||
)
|
)
|
||||||
price = MultiPriceDB(
|
|
||||||
ctx=ctx,
|
|
||||||
pricedb=pricedb,
|
|
||||||
item_count=len(ingredients),
|
|
||||||
item_prices_missing=ingswithoutprice,
|
|
||||||
)
|
|
||||||
|
|
||||||
stepsections: List[StepSection] = []
|
stepsections: List[StepSection] = []
|
||||||
if "steps" in dct:
|
if "steps" in dct:
|
||||||
|
@ -601,16 +594,3 @@ class PriceDB(Element):
|
||||||
if currency is None:
|
if currency is None:
|
||||||
raise RuntimeError("currency not specified and default_currency is also not set")
|
raise RuntimeError("currency not specified and default_currency is also not set")
|
||||||
return cls(ctx=ctx, price=price, amount=amount, unit=unit, currency=currency)
|
return cls(ctx=ctx, price=price, amount=amount, unit=unit, currency=currency)
|
||||||
|
|
||||||
class MultiPriceDB(Element):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
ctx: Context,
|
|
||||||
pricedb: PriceDB,
|
|
||||||
item_count: int,
|
|
||||||
item_prices_missing: int,
|
|
||||||
) -> None:
|
|
||||||
super().__init__(ctx)
|
|
||||||
self.pricedb = pricedb
|
|
||||||
self.item_count = item_count
|
|
||||||
self.item_prices_missing = item_prices_missing
|
|
||||||
|
|
|
@ -1,24 +1,12 @@
|
||||||
{% macro price(price) -%}
|
{% macro price(price) -%}
|
||||||
{% if price != None and price is defined and price.price is defined %}{{price.price|round(1)|numprint}}{%else%}?{% endif %} {{price.currency}}
|
{% if price != None and price is defined and price.price is defined %}{{price.price|round(1)|numprint}}{%else%}?{% endif %} {{price.currency}}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
{% macro multiprice(multiprice, shortform) -%}
|
|
||||||
{% if multiprice != None and multiprice.pricedb != None and multiprice.pricedb is defined and multiprice.pricedb.price is defined -%}
|
|
||||||
{{multiprice.pricedb.price|round(1)|numprint}}
|
|
||||||
{%else%}
|
|
||||||
?
|
|
||||||
{%- endif %}
|
|
||||||
{{multiprice.pricedb.currency}}
|
|
||||||
{%if multiprice.item_prices_missing != 0 and not shortform%}
|
|
||||||
({{multiprice.item_prices_missing}}/{{multiprice.item_count}} prices missing)
|
|
||||||
{%endif%}
|
|
||||||
{%- endmacro %}
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{% endblock %}</title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
{%block body %}
|
{%block body %}
|
||||||
<h1>Recipes</h1>
|
<h1>Recipes</h1>
|
||||||
{% for recipe in recipes %}
|
{% for recipe in recipes %}
|
||||||
<li>{% if recipe.price != None %}{{multiprice(recipe.price, true)}} {%endif%}<a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
|
<li>{% if recipe.price != None %}{{price(recipe.price)}} {%endif%}<a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%endblock%}
|
{%endblock%}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% macro ingredientpart(ing) -%}
|
{% macro ingredientpart(ing) -%}
|
||||||
{% if ing.price != None %}{{price(ing.price)}} {%endif%}
|
{% if recipe.price != None %}{{price(ing.price)}} {%endif%}
|
||||||
{% if ing.amount != None %} {{ing.amount|amountprint}}
|
{% if ing.amount != None %} {{ing.amount|amountprint}}
|
||||||
{% if ing.unit != None %} {{ing.unit.name}}{% endif %}
|
{% if ing.unit != None %} {{ing.unit.name}}{% endif %}
|
||||||
{%endif%}
|
{%endif%}
|
||||||
|
@ -29,10 +29,7 @@
|
||||||
{% for ing in rec.ingredients %}
|
{% for ing in rec.ingredients %}
|
||||||
<li>{{ingredient(ing)}}</li>
|
<li>{{ingredient(ing)}}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if rec.price != None %}
|
{% if rec.price != None %}price: {{price(rec.price)}}{%endif%}
|
||||||
<br>
|
|
||||||
price: {{multiprice(rec.price)}}
|
|
||||||
{%endif%}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if rec.stepsections|length != 0 %}
|
{% if rec.stepsections|length != 0 %}
|
||||||
<h3>Steps</h3>
|
<h3>Steps</h3>
|
||||||
|
|
13
docs/book.toml
Normal file
13
docs/book.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[book]
|
||||||
|
authors = ["Emi Vasilek"]
|
||||||
|
language = "en"
|
||||||
|
multilingual = false
|
||||||
|
title = "Comfy Recipes Documentation"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
create-missing = true
|
||||||
|
|
||||||
|
[output.html]
|
||||||
|
preferred-dark-theme = "Ayu"
|
||||||
|
git-repository-url = "https://codeberg.org/comfy.city/comfy-recipes"
|
||||||
|
git-repository-icon = "fa-git"
|
15
docs/examples/firstrealrecipe.yaml
Normal file
15
docs/examples/firstrealrecipe.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
title: Swedish Pancakes
|
||||||
|
ingredients:
|
||||||
|
- 3 piece egg
|
||||||
|
- 1.25 cup milk
|
||||||
|
- 0.75 cup all purpose flour
|
||||||
|
- 1 tablespoon white sugar
|
||||||
|
- 1 tablespoon butter
|
||||||
|
steps:
|
||||||
|
- Beat eggs in a bowl until the mixture is smooth.
|
||||||
|
- Add milk
|
||||||
|
- Mix flour, sugar and salt in a separate bowl
|
||||||
|
- Mix together with the egg mixture, mix until it's smooth
|
||||||
|
- heat a griddle
|
||||||
|
- Drop just enough of the mixture to the griddle to spread to all corners
|
||||||
|
- After about a minute, turn the pancake over
|
1
docs/examples/minimal.yaml
Normal file
1
docs/examples/minimal.yaml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
- title: Pancakes
|
5
docs/examples/minimalusable.yaml
Normal file
5
docs/examples/minimalusable.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
- title: Pancakes
|
||||||
|
ingredients:
|
||||||
|
- 100 gram flour
|
||||||
|
steps:
|
||||||
|
- make pancakes
|
14
docs/src/SUMMARY.md
Normal file
14
docs/src/SUMMARY.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
- [Introduction](./introduction.md)
|
||||||
|
- [Installation](./installation.md)
|
||||||
|
- [Tutorial](./tutorial/index.md)
|
||||||
|
- [Quick Start](./tutorial/quickstart.md)
|
||||||
|
- [Units](./tutorial/units.md)
|
||||||
|
- [Ingredients](./tutorial/ingredients.md)
|
||||||
|
- [Prices and Conversions](./tutorial/pricesconversions.md)
|
||||||
|
- [Reference](./reference/index.md)
|
||||||
|
- [Recipe (recipes/*.yaml)](./reference/recipe.md)
|
||||||
|
- [Units (units.yaml)](./reference/units.md)
|
||||||
|
- [Ingredients (ingredients.yaml)](./reference/ingredients.md)
|
||||||
|
- [Settings (settings.yaml)](./reference/settings.md)
|
14
docs/src/installation.md
Normal file
14
docs/src/installation.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Installation
|
||||||
|
## Docker
|
||||||
|
The containers are available on <https://codeberg.org/comfy.city/-/packages/container/comfy-recipes/latest>
|
||||||
|
```sh
|
||||||
|
docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes ARGUMENTS
|
||||||
|
```
|
||||||
|
|
||||||
|
for example:
|
||||||
|
```sh
|
||||||
|
docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes build /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
Docker is currently the only supported installation method, if you would like to use another method, please refer to the building instructions which are available in the project [README.md](https://codeberg.org/comfy.city/comfy-recipes/src/branch/main/README.md)
|
22
docs/src/introduction.md
Normal file
22
docs/src/introduction.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Comfy Recipes is a program that allows you to create a rich collection of recipes and create a presentable website from them.
|
||||||
|
|
||||||
|
## Get started
|
||||||
|
If you don't have comfyrecipes installed yet, please see [Installation](./installation.md)
|
||||||
|
|
||||||
|
1. write a recipe in a yaml format to `myrecipes/recipes/xxxx.yaml`, for example
|
||||||
|
|
||||||
|
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||||
|
```yaml
|
||||||
|
{{#include ../examples/firstrealrecipe.yaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. run `comfyrecipes build myrecipes/` (this will build the website to `myrecipes/out/html`)
|
||||||
|
3. run `comfyrecipes serve` myrecipes and navigate to <http://localhost:8000> (this will run a web server and allow you to see your rendered recipe)
|
||||||
|
|
||||||
|
## Links
|
||||||
|
* Repository: <https://codeberg.org/comfy.city/comfy-recipes>
|
||||||
|
* Issues: <https://codeberg.org/comfy.city/comfy-recipes/issues>
|
||||||
|
* Website: <https://comfy.city/comfy-recipes>
|
||||||
|
* Documentation: <https://comfy.city/comfy-recipes/docs>
|
15
docs/src/reference/index.md
Normal file
15
docs/src/reference/index.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Reference
|
||||||
|
|
||||||
|
* What's not marked as **MANDATORY** is optional.
|
||||||
|
|
||||||
|
## Data Types
|
||||||
|
* `string` - text of arbitrary length
|
||||||
|
* `integer` - a whole number
|
||||||
|
* `float` - a decimal number
|
||||||
|
* `number` - `integer` or `float`
|
||||||
|
|
||||||
|
## Table Of Contents
|
||||||
|
* [Recipes](recipe.md) - documenting recipes/*.yaml
|
||||||
|
* [Units](units.md) - documenting units.yaml
|
||||||
|
* [Ingredients](ingredients.md) - documenting ingredients.yaml
|
||||||
|
* [Settings](settings.md) - documenting settings.yaml
|
20
docs/src/reference/ingredients.md
Normal file
20
docs/src/reference/ingredients.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Ingredients (ingredients.yaml)
|
||||||
|
- list of [Ingredient](#ingredient)
|
||||||
|
|
||||||
|
## Ingredient
|
||||||
|
- name, **MANDATORY**, string
|
||||||
|
- aliases, list of strings
|
||||||
|
- wdid, integer
|
||||||
|
- prices, list of [Prices](#price)
|
||||||
|
- conversions, list of [Conversions](#conversion)
|
||||||
|
|
||||||
|
## Price
|
||||||
|
- price, **MANDATORY**, number
|
||||||
|
- amount, **MANDATORY**, number
|
||||||
|
- unit, **MANDATORY**, string, unit has to be listed in units.yaml if units.yaml exists
|
||||||
|
- currency, string
|
||||||
|
|
||||||
|
## Conversion
|
||||||
|
- from, **MANDATORY**, string, from has to be listed in units.yaml if units.yaml exists
|
||||||
|
- to, **MANDATORY**, string, to has to be listed in units.yaml if units.yaml exists
|
||||||
|
- ratio, **MANDATORY**, number
|
54
docs/src/reference/recipe.md
Normal file
54
docs/src/reference/recipe.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# Recipe (recipes/*.yaml)
|
||||||
|
- title - **MANDATORY**, string
|
||||||
|
- ingredients - list of [Simplified Ingredients](#simplified-ingredient) and [Ingredients](#ingredient)
|
||||||
|
- steps - list of strings and [Steps Sections](#steps-section)
|
||||||
|
- subrecipes - list of [Recipes](#recipe-recipesyaml)
|
||||||
|
|
||||||
|
## Simplified Ingredient
|
||||||
|
= string in a specific format
|
||||||
|
```
|
||||||
|
[amount unit] ingredient name [(note)]
|
||||||
|
```
|
||||||
|
[] means these sections are optional
|
||||||
|
|
||||||
|
* `amount` - number
|
||||||
|
* `unit` - a single word string
|
||||||
|
* `name` - string with arbitrary content
|
||||||
|
* `note` - string with arbitrary content, but has to be enclosed in parentheses, otherwise it will be considered to be part of `name`
|
||||||
|
|
||||||
|
for example, valid values are:
|
||||||
|
```
|
||||||
|
1 piece carrot (sliced)
|
||||||
|
^ amount
|
||||||
|
^---^ unit
|
||||||
|
^----^ ingredient name
|
||||||
|
^-----^ note
|
||||||
|
```
|
||||||
|
```
|
||||||
|
200 gram green onion
|
||||||
|
^-^ amount
|
||||||
|
^--^ unit
|
||||||
|
^---------^ ingredient name
|
||||||
|
```
|
||||||
|
```
|
||||||
|
apple
|
||||||
|
^---^ ingredient name
|
||||||
|
```
|
||||||
|
```
|
||||||
|
apple (red)
|
||||||
|
^---^ ingredient name
|
||||||
|
^---^ note
|
||||||
|
```
|
||||||
|
|
||||||
|
When amount and unit is not in the string, it is assumed to be `1 piece`.
|
||||||
|
|
||||||
|
## Ingredient
|
||||||
|
- name - **MANDATORY**, string, name has to be listed in ingredients.yaml if ingredients.yaml exists
|
||||||
|
- amount - number
|
||||||
|
- unit - string, unit has to be listed in units.yaml if units.yaml exists
|
||||||
|
- or - list of [Ingredient](#ingredient)
|
||||||
|
- note - string
|
||||||
|
|
||||||
|
## Steps Section
|
||||||
|
- section - **MANDATORY**, string, section name
|
||||||
|
- steps - list of strings
|
2
docs/src/reference/settings.md
Normal file
2
docs/src/reference/settings.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Settings (settings.yaml)
|
||||||
|
* default_currency, string
|
13
docs/src/reference/units.md
Normal file
13
docs/src/reference/units.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Units (units.yaml)
|
||||||
|
- list of [Units](#unit)
|
||||||
|
|
||||||
|
## Unit
|
||||||
|
- name, **MANDATORY**, string
|
||||||
|
- conversions, list of [Conversions](#conversion)
|
||||||
|
- aliases, list of strings
|
||||||
|
|
||||||
|
## Conversion
|
||||||
|
- to, **MANDATORY**, string, to has to be listed in units.yaml if units.yaml exists
|
||||||
|
- ratio, **MANDATORY**, number
|
||||||
|
|
||||||
|
(this is similar to [Ingredients Conversion](./ingredients.md#conversion), but the `from` field is automatically set to unit's name)
|
21
docs/src/tutorial/index.md
Normal file
21
docs/src/tutorial/index.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Tutorial
|
||||||
|
|
||||||
|
This is the full file structure of comfy recipes input data:
|
||||||
|
|
||||||
|
```
|
||||||
|
- myrecipes/ - can be named according to your preference
|
||||||
|
|
||||||
|
- recipes/ - directory that will hold the recipes
|
||||||
|
- pancakes.yaml - the individual recipe
|
||||||
|
|
||||||
|
- units.yaml - OPTIONAL, file containing all valid units and their properties
|
||||||
|
- ingredients.yaml - OPTIONAL, file containing all valid ingredients and their properties
|
||||||
|
- settings.yaml - OPTIONAL, file for overriding default settings
|
||||||
|
```
|
||||||
|
|
||||||
|
In the following sub-chapters we will first create a simple recipe and then find out what each file does and what functionalities they can offer.
|
||||||
|
|
||||||
|
- [Quick Start](./quickstart.md) - Creating simple recipes
|
||||||
|
- [Units](./units.md) - What units.yaml is for and how to use it
|
||||||
|
- [Ingredients](./ingredients.md) - Why list ingredients in ingredients.yaml and what it can offer
|
||||||
|
- [Prices and Conversions](./pricesconversions.md) - Let's start adding and calculating prices of recipes
|
54
docs/src/tutorial/ingredients.md
Normal file
54
docs/src/tutorial/ingredients.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# Ingredients
|
||||||
|
|
||||||
|
Similar to `units.yaml`, also `ingredients.yaml` is not a mandatory file, but having it gives us several advantages.
|
||||||
|
* spelling mistakes are not silently ignored, if something is not listed in ingredients.yaml, comfyrecipes will warn you
|
||||||
|
* we can use aliases - different names referring the same ingredient
|
||||||
|
* we will be able to add some more data to ingredients that will allow us to calculate prices (described in [Prices and Conversions](./pricesconversions.md))
|
||||||
|
|
||||||
|
```
|
||||||
|
- myrecipes/
|
||||||
|
- recipes/
|
||||||
|
- pancakes.yaml
|
||||||
|
...
|
||||||
|
- ingredients.yaml (we will be creating this file)
|
||||||
|
```
|
||||||
|
|
||||||
|
We will again use the final recipe from [Quick Start](quickstart.md).
|
||||||
|
|
||||||
|
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||||
|
```yaml
|
||||||
|
{{#include ../../examples/firstrealrecipe.yaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't want to write the file manually, we can generate it using:
|
||||||
|
```sh
|
||||||
|
$ comfyrecipes generate-ingredients
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate a minimal ingredients.yaml:
|
||||||
|
|
||||||
|
`🗎 myrecipes/ingredients.yaml:`
|
||||||
|
```yaml
|
||||||
|
- name: all purpose flour
|
||||||
|
- name: butter
|
||||||
|
- name: egg
|
||||||
|
- name: milk
|
||||||
|
- name: white sugar
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, let's say we would want to call `all purpose flour` just `flour`, we can add an alias:
|
||||||
|
|
||||||
|
`🗎 myrecipes/ingredients.yaml:`
|
||||||
|
```yaml
|
||||||
|
- name: all purpose flour
|
||||||
|
aliases:
|
||||||
|
- flour
|
||||||
|
- name: butter
|
||||||
|
- name: egg
|
||||||
|
- name: milk
|
||||||
|
- name: white sugar
|
||||||
|
```
|
||||||
|
|
||||||
|
Now whenever we add an ingredient called flour, it will be a reference to `all purpose flour`.
|
||||||
|
|
||||||
|
For a full reference for what an ingredients yaml can contain, please see the [Ingredients Reference](../reference/ingredients.md)
|
27
docs/src/tutorial/pricesconversions.md
Normal file
27
docs/src/tutorial/pricesconversions.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Prices and Conversions
|
||||||
|
|
||||||
|
ComfyRecipes has the ability to compute recipe prices if we give it enough information.
|
||||||
|
This requires your recipe collection to have an [`ingredients.yaml` file](./ingredients.md).
|
||||||
|
Like with the previous sections, we will use
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
|
||||||
|
Sometimes we need to configure some defaults globally, this is what settings.yaml is for.
|
||||||
|
Currently it's only used for setting the default_currency.
|
||||||
|
|
||||||
|
Let's create settings.yaml and set the default currency to USD.
|
||||||
|
|
||||||
|
```
|
||||||
|
- myrecipes/
|
||||||
|
- recipes/
|
||||||
|
- pancakes.yaml
|
||||||
|
...
|
||||||
|
- settings.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
`🗎 myrecipes/settings.yaml:`
|
||||||
|
```yaml
|
||||||
|
default_currency: USD
|
||||||
|
```
|
||||||
|
|
||||||
|
For a full reference for what a settings yaml can contain, please see the [Settings Reference](../reference/settings.md)
|
65
docs/src/tutorial/quickstart.md
Normal file
65
docs/src/tutorial/quickstart.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# Quick Start
|
||||||
|
|
||||||
|
Let's start writing recipes. First, create the directory structure that will hold all our input data.
|
||||||
|
|
||||||
|
```
|
||||||
|
- myrecipes/
|
||||||
|
- recipes/
|
||||||
|
- pancakes.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Now when we have the structure created, let's create the most minimal possible `pancakes.yaml`:
|
||||||
|
|
||||||
|
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||||
|
```yaml
|
||||||
|
{{#include ../../examples/minimal.yaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
And render it by running:
|
||||||
|
```sh
|
||||||
|
$ comfyrecipes build myrecipes
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a new directory `out/` in `myrecipes/` containing the built data.
|
||||||
|
```
|
||||||
|
- myrecipes/
|
||||||
|
- out/
|
||||||
|
- html/
|
||||||
|
- index.html
|
||||||
|
- pancakes.html
|
||||||
|
- recipes/
|
||||||
|
- pancakes.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
We can see the result if we start a web server pointing to that directory, for example by using:
|
||||||
|
```sh
|
||||||
|
$ comfyrecipes serve myrecipes
|
||||||
|
```
|
||||||
|
and navigate to <http://127.0.0.1:8000/>
|
||||||
|
|
||||||
|
`serve` should NOT be used in production.
|
||||||
|
|
||||||
|
While that was a valid recipe, it's not very useful and we can only see the title. Let's improve that:
|
||||||
|
|
||||||
|
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||||
|
```yaml
|
||||||
|
{{#include ../../examples/minimalusable.yaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
* each ingredient is a step in the format `amount unit name`
|
||||||
|
* `amount` has to be a number
|
||||||
|
* `unit` has to be a single word
|
||||||
|
* `name` can be a string with arbitrary content
|
||||||
|
* for a full description of this format, please see the [Reference section](../reference/recipe.md#simplified-ingredient)
|
||||||
|
* each step is a string with arbitrary content
|
||||||
|
|
||||||
|
And again, build, make sure the server is running and navigate to <http://127.0.0.1:8000/>. From now on, we will assume you know how to build and serve your output directory.
|
||||||
|
|
||||||
|
Once more, let's improve the recipe once again to something that can actually be made and is not just a demo. This does not introduce any new concepts compared to the last recipe we wrote.
|
||||||
|
|
||||||
|
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||||
|
```yaml
|
||||||
|
{{#include ../../examples/firstrealrecipe.yaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
For a full reference for what a recipe yaml can contain, please see the [Recipe Reference](../reference/recipe.md)
|
51
docs/src/tutorial/units.md
Normal file
51
docs/src/tutorial/units.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# Units
|
||||||
|
|
||||||
|
Each recipe ingredient has a string unit assigned to it. This is great, but a centralized list of all alowed units with some additional properties has several advantages:
|
||||||
|
|
||||||
|
* spelling mistakes are not silently ignored, if you make a mistake in the ingredient unit name, comfyrecipes will warn you that it's not on the units list
|
||||||
|
* `gram` and `g` can refer to the same unit (using aliases)
|
||||||
|
* we can tell comfyrecipes unit conversion rates (for example 1000 gram = 1 kilogram) which it can then use for example for calculating prices
|
||||||
|
|
||||||
|
This example will use the final example from [Quick Start](quickstart.md).
|
||||||
|
|
||||||
|
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||||
|
```yaml
|
||||||
|
{{#include ../../examples/firstrealrecipe.yaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
- myrecipes/
|
||||||
|
- recipes/
|
||||||
|
- pancakes.yaml
|
||||||
|
...
|
||||||
|
- units.yaml (we will be creating this file)
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't want to write the file manually, we can generate it using:
|
||||||
|
```sh
|
||||||
|
$ comfyrecipes generate-units
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate a minimal units.yaml:
|
||||||
|
|
||||||
|
`🗎 myrecipes/units.yaml:`
|
||||||
|
```yaml
|
||||||
|
- name: cup
|
||||||
|
- name: piece
|
||||||
|
- name: tablespoon
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, let's say we would want to call `tablespoon` just `tbsp`, we can add an alias:
|
||||||
|
|
||||||
|
`🗎 myrecipes/units.yaml:`
|
||||||
|
```yaml
|
||||||
|
- name: cup
|
||||||
|
- name: piece
|
||||||
|
- name: tablespoon
|
||||||
|
aliases:
|
||||||
|
- tbsp
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we can rename the `tablespoon` unit in the recipe to `tbsp` and it will reference the `tablespoon` unit.
|
||||||
|
|
||||||
|
For a full reference for what a recipe yaml can contain, please see the [Units Reference](../reference/units.md)
|
|
@ -9,7 +9,7 @@ description = "Smart recipe static site generator"
|
||||||
authors = [{ name = "Emi Vasilek", email = "emi.vasilek@gmail.com" }]
|
authors = [{ name = "Emi Vasilek", email = "emi.vasilek@gmail.com" }]
|
||||||
keywords = ["recipes", "recipe", "static site generator"]
|
keywords = ["recipes", "recipe", "static site generator"]
|
||||||
requires-python = ">= 3.8"
|
requires-python = ">= 3.8"
|
||||||
dependencies = ["jsonschema", "jinja2", "PyYAML", "mistune", "lxml", "lxml_html_clean"]
|
dependencies = ["jsonschema", "jinja2", "PyYAML", "mistune", "lxml"]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 3 - Alpha",
|
"Development Status :: 3 - Alpha",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
|
@ -17,9 +17,9 @@ classifiers = [
|
||||||
license = { file = "LICENSE" }
|
license = { file = "LICENSE" }
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Homepage = "https://git.comfy.city/Emi/comfy-recipes"
|
Homepage = "https://codeberg.org/comfy.city/comfy-recipes"
|
||||||
Repository = "https://git.comfy.city/Emi/comfy-recipes.git"
|
Repository = "https://codeberg.org/comfy.city/comfy-recipes.git"
|
||||||
Issues = "https://git.comfy.city/Emi/comfy-recipes/issues"
|
Issues = "https://codeberg.org/comfy.city/comfy-recipes/issues"
|
||||||
Documentation = "https://comfy.city/comfy-recipes/docs"
|
Documentation = "https://comfy.city/comfy-recipes/docs"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue