first commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Parsing pur des fichiers `.bentext` (sources recette).
|
||||
* Aucun effet de bord : ne touche pas au système de fichiers, au catalogue,
|
||||
* ni aux assets. Utilisé par `scripts/build-recipes.mjs`.
|
||||
*
|
||||
* Format bentext :
|
||||
* Title
|
||||
* Version
|
||||
* Description
|
||||
* ---
|
||||
* Ingredients (une ligne par ingrédient : `Nom|quantité|unité|note`)
|
||||
* ---
|
||||
* Steps (une ligne par étape, ordre du fichier = priorité)
|
||||
* ---
|
||||
* Notes (optionnel, présent si 6+ blocs `---`)
|
||||
* Tags (optionnel dès 4 blocs)
|
||||
* Meta (optionnel dès 5 blocs)
|
||||
*/
|
||||
|
||||
const splitIngredientLine = (line) => {
|
||||
const parts = line.split("|").map((token) => token.trim());
|
||||
const name = parts[0] ?? "";
|
||||
const quantity = Number(parts[1] ?? "0");
|
||||
const unit = parts[2] ?? "";
|
||||
const note = parts.slice(3).join(" | ").trim();
|
||||
return { name, quantity, unit, note };
|
||||
};
|
||||
|
||||
const splitNonEmptyLines = (raw) =>
|
||||
raw
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
const readBentext = (raw) => {
|
||||
const parts = raw.split("---").map((part) => part.trim());
|
||||
|
||||
const header = (parts[0] ?? "").split("\n").map((line) => line.trim());
|
||||
const title = header[0] ?? "";
|
||||
const version = header[1] ?? "";
|
||||
const servings = Number.parseInt(version, 10);
|
||||
const description = header.slice(2).join("\n").trim();
|
||||
|
||||
const ingredientsBlock = parts[1] ?? "";
|
||||
const stepsBlock = parts[2] ?? "";
|
||||
|
||||
let notesBlock = "";
|
||||
let tagsBlock = "";
|
||||
let metaBlock = "";
|
||||
|
||||
if (parts.length === 4) {
|
||||
tagsBlock = parts[3] ?? "";
|
||||
} else if (parts.length === 5) {
|
||||
tagsBlock = parts[3] ?? "";
|
||||
metaBlock = parts[4] ?? "";
|
||||
} else if (parts.length >= 6) {
|
||||
notesBlock = parts[3] ?? "";
|
||||
tagsBlock = parts[4] ?? "";
|
||||
metaBlock = parts[5] ?? "";
|
||||
}
|
||||
|
||||
const stepLines = splitNonEmptyLines(stepsBlock);
|
||||
const steps = stepLines.map((line, index) => ({
|
||||
id: `step-${index + 1}`,
|
||||
priority: (index + 1) * 10,
|
||||
phase: "cook",
|
||||
dependsOn: index === 0 ? [] : [`step-${index}`],
|
||||
text: line
|
||||
}));
|
||||
|
||||
return {
|
||||
title,
|
||||
version,
|
||||
servings: Number.isFinite(servings) && servings > 0 ? servings : 1,
|
||||
description,
|
||||
ingredients: splitNonEmptyLines(ingredientsBlock).map((line) => splitIngredientLine(line)),
|
||||
steps,
|
||||
notes: splitNonEmptyLines(notesBlock),
|
||||
tags: splitNonEmptyLines(tagsBlock).map((line) => line.toLowerCase()),
|
||||
meta: splitNonEmptyLines(metaBlock)
|
||||
};
|
||||
};
|
||||
|
||||
export { readBentext, splitIngredientLine };
|
||||
Reference in New Issue
Block a user