Hierarchische Rezepte

Heute bin ich über eine interessante Darstellung von Rezepten gestossen:

(Quelle: http://www.cookingforengineers.com/recipe/268/Buffalo-Chicken-Chili)

Durch den hierarchischen Aufbau ist sofort klar, wie das Essen zubereitet werden soll. Es ist viel übersichtlicher als konventionelle Rezepte im Fliesstextformat.

Ich fände es cool, in einem Git Repository eine Rezeptsammlung zu beginnen. Dafür müsste man dieses Format in einfachen Textdateien codieren können. Eine Erweiterung davon wäre ein JavaScript-Editor, bei dem man diese Tabellen “zusammenklicken” kann.

Anforderungen für das Datenformat:

  • Text only
  • Sortierung muss beibehalten werden (schliesst JSON Objekte aus)
  • Sollte einfach genug sein, dass man es von Hand editieren kann
  • Sollte einfach zu parsen sein, idealerweise mit einem LR(0) parser (kontextfrei)
  • Die Rezepte sollten Metadaten enthalten.

Gemäss Requirements fallen Datenformate wie JSON und YAML weg, da die Objekt-Notation die Reihenfolge nicht garantiert. Diese ist jedoch einigermassen relevant.

Zudem müsste man bei JSON den Baum von rechts nach links aufbauen. Das ist unintuitiv und schwierig zu lesen.

Ich habe mir ein einfaches kontextfreies Datenformat überlegt:

<identifier>: <action>
    <dependencies>
  • Zuerst kommt ein Identifier, im einfachsten Fall ein Grossbuchstabe. Der Identifier beschreibt eine Gruppe von Zutaten oder Aktionen.
  • Nach dem Doppelpunkt folgt die “Aktion”, beispielsweise “Fein hacken” oder “20 Minuten kochen”. Die Aktion darf auch leer sein.
  • Auf einer neuen Zeile folgen eingerückt die Abhängigkeiten, also die Zutaten und/oder Untergruppen.

Obiges Beispiel würde so aussehen:

A: saute until browned
  1 Tbs. (15 mL) olive oil    
  1 lb. (450 g) ground chicken
  salt & pepper
B: saute until soft
  2 Tbs. (30 g) unsalted butter
  salt
  &C
C: chop fine
  3 celery ribs
  2 carrots
  1 medium onion
  1 red bell pepper
D: toast 30 sec in pan
  5 garlic cloves
  2 Tbs. (15 g) chili powder
  2 tsp. (4 g) ground cumin
  1 tsp. (2 g) ground coriander
  1 Tbs. (15 mL) olive oil
E: shred meat
  1 rotisserie chicken
F:
  12 oz. (355 mL) beer (good micro brew)
  1/2 cup (120 mL) cayenne pepper hot sauce
  15 oz. can (425 g) tomato sauce
  14.5-oz. (410 g) can diced tomatoes
G:
  salt & pepper
H: drink while chili simmers
  12 oz. (355 mL) beer
I: combine
  &A
  &B
J: simmer 5 min
  &I
  &D
  &E
K: simmer 15 min or until thickened
  &J
  &F
L: season
  &K
  &H 

Das Format müsste mit einer State Machine parseable sein, da kontextfrei. Zudem ist es relativ einfach lesbar.

Findet das jemand interessant? Ich würde mich über Feedback zum Datenformat (oder auch zu Alternativen) freuen.

Offene Punkte:

  • Es wäre vermutlich gut, wenn man die Mengenangaben von den Zutaten unterscheiden könnte. Das ermöglicht das Umrechnen auf eine bestimmte Anzahl von Personen, sowie auf andere Formate (e.g. imperial vs. metrisch).
  • Metadaten sind hier noch nicht enthalten. Wäre aber relativ einfach, man könnte oben an der Definition key-value Paare für Metadaten ermöglichen, und unterhalb des Rezeptes noch eine Fliesstext-Beschreibung mit Tipps und Erläuterungen.

Ein Parser für dieses Format könnte Zeilwenweise vorgehen. Die State Machine für das Parsen von Zeilen würde so aussehen (leere Zeilen werden ignoriert):

Eine Group sieht folgendermassen aus:

struct Group {
    label: String,
    description: Option<String>,
}

Ein Member:

enum Member {
    Reference(&Group),
    Ingredient(String),
}

Vielleicht liesse sich ein Renderer für Nassi-Shneiderman-Diagramme oder ähnliche Struktogramme dazu umbiegen, solche Rezept-Darstellungen zu erzeugen?

Hm, könnte funktionieren :slight_smile: