Markdown 语法篇

概览

宗旨

Markdown 旨在成为一门 「易读易写」 的语言。

可读性高于一切。一个 Markdown 格式的文档应该能够像纯文本一样发布,而不是看起来有一大堆的标签或者指示符。 虽然 Markdown 的语法受到了一些既有的文本转 HTML 机制的影响 —— 其中就包括 SetextatxTextilereStructuredText
GrutatextEtText —— 但其最大的灵感是来自于纯文本的电子邮件格式。

概括来说,Markdown 的语法是由一些精挑细选的符号所组成的,这些符号的作用一目了然。 比如在一个词的前后加上星号,看起来就是在表达 *强调*。 而 Markdown 的列表看起来,嗯,就像是列表。甚至 Markdown 的引用看起来就是在表达引用了一段文字,就像电子邮件中的一样。

兼容 HTML

Markdown 语法的目标:成为一种是用语网络的书写格式。

Markdown 的出现并不是想代替 HTML,甚至不想与 HTML 类似。所以 Markdown 的语法只对应了 HTML 中的很少一部分标签。Markdown 语法并不是为了方便生成 HTML 标签而发明的。在我看来,HTML 标签 本来就很容易书写。Markdown 的诞生是为了让阅读、编辑和写作简单化。HTML 是一种 排版 格式,而 Markdown 是一种 书写 格式。

对于那些不能用 Markdown 语法生成的 HTML 标签,你可以直接使用 HTML。你也不需要额外标注是 Markdown 还是 HTML,直接使用 HTML 标签即可。

唯一受限制的只有 HTML 中的块级元素 —— 比如 <div>
<table><pre><p> 等标签 —— 必须用空行将之与其他内容隔开,而且标签的首尾不能有任何缩进。Markdown 足够智能,不会为 HTML 的块级标签添加额外的 (不必要的) <p> 标签。

比如,为 Markdown 文章添加 HTML 的表格:

这是一个常规段落。

<table>
    <tr>
        <td>Foo</td>
    </tr>
</table>

这是另一个常规段落。

需要注意的是在块级 HTML 标签内的 Markdown 语句将不会被处理。比如,你不能在块级 HTML 标签内使用 Markdown 的 *强调*

行内元素 —— 比如 <span><cite> 或者 <del> —— 能够在 Markdown 段落、列表、标题的任何位置使用。如果你想,还可以直接使用 HTML 的标签替换 Markdown 的。比如,你想要使用 HTML 的 <a><img> 标签取代 Markdown 的,放心用就是。

与 HTML 的块级标签不同,行内的 HTML 标签内的 Markdown 语句是可被处理的。

自动转义特殊字符

在 HTML 中, 有两个字符需要特别的处理: <
&< 被用来表示标签的开始。 & 被用来标记 HTML 中的实体。如果你想使用这些字符,你必须使用实体形式。比如,&lt;
&amp;

& 符号对网络编写者来说简直是噩梦。如果你想要写 ‘AT&T’,你就必须写成 ‘AT&amp;T‘。甚至 URL 中的 & 符号都需要你手动转义。因此,如果你想链接到:

http://images.google.com/images?num=30&q=larry+bird

你就必须将它转换成:

http://images.google.com/images?num=30&amp;q=larry+bird

之后放入 href 属性中。不用说也知道很容易忽略这一细节。

Markdown 可以让你很自然的使用这些符号,转义的过程会自动完成。只有将 & 用在 HTML 实体中会保持原样,否则会被转换成 &amp;

因此,如果你想在你的文章里引入一个版权符号,可以这样写:

&copy;

Markdown 会使 & 符号保持原样,但如果这样写:

AT&T

Markdown 会将其转换成:

AT&amp;T

与之类似,由于 Markdown 支持 内联 HTML,如果你使用尖括号作为 HTML 标签的界定符,Markdown 会原样输出,但是如果你这样写:

4 < 5

Markdown 会将其转换成:

4 &lt; 5

然而,在 Markdown 的行内代码和代码块中,尖括号总是会自动的被转换。这一特性使得用 Markdown 来书写 HTML 更加的容易。 (与原始的 HTML 相反,如果你想用 HTML 来写 HTML 有关的语法就如同噩梦,因为在你的示例代码中的每一个 <
& 符号都需要被转义。)

块级元素

段落与换行

一个段落是简单的一行或多行的连续文字,段落之间用一个或多个空行分隔。 (任何看起来像空行的都是空行 —— 只包含空格或者制表符的行也被视为空行。) 正常的段落不因用空格或者制表符缩进。

一行或多行的连续文字是指 Markdown 支持 “hard-wrapped” 的文字段落。这与其他的文字转 HTML 格式将段落中的每一个换行符都转换成一个 <br /> 标签的特性显著不同(including Movable
Type’s “Convert Line Breaks” option) 。

当你想在 Markdown 文档中插入一个 <br /> 标签时,你需要用两个或者多个空格来结束一行并按回车键。

是的, 虽然为了创建一个 <br /> 需要多做一点工作,但简单的将每一个换行符都转换为 <br /> 的规则在 Markdown 中不起作用。
当你使用硬换行来格式化 Markdown 的 email 风格的 引用 和 多行 列表元素 时最好用,也更好看。

标题

Markdown 提供了两种风格的标题: Setextatx
Setext 风格的标题的分别使用等号 (=) 和短线 (-) 用作 “下划线” 来产生 <h1><h2>。比如:

这是一级标题
==========

这是二级标题
----------

可以使用任意数量的 = 或者 - 作下划线

Atx 风格的标题在行首使用 1-6 个 # 来产生 1-6 级标题。 比如:

# 这是一级标题

## 这是二级标题

###### 这是三级标题

你也可以选择 “封闭” atx 风格的标题。纯粹起装饰作用 —— 如果你认为这样看起来更好的话。封闭的 # 甚至不要求前后数量相等。(标题级别由前面的 # 数量决定)。

# 这是一级标题 #

## 这是二级标题 ##

### 这是三级标题 ######

引用

Markdown 采用 email 风格的 > 符号来表示引用。如果你熟悉在电子邮件中引用文字的话,那你就知道该如何在 Markdown 中使用引用。对要引用的文字使用手动换行并在每一行之前添加 > 符号看起来效果最棒。

> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
>
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
> id sem consectetuer libero luctus adipiscing.

Markdown 允许你只在的段落的第一行添加 > 符号:

> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.

引用可以嵌套 (也就是引用中的引用) 通过添加额外级数的 > 符号:

> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.

引用也可以包含其他的 Markdown 元素,包括标题,列表和代码块:

> ## This is a header.
>
> 1.   This is the first list item.
> 2.   This is the second list item.
>
> Here's some example code:
>
>     return shell_exec("echo $input | $markdown_script");

任何正规编辑器都可以轻松地实现 email 风格的引用。以 BBEdit 软件为例,你可以选取一段文字并在 Text 菜单里选择 Increase
Quote Level。

列表

Markdown 支持有序和无序两种列表。

无序列表使用星号,加号和连字符 —— 可互换 —— 作为标记:

*   Red
*   Green
*   Blue

等价于:

+   Red
+   Green
+   Blue

也等价于:

-   Red
-   Green
-   Blue

有序列表使用数字加上点号:

1.  Bird
2.  McHale
3.  Parish

需要注意的是你用来标记列表元素的数字对 HTML 的输出是没有影响的。上例中的列表对应的 HTML 输出如下:

<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>

如果你将一个列表写成这样:

1.  Bird
1.  McHale
1.  Parish

甚至这样:

3. Bird
1. McHale
8. Parish

你将获得相同的 HTML 输出。关键是,如果你想,你可以在你的 Markdown 列表中使用有序数字,这样你的源代码中的数字就和输出的 HTML 中的匹配了。但是如果你想偷懒,也可以不这么做。

如果你确实偷懒了,然而,你还是应该使用数字 1 作为列表的首元素。在以后 Markdown 也许会支持字母顺序的有序列表。

列表标记默认是在左侧,但也可以用三个或以上的空格来缩进。列表标记必须紧跟 1 个或多个空格或者制表符。

为了让列表更好看,你可以将列表元素固定缩进。

*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    viverra nec, fringilla in, laoreet vitae, risus.
*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    Suspendisse id sem consectetuer libero luctus adipiscing.

但如果你想偷懒,也可以不这么做:

*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.

如果用空行将列表元素分隔开,Markdown 对应的 HTML 输出中会用 <p> 标签将列表元素包裹起来。比如说,这个输入:

