选择合适的 Markdown 解析器

Avatar of Ray Villalobos
Ray Villalobos 发表

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

以下是 Ray Villalobos 的客座文章。 Ray 将探讨 Markdown 的许多不同变种。 它们都提供了超出原始 Markdown 功能的功能,但它们之间提供了不同的功能。 如果您要选择要使用的版本(或您在 Web 产品上提供给用户的版本),了解您正在使用什么非常重要,因为一旦您选择就很难切换,并且存在依赖于这些功能的内容。 Ray 拥有 关于 Markdown 的课程,他将分享哪些版本具有哪些功能,以帮助您做出明智的选择。

Markdown 改变了许多领域专业人士的写作方式。 该语言使用简单的文本和最少的标记,并且可以将其转换为越来越多的格式。 但是,并非所有 Markdown 解析器都是平等创建的。 由于原始规范没有随着时代发展,因此 Multi-Markdown、GFM(Github Flavored Markdown)、Markdown Extra 等替代版本扩展了该语言。

最初的 解析器是用 Perl 编写的。 核心功能包括解析块元素(例如段落、换行符、标题、块引用、列表、代码块和水平线)和跨度元素(链接、强调、代码片段和图像)。 从那时起,该语言就没有被其创建者 John Gruber 扩展,因此随着不同的解析器根据需要添加对不同实现的支持或解释某些元素的解析方式,出现了许多添加和实现。

选择版本

在考虑将 Markdown 实现到项目中时,需要考虑很多因素,包括您将使用的开发语言以及您想要支持的功能。 最初的实现是用 Perl 编写的,但这并非每个项目的实用选择。 大多数流行的语言都有实现,包括:PHP、Ruby 和 JavaScript。 您选择的语言将对您可以支持的功能以及可用的库产生影响。 让我们看看一些选项

语言 库(下载项目)
Perl 原始版本
JavaScript CommonMarkMarkedMarkdown-itRemarkableShowdown
Ruby Github Flavored MarkupKramdownMarukuRedcarpet
PHP Cebe MarkdownCiconiaParsedownPHP Markdown Extended
Python Python Markdown

如果您想在其他语言中实现 Markdown,还有其他语言的 许多其他实现

核心功能

核心 Markdown 语言支持许多非常有用的默认功能。 尽管不同的实现支持一系列扩展功能,但它们都应该至少支持以下核心语法:内联 HTML自动段落标题块引用列表代码块水平线链接强调内联代码图像

值得注意的扩展

随着许多 Markdown 版本的可用,其中一些对其他版本产生了重大影响。 以至于您经常会看到它们被引用为其他版本的一部分。 例如,库会提到支持 CommonMark、GFM 或 Multi-Markdown。 让我们看看这些意味着什么。

GFM

Markdown 如此受欢迎的原因之一是,开源共享平台 Github 接受并扩展了该语言,并使用名为 Github Flavored Markup (GFM) 的版本来包含 围栏代码块URL 自动链接删除线表格,甚至能够 在存储库中创建待办事项。 因此,当某个版本提到支持 GFM 时,请查找已实现的这些扩展。

支持围栏代码块语法高亮表格URL 自动链接待办事项删除线

CommonMark

最近,人们一直在努力标准化 Markdown。 一组 Markdown 开发人员联合起来为该语言创建了一个版本、测试和文档,从而产生了更强大的语言规范,称为 CommonMark。 此时,该实现添加了 围栏代码块,但主要详细说明了如何实现某些功能以获得一致的输出和转换。 还有更多扩展可以使它更符合其他语言中的可用功能,已提出用于未来。

此格式相对较新,不支持很多功能,但它正在积极开发中,并且计划添加许多 Multi-Markdown 功能。

支持围栏代码块URL 自动链接

Multi-markdown

扩展该语言的第一个严肃项目是 Multi-Markdown。 它为该语言添加了许多其他版本支持的功能。 它最初是用 Perl 编写的,就像 Markdown 一样,然后迁移到 C。 因此,如果您看到某个项目支持 Multi-Markdown,那么它可能具有 这些功能中的大多数

支持围栏代码块语法高亮表格元数据片段/交叉引用链接脚注删除线定义列表数学

可选功能

让我们看看通过不同的实现可用的功能。

围栏代码块

