RecipeMD
RecipeMD copied to clipboard
Reference implementation/testcases differ from specification
As a long-time user of the RecipeMD format for storing and displaying my recipe collection, I am deeply grateful for your work on this project.
I am currently implementing a RecipeMD parser in Rust based on the specification, and I am encountering a few issues. In some aspects, the reference implementation and its accompanying testcases show and enforce behavior that differs from what I expect based on the specification.
(I previously created a TypeScript implementation, but since it is a direct port of the Python reference implementation, it has the exact same behavior as the latter one.)
Serialization
The serialized representation (e.g. as JSON) is not specified which results in some uncertainties for testing and general interoperability problems between different implementations.
Main aspects:
- naming of fields
- casing of fields: e.g.
ingredient_groups
vs.ingredientGroups
- representation of empty fields:
[]
(for list-like data types),null
or complete absence of the field - ordering of fields: specific order, alphabetical or any order
- whitespace: should leading/trailing newlines and other whitespace be stripped?
Data types
In the following, I use some pseudocode syntax to describe the structure/schema of different data type representations. I hope it helps to represent them language-independently (is there an actual standard for such a format?).
Recipe
The reference implementation assigns ingredients without a preceding heading to a ingredients
field of the recipe. The specification only mentions a field that holds ingredient groups.
Schema descriptions
Specification
Recipe {
title: String,
description: String | None,
tags: String[1..n] | None,
yields: Amount[1..n] | None,
ingredients: IngredientGroup[1..n],
instructions: String | None,
}
Reference implementation
Recipe {
title: String,
description: String | None,
tags: String[0..n],
yields: Amount[0..n],
ingredients: Ingredient[0..n],
ingredient_groups: IngredientGroup[0..n],
instructions: String | None,
}
Ingredient Group
The reference implementation uses nested ingredient groups based on the heading level. Such behavior is not defined by the specification.
The specification does not allow ingredient groups with no ingredients (“1..n ingredients”). The reference implementation accepts them and many testcases require them and have no ingredients at all.
Schema descriptions
Specification
IngredientGroup {
title: String | None,
ingredients: Ingredient[1..n],
}
Reference implementation
IngredientGroup {
title: String | None,
ingredients: Ingredient[0..n],
ingredient_groups: IngredientGroup[0..n],
}
Amount
See https://github.com/tstehr/RecipeMD/issues/38.
Schema descriptions
Specification
Amount {
factor: Number,
unit: String | None,
}
Reference implementation
Amount {
factor: Number | None,
unit: String | None,
}
What now?
Regarding serialization, it would be great if the JSON representation was formalized and a JSON Schema would be created.
Regarding nested ingredient groups, I think they make sense and should be incorporated into the specification.
Regarding empty ingredient groups, I think they are useful when drafting a recipe and should be allowed by the specification.
I am willing to discuss any changes that need to be taken, and I am happy to help where I can.