@gram-lang/analyzer
Enrichit un CompilationResult (issu de @gram-lang/kitchen) avec des propriétés physiques (masse standardisée, rendement d’achat, estimations nutritionnelles et % du boulanger) en les croisant avec une base de données d’ingrédients. C’est la seule étape qui requiert une base de données : le parsing et la compilation fonctionnent sur n’importe quelle recette, sans la moindre donnée externe.
La base de données d’ingrédients est le deuxième argument positionnel, pas un champ de
options—analyze(compiled, database, options?).
analyze() est une fonction pure et ne mute jamais result. AnalyzedCompilationResult étend CompilationResult (même forme) en y ajoutant les champs normalizedMass/conversionMethod/isEstimate/purchasingMass/bakersPercentage pour chaque ingrédient, ainsi qu’un bloc metrics.nutrition. Voir Formats de données pour un exemple entièrement annoté.
AnalyzerOptions
Section intitulée « AnalyzerOptions »Tous les flags d’enrichissement sont activés par défaut (via des vérifications internes !== false). Il suffit de passer false pour désactiver l’enrichissement correspondant.
| Option | Type | Description |
|---|---|---|
enableMassStandardization | boolean | Convertit les quantités d’ingrédients en grammes standardisés. |
enableYieldCalculation | boolean | Applique le physical.yield (facteur de perte) de la base de données lors de la standardisation de la masse. |
enableNutritionalEstimation | boolean | Calcule metrics.nutrition (calories, macros, éventuellement par portion). |
enableBakersMath | boolean | Calcule bakersPercentage par rapport à l’ingrédient marqué * (ou bakersReference). |
bakersReference | string | Id d’ingrédient explicite à utiliser comme base 100% du pourcentage boulanger, au lieu du modificateur *. |
portions | number | Nombre de portions utilisé pour calculer metrics.nutrition.perPortion. |
lang | string | Code de langue optionnel (ex : 'en', 'fr') pour la normalisation d’unités et le tri des catégories par langue. |
validateIngredientDatabase
Section intitulée « validateIngredientDatabase »Valide la base entrée par entrée plutôt qu’en bloc : un ingrédient malformé ne fera pas planter le chargement des autres. Utilisez data pour la compilation/analyse, et remontez rejected à l’utilisateur (ex : gram db validate). Voir Formats de données pour le schéma YAML de IngredientData.
Utilitaires de masse
Section intitulée « Utilitaires de masse »standardizeMass résout une quantité en grammes selon l’ordre suivant : (1) une unité de masse directe (g, kg, oz…), (2) une unité de volume convertie grâce à la densité de l’ingrédient, (3) une unité non reconnue (gousse, tranche…) traitée comme un comptage via le unit_weight de l’ingrédient. La fonction retourne null (elle ne devine jamais) lorsqu’une unité de volume n’a aucune densité résolue.
convertUnit convertit entre deux chaînes d’unités arbitraires, et jette un pont masse↔volume si une density (g/mL) est fournie. Retourne null lorsqu’une conversion inter-famille est impossible faute de densité.
Table de conversion masse & volume
Section intitulée « Table de conversion masse & volume »Voici les facteurs de conversion par défaut employés par standardizeMass et convertUnit pour les conversions intra-famille (masse↔masse, volume↔volume), c’est-à-dire avant même de requérir une densité :
| Famille | Unité | Facteur (par rapport à la base) |
|---|---|---|
mass (base: g) | mg | 0.001 |
mass (base: g) | g | 1 |
mass (base: g) | kg | 1000 |
mass (base: g) | oz | 28.3495 |
mass (base: g) | lb | 453.592 |
mass (base: g) | livre | 500 |
volume (base: ml) | ml | 1 |
volume (base: ml) | cl | 10 |
volume (base: ml) | dl | 100 |
volume (base: ml) | l | 1000 |
volume (base: ml) | drop | 0.078 |
volume (base: ml) | smidgen | 0.156 |
volume (base: ml) | pinch | 0.3125 |
volume (base: ml) | dash | 0.625 |
volume (base: ml) | tad | 1.25 |
volume (base: ml) | tsp | 4.9289 |
volume (base: ml) | tbsp | 14.7868 |
volume (base: ml) | cup | 236.588 |
volume (base: ml) | tasse | 250 |
volume (base: ml) | pt | 473.176 |
volume (base: ml) | qt | 946.353 |
volume (base: ml) | gal | 3785.41 |
volume (base: ml) | fl oz | 29.5735 |
calculateNutrition
Section intitulée « calculateNutrition »Aplatit les composites et les alternatives (en conservant la première option), ignore les ingrédients marqués optional et les quantités nulles, puis fait la somme des champs nutrition (déclarés pour 100g dans la base de données — voir Formats de données) ajustés (scale) via la masse standardisée de chaque ingrédient. Retourne isEstimate: true si au moins une masse contributrice était déjà une estimation, ainsi qu’un taux de coverage de 0 à 1 (fraction d’ingrédients possédant des données nutritionnelles).
diffRecipes
Section intitulée « diffRecipes »Calcule le diff structurel entre deux recettes compilées (ex : deux versions d’un même fichier, ou la version de base contre la version scalée). Il gère les changements de quantité/unité des ingrédients (incluant un percentChange pertinent), de préparation, d’écarts de durée, les ajouts/modifications/suppressions de sections, les variations de température et de minuteur, ainsi que les altérations du frontmatter (meta). hasChanges vaut true dès qu’une catégorie n’est pas vide.
Une section importée via @use (ProcessedSection.module renseigné) est exclue des comparaisons de sections/préparations/températures/minuteurs — sans quoi l’ajout d’un simple import décalerait la position de toutes les autres sections et ferait croire que toute la recette a changé. Son propre import est comparé séparément, par (uri, binding, facteur d'échelle), dans modules: ModuleDelta[] — un import re-scalé ou re-lié est signalé comme "changed".