Die Embed-Directive-Syntax (:::key{attr=value flag}) hat eine normative Quelle:
embed-directive.ts
in @cocoar/vue-markdown-core. Dieses Repo ist ein byte-genauer Port.
Der geteilte Vertrag ist maschinell geprüft — nicht per Doku-Behauptung:
- Normative Vektoren:
cocoar-ui-vue/packages/markdown-core/src/lib/embed-directive.conformance.json(74 Vektoren: parse / serialize / roundtrip / segment), dort von Vitest ausgeführt (embed-directive.conformance.test.ts). - Vendored Kopie:
Tests/CocoarMarkdownCoreTests/Fixtures/embed-directive.conformance.json, vonConformanceTests.swift(XCTest) durch dieselben Prüfungen gezogen. - Sync: ausschließlich über
Scripts/sync-vectors.sh(kopiert + pinnt SHA-256;testVendoredVectorsAreUntouchedschlägt bei Handbearbeitung der Kopie fehl).
Workflow bei Spec-Änderungen: Verhalten in embed-directive.ts ändern → Vektoren dort
erweitern (Vitest grün) → Scripts/sync-vectors.sh → Swift-Port nachziehen (XCTest grün).
Beide CIs zusammen beweisen die Parität.
| Verhalten | Web (parse.ts fold) |
Swift (segmentMarkdown) |
Im Vertrag? |
|---|---|---|---|
| Standalone-Directive-Zeile auf Top-Level | ✅ Embed | ✅ Embed | ✅ Vektoren |
| Mehrzeilige Directive (Zeilenumbruch im quoted value) | ✅ Embed | ✅ Embed | ✅ Vektoren |
| Directive an Text angelehnt (gleicher Absatz) | Markdown | Markdown | ✅ Vektoren |
:::key{…} trailing |
Markdown | Markdown | ✅ Vektoren |
| 4-Spaces-Einrückung (CommonMark Indented Code) | Code-Block | Markdown (kein Embed) | ✅ Vektoren |
| NBSP-only-Zeile als „Blank Line" | nein (Absatz läuft weiter) | nein | ✅ Vektoren |
| Directive verschachtelt in Liste/Blockquote | ✅ faltet (Tree-Walk) | ❌ bleibt Markdown | |
Fenced Code Block mit :::-Zeile |
Code | Code (kein Fold in Fences) | Header-Doku Segmenter |
Die eine bewusste Divergenz (verschachtelte Embeds) ist Absicht: der Swift-Segmenter arbeitet auf Top-Level-Blöcken; Embeds in Listen sind im Produkt nicht vorgesehen. Wird das je gebraucht, wandert es zuerst als Vektor in die normative Datei.
Ein Embed erscheint immer auf genau eine von drei Arten — nie als Roh-Text:
- gerendert (Key in der Registry),
- Platzhalter-Chip (unbekannter Key; Web:
coar-markdown-embed--unknown, Swift: 🧩-Chip), - bewusst nicht registriert → ebenfalls Platzhalter (Entscheidung pro App/Plattform).