@tmlmt/cooklang-parser 3.0.0-alpha.21 → 3.0.0-alpha.23
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/dist/index.cjs +112 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -11
- package/dist/index.d.ts +20 -11
- package/dist/index.js +112 -47
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -1833,6 +1833,10 @@ function parseNestedMetaVar(content, varName) {
|
|
|
1833
1833
|
const match = content.match(nestedMetaVarRegex(varName));
|
|
1834
1834
|
if (!match) return void 0;
|
|
1835
1835
|
const nestedContent = match[1];
|
|
1836
|
+
const lines = nestedContent.split(/\r?\n/).filter((line) => line.trim() !== "");
|
|
1837
|
+
if (lines.length > 0 && lines[0].trim().startsWith("- ")) {
|
|
1838
|
+
return parseListItems(lines);
|
|
1839
|
+
}
|
|
1836
1840
|
return parseNestedBlock(nestedContent);
|
|
1837
1841
|
}
|
|
1838
1842
|
function parseNestedBlock(content) {
|
|
@@ -1859,7 +1863,7 @@ function parseNestedBlock(content) {
|
|
|
1859
1863
|
if (currentIndent !== baseIndent) {
|
|
1860
1864
|
throw new BadIndentationError();
|
|
1861
1865
|
}
|
|
1862
|
-
const keyValueMatch = line.match(/^
|
|
1866
|
+
const keyValueMatch = line.match(/^ *([^:\n]+?):\s*(.*)$/);
|
|
1863
1867
|
if (!keyValueMatch) {
|
|
1864
1868
|
i2++;
|
|
1865
1869
|
continue;
|
|
@@ -1871,7 +1875,7 @@ function parseNestedBlock(content) {
|
|
|
1871
1875
|
let j = i2 + 1;
|
|
1872
1876
|
while (j < lines.length) {
|
|
1873
1877
|
const childLine = lines[j];
|
|
1874
|
-
const childIndent = childLine.match(/^(
|
|
1878
|
+
const childIndent = childLine.match(/^( *)/)?.[1]?.length;
|
|
1875
1879
|
if (childIndent && childIndent > baseIndent) {
|
|
1876
1880
|
childLines.push(childLine);
|
|
1877
1881
|
j++;
|
|
@@ -1882,14 +1886,7 @@ function parseNestedBlock(content) {
|
|
|
1882
1886
|
if (childLines.length > 0) {
|
|
1883
1887
|
const firstChildTrimmed = childLines[0].trim();
|
|
1884
1888
|
if (firstChildTrimmed.startsWith("- ")) {
|
|
1885
|
-
|
|
1886
|
-
${childLines.join("\n")}`;
|
|
1887
|
-
const listResult = parseListMetaVar(reconstructedContent, key);
|
|
1888
|
-
if (listResult) {
|
|
1889
|
-
result[key] = listResult.map(
|
|
1890
|
-
(item) => parseMetadataValue(item)
|
|
1891
|
-
);
|
|
1892
|
-
}
|
|
1889
|
+
result[key] = parseListItems(childLines);
|
|
1893
1890
|
} else {
|
|
1894
1891
|
const childContent = childLines.join("\n");
|
|
1895
1892
|
const nested = parseNestedBlock(childContent);
|
|
@@ -1897,16 +1894,67 @@ ${childLines.join("\n")}`;
|
|
|
1897
1894
|
result[key] = nested;
|
|
1898
1895
|
}
|
|
1899
1896
|
}
|
|
1897
|
+
} else {
|
|
1898
|
+
result[key] = "";
|
|
1900
1899
|
}
|
|
1901
1900
|
i2 = j;
|
|
1902
1901
|
} else {
|
|
1903
|
-
result[key] =
|
|
1902
|
+
result[key] = parseSingleLineMetadataValue(rawValue);
|
|
1904
1903
|
i2++;
|
|
1905
1904
|
}
|
|
1906
1905
|
}
|
|
1907
1906
|
return result;
|
|
1908
1907
|
}
|
|
1909
|
-
function
|
|
1908
|
+
function parseListItems(childLines) {
|
|
1909
|
+
const listIndent = childLines[0].match(/^( *)/)?.[1]?.length;
|
|
1910
|
+
const groups = [];
|
|
1911
|
+
let currentGroup = [];
|
|
1912
|
+
for (const line of childLines) {
|
|
1913
|
+
const indent = line.match(/^( *)/)?.[1]?.length;
|
|
1914
|
+
if (indent === listIndent && line.trim().startsWith("- ")) {
|
|
1915
|
+
if (currentGroup.length > 0) {
|
|
1916
|
+
groups.push(currentGroup);
|
|
1917
|
+
}
|
|
1918
|
+
currentGroup = [line];
|
|
1919
|
+
} else {
|
|
1920
|
+
currentGroup.push(line);
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
groups.push(currentGroup);
|
|
1924
|
+
const isObjectItem = (group) => {
|
|
1925
|
+
if (group.length > 1) return true;
|
|
1926
|
+
const value = group[0].replace(/^\s*-\s*/, "").trim();
|
|
1927
|
+
return /^[^:\n]+:\s/.test(value);
|
|
1928
|
+
};
|
|
1929
|
+
const hasObjectItems = groups.some(isObjectItem);
|
|
1930
|
+
if (!hasObjectItems) {
|
|
1931
|
+
return groups.map((group) => {
|
|
1932
|
+
const value = group[0].replace(/^\s*-\s*/, "").trim();
|
|
1933
|
+
return parseSingleLineMetadataValue(value);
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
const items = [];
|
|
1937
|
+
for (const group of groups) {
|
|
1938
|
+
const firstLine = group[0];
|
|
1939
|
+
const afterDash = firstLine.replace(/^\s*-\s*/, "");
|
|
1940
|
+
const dashPrefixMatch = firstLine.match(/^( *-\s*)/);
|
|
1941
|
+
const contentIndent = dashPrefixMatch?.[1]?.length;
|
|
1942
|
+
const objectLines = [" ".repeat(contentIndent) + afterDash];
|
|
1943
|
+
for (let k = 1; k < group.length; k++) {
|
|
1944
|
+
objectLines.push(group[k]);
|
|
1945
|
+
}
|
|
1946
|
+
const parsed = parseNestedBlock(objectLines.join("\n"));
|
|
1947
|
+
if (parsed) {
|
|
1948
|
+
items.push(parsed);
|
|
1949
|
+
} else {
|
|
1950
|
+
items.push(
|
|
1951
|
+
parseSingleLineMetadataValue(afterDash.trim())
|
|
1952
|
+
);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
return items;
|
|
1956
|
+
}
|
|
1957
|
+
function parseSingleLineMetadataValue(rawValue) {
|
|
1910
1958
|
if (rawValue.startsWith("[") && rawValue.endsWith("]")) {
|
|
1911
1959
|
return rawValue.slice(1, -1).split(",").map((item) => item.trim());
|
|
1912
1960
|
}
|
|
@@ -1921,7 +1969,7 @@ function parseAnyMetaVar(content, varName) {
|
|
|
1921
1969
|
const list = parseListMetaVar(content, varName);
|
|
1922
1970
|
if (list) return list;
|
|
1923
1971
|
const simple = parseSimpleMetaVar(content, varName);
|
|
1924
|
-
if (simple) return
|
|
1972
|
+
if (simple) return parseSingleLineMetadataValue(simple);
|
|
1925
1973
|
return void 0;
|
|
1926
1974
|
}
|
|
1927
1975
|
function getNumericValueFromYield(v) {
|
|
@@ -2005,7 +2053,7 @@ function extractMetadata(content) {
|
|
|
2005
2053
|
const sourceName = parseSimpleMetaVar(metadataContent, "source.name");
|
|
2006
2054
|
const sourceUrl = parseSimpleMetaVar(metadataContent, "source.url");
|
|
2007
2055
|
const sourceAuthor = parseSimpleMetaVar(metadataContent, "source.author");
|
|
2008
|
-
if (sourceNested) {
|
|
2056
|
+
if (sourceNested && !Array.isArray(sourceNested)) {
|
|
2009
2057
|
const source = {};
|
|
2010
2058
|
if (typeof sourceNested.name === "string") source.name = sourceNested.name;
|
|
2011
2059
|
if (typeof sourceNested.url === "string") source.url = sourceNested.url;
|
|
@@ -2025,7 +2073,7 @@ function extractMetadata(content) {
|
|
|
2025
2073
|
const prepTime = parseSimpleMetaVar(metadataContent, "prep time") ?? parseSimpleMetaVar(metadataContent, "time.prep");
|
|
2026
2074
|
const cookTime = parseSimpleMetaVar(metadataContent, "cook time") ?? parseSimpleMetaVar(metadataContent, "time.cook");
|
|
2027
2075
|
const totalTime = parseSimpleMetaVar(metadataContent, "time required") ?? parseSimpleMetaVar(metadataContent, "time") ?? parseSimpleMetaVar(metadataContent, "duration");
|
|
2028
|
-
if (timeNested) {
|
|
2076
|
+
if (timeNested && !Array.isArray(timeNested)) {
|
|
2029
2077
|
const time = {};
|
|
2030
2078
|
if (typeof timeNested.prep === "string") time.prep = timeNested.prep;
|
|
2031
2079
|
if (typeof timeNested.cook === "string") time.cook = timeNested.cook;
|
|
@@ -2092,7 +2140,7 @@ function unionOfSets(s1, s2) {
|
|
|
2092
2140
|
}
|
|
2093
2141
|
function getAlternativeSignature(alternatives) {
|
|
2094
2142
|
if (!alternatives || alternatives.length === 0) return null;
|
|
2095
|
-
return alternatives.map((a2) => a2.index).sort((a2, b) => a2 - b).join(",");
|
|
2143
|
+
return alternatives.flat().map((a2) => a2.index).sort((a2, b) => a2 - b).join(",");
|
|
2096
2144
|
}
|
|
2097
2145
|
|
|
2098
2146
|
// src/classes/pantry.ts
|
|
@@ -3405,7 +3453,7 @@ var _Recipe = class _Recipe {
|
|
|
3405
3453
|
const currentSubgroupIdx = groupSubgroups.findIndex(
|
|
3406
3454
|
(sg) => sg.some((alt) => alt.itemId === item.id)
|
|
3407
3455
|
);
|
|
3408
|
-
alternativeRefs = groupSubgroups.filter((_, idx) => idx !== currentSubgroupIdx).
|
|
3456
|
+
alternativeRefs = groupSubgroups.filter((_, idx) => idx !== currentSubgroupIdx).map(
|
|
3409
3457
|
(subgroup) => subgroup.map((otherAlt) => {
|
|
3410
3458
|
const ref = {
|
|
3411
3459
|
index: otherAlt.index
|
|
@@ -3444,7 +3492,7 @@ var _Recipe = class _Recipe {
|
|
|
3444
3492
|
};
|
|
3445
3493
|
ref.quantities = [altQty];
|
|
3446
3494
|
}
|
|
3447
|
-
return ref;
|
|
3495
|
+
return [ref];
|
|
3448
3496
|
});
|
|
3449
3497
|
}
|
|
3450
3498
|
const altIndices = getAlternativeSignature(alternativeRefs) ?? "";
|
|
@@ -3465,28 +3513,36 @@ var _Recipe = class _Recipe {
|
|
|
3465
3513
|
if (!groupsForIng.has(signature)) {
|
|
3466
3514
|
groupsForIng.set(signature, {
|
|
3467
3515
|
quantities: [],
|
|
3468
|
-
alternativeQuantities: /* @__PURE__ */ new Map()
|
|
3516
|
+
alternativeQuantities: /* @__PURE__ */ new Map(),
|
|
3517
|
+
alternativeSubgroups: []
|
|
3469
3518
|
});
|
|
3470
3519
|
}
|
|
3471
3520
|
const group = groupsForIng.get(signature);
|
|
3472
3521
|
group.quantities.push(quantityEntry);
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3522
|
+
if (alternativeRefs && alternativeRefs.length > 0 && group.alternativeSubgroups.length === 0) {
|
|
3523
|
+
group.alternativeSubgroups = alternativeRefs.map(
|
|
3524
|
+
(subgroup) => subgroup.map((ref) => ref.index)
|
|
3525
|
+
);
|
|
3526
|
+
}
|
|
3527
|
+
for (const subgroup of alternativeRefs ?? []) {
|
|
3528
|
+
for (const ref of subgroup) {
|
|
3529
|
+
if (!group.alternativeQuantities.has(ref.index)) {
|
|
3530
|
+
group.alternativeQuantities.set(ref.index, []);
|
|
3531
|
+
}
|
|
3532
|
+
for (const altQty of ref.quantities ?? []) {
|
|
3533
|
+
const extended = toExtendedUnit({
|
|
3534
|
+
quantity: altQty.quantity,
|
|
3535
|
+
unit: altQty.unit
|
|
3536
|
+
});
|
|
3537
|
+
if (altQty.equivalents?.length) {
|
|
3538
|
+
const eqEntries = [
|
|
3539
|
+
extended,
|
|
3540
|
+
...altQty.equivalents.map((eq) => toExtendedUnit(eq))
|
|
3541
|
+
];
|
|
3542
|
+
group.alternativeQuantities.get(ref.index).push({ or: eqEntries });
|
|
3543
|
+
} else {
|
|
3544
|
+
group.alternativeQuantities.get(ref.index).push(extended);
|
|
3545
|
+
}
|
|
3490
3546
|
}
|
|
3491
3547
|
}
|
|
3492
3548
|
}
|
|
@@ -3609,17 +3665,25 @@ var _Recipe = class _Recipe {
|
|
|
3609
3665
|
this.unitSystem
|
|
3610
3666
|
);
|
|
3611
3667
|
const flattened = flattenPlainUnitGroup(summed);
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3668
|
+
let alternatives;
|
|
3669
|
+
if (group.alternativeSubgroups.length > 0) {
|
|
3670
|
+
alternatives = group.alternativeSubgroups.map(
|
|
3671
|
+
(subgroupIndices) => subgroupIndices.map((altIdx) => {
|
|
3672
|
+
const altQtys = group.alternativeQuantities.get(altIdx);
|
|
3673
|
+
return {
|
|
3674
|
+
index: altIdx,
|
|
3675
|
+
...altQtys.length > 0 && {
|
|
3676
|
+
quantities: flattenPlainUnitGroup(
|
|
3677
|
+
addEquivalentsAndSimplify(altQtys, this.unitSystem)
|
|
3678
|
+
).flatMap(
|
|
3679
|
+
/* v8 ignore next -- item.and branch requires complex nested AND-with-equivalents structure */
|
|
3680
|
+
(item) => "quantity" in item ? [item] : item.and
|
|
3681
|
+
)
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
})
|
|
3685
|
+
);
|
|
3686
|
+
}
|
|
3623
3687
|
for (const gq of flattened) {
|
|
3624
3688
|
if ("and" in gq) {
|
|
3625
3689
|
quantityGroups.push({
|
|
@@ -5144,6 +5208,7 @@ function getEffectiveChoices(recipe, variant) {
|
|
|
5144
5208
|
// v8 ignore if -- @preserve
|
|
5145
5209
|
/* v8 ignore else -- expliciting error type -- @preserve */
|
|
5146
5210
|
/* v8 ignore next 4 -- @preserve: defensive guard; regex always matches */
|
|
5211
|
+
/* v8 ignore else -- @preserve: empty non nested block will in practice be detected earlier */
|
|
5147
5212
|
// v8 ignore if -- @preserve: defensive type guard
|
|
5148
5213
|
/* v8 ignore if -- @preserve */
|
|
5149
5214
|
// v8 ignore next -- @preserve
|