以下是 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 | CommonMark、Marked、Markdown-it、Remarkable、Showdown |
Ruby | Github Flavored Markup、Kramdown、Maruku、Redcarpet |
PHP | Cebe Markdown、Ciconia、Parsedown、PHP Markdown Extended |
Python | Python Markdown |
如果您想在其他语言中实现 Markdown,还有其他语言的 许多其他实现。
核心功能
核心 Markdown 语言支持许多非常有用的默认功能。 尽管不同的实现支持一系列扩展功能,但它们都应该至少支持以下核心语法:内联 HTML、自动段落、标题、块引用、列表、代码块、水平线、链接、强调、内联代码和图像。
值得注意的扩展
随着许多 Markdown 版本的可用,其中一些对其他版本产生了重大影响。 以至于您经常会看到它们被引用为其他版本的一部分。 例如,库会提到支持 CommonMark、GFM 或 Multi-Markdown。 让我们看看这些意味着什么。
GFM
Markdown 如此受欢迎的原因之一是,开源共享平台 Github 接受并扩展了该语言,并使用名为 Github Flavored Markup (GFM) 的版本来包含 围栏代码块、URL 自动链接、删除线、表格,甚至能够 在存储库中创建待办事项。 因此,当某个版本提到支持 GFM 时,请查找已实现的这些扩展。
CommonMark
最近,人们一直在努力标准化 Markdown。 一组 Markdown 开发人员联合起来为该语言创建了一个版本、测试和文档,从而产生了更强大的语言规范,称为 CommonMark。 此时,该实现添加了 围栏代码块,但主要详细说明了如何实现某些功能以获得一致的输出和转换。 还有更多扩展可以使它更符合其他语言中的可用功能,已提出用于未来。
此格式相对较新,不支持很多功能,但它正在积极开发中,并且计划添加许多 Multi-Markdown 功能。
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 Markdown、Ciconia、Github Flavored Markdown、Kramdown、Markdown-it、Marked、Maruku、Multi-Markdown、Parsedown、PHP Markdown Extended、Python Markdown、Redcarpet、Remarkable、Showdown
语法高亮
添加代码块很棒,但是默认情况下,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;
}
```
可用版本:
Ciconia、Github Flavored Markdown、Kramdown*、Marked、Maruku、Multi-Markdown、Parsedown、PHP Markdown Extended、Python Markdown、Redcarpet、Remarkable、Showdown
* 一些支持并非嵌入到解析器中,而是依赖于其他库,例如 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 表格生成器。
可用版本:
Cebe Markdown、Ciconia、Github Flavored Markdown、Kramdown、Markdown-it、Marked、Maruku、Multi-Markdown、Parsedown、PHP Markdown Extended、Python Markdown、Redcarpet、Remarkable、Showdown
元数据
一些扩展允许您添加元数据,您可以使用这些元数据添加应用程序可以解析的信息,例如选择模板或设置页面标题。一些扩展使用 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-it、Maruku、Multi-Markdown、PHP Markdown Extended、Python Markdown、Redcarpet、Remarkable、Showdown
URL 自动链接
这个相当简单的扩展允许文本中自然出现的 URL 通过解析器转换为链接。这在 GFM 等实现中非常方便和有用,在这些实现中,无需额外工作即可使 URL 可点击,从而更容易编写文档。
可用版本:
Cebe Markdown、Ciconia、CommonMark、Github Flavored Markdown、Kramdown、Markdown-it、Marked、Maruku、Multi-Markdown、Parsedown、PHP Markdown Extended、Python Markdown、Redcarpet、Remarkable、Showdown
片段/交叉引用链接
使用 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.
可用版本:
Ciconia、Multi-Markdown、Maruku、Multi-Markdown、Parsedown、PHP Markdown Extended、Redcarpet、Showdown
标题的自定义 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 Markdown、Kramdown
脚注和其他链接类型
脚注允许您在文档中创建指向放置在 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 Markdown、Kramdown、Markdown-it、Maruku、Multi-Markdown、Parsedown、PHP Markdown Extended、Python Markdown、Redcarpet、Remarkable、Showdown
**注意**:解析器(如 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`
可用版本:
Ciconia、GitHub Flavored Markdown、Markdown-it、Marked、Python Markdown、Redcarpet、Showdown
删除线
如果您想用删除线标记文本,您可以在许多版本中使用一种符号,该符号使用<s>
标签将文本括起来。但是,为了更全面地实现编辑器注释,您可能需要查看称为CriticMarkup的相关格式。
可用版本:
Ciconia、Markdown-it、Marked、Multi-Markdown、Parsedown、Remarkable、Redcarpet、Showdown
定义列表
虽然定义列表不像其他类型的列表那么常见,但它是用 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.
可用版本:
Kramdown、Markdown-it*、Maruku、Multi-Markdown、PHP Markdown Extended、Python Markdown、Remarkable
* 需要扩展
数学公式
能够创建数学公式对某些用户来说可能很有用,因此,一些实现(如 Multi-Markdown)中出现了一种创建数学公式的语言。尽管某些语言声称支持,但在其他语言中也可用,有时可以通过扩展实现。
可用版本:
Kramdown*、Maruku、Multi-Markdown、Markdown-it、Python Markdown*
* 需要扩展
哦,甜蜜的 I/O
您必须注意的一件事是不同版本如何处理输入和输出。仅仅因为某个版本说它支持表格,并不意味着存在创建表格代码的标准方法。某些版本将生成冗长的 HTML,而某些版本将呈现简约的代码。
处理空格的方式也存在差异。某些版本将在每个标题内放置 ID,而某些版本则不会。这是 OpenMark 平台试图解决的问题之一,即如何生成一致的输出。找出您选择的版本如何处理此问题的最佳方法是使用Babelmark 2 测试。粘贴一些代码,它将向您展示不同的解析器如何处理输出以及在浏览器中显示的预览。

