@tmlmt/cooklang-parser 3.0.0-alpha.22 → 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.d.cts CHANGED
@@ -334,7 +334,7 @@ interface MetadataObject {
334
334
  * Represents any value that can appear in recipe metadata.
335
335
  * @category Types
336
336
  */
337
- type MetadataValue = string | number | (string | number)[] | MetadataObject | MetadataSource | MetadataTime | Yield | undefined;
337
+ type MetadataValue = string | number | (string | number | MetadataObject)[] | MetadataObject | MetadataSource | MetadataTime | Yield | undefined;
338
338
  /**
339
339
  * Represents the metadata of a recipe.
340
340
  * @category Types
package/dist/index.d.ts CHANGED
@@ -334,7 +334,7 @@ interface MetadataObject {
334
334
  * Represents any value that can appear in recipe metadata.
335
335
  * @category Types
336
336
  */
337
- type MetadataValue = string | number | (string | number)[] | MetadataObject | MetadataSource | MetadataTime | Yield | undefined;
337
+ type MetadataValue = string | number | (string | number | MetadataObject)[] | MetadataObject | MetadataSource | MetadataTime | Yield | undefined;
338
338
  /**
339
339
  * Represents the metadata of a recipe.
340
340
  * @category Types
package/dist/index.js CHANGED
@@ -1774,6 +1774,10 @@ function parseNestedMetaVar(content, varName) {
1774
1774
  const match = content.match(nestedMetaVarRegex(varName));
1775
1775
  if (!match) return void 0;
1776
1776
  const nestedContent = match[1];
1777
+ const lines = nestedContent.split(/\r?\n/).filter((line) => line.trim() !== "");
1778
+ if (lines.length > 0 && lines[0].trim().startsWith("- ")) {
1779
+ return parseListItems(lines);
1780
+ }
1777
1781
  return parseNestedBlock(nestedContent);
1778
1782
  }
1779
1783
  function parseNestedBlock(content) {
@@ -1800,7 +1804,7 @@ function parseNestedBlock(content) {
1800
1804
  if (currentIndent !== baseIndent) {
1801
1805
  throw new BadIndentationError();
1802
1806
  }
1803
- const keyValueMatch = line.match(/^[ ]*([^:\n]+?):\s*(.*)$/);
1807
+ const keyValueMatch = line.match(/^ *([^:\n]+?):\s*(.*)$/);
1804
1808
  if (!keyValueMatch) {
1805
1809
  i2++;
1806
1810
  continue;
@@ -1812,7 +1816,7 @@ function parseNestedBlock(content) {
1812
1816
  let j = i2 + 1;
1813
1817
  while (j < lines.length) {
1814
1818
  const childLine = lines[j];
1815
- const childIndent = childLine.match(/^([ ]*)/)?.[1]?.length;
1819
+ const childIndent = childLine.match(/^( *)/)?.[1]?.length;
1816
1820
  if (childIndent && childIndent > baseIndent) {
1817
1821
  childLines.push(childLine);
1818
1822
  j++;
@@ -1823,14 +1827,7 @@ function parseNestedBlock(content) {
1823
1827
  if (childLines.length > 0) {
1824
1828
  const firstChildTrimmed = childLines[0].trim();
1825
1829
  if (firstChildTrimmed.startsWith("- ")) {
1826
- const reconstructedContent = `${key}:
1827
- ${childLines.join("\n")}`;
1828
- const listResult = parseListMetaVar(reconstructedContent, key);
1829
- if (listResult) {
1830
- result[key] = listResult.map(
1831
- (item) => parseMetadataValue(item)
1832
- );
1833
- }
1830
+ result[key] = parseListItems(childLines);
1834
1831
  } else {
1835
1832
  const childContent = childLines.join("\n");
1836
1833
  const nested = parseNestedBlock(childContent);
@@ -1838,16 +1835,67 @@ ${childLines.join("\n")}`;
1838
1835
  result[key] = nested;
1839
1836
  }
1840
1837
  }
1838
+ } else {
1839
+ result[key] = "";
1841
1840
  }
1842
1841
  i2 = j;
1843
1842
  } else {
1844
- result[key] = parseMetadataValue(rawValue);
1843
+ result[key] = parseSingleLineMetadataValue(rawValue);
1845
1844
  i2++;
1846
1845
  }
1847
1846
  }
1848
1847
  return result;
1849
1848
  }
1850
- function parseMetadataValue(rawValue) {
1849
+ function parseListItems(childLines) {
1850
+ const listIndent = childLines[0].match(/^( *)/)?.[1]?.length;
1851
+ const groups = [];
1852
+ let currentGroup = [];
1853
+ for (const line of childLines) {
1854
+ const indent = line.match(/^( *)/)?.[1]?.length;
1855
+ if (indent === listIndent && line.trim().startsWith("- ")) {
1856
+ if (currentGroup.length > 0) {
1857
+ groups.push(currentGroup);
1858
+ }
1859
+ currentGroup = [line];
1860
+ } else {
1861
+ currentGroup.push(line);
1862
+ }
1863
+ }
1864
+ groups.push(currentGroup);
1865
+ const isObjectItem = (group) => {
1866
+ if (group.length > 1) return true;
1867
+ const value = group[0].replace(/^\s*-\s*/, "").trim();
1868
+ return /^[^:\n]+:\s/.test(value);
1869
+ };
1870
+ const hasObjectItems = groups.some(isObjectItem);
1871
+ if (!hasObjectItems) {
1872
+ return groups.map((group) => {
1873
+ const value = group[0].replace(/^\s*-\s*/, "").trim();
1874
+ return parseSingleLineMetadataValue(value);
1875
+ });
1876
+ }
1877
+ const items = [];
1878
+ for (const group of groups) {
1879
+ const firstLine = group[0];
1880
+ const afterDash = firstLine.replace(/^\s*-\s*/, "");
1881
+ const dashPrefixMatch = firstLine.match(/^( *-\s*)/);
1882
+ const contentIndent = dashPrefixMatch?.[1]?.length;
1883
+ const objectLines = [" ".repeat(contentIndent) + afterDash];
1884
+ for (let k = 1; k < group.length; k++) {
1885
+ objectLines.push(group[k]);
1886
+ }
1887
+ const parsed = parseNestedBlock(objectLines.join("\n"));
1888
+ if (parsed) {
1889
+ items.push(parsed);
1890
+ } else {
1891
+ items.push(
1892
+ parseSingleLineMetadataValue(afterDash.trim())
1893
+ );
1894
+ }
1895
+ }
1896
+ return items;
1897
+ }
1898
+ function parseSingleLineMetadataValue(rawValue) {
1851
1899
  if (rawValue.startsWith("[") && rawValue.endsWith("]")) {
1852
1900
  return rawValue.slice(1, -1).split(",").map((item) => item.trim());
1853
1901
  }
@@ -1862,7 +1910,7 @@ function parseAnyMetaVar(content, varName) {
1862
1910
  const list = parseListMetaVar(content, varName);
1863
1911
  if (list) return list;
1864
1912
  const simple = parseSimpleMetaVar(content, varName);
1865
- if (simple) return parseMetadataValue(simple);
1913
+ if (simple) return parseSingleLineMetadataValue(simple);
1866
1914
  return void 0;
1867
1915
  }
1868
1916
  function getNumericValueFromYield(v) {
@@ -1946,7 +1994,7 @@ function extractMetadata(content) {
1946
1994
  const sourceName = parseSimpleMetaVar(metadataContent, "source.name");
1947
1995
  const sourceUrl = parseSimpleMetaVar(metadataContent, "source.url");
1948
1996
  const sourceAuthor = parseSimpleMetaVar(metadataContent, "source.author");
1949
- if (sourceNested) {
1997
+ if (sourceNested && !Array.isArray(sourceNested)) {
1950
1998
  const source = {};
1951
1999
  if (typeof sourceNested.name === "string") source.name = sourceNested.name;
1952
2000
  if (typeof sourceNested.url === "string") source.url = sourceNested.url;
@@ -1966,7 +2014,7 @@ function extractMetadata(content) {
1966
2014
  const prepTime = parseSimpleMetaVar(metadataContent, "prep time") ?? parseSimpleMetaVar(metadataContent, "time.prep");
1967
2015
  const cookTime = parseSimpleMetaVar(metadataContent, "cook time") ?? parseSimpleMetaVar(metadataContent, "time.cook");
1968
2016
  const totalTime = parseSimpleMetaVar(metadataContent, "time required") ?? parseSimpleMetaVar(metadataContent, "time") ?? parseSimpleMetaVar(metadataContent, "duration");
1969
- if (timeNested) {
2017
+ if (timeNested && !Array.isArray(timeNested)) {
1970
2018
  const time = {};
1971
2019
  if (typeof timeNested.prep === "string") time.prep = timeNested.prep;
1972
2020
  if (typeof timeNested.cook === "string") time.cook = timeNested.cook;
@@ -5100,6 +5148,7 @@ export {
5100
5148
  // v8 ignore if -- @preserve
5101
5149
  /* v8 ignore else -- expliciting error type -- @preserve */
5102
5150
  /* v8 ignore next 4 -- @preserve: defensive guard; regex always matches */
5151
+ /* v8 ignore else -- @preserve: empty non nested block will in practice be detected earlier */
5103
5152
  // v8 ignore if -- @preserve: defensive type guard
5104
5153
  /* v8 ignore if -- @preserve */
5105
5154
  // v8 ignore next -- @preserve