From 9d5a642a9bd5ca72bd899f5a624a0f77e6657ce1 Mon Sep 17 00:00:00 2001 From: Alexey Dubovskoy Date: Sun, 2 Mar 2025 19:07:16 +0000 Subject: [PATCH 1/3] proposal: draft 0015-other-recipes --- proposals/0015-other-recipes.md | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 proposals/0015-other-recipes.md diff --git a/proposals/0015-other-recipes.md b/proposals/0015-other-recipes.md new file mode 100644 index 0000000..dbea5a7 --- /dev/null +++ b/proposals/0015-other-recipes.md @@ -0,0 +1,91 @@ +# Reference other recipes + +* Proposal: [0015-other-recipes](0015-other-recipes.md) +* Authors: [Alexey Dubovskoy](https://github.com/dubadub) +* Status: **Awaiting review** + +## Introduction + +This proposal introduces the ability to reference ingredients +from other recipes using relative file paths. This allows recipes +to be modular and reusable, enabling cooks to maintain base recipes +(like sauces, dressings, or common components) that can be referenced +from multiple other recipes. + +Discussion thread: [Include other recipes](https://github.com/cooklang/spec/discussions/55) and +[Link/Include one recipe in another?](https://github.com/cooklang/spec/discussions/117) + +## Motivation + +Currently, Cooklang doesn't have a built-in way to reference other recipes. +This leads to several issues: + +1. Recipe duplication - Common components like sauces + or marinades need to be copied into each recipe that uses them +2. Maintenance challenges - When a base recipe is updated, + all copies need to be manually updated +3. Lack of modularity - Cannot break down complex + recipes into reusable components + +## Proposed solution + +Add support for referencing other recipes using relative file paths with the `@` syntax: + +```cooklang +Add @./Pesto Sauce{100%g} and stir. +Add @../sauces/Bechamel{200%ml} to the pan. +Add @./Hollandaise{150%g} and mix well. +``` + +## Detailed design + +The parser will: +1. Identify recipe references starting with `@` +2. Validate the relative path exists +3. Load and parse the referenced recipe +4. Apply the specified quantity to the referenced recipe +5. Include the referenced recipe's ingredients in shopping lists with adjusted quantities + +The grammar should be extended to support the following syntax: + +```ebnf:proposals/0015-other-recipes.md +recipe_reference ::= '@' relative_path '{' quantity '}' +relative_path ::= ('./' | '../' | '.\' | '..\') path_component +path_component ::= [a-zA-Z0-9_-]+ ('/' | '\' path_component)* +``` + +## Effect on applications which use Cooklang + +Changes in Cooklang syntax often require supplementary UI changes in +apps which use it (otherwise why these changes if nothing will +use them). Describe in details what changes should be implemented. +The detail in this section should be sufficient for someone +who is *not* one of the authors to be able to reasonably implement +the feature. + +### CookCLI (terminal and web-server) + +CookCLI needs to be updated to: +1. Support resolving relative paths when parsing recipes +2. Adjust the shopping list generation to include ingredients from referenced recipes +3. Add a new flag `--expand-references` to optionally show full contents of referenced recipes + +### Mobile applications + +Mobile apps need to: +1. Add UI elements to indicate referenced recipes (e.g., links or expandable sections) +2. Update shopping list generation to include referenced recipe ingredients +3. Allow users to navigate to referenced recipes +4. Provide visual feedback when referenced recipes cannot be found + +## Alternatives considered + +1. **Absolute paths only**: Considered only allowing absolute paths from recipe root, but this would make recipe collections less portable. + +2. **Recipe IDs**: Considered using unique IDs instead of file paths, but this would make recipes less human-readable and harder to manage manually. + +3. **Include syntax**: Considered using an include-style syntax like `!include`, but the `@` syntax is more consistent with Cooklang's existing conventions for ingredients. + +## Acknowledgments + +Thanks to the Cooklang community members who provided feedback on the relative path syntax and cross-platform compatibility considerations. From 801682138b7bbc5665523efe075001d057725c83 Mon Sep 17 00:00:00 2001 From: Alexey Dubovskoy Date: Sun, 2 Mar 2025 19:14:49 +0000 Subject: [PATCH 2/3] proposal: cleanup --- proposals/0015-other-recipes.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/proposals/0015-other-recipes.md b/proposals/0015-other-recipes.md index dbea5a7..81e09a9 100644 --- a/proposals/0015-other-recipes.md +++ b/proposals/0015-other-recipes.md @@ -80,12 +80,23 @@ Mobile apps need to: ## Alternatives considered -1. **Absolute paths only**: Considered only allowing absolute paths from recipe root, but this would make recipe collections less portable. +1. Separate syntax for referencing recipes `@@recipe_name{quantity}`. + This would be more consistent with the existing syntax for ingredients, + but it would be more verbose and harder to read. -2. **Recipe IDs**: Considered using unique IDs instead of file paths, but this would make recipes less human-readable and harder to manage manually. +2. Considered only allowing absolute paths from recipe root, + but this would make recipe collections less portable. -3. **Include syntax**: Considered using an include-style syntax like `!include`, but the `@` syntax is more consistent with Cooklang's existing conventions for ingredients. +3. Considered using unique IDs instead of file paths, + but this would make recipes less human-readable and harder to manage manually. + +4. Considered using an include-style syntax + like `!include`, but the `@` syntax is more consistent + with Cooklang's existing conventions for ingredients. ## Acknowledgments -Thanks to the Cooklang community members who provided feedback on the relative path syntax and cross-platform compatibility considerations. +Thanks to the Cooklang community members who provided feedback +on the relative path syntax and cross-platform compatibility considerations. +Thanks to [@dubadub](https://github.com/dubadub) for having that implemented with slightly different syntax +as [parser extension](https://github.com/cooklang/spec/blob/proposal/0015-other-recipes/proposals/0015-other-recipes.md). From 346a7a51d0fe46ceee7cd0c53ab4fbb9372eb7cd Mon Sep 17 00:00:00 2001 From: Alexey Dubovskoy Date: Sun, 9 Mar 2025 13:41:35 +0000 Subject: [PATCH 3/3] proposal: finilised proposal --- proposals/0015-other-recipes.md | 165 +++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 57 deletions(-) diff --git a/proposals/0015-other-recipes.md b/proposals/0015-other-recipes.md index 81e09a9..21fb14e 100644 --- a/proposals/0015-other-recipes.md +++ b/proposals/0015-other-recipes.md @@ -6,30 +6,32 @@ ## Introduction -This proposal introduces the ability to reference ingredients -from other recipes using relative file paths. This allows recipes -to be modular and reusable, enabling cooks to maintain base recipes -(like sauces, dressings, or common components) that can be referenced -from multiple other recipes. +This proposal introduces the ability to reference ingredients that are essentially +other recipes using relative file paths. This feature allows recipes to be modular +and reusable, enabling cooks to maintain base recipes (like sauces, dressings, or +common components) that can be referenced from multiple other recipes. -Discussion thread: [Include other recipes](https://github.com/cooklang/spec/discussions/55) and -[Link/Include one recipe in another?](https://github.com/cooklang/spec/discussions/117) +Discussion threads: +- [Include other recipes](https://github.com/cooklang/spec/discussions/55) +- [Link/Include one recipe in another?](https://github.com/cooklang/spec/discussions/117) ## Motivation -Currently, Cooklang doesn't have a built-in way to reference other recipes. -This leads to several issues: +Currently, Cooklang doesn't have a built-in way to reference other recipes. This +leads to several issues: -1. Recipe duplication - Common components like sauces - or marinades need to be copied into each recipe that uses them -2. Maintenance challenges - When a base recipe is updated, - all copies need to be manually updated -3. Lack of modularity - Cannot break down complex - recipes into reusable components +1. Recipe duplication - Common components like sauces or marinades need to be + copied into each recipe that uses them +2. Maintenance challenges - When a base recipe is updated, all copies need to be + manually updated +3. Limited organization capabilities - Cannot create meta-recipes or meal plans + (like "Thanksgiving Dinner" or "Weekly Meal Prep") that reference multiple + individual recipes with their respective quantities ## Proposed solution -Add support for referencing other recipes using relative file paths with the `@` syntax: +Add support for referencing other recipes using the existing @ ingredient syntax, +inferring relative file paths from the recipe name: ```cooklang Add @./Pesto Sauce{100%g} and stir. @@ -37,66 +39,115 @@ Add @../sauces/Bechamel{200%ml} to the pan. Add @./Hollandaise{150%g} and mix well. ``` +When the parser detects a relative path, it marks the ingredient as a reference +that can be parsed separately. + ## Detailed design -The parser will: -1. Identify recipe references starting with `@` -2. Validate the relative path exists -3. Load and parse the referenced recipe -4. Apply the specified quantity to the referenced recipe -5. Include the referenced recipe's ingredients in shopping lists with adjusted quantities - -The grammar should be extended to support the following syntax: - -```ebnf:proposals/0015-other-recipes.md -recipe_reference ::= '@' relative_path '{' quantity '}' -relative_path ::= ('./' | '../' | '.\' | '..\') path_component -path_component ::= [a-zA-Z0-9_-]+ ('/' | '\' path_component)* +Two main approaches have been considered for recipe references: + +### Approach 1: Special Recipe Reference Syntax + +This approach is implemented as a parser extension: + +```cooklang +Add @@Boiled Icing{6%tsp} to the cake. ``` -## Effect on applications which use Cooklang +**Advantages:** +- Works in non-filesystem environments (e.g., databases) +- More sharing-friendly as it doesn't assume specific directory structures +- Simpler for non-technical users who don't understand file paths +- Allows for flexible organization as recipes can be reorganized without updating + references + +**Disadvantages:** +- Requires recipe lookup/resolution rules to be defined +- May be ambiguous when multiple recipes have the same name +- Introduces new syntax that may not be immediately intuitive +- Requires clear documentation about lookup behavior -Changes in Cooklang syntax often require supplementary UI changes in -apps which use it (otherwise why these changes if nothing will -use them). Describe in details what changes should be implemented. -The detail in this section should be sufficient for someone -who is *not* one of the authors to be able to reasonably implement -the feature. +### Approach 2: File-based References (Current Proposal) -### CookCLI (terminal and web-server) +```cooklang +Add @./Boiled Icing{6%tsp} to the cake. +Add @../sauces/Bechamel{200%ml} to the pan. +``` + +**Advantages:** +- Explicit and unambiguous about recipe location +- Follows familiar file system patterns +- No inference required about recipe location +- Consistent with how other systems handle file references + +**Disadvantages:** +- References break when files are moved +- Less suitable for database-backed implementations +- Requires understanding of relative file paths +- May make recipe sharing more complex due to assumed directory structures + +After careful consideration, this proposal recommends the file-based approach +(Approach 2) because: +1. It maintains clarity and explicitness about recipe locations +2. It follows the Unix philosophy of being explicit rather than magical +3. It allows for clear error messages when recipes can't be found +4. It enables static analysis of recipe dependencies + +The parser will: +1. Identify recipe references starting with `@./`, `@../` or Windows `@.\`, `@..\` +2. Mark these ingredients as references and store their relative paths +3. Set the ingredient name as the file stem of the reference + +The parser will not: +1. Validate that the relative path exists +2. Load and parse the referenced recipe +3. Apply the specified quantity to the referenced recipe + +These responsibilities are left to the parser caller. + +## Effect on Applications Using Cooklang + +Applications should display a link to referenced recipes in ingredient lists. For +shopping lists, applications need to recursively apply quantities and extract +ingredients from referenced recipes. + +### CookCLI (Terminal and Web-server) CookCLI needs to be updated to: -1. Support resolving relative paths when parsing recipes -2. Adjust the shopping list generation to include ingredients from referenced recipes -3. Add a new flag `--expand-references` to optionally show full contents of referenced recipes +1. Output an extra note indicating that an ingredient is a reference and its path +2. Adjust shopping list generation to include ingredients from referenced recipes -### Mobile applications +### Mobile Applications Mobile apps need to: -1. Add UI elements to indicate referenced recipes (e.g., links or expandable sections) +1. Add UI elements to indicate referenced recipes with links 2. Update shopping list generation to include referenced recipe ingredients 3. Allow users to navigate to referenced recipes 4. Provide visual feedback when referenced recipes cannot be found -## Alternatives considered +### Implementation Considerations + +When implementing recipe references, systems should: +1. Maintain a cache of recipe locations to avoid repeated filesystem traversal +2. Provide clear error messages for missing or circular references +3. Provide tools for finding broken references when recipes are reorganized -1. Separate syntax for referencing recipes `@@recipe_name{quantity}`. - This would be more consistent with the existing syntax for ingredients, - but it would be more verbose and harder to read. +## Alternatives Considered -2. Considered only allowing absolute paths from recipe root, - but this would make recipe collections less portable. +1. Separate syntax for referencing recipes (`@@recipe_name{quantity}`): + While more consistent with existing ingredient syntax, this would be more + verbose and harder to read. -3. Considered using unique IDs instead of file paths, - but this would make recipes less human-readable and harder to manage manually. +2. Using unique IDs instead of file paths: + This would make recipes less human-readable and harder to manage manually. -4. Considered using an include-style syntax - like `!include`, but the `@` syntax is more consistent - with Cooklang's existing conventions for ingredients. +3. Using an include-style syntax (like `!include`): + The `@` syntax was chosen as it's more consistent with Cooklang's existing + conventions for ingredients. ## Acknowledgments -Thanks to the Cooklang community members who provided feedback -on the relative path syntax and cross-platform compatibility considerations. -Thanks to [@dubadub](https://github.com/dubadub) for having that implemented with slightly different syntax -as [parser extension](https://github.com/cooklang/spec/blob/proposal/0015-other-recipes/proposals/0015-other-recipes.md). +Thanks to the Cooklang community members who provided feedback on the relative path +syntax and cross-platform compatibility considerations. Special thanks to +[@Zheoni](https://github.com/Zheoni) for implementing the extension that preceded +this feature.