CommonMark: formalna specyfikacja przecen
Opublikowany: 2022-03-10CommonMark to zracjonalizowana wersja składni Markdown ze specyfikacją, której celem jest usunięcie niejasności i niespójności otaczającej oryginalną specyfikację Markdown. Oferuje ustandaryzowaną specyfikację, która definiuje wspólną składnię języka wraz z zestawem kompleksowych testów w celu weryfikacji implementacji Markdown pod kątem tej specyfikacji.
GitHub używa języka Markdown jako języka znaczników dla treści użytkownika.
„CommonMark to ambitny projekt polegający na formalnym określeniu składni Markdown używanej przez wiele witryn internetowych w sposób, który odzwierciedla jej rzeczywiste użycie [...] Pozwala ludziom nadal korzystać z Markdown w ten sam sposób, w jaki zawsze mają, oferując programistom obszerną specyfikację i implementacje referencyjne, aby współdziałać i wyświetlać Markdown w spójny sposób między platformami”.
— „Oficjalna specyfikacja przecen o smaku GitHub”, blog GitHub
W 2012 roku GitHub przystąpił do tworzenia własnej odmiany Markdown — GitHub Flavored Markdown (GFM) — w celu zwalczania braku standaryzacji Markdown i rozszerzenia składni na swoje potrzeby. GFM został zbudowany na Sundown, parserze stworzonym specjalnie przez GitHub w celu rozwiązania niektórych niedociągnięć istniejących w tym czasie parserów Markdown. Pięć lat później, w 2017 roku, ogłosił wycofanie Sundown na rzecz biblioteki parsowania i renderowania CommonMark, cmark w formalnej specyfikacji GitHub Flavored Markdown.
W sekcji Często zadawane pytania w Markdown i Visual Studio Code udokumentowano, że Markdown w VSCode jest przeznaczony dla specyfikacji CommonMark Markdown przy użyciu biblioteki markdown-it, która sama w sobie jest zgodna ze specyfikacją CommonMark.
CommonMark został powszechnie przyjęty i zaimplementowany (patrz Lista implementacji CommonMark) do użytku w różnych językach, takich jak C (np. Cmark), C# (np. CommonMark.NET), JavaScript (np. markdown-it) itp. To dobra wiadomość dla programistów a autorzy stopniowo wkraczają na nową granicę, jaką jest możliwość korzystania z języka Markdown ze spójną składnią i ustandaryzowaną specyfikacją.
Krótka uwaga na temat analizatorów przecen
Parsery Markdown są sercem konwersji tekstu Markdown na HTML, bezpośrednio lub pośrednio.
Parsery, takie jak cmark i commonmark.js, nie konwertują języka Markdown bezpośrednio na HTML, zamiast tego konwertują go na drzewo składni abstrakcyjnej (AST), a następnie renderują AST jako HTML, czyniąc proces bardziej szczegółowym i podatnym na manipulacje. Między analizowaniem — do AST — i renderowaniem — do HTML — na przykład tekst Markdown może zostać rozszerzony.
Obsługa składni Markdown w CommonMark
Projekty lub platformy, które już implementują specyfikację CommonMark jako podstawę swojego specyficznego smaku, są często nadrzędnym zbiorem ścisłego podzbioru specyfikacji CommonMark Markdown. W większości przypadków CommonMark złagodził wiele niejasności, tworząc specyfikację, która jest zbudowana na podstawie. GFM jest najlepszym przykładem, chociaż obsługuje każdą składnię CommonMark, ale także rozszerza ją, aby pasowała do jej użycia.
Obsługa składni CommonMark może być początkowo ograniczona, na przykład nie ma obsługi tej składni tabeli, ale ważne jest, aby wiedzieć, że jest to zgodne z projektem, ponieważ ten komentarz w tym wątku rozmowy ujawnia: obsługiwana składnia jest ścisła i powiedziana być podstawową składnią samego języka — taką samą, jaką określił jego twórca, John Gruber w Markdown: Syntax.
W chwili pisania tego tekstu istnieje kilka obsługiwanych składni:
- Akapity i łamanie wierszy,
- nagłówki,
- Nacisk i silny nacisk,
- Zasady horyzontalne,
- Listy,
- Spinki do mankietów,
- Zdjęcia,
- Cytaty blokowe,
- Kod,
- Bloki kodu.
Aby podążać za przykładami, zaleca się użycie edytora dingus commonmark.js, aby wypróbować składnię i uzyskać wyrenderowany podgląd, wygenerowany kod HTML i AST.
Akapity i łamanie wierszy
W Markdown akapity to ciągłe wiersze tekstu oddzielone co najmniej pustym wierszem.
Poniższe zasady definiują paragraf:
- Akapity Markdown są renderowane w HTML jako element Akapit, <p>.
- Poszczególne akapity są rozdzielone co najmniej jedną pustą linią.
- W przypadku łamania wiersza akapit powinien być uzupełniony o dwie spacje (lub jego odpowiednik w tabulatorach) lub ukośnik odwrotny (
\
).
Składnia | Renderowany kod HTML |
---|---|
To jest linia tekstu | <p>To jest linia tekstu</p> |
To jest linia tekstu I kolejna linijka tekstu I jeszcze jeden, ale ten sam akapit | <p>To jest linia tekstu I kolejna linijka tekstu I jeszcze jeden, ale ten sam akapit</p> |
To jest akapit I kolejny akapit I kolejny | <p>To jest akapit</p> <p>I kolejny akapit</p> <p>I jeszcze</p> |
Dwie spacje po wierszu tekstu Lub post-fixed backslash\ Oba oznaczają przerwę w wierszu | <p>Dwie spacje po wierszu tekstu<br /><br>Lub stały ukośnik odwrotny<br /><br>Oba oznaczają podział wiersza</p> |
- Interaktywny samouczek, aby dowiedzieć się o akapitach.
- Dingus permalink sprawdź pełny przykład z podglądem i AST.
- Dowiedz się więcej o paragrafach.
Nagłówki
Nagłówki w Markdown reprezentują jeden z elementów nagłówka HTML. Istnieją dwa sposoby definiowania nagłówków:
- Nagłówek ATX.
- Nagłówek setekstu.
Poniższe zasady definiują nagłówki ATX:
- Obsługiwane są nagłówki od poziomu 1 (
h1
) do poziomu nagłówka 6 (h6
). - Nagłówki w stylu ATX są poprzedzone symbolem hash (
#
). - Musi być co najmniej spacja oddzielająca tekst i symbol hash (
#
). - Liczba skrótów odpowiada liczbie kardynalnej nagłówka. Jeden hasz to
h1
, dwa haszy,h2
, 6 haszy,h6
. - Możliwe jest również dodanie dowolnej liczby symboli haszowania do nagłówków, chociaż nie powoduje to żadnego efektu (np.
# Heading 1 #
)
Składnia | Renderowany kod HTML |
---|---|
# Nagłówek 1 | <h1>Nagłówek 1</h1> |
## Nagłówek 2 | <h2>Nagłówek 2</h2> |
### Nagłówek 3 | <h3>Nagłówek 3</h3> |
#### Nagłówek 4 | <h4>Nagłówek 4</h4> |
##### Nagłówek 5 | <h5>Nagłówek 5</h5> |
###### Nagłówek 6 | <h6>Nagłówek 6</h6> |
## Nagłówek 2 ## | <h2>Nagłówek 2</h2> |
Poniższe zasady definiują nagłówki Setext:
- Obsługiwane są tylko nagłówki poziomu 1 (h1) i nagłówka poziomu 2 (h2).
- Definicja stylu setekstu odbywa się odpowiednio za pomocą symboli równości (=) i myślnika.
- W przypadku Setekstu wymagany jest co najmniej jeden symbol równości lub myślnika.
Składnia | Renderowany kod HTML |
---|---|
Nagłówek 1 = | <h1>Nagłówek 1</h1> |
Nagłówek 2 - | <h2>Nagłówek 2</h2> |
- Interaktywny samouczek do nauki nagłówków.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o nagłówkach ATX.
- Dowiedz się więcej o nagłówkach Setext.
Nacisk i silny nacisk
Nacisk w Markdown może być kursywą lub pogrubieniem (silny nacisk).
Poniższe zasady definiują nacisk:
- Zwykłe i silne podkreślenie są renderowane w HTML jako odpowiednio elementy Emphasis <em> i Strong <strong>.
- Tekst ograniczony pojedynczą gwiazdką (
*
) lub podkreśleniem (_
) zostanie wyróżniony. - Tekst ograniczony podwójną gwiazdką lub podkreśleniem będzie mocno akcentowany.
- Symbole ograniczające (gwiazdki lub podkreślenia) muszą być zgodne.
- Między symbolami a załączonym tekstem nie może być spacji.
Składnia | Renderowany kod HTML |
---|---|
_Italic_ | <em>kursywa</em> |
*Italic* | <em>kursywa</em> |
__Bold__ | <strong>Pogrubienie</strong> |
**Bold** | <strong>Pogrubienie</strong> |
- Interaktywny samouczek, aby dowiedzieć się o nacisku.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o nacisku i silnym nacisku.
Linia pozioma
Reguła pozioma <hr/> jest tworzona z co najmniej trzema gwiazdkami ( *
), łącznikami ( -
) lub podkreśleniami ( _
) w nowym wierszu. Symbole są oddzielone dowolną liczbą spacji lub wcale.
Składnia | Renderowany kod HTML |
---|---|
*** | <godz /> |
* * * | <godz /> |
--- | <godz /> |
- - - | <godz /> |
___ | <godz /> |
_ _ _ | <godz /> |
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o przerwach tematycznych.
Listy
Listy w Markdown są listą punktowaną (nieuporządkowaną) lub listą uporządkowaną.

