Recipe website syntax ideas
===========================

Informal overview
-----------------

Recipes are defined using a hierarchical, bracket-based syntax like so:

    stir in(
        1 tsp coffee powder,
        boiled({1 mug} water),
        1 tsp milk,
    )

Note that quantities and common units (e.g. tsp) will be spotted automatically
and the proceeding value auto-scaled up/down with the recipe.

For unusual units (or if you just prefer to be explicit), quantities and units
may be provided in curly braces (e.g. `{1 mug}` in the example above).

Parts of a recipe may be assigned to variables like so:

    pizza sauce = mix(
        blended(1 can tomatoes),
        1 tsp basil,
    )
    
    spread(
        1 ready made pizza base,
        pizza sauce,
        1.5 kg cheese,
    )

In the simple case above, the sub-recipe will be inlined in the generated
recipe grid.

It is often convenient to list ingredient quantities separately from the rest
of the recipe. The following syntax is supported:

    1 tsp coffee powder
    {1 mug} water
    1 tsp milk
    
    stir in(
        coffee powder,
        boiled(water),
        milk,
    )

The ingredient lines above are a short-hand for defining the following
sub-recipes:

    coffee powder = 1 tsp coffee powder
    water = {1 mug} water
    milk = 1 tsp milk

While the hierarchical definition is often convenient sometimes it is more
readable to present a series of simpler steps left-to-right. For example, we
can combine the 'boiled' step with the definition of the quantity of water in
the ingredient list below:

    1 tsp coffee powder
    {1 mug} water, boiled
    1 tsp milk
    
    stir in(
        coffee powder,
        water,
        milk,
    )

Since commas are already used as separators in hierarchical parts of a recipe,
you need to surround a left-to-right series of steps in parentheses. For
example:

    fry(
        1 tbsp oil,
        (1 onion, peeled, sliced, diced),
    )

Sometimes ingredients are used in multiple parts of a recipe. This will cause
the ingredient in question to be broken into its own sub-recipe and partial
quantities can be referred to later on. These will be checked that they add up
correctly and have the correct units.

    {1 packet} white source
    500g cheese, grated
    200g macaroni
    
    sprinkle on top(
        mix(
            white sauce,
            375g cheese,
            macaroni
        ),
        125g cheese,
    )

Alternatively, references to sub-recipes may use proportions to specify how
much of an ingredient to use. For example:

    {1 packet} white source
    500g cheese, grated
    200g macaroni
    
    sprinkle on top(
        mix(
            white sauce,
            75% cheese,
            macaroni
        ),
        1/4 cheese,
    )

These will be displayed as '25% (375g) cheese' and '1/4 (125g) cheese'
respectively.

> NB: In the special case of unit-less values (e.g. '3 onions'), the form '1/3
> onions' always means 1/3rd of an onion, not 1/3rd of the specified number of
> onions). The '%' based ratio must be used if you want to divide up the
> amounts by ratio.

The splitting syntax may be used to use the result of a sub-recipe in several
places. For example:

    tomato sauce = boil(1 can tomatoes, 1 tbsp spices)
    
    drizzle on top(
        wrap (
            fry(200g diced chicken pieces, 1 onion),
            75% tomato sauce
        ),
        1/4 tomato sauce,
    )

In some cases, a step may result in multiple outputs. To achieve this, the
multiple-output-producing sub-step should be written as a sub-recipe like so:

    soaked mushrooms, mushroom water = drain reserving water(
        soak for 20 minutes(
            10g dried porchini mushrooms,
            boiling water,
        )
    )
    
    boil(
        fry(
            onions,
            soaked mushrooms,
        ),
        mushroom water,
    )

Finally, if you want to use commas or other special characters in a
description, you can use quotes, e.g.:

    "chop, finely (until conceptually smooth)" (
        mushrooms, onions
    )

Sub recipe handling
-------------------

Sub-recipes defined using `=` will be inlined where possible.

    // Inlined if possible
    white sauce = add gradually(mix(melt(butter), flour), milk)
    
    interlace(lasagne sheets, white sauce)

Sub-recipes whose outputs are divided into multiple parts are always shown as a
separate recipe grid.


    // Not inlined as output is used in multiple places
    tomato sauce = boil down(chopped tomatoes, basil)

    drizzle(wrap(filling, 2/3 tomato sauce)< 1/3 tomato sauce)

Where a sub-recipe output (or ingredient) is split into multiple parts, these
parts must sum to the original amount. For example:

    // Error: Not all sauce used!
    sauce = boiled(tomatoes)
    drizzle(wrap(chicken, 1/2 sauce), 1/3 sauce)

Sub-recipes with multiple outputs will also always be shown as a separate
recipe grid:

    // Never inlined
    veg, veg water = drain reserving water(boil(veg, water))

Sometimes sub-recipes are used for the convenience of authoring the recipe
file, e.g. allowing ingredients to be listed separately:

    // Three sub-recipes (using convenience syntax)
    1 tsp coffee powder
    {1 mug} water, boiled
    1 tsp milk
    
    stir in(coffee powder, water, milk)

Other times the sub-recipes represent distinct parts of a recipe where it might
be desirable to highlight and label those parts of the recipe, even when
they're inlined. To make this happen `:=` may be used instead of `=`:

    // Though 'burger patties' will be inlined since they're only used in one
    // place, this sub-recipe will be given a thick border and the label
    // 'Burger Patties'.
    burger patties := mix(minced beef, cellery, onion, mixed herbs)

    insert(burgery patties, bun)

All 'anonymous' sub-recipes will be collected together into the final recipe
grid in the recipe. For example:

    burger patties := mix(minced beef, cellery, onion, mixed herbs)

    insert(burgery patties, bun)

    oven chips, cooked

In the above recipe example, a single recipe grid will be produced with both
the burger and chips listed. This means that nothing mentioned in the recipe
will 'go missing'.


Recipe file structure
---------------------

Recipe files consist of two halves: a markdown title and introduction followed
by a recipe using the above format. These parts are divided by a horizontal
line made out of dashes (`-`). For example::


    Instant coffee for 1
    ====================

    A foul tasting concoction.

    Coffee Brands
    -------------

    The brand does't matter. They all smell OK but taste bad!

    Milks
    -----

    Yeah, at this point it just doesn't matter...

    ---

    1 tsp coffee powder
    {1 mug} water, boiled
    1 tsp milk

    stir in(coffee powder, water, milk)

The number of servings should be given in the title (e.g. 'Soup *for 3*').

