CommonMark: Eine formale Spezifikation für Markdown

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Markdown ist eine leistungsstarke Auszeichnungssprache, die das Bearbeiten und Formatieren im Nur-Text-Format ermöglicht, das dann geparst und als HTML gerendert werden kann. Es hat eine deklarative Syntax, die sowohl leistungsfähig als auch für technisch und nicht technisch versierte Leute leicht zu erlernen ist. Aufgrund der daraus resultierenden Mehrdeutigkeiten in der ursprünglichen Spezifikation gab es jedoch eine Reihe unterschiedlicher Varianten (oder benutzerdefinierter Versionen), die darauf abzielen, diese Mehrdeutigkeiten zu beseitigen und die ursprüngliche Syntaxunterstützung zu erweitern. Dies hat zu einer steilen Abweichung zwischen dem, was analysiert werden kann, und dem, was gerendert wird, geführt. CommonMark zielt darauf ab, eine standardisierte Spezifikation von Markdown bereitzustellen, die die Verwendung in der realen Welt widerspiegelt.

CommonMark ist eine rationalisierte Version der Markdown-Syntax mit einer Spezifikation, deren Ziel es ist, die Mehrdeutigkeiten und Inkonsistenzen rund um die ursprüngliche Markdown-Spezifikation zu beseitigen. Es bietet eine standardisierte Spezifikation, die die gemeinsame Syntax der Sprache zusammen mit einer Reihe umfassender Tests definiert, um Markdown-Implementierungen anhand dieser Spezifikation zu validieren.

GitHub verwendet Markdown als Auszeichnungssprache für seine Benutzerinhalte.

„CommonMark ist ein ehrgeiziges Projekt, um die Markdown-Syntax, die von vielen Websites im Internet verwendet wird, formal so zu spezifizieren, dass sie ihre reale Nutzung widerspiegelt eine umfassende Spezifikation und Referenzimplementierungen, um Markdown auf konsistente Weise zwischen Plattformen zu interagieren und anzuzeigen.“

– „Eine formelle Spezifikation für GitHub Flavored Markdown“, The GitHub Blog

Im Jahr 2012 entwickelte GitHub eine eigene Variante von Markdown – GitHub Flavored Markdown (GFM) – um dem Mangel an Markdown-Standardisierung entgegenzuwirken und die Syntax an seine Bedürfnisse anzupassen. GFM wurde auf Sundown aufgebaut, einem Parser, der speziell von GitHub entwickelt wurde, um einige der Mängel der damals vorhandenen Markdown-Parser zu beheben. Fünf Jahre später, im Jahr 2017, kündigte es die Abschaffung von Sundown zugunsten der CommonMark-Parsing- und Rendering-Bibliothek cmark in A formal spec for GitHub Flavored Markdown an.

Im Abschnitt „Häufige Fragen“ von Markdown und Visual Studio-Code wird dokumentiert, dass Markdown in VSCode mithilfe der markdown-it-Bibliothek auf die CommonMark-Markdown-Spezifikation abzielt, die selbst der CommonMark-Spezifikation folgt.

CommonMark wurde weit verbreitet und implementiert (siehe Liste der CommonMark-Implementierungen) für die Verwendung in verschiedenen Sprachen wie C (zB cmark), C# (zB CommonMark.NET), JavaScript (zB markdown-it) usw. Das sind gute Nachrichten für Entwickler und Autoren bewegen sich allmählich an eine neue Grenze, um Markdown mit einer konsistenten Syntax und einer standardisierten Spezifikation verwenden zu können.

Eine kurze Anmerkung zu Markdown-Parsern

Markdown-Parser sind das Herzstück der direkten oder indirekten Umwandlung von Markdown-Text in HTML.

Parser wie cmark und commonmark.js konvertieren Markdown nicht direkt in HTML, sondern konvertieren es in einen Abstract Syntax Tree (AST) und rendern dann den AST als HTML, wodurch der Prozess granularer und anfälliger für Manipulationen wird. Zwischen dem Parsen – nach AST – und dem Rendern – nach HTML – könnte beispielsweise der Markdown-Text erweitert werden.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Unterstützung der Markdown-Syntax von CommonMark

