cooklang-parse 1.1.2 → 1.2.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.
- package/README.md +69 -30
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10698 -9909
- package/dist/parse-cooklang.d.ts +3 -0
- package/dist/parse-cooklang.d.ts.map +1 -0
- package/dist/parser/component-builders.d.ts +10 -0
- package/dist/parser/component-builders.d.ts.map +1 -0
- package/dist/parser/extensions.d.ts +5 -0
- package/dist/parser/extensions.d.ts.map +1 -0
- package/dist/parser/frontmatter.d.ts +9 -0
- package/dist/parser/frontmatter.d.ts.map +1 -0
- package/dist/parser/internal-types.d.ts +31 -0
- package/dist/parser/internal-types.d.ts.map +1 -0
- package/dist/parser/metadata.d.ts +8 -0
- package/dist/parser/metadata.d.ts.map +1 -0
- package/dist/parser/ohm-ast.d.ts +14 -0
- package/dist/parser/ohm-ast.d.ts.map +1 -0
- package/dist/parser/preprocess.d.ts +10 -0
- package/dist/parser/preprocess.d.ts.map +1 -0
- package/dist/parser/quantity.d.ts +3 -0
- package/dist/parser/quantity.d.ts.map +1 -0
- package/dist/parser/raw-step-items.d.ts +4 -0
- package/dist/parser/raw-step-items.d.ts.map +1 -0
- package/dist/parser/step-processing.d.ts +14 -0
- package/dist/parser/step-processing.d.ts.map +1 -0
- package/dist/semantics.d.ts +2 -5
- package/dist/semantics.d.ts.map +1 -1
- package/dist/types.d.ts +62 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/grammars/cooklang.ohm +43 -24
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-cooklang.d.ts","sourceRoot":"","sources":["../src/parse-cooklang.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EAQrB,MAAM,SAAS,CAAA;AAehB,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,cAAc,CAkRhG"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RecipeCookware, RecipeIngredient } from "../types";
|
|
2
|
+
/** Build an ingredient from structured grammar data. */
|
|
3
|
+
export declare function buildIngredient(mods: string, rawName: string, amount: {
|
|
4
|
+
quantity: string | number;
|
|
5
|
+
units: string;
|
|
6
|
+
fixed: boolean;
|
|
7
|
+
}, note: string | undefined): RecipeIngredient;
|
|
8
|
+
/** Build a cookware item from structured grammar data. */
|
|
9
|
+
export declare function buildCookware(mods: string, rawName: string, quantity: string | number, note: string | undefined): RecipeCookware;
|
|
10
|
+
//# sourceMappingURL=component-builders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-builders.d.ts","sourceRoot":"","sources":["../../src/parser/component-builders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,cAAc,EACd,gBAAgB,EAEjB,MAAM,UAAU,CAAA;AAoBjB,wDAAwD;AACxD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,EACpE,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,gBAAgB,CAWlB;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,cAAc,CAkBhB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ParseCooklangOptions } from "../types";
|
|
2
|
+
import type { ExtensionState } from "./internal-types";
|
|
3
|
+
export declare function resolveExtensions(options?: ParseCooklangOptions): ExtensionState;
|
|
4
|
+
export declare function hasAllExtensions(options?: ParseCooklangOptions): boolean;
|
|
5
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/parser/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,cAAc,CAKhF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAExE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SourcePosition } from "../types";
|
|
2
|
+
interface YamlParseResult {
|
|
3
|
+
data: Record<string, unknown>;
|
|
4
|
+
warning?: string;
|
|
5
|
+
position?: SourcePosition;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseYamlFrontmatter(content: string, yamlStartOffset: number): YamlParseResult;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=frontmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/parser/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAA;CAC1B;AAyBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,eAAe,CAoC9F"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RecipeStepItem, SourcePosition } from "../types";
|
|
2
|
+
export interface ExtensionState {
|
|
3
|
+
modes: boolean;
|
|
4
|
+
inlineQuantities: boolean;
|
|
5
|
+
}
|
|
6
|
+
export type DefineMode = "all" | "components" | "steps" | "text";
|
|
7
|
+
export interface DirectiveNode {
|
|
8
|
+
type: "directive";
|
|
9
|
+
key: string;
|
|
10
|
+
rawValue: string;
|
|
11
|
+
rawLine: string;
|
|
12
|
+
position: SourcePosition;
|
|
13
|
+
}
|
|
14
|
+
export type SemanticItem = {
|
|
15
|
+
kind: "step";
|
|
16
|
+
items: RecipeStepItem[];
|
|
17
|
+
} | {
|
|
18
|
+
kind: "section";
|
|
19
|
+
name: string;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "note";
|
|
22
|
+
text: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "directive";
|
|
25
|
+
directive: DirectiveNode;
|
|
26
|
+
};
|
|
27
|
+
export interface SemanticResult {
|
|
28
|
+
frontmatter: string | null;
|
|
29
|
+
items: SemanticItem[];
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=internal-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-types.d.ts","sourceRoot":"","sources":["../../src/parser/internal-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAEhE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,cAAc,CAAA;CACzB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,aAAa,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParseError } from "../types";
|
|
2
|
+
import type { DefineMode, DirectiveNode } from "./internal-types";
|
|
3
|
+
/** Validate standard metadata entries and push type-mismatch warnings. */
|
|
4
|
+
export declare function checkStandardMetadata(metadata: Record<string, unknown>, warnings: ParseError[], directives: DirectiveNode[]): void;
|
|
5
|
+
export declare function isSpecialDirectiveKey(key: string): boolean;
|
|
6
|
+
export declare function applyDirectiveMode(current: DefineMode, key: string, rawValue: string): DefineMode;
|
|
7
|
+
export declare function createDeprecatedMetadataWarning(directives: DirectiveNode[]): ParseError | null;
|
|
8
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/parser/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,UAAU,CAAA;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AA4GjE,0EAA0E;AAC1E,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,EAAE,UAAU,EAAE,EACtB,UAAU,EAAE,aAAa,EAAE,GAC1B,IAAI,CAuBN;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAYjG;AAED,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,UAAU,GAAG,IAAI,CAwB9F"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as Ohm from "ohm-js";
|
|
2
|
+
import type { ParseError } from "../types";
|
|
3
|
+
import type { SemanticResult } from "./internal-types";
|
|
4
|
+
declare const grammar: Ohm.Grammar;
|
|
5
|
+
type ParseWithOhmResult = {
|
|
6
|
+
ok: true;
|
|
7
|
+
value: SemanticResult;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: ParseError;
|
|
11
|
+
};
|
|
12
|
+
export declare function parseWithOhm(source: string): ParseWithOhmResult;
|
|
13
|
+
export { grammar };
|
|
14
|
+
//# sourceMappingURL=ohm-ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ohm-ast.d.ts","sourceRoot":"","sources":["../../src/parser/ohm-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,UAAU,CAAA;AAG1D,OAAO,KAAK,EAA+B,cAAc,EAAE,MAAM,kBAAkB,CAAA;AASnF,QAAA,MAAM,OAAO,aAA6B,CAAA;AAwN1C,KAAK,kBAAkB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAA;AAEhG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAsB/D;AAED,OAAO,EAAE,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Strip block comments [- ... -] from source, preserving only newlines. */
|
|
2
|
+
export declare function stripBlockComments(source: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Normalize marker spacing variants accepted by cooklang-rs parser:
|
|
5
|
+
* - `@ example{}` -> `@example{}`
|
|
6
|
+
* - `# 10{}` -> `#10{}`
|
|
7
|
+
* - `~ {5}` -> `~{5}`
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeMarkerSpacing(source: string): string;
|
|
10
|
+
//# sourceMappingURL=preprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preprocess.d.ts","sourceRoot":"","sources":["../../src/parser/preprocess.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAK7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantity.d.ts","sourceRoot":"","sources":["../../src/parser/quantity.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAyB1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-step-items.d.ts","sourceRoot":"","sources":["../../src/parser/raw-step-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAI9C,wBAAgB,SAAS,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAG3E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAuCjE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ParseError, RecipeInlineQuantity, RecipeStepItem } from "../types";
|
|
2
|
+
import type { DefineMode } from "./internal-types";
|
|
3
|
+
/** Merge adjacent text items into single items (e.g. across soft line breaks). */
|
|
4
|
+
export declare function mergeConsecutiveTexts(items: RecipeStepItem[]): RecipeStepItem[];
|
|
5
|
+
/** Collect unique items of a given type across parsed step items. */
|
|
6
|
+
export declare function collectUniqueFromSteps<T extends RecipeStepItem>(allSteps: RecipeStepItem[][], type: RecipeStepItem["type"], key: (item: T) => string): T[];
|
|
7
|
+
export declare function applyInlineQuantityExtraction(stepItems: RecipeStepItem[], inlineQuantities: RecipeInlineQuantity[], enabled: boolean): RecipeStepItem[];
|
|
8
|
+
export declare function applyAdvancedUnits(stepItems: RecipeStepItem[], enabled: boolean): RecipeStepItem[];
|
|
9
|
+
export declare function applyAliasMode(stepItems: RecipeStepItem[], aliasEnabled: boolean): RecipeStepItem[];
|
|
10
|
+
export declare function splitInvalidMarkerTextItems(stepItems: RecipeStepItem[]): RecipeStepItem[];
|
|
11
|
+
export declare function warnTimerMissingUnit(stepItems: RecipeStepItem[], warnings: ParseError[]): void;
|
|
12
|
+
export declare function warnUnnecessaryScalingLock(stepItems: RecipeStepItem[], warnings: ParseError[]): void;
|
|
13
|
+
export declare function checkStepsModeReferences(stepItems: RecipeStepItem[], defineMode: DefineMode, knownIngredients: Set<string>, knownCookware: Set<string>, errors: ParseError[]): void;
|
|
14
|
+
//# sourceMappingURL=step-processing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-processing.d.ts","sourceRoot":"","sources":["../../src/parser/step-processing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAGlD,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAW/E;AAED,qEAAqE;AACrE,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,cAAc,EAC7D,QAAQ,EAAE,cAAc,EAAE,EAAE,EAC5B,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GACvB,CAAC,EAAE,CAcL;AAkGD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,cAAc,EAAE,EAC3B,gBAAgB,EAAE,oBAAoB,EAAE,EACxC,OAAO,EAAE,OAAO,GACf,cAAc,EAAE,CAWlB;AA0BD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,EAAE,EAC3B,OAAO,EAAE,OAAO,GACf,cAAc,EAAE,CAgBlB;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,cAAc,EAAE,EAC3B,YAAY,EAAE,OAAO,GACpB,cAAc,EAAE,CAmBlB;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAyDzF;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAW9F;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,cAAc,EAAE,EAC3B,QAAQ,EAAE,UAAU,EAAE,GACrB,IAAI,CASN;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,cAAc,EAAE,EAC3B,UAAU,EAAE,UAAU,EACtB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,EAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAC1B,MAAM,EAAE,UAAU,EAAE,GACnB,IAAI,CA0BN"}
|
package/dist/semantics.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
declare const grammar: Ohm.Grammar;
|
|
4
|
-
export declare function parseCooklang(source: string): CooklangRecipe;
|
|
5
|
-
export { grammar };
|
|
1
|
+
export { parseCooklang } from "./parse-cooklang";
|
|
2
|
+
export { grammar } from "./parser/ohm-ast";
|
|
6
3
|
//# sourceMappingURL=semantics.d.ts.map
|
package/dist/semantics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantics.d.ts","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"semantics.d.ts","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,35 +8,88 @@ export interface ParseError {
|
|
|
8
8
|
shortMessage?: string;
|
|
9
9
|
position: SourcePosition;
|
|
10
10
|
severity: "error" | "warning";
|
|
11
|
+
help?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ParseCooklangOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Parser behavior preset:
|
|
16
|
+
* - "canonical": canonical/spec-oriented behavior (extensions off)
|
|
17
|
+
* - "all": cooklang-rs default behavior (extensions on)
|
|
18
|
+
*/
|
|
19
|
+
extensions?: "canonical" | "all";
|
|
20
|
+
}
|
|
21
|
+
export type SectionContent = {
|
|
22
|
+
type: "step";
|
|
23
|
+
items: RecipeStepItem[];
|
|
24
|
+
number?: number;
|
|
25
|
+
} | {
|
|
26
|
+
type: "text";
|
|
27
|
+
value: string;
|
|
28
|
+
};
|
|
29
|
+
export interface RecipeSection {
|
|
30
|
+
name: string | null;
|
|
31
|
+
content: SectionContent[];
|
|
11
32
|
}
|
|
12
33
|
export interface CooklangRecipe {
|
|
13
34
|
metadata: Record<string, unknown>;
|
|
14
|
-
|
|
35
|
+
sections: RecipeSection[];
|
|
15
36
|
ingredients: RecipeIngredient[];
|
|
16
37
|
cookware: RecipeCookware[];
|
|
17
38
|
timers: RecipeTimer[];
|
|
18
|
-
|
|
19
|
-
notes: string[];
|
|
39
|
+
inlineQuantities: RecipeInlineQuantity[];
|
|
20
40
|
errors: ParseError[];
|
|
21
41
|
warnings: ParseError[];
|
|
22
42
|
}
|
|
23
43
|
export type RecipeStepItem = {
|
|
24
44
|
type: "text";
|
|
25
45
|
value: string;
|
|
26
|
-
} | RecipeIngredient | RecipeCookware | RecipeTimer
|
|
46
|
+
} | RecipeIngredient | RecipeCookware | RecipeTimer | {
|
|
47
|
+
type: "inline_quantity";
|
|
48
|
+
index: number;
|
|
49
|
+
};
|
|
50
|
+
export type ComponentRelation = {
|
|
51
|
+
type: "definition";
|
|
52
|
+
referencedFrom: number[];
|
|
53
|
+
definedInStep: boolean;
|
|
54
|
+
} | {
|
|
55
|
+
type: "reference";
|
|
56
|
+
referencesTo: number;
|
|
57
|
+
};
|
|
58
|
+
export type IngredientReferenceTarget = "ingredient" | "step" | "section";
|
|
59
|
+
export interface IngredientRelation {
|
|
60
|
+
type: "definition" | "reference";
|
|
61
|
+
referencedFrom?: number[];
|
|
62
|
+
definedInStep?: boolean;
|
|
63
|
+
referencesTo?: number;
|
|
64
|
+
referenceTarget?: IngredientReferenceTarget;
|
|
65
|
+
}
|
|
66
|
+
export interface RecipeModifiers {
|
|
67
|
+
recipe?: boolean;
|
|
68
|
+
reference?: boolean;
|
|
69
|
+
hidden?: boolean;
|
|
70
|
+
optional?: boolean;
|
|
71
|
+
new?: boolean;
|
|
72
|
+
}
|
|
27
73
|
export interface RecipeIngredient {
|
|
28
74
|
type: "ingredient";
|
|
29
75
|
name: string;
|
|
76
|
+
alias?: string;
|
|
30
77
|
quantity: number | string;
|
|
31
78
|
units: string;
|
|
32
79
|
fixed: boolean;
|
|
33
|
-
|
|
80
|
+
note?: string;
|
|
81
|
+
modifiers: RecipeModifiers;
|
|
82
|
+
relation: IngredientRelation;
|
|
34
83
|
}
|
|
35
84
|
export interface RecipeCookware {
|
|
36
85
|
type: "cookware";
|
|
37
86
|
name: string;
|
|
87
|
+
alias?: string;
|
|
38
88
|
quantity: number | string;
|
|
39
89
|
units: string;
|
|
90
|
+
note?: string;
|
|
91
|
+
modifiers: RecipeModifiers;
|
|
92
|
+
relation: ComponentRelation;
|
|
40
93
|
}
|
|
41
94
|
export interface RecipeTimer {
|
|
42
95
|
type: "timer";
|
|
@@ -44,4 +97,8 @@ export interface RecipeTimer {
|
|
|
44
97
|
quantity: number | string;
|
|
45
98
|
units: string;
|
|
46
99
|
}
|
|
100
|
+
export interface RecipeInlineQuantity {
|
|
101
|
+
quantity: number | string;
|
|
102
|
+
units: string;
|
|
103
|
+
}
|
|
47
104
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEjE"}
|
package/grammars/cooklang.ohm
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
Cooklang {
|
|
7
7
|
// Main recipe structure
|
|
8
8
|
Recipe
|
|
9
|
-
= Metadata? RecipeItem*
|
|
9
|
+
= (MetadataDirective | blankLine)* Metadata? RecipeItem*
|
|
10
10
|
|
|
11
11
|
// Recipe items can be interleaved
|
|
12
12
|
RecipeItem
|
|
13
|
-
= Section |
|
|
13
|
+
= Section | MetadataDirective | Note | CommentLine | blankLine | spaceOnly | Step
|
|
14
14
|
|
|
15
15
|
// YAML front matter metadata
|
|
16
16
|
Metadata
|
|
@@ -32,7 +32,7 @@ Cooklang {
|
|
|
32
32
|
= StepLine+
|
|
33
33
|
|
|
34
34
|
StepLine
|
|
35
|
-
= ~(hspace* "-- ") ~(hspace* newline) ~sectionStart StepItem+ InlineComment? "\n"?
|
|
35
|
+
= ~(hspace* "-- ") ~(hspace* newline) ~sectionStart ~MetadataDirective StepItem+ InlineComment? "\n"?
|
|
36
36
|
|
|
37
37
|
sectionStart
|
|
38
38
|
= "==" | "=" ~"=" ~"@"
|
|
@@ -43,7 +43,7 @@ Cooklang {
|
|
|
43
43
|
|
|
44
44
|
// Text without special Cooklang syntax
|
|
45
45
|
Text
|
|
46
|
-
= (~("\n" | "\r\n" | "\r" | "
|
|
46
|
+
= (~("\n" | "\r\n" | "\r" | "@" &ingredientStartChar | "#" &cookwareStartChar | "~" &wordChar | "~" &"{" | "-- ") any)+
|
|
47
47
|
|
|
48
48
|
ingredientStartChar
|
|
49
49
|
= wordChar | "@" | "&" | "?" | "+" | "-"
|
|
@@ -52,12 +52,11 @@ Cooklang {
|
|
|
52
52
|
= wordChar | "&" | "?" | "+" | "-"
|
|
53
53
|
|
|
54
54
|
// Ingredient: @name{quantity%unit} or @multi word name{}
|
|
55
|
-
// Fixed quantity: =@name{quantity%unit}
|
|
56
55
|
Ingredient
|
|
57
|
-
=
|
|
58
|
-
|
|
|
56
|
+
= "@" ingredientModifiers ingredientWord (hspace+ ingredientWord)+ ingredientAmount ingredientNote? -- multi
|
|
57
|
+
| "@" ingredientModifiers ingredientWord ingredientAmount? ingredientNote? -- single
|
|
59
58
|
|
|
60
|
-
|
|
59
|
+
ingredientNote
|
|
61
60
|
= "(" (~")" ~newline any)* ")"
|
|
62
61
|
|
|
63
62
|
ingredientModifiers
|
|
@@ -67,15 +66,17 @@ Cooklang {
|
|
|
67
66
|
= componentWordChar+
|
|
68
67
|
|
|
69
68
|
ingredientAmount
|
|
70
|
-
= "{"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
= "="
|
|
69
|
+
= "{" amountFixed? amountQuantity "%" amountUnit "}" -- withUnit
|
|
70
|
+
| "{" hspace* amountFixed? hspace* "}" -- empty
|
|
71
|
+
| "{" amountFixed? amountQuantity "}" -- quantityOnly
|
|
74
72
|
|
|
75
73
|
// Cookware: #name or #multi word{}
|
|
76
74
|
Cookware
|
|
77
|
-
= "#" cookwareModifiers cookwareWord (hspace+ cookwareWord)+ cookwareAmount -- multi
|
|
78
|
-
| "#" cookwareModifiers cookwareWord cookwareAmount? -- single
|
|
75
|
+
= "#" cookwareModifiers cookwareWord (hspace+ cookwareWord)+ cookwareAmount cookwareNote? -- multi
|
|
76
|
+
| "#" cookwareModifiers cookwareWord cookwareAmount? cookwareNote? -- single
|
|
77
|
+
|
|
78
|
+
cookwareNote
|
|
79
|
+
= "(" (~")" ~newline any)* ")"
|
|
79
80
|
|
|
80
81
|
cookwareModifiers
|
|
81
82
|
= ("&" | "?" | "+" | "-")*
|
|
@@ -84,21 +85,30 @@ Cooklang {
|
|
|
84
85
|
= componentWordChar+
|
|
85
86
|
|
|
86
87
|
cookwareAmount
|
|
87
|
-
= "{"
|
|
88
|
+
= "{" hspace* "}" -- empty
|
|
89
|
+
| "{" cookwareQuantity "}" -- withQuantity
|
|
90
|
+
|
|
91
|
+
cookwareQuantity
|
|
92
|
+
= (~"}" any)+
|
|
88
93
|
|
|
89
94
|
// Timer: ~{quantity%unit} or ~name{quantity%unit}
|
|
90
95
|
Timer
|
|
91
|
-
= "~" timerName? "{"
|
|
92
|
-
| "~" timerName
|
|
96
|
+
= "~" timerName? "{" amountQuantity "%" amountUnit "}" -- withUnit
|
|
97
|
+
| "~" timerName? "{" amountQuantity "}" -- quantityOnly
|
|
98
|
+
| "~" timerName -- word
|
|
93
99
|
|
|
94
100
|
timerName
|
|
95
101
|
= word+
|
|
96
102
|
|
|
97
|
-
|
|
103
|
+
// Shared amount sub-rules for ingredients and timers
|
|
104
|
+
amountFixed
|
|
105
|
+
= hspace* "=" hspace*
|
|
106
|
+
|
|
107
|
+
amountQuantity
|
|
98
108
|
= (~"%" ~"}" any)+
|
|
99
109
|
|
|
100
|
-
|
|
101
|
-
=
|
|
110
|
+
amountUnit
|
|
111
|
+
= (~"}" any)+
|
|
102
112
|
|
|
103
113
|
// Note lines (start with >)
|
|
104
114
|
Note
|
|
@@ -107,6 +117,19 @@ Cooklang {
|
|
|
107
117
|
noteText
|
|
108
118
|
= (~"\n" ~"\r" ~">" any)+
|
|
109
119
|
|
|
120
|
+
// Metadata directive: >> key: value
|
|
121
|
+
MetadataDirective
|
|
122
|
+
= hspace* ">>" directiveBody Newline?
|
|
123
|
+
|
|
124
|
+
directiveBody
|
|
125
|
+
= hspace* directiveKey hspace* ":" directiveValue
|
|
126
|
+
|
|
127
|
+
directiveKey
|
|
128
|
+
= (~":" ~newline any)+
|
|
129
|
+
|
|
130
|
+
directiveValue
|
|
131
|
+
= (~newline any)*
|
|
132
|
+
|
|
110
133
|
// Inline comment: -- comment
|
|
111
134
|
InlineComment
|
|
112
135
|
= "-- " (~Newline any)*
|
|
@@ -115,10 +138,6 @@ Cooklang {
|
|
|
115
138
|
CommentLine
|
|
116
139
|
= hspace* InlineComment Newline?
|
|
117
140
|
|
|
118
|
-
// Block comment: [- comment -]
|
|
119
|
-
BlockComment
|
|
120
|
-
= "[-" (~"-]" any)+ "-]"
|
|
121
|
-
|
|
122
141
|
// Component name word char - wordChar plus | for alias syntax
|
|
123
142
|
componentWordChar
|
|
124
143
|
= wordChar | "|"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cooklang-parse",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A simple, type-safe Cooklang parser built with Ohm.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@biomejs/biome": "^2.3.11",
|
|
48
|
-
"@types/bun": "latest"
|
|
48
|
+
"@types/bun": "latest",
|
|
49
|
+
"lefthook": "^2.1.0"
|
|
49
50
|
},
|
|
50
51
|
"peerDependencies": {
|
|
51
52
|
"typescript": "^5"
|