对于开发者来说,最好的功能之一就是能够轻松地在 Markdown 中添加代码。最初的实现会自动将缩进 4 个空格或一个制表符的文本块视为代码。这有时不太方便,因此一些实现通过允许您在文本块的开头放置三个反引号(`)或某些情况下三个波浪号(~)字符来标记为代码,从而引入了围栏代码块。

```
body {
  margin: 0;
  padding: 0;
  color: #222;
  background-color: white;
  font-family: sans-serif;
  font-size: 1.8rem;
  line-height: 160%;
  font-weight: 400;
}
```

可用版本:
Cebe MarkdownCiconiaGithub Flavored MarkdownKramdownMarkdown-itMarkedMarukuMulti-MarkdownParsedownPHP Markdown ExtendedPython MarkdownRedcarpetRemarkableShowdown

语法高亮

添加代码块很棒,但是默认情况下,Markdown 解释器只会将代码块包装在<code><pre> 标签内,这使得文本以等宽字体显示为预格式化的文本。一些实现可以通过允许您在反引号旁边指定语言来改进这一点,并且可能包含一个解析器,该解析器允许您自动选择不同的颜色样式并指定代码的编写语言,以便颜色更有意义。

```css
body {
  margin: 0;
  padding: 0;
  color: #222;
  background-color: white;
  font-family: sans-serif;
  font-size: 1.8rem;
  line-height: 160%;
  font-weight: 400;
}
```

可用版本:
CiconiaGithub Flavored MarkdownKramdown*、MarkedMarukuMulti-MarkdownParsedownPHP Markdown ExtendedPython MarkdownRedcarpetRemarkableShowdown

* 一些支持并非嵌入到解析器中,而是依赖于其他库,例如 highlight.js

表格

在 HTML 中编写表格可能很麻烦。一些 Markdown 版本可以通过让您使用相当简单的语法添加表格来解决此问题。

Dimensions | Megapixels
---|---
1,920 x 1,080 | 2.1MP
3,264 x 2,448 | 8MP
4,288 x 3,216 | 14MP

渲染效果如下:

尺寸 百万像素
1,920 x 1,080 2.1MP
3,264 x 2,448 8MP
4,288 x 3,216 14MP

构建这样的表格需要几分钟才能掌握,但是您操作几次之后,就会觉得使用 HTML 有点麻烦。如果您需要帮助创建表格,请查看此 Markdown 表格生成器

Markdown Tables Generator

可用版本:
Cebe MarkdownCiconiaGithub Flavored MarkdownKramdownMarkdown-itMarkedMarukuMulti-MarkdownParsedownPHP Markdown ExtendedPython MarkdownRedcarpetRemarkableShowdown

元数据

一些扩展允许您添加元数据,您可以使用这些元数据添加应用程序可以解析的信息,例如选择模板或设置页面标题。一些扩展使用 Multi-Markdown 结构 来表示这些元数据,而另一些扩展(如 Jekyll 解析器)则使用 YAML 作为格式,这使您可以在此元数据部分表达复杂数据。这对于应用程序开发人员来说可能是一个非常有用的功能。

---
Title:  SVG Article
Author: Ray Villalobos
Date:   January 6, 2016
heroimage: "http://i.imgur.com/rBX9z0k.png"
tags:
- data visualization
- bitmap
- raster graphics
- navigation
---

可用版本:
Markdown-itMarukuMulti-MarkdownPHP Markdown ExtendedPython MarkdownRedcarpetRemarkableShowdown

URL 自动链接

这个相当简单的扩展允许文本中自然出现的 URL 通过解析器转换为链接。这在 GFM 等实现中非常方便和有用,在这些实现中,无需额外工作即可使 URL 可点击,从而更容易编写文档。

可用版本:
Cebe MarkdownCiconiaCommonMarkGithub Flavored MarkdownKramdownMarkdown-itMarkedMarukuMulti-MarkdownParsedownPHP Markdown ExtendedPython MarkdownRedcarpetRemarkableShowdown

片段/交叉引用链接

使用 HTML,您可以通过在锚标记中使用页面上元素 ID 的井号轻松创建文档内部的引用。一些实现允许您为此类引用创建快捷方式。这特别有用,因为它允许您快速交叉引用自己的文档,而无需编写大量 HTML。此功能的实现方式多种多样,因此您确实需要仔细阅读您将使用的特定版本的文档。

You can link to a headline called 'myheadline' in your document using this [My Headline][].

## My Headline
The word 'reference' right next to this will get a link that links via an href to the headline above. The headline, in other words, gets an ID that the link points to.

可用版本:
CiconiaMulti-MarkdownMarukuMulti-MarkdownParsedownPHP Markdown ExtendedRedcarpetShowdown

标题的自定义 ID

另一个有用的功能是在标题中添加 ID,以便您可以更轻松地通过 CSS 针对它们。一些解析器会自动为所有标题添加 ID(特别是如果它们支持 片段/交叉引用),因此此功能并不总是必需的。但是,一些版本允许您自定义解析器如何命名 ID 这一点很好,这有时比自动命名更方便。

### Custom IDs {#custom-id}
The headline above, when rendered by the parser, will have a custom ID that you specify in the curly braces.

可用版本:
Cebe MarkdownKramdown

脚注和其他链接类型

脚注允许您在文档中创建指向放置在 Markdown 页面底部的引用的链接。这与普通链接不同,普通链接是内联放置在内容中的。这允许用户在一个部分中查看文档中所有相关的链接,这在某些情况下很好。

You can find a demo of a site[^Demo] built with PostCSS in our footnotes, or you can checkout the [^Github Repo] for the project.

#### Footnotes
[Demo](http://iviewsource.com/exercises/postcsslayouts)
[Github Repo](https://github.com/planetoftheweb/postcsslayouts)

可用版本:
Cebe MarkdownKramdownMarkdown-itMarukuMulti-MarkdownParsedownPHP Markdown ExtendedPython MarkdownRedcarpetRemarkableShowdown

**注意**:解析器(如 Multi-Markdown)中有很多替代链接方法。对这些方法的支持在各个版本中非常零散。这意味着,即使解析器宣传“多 Markdown”兼容性,不同的解析器也会实现不同类型的链接引用。这包括诸如 引用、标题中的自动生成 ID、创建自定义 ID 的能力、交叉引用链接等。一些解析器甚至会发明自己的链接功能。

待办事项

这是一项在某些实现中流行起来的 GitHub Flavored Markdown 功能。它增加了待办事项列表标记,以便您可以创建内容旁边的复选框来模拟待办事项列表。

- [ ] Run `> npm-install` to install the project dependencies
- [X] Install gulp.js via the Mac terminal or Gitbash on a PC `> npm install -g gulp`
- [ ] Run the Gulp command `> gulp`

可用版本:
CiconiaGitHub Flavored MarkdownMarkdown-itMarkedPython MarkdownRedcarpetShowdown

删除线

如果您想用删除线标记文本,您可以在许多版本中使用一种符号,该符号使用&lt;s&gt;标签将文本括起来。但是,为了更全面地实现编辑器注释,您可能需要查看称为CriticMarkup的相关格式。

可用版本:
CiconiaMarkdown-itMarkedMulti-MarkdownParsedownRemarkableRedcarpetShowdown

定义列表

虽然定义列表不像其他类型的列表那么常见,但它是用 HTML 编码某些类型元素的好方法,一些实现添加了一种更简单的方法来创建这些元素。有两种定义它们的方法,具体取决于语言,使用冒号 (`:`) 或波浪号 (`~`),尽管使用冒号的实现更常见。

ES6/ES2015
:   The new version of the popular JavaScript language

TypeScript
  ~ TypeScript is a language that is a superset of JavaScript that can be compiled through a transpiler to JavaScript that will work with most browsers.

可用版本:
KramdownMarkdown-it*、MarukuMulti-MarkdownPHP Markdown ExtendedPython MarkdownRemarkable

* 需要扩展

数学公式

能够创建数学公式对某些用户来说可能很有用,因此,一些实现(如 Multi-Markdown)中出现了一种创建数学公式的语言。尽管某些语言声称支持,但在其他语言中也可用,有时可以通过扩展实现。

可用版本:
Kramdown*、MarukuMulti-MarkdownMarkdown-itPython Markdown*

* 需要扩展

哦,甜蜜的 I/O

您必须注意的一件事是不同版本如何处理输入和输出。仅仅因为某个版本说它支持表格,并不意味着存在创建表格代码的标准方法。某些版本将生成冗长的 HTML,而某些版本将呈现简约的代码。

处理空格的方式也存在差异。某些版本将在每个标题内放置 ID,而某些版本则不会。这是 OpenMark 平台试图解决的问题之一,即如何生成一致的输出。找出您选择的版本如何处理此问题的最佳方法是使用Babelmark 2 测试。粘贴一些代码,它将向您展示不同的解析器如何处理输出以及在浏览器中显示的预览。