Warum sich zwei Parser über Ihr Dokument streiten
Markdown wurde 2004 als Perl-Skript und eine Seite Prosa veröffentlicht, ohne formale Grammatik. Diese Informalität ist der Grund, warum es sich verbreitete, und auch warum dasselbe Dokument in verschiedenen Tools unterschiedlich gerendert wird. Die ursprüngliche Implementierung ließ Dutzende Fälle undefiniert: was ein Listenmarker bei drei Leerzeichen Einzug macht, wie sich Betonung in einem Wort verschachtelt, ob eine Überschrift eine Leerzeile vor sich braucht. Jeder Implementierer löste diese Lücken durch Raten, und sie rieten unterschiedlich.
CommonMark existiert, um diese Lücke zu schließen. Es ist eine präzise Spezifikation mit mehreren hundert Konformitätstests, die genau die mehrdeutigen Fälle abdecken, die das Original offenließ. Dieser Konverter verwendet markdown-it, das die vollständige CommonMark-Suite besteht, sodass die Ausgabe mit dem übereinstimmt, was GitHub, Reddit, Discourse und die meisten modernen Tools produzieren. Wenn ein Dokument hier gerendert wird, wird es dort auf dieselbe Weise gerendert.
GitHub Flavored Markdown ist ein Superset, das obenauf liegt: Tabellen, Durchgestrichenes, Aufgabenlisten und automatisch verlinkte URLs. Tabellen und Aufgabenlisten funktionieren in diesem Tool, weshalb das Beispieldokument beide enthält. Der Unterschied ist wichtig, wenn Sie für ein Ziel schreiben, das Sie nicht kontrollieren, denn eine Tabelle ist nicht Teil von CommonMark selbst, und ein strenger Parser wird sie als einfachen Text durchreichen.
Was die vier Schalter tatsächlich ändern
Autolinking verwandelt eine nackte URL in einen Anker. Es ist praktisch für Changelogs und Notizen, aber es ist eine Abweichung von CommonMark, das Winkelklammern um einen nackten Link verlangt. Schalten Sie es aus, wenn die Ausgabe zu einem strengen Parser portabel sein muss.
Intelligente Typografie schreibt gerade Anführungszeichen in geschwungene um und wandelt -- in einen Halbgeviert-Strich. Das ist richtig für Prosa und falsch für alles, was Code-Fragmente außerhalb eines Code-Blocks enthält, da es bereitwillig ein Kommandozeilen-Flag verstümmelt. Code-Spans und Fenced-Blocks bleiben stets unangetastet.
Harte Zeilenumbrüche ändern, was ein einzelner Zeilenumbruch bedeutet. Standardmäßig fügt Markdown aufeinanderfolgende Zeilen zu einem Absatz zusammen, was die meisten Dokumente annehmen. Chat-artige Eingabe, wo Leute für eine neue Zeile Enter drücken, braucht das eingeschaltet, sonst kollabiert ihre Formatierung.
Der Durchlass von rohem HTML ist der mit Sicherheitsfolgen. Ist er aus, wird ein <img onerror=...> in der Quelle escaped und als Text angezeigt. Ist er an, wird es als live Markup ausgegeben. Lassen Sie es für alles Benutzereingereichte aus.
Bereinigen ist ein eigener Job
Der häufigste Fehler bei jeder Markdown-Pipeline ist anzunehmen, der Konverter schütze Sie. Tut er nicht, und er soll es auch nicht. Selbst mit deaktiviertem rohen HTML bleibt ein Linkziel angreiferkontrolliert, also erzeugt [click](javascript:alert(1)) einen Anker, den ein Browser möglicherweise ausführt. Allein die Markdown-Syntax reicht, um einen funktionierenden Angriff zu bauen.
Das korrekte Muster ist konvertieren, dann bereinigen, dann einfügen. Lassen Sie das HTML durch einen dedizierten Sanitizer wie DOMPurify mit einer Allowlist von Tags und Attributen laufen, und erst dann setzen Sie es in die Seite. Tun Sie das auf dem Server, wenn der Inhalt jemandem außer seinem Autor gezeigt wird, denn clientseitiges Bereinigen kann von jedem umgangen werden, der direkt mit Ihrer API sprechen kann. Dieses Tool rendert seine Vorschau lokal in Ihrem eigenen Browser mit Ihrer eigenen Eingabe, was ein anderes Bedrohungsmodell ist als das Veröffentlichen von fremdem Markdown.