cooklang-parse 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ import * as Ohm from "ohm-js";
2
+ import type { CooklangRecipe } from "./types";
3
+ declare const grammar: Ohm.Grammar;
4
+ export declare function parseCooklang(source: string): CooklangRecipe;
5
+ export { grammar };
6
+ //# sourceMappingURL=semantics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantics.d.ts","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAA;AAG7B,OAAO,KAAK,EACV,cAAc,EAOf,MAAM,SAAS,CAAA;AAEhB,QAAA,MAAM,OAAO,aAA6B,CAAA;AA8T1C,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CA0D5D;AAED,OAAO,EAAE,OAAO,EAAE,CAAA"}
@@ -0,0 +1,46 @@
1
+ export interface SourcePosition {
2
+ line: number;
3
+ column: number;
4
+ offset: number;
5
+ }
6
+ export interface ParseError {
7
+ message: string;
8
+ shortMessage?: string;
9
+ position: SourcePosition;
10
+ severity: "error" | "warning";
11
+ }
12
+ export interface CooklangRecipe {
13
+ metadata: Record<string, unknown>;
14
+ steps: RecipeStepItem[][];
15
+ ingredients: RecipeIngredient[];
16
+ cookware: RecipeCookware[];
17
+ timers: RecipeTimer[];
18
+ sections: string[];
19
+ notes: string[];
20
+ errors: ParseError[];
21
+ }
22
+ export type RecipeStepItem = {
23
+ type: "text";
24
+ value: string;
25
+ } | RecipeIngredient | RecipeCookware | RecipeTimer;
26
+ export interface RecipeIngredient {
27
+ type: "ingredient";
28
+ name: string;
29
+ quantity: number | string;
30
+ units: string;
31
+ fixed: boolean;
32
+ preparation?: string;
33
+ }
34
+ export interface RecipeCookware {
35
+ type: "cookware";
36
+ name: string;
37
+ quantity: number | string;
38
+ units: string;
39
+ }
40
+ export interface RecipeTimer {
41
+ type: "timer";
42
+ name: string;
43
+ quantity: number | string;
44
+ units: string;
45
+ }
46
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,KAAK,EAAE,cAAc,EAAE,EAAE,CAAA;IACzB,WAAW,EAAE,gBAAgB,EAAE,CAAA;IAC/B,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B,gBAAgB,GAChB,cAAc,GACd,WAAW,CAAA;AAEf,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;CACd"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Cooklang Grammar for Ohm
3
+ * Based on the official Cooklang specification at https://cooklang.org/docs/spec/
4
+ */
5
+
6
+ Cooklang {
7
+ // Main recipe structure
8
+ Recipe
9
+ = Metadata? RecipeItem*
10
+
11
+ // Recipe items can be interleaved
12
+ RecipeItem
13
+ = Section | Note | BlockComment | CommentLine | blankLine | spaceOnly | Step
14
+
15
+ // YAML front matter metadata
16
+ Metadata
17
+ = "---" YamlContent "---"
18
+
19
+ YamlContent
20
+ = (~"---" any)*
21
+
22
+ // Named section ==Name==
23
+ Section
24
+ = "==" sectionName "==" -- double
25
+ | "=" sectionName -- single
26
+
27
+ sectionName
28
+ = (~"==" ~newline any)+
29
+
30
+ // Recipe step - paragraphs separated by blank lines
31
+ Step
32
+ = StepLine+
33
+
34
+ StepLine
35
+ = ~(hspace* "-- ") ~(hspace* newline) ~sectionStart StepItem+ InlineComment? "\n"?
36
+
37
+ sectionStart
38
+ = "==" | "=" ~"=" ~"@"
39
+
40
+ // Items that can appear in a step
41
+ StepItem
42
+ = Ingredient | Cookware | Timer | Text
43
+
44
+ // Text without special Cooklang syntax
45
+ Text
46
+ = (~("\n" | "\r\n" | "\r" | "=" &"@" | "@" &ingredientStartChar | "#" &cookwareStartChar | "~" &wordChar | "~" &"{" | "-- " | "[-") any)+
47
+
48
+ ingredientStartChar
49
+ = wordChar | "@" | "&" | "?" | "+" | "-"
50
+
51
+ cookwareStartChar
52
+ = wordChar | "&" | "?" | "+" | "-"
53
+
54
+ // Ingredient: @name{quantity%unit} or @multi word name{}
55
+ // Fixed quantity: =@name{quantity%unit}
56
+ Ingredient
57
+ = FixedIndicator? "@" ingredientModifiers ingredientWord (hspace+ ingredientWord)+ ingredientAmount ingredientPreparation? -- multi
58
+ | FixedIndicator? "@" ingredientModifiers ingredientWord ingredientAmount? ingredientPreparation? -- single
59
+
60
+ ingredientPreparation
61
+ = "(" (~")" ~newline any)* ")"
62
+
63
+ ingredientModifiers
64
+ = ("@" | "&" | "?" | "+" | "-")*
65
+
66
+ ingredientWord
67
+ = componentWordChar+
68
+
69
+ ingredientAmount
70
+ = "{" (~"}" any)* "}"
71
+
72
+ FixedIndicator
73
+ = "="
74
+
75
+ // Cookware: #name or #multi word{}
76
+ Cookware
77
+ = "#" cookwareModifiers cookwareWord (hspace+ cookwareWord)+ cookwareAmount -- multi
78
+ | "#" cookwareModifiers cookwareWord cookwareAmount? -- single
79
+
80
+ cookwareModifiers
81
+ = ("&" | "?" | "+" | "-")*
82
+
83
+ cookwareWord
84
+ = componentWordChar+
85
+
86
+ cookwareAmount
87
+ = "{" (~"}" any)* "}"
88
+
89
+ // Timer: ~{quantity%unit} or ~name{quantity%unit}
90
+ Timer
91
+ = "~" timerName? "{" timerQuantity timerUnit? "}" -- withAmount
92
+ | "~" timerName -- word
93
+
94
+ timerName
95
+ = word+
96
+
97
+ timerQuantity
98
+ = (~"%" ~"}" any)+
99
+
100
+ timerUnit
101
+ = "%" (~"}" any)+
102
+
103
+ // Note lines (start with >)
104
+ Note
105
+ = ">" noteText Newline?
106
+
107
+ noteText
108
+ = (~"\n" ~"\r" ~">" any)+
109
+
110
+ // Inline comment: -- comment
111
+ InlineComment
112
+ = "-- " (~Newline any)*
113
+
114
+ // Full-line comments
115
+ CommentLine
116
+ = hspace* InlineComment Newline?
117
+
118
+ // Block comment: [- comment -]
119
+ BlockComment
120
+ = "[-" (~"-]" any)+ "-]"
121
+
122
+ // Component name word char - wordChar plus | for alias syntax
123
+ componentWordChar
124
+ = wordChar | "|"
125
+
126
+ // Basic tokens
127
+ word
128
+ = wordChar+
129
+
130
+ wordChar
131
+ = letter | digit | "_" | "-" | emoji | otherWordChar
132
+
133
+ emoji
134
+ = "\u{1F600}".."\u{1F64F}"
135
+ | "\u{1F300}".."\u{1F5FF}"
136
+ | "\u{1F680}".."\u{1F6FF}"
137
+ | "\u{2600}".."\u{26FF}"
138
+ | "\u{2700}".."\u{27BF}"
139
+ | "\u{1F900}".."\u{1F9FF}"
140
+ | "\u{1FA70}".."\u{1FAFF}"
141
+
142
+ otherWordChar
143
+ = "\u00C0".."\u00FF"
144
+ | "\u0100".."\u017F"
145
+ | "\u0400".."\u04FF"
146
+
147
+ newline
148
+ = "\n" | "\r\n" | "\r"
149
+
150
+ Newline
151
+ = newline
152
+
153
+ blankLine
154
+ = hspace* newline
155
+
156
+ spaceOnly
157
+ = hspace+ &end
158
+
159
+ hspace
160
+ = " " | "\t"
161
+
162
+ // Keep Ohm's implicit skipping from crossing lines.
163
+ space := "\t"
164
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "cooklang-parse",
3
+ "version": "1.0.0",
4
+ "description": "A simple, type-safe Cooklang parser built with Ohm.js",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "grammars"
18
+ ],
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/briansunter/cooklang-parse.git"
23
+ },
24
+ "homepage": "https://github.com/briansunter/cooklang-parse#readme",
25
+ "bugs": {
26
+ "url": "https://github.com/briansunter/cooklang-parse/issues"
27
+ },
28
+ "author": "Brian Sunter",
29
+ "keywords": [
30
+ "cooklang",
31
+ "parser",
32
+ "recipe",
33
+ "cooking",
34
+ "ohm",
35
+ "peg"
36
+ ],
37
+ "scripts": {
38
+ "build": "bun build src/index.ts --outdir dist --target=node --format=esm && tsc -p tsconfig.build.json",
39
+ "typecheck": "tsc --noEmit",
40
+ "lint": "biome check src/",
41
+ "lint:fix": "biome check --write src/",
42
+ "format": "biome format --write src/",
43
+ "check": "biome check src/",
44
+ "test": "bun test"
45
+ },
46
+ "devDependencies": {
47
+ "@biomejs/biome": "^2.3.11",
48
+ "@types/bun": "latest"
49
+ },
50
+ "peerDependencies": {
51
+ "typescript": "^5"
52
+ },
53
+ "dependencies": {
54
+ "ohm-js": "^17.3.0",
55
+ "yaml": "^2.8.2"
56
+ }
57
+ }