*   Bird
*   Magic

会被转换成:

<ul>
<li>Bird</li>
<li>Magic</li>
</ul>

但这个:

*   Bird

*   Magic

会被转换成:

<ul>
<li><p>Bird</p></li>
<li><p>Magic</p></li>
</ul>

列表元素可以由多段落组成。每一个自段落必须用 4 个空格或者 1 个制表符缩进:

1.  This is a list item with two paragraphs. Lorem ipsum dolor
    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
    mi posuere lectus.

    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
    sit amet velit.

2.  Suspendisse id sem consectetuer libero luctus adipiscing.

如果你将子段落中的每一行都缩进看起来会更棒,但再一次,Markdown 允许你偷懒:

*   This is a list item with two paragraphs.

    This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.

*   Another item in the same list.

To put a blockquote within a list item, the blockquote’s >
delimiters need to be indented:

*   A list item with a blockquote:

    > This is a blockquote
    > inside a list item.

要在列表元素中放置代码块,需要将代码块缩进 2 次 —— 8 个空格或者 2 个制表符。

*   A list item with a code block:

        <code goes here>

你有可能会意外触发一个有序列表,像这样:

1986. What a great season.

换句话说,就是在行首的 数字-点号-空格 序列。为了避免这种情况,你可以转义点号:

1986\. What a great season.

代码块

预定义的代码块被用来写程序代码或者标记语言。与普通段落不一样,Markdown 会将代码块同时包裹在 <pre><code> 标签中。

要在 Markdown 中生成一个代码块,只需要将代码块的每一行都用至少 4 个空格 或者 1 个制表符来缩进,比如这样的输入:

This is a normal paragraph:

    This is a code block.

Markdown 会生成:

<p>This is a normal paragraph:</p>

<pre><code>This is a code block.
</code></pre>

One level of indentation —— 4 spaces or 1 tab —— is removed from each
line of the code block. For example, this:
一级缩进 —— 4 个空格或者 1 个制表符 —— 在代码块中会被移除。如下例:

Here is an example of AppleScript:

    tell application "Foo"
        beep
    end tell

会转换为:

<p>Here is an example of AppleScript:</p>

<pre><code>tell application "Foo"
    beep
end tell
</code></pre>

直到遇到没有缩进的行 (或者文章末尾),才会结束代码块的范围。

在代码块中,& 符号和尖括号 (<>) 会被自动的转换成 HTML 实体形式。这使得在 Markdown 中引入 HTML 实例代码变得非常简单 —— 直接粘贴并缩进即可,Markdown 会自动完成转义工作。比如:

<div class="footer">
    &copy; 2004 Foo Corporation
</div>

会转换成:

<pre><code>&lt;div class="footer"&gt;
    &amp;copy; 2004 Foo Corporation
&lt;/div&gt;
</code></pre>

正规的 Markdown 语法在代码块中不会被处理。比如代码块中的星号仅仅只是星号。也就是说,用 Markdown 来写 Markdown 本身的语法也很容易。

分割线

你可以用 3 个或更多连字符,星号或者下划线来生成一条水平分割线 (<hr />)。如果你想,你可以在星号或者短线之间添加空格。下面的每一种都可以生成一条分割线:

* * *

***

*****

- - -

---------------------------------------

行内元素

超链接

Markdown 支持两种风格的超链接: 内联式引用式

两种风格的都使用 [方括号] 将链接文字括起来。

要创建行内超链接,在超链接的方括号之后紧跟一对圆括号即可。在圆括号中,放入你想链接到的 URL,还可以加一个 可选的 标题。实例:

