文章翻譯自Markdown創始人JOHN GRUBER的 個人部落格, 英文原文請參見 Markdown Syntax;
綜述
宗旨
Markdown致力於讓讀寫文章變得更加容易.
不過良好的可讀性更加應該被關注. 一個Markdown格式的文件應該就像普通文字一樣容易(排版)列印, 而不是用各種標籤和格式指令來標記. 現有的一些文字-HTML過濾器(text-to-HTML filters)對Markdown的語法有著重要的影響, 包括Setext, atx, Textlie, reStructuredText, Grutatext, 和EtText, 不過Markdown語法最大的靈感則來自於純文字郵件的格式.
鑑於此, Markdown的語法完全由標點字元組成, 這些字元經過精心挑選, 就是為了能夠讓它們起到它們看起來應該起的作用. 比如一個單詞兩邊的星號看起來就像emphasis. Markdown(語法的)列表就應該看起來就像是(實際的)列表. 如果你此前使用的email, 那麼即使是Markdown的引用也能夠看起來就像是實際的對一段文字的引用一樣.
內聯HTML
Markdown的語法只有一個目的: 用來作為一種專門為web寫作設計的格式.
Markdown不是為了取代HTML, 也不是為了接近HTML. 它的語法非常少, 僅對應著HTML標籤的一個很小的子集. 創造Markdown的目標不是為了讓插入HTML標籤更容易. 就我個人來說, HTML標籤已經很簡單了. Markdown的理念是為了讓閱讀, 編寫, 編輯簡單文字更加容易. HTML是一個印刷格式, 而Markdown是一個寫作格式. 因此Markdown格式的語法只用於處理能夠轉變為純文字的一些功能.
對於那些不包括在Markdown語法之內的標記, 你可以直接使用HTML標籤, 而不用在從Markdown語法轉換到HTML之前做任何說明或者分隔. 直接使用HTML標籤就行了.
唯一的限制是當你使用HTML塊元素的時候-例如 <div> , <table> , <pre> , <p> 等-必須和上下文用空行分開, 並且開始標記和結束標記不能使用tab或者空格縮排(否則會被當做程式碼段). Markdown能夠智慧地識別出何時不在HTML塊級元素新增額外的(不必要)的<p>
.
例如, 為了向一片Markdown文字新增一個HTML表格:
This is a regular paragraph. <table> <tr> <td>Foo</td> </tr> </table> This is another regular paragraph.
注意到在HTML塊元素標籤裡面Markdown格式的語法不會被解釋, 例如你不能在HTML塊元素裡面使用Markdown風格的強調*emphasis*.
內聯HTML元素-例如<span>
, <cite>
或者<del>
-可以在Markdown段落, 列表項或者頭部中的任何地方. 你甚至可以使用HTML標籤代替Markdown的格式. 例如你可以用HTML的<a>
或者<img>
標籤代替Markdown的超連結或者圖片語法.
與HTML塊元素不同的是, 內聯元素內的Markdown語法會被解釋處理.
特殊字元的自動轉義
在HTML中, 有兩個字元需要特殊對待: <
和&
. <
左尖括號表示標籤的開始, &
表示HTML字元實體. 如果你想使用它們的字面常量, 就必須把它們轉義成實體, 例如<
和&
.
對於web作家來說字元&
尤其令人苦惱. 如果你想寫一個'AT&T'
, 你就必須寫成'AT&T'
. 甚至你需要對URL中的字元&
進行轉義. 因此如果你要連結到:
http://images.google.com/images?num=30&q=larry+bird
你必須把URL編碼成下面這樣:
http://images.google.com/images?num=30&q=larry+bird
然後設定為<a>
標籤href
屬性值. 毋庸置疑這很容易忘記, 並且最容易稱為一個編寫良好的站點中唯一一個校驗錯誤的地方.
Markdown允許你自然地使用這個字元, 在需要轉義的時候替你完成這些任務. 如果你需要在HTML實體裡面插入一個 &
, 那麼Markdown不會做任何轉換; 否則Markdown會將它轉換成 &
.
所以如果你要包含一個copyright符號在你的文字中, 你可以寫成
©
Markdown將保持它的原樣. 但是如果你想寫一個:
AT&T
Markdown就會把它轉換成:
AT&T
類似地, 由於Markdown支援內聯HTML, 如果你用一對尖括號作為HTML標籤的分隔符, Markdown則會保持尖括號的原樣; 但是如果你要寫一個:
4<5
Markdown就會把它轉換成:
4<5
不管怎樣, 在Markdown程式碼片段和塊元素中, 尖括號和符號&
始終會被自動編碼. 這就使得使用Markdown編寫HTML程式碼變得很容易. (這和原生HTML程式碼中糟糕的格式恰好相反, 因為對於每一個程式碼中的<
, >
和&
你都必須要手動轉義).
...
塊級元素
段落與換行
一個段落是由一個或多個連續的行組成的, 段與段之間通過一個或多個空行分隔. (除了空格和tab外不包含其他任何字元的行都被視為空行.) 普通的行不能用空格或者tab縮排.
上面"一個或多個連續的行"所暗含的意思就是, Markdown支援"hard-wrapped"文字段落. 這跟大部分把每一個換行符轉換成一個HTML<br />
標籤的text-to-HTML格式化程式(包括Movable Type's的"轉換換行符"選項)有著顯著不同.
當你確實需要使用Markdown插入一個<br />
換行標籤的時候, 只要在行結尾新增兩個或者多個空格再加一個回車就可以了.
這的確需要額外的功夫才能插入一個<br />
, 但是過分簡化的"每個換行符就是一個HTML<br />
標籤"的規則不太適用於Markdown. Markdown基於email風格的塊引用和列表項最好用-並且更易讀-當你用硬換行格式化的時候.
HEADERS頭部
Markdown支援兩種風格的頭部, [Setext][1]和[atx][2].
Setext風格的頭部是使用雙等號的下劃線(一級頭部)和使用破折號的下劃線(二級頭部). 例如:
This is an H1
=============
This is an H2
-------------
任意數量的=
和-
都可以.
Atx風格的頭部是在每一行的開頭新增1到6個井號字元#, 對應著1級到6級頭部. 例如:
#This is an H1
##This is an H2
######This is an H6
你可以選擇帶有"結束"標記的atx頭部. 這純粹是為了美觀-如果你覺得這會讓你的Markdown程式碼更加易讀. #
符號的數目甚至都不用與頭部的開始標記數量相同.(開始#
號的數量用於表示頭部的級別):
#This is an H1 #
##This is an H2 ##
###This is an H3 ######
引用
Markdown使用email風格的字元>
作為引用. 如果你熟悉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你可以選定一段文字然後從文字選單選擇升級引用級別.
列表
Markdown支援有序(編號的)列表和無序列表.
無序列表使用星號(*
), 加號(+
)和減號(-
)-可以交替使用-來作為列表標記:
* Red
* Green
* Blue
等同於:
+ Red
+ Green
+ Blue
和
- Red
- Green
- Blue
有序列表使用數字緊跟一個句號.:
1. Bird
2. McHale
3. Parish
重要的一點是, 你用來標記列表項的實際數字並不會影響Markdown所生成的HTML列表格式. 上面使用Markdown生成的HTML列表是:
<ol> <li>Bird</li> <li>McHale</li> <li>Parish</li> </ol>`
如果你像這樣編寫Markdown:
1. Bird
1. Mchale
1. Parish
甚至這樣:
3. Bird
1. Mchale
8. Parish
都能生成完全一樣的HTML. 關鍵在於, 如果你想, 你可以使用有序數字來標記Markdown列表, 這樣Markdown源文字里面的數字就能和輸出的HTML列表項數字保持一致了. 但是如果你想偷懶, 也可以不強制這樣做.
如果你偷懶(不使用有序數字來標記Markdown有序列表), 你仍然應該從1開始標記列表項. 在未來Markdown有可能會支援有序列表的start屬性.
一般情況下列表標記從左邊開始, 也有可能縮排最多三個空格. 列表標記之後必須緊跟至少一個空格或者一個tab.
為了讓列表更加美觀, 你可以使用hanging(對齊的)縮排來包裝列表項:
* 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程式碼會將列表項用
標籤包裝起來. 例如:
* Bird
* Magic
將被轉換成HTML:
<ul> <li>Bird</li> <li>Magic</li> <ul>
但是下面的:
* Bird
* Magic
將被轉換成:
<ul> <li><p>Bird</p></li> <li><p>Magic</p></li> </ul>
列表項可能會有多個段落, 每個子段落必須用四個空格或者一個tab縮排:
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文字更加美觀. 但是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.
為了在列表項內部插入一個引用, 則需要對引用的>分隔符縮排:
* A list item with a blockquote:
> This is a blockquote
> inside a list item
要在列表項裡插入程式碼段, 那麼需要對程式碼段進行兩次縮排 - 8個空格或者2個tab:
* A list item with a code block:
public class Test() {
public static void main(String[] args) {
System.out.println("Hello Markdown");
}
}
有時候會不經意間導致生成Markdown列表, 比如這種寫法:
1986. What a great season.
換句話說, 在任一段開頭如果如果恰好包含一個 數字-句號-空格 序列模式就會生成一個列表項. 你可以在句號前面加一個斜線轉義來避免這種情況:
1986\. What a great season.
程式碼塊
格式化的程式碼塊通常用在與程式設計或者標記文字原始碼的寫作中. 與格式化普通段落不同的是, 我們希望程式碼塊裡的行保持原有格式. Markdown將程式碼塊同時用 <pre>
和 <code>
標籤包裝起來.
要在Markdown裡面生成程式碼塊, 只需要對程式碼塊中的每一行縮排4個空格或者1個tab就可以了. 例如下面這一段文字:
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>
一級縮排-4個空格或1個tab-將會從程式碼段中被移除. 例如:
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"> © 2004 Foo Corporation </div>
將被轉換成:
<pre><code><pre><div class="footer"> &copy; 2004 Foo Corporation </div> </code></pre>
程式碼段內的普通Markdown語法不會被處理, 例如程式碼段內的星號*
就是字面量星號*
. 這就意味著使用Markdown去編寫Markdown的語法很容易.
水平線
在一行內輸入(且只能是)三個或以上的*
, -
或_
就能生成一個水平線(<hr />
). 當然你可以在連續的-
或*
之間插入空格. 下面的每一行都將生成一個水平線:
* * *
***
*****
- - -
__________________________________
...
內聯元素
超連結
Markdown支援兩種風格的連結: 內聯式(inline)和引用式(reference).
這兩種風格都要求超連結的文字內容用中括號[]
分隔.
在中括號的結尾使用一對圓括號()
就能建立連結地址, 圓括號內部就是要指向的連結地址, 如果你想為連結建立標題那麼可以在連結URL之後輸入一段用雙引號包含的文字. 例如:
This is [an example](https://ayningcao.github.io "My Github") inline link
[This link](https://ayningcao.github.io) has no title attribute
將會生成:
<p>This is <a href="https://ayningcao.github.io" title="My Github"> an example</a> inline link.</p> <p><a href="https://ayningcao.github.io">This link</a> has no title attribute.</p>
如果是連結是指向本地資源你也可以使用相對路徑:
See my [About](/about/) apge for details.
引用式的連結是在超連結文字後面新增一對中括號, 中括號的內容是目標URL的標籤:
This is [an example][id] reference-style link.
你也可以在兩對中括號之間插入一個空格.
然後你可以在文件其他任何地方定義連結的標籤:
[id]: http://ayningcao.github.io/ "title"
這個引用式連結的格式是:
- 開頭是一箇中括號
[]
, 中括號裡面包含連結ID(從左開始可以包含最多三個空格作為縮排); - 然後跟著一個冒號
:
; - 然後是一個或多個空格;
- 連結的實際URL;
- 最後是一個可選的連結標題, 標題用雙引號, 單引號或者圓括號包圍.
下面這三個連結定義是等價的:
[Github]: http://github.com/ "github.com"
[Github]: http://github.com/ 'github.com'
[Github]: http://github.com/ (github.com)
注意: 在Markdown.pl 1.0.1版本里有一個bug會使得用單引號對title定界出現異常.
也可以用尖括號來包含連結URL:
[id]: <http://github.com> "Github"
如果URL很長影響可讀性, 你也可以把連結title放到下一行, 並用額外的空格或者tab來對齊標題:
[id]: <https://ayningcao.github.com/index.html> "My Own Github"
連結定義只在Markdown處理期間用於建立連結, 並不會輸出到最終的HTML.
連結定義可以包含字母, 數字, 空格和標點符號 - 並且大小寫不敏感. 比如下面的兩個連結定義是等價的:
[link text][a]
[link text][A]
在連結的文字本身就是連結名的情況下, 可以通過隱式連結名這種快捷方式省略連結名. 只要用一對空中括號-比如, 通過單詞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 [Goole][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>
我們可以對比下使用Markdown內聯風格的連結寫法:
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").
引用式的連結寫法關鍵點不在於更易寫, 而是它會使得你的Markdown原文字明顯更加易讀. 對比以上兩個例子: 使用引用式連結, 段落本身只有81個字元, 而內聯方風格要176個字元, 而原始HTML程式碼則需要234個字元, 而且HTML標籤比文字內容竟然都要多.
通過Markdown的引用式連結可以使得源文件格式儘可能與瀏覽器裡渲染出的最終的樣式接近. 通過將與文字無關的標記相關的後設資料移出段落, 就可以不用打斷正常的段落敘述(而將精力集中在文字本身的內容).
強調(EMPHASIS)
Markdown將星號(*)
和下劃線(_)
作為強調指示符. 被一個*
或者_
包圍的文字將會被轉換成HTML <em>
標籤的內容, 而被兩個*
或者_
包圍的本文則會被轉換成被HTML <strong>
標籤包圍的內容. 例如輸入以下Markdown文字:
*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
但是如果你用空格包含一個*或者_, 那麼Markdown將會把他們當做普通的星號或者下劃線.
在一些情況下星號或者下劃線可能被當做強調符號, 這時要生成一個普通的星號或者下劃線, 你可以用一個反斜槓來轉義
\*this text is surrounded by literal asterisks\*
程式碼
可以通過重音符(`
)來標記一段程式碼(譯者注: 重音符在數字1鍵左邊), 與格式化的程式碼段不同, 一個程式碼片段用來標記一個普通段落內的程式碼. 例如:
Use the 'printf()' function
將會生成:
<p>Use the <code>printf()</code> function.</p>
如果要在一個程式碼行內包含一個字面常量的重音符, 你可以使用多個重音符來作為這一行的起始和開頭標記
``This 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字元實體, 這樣就很容易在Markdown段落中包含HTML標籤了. Markdown會將下面的文字:
Please don't use any '<blink>' tags.
轉換成:
<p>Please don't use any <code><blink><code> tags</p>
你可以這樣寫:
`—` is the decimal-encoded equivalent of `—`.
來生成:
<p><code>&#8212;</code> is the decimal-encoded equivalent of <code>&mdash;</code>.</p>
圖片(IMAGES)
設計一種比較"自然"的語法, 能夠實現向一段純文字格式的文件裡面插入一張圖片, 是相對比較困難的一件事.
Markdown使用一種結合超連結的語法的方式來實現插入圖片, 並且支援兩種風格: 內聯式和引用式.
使用內聯式語法的Markdown文字是這樣的:
![Alt text](/path/to/img.jpg)
![Alt text](/path/to/img.jpg "Optional title")
就是:
- 以一個感嘆號開頭: !;
- 緊跟一對中括號, 中括號的內容是圖片的alt屬性;
- 然後是一對圓括號, 包含圖片的URL和一個可選的圖片標題(title)屬性, 屬性值用單引號或者雙引號包圍起來.
引用式的圖片語法類似下面這樣:
![Alt text][id]
這裡的"id" 是一個預定義的圖片引用名字. 定義圖片引用的語法與引用式連結定義的語法是類似的:
[id]: url/to/image "Optional title attribute"
到目前為止, Markdown還沒有制定圖片尺寸的方法; 如果有必要, 你可以直接使用HTML的<img>
標籤.
...
其它(MISCELLANEOUS)
自動連結
Markdown為建立指向URL或者EMAIL地址的自動連結提供了一種快捷方式: 用一對尖括號<>
把URL或者EMAIL地址包圍起來就行了. 意思就是說, 如果你想顯示URL或者EMAIL地址的值, 並且希望可以直接點選他們(實現跳轉), 你就可以直接這樣寫:
<http://example.com/>
Markdown會把它轉換為:
<a href="http://example.com/">http://example.com/</a>
指向EMAIL地址的自動連結工作方式大體與連結相同, 不同的是, Markdown會首先對(email地址)執行一些隨機十進位制和十六進位制實體編碼, 以防止專門收集email地址的垃圾郵件程式. 例如, Markdown會把下面的地址:
address@example.com
轉換成:
<a href="mailto:address@example.com">address@example.com</a>
最終在HTML程式碼中渲染出一個指向 "address@example.com"的連結.
(這種實體編碼的方法即時不能糊弄全部的地址爬蟲, 也至少可以阻止大部分, 但是肯定不會阻止掉全部的. 這樣總比什麼都不做要好, 公開你的郵件地址最終會導致你收到垃圾郵件)
反斜槓轉義字元
你可以使用Markdown的反斜槓轉義字元來生成一些有特殊含義的語法的字面常量. 例如如果你想生成一個星號(*
, 不是HTML中的<em>
)包圍一個單詞, 你就可以在星號之前加上一個反斜槓\
, 像這樣:
\*literal asterisks\*
Markdown轉義字元可以對下面的特殊字元進行轉義:
\ backslash
` backtick
* asterisk
_ underscore
{} curly braces
[] square brackets
() parentheses
# hash mark
+ plus sign
- minus sign (hyphen)
. dot
! exclamation mark