Projekte oder Plattformen, die die CommonMark-Spezifikation bereits als Basis ihrer spezifischen Variante implementieren, sind oft eine Obermenge der strengen Teilmenge der CommonMark-Markdown-Spezifikation. Zum größten Teil hat CommonMark viele Unklarheiten beseitigt, indem es eine Spezifikation erstellt hat, auf der aufgebaut werden kann. GFM ist ein Paradebeispiel, das zwar jede CommonMark-Syntax unterstützt, sie aber auch entsprechend ihrer Verwendung erweitert.

Die Syntaxunterstützung von CommonMark kann zunächst eingeschränkt sein, zum Beispiel hat es keine Unterstützung für diese Tabellensyntax, aber es ist wichtig zu wissen, dass dies beabsichtigt ist, wie dieser Kommentar in diesem Konversationsthread zeigt: dass die unterstützte Syntax streng und gesagt ist die Kernsyntax der Sprache selbst zu sein – die gleiche, die von ihrem Schöpfer John Gruber in Markdown: Syntax angegeben wurde.

Zum Zeitpunkt des Schreibens sind hier einige unterstützte Syntaxen aufgeführt:

  1. Absätze und Zeilenumbrüche,
  2. Überschriften,
  3. Betonung und starke Betonung,
  4. Horizontale Regeln,
  5. Listen,
  6. Links,
  7. Bilder,
  8. Block Zitate,
  9. Code,
  10. Code-Blöcke.

Um den Beispielen zu folgen, wird empfohlen, dass Sie den commonmark.js Dingus-Editor verwenden, um die Syntax auszuprobieren und die gerenderte Vorschau, generiertes HTML und AST zu erhalten.

Absätze und Zeilenumbrüche

In Markdown sind Absätze fortlaufende Textzeilen, die durch mindestens eine Leerzeile getrennt sind.

Die folgenden Regeln definieren einen Absatz:

  1. Markdown-Absätze werden in HTML als Paragraph-Element <p> gerendert.
  2. Verschiedene Absätze werden durch eine oder mehrere Leerzeilen getrennt.
  3. Bei einem Zeilenumbruch sollte ein Absatz mit zwei Leerzeichen (oder dem entsprechenden Tabulator) oder einem umgekehrten Schrägstrich ( \ ) nachgestellt werden.
Syntax Gerenderter HTML-Code
Dies ist eine Textzeile <p>Dies ist eine Textzeile</p>
Dies ist eine Textzeile
Und noch eine Textzeile
Und eine andere, aber die
gleichen Absatz
<p>Dies ist eine Textzeile
Und noch eine Textzeile
Und eine andere, aber die
gleichen Absatz</p>
Dies ist ein Absatz

Und noch ein Absatz

Und ein anderer
<p>Dies ist ein Absatz</p>
<p>Und noch ein Absatz</p>
<p>Und noch eins</p>
Zwei Leerzeichen nach einer Textzeile
Oder ein nachgestellter Backslash\
Beides bedeutet Zeilenumbruch
<p>Zwei Leerzeichen nach einer Textzeile<br /><br>Oder ein nachgestellter umgekehrter Schrägstrich<br /><br>Beides bedeutet einen Zeilenumbruch</p>
  • Interaktives Tutorial zum Erlernen von Absätzen.
  • Dingus permalink check out the full example with the Preview and AST.
  • Erfahren Sie mehr über Absätze.

Überschriften

Überschriften in Markdown stellen eines der HTML-Überschriftenelemente dar. Es gibt zwei Möglichkeiten, Überschriften zu definieren:

  1. ATX-Überschrift.
  2. Setext-Überschrift.

