Markdown-Aufgabenlisten und was tatsächlich wo dargestellt wird
Veröffentlicht am 2.7.2025 · 10 Min. Lesezeit · Text- & Sprach-Tools
Daniel Okonkwo — Front-end-Entwickler und Tech-Redakteur bei OneKitly
Web-Performance · Dateiformate
Anhand von 4 Quellen geprüft
Eine Markdown-Aufgabenliste — ein Listeneintrag, der mit [ ] oder [x] beginnt — gehört nicht zu CommonMark. Wir haben die CommonMark-Spezifikation 0.31.2 vom 28. Januar 2024 durchsucht: Die Ausdrücke „task list“ und „checkbox“ kommen darin null Mal vor. Aufgabenlisten sind in der Spezifikation GitHub Flavored Markdown 0.29-gfm vom 6. April 2019, Abschnitt 5.3, als Erweiterung definiert. Das ist die ganze Erklärung dafür, dass dieselbe Datei auf GitHub Kontrollkästchen und anderswo wörtliche Klammern zeigt. Wir haben eine Zeile, „- [ ] Milch kaufen“, durch vier Renderer geschickt: Nur der GitHub-Variante erzeugte ein input-Element vom Typ checkbox; die CommonMark-Referenzimplementierung und zwei weitere Konfigurationen erzeugten einen Listeneintrag mit dem wörtlichen Text [ ] Milch kaufen. Die Markerregel ist exakt und unnachgiebig: eine optionale Folge von Leerzeichen, eine öffnende Klammer, entweder ein Leerraumzeichen oder der Buchstabe x in beliebiger Schreibung, eine schließende Klammer und dann mindestens ein Leerraumzeichen vor dem Inhalt. „- [x]Milch“ ohne Leerzeichen erscheint überall als Text, „- []“ erscheint als Text, und „- [ ]“ mit zwei Leerzeichen ebenso. Dieselbe Vorsicht gilt für Tabellen, Durchstreichung und Autolinks, ebenfalls Erweiterungen, und für Fußnoten, die in keiner der Spezifikationen stehen.
Aufgabenlisten stehen nicht in CommonMark. Sie sind eine Erweiterung von GitHub Flavored Markdown, weshalb dieselbe Datei hier Kontrollkästchen und dort wörtliche Klammern zeigt. Die genaue Markerregel, was Verschachtelung bewirkt, und eine Tabelle darüber, was CommonMark ist, was GFM und was keines von beidem — gegen beide Spezifikationen und vier Renderer geprüft.
Eine Zeile, vier Renderer, zwei verschiedene Dokumente
Wir haben eine einzige Zeile genommen — Bindestrich, Leerzeichen, leeres Klammerpaar, Leerzeichen, etwas Text — und sie auf vier Arten dargestellt. Mit eingeschalteter GitHub-Variante wurde daraus ein Listeneintrag mit einem input-Element vom Typ checkbox, deaktiviert. Mit derselben Bibliothek bei ausgeschalteter Variante, mit der CommonMark-Referenzimplementierung und mit einer dritten Bibliothek in ihrer Standardkonfiguration wurde daraus ein Listeneintrag mit den Zeichen [ ] gefolgt vom Text. Nichts schlug fehl. Vier korrekte Renderer erzeugten aus einer Datei zwei verschiedene Dokumente.
Der Grund ist dokumentiert, nicht geheimnisvoll. Wir haben die CommonMark-Spezifikation 0.31.2 vom 28. Januar 2024 nach „task list“ und „checkbox“ durchsucht: Beide kommen null Mal vor. Die Spezifikation GitHub Flavored Markdown 0.29-gfm vom 6. April 2019 hat einen Abschnitt 5.3 mit dem Titel „Task list items (extension)“. Das Wort Erweiterung leistet in diesem Titel die ganze Arbeit: GFM ist CommonMark plus fünf benannte Zusätze, und ein Renderer, der nur CommonMark umsetzt, ist nicht defekt, wenn er deine Kontrollkästchen als Klammern ausgibt. Er ist korrekt.
Die Markerregel, Zeichen für Zeichen
GFM-Abschnitt 5.3 definiert einen Aufgabenlisteneintrag als Listeneintrag, dessen erster Block ein Absatz ist, der mit einem Aufgabenlisten-Marker beginnt, gefolgt von mindestens einem Leerraumzeichen vor jedem weiteren Inhalt. Der Marker ist eine beliebige Anzahl Leerzeichen, eine öffnende Klammer, entweder ein Leerraumzeichen oder der Buchstabe x in Klein- oder Großschreibung, und eine schließende Klammer. Jedes Wort dieses Satzes trägt, und die Fehlschläge sind lautlos: Wir haben jede Verletzung ausgeführt, und alle erschienen in allen vier Renderern als gewöhnlicher Text.
Lass das Leerzeichen nach der schließenden Klammer weg und nichts geschieht: „- [x]Milch kaufen“ ist Text. Setz zwei Leerzeichen zwischen die Klammern und nichts geschieht: Der Marker fasst genau ein Zeichen. Lass die Klammern leer und nichts geschieht. Nimm einen anderen Buchstaben als x und nichts geschieht. Rücke den Marker vom Absatzanfang weg — „- Milch [ ] kaufen“ — und nichts geschieht. Streiche die Liste, und „[ ] Milch kaufen“ ist ein Absatz. Was funktioniert, ist großzügiger als erwartet: Der Buchstabe darf ein großes X sein, der Aufzählungspunkt ein Bindestrich, ein Sternchen oder ein Plus, die Liste darf nummeriert sein, und ein Tabulator zählt als das Leerraumzeichen nach der Klammer.
Verschachtelung und die Erst-Block-Regel
Aufgabenlisten lassen sich beliebig verschachteln, und die Spezifikation zeigt das an einem ausgeführten Beispiel. Wir haben einen Elterneintrag mit zwei eingerückten Kindern laufen lassen: Kontrollkästchen beim Elternteil, verschachtelte Liste innerhalb desselben Listeneintrags, Kontrollkästchen bei jedem Kind. Auch das Mischen markierter, unmarkierter und gewöhnlicher Einträge in derselben Liste funktioniert: Der gewöhnliche bleibt gewöhnlich, die markierten werden Kontrollkästchen — das macht eine Checkliste als gemischte Tagesordnung lesbar.
Die Forderung, dass der erste Block ein Absatz sein muss, übersieht man leicht. Setz ein Zitat an den Anfang — „- > [ ] zitiert“ — und kein Renderer erzeugt ein Kontrollkästchen, auch der GitHub-Variante nicht, denn der erste Block ist ein Zitat, und der Marker kommt nie zum Zug. Füge nach dem markierten Absatz einen zweiten hinzu, und das Kontrollkästchen überlebt: Es steht vor dem ersten Absatz, der zweite folgt im selben Eintrag. Das sind keine Renderer-Marotten, sondern folgt unmittelbar aus dem Satz in Abschnitt 5.3.
Die benachbarten Erweiterungen und eine, die in keiner Spezifikation steht
Tabellen sind Abschnitt 4.10 der GFM-Spezifikation, ebenfalls eine Erweiterung. Unsere dreizeilige Pipe-Tabelle kam unter GitHub-Variante und unter den Standardeinstellungen einer anderen Bibliothek als echtes table-Element heraus und unter der CommonMark-Referenzimplementierung als ein einziger Absatz mit wörtlichen Strichen. Die Durchstreichung ist Abschnitt 6.5 und seltsamer, als sie aussieht: Die Spezifikation erlaubt eine oder zwei Tilden, also wird ~hier~ durchgestrichen, drei oder mehr aber nicht, also bleibt ~~~nein~~~ wörtlich. Eine getestete Bibliothek strich mit zwei Tilden durch, mit einer nicht, und gab ein Durchstreichungselement statt des in der GFM-Spezifikation gezeigten Gelöscht-Elements aus. Zwei Renderer können beide Durchstreichung unterstützen und sich dennoch über Eingabe und Ausgabe uneinig sein.
Autolinks gibt es in zwei Formen, und nur eine gehört zum Kern. Eine Adresse in spitzen Klammern ist CommonMark und wurde in jedem getesteten Renderer zum Link. Eine nackte Adresse ist Abschnitt 6.9 von GFM, eine Erweiterung mit eigenen Regeln: Vor eine www-Adresse wird das Schema http gesetzt, und abschließende Interpunktion bleibt außerhalb des Links, sodass „Besuch www.commonmark.org.“ die Adresse verlinkt und den Punkt draußen lässt. Nur die GitHub-Konfiguration erzeugte diese Links; die anderen ließen den Text unangetastet.
Fußnoten sind der lehrreiche Fall, denn sie stehen in keiner der beiden Spezifikationen. Das Wort footnote kommt in der CommonMark-Spezifikation genau einmal und in der GFM-Spezifikation genau einmal vor, im selben historischen Einleitungssatz über Implementierungen, die Konventionen für Fußnoten und Tabellen hinzufügten. Alle vier Renderer ließen [^1] als wörtlichen Text stehen und machten aus der Definitionszeile einen verwaisten Absatz. GitHub selbst stellt Fußnoten dar, und genau darin liegt die Falle: Eine Funktion, die man hat funktionieren sehen, gehört deshalb noch nicht zum Format.
„Markdown“ ist nicht ein Format
Zwei Spezifikationen mit verschiedenen Versionsnummern und fünf Jahren Abstand, dazu ein Optionssatz je Bibliothek — das ist kein einziges Format. Die Uneinigkeiten reichen weit unter die Ebene der Funktionen. Beim harten Zeilenumbruch gaben zwei unserer Renderer ein selbstschließendes Umbruch-Tag aus und zwei die HTML5-Form. Bei einem script-Element in der Quelle reichten zwei es unverändert in die Ausgabe durch und einer maskierte es als Text; die GFM-Spezifikation hat eine ganze Erweiterung, Abschnitt 6.11, die neun bestimmte Tags filtert, indem sie deren öffnende spitze Klammer durch eine Entität ersetzt. Nichts davon ist ein Fehler.
Die praktische Regel daraus ist kurz: Schreibe für den Renderer, auf den du tatsächlich zielst, und wisse, welcher das ist. Eine README auf einer Code-Plattform, ein Dokumentations-Generator, ein Chat-Client und ein Static-Site-Builder sind vier Ziele mit vier Funktionsumfängen, und ein Dokument, das in einem korrekt erscheint, gibt keine Garantie für die anderen. Ist das Ziel unbekannt, bleib innerhalb von CommonMark: Überschriften, Hervorhebung, Listen, Code, Links, Autolinks in spitzen Klammern und Zitate sind überall gleich.
Teste den Hin- und Rückweg und zähl aus der Quelle
Der billigste Test einer Checkliste ist Arithmetik. Wir haben eine verschachtelte Sprint-Liste mit fünf Einträgen geschrieben, zwei davon als erledigt markiert, sie aus der Markdown-Quelle mit einem Muster gezählt, das den Marker am Eintragsanfang erkennt, und 2 von 5 erhalten. Dasselbe Dokument mit GitHub-Variante gerendert und die angehakten input-Elemente im HTML gezählt ergab ebenfalls 2 von 5. Mit der CommonMark-Referenzimplementierung gerendert ergab es null input-Elemente — das Dokument ist unversehrt, die Kontrollkästchen waren in diesem Dialekt nur nie ein Merkmal.
Das ist die Gewohnheit, die sich lohnt: aus der Quelle zählen, nicht aus der Darstellung. Die Markdown-Datei ist der Datensatz; das HTML ist eine Deutung davon, und welche du bekommst, hängt von einer Bibliotheksversion und einem Schalter ab. Unser Checklisten-Generator schreibt den GFM-Marker genau so, wie Abschnitt 5.3 ihn festlegt — Aufzählungszeichen, Leerzeichen, Klammer, ein Zeichen, Klammer, Leerzeichen —, sodass die Datei dort funktioniert, wo die Erweiterung unterstützt wird, und dort, wo nicht, zu einer lesbaren Klammerliste zerfällt. Muss das Kontrollkästchen überall überleben, ist die ehrliche Alternative eine einfache Liste mit dem Wort „erledigt“ darin.
| Funktion | In CommonMark 0.31.2? | In der GFM-Spez. 0.29? | Ausgabe der Referenzimplementierung | Ausgabe von markdown-it Standard |
|---|---|---|---|---|
| Aufgabenliste - [ ] / - [x] | Nein — 0 Erwähnungen | Ja — Abschnitt 5.3, Erweiterung | Wörtliches [ ] im Listeneintrag | Wörtliches [ ] im Listeneintrag |
| Pipe-Tabelle | Nein | Ja — Abschnitt 4.10, Erweiterung | Ein Absatz mit wörtlichen Strichen | Ein echtes table-Element |
| Durchstreichung mit zwei Tilden | Nein | Ja — Abschnitt 6.5, Erweiterung | Wörtliche Tilden | Ein durchgestrichenes Element, aber s statt del |
| Durchstreichung mit einer Tilde | Nein | Ja — eine oder zwei Tilden | Wörtliche Tilden | Wörtliche Tilden — es verlangt zwei |
| Nackte URL wird zum Link | Nein | Ja — Abschnitt 6.9, Erweiterung | Reiner Text | Reiner Text in den getesteten Konfigurationen |
| Autolink in spitzen Klammern | Ja — Teil der Kernspezifikation | Ja, geerbt | Ein echter Link | Ein echter Link |
| Fußnote [^1] | Nein | Nein — auch nicht in der Spezifikation | Wörtliches [^1] und eine verwaiste Definitionszeile | Wörtliches [^1] und eine verwaiste Definitionszeile |
| Rohes HTML durchgereicht | Ja, standardmäßig | Ja, abzüglich neun gefilterter Tags | Unverändert durchgereicht | Als Text maskiert |
Häufige Fragen
- Warum erscheinen meine Kontrollkästchen als [ ] statt als Kästchen?
- Weil der Renderer CommonMark ohne die GitHub-Erweiterungen umsetzt. Aufgabenlisten sind Abschnitt 5.3 der GFM-Spezifikation und kommen in CommonMark 0.31.2 nirgends vor. Die zweite Möglichkeit ist ein fehlerhafter Marker: Das Leerzeichen nach der schließenden Klammer ist Pflicht, zwischen die Klammern gehört genau ein Zeichen, und der Marker muss den ersten Absatz des Eintrags eröffnen. All diese Fehler erscheinen ohne Warnung als wörtlicher Text.
- Muss das x klein geschrieben sein?
- Nein. Die GFM-Spezifikation sagt: der Buchstabe x in Klein- oder Großschreibung, und wir haben bestätigt, dass beide ein angehaktes Kästchen ergeben. Kein anderer Buchstabe tut das: ein o zwischen den Klammern erschien in jedem getesteten Renderer als wörtlicher Text. Auch zwei Zeichen sind nicht erlaubt — ein Marker mit zwei Leerzeichen zwischen den Klammern ist kein Marker.
- Lassen sich Aufgabenlisten verschachteln oder in nummerierten Listen verwenden?
- Beides. Die GFM-Spezifikation zeigt beliebig verschachtelte Aufgabenlisten in einem ausgeführten Beispiel, und unser Lauf erzeugte ein Kontrollkästchen beim Elternteil und bei jedem eingerückten Kind. Ein nummerierter Listeneintrag funktioniert genauso — der Marker steht nach Zahl und Punkt. Nicht funktioniert ein Eintrag, dessen erster Block kein Absatz ist: Ein Zitat vor dem Marker unterdrückte das Kästchen in jedem Renderer.
- Sind Tabellen und Durchstreichung überall sicher?
- Nein. Beide sind GFM-Erweiterungen, Abschnitte 4.10 und 6.5, und keine steht in CommonMark. Unsere Pipe-Tabelle kam in zwei Konfigurationen als echte Tabelle heraus und in einer anderen als Absatz mit wörtlichen Strichen. Die Durchstreichung ist schlimmer: Die GFM-Spezifikation streicht Text zwischen einer oder zwei Tilden durch, aber nicht bei dreien, während eine andere verbreitete Bibliothek zwei verlangte und ein anderes HTML-Element für das Ergebnis erzeugte.
- Gehören Fußnoten zu GitHub Flavored Markdown?
- Nach der veröffentlichten GFM-Spezifikation nicht. Das Wort footnote kommt darin genau einmal vor, in einem historischen Satz der Einleitung, und es gibt keinen Abschnitt über Fußnoten. GitHubs eigene Website stellt sie dennoch dar, was den Unterschied zwischen Spezifikation und Produkt gut zeigt. Alle vier getesteten Renderer ließen den Verweis als wörtlichen Text und die Definition als verwaisten Absatz stehen.
Artikel, die dich interessieren könnten
Alle Ratgeber →Ähnliche Tools
Quellen
- CommonMark — CommonMark Spec, version 0.31.2 (2024-01-28) — the core grammar, which contains no task lists, tables, strikethrough or footnotes
- GitHub — GitHub Flavored Markdown Spec, version 0.29-gfm (2019-04-06) — sections 4.10 Tables, 5.3 Task list items, 6.5 Strikethrough, 6.9 Autolinks, 6.11 Disallowed Raw HTML
- CommonMark — The CommonMark project — reference implementations and the Dingus for testing a document against the core spec
- GitHub Docs — Basic writing and formatting syntax — the features GitHub renders beyond its own published specification, including footnotes
Hast du einen Fehler in diesem Artikel entdeckt?