Aus ## Zwischenstand wird <h2>Zwischenstand</h2>, aus *Frist* wird <em>Frist</em>, und aus drei Zeilen mit führendem Bindestrich wird eine <ul> mit drei <li>. Der Konverter gibt genau dieses HTML aus — ein Fragment ohne Stylesheet, ohne Seitengerüst, nur die Elemente.
Umgewandelt wird ein Teil von Markdown, nicht die ganze Sprache: Überschriften, Fett- und Kursivschrift, Inline-Code, Links, Bilder in der Form , nummerierte und Aufzählungslisten, Codeblöcke und Absätze. Tabellen, Zitate, Fußnoten und rohes HTML gehören ausdrücklich nicht dazu — was davon in Ihrem Text steckt, nennt das Feld „Hinweis“ beim Namen.
Warum es den einen Markdown-Standard nicht gibt
Markdown entstand 2004 als Beschreibung in Prosa plus ein Perl-Skript, das sie umsetzte. Wo die Beschreibung schwieg — verschachtelte Listen, Hervorhebung mitten im Wort, ein Codeblock direkt hinter einer Liste — entschied das Skript, und andere Programme entschieden anders. CommonMark ist seit 2014 der Versuch, diese Fälle verbindlich festzuschreiben, mit einer Spezifikation und mehreren hundert Testfällen statt einer Erzählung.
Durchgesetzt hat sich das nur zur Hälfte. GitHub setzt mit GitHub Flavored Markdown auf CommonMark auf, ergänzt aber Tabellen, Aufgabenlisten, durchgestrichenen Text und automatisch verlinkte URLs (Autolinks); GitLab, Obsidian und Pandoc bringen jeweils eigene Zusätze mit. Eine Datei, die an einer Stelle sauber aussieht, kann an der nächsten anders aussehen — und Tabellen sind eben eine solche Erweiterung, kein Bestandteil von Markdown selbst.
Was hier umgewandelt wird — und was nicht
Erkannt werden Überschriften der Ebenen eins bis sechs mit führenden Rautezeichen, **fett** und *kursiv*, Inline-Code in einfachen Backticks, Links in der Form [Text](Adresse), Bilder in der Form , Aufzählungen mit -, * oder +, nummerierte Listen, Codeblöcke zwischen drei Backticks sowie normale Absätze, die durch eine Leerzeile getrennt sind. Fett geht auch mit __zwei Unterstrichen__; ein einzelner Unterstrich wird nicht als Kursivschrift gelesen, und in nummerierten Listen dürfen Sie 1. oder 1) schreiben. Wie viele Blöcke der Konverter gezählt hat, steht neben der Ausgabe: Ein Block ist eine Überschrift, ein Absatz, eine Liste oder ein Codeblock.
Nicht unterstützt sind Tabellen mit senkrechten Strichen, Fußnoten und rohes HTML, das Sie in den Markdown-Text schreiben. Ebenso wenig erkannt werden Zitate mit >, Trennlinien aus ---, mit vier Leerzeichen eingerückte Codeblöcke und harte Zeilenumbrüche: Zeilen eines Absatzes werden zu einer Zeile zusammengezogen. Diese Zeilen verschwinden nicht, sie werden aber als gewöhnlicher Text behandelt und erscheinen mit ihren Sonderzeichen in der Ausgabe — das Feld „Hinweis“ zählt auf, was davon in Ihrem Text vorkam. Wenn Sie eine Tabelle brauchen, schreiben Sie das <table> von Hand oder lassen Sie die Datei von dem System umwandeln, dessen Erweiterung Sie benutzen.
Warum spitze Klammern maskiert und Adressen geprüft werden
Jedes <, > und & aus Ihrer Eingabe wird zu <, > und &, jedes doppelte Anführungszeichen zu " — sonst ließe sich das href-Attribut eines erzeugten Links von innen aufbrechen. Ohne diesen Schritt wäre der Konverter eine offene Tür: Ein Text mit einem <script>-Element oder einem onerror-Attribut würde unverändert in die Seite wandern und dort ausgeführt werden — genau das Muster, das als Cross-Site-Scripting bekannt ist. Maskiert wird nur, was aus der Eingabe stammt; die Elemente, die der Konverter selbst erzeugt, bleiben natürlich HTML.
Maskieren allein genügt allerdings nicht, denn auch das Ziel eines Links kommt aus Ihrem Text, und [klick](javascript:…) enthält kein einziges der maskierten Zeichen. Deshalb prüft der Konverter jede Adresse gegen eine Positivliste: http, https, mailto, tel und Adressen ohne Schema, also relative Pfade und Anker. Alles andere wird kein Link, sondern bleibt sichtbar als Text stehen. Der Preis für beides ist, dass sich kein HTML durch den Markdown-Text schmuggeln lässt; wer das braucht — und die Ursprungsfassung von Markdown erlaubt es ausdrücklich —, kommt an einem nachgeschalteten Filter nicht vorbei, der erlaubte Elemente und Attribute gegen eine Positivliste prüft.