This is [an example](http://example.com/ "Title") inline link.

[This link](http://example.net/) has no title attribute.

会生成:

<p>This is <a href="http://example.com/" title="Title">
an example</a> inline link.</p>

<p><a href="http://example.net/">This link</a> has no
title attribute.</p>

如果你想链接到在相同服务器上的本地资源,你可以使用相对路径:

See my [About](/about/) page for details.

引用风格的超链接使用了另一对方括号,在其中放入链接的 ID。

This is [an example][id] reference-style link.

你可以在两对方括号之间插入一个空格:

This is [an example] [id] reference-style link.

然后,无论在文档的任意行都可以像这样定义你的链接:

[id]: http://example.com/  "Optional Title Here"

也就是:

  • 方括号中包含链接的 ID (可以选择性的使用 3 个及以上的空格来缩进);
  • 紧跟一个冒号;
  • 再跟上一个或多个空格 (或者制表符);
  • 再跟上链接的 URL;
  • 选择性的跟上 title 属性,包裹在单引号或者双引号或者圆括号中;

以下三个链接是等效的:

[foo]: http://example.com/  "Optional Title Here"
[foo]: http://example.com/  'Optional Title Here'
[foo]: http://example.com/  (Optional Title Here)

注意: 在 Markdown.pl 1.0.1 版本种存在一个已知的 bug —— 不允许是用单括号来包含链接。

可以选择性的用尖括号将链接扩起来:

[id]: <http://example.com/>  "Optional Title Here"

你可以将 title 属性放在下一行并且使用额外的空格或者制表符来缩进,可以使比较长的 URL 看起来更棒:

[id]: http://example.com/longish/path/to/resource/here
    "Optional Title Here"

Link definitions are only used for creating links during Markdown
processing, and are stripped from your document in the HTML output.
超链接的定义只能在 Markdown 处理的时候才会创建超链接 >>> unfinished

超链接的 ID 可以由字母、数字、空格和标点符号 —— 但是 区分大小写。比如以下两个连接:

[link text][a]
[link text][A]

是等效的。

隐式的链接 ID 允许你省略链接的名字,而将链接文字本身作为 ID。
只需使用一对空的方括号 —— 比如,要使用 “Google” 来链接到 google.com,你可以简单地这样写:

[Google][]

然后定义该链接:

[Google]: http://google.com/

由于链接中可能会包含空格,所以这种简洁形式允许链接文字包含多个单词:

Visit [Daring Fireball][] for more information.

然后定义该链接:

[Daring Fireball]: http://daringfireball.net/

链接定义可以放置在你的 Markdown 文档的任何位置。我打算将它们放在使用它们的段落之后,但如果你想,你可以将所有的链接定义放在文档的最后,就像脚注一样。

下面是一个引用风格的实例:

I get 10 times more traffic from [Google] [1] than from
[Yahoo] [2] or [MSN] [3].

  [1]: http://google.com/        "Google"
  [2]: http://search.yahoo.com/  "Yahoo Search"
  [3]: http://search.msn.com/    "MSN Search"

使用隐式链接名的简洁形式,你可以这样写:

I get 10 times more traffic from [Google][] than from
[Yahoo][] or [MSN][].

  [google]: http://google.com/        "Google"
  [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
  [msn]:    http://search.msn.com/    "MSN Search"

上面的例子都会生成以下的 HTML 输出:

<p>I get 10 times more traffic from <a href="http://google.com/"
title="Google">Google</a> than from
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>

作为对比,这里给出了用内联风格写的相同的段落:

I get 10 times more traffic from [Google](http://google.com/ "Google")
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
[MSN](http://search.msn.com/ "MSN Search").

引用风格超链接的关键不在于方便书写,而是使你的文档可读性更强。比较上面的例子你会发现:使用引用风格的超链接,段落本身只有 81 个字符;而使用内联式的超链接,段落长度达到了 176 个字符;而使用原始的 HTML,长度是 234 个字符。在原始的 HTML 中有更多的标签。

使用 Markdown 的引用风格链接,使得源文档更接近于在浏览器中的最终输出。这一特性使得在你得文章里添加超链接而不会看起来很乱。

强调

Markdown 将星号 (*) 和下划线 (_) 作为强调的标记符号。被包裹在一个 * 或者 _ 中的文字会生成一个 <em> 标签;包裹在两个 * 或者 _ 中的文字会则生成一个 <strong> 的 HTML 标签。比如,这个输入:

*single asterisks*

_single underscores_

**double asterisks**

__double underscores__

会生成:

<em>single asterisks</em>

<em>single underscores</em>

<strong>double asterisks</strong>

<strong>double underscores</strong>

你可以使用你喜欢的任何一种风格,但是同一中符号必须封闭。

强调可以使用在单词中间:

un*frigging*believable

但是如果你在 * 或者 _ 周围添加空格,就会将它们视为文本的星号或者空格。

要在会生成强调的文字中使用文本的星号或者下划线,你可以使用反斜杠来转义它:

\*this text is surrounded by literal asterisks\*

行内代码

要指明一段行内代码,可以将代码用反引号 (` ) 包裹起来。与代码块的不同的是,行内代码可以放置在正常的段落中。比如:

Use the `printf()` function.

会生成:

<p>Use the <code>printf()</code> function.</p>

想要在行内代码中使用文本的反引号,你可以使用双反引号来作为代码标记:

``There is a literal backtick (`) here.``

这会生成这个:

<p><code>There is a literal backtick (`) here.</code></p>

包裹代码反引号中可以有空格 —— 一个开放标记之后,一个在闭合标记之前。这就允许你将文本的反引号放置在行内代码的开头或末尾:

A single backtick in a code span: `` ` ``

A backtick-delimited string in a code span: `` `foo` ``

会生成:

<p>A single backtick in a code span: <code>`</code></p>

<p>A backtick-delimited string in a code span: <code>`foo`</code></p>

在行内代码中,& 符号和尖括号 (<>) 会自动的转换为 HTML 的实体形式,这使得引入 HTML 的示例代码很容易。Markdown 会将这个:

Please don't use any `<blink>` tags.

转换成:

<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>

你也可以这样写:

`&#8212;` is the decimal-encoded equivalent of `&mdash;`.

来生成:

<p><code>&amp;#8212;</code> is the decimal-encoded
equivalent of <code>&amp;mdash;</code>.</p>

图片

固然,设计一门 「自然语言」 来在纯文本格式文档中放置图片是相当困难的。

Markdown uses an image syntax that is intended to resemble the syntax
for links, allowing for two styles: inline and reference.
Markdown 的图片语法和超链接非常相似,也允许两种风格: 内联式引用式

内联式的图片语法看起来像这样:

![Alt text](/path/to/img.jpg)

![Alt text](/path/to/img.jpg "Optional title")

也就是:

  • 一个感叹号: !
  • 紧跟一对方括号,里面包含图片的 alt 属性;
  • followed by a set of parentheses, containing the URL or path to
    the image, and an optional title attribute enclosed in double
    or single quotes.
  • 在跟上一对花括号,里面放置图片的 URL 或者路径,以及一个单引号或者双引号扩起来的可选的 title 属性。

引用风格的图片语法看起来像这样:

![Alt text][id]

Where “id” is the name of a defined image reference. Image references
are defined using syntax identical to link references:
这里的 “id” 是图片引用的名字。 >>>unfinished

[id]: url/to/image  "Optional title attribute"

这种写法中,Markdown 不会指定图片的大小,如果这对你很重要,请的使用正规的 HTML 的 <img> 标签。


杂七杂八

自动链接

Markdown 支持一种为 URL 和 email 地址创建自动链接的简洁形式: 只需要在 URL 或者 email 地址用尖括号包裹起来。这就意味着如果你想显示 URL 或者 email 的实际地址,又想使之成为可点击的链接,你可以这样做:

<http://example.com/>

Markdown 会将它转换成:

<a href="http://example.com/">http://example.com/</a>

email 的自动链接与之类似,除了 Markdown 会将你的 email 地址使用十进制和十六进制的实体编码来帮助你的邮箱免受邮箱搜集工具的的骚扰。比如,Markdown 会将这个:

<address@example.com>

转换成像这样的东西:

<a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>

在浏览器中会被渲染成一个可点击的链接 “address@example.com”。

(这一串实体编码的小把戏确实可以绕得过许多邮件搜集机器人,但并不是完全有效。但总比不采取措施要好,采用这种方式最后可能还是不能避免垃圾邮件的骚扰。)

反斜杠转义

Markdown 允许你使用反斜杠来转义某些在 Markdown 的语法中具有特殊含义的符号,来生成纯文本。比如,若果你想使用纯文本的星号来将文本包裹起来 (不生成 HTML 的 <em> 标签),你可以在星号前加上反斜杠,像这样:

\*literal asterisks\*

Markdown 为以下的字符提供了转义:

\   反斜杠
`   反引号
*   星号
_   下划线
{}  花括号
[]  方括号
()  圆括号
#   井号
+   加号
-   减号 (连字符)
.   点号
!   感叹号
很惭愧<br><br>只做了一点微小的工作<br>谢谢大家