Listę definiują następujące zasady:
- Listy punktowane są renderowane w HTML jako element listy nieuporządkowanej, <ul>.
- Listy uporządkowane są renderowane w języku HTML jako element listy uporządkowanej, <ol>.
- Listy punktowane używają gwiazdek, plusów i myślników jako znaczników.
- Listy uporządkowane zawierają liczby, po których następują kropki lub nawias zamykający.
- Znaczniki muszą być spójne (w pozostałej części definicji elementów listy należy używać tylko znacznika, od którego zaczynasz).
Składnia | Renderowany kod HTML |
---|---|
* jeden * dwa * trzy | <ul> <li>jeden</li> <li>dwa</li> <li>trzy</li> </ul> |
+ jeden + dwa + trzy | <ul> <li>jeden</li> <li>dwa</li> <li>trzy</li> </ul> |
- jeden - dwa - trzy | <ul> <li>jeden</li> <li>dwa</li> <li>trzy</li> </ul> |
- jeden - dwa + trzy | <ul> <li>jeden</li> <li>dwa</li> </ul> <ul> <li>trzy</li> </ul> |
1 jeden 2. dwa 3. trzy | <ol> <li>jeden</li> <li>dwa</li> <li>trzy</li> </ol> |
3. trzy 4. cztery 5. pięć | <ol start="3"> <li>trzy</li> <li>cztery</li> <li>pięć</li> </ol> |
1 jeden 2. dwa 3. trzy | <ol> <li>jeden</li> <li>dwa</li> <li>trzy</li> </ol> |
- Interaktywny samouczek, aby dowiedzieć się o listach.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o elementach list.
Spinki do mankietów
Łącza są obsługiwane w formacie wbudowanym i referencyjnym .
Poniższe zasady definiują łącze:
- Łącza są renderowane jako element zakotwiczenia HTML, <a>.
- Format wbudowany ma składnię:
[value](URL "optional-title")
bez spacji między nawiasami. - Format odniesienia ma składnię:
[value][id]
w przypadku odniesienia i[id]: href "optional-title"
w przypadku etykiety hiperlinku, oddzielone co najmniej linią. -
id
jest identyfikatorem definicji i może składać się z liter, cyfr, spacji i znaków interpunkcyjnych. - Definicja W identyfikatorach nie jest rozróżniana wielkość liter.
- Istnieje również wsparcie dla łączy automatycznych, w których adres URL jest ograniczony symbolem mniejszego (<) i większego niż (>) i jest wyświetlany dosłownie.
<!--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>
- Interaktywny samouczek, aby dowiedzieć się więcej o linkach.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o linkach.
Zdjęcia
Obrazy w Markdown są zgodne z formatami wbudowanymi i referencyjnymi dla linków.
Poniższe zasady definiują obrazy:
- Obrazy są renderowane jako element obrazu HTML, <img>.
- Format wbudowany ma składnię:

. - Format odniesienia ma składnię:
![alt text][id]
dla odniesienia i[id]: image-url "optional-title"
dla etykiety obrazu. Oba powinny być oddzielone co najmniej pustą linią. - Tytuł obrazu jest opcjonalny, a adres URL obrazu może być względny.
<!--Markdown-->  <!--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" />
- Interaktywny samouczek, aby dowiedzieć się o obrazach.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o obrazach.
Cytaty blokowe
Element cytatu blokowego HTML, <blockquote>, można utworzyć, poprzedzając nową linię symbolem większa niż ( >
).
<!--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>
Cytaty blokowe mogą być zagnieżdżane:
<!--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>
Mogą również zawierać inne elementy Markdown, takie jak nagłówki, kod, elementy listy i tak dalej.
<!--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>
- Interaktywny samouczek, aby dowiedzieć się o cytatach blokowych.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o cytatach blokowych.
Kod
Obsługiwany jest również element HTML Inline Code, <code>. Aby go utworzyć, ogranicz tekst tylnym haczykiem (`) lub podwójnym hakiem wstecznym, jeśli w otaczającym tekście musi być dosłowny znak wsteczny.
<!--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>
- Interaktywny samouczek do nauki kodu.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o zakresach kodu.
Bloki kodu
Obsługiwany jest również element HTML Preformated Text, <pre>. Można to zrobić za pomocą co najmniej trzech i równej liczby ograniczających kresek ( `
) lub tyld ( ~
) — zwykle określanych mianem ogrodzenia kodu lub nowej linii rozpoczynającej wcięcie co najmniej 4 spacji.
<!--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>
- Interaktywny samouczek do nauki kodu.
- Dingus permalink, aby sprawdzić pełny przykład z podglądem i AST.
- Dowiedz się więcej o zablokowanych i wciętych blokach kodu.
Korzystanie z wbudowanego HTML
Według oryginalnej noty technicznej Johna Grubersa dotyczącej wbudowanego HTML, wszelkie znaczniki, które nie są objęte składnią Markdowna, po prostu używasz samego HTML, z jedynymi ograniczeniami są elementy HTML na poziomie bloków — np. <div>
, <table>
, <pre>
, <p>
itd. — muszą być oddzielone od otaczającej treści pustymi liniami, a znaczniki początku i końca bloku nie powinny być wcięte tabulatorami ani spacjami.
Jednakże, jeśli nie jesteś prawdopodobnie jedną z osób stojących za samym CommonMark lub w pobliżu, najprawdopodobniej będziesz pisać Markdown ze smakiem, który jest już rozszerzony, aby obsłużyć dużą liczbę składni, które obecnie nie są obsługiwane przez CommonMark.
Iść naprzód
CommonMark jest stale w toku, a jego specyfikacja została ostatnio zaktualizowana 6 kwietnia 2019 r. W puli narzędzi Markdown znajduje się wiele popularnych aplikacji, które go obsługują. Mając świadomość wysiłków CommonMark w kierunku standaryzacji, myślę, że wystarczy stwierdzić, że w uproszczeniu Markdowna za kulisami jest dużo pracy i że dobrą rzeczą dla wysiłków CommonMark jest to, że formalna specyfikacja GitHub Flavored Markdown opiera się na specyfikacji.
Ruch w kierunku standaryzacji CommonMark nie przeszkadza w tworzeniu smaków rozszerzających obsługiwaną składnię, a ponieważ CommonMark przygotowuje się do wydania 1.0 z problemami, które muszą zostać rozwiązane, istnieje kilka interesujących zasobów dotyczących ciągłego wysiłku, który można wykorzystać do uważne przeczytanie.
Zasoby
- Przedstawiamy Markdown autorstwa Johna Grubera
- Oficjalna strona internetowa CommonMark
- Specyfikacja przecen o smaku GitHub
- Cmark oficjalne repozytorium
- Widelec Cmark na GitHub
- Przecena na Wikipedii
- Przewodnik po przecenach