cooklang / cooklang-ts Goto Github PK
View Code? Open in Web Editor NEWLightweight Cooklang parser implemented in TypeScript
Home Page: https://cooklang.github.io/cooklang-ts/
License: MIT License
Lightweight Cooklang parser implemented in TypeScript
Home Page: https://cooklang.github.io/cooklang-ts/
License: MIT License
Is your feature request related to a problem? Please describe.
I would like to extend the parsing to include the recipe step for each ingredient, i.e. if aubergine is used in steps 1 and 3, have that information included in the AST, is that possible? I know this is beyond the cooklang spec but I have browsed for cooklang extensions and haven't seen anything.
Describe the solution you'd like
The step number to be included in the AST perhaps through extending the cooklang parser
Describe alternatives you've considered
I have browsed for cooklang extensions in different languages (ts, py)
Describe the bug
The package used in readme example is cooklang-ts
which is not exist in npm. It should be @cooklang/cooklang-ts
?
This is a cross-post from a bug in the VS Code Cook Render extension, which uses this library.
User behavior: The following code at the top of a .cook document.
>> source: [Small Town Woman](https://www.smalltownwoman.com/easy-matzo-ball-soup/)
Expected result: The following Markdown:
**source:** [Small Town Woman](https://www.smalltownwoman.com/easy-matzo-ball-soup/)
Actual result:
## Small Town Woman
- (https://www\.smalltownwoman\.com/easy\-matzo\-ball\-soup/)
- [all remaining metadata are bullet-pointed, and ingredients/steps are not rendered]
According to the extension's dev (see link above), this is because there is no way to specify to the renderer whether this file is a recipe or shopping list. When the renderer sees a [
(as in a Markdown link), it switches to shopping list mode.
Is your feature request related to a problem? Please describe.
https://www.schema.org/Recipe uses their Duration type for things related to time. That type uses ISO8601. It would be nice to get the values as such to be able to convert to schema.org in renderers.
Describe the solution you'd like
A getter for it would be nice
Describe alternatives you've considered
Apart from parsing it myself none.
Additional context
I guess this may need a spec change to cooklang itself as well.
Describe the bug
Sometimes the parser fails to detect the closing }
after a timer declaration, and instead parses all of the following text as a unit for that timer.
To Reproduce
This is a simple script that reproduces the behaviour:
import { Parser } from "@cooklang/cooklang-ts";
const source = `Continue frying for ~{1%minute}. Add the @garlic{1%clove}.`;
const recipe = new Parser().parse(source);
console.log(JSON.stringify(recipe, null, 2));
This outputs:
{
"metadata": {},
"steps": [
[
{
"type": "text",
"value": "Continue frying for "
},
{
"type": "timer",
"name": "",
"quantity": 1,
"units": "minute}. Add the @garlic{1%clove"
},
{
"type": "text",
"value": "."
}
]
],
"shoppingList": {}
}
I've tested against the published npm version (1.0.0
) and the latest code on main
.
Expected behavior
In the above example, I expected the timer to have a unit of minute
(or minutes
), and for the following text and ingredient to be parsed correctly.
Describe the bug
If there's more than one inline comment (using [- comment -]
syntax) in a recipe file, everything between the opening of the first comment and the closing of the last comment is lost when parsing the recipe file.
This bug is only present in the code on the main
branch of the repository; it has not yet been released to npm.
To Reproduce
An example that reproduces the issue:
import { Parser } from "@cooklang/cooklang-ts";
const source = "Add some [- comment -] @salt and [- another comment -] @pepper";
const recipe = new Parser().parse(source);
console.log(recipe.steps);
When running this against the code in the npm release:
$ npm install @cooklang/cooklang-ts
This outputs:
[
[
{ type: 'text', value: 'Add some ' },
{ type: 'ingredient', name: 'salt', quantity: 'some' },
{ type: 'text', value: ' and ' },
{ type: 'ingredient', name: 'pepper', quantity: 'some' }
]
]
However, when running against the code in the main
branch:
$ npm uninstall @cooklang/cooklang-ts
$ npm install https://github.com/cooklang/cooklang-ts
This outputs:
[
[
{ type: 'text', value: 'Add some ' },
{ type: 'ingredient', name: 'pepper' }
]
]
Expected behavior
I expected the salt in the recipe to not be ignored!
Additional context
I think this is almost certainly because the regex matching that strips out comments at the start of parsing is being too greedy, and is matching everything between the first comment opening character and last comment closing character.
In the short term this can probably be fixed by adjusting the regex, but I think in the long-term a more robust token-based lexer/parser algorithm could be considered (similar to what is already done in cooklang-swift) to avoid the inherent fragility of regex matching.
Hello,
Could someone publish the most recent changes to the package to npm?
Thanks!
If you have CRLF ("\r\n") line endings enabled (i.e. on a windows machine), the following input:
>> source: example.com
step
parses as:
{
"ingredients": [],
"cookwares": [],
"metadata": {
"source": "example.com"
},
"steps": [
[
{
"type": "text",
"value": "\r"
}
],
[
{
"type": "text",
"value": "step"
}
]
],
"shoppingList": {}
}
When LF ("\n") line endings are enabled it parses correctly as:
{
"ingredients": [],
"cookwares": [],
"metadata": {
"source": "example.com"
},
"steps": [
[
{
"type": "text",
"value": "step"
}
]
],
"shoppingList": {}
}
Describe the bug
Small issue, but if there is a [
in metadata, we parse a recipe as a shopping-list.
I see this as a minor bug, but want to double-check it's unexpected before I put in any work to make a fix.
To Reproduce
Steps to reproduce the behavior:
// can ignore import syntax; this is standard usage via Deno
import { Parser } from 'npm:@cooklang/cooklang-ts';
const parser = new Parser()
console.log(parser.parse(`
>> source: https://www.youtube.com/watch?v=oTyVtAAKPRo
>> tags: [ breakfast ]
>> description: It's scrambled egg, with kimchi, and miso soup
>> servings: 1
Crack @eggs{2} into a #bowl, and beat with chopsticks
Make @Kombu broth (or dashi)
Heat a #small pan{} to high heat with #cooking oil{}
Slowly stir eggs onto pan, cook for about ~{10-15%sec}, then remove and add @sesame oil{} and @kimchi
Stir @miso paste{} into kombu broth, and bring to boil
Pour the soup into the egg-stirring bowl, and top with chopped @scallions
`))
this will produce a result of:
{
ingredients: [],
cookwares: [],
metadata: { source: "https://www.youtube.com/watch?v=oTyVtAAKPRo", tags: "" },
steps: [],
shoppingList: {
" breakfast ": [
{
name: ">> description: It's scrambled egg, with kimchi, and miso soup",
synonym: ""
},
{ name: ">> servings: 1", synonym: "" }
]
}
}
Expected behavior
Should parse as a recipe (with ingredients
, cookwares
, and steps
instead of `shoppingList:
{
ingredients: [
{ type: "ingredient", name: "eggs", quantity: 2, units: "" },
{ type: "ingredient", name: "Kombu", quantity: "some", units: "" },
...
{
type: "ingredient",
name: "scallions",
quantity: "some",
units: ""
}
],
cookwares: [
{ type: "cookware", name: "bowl,", quantity: 1 },
{ type: "cookware", name: "small pan", quantity: 1 },
{ type: "cookware", name: "cooking oil", quantity: 1 }
],
metadata: {
source: "https://www.youtube.com/watch?v=oTyVtAAKPRo",
tags: "[ breakfast ]",
description: "It's scrambled egg, with kimchi, and miso soup",
servings: "1"
},
shoppingList: {},
...
}
Describe the bug
When parsing a string with the Parser.parse()
method, groups for the parser tokens are not detected.
I have a simple page where I listen for changes in a text area and call the parse()
method on the user input
this.form.valueChanges
.pipe(takeUntil(this.unsubscribe$), debounceTime(200))
.subscribe((value) => {
if (!value.content) {
return;
}
console.log(value.content);
this.parsedRecipe = this.parser.parse(value.content)
console.log(this.parsedRecipe);
});
You can see the result of the two console.log
statements in the console in the screenshot.
In the screenshot you can also see that the parser code fails because the regex does not capture any groups.
The tokens seem to be correctly picked up by the regex but match.groups = undefined
This is really strange as I clearly remember that I used this lib in the past and it used to work.
I tried all past published versions and they have the same identicaly problem
To Reproduce
Steps to reproduce the behavior:
const parser = new Parser()
parser.parse(recipe)
Expected behavior
I used one of the example recipes as input for the parser I would expect the parser to correcly pick up the various elements of the recipe along the lines of:
{
"ingredients": [{
"type": "ingredient",
"name": "egg yoke"
"quantity": 1
},
...
],
"cookwares": [],
"metadata": {},
"steps": [
[
{
"type": "text",
"value": "Crack the @egg yoke{1} into a bowl, then add the @condenced milk{125%g} and @instant coffee{3tsp}, and mix until a nice caramel is formed. Do not allow to bubble."
}
],
...
"shoppingList": {}
}
Additional context
"dependencies": {
"@angular/cdk": "^15.0.0",
"@angular/common": "^15.0.0",
"@angular/core": "^15.0.0",
"@angular/fire": "^7.5.0",
"@angular/forms": "^15.0.0",
"@angular/platform-browser": "^15.0.0",
"@angular/platform-browser-dynamic": "^15.0.0",
"@angular/router": "^15.0.0",
"@capacitor/app": "4.1.1",
"@capacitor/core": "4.6.3",
"@capacitor/haptics": "4.1.0",
"@capacitor/keyboard": "4.1.1",
"@capacitor/status-bar": "4.1.1",
"@cooklang/cooklang-ts": "1.2.3",
"@ionic/angular": "^6.1.9",
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "7.0.0",
"ionicons": "^6.0.3",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
}
Should I add it as a list in the metadata section?
Describe the bug
A while ago I requested expanding the AST to include the step number(s) for the ingredients in a recipe. I've now realized that the cooklang specification suggests only mentioning each ingredient once:
## If you’re writing a recipe, only @mention each ingredient once.
After the first time, you can simply refer to the ingredient by name and relative quantity (e.g. “then put half the remaining bacon in the oven to crispen.”).
so because of this the step element in the AST doesn't properly work when an ingredient is used in several steps, e.g. Chop cabbage in step 1, put potatoes in the oven in step 2, combine potatoes and cabbage in step 3. With the cooklang suggested specification cabbage would only list step 1 and potatoes would only list step 2 rather than listing steps 1,3 and steps 1,2 respectively.
I realize that I can omit the cooklang spec suggestion and just add @ingredient{0} at every step but that would add ingredient 0, 0, 0
to the ingredients list when parsed.
Note while writing out the issue: I'm getting every step number to be wrong by 1 (step listed as 3 instead of 2 when ingredient listen in 2nd step)
To Reproduce
I have a recipe that repeats ingredients in several steps (tomatoes) as you can tell tomatoes only list step number 1 instead of all the steps they're needed in
import { Recipe, Parser, getImageURL } from '@cooklang/cooklang-ts';
const source = `
>> name: Stuffed Tomatoes with Rice
>> servings: 4
Preheat the #oven{} to ~{180°C}.
Cut the tops off of @tomatoes{4 large} and scoop out the insides to create a 'shell'. Keep the insides.
In a #pan{}, sauté @onions{1 chopped} and @garlic{2 cloves minced} in @olive oil{2 tbsp} until translucent.
Add the insides of the tomatoes (chopped) to the pan and cook for ~{5 minutes}.
Add @uncooked rice{1 cup} to the pan, along with @water{2 cups}, @salt{}, and @pepper{}. Allow the mixture to simmer until the rice is cooked, approximately ~{18 minutes}.
In the meantime, place the tomato 'shells' in a #baking dish{} and drizzle with a bit of olive oil, then bake for ~{10 minutes}.
Once the rice is cooked, add chopped @fresh basil{2 tbsp} and @grated Parmesan cheese{1/4 cup} to the pan and stir to combine.
Fill the pre-baked tomato shells with the rice mixture.
Return the stuffed tomatoes to the oven and bake for an additional ~{15 minutes}.
Garnish with more fresh basil and serve hot.
`;
console.log(
new Parser({
includeStepNumber: true
})
.parse(source)
.ingredients
);
I run it with ts-node
and I get:
[
{
type: 'ingredient',
name: 'tomatoes',
quantity: '4 large',
units: '',
step: 3
},
...
]
Expected behavior
Actually just noticed that I'm getting the wrong step number (3) instead of 2
[
{
type: 'ingredient',
name: 'tomatoes',
quantity: '4 large',
units: '',
steps: [2, 4, 6, 7]
},
...
]
Describe the bug
The page https://cooklang.org/docs/spec/, section Cookware
shows example where it should be possible to define cookware without the need to provide ending {}
. It should work for single cookware defined by single word.
The TS parser is not respecting this specification, which was confirmed by @dubadub on Discord.
This parser should be fixed or the specification should be changed to require {}
.
To Reproduce
Parse
Place the potatoes into a #pot.
Mash the potatoes with a #potato masher{}.
The problem is visible also by putting this text to https://biowaffeln.github.io/cooklang-parser/.
Expected behavior
Parser should recognize pot
and potato masher
as used cookware.
Now it incorrectly recognizes pot.
as cookware.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.