refactor: simplify parse ingredients code
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
type DocumentChild,
|
||||
getTextOfChild,
|
||||
getTextOfRange,
|
||||
parseDocument,
|
||||
} from "@lib/documents.ts";
|
||||
@@ -9,7 +8,7 @@ import { createCrud } from "@lib/crud.ts";
|
||||
import { extractHashTags } from "@lib/string.ts";
|
||||
import { Ingredient, IngredientGroup } from "@lib/recipeSchema.ts";
|
||||
import { fixRenderedMarkdown } from "@lib/helpers.ts";
|
||||
import { parseIngredient } from "@lib/parseIngredient.ts";
|
||||
import { parseIngredients } from "@lib/parseIngredient.ts";
|
||||
|
||||
export type Recipe = {
|
||||
type: "recipe";
|
||||
@@ -33,72 +32,14 @@ export type Recipe = {
|
||||
};
|
||||
};
|
||||
|
||||
function parseIngredientItem(listItem: DocumentChild): Ingredient | undefined {
|
||||
if (listItem.type === "listItem") {
|
||||
const children: DocumentChild[] = listItem.children[0]?.children ||
|
||||
listItem.children;
|
||||
|
||||
const text = children.map((c) => getTextOfChild(c)).join(" ").trim();
|
||||
|
||||
return parseIngredient(text);
|
||||
}
|
||||
}
|
||||
|
||||
const isIngredient = (item: Ingredient | undefined): item is Ingredient => {
|
||||
return !!item;
|
||||
};
|
||||
|
||||
function parseIngredientsList(list: DocumentChild): Ingredient[] {
|
||||
if (list.type === "list" && "children" in list) {
|
||||
return list.children.map((listItem) => {
|
||||
return parseIngredientItem(listItem);
|
||||
}).filter(isIngredient);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function parseIngredients(children: DocumentChild[]): Recipe["ingredients"] {
|
||||
const ingredients: (Ingredient | IngredientGroup)[] = [];
|
||||
if (!children) return [];
|
||||
let skip = false;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (skip) {
|
||||
skip = false;
|
||||
continue;
|
||||
}
|
||||
const child = children[i];
|
||||
|
||||
if (child.type === "paragraph") {
|
||||
const nextChild = children[i + 1];
|
||||
|
||||
if (!nextChild || nextChild.type !== "list") continue;
|
||||
|
||||
const name = getTextOfChild(child);
|
||||
ingredients.push({
|
||||
name: name || "",
|
||||
items: parseIngredientsList(nextChild),
|
||||
});
|
||||
skip = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.type === "list") {
|
||||
ingredients.push(...parseIngredientsList(child));
|
||||
}
|
||||
}
|
||||
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
function extractSteps(
|
||||
content: string,
|
||||
seperator: RegExp = /\n(?=\d+\.)/g,
|
||||
): string[] {
|
||||
const steps = content.split(seperator).map((step) => {
|
||||
const match = step.match(/^(\d+)\.\s*(.*)/);
|
||||
if (!match) return;
|
||||
const [, , text] = match;
|
||||
return text;
|
||||
if (match) return match[2];
|
||||
return step;
|
||||
}).filter((step) => !!step);
|
||||
return steps as string[];
|
||||
}
|
||||
@@ -141,7 +82,14 @@ export function parseRecipe(original: string, id: string): Recipe {
|
||||
|
||||
let description = getTextOfRange(groups[0], original);
|
||||
|
||||
const ingredients = parseIngredients(groups[1]);
|
||||
let ingredientsText = getTextOfRange(groups[1], original);
|
||||
if (ingredientsText) {
|
||||
ingredientsText = ingredientsText.replace(/#+\s?Ingredients?/, "");
|
||||
} else {
|
||||
ingredientsText = "";
|
||||
}
|
||||
|
||||
const ingredients = parseIngredients(ingredientsText);
|
||||
|
||||
const instructionText = getTextOfRange(groups[2], original);
|
||||
let instructions = extractSteps(instructionText || "");
|
||||
|
Reference in New Issue
Block a user