# WBS-Notation – Spezifikation Textuelle Notation für Projektstrukturpläne (Work Breakdown Structure) mit Und/Oder-Zerlegung. Diese Datei ist die verbindliche Sprachdefinition. Syntaxänderungen werden zuerst hier dokumentiert, dann implementiert. ## 1. Zeilenformat ``` [Einrückung][Zeichen] [Statusbox] Label (Größe) URL @tag … %% Kommentar ``` Alle Bestandteile außer dem Label sind optional. Die Extraktion erfolgt in dieser Reihenfolge (wichtig für Kollisionsfreiheit): 1. Kommentar entfernen: alles ab `%%` bis Zeilenende. 2. Einrückung, Zeichen (`-` / `|`) und Statusbox `[…]` per Zeilen-Regex. 3. URL: erstes Token, das auf `https?://\S+` passt (dadurch stören `@` in URLs nicht). 4. Größe: erstes `(XS|S|M|L|XL|XXL)`, Groß-/Kleinschreibung egal. 5. Tags: alle `@name`-Vorkommen. 6. Rest, whitespace-normalisiert = Label. Leeres Label ⇒ Zeile ignorieren. Referenz-Regex der Implementierung: ``` ^([ \t]*)([-|])?\s*(?:\[([ ?~xX^/-])\]\s*)?(.*)$ ``` ## 2. Hierarchie - Die Einrückung bestimmt die Ebene. Es gibt keine feste Schrittweite: Elternknoten ist die nächste vorangehende Zeile mit **kleinerer** Einrückungsbreite (Tab zählt als 2 Leerzeichen). - Zeilen ohne Zeichen (`-`/`|`) sind Wurzelknoten. Mehrere Wurzeln = mehrere Bäume nebeneinander. ## 3. Zerlegungsart (Gate) | Zeichen | Bedeutung | Semantik | |---|---|---| | `-` | all of (Und-Zerlegung) | Alle Teilpakete sind erforderlich. | | `\|` | any of (Oder-Zerlegung) | Mindestens eine Alternative wird gewählt. | - Das Gate ist eine Eigenschaft der Geschwistergruppe; alle Geschwister sollen dasselbe Zeichen tragen. - Gemischte Geschwister: Darstellung nach dem **ersten** Kind, plus Warnung mit Zeilennummer. ## 4. Status Codiert als Checkbox nach dem Zeichen (Erweiterung der Markdown-Task-Syntax): | Code | Key | Name | Bedeutung | Hintergrund | Rahmen | |---|---|---|---|---|---| | `[?]` | idee | Idee | vage Idee | `#EBEDEF` (grau) | `#A2ABB5` | | `[ ]` | geplant | geplant | beschlossen, nichts investiert | `#EBE4F6` (flieder) | `#A991D4` | | `[~]` | arbeit | in Arbeit | Kosten investiert, Risiko hoch | `#FADDE4` (rosé) | `#D897A8` | | `[/]` | durchstich | Durchstich | funktionsbereit/vorführbar, Feinarbeiten offen | `#FBF2CE` (pastellgelb) | `#D9BE63` | | `[x]` | fertig | fertig | abgeschlossen | `#DCF1DE` (pastellgrün) | `#86C293` | | `[^]` | prod | in Produktion | deployed/live | `#DBEAF8` (pastellblau) | `#85ACD7` | | `[-]` | verworfen | verworfen | bewusst nicht weiterverfolgt | `#F1F2F4`, gestrichelter Rahmen, Text durchgestrichen | `#B3BAC2` | - Ohne Statusbox: neutraler Knoten (weiß). - `x` auch als `X` zulässig. - Verworfene Knoten (inkl. Teilbaum) sind per Default **ausgeblendet**; Toggle „verworfene einblenden“ zeigt sie. ## 5. Aufwand (T-Shirt-Größen) - Werte: `XS < S < M < L < XL < XXL`, notiert in Klammern, z. B. `(L)`. - **Untergliederungsregel:** Ab `(M)` muss ein Element weiter zerlegt sein. Ein Element ≥ M **ohne Kinder** erhält einen Geister-Knoten an gestrichelter Linie darunter (in `--warn`, `#B45309`). Sein Label ist knapp „…“; die Erklärung („Ab Größe M sollte ein Element weiter untergliedert werden.“) steht im Tooltip — der ausgeschriebene Text machte die Zelle sonst breiter als der Knoten und verschob gestapelte Geschwister. Der angedeutete Unterpunkt genügt als Hinweis; eine zusätzliche Umrandung des Knotens gibt es nicht. - Ausnahme: verworfene Elemente lösen die Regel nie aus. - Anzeige: petrolfarbenes Badge (`--or`, `#0F766E`) mit weißer Schrift oben rechts an der Knoten-Ecke. ## 6. Links - Ein nacktes `https://…`-Token macht den ganzen Knoten klickbar (neuer Tab, `rel="noopener"`); Kennzeichnung mit ↗ hinter dem Label. ## 7. Personen-Tags - `@name` mit `name` aus Unicode-Buchstaben, Ziffern, `.`, `_`, `-`. - Mehrere Tags pro Zeile möglich, Position im Text egal. - Anzeige: helle Pillen unten rechts an der Knoten-Ecke. ## 8. Kommentare - `%%` leitet einen Kommentar ein — ganze Zeile oder ab Zeilenmitte. - Konvention aus Mermaid übernommen; `%%{` vermeiden (dort Direktiven-Syntax). ## 9. Darstellung Drei Modi, im Editor umschaltbar über Icon-Buttons (Reihenfolge **horizontal · kompakt · vertikal**, je mit Tooltip). Der Modus wählt zugleich die Seitenanordnung: **horizontal** stellt Diagramm über den Editor (volle Breite), **vertikal** und **kompakt** stellen Editor und Diagramm nebeneinander (schmales Diagramm rechts). **Linienführung (in allen Modi gleich):** all-of-Linien durchgezogen in Tinte (`#41556E`); any-of-Linien — Haupt-/Sammelleiste **und** Abzweige — durchgehend **gestrichelt in Grau** (`#6B7A8C`). Auch der **Rahmen der Alternative-Knoten** ist grau (`#6B7A8C`) — kein Petrol mehr im Diagramm. Der Modus ändert nur die **Anordnung**, nicht die Linienfarbe. ### Horizontal (Normalmodus) - **all of:** Kinder nebeneinander, klassischer Organigramm-Fächer. - **any of:** Alternativen untereinander; gestrichelte graue Sammelleiste links unterhalb des Parents, gestrichelte graue Abzweige zu den Alternativen. ### Vertikal (transponiert) - **all of:** exakter transponierter Organigramm-Fächer (horizontal um 90° gedreht): Der Parent sitzt **vertikal mittig** zu seiner Kindergruppe, die Linie tritt **rechts auf halber Höhe** aus (entspricht Richtung LR), eine vertikale Sammelleiste (von erster bis letzter Kindmitte) verteilt mit durchgezogenen Abzweigen; Kinder rechts untereinander. - **any of:** Austritt **unten links**, gestrichelte graue Abzweige. - Merkregel: Austrittsseite codiert das Gate (rechts = und, unten = oder), Linienstil bestätigt es. ### Kompakt (transponiert, platzsparend) - **Beide Gates** laufen **unten links** aus dem Parent heraus, Kinder untereinander — kein Rechts-Fächer, dadurch minimale Breite. - Das Gate wird hier allein über den **Linienstil** codiert (siehe D15): und = durchgezogen (Tinte), oder = gestrichelt (Grau). ### Geometrie-Invarianten - Knoten haben feste Zeilenhöhe (`line-height: 1.3`), damit Abzweige deterministisch auf Knotenmitte liegen (Offset 23 px = 5 px Listenabstand + halbe Knotenhöhe). Abzweige zielen auf den **Knoten**, nie auf die Mitte des Teilbaums. - In den transponierten Modi (vertikal, kompakt) stehen untereinander gestapelte Geschwister mit **zusätzlichem Abstand nach unten** (damit das Größen-Badge oben rechts nicht mit den Tags unten rechts des darüber liegenden Knotens überlappt). Der Abstand wird nur **unterhalb** ergänzt, der 23-px-Abzweig oben bleibt unverändert; die vertikal **zentrierten** all-of-Zwischenknoten bekommen ihn **symmetrisch**, damit ihr Abzweig (50 %-Höhe) weiterhin auf der Knotenmitte liegt. ### Kleiner Bildschirm (mobil) Ab schmaler Breite (≤ 640 px, z. B. Smartphone) ist immer nur **ein** Bereich groß sichtbar — Diagramm **oder** Texteditor; der andere schrumpft auf seine Titelzeile und dient als Umschalter (Antippen bringt ihn nach vorn). Die Min/Normal/Max-Buttons entfallen; geteilt wird weiterhin über den **Splitter** (Ziehen). Die **Legende** bekommt hier einen eigenen Umschalter im Editor-Kopf (statt der dauerhaften „AGENDA“-Zeile), damit sie zugeklappt keinen Platz kostet. Der **Modus-Wähler** zeigt nur das aktive Icon und schaltet bei jedem Tippen reihum weiter (horizontal → kompakt → vertikal → …), spart also zwei Drittel der Breite. Die **Sprachwahl** zeigt eingeklappt nur die aktive Sprache; ein Tipp darauf klappt die volle Leiste als **Overlay über die Kopfzeile** auf (verdeckt die übrigen Bedienelemente, statt die Zeile zu verbreitern), nach der Auswahl klappt sie wieder auf die gewählte Sprache ein (Tipp daneben schließt ebenfalls). Die **Download-Buttons** (SVG/PNG mit Text-Label) verbergen sich hinter einem einzelnen Download-Icon, das die Formatwahl bei Bedarf als kleines **Dropdown-Overlay** unter der Kopfzeile zeigt — sonst bräche die Titelzeile um; „Kopieren" bleibt sichtbar. Der **Untertitel** wird auf eine garantiert einzeilige Kurzfassung reduziert. Voreinstellung auf kleinem Bildschirm ist **Vollbild** (siehe D17). ### Günstigster Pfad (Kosten-Hervorhebung) Ein Umschalter (Icon-Button im Diagramm-Kopf, Voreinstellung **an**, Zustand persistiert) hebt den kostengünstigsten Weg durch den Baum hervor. Ermittelt werden die für die günstigste Realisierung **nötigen** Knoten: - **all of:** alle Kinder sind nötig. - **any of:** nur die **günstigste** Alternative ist nötig. „Günstig" = kleinste rekursive Kosten (eigene T-Shirt-Größe plus — je Gate — Summe bzw. Minimum der Kinder). Bei Gleichstand gewinnt die **erste** Alternative. - Verworfene Knoten zählen nie mit (unabhängig vom „verworfene einblenden"- Filter). - **Fehlende Größe wird als `M` gewertet** (nur für diese Kostenschätzung; die SPEC-Semantik der Größen in §5 bleibt unberührt). Darstellung per **Inversion**: nicht benötigte Knoten (nicht-gewählte any-of-Alternativen samt Teilbaum) treten zurück (blass, entsättigt); der günstige Pfad hebt sich dadurch von selbst ab — kein zusätzlicher Rahmen an den ohnehin dichten Knoten-Ecken. Wo die Größe **implizit** als `M` angenommen wird, zeigt der Knoten ein **invertiertes** Größen-Badge (weiß mit petrolfarbenem Rand/Text statt gefüllt) mit erläuterndem Tooltip. Zusätzlich fädelt eine **gestrichelte, geschwungene Petrol-Linie** durch die **Endknoten (Blätter)** des Pfads (Katmull-Rom-Spline in Dokument-Reihenfolge, in allen Modi). Die kräftige Linie liegt **hinter** den Knoten (nur in den Lücken voll sichtbar), eine **abgetönte Kopie** davor deutet den Verlauf beim Durchschreiten eines Knotens nur schwach an. An jedem echten Endknoten sitzt ein großer, **blasser Petrol-Stationspunkt** (U-Bahn-Plan-Prinzip: der Knotentext bleibt lesbar) — nur **durchquerte** Fremd- oder Zwischenknoten tragen keinen Punkt, sodass eindeutig bleibt, welche Knoten auf dem Pfad **enden**. Linie, abgetönte Kopie und Punkte erscheinen bei aktivem Umschalter auch im Grafikexport. Siehe D18. ### Grafikexport des Diagramms Das Diagramm wird aus der Live-Geometrie in ein eigenständiges SVG (nur Formen + Text, keine externen Ressourcen) nachgezeichnet. Zwei Icon-Schaltflächen: - **Kopieren** — als **PNG** in die Zwischenablage. Es werden zwei Flavors geschrieben: `image/png` (das eigentliche Bild) und `text/html` mit eingebettetem PNG. Fällt der Bild-Clipboard ganz aus (fehlende `ClipboardItem`-Unterstützung), wird der **SVG-Quelltext** kopiert. - **Herunterladen** — als Datei, zwei Schaltflächen mit Format-Label: **SVG** (`werkbaum-diagramm.svg`, Vektor) und **PNG** (`werkbaum-diagramm.png`, Raster). Der Datei-Weg ist der verlässliche Weg für Programme, die das Browser-Bild-Clipboard nicht erkennen. Manche Programme lesen auch das SVG nicht (z. B. LibreOffice) — dafür gibt es die PNG-Datei, die überall per „Bild einfügen“ importierbar ist. - Übernommen werden Knotenfarben (Status §4), Größen-Badge, Tags und der Geister-Knoten; die Verbindungslinien werden je Gate neu gezogen (und = durchgezogen Tinte, oder = gestrichelt Grau) und treffen die Knoten unabhängig vom Darstellungsmodus. - Es wird genau die **sichtbare** Struktur exportiert (der „verworfene einblenden“-Filter wirkt auch hier). ## 10. Beispiel (kanonisch) ``` %% Projektstruktur – Stand Sprint 14 [~] Website-Relaunch (XL) https://wiki.example.de/relaunch - [x] Konzeption (M) - [x] Zielgruppenanalyse (S) - [x] Sitemap (XS) - [~] Umsetzung (XL) - [/] Frontend (S) https://git.example.de/frontend @anna - [ ] Backend (L) @ben @carla - [ ] CMS-Anbindung (M) | [ ] WordPress | [?] Headless CMS | [-] Eigenentwicklung %% Aufwand zu hoch - [?] Hosting (M) | Cloud | On-Premise ``` ## 11. Reservierte Erweiterungen (noch nicht implementiert) - `#123` — Referenz auf externe Tickets (geplant für Taiga-Integration). - `#tag` — freie Schlagworte (deshalb `#` nicht anderweitig verwenden).