Ajustement dynamique des proportions des recettes
Gram est conçu pour que les recettes se recalculent (scale) avec une précision mathématique parfaite dans tout l’écosystème. Que vous utilisiez le Playground interactif, génériez des documents HTML/Markdown ou lanciez des commandes CLI, Gram intègre nativement deux fonctionnalités taillées pour la cuisine basée sur les ratios (comme la boulangerie ou la pâtisserie) : les Quantités Relatives et le Pourcentage du Boulanger (Baker’s Math).
Ce guide vous montre comment exploiter les Quantités Relatives pour architecturer des recettes dynamiques et auto-documentées, et comment utiliser le Pourcentage du Boulanger pour formater des recettes traditionnelles en pourcentages purs.
Les limites des quantités statiques
Section intitulée « Les limites des quantités statiques »Prenons une recette de pain classique :
Si vous ajustez les proportions de cette recette avec un facteur 2 (via gram build --scale 2), l’ensemble des quantités est multiplié par deux. Et si vos placards sont vides et qu’il ne vous reste que 400 g de farine, vous pouvez utiliser l’ajustement par ingrédient repère : gram build --scale farine=400g. Gram calculera le multiplicateur (0.8) et ajustera tout automatiquement.
Alors, pourquoi aurions-nous besoin d’autre chose ?
Le hic survient lorsque vous voulez modifier la logique de la recette elle-même.
Et si vous vouliez passer l’hydratation de 70 % à 75 % ? Vous devriez calculer de tête ce que représentent 75 % de 500 g, puis remplacer 350 ml par 375 ml. La logique métier de la recette (ses ratios) est masquée par des valeurs statiques (hardcodées), la rendant laborieuse à lire et à maintenir.
La solution pour les recettes par ratios : les quantités relatives
Section intitulée « La solution pour les recettes par ratios : les quantités relatives »Certaines préparations reposent fondamentalement sur des relations mathématiques entre leurs composants, plutôt que sur des quantités absolues (ex: une pâte à pain entièrement définie par son hydratation à 70 %).
Gram permet d’exprimer ces relations directement dans le code source via des Quantités Relatives (% @&cible pour un ingrédient, ou % &cible pour une variable intermédiaire). La recette devient alors capable de se recalculer dynamiquement à la volée dès que vous tweakez un seul pourcentage.
-
Définir l’ancre (la cible)
Section intitulée « Définir l’ancre (la cible) »Commencez par définir la farine comme un ingrédient standard dans votre recette.
-
Définir les relatifs
Section intitulée « Définir les relatifs »Maintenant, remplacez les quantités statiques de l’eau, du sel et de la levure par des pourcentages pointant vers la farine. Puisque la farine a déjà été définie dans une étape précédente, vous la référencez en utilisant
@&farine.
Ajuster les proportions d’une recette dynamique
Section intitulée « Ajuster les proportions d’une recette dynamique »Puisque ces relations sont encodées à la racine de la recette, Gram assure toute la gymnastique mathématique dynamiquement. Tout développeur ou boulanger lisant le .gram comprend instantanément qu’il s’agit d’une pâte hydratée à 70 %.
Si vous voulez ajuster la recette pour une pâte plus humide à 75 % d’hydratation, vous ne changez qu’un seul nombre :
Et Gram s’occupe du reste. Fini le calcul mental fastidieux des poids absolus pour ajuster vos recettes.
Ajustement universel des proportions
Section intitulée « Ajustement universel des proportions »Vous pouvez ajuster les proportions des recettes visuellement dans le Playground, ou depuis le CLI en utilisant le paramètre --scale (disponible sur view, build, print, et export) :
Gram va résoudre le facteur global (400/500 = 0.8), ajuster l’ancre farine à 400 g, et tous les ingrédients relatifs s’évalueront en cascade sur cette nouvelle base (Eau : 70 % de 400 g = 280 g).
Les limites de l’ajustement par ingrédient repère
Section intitulée « Les limites de l’ajustement par ingrédient repère »Puisque l’ajustement par ingrédient repère dérive le facteur depuis la quantité d’un ingrédient, tout n’est pas éligible comme cible — seul un ingrédient doté d’une quantité absolue explicite fait l’affaire. Si vous tentez de passer l’un des cas suivants, Gram jettera une erreur (throw) plutôt que de calculer silencieusement un facteur aberrant :
| Vous avez tenté d’utiliser… | Pourquoi c’est rejeté | Que faire à la place |
|---|---|---|
Une quantité relative (ex : eau, définie comme 70% @&farine) | Sa valeur est dérivée d’un autre ingrédient — elle ne peut pas non plus servir de référence | Ajustez les proportions de l’ingrédient ancre (--scale farine=400g) |
Un ingrédient fixe (@=) ou une quantité textuelle comme une pincée | Il ne s’ajuste jamais par définition, il ne peut donc pas non plus décrire un facteur d’ajustement | Choisissez un autre ingrédient qui évolue effectivement avec la recette |
Un ingrédient utilisé uniquement à l’intérieur d’une sous-recette (ex : zeste-de-citron, partie d’un composite <@citron) | Il n’est pas directement déclaré avec sa propre quantité — seul le parent composite en possède une | Ajustez les proportions du parent composite (ex : --scale citron=4) — son propre total est une cible valide |
Une option au sein d’un groupe d’ingrédients alternatifs (@beurre{100 g}|@margarine{100 g}) | Choisir une option de manière isolée ne représente pas le choix “soit l’un soit l’autre” qu’exprime la recette | Ajustez les proportions d’un ingrédient différent et non ambigu, ailleurs dans la recette |
Un ingrédient fragmenté sur deux unités incompatibles dans la recette (ex : 300 g dans une étape, 2 tasses dans une autre) | Le total de la liste de courses ne peut pas être réduit à un seul chiffre par lequel diviser | Réécrivez la recette en utilisant une seule unité pour cet ingrédient, ou ajustez les proportions par rapport à un autre ingrédient |
Une unité appartenant à une famille physique différente (ex : eau=1L contre une recette écrite en g) sans aucune densité disponible | Convertir de la masse au volume requiert une densité spécifique à l’ingrédient | Ajoutez une densité via gram db enrich, ou déclarez-en une directement dans le bloc densities: du frontmatter de la recette |
Les unités d’une même famille se convertissent automatiquement — --scale farine=1kg pour une recette écrite en 500 g fonctionne directement (facteur 2), sans recourir à la base de données. Croiser les familles (masse ↔ volume) fonctionne également, tant qu’une densité est disponible : soit via votre ingredients.yaml (gram db enrich), soit via une surcharge ponctuelle au sein de la recette elle-même :
Avec cela, --scale eau=150g sur une recette écrite en ml se résout correctement — pas besoin de base de données pour cet ingrédient précis.
Pourcentage du boulanger (Baker’s Math)
Section intitulée « Pourcentage du boulanger (Baker’s Math) »Si les Quantités Relatives sont idéales pour concevoir des recettes dynamiques, les professionnels se reposent souvent sur un concept appelé Pourcentage du Boulanger (Baker’s Math) pour déchiffrer et analyser des recettes statiques. Dans ce paradigme, l’ingrédient phare (généralement la farine) fait office de base de référence (100 %), et tous les autres ingrédients s’expriment en pourcentage de ce poids.
Si vous avez une recette classique avec des poids absolus, vous pouvez utiliser le Modificateur de Pourcentage du Boulanger (*) pour indiquer explicitement à Gram : “Cet ingrédient est le point de référence de 100 %”.
La recette compilée calculera automatiquement ces pourcentages afin que n’importe quelle interface (frontend) puisse les afficher.
Lorsque vous utilisez le CLI, vous pouvez afficher ces pourcentages en ajoutant l’argument --bakers-math :
La sortie affichera automatiquement le pourcentage de chaque ingrédient par rapport à la farine :
Si votre recette n’inclut pas le modificateur @*, vous pouvez tout de même forcer le calcul des pourcentages du boulanger en spécifiant explicitement l’ingrédient de référence à la volée :
(Vous pouvez également utiliser l’argument --bakers-math-only si vous souhaitez masquer complètement les poids absolus.)
Ingrédients fixes
Section intitulée « Ingrédients fixes »Parfois, une recette contient des ingrédients dont les proportions ne doivent jamais varier, peu importe le nombre de portions générées. Pensez à l’huile de friture au fond d’une poêle, ou à une pincée de sel pour l’assaisonnement.
Vous pouvez utiliser le Modificateur Fixe (=) pour protéger un ingrédient de l’ajustement des proportions :
Si vous exécutez gram build --scale 2, l’huile de friture restera à 1 L.
En combinant les Quantités Relatives pour les ratios et les Quantités Fixes pour les constantes immuables, vous pouvez écrire des recettes qui s’adaptent parfaitement à n’importe quelle contrainte de votre garde-manger ou taille de portion.