Die folgenden Regeln definieren ATX-Überschriften:

  1. Überschriftenebene 1 ( h1 ) bis Überschriftenebene 6 ( h6 ) werden unterstützt.
  2. Überschriften im ATX-Stil wird das Hash-Symbol ( # ) vorangestellt.
  3. Es muss mindestens ein Leerzeichen vorhanden sein, das den Text und das Hash-Symbol ( # ) trennt.
  4. Die Anzahl der Hashes entspricht der Kardinalzahl der Überschrift. Ein Hash ist h1 , zwei Hashes h2 , 6 Hashes h6 .
  5. Es ist auch möglich, eine beliebige Anzahl von Rautenzeichen an Überschriften anzuhängen, was jedoch keinen Effekt hat (z. B. # Heading 1 # )
Syntax Gerenderter HTML-Code
# Überschrift 1 <h1>Überschrift 1</h1>
## Überschrift 2 <h2>Überschrift 2</h2>
### Überschrift 3 <h3>Überschrift 3</h3>
#### Überschrift 4 <h4>Überschrift 4</h4>
##### Überschrift 5 <h5>Überschrift 5</h5>
###### Überschrift 6 <h6>Überschrift 6</h6>
## Überschrift 2 ## <h2>Überschrift 2</h2>

Die folgenden Regeln definieren Setext-Überschriften:

  1. Nur Überschriftenebene 1 (h1) und Überschriftenebene 2 (h2) werden unterstützt.
  2. Die Definition im Settext-Stil erfolgt mit den Gleichheitszeichen (=) bzw. Bindestrichen.
  3. Bei Setext ist mindestens ein Gleichheits- oder Bindestrichzeichen erforderlich.
Syntax Gerenderter HTML-Code
Überschrift 1
=
<h1>Überschrift 1</h1>
Überschrift 2
-
<h2>Überschrift 2</h2>
  • Interaktives Tutorial zum Erlernen von Überschriften.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über ATX-Kurse.
  • Erfahren Sie mehr über Setext-Überschriften.

Betonung und starke Betonung

Hervorhebungen in Markdown können entweder kursiv oder fett (starke Hervorhebung) sein.

Die folgenden Regeln definieren die Betonung:

  1. Gewöhnliche und starke Hervorhebungen werden in HTML als Emphasis, <em> bzw. Strong, <strong> Element dargestellt.
  2. Ein Text, der durch ein einzelnes Sternchen ( * ) oder einen Unterstrich ( _ ) begrenzt ist, wird hervorgehoben.
  3. Ein Text, der von doppelten Sternchen oder Unterstrichen umgeben ist, wird stark hervorgehoben.
  4. Die Begrenzungssymbole (Sternchen oder Unterstrich) müssen übereinstimmen.
  5. Zwischen den Symbolen und dem eingeschlossenen Text darf kein Leerzeichen stehen.
Syntax Gerenderter HTML-Code
_Italic_ <em>Kursiv</em>
*Italic* <em>Kursiv</em>
__Bold__ <strong>Fett</strong>
**Bold** <strong>Fett</strong>
  • Interaktives Tutorial zum Erlernen von Betonung.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Betonung und starke Betonung.

Horizontale Regel

Eine horizontale Linie <hr/> wird mit drei oder mehr Sternchen ( * ), Bindestrichen ( - ) oder Unterstrichen ( _ ) in einer neuen Zeile erstellt. Die Symbole werden durch beliebig viele Leerzeichen oder gar nicht getrennt.

Syntax Gerenderter HTML-Code
*** <hr />
* * * <hr />
--- <hr />
- - - <hr />
___ <hr />
_ _ _ <hr />
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Thematische Pausen.

Listen

Listen in Markdown sind entweder eine Aufzählungsliste (ungeordnet) oder eine geordnete Liste.

Die folgenden Regeln definieren eine Liste:

  1. Aufzählungslisten werden in HTML als ungeordnetes Listenelement <ul> gerendert.
  2. Geordnete Listen werden in HTML als geordnetes Listenelement <ol> gerendert.
  3. Aufzählungslisten verwenden Sternchen, Pluszeichen und Bindestriche als Markierungen.
  4. Geordnete Listen verwenden Zahlen gefolgt von Punkten oder schließenden Klammern.
  5. Die Markierungen müssen konsistent sein (Sie dürfen nur die Markierung verwenden, mit der Sie für den Rest der Definition der Listenelemente beginnen).
Syntax Gerenderter HTML-Code
* ein
* zwei
* drei
<ul>
<li>eins</li>
<li>zwei</li>
<li>drei</li>
</ul>
+ eins
+ zwei
+ drei
<ul>
<li>eins</li>
<li>zwei</li>
<li>drei</li>
</ul>
- ein
- zwei
- drei
<ul>
<li>eins</li>
<li>zwei</li>
<li>drei</li>
</ul>
- ein
- zwei
+ drei
<ul>
<li>eins</li>
<li>zwei</li>
</ul>
<ul>
<li>drei</li>
</ul>
1 Eins
2. zwei
3. drei
<ol>
<li>eins</li>
<li>zwei</li>
<li>drei</li>
</ol>
3. drei
4. vier
5. fünf
<ol start="3">
<li>drei</li>
<li>vier</li>
<li>fünf</li>
</ol>
1 Eins
2. zwei
3. drei
<ol>
<li>eins</li>
<li>zwei</li>
<li>drei</li>
</ol>
  • Interaktives Tutorial zum Erlernen von Listen.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Listenelemente.

Verknüpfungen

Links werden im Inline- und Referenzformat unterstützt.

Die folgenden Regeln definieren einen Link:

  1. Links werden als HTML-Ankerelement <a> gerendert.
  2. Das Inline-Format hat die Syntax: [value](URL "optional-title") ohne Leerzeichen zwischen den Klammern.
  3. Das Referenzformat hat die Syntax: [value][id] für die Referenz und [id]: href "optional-title" für die Hyperlinkbezeichnung, getrennt durch mindestens eine Linie.
  4. Die id ist die Definitionskennung und kann aus Buchstaben, Zahlen, Leerzeichen und Satzzeichen bestehen.
  5. Definition Bezeichner unterscheiden nicht zwischen Groß- und Kleinschreibung.
  6. Es gibt auch Unterstützung für automatische Links, bei denen die URL durch das Kleiner-als- (<) und Größer-als-Symbol (>) begrenzt und wörtlich angezeigt wird.
 <!--Markdown--> [Google](https://google.com “Google”) <!--Rendered HTML--> <a href="https://google.com" title="Google">Google</a> <!--Markdown--> [Google](https://google.com) <!--Rendered HTML--> <a href="https://google.com">Google</a> <!--Markdown--> [Comparing Styling Methods in Next.js](/2020/09/comparing-styling-methods-next-js) <!--Rendered HTML--> <a href="/2020/09/comparing-styling-methods-next-js">Comparing Styling Methods In Next.js</a> <!--Markdown--> [Google][id] <!--At least a line must be in-between--> <!--Rendered HTML--> <a href="https://google.com" title="Google">Google</a> <!--Markdown--> <https://google.com> <!--Rendered HTML--> <a href="https://google.com">google.com</a> <!--Markdown--> <[email protected]> <!--Rendered HTML--> <a href="mailto:[email protected]">[email protected]</a>
  • Interaktives Tutorial, um mehr über Links zu erfahren.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Verknüpfungen.

Bilder

Bilder in Markdown folgen den Inline- und Referenzformaten für Links.

Die folgenden Regeln definieren Bilder:

  1. Bilder werden als HTML-Bildelement <img> gerendert.
  2. Das Inline-Format hat die Syntax: ![alt text](image-url "optional-title") .
  3. Das Referenzformat hat die Syntax: ![alt text][id] für die Referenz und [id]: image-url "optional-title" für die Bildbezeichnung. Beide sollten durch mindestens eine Leerzeile getrennt werden.
  4. Der Bildtitel ist optional und die Bild-URL kann relativ sein.
 <!--Markdown--> ![alt text](image-url "optional-title") <!--Rendered HTML--> <img src="image-url" alt="alt text" title="optional-title" /> <!--Markdown--> ![alt text][id] <!--At least a line must be in-between--> <!--Markdown--> <!--Rendered HTML--> <img src="image-url" alt="alt text" title="optional-title" />
  • Interaktives Tutorial zum Erlernen von Bildern.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Bilder.

Block Zitate

Das HTML-Blockzitatelement <blockquote> kann erstellt werden, indem einer neuen Zeile das Größer-als-Symbol ( > ) vorangestellt wird.

 <!--Markdown--> > This is a blockquote element > You can start every new line > with the greater than symbol. > That gives you greater control > over what will be rendered. <!--Rendered HTML--> <blockquote> <p>This is a blockquote element You can start every new line with the greater than symbol. That gives you greater control over what will be rendered.</p> </blockquote>

Blockquotes können verschachtelt werden:

 <!--Markdown--> > Blockquote with a paragraph >> And another paragraph >>> And another <!--Rendered HTML--> <blockquote> <p>Blockquote with a paragraph</p> <blockquote> <p>And another paragraph</p> <blockquote> <p>And another</p> </blockquote> </blockquote> </blockquote>

Sie können auch andere Markdown-Elemente wie Header, Code, Listenelemente usw. enthalten.

 <!--Markdown--> > Blockquote with a paragraph > # Heading 1 > Heading 2 > - > 1. One > 2. Two <!--Rendered HTML--> <blockquote> <p>Blockquote with a paragraph</p> <h1>Heading 1</h1> <h2>Heading 2</h2> <ol> <li>One</li> <li>Two</li> </ol> </blockquote>
  • Interaktives Tutorial zum Erlernen von Blockquotes.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Blockquotes.

Code

Das HTML-Inline-Code-Element <code> wird ebenfalls unterstützt. Um einen zu erstellen, begrenzen Sie den Text mit Backticks (`) oder doppelten Backticks, wenn der umschließende Text einen wörtlichen Backtick enthalten muss.

 <!--Markdown--> `inline code snippet` <!--Rendered HTML--> <code>inline code snippet</code> <!--Markdown--> `<button type='button'>Click Me</button>` <!--Rendered HTML--> <code><button type='button'>Click Me</button></code> <!--Markdown--> `` There's an inline back-tick (`). `` <!--Rendered HTML--> <code>There's an inline back-tick (`).</code>
  • Interaktives Tutorial zum Erlernen von Code.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über Codespannen.

Code-Blöcke

Das vorformatierte HTML-Textelement <pre> wird ebenfalls unterstützt. Dies kann mit mindestens drei und einer gleichen Anzahl von Begrenzungsrückstrichen ( ` ) oder Tilden ( ~ ) erfolgen – normalerweise als Codezaun bezeichnet, oder mit einer Einrückung von mindestens 4 Leerzeichen am Anfang einer neuen Zeile.

 <!--Markdown--> ``` const dedupe = (array) => [...new Set(array)]; ``` <!--Rendered HTML--> <pre><code>const dedupe = (array) => [...new Set(array)];</code></pre> <!--Markdown--> const dedupe = (array) => [...new Set(array)]; <!--Rendered HTML--> <pre><code>const dedupe = (array) => [...new Set(array)];</code></pre>
  • Interaktives Tutorial zum Erlernen von Code.
  • Dingus-Permalink, um sich das vollständige Beispiel mit Vorschau und AST anzusehen.
  • Erfahren Sie mehr über eingezäunte und eingerückte Codeblöcke.

Verwendung von Inline-HTML

Laut John Grubers ursprünglicher Spezifikationsnotiz zu Inline-HTML verwenden Sie jedes Markup, das nicht von Markdowns Syntax abgedeckt wird, einfach HTML selbst, wobei die einzigen Einschränkungen darin bestehen, dass HTML-Elemente auf Blockebene – z. B. <div> , <table> , <pre> , <p> usw. – müssen durch Leerzeilen vom umgebenden Inhalt getrennt sein, und die Start- und End-Tags des Blocks sollten nicht durch Tabulatoren oder Leerzeichen eingerückt sein.

Wenn Sie jedoch wahrscheinlich nicht zu den Personen gehören, die hinter CommonMark selbst stehen, werden Sie Markdown höchstwahrscheinlich mit einer Variante schreiben, die bereits erweitert wurde, um eine große Anzahl von Syntaxen zu verarbeiten, die derzeit nicht von CommonMark unterstützt werden.

Vorwärts gehen

CommonMark befindet sich in ständiger Arbeit, seine Spezifikation wurde zuletzt am 6. April 2019 aktualisiert. Es gibt eine Reihe beliebter Anwendungen, die es im Pool der Markdown-Tools unterstützen. In Anbetracht der Standardisierungsbemühungen von CommonMark halte ich es für ausreichend, zu dem Schluss zu kommen, dass hinter der Einfachheit von Markdown viel Arbeit hinter den Kulissen steckt und dass es für die CommonMark-Bemühungen gut ist, dass die formale Spezifikation von GitHub Flavored Markdown basiert auf der Spezifikation.

Der Schritt hin zu den CommonMark-Standardisierungsbemühungen verhindert nicht die Erstellung von Varianten zur Erweiterung der unterstützten Syntax, und da sich CommonMark mit Problemen, die gelöst werden müssen, auf Version 1.0 vorbereitet, gibt es einige interessante Ressourcen zu den kontinuierlichen Bemühungen, die Sie für Ihre Zwecke nutzen können Durchsicht.

Ressourcen

  • Wir stellen Markdown von John Gruber vor
  • Offizielle CommonMark-Website
  • GitHub Flavored Markdown Spec
  • cmark offizielles Repo
  • GitHubs Fork von cmark
  • Markdown auf Wikipedia
  • Markdown-Leitfaden