-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Be more explicit documenting Dr. Syntax's objects #9
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,64 +9,159 @@ Dr. Syntax (in America known as Syntax, M.D.) | |
is an object model, and file layout | ||
for representing recipes, ingredients, and shopping lists. | ||
|
||
Examples are shown in JSON format, and the `nosebag` project will continue to | ||
use JSON, but Dr. Syntax is format agnostic as long as the object can be | ||
serialised and deserialised intact. | ||
|
||
## Object model | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need something at the top of this section which talks about ontology + recipe list + recipes before it gets into the details. |
||
### Recipes | ||
|
||
Each recipe is represented as a core object and optional additional media. | ||
The central properties of each recipe are two lists: | ||
|
||
* recipe ingredients, which: | ||
* reference an ingredient by name (which may not exist, | ||
in which case it is treated as if an ingredient of that name exists | ||
with no other defined properties) | ||
* have an optional quantity which are either a naked | ||
positive number, meaning an amount without unit, or contain: | ||
* an amount | ||
* a unit | ||
* optional notes that provide advice on how to modify the amount | ||
required (such as "more if they are small") | ||
* an optional property of 'optional', meaning that the ingredient can be | ||
omitted | ||
* an optional prep instruction | ||
* an optional note (distinct from the quantity note), which can be used | ||
to express a preference; for instance, you could indicate a preferred | ||
variety | ||
* steps, each of which is a narrative of the task to be accomplished | ||
|
||
Recipes also have a name, an optional "serves" property to represent how many | ||
people this recipe will feed, and zero or more attributes (such as "gluten | ||
free"), which are used for searching and filtering. | ||
|
||
Prep instructions for ingredients are implicit steps that all come before | ||
the first recipe step. | ||
|
||
### Ingredients | ||
### The list of known ingredients — `ontology.json` | ||
|
||
Stored serialised as `ontology.json`, the ontology is an object containing | ||
an abstraction of foodstuff used in recipes. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "an object listing the foodstuffs used in recipes"? Yes, it's an abstraction, but I'm not sure saying that makes things clearer. |
||
|
||
```javascript | ||
{ | ||
"ingredients": [ | ||
{ | ||
"name": "carrot", | ||
"group": "vegetable", | ||
"attributes": [ | ||
"meat free", | ||
... | ||
] | ||
}, | ||
... | ||
] | ||
} | ||
``` | ||
|
||
Each ingredient is an object, containing: | ||
|
||
* `name` — _required_, the unique, singular name of the foodstuff, by | ||
convention lower cased (ie "carrot" not "Carrots") | ||
* `group` — _optional_, the unique, singular name of the grouping of the | ||
foodstuff, also by convention lower cased (ie "spice" not "Spices") | ||
* `attributes` — _optional_, an array of strings which represents aspects of the | ||
ingredient, such as "dairy" or "meat" that could be used for searching | ||
and filtering | ||
|
||
Groups represent a phase of shopping where similar items are collected | ||
together, such as an aisle or area in a supermarket, or visiting different | ||
shops. | ||
|
||
Ingredients are the abstraction of the food stuff used in recipes. So | ||
"carrot" rather than "100g carrots". The names of ingredients are unique, | ||
and by convention are singular and lower-cased. | ||
|
||
Ingredients also have an optional group, referenced by name, and zero or | ||
more attributes (such as "meat") which are used for searching and filtering | ||
recipes. | ||
### The list of recipes — `recipes.json` | ||
|
||
### Groups | ||
Stored serialised as `recipes.json`, the list of recipes is an array of | ||
strings that represent the directory relative to the location storing both | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since nosebag can work over HTTP, it's not necessarily the directory. Perhaps just a note that "equivalent things happen" under HTTP? Or "path"? |
||
`recipes.json` and `ontology.json` under which the recipe serialisation can be | ||
found. | ||
|
||
Groups represent a phase of your shopping, and may be thought of as aisles | ||
of a supermarket, or different shopkeepers. They have a name, which like | ||
ingredients are unique, singular, and lower-cased. For example, "vegetable", | ||
or "spice". | ||
```javascript | ||
{ | ||
|
||
## File layout | ||
"recipes": [ | ||
"bacon-hash", | ||
"cauliflower-fritter-lime-sauce", | ||
... | ||
] | ||
} | ||
``` | ||
|
||
|
||
### A recipe — `<dir>/recipe.json` | ||
|
||
The recipe core object is serialised as JSON, and stored as `recipe.json` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's no longer the case that Dr. Syntax is always JSON, this should be updated. |
||
alongside additional media files for that recipe. (Media files are | ||
referenced using either a relative URL, meaning their leaf filename, or an | ||
absolute URL if the media files are stored elsewhere such as on Wikipedia.) | ||
|
||
Ingredients and groups are serialised as one JSON object, stored as | ||
`ontology.json`. | ||
```javascript | ||
{ | ||
"name": "Mashed potatoes", | ||
"serves": "2", | ||
"attributes": [ | ||
"gluten free", | ||
... | ||
], | ||
"ingredients": [ | ||
{ | ||
"name": "large potato", | ||
"quantity": 4, | ||
"prep": "cut into 1-inch cubes", | ||
"notes": "Preferably Maris Piper or other floury potato." | ||
}, | ||
... | ||
], | ||
"steps": [ | ||
{ | ||
"task": "Heat water in a large pan until boiling.", | ||
}, | ||
... | ||
], | ||
} | ||
``` | ||
|
||
The **recipe object** contains: | ||
|
||
* `name` — _required_, a string containing the name of the recipe (this does not | ||
have to be unique within a collection of recipes) | ||
* `ingredients` - _required_, an array of ingredient objects (see below) | ||
* `steps` — _required_, an array of step objects (see below) | ||
* `serves` — _optional_, a string representing how many people this recipe will feed | ||
* `attributes` — _optional_, an array of strings which represent aspects of | ||
this recipe (such as "gluten free") which can be used for searching and | ||
filtering | ||
|
||
|
||
The **ingredient object** contains: | ||
|
||
* `name` — _required_, a string containing the name of the ingredient to | ||
reference from the ontology (which may not exist, in which case it is | ||
treated as if an ingredient of that name exists with no other defined | ||
properties) | ||
* `quantity` — _optional_, an object which contains: | ||
|
||
```javascript | ||
{ | ||
"amount": 300, | ||
"unit": "g", | ||
} | ||
``` | ||
|
||
* `amount` — _required_, a positive integer | ||
* `unit` — _optional_, a string representing the unit of which _amount_ is | ||
needed | ||
* `notes` — _optional_, a string containing advice on how to adjust the amount if | ||
necessary (eg "more if they are small") | ||
|
||
If both `unit` and `notes` are not needed, the object can be collapsed to a | ||
positive integer (eg requiring 2 onions has no new unit to be expressed). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what the word "new" is doing here? |
||
* `prep` — _optional_, a string containing directions on how to prepare the | ||
ingredient before making the recipe (eg "finely chopped") | ||
* `notes` — _optional_, a string containing advice on the ingredient (such as | ||
a preferred variety, acceptable substitutions, things to look out for when | ||
purchasing, etc) | ||
* `optional` — _optional_, a boolean value set to `true` if the ingredient is | ||
not strictly necessary, such as a garnish or extra herbs/spices | ||
|
||
The **step object** contains: | ||
|
||
* `task` — _required_, a string containing the narrative description of a step | ||
in making the recipe | ||
|
||
|
||
When interpreting a recipe object, these are the keys Dr. Syntax has imbued | ||
with meaning. Other keys can exist in the object for private use, but note | ||
that this specification may be expanded later which could introduce | ||
incompatibilities. There is as yet no explicit extension model. | ||
|
||
Prep instructions for ingredients are implicit steps that all come before | ||
the first recipe step. | ||
|
||
|
||
## Doctor Syntax recommends that | ||
|
||
|
@@ -91,7 +186,5 @@ Ingredients and groups are serialised as one JSON object, stored as | |
tools to suggest ways of scheduling the steps of multiple recipes you need | ||
to cook at once, such as for a dinner. | ||
|
||
* group and ingredient names are singular and lower-cased. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest we keep this advice for ingredient names, noting that while they may not appear in the ontology, they should still follow the convention that the ontology itself uses. |
||
|
||
* "large potato" as an ingredient can be more useful than "potato" with a | ||
quantity unit of "large". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might add something like: