RFDs #0003

Recipe format

This living specification describes the fork.club recipe format in detail. I'll keep this document up to date with the working live spec.

Recipe document

A recipe document combines Primitives separated by line breaks. Primitivies can appear in any order within a document, but certain combinations will yield a Semantic structure.

These semantic meanings do not alter the intrinsic structure of each of the primitives.

Content within some Primitives can be enhanced using Rich content markup.

Primitives

Semantic structures

  • Step [h2] + ul + ol

Rich content

Full example

# Fluffy Pancakes

- Duration: About 20 minutes
- Yield: [4 servings]

Fluffy pancakes that are perfect for breakfast or brunch. Top with syrup, fresh fruits, or your favorite toppings!

- 1 cup of All-Purpose Flour
- 2 tbsp of Sugar
- 1 tbsp of Baking Powder
- 1/2 tsp of Baking Soda
- 1/4 tsp of Salt
- 1 cup of Milk
- 1 Egg
- 2 tbsp of Melted Butter

1. In a bowl, mix all dry ingredients (flour, sugar, baking powder, baking soda, and salt).
2. In another bowl, whisk together milk, egg, and melted butter.
3. Gradually add the wet mixture to the dry ingredients, stirring until just combined.
4. Heat a lightly oiled skillet or griddle over medium heat.
5. Pour [1/4 cup] of batter for each pancake onto the skillet. Cook until bubbles form and edges are dry, about 2 minutes.
6. Flip and cook the other side until golden brown, about 1-2 minutes.

Enjoy your pancakes with your favorite toppings!

> You can keep these refigerated for a couple days in your fridge.

Header

Format

# <text>

Example

# Fluffy Pancakes

Usage

  • There must be one header in the document, used as the recipe's title.

Subheader

Format

## <text>

Example

## For the sauce

Usage

  • Subheaders separate sections within the recipe.
  • If a subheader precedes a step, it names that step.

Unordered lists

Format

- <text>
- <text>
...

Example

- 300 grams of sugar
- 500 ml of milk

Usage

  • Primarily used to define ingredient lists within a step but can be used anywhere.

Ordered lists

Format

1. <text>
2. <text>
...

Example

1. In a bowl, mix the dry ingredients.
2. In another bowl, whisk together buttermilk, egg, and melted butter.

Usage

  • Primarily used for instructions within a step but can be used anywhere.

Definition lists

Definiton lists share lot's in comon with unordered lists. They main diference is that all elements must follow the a key-value structure using : as separator.

Format

- <key>: <value>
- <key>: <value>
...

Example

- Yield: 30 servings
- Duration: About 40 minutes

Usage

  • Recipe facts should to be one of the first element in the recipe after the header to improve readability.
  • We promote the usage of creative facts instead of constrain cooks with a predefined list of posible key facts.
  • Cooks should keep in mind that we'll index the recipe raw text in our search engine. This makes definition lists a powerfull tool to make your recipes searchable within your library in creative ways. For example if you add Cuisine: Spanish, Arabic. You'll be able to find your recipe by searching cuisine arabic.

Block Quote

Format

> <text>

Example

> Remember, do not let the sauce boil, as it may split.

Usage

  • Blockquotes are used to highlight important notes or tips.
  • In general we expect these to be used at the end of the recipe.
  • Block Quotes could be multi-line with or without adding > on the subsequent lines as far as you dont add a line break after.

Paragraph

Format

<text>

Example

Fluffy pancakes that are perfect for breakfast or brunch.

Usage

  • You can use paragraphs anywhere in the recipe
  • We expect you to include a brief explanation for your recipe before listing the ingredients and instructions but after you share the recipe facts

Step

When you combine an unordered list with an ordered list (plus an optional subheader) you'll produce a step. These are the main building block of recipes.

Example

# For the Sriracha mayonnaise

- 100g of mayonnaise
- 40g of Sriracha sauce

1. Mix both the mayo and sriracha in a bowl
2. Keep it refrigerated util you use it

Usage

  • Steps are the main semantic block in fork.club
  • A recipe might include several steps, each separated by some context.
  • You can use subsequent steps to share alternatives or variations to the main recipe.
  • We'll automatically inspect each element in the unordered list to indentify the implicit scalable amount in the text. You can optionally wrap it using the scalable amount format, but if not present we'll use tokens in the following order amount > number > range > fraction.
  • We'll do a best-efford to identify the stop words between the scalable amount and the ingredient to remove those when displaying the step as a table to improve readability.

Scalable amounts

Scalable amounts can be implicit or explicit.

Implicit scalable amounts

We'll automatically identify scalable amounts within unordered lists which are part of steps. This is becase we expect this to be the list of ingredientes needed in the recipe.

Although this process is automatic, you can explicitly wrap any amount within [...] to make it explicit. If no explicit amount is present we'll use tokens in the following order amount > number > range > fraction.