我发现还有其他一些非常重要的功能需要考虑。
一个是**图像**
另一个是**带 ID 的标题**
图像是在 Markdown 中最麻烦的事情之一——它们总是被包裹在段落标签中,并且几乎不可能控制它们。
我绝对推荐http://parsedown.org/ 用于 PHP。我们在 Kirby 中使用它,它是一个性能和支持都非常出色的解析器。
PHP Markdown Extended 速度慢且过时。PHP 当前的解析器有
https://github.com/cebe/markdown
https://github.com/erusev/parsedown
https://github.com/kzykhys/Ciconia
所有这些在风格方面都是完全可定制的,并且速度很快。
好的观点。我已将这些添加到文章中。谢谢。
我对 Markdown 还比较陌生,除了在论坛等用户端使用外,有没有办法或解析器可以添加特定的标签?我搜索过这个问题,但很难找到合适的关键词来获得答案。我基本上希望能够指示我自己之前定义的小写和大写和其他自定义字符样式,这很繁琐。我只需要能够通过 Markdown 附加自定义标签和/或类。
Markdown 也允许使用 HTML,因此您可能需要在其中放置
<span>
以及您需要的类。我喜欢 Markdown 的一点是,它本质上会阻止这种情况(因为您内容中的自定义 HTML 可能会缩短其生命周期),但如果您负责任地使用它(简单的有意义的类名),您将没问题。Markdown 最大的问题是,有一天您决定扩展它。然后您发现,使用当前解析器是不可能的,并决定编写自己的解析器:)。Markdown 在实现方面不是很方便,大多数项目只允许渲染器(输出)自定义。而在许多情况下,您可能希望更改语法(输入处理规则)。依我拙见,这就是有如此多不同解析器的主要原因。
这就是为什么当我们需要一个好的 JavaScript 解析器时,我们开发了 markdown-it。我的建议是——检查解析器的灵活性,而不是内置功能。
您可能还希望拥有其他哪些“奇怪”功能?我们需要编辑区域和预览的同步滚动(请参阅 markdown-it 演示)。这需要源映射(就像您可能在 JS 中拥有的那些)。据我所知,现有的解析器都没有提供完整的源映射信息,但有些为块级节点(段落、列表)提供了此类数据,这足以实现同步滚动。
remark——最好的 Markdown 解析器之一没有在评论中 =(