This two examples yield the same result

# For the Sriracha mayonnaise

- 100g of mayonnaise
- 40g of Sriracha sauce

1. Mix both the mayo and sriracha in a bowl
2. Keep it refrigerated util you use it
# For the Sriracha mayonnaise

- [100g] of mayonnaise
- [40g] of Sriracha sauce

1. Mix both the mayo and sriracha in a bowl
2. Keep it refrigerated util you use it

If for example we fail to identify an odd unit, you can make that amount explicit to solve the issue:

Odd unit (bricks and tiles)

# My Lego set

- [20 bricks] Blue 3x6
- [10 tiles] White 2x2

1. Build a structure
2. Have fun!

Explicit scalable amounts

If you want to make any amount scalable within paragraphs, definition lists, underdered lists, or blockquotes, you can wrap the amount between [...], and we'll make it interactive to scale using the recipe ratio.

Example

You can feed about [20 people] with this recipe, but not more than [10] if this is the main dish.

We'll scale those two amounts when the recipe scales up/down.

Usage

  • Within step instructions sometimes is useful to define a portion of the main ingredient that you want to incorporate. In those cases it is useful to wrap that amount, so that it doesn't remain constant and scales with the recipe.
  • Some facts in definition lists benefit greately. For example if you include a Yield fact, you will probably want to wrap the amount as scalable. Yield: Up to [20 portions] if people is hungry

Scalable amounts % (Baker's Percentagences)

Scalable amounts which unit is a percentage %, will scale up/down using a diferent logic than other amounts.

Professional recipes are often expressed as percentages relative to the main ingredient, a method commonly used in bread recipes where flour serves as the reference point. However, this approach is also applied in other contexts.

When scaling a recipe that uses amounts expresed as %, you'll be asked to introduce the amount in grams you expect to use of that ingredient.

While it's possible to mix standard measurements and percentages in a recipe, we recommend sticking to just one method for clarity and consistency.

Example

# Sourdough bread

- Bread flour 100.00%
- Sourdough starter 0.80%
- Water 76.00%
- Salt 1.90%

1. Combine the bread flour, whole wheat flour, and water in a large bowl and mix well.
2. After the autolyse, add the sourdough starter and salt to the dough.
3. Cover the dough and let it ferment at room temperature for 4-6 hours doing stretch-and-folds every 30 minutes.
4. Shape, proof and bake.

Scalable amounts (Advanced)

This is a bit nerdy, but... well, you are here, so you'll probably appreciate it

There are many examples in cooking and baking where ingredient amounts do not scale linearly due to the complex chemical and physical interactions involved.

In those cases, you can markup any amount to scale given any mathematical function you need.

Within this function you can use two variables, x with the original quantity in the amount, and y with the ratio the recipe is been scaled to.

You can think that by default any scaled amount is generated using this formula: f=x*y, but you are given the opportunity to customize it.

Format

[quantity unit](f=x*y)

Example

When scaling yeast very large batches of dough, it's common to use a sublinear function because yeast activity doesn't need to double just because the amount of flour doubles. Here's an example of a yeast scaling function:

Yeast Scaling Function: ๐‘Œ = ๐‘˜ โ‹… ๐น 0.85

Where:

  • ๐‘Œ Amount of yeast required
  • ๐น Amount of flour in the recipe
  • ๐‘˜ Proportionality constant based on the original recipe

Suppose the original recipe calls for:

- 500g of flour
- 5g of yeast

In this example ๐‘˜ โ‰ˆ 0.0254

For a larger batch of let's say 4x you'll need 2000g of flour and:

๐‘Œ = 0.0254 * 2000^0.85 โ‰ˆ 16.24g of yeast

For reference, if yeast scaled linearly, you would use 5 ร— 4 = 20g, but the sublinear scaling reduces this slightly to account for slower fermentation rates in larger dough masses.

- 500g of flour
- [5g](f=0.0254*(500*y)^0.85) of yeast

This example is for a very small amount of bread were 20 grams of yeast would probably be completely fine.

In general terms, not many recipes will benefit from this feature, but I think somebody will be delighted when using it with for some large-batch recipes that use hops, eggs, etc...

If you find this useful, please drop me an email, I'll appreaciate it.

For reference, we use the following javascript library to parse the formula: expr-eval It supports many useful functions like min, max, roundTo, etc....

Links

Format


[text](url)

Example


Buy a simple kitchen clock like [this one](https://amzn.eu/d/327QMaB)

Usage

  • You can make part of the text a link to other recipes or external websites
  • Destination urls must start with https://

Author: Jorge Bastida
Published: January 14, 2024
RFD: #0003

If you'd like to discuss this RFD, share your thoughts, or simply chat about it, feel free to reach out to me - To stay up to date with the project's development, you can follow me on X