-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspec.txt
6842 lines (5357 loc) · 103 KB
/
spec.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: CommonMark Spec
author: John MacFarlane
version: 0.18
date: 2015-03-03
license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)'
...
中文翻译:[Ivan Yan](https://github.com/yanxyz/commonmark-spec)
# 前言
## 什么是 Markdown?
Markdown 是一种纯文本格式,用来撰写结构化文档。它基于 email 和 usenet
的格式化标记,由 John Gruber 在 2004 年创造。他用 perl
实现了第一个 Markdown 到 HTML 的转换器,迅速地在网络上普及开来。
到 2014 年已有几十种不同语言的实现。
一些扩展了 Markdown 语法,比如脚注、定义列表、表格等,
一些可以将 Markdown 转换到 LaTeX 等多种格式。
## 为什么需要规范?
John Gruber 的
[Markdown 语法说明](http://daringfireball.net/projects/markdown/syntax)
没有清晰的定义 Markdown 语法,下面列举一些问题:
1. 子列表需要缩进多少?语法说明指出列表项内的段落需要缩进四个空格,
但是对于子列表没有明确说明。我们自然地以为子列表也需要缩进,可是
`Markdown.pl` 不需要。这不是极端情况,
而且各实现在这个上面的分歧常常让用户惊奇。
见 [John Gruber 的评论](http://article.gmane.org/gmane.text.markdown.general/1997)。
2. 块级引用或标题前是否需要空行?多数实现不要求。但是对于硬换行的文本
可能会导致问题,解析也模棱两可。注意一些实现可以将标题放到块级引用内,
其它则不行。John Gruber 曾提到
[倾向于需要空行](http://article.gmane.org/gmane.text.markdown.general/2146)。
3. 缩进式代码块前是否需要空行?`Markdown.pl` 需要,
但是语法说明没有提到,而一些实现不需要。
``` markdown
paragraph
code?
```
4. 如何确定列表项包含在 `<p>` 标签内?列表可以半紧半松吗?
这样的列表怎么做?
``` markdown
1. one
2. two
3. three
```
或这样?
``` markdown
1. one
- a
- b
2. two
```
John Gruber 的相关评论见
[这里](http://article.gmane.org/gmane.text.markdown.general/2554)。
5. 列表标记可以缩进吗?有序列表的标记可以右对齐吗?
``` markdown
8. item 1
9. item 2
10. item 2a
```
6. 下面是一个列表,它的第二项包含水平线,还是被水平线隔开的两个列表?
``` markdown
* a
* * * * *
* b
```
7. 当列表标记从数字变成无序标记时,结果是一个还是两个列表?
语法说明说是两个,而 `Markdown.pl` 及许多其它的实现只生成一个。
``` markdown
1. fee
2. fie
- foe
- fum
```
8. 内联元素标记的优先级?例如下面是链接还是行内代码?
``` markdown
[a backtick (`)](/url) and [another backtick (`)](/url).
```
9. 强调与着重强调的优先级?例如下面如何解析?
``` markdown
*foo *bar* baz*
```
10. 块与内联结构的优先级?例如下面如何解析?
``` markdown
- `a long code span can contain a hyphen like this
- and it can screw things up`
```
11. 列表项可以包含标题吗?`Markdown.pl` 不允许这样,
但是允许块引用可以包含标题。
``` markdown
- # Heading
```
12. 列表项可以为空吗?
``` markdown
* a
*
* b
```
13. 块引用或列表项可以包含链接引用吗?
``` markdown
> Blockquote [foo].
>
> [foo]: /url
```
14. 如果一个链接引用有多个定义,那么该用哪个?
``` markdown
[foo]: /url1
[foo]: /url2
[foo][]
```
在缺少规范的情况下,早期的实现大都参考 `Markdown.pl` 来处理这些含糊的地方。
但是 `Markdown.pl` 有较多缺陷,许多情况下的结果明显不好,因此它不足以为范本。
由于没有清晰的规范,各种实现之间有分歧,结果用户常常惊奇的发现文档在一个
系统上是这样的(比如说 github wiki),在另一个系统上又是另样的(比如说
用 pandoc 转换到 docbook)。更糟的是,由于 Markdown 没有定义语法错误,
常常不能立即发现这些分歧。
## 关于本文档
本文档尝试清晰的定义 Markdown 语法。文档包含许多示例,Markdown 与 HTML
并排对照,也用作一致性测试。可以运行 `spec_tests.py` 来对比测试各
Markdown 实现:
python test/spec_tests.py --spec spec.txt --program PROGRAM
本文档描述了 Markdown 如何解析为一个抽象语法树,可以用 HTML 之外
的语法树表示法,不过 HTML 能够呈现结构差异,并且选择 HTML 后,
测试时便不用写抽象语法树渲染器。
本文档由一个纯文本文件 `spec.txt` 生成,用 Markdown 写成,有个小的扩展:
并排比较。可以用脚本 `tools/makespec.py` 把它转换为 HTML 或者 CommonMark,
CommonMark 可以再转换成其它格式。
示例中字符 `→` 代表制表符。
# 预备
## 字符与行
任意一串[字符]都是有效的 CommonMark 文档。
一个 [字符](@character) 是一个 unicode 代码点。本规范不指定编码,
行视为由字符而不是字节组成。某个解析器可能只处理某个编码。
一个[行](@line)是一串零或多个的[字符],以及[行结束符]或文档结尾。
[行结束符](@line-ending) 是换行(`U+000A`)、回车(`U+000D`) 或回车换行,
取决于操作系统。
出于安全原因,解析器需要删除或替换字符 `U+0000`。
不包含字符,或者只包含空格(`U+0020`) 或制表符(`U+0009`) 的行称为
[空行](@blank-line)。
本规范使用下面字符类定义:
[空白字符](@whitespace-character) 是空格(`U+0020`),
制表符(`U+0009`), 换行 (`U+000A`), 竖向制表符(`U+000B`),
换页(`U+000C`), 或回车(`U+000D`)。
[空白](@whitespace) 是一串一或多个[空白字符]。
[unicode 空白字符](@unicode-whitespace-character) 是一个 unicode `Zs`
类中的代码点,或制表符(`U+0009`), 回车(`U+000D`), 换行(`U+000A`)
或换页(`U+000C`)。
[Unicode 空白](@unicode-whitespace)是一串一或多个[unicode 空白字符]。
[非空白字符](@non-space-character)是除 `U+0020` 之外的字符。
[ASCII 标点符号](@ascii-punctuation-character)是
`!`, `"`, `#`, `$`, `%`, `&`, `'`, `(`, `)`,
`*`, `+`, `,`, `-`, `.`, `/`, `:`, `;`, `<`, `=`, `>`, `?`, `@`,
`[`, `\`, `]`, `^`, `_`, `` ` ``, `{`, `|`, `}`, 或 `~`。
[标点符号](@punctuation-character) 是 [ASCII 标点符号]或 unicode 类
`Pc`, `Pd`, `Pe`, `Pf`, `Pi`, `Po`, 或 `Ps` 中的代码点。
## 制表符
行内的制表符转为四个空格,制表位为四个字符宽度:
.
→foo→baz→→bim
.
<pre><code>foo baz bim
</code></pre>
.
.
a→a
ὐ→a
.
<pre><code>a a
ὐ a
</code></pre>
.
# 块与内联元素
文档可视为连续的[块](@block),比如:段落、块引用、标题、水平线、
代码块。块可以包含其它块或[内联元素](@inline):单词、空格、链接、
强调、图片、内联代码。
## 优先级
块始终优先于内联元素。例如下面列表,包含两个列表项,而不是一个包含
内联代码的列表项:
.
- `one
- two`
.
<ul>
<li>`one</li>
<li>two`</li>
</ul>
.
这意味着解析过程可分为两步:一,块结构;二,段落、标题及其它块内的
文本行,解析出内联元素。第二步的引用链接定义,需要等到第一步解析完成。
注意第一步只能串行解析行,但是第二步可并行,因为解析一个块内的内联元素不
影响解析其它块内的内联元素。
## 容器块和叶块
块分为两类:[容器块](@container-block)和 [叶块](@leaf-block)。
前者可以包含其它块,后者不能。
# 叶块
这节描述各类叶块。
## 水平线
由0-3 个空格的缩进及三或多个 `-`, `_`, `*` 字符组成的行,形成
[水平线](@horizontal-rule)。几个字符一样,每个字符后面可以有任意的空格。
.
***
---
___
.
<hr />
<hr />
<hr />
.
字符错误:
.
+++
.
<p>+++</p>
.
.
===
.
<p>===</p>
.
字符不够:
.
--
**
__
.
<p>--
**
__</p>
.
可以缩进 1-3 个空格:
.
***
***
***
.
<hr />
<hr />
<hr />
.
缩进四个空格就多了:
.
***
.
<pre><code>***
</code></pre>
.
.
Foo
***
.
<p>Foo
***</p>
.
可以用三个以上的字符:
.
_____________________________________
.
<hr />
.
字符之间可以有空格:
.
- - -
.
<hr />
.
.
** * ** * ** * **
.
<hr />
.
.
- - - -
.
<hr />
.
末尾可以有空格:
.
- - - -
.
<hr />
.
但是开头或末尾不能有其它的字符:
.
_ _ _ _ a
a------
.
<p>_ _ _ _ a</p>
<p>a------</p>
.
[非空格字符]要求一样,下面便不是水平线:
.
*-*
.
<p><em>-</em></p>
.
水平线前后不需要空行:
.
- foo
***
- bar
.
<ul>
<li>foo</li>
</ul>
<hr />
<ul>
<li>bar</li>
</ul>
.
水平线可以中断段落:
.
Foo
***
bar
.
<p>Foo</p>
<hr />
<p>bar</p>
.
如果一行 `-` 可以为水平线,也可以为[Setext 式标题]的底线,则优先考虑
[Setext 式标题]。因此,下面是[Setext 式标题],而不是跟着水平线
的段落:
.
Foo
---
bar
.
<h2>Foo</h2>
<p>bar</p>
.
水平线优先于列表项:
.
* Foo
* * *
* Bar
.
<ul>
<li>Foo</li>
</ul>
<hr />
<ul>
<li>Bar</li>
</ul>
.
如果想在列表项中插入水平线,那么使用不同的项目符号:
.
- Foo
- * * *
.
<ul>
<li>Foo</li>
<li><hr /></li>
</ul>
.
## ATX 式标题
[ATX 式标题](@atx-header)由开始序列、标题内容、关闭序列组成。
开始序列为 1-6 个 `#`, 可以缩进 1-3个空格。
它的后面不能直接跟着[非空白字符]。
关闭序列可选,为任意个 `#`,它的前面必须有一个空格,后面只能是空格。
标题的原生内容在解析前删除首尾空格。标题的级别等于开始序列 `#` 的个数。
简单标题:
.
# foo
## foo
### foo
#### foo
##### foo
###### foo
.
<h1>foo</h1>
<h2>foo</h2>
<h3>foo</h3>
<h4>foo</h4>
<h5>foo</h5>
<h6>foo</h6>
.
超过六个 `#` 不是标题:
.
####### foo
.
<p>####### foo</p>
.
`#` 字符与标题内容之间需要一个空格。注意目前许多实现不要求这样。
不过 [ATX 实现](http://www.aaronsw.com/2002/atx/atx.py)需要,并且
可以避免下面情形被解析为标题:
.
#5 bolt
.
<p>#5 bolt</p>
.
下例不是标题,因为第一个 `#` 被转义:
.
\## foo
.
<p>## foo</p>
.
标题内容解析为内联元素:
.
# foo *bar* \*baz\*
.
<h1>foo <em>bar</em> *baz*</h1>
.
解析时忽略内容的首尾空白:
.
# foo
.
<h1>foo</h1>
.
可以缩进 1-3 个空格:
.
### foo
## foo
# foo
.
<h3>foo</h3>
<h2>foo</h2>
<h1>foo</h1>
.
缩进四个空格就多了:
.
# foo
.
<pre><code># foo
</code></pre>
.
.
foo
# bar
.
<p>foo
# bar</p>
.
关闭序列可选:
.
## foo ##
### bar ###
.
<h2>foo</h2>
<h3>bar</h3>
.
它的长度不需要与开始序列一致:
.
# foo ##################################
##### foo ##
.
<h1>foo</h1>
<h5>foo</h5>
.
关闭序列后面可以有空格:
.
### foo ###
.
<h3>foo</h3>
.
后面跟着[非空白字符]的 `#` 序列不是关闭序列,视为标题内容的一部分:
.
### foo ### b
.
<h3>foo ### b</h3>
.
被反斜杠转义的 `#` 字符计入关闭序列:
.
### foo \###
## foo \#\##
# foo \#
.
<h3>foo #</h3>
<h2>foo ##</h2>
<h1>foo #</h1>
.
ATX 式标题前后不需要空行,它可以中断段落:
.
****
## foo
****
.
<hr />
<h2>foo</h2>
<hr />
.
.
Foo bar
# baz
Bar foo
.
<p>Foo bar</p>
<h1>baz</h1>
<p>Bar foo</p>
.
ATX 式标题可以为空:
.
##
#
### ###
.
<h2></h2>
<h1></h1>
<h3></h3>
.
## Setext 式标题
[Setext 式标题](@setext-header)由一行文本(至少有一个[非空白字符],
至多缩进三个空格)及 [setext 式标题底线]组成。
[setext 式标题底线](@setext-header-underline)是一串 `=` 或 `-` 字符,
至多缩进三个空格,末尾可以有任意个空格。如果一个包含单个 `-` 行
能解析为列表项,则不能解析为标题底线。
[setext 式标题底线]使用 `=` 则是第一级标题,使用 `-` 字符则是第二级
标题。第一行按内联元素解析的结果是标题的内容。
通常 Setext 式标题前后不需要空行。不过它不能中断段落,所以当它后面跟着
段落时,它们之间需要空行。
简单示例:
.
Foo *bar*
=========
Foo *bar*
---------
.
<h1>Foo <em>bar</em></h1>
<h2>Foo <em>bar</em></h2>
.
底线长度任意:
.
Foo
-------------------------
Foo
=
.
<h2>Foo</h2>
<h1>Foo</h1>
.
标题内容可以缩进 1-3 个空格,并且不需要与底线对齐:
.
Foo
---
Foo
-----
Foo
===
.
<h2>Foo</h2>
<h2>Foo</h2>
<h1>Foo</h1>
.
缩进四个空格就多了:
.
Foo
---
Foo
---
.
<pre><code>Foo
---
Foo
</code></pre>
<hr />
.
底线可以缩进 1-3 个空格,并且末尾可以有空格:
.
Foo
----
.
<h2>Foo</h2>
.
缩进四个空格就多了:
.
Foo
---
.
<p>Foo
---</p>
.
底线内部不能有空格:
.
Foo
= =
Foo
--- -
.
<p>Foo
= =</p>
<p>Foo</p>
<hr />
.
内容行末尾的空格不会导致换行:
.
Foo
-----
.
<h2>Foo</h2>
.
反斜杠也不会:
.
Foo\
----
.
<h2>Foo\</h2>
.
因为块结构优先于内联结构,所以下面的是 Setext 式标题:
.
`Foo
----
`
<a title="a lot
---
of dashes"/>
.
<h2>`Foo</h2>
<p>`</p>
<h2><a title="a lot</h2>
<p>of dashes"/></p>
.
底线不能是列表黄或块引用的[懒惰连续行]:
.
> Foo
---
.
<blockquote>
<p>Foo</p>
</blockquote>
<hr />
.
Setext 式标题不能中断段落:
.
Foo
Bar
---
Foo
Bar
===
.
<p>Foo
Bar</p>
<hr />
<p>Foo
Bar
===</p>
.
不过通过前后不需要空行:
.
---
Foo
---
Bar
---
Baz
.
<hr />
<h2>Foo</h2>
<h2>Bar</h2>
<p>Baz</p>
.
Setext 式标题不能为空:
.
====
.
<p>====</p>
.
内容行不能解析为段落之外的块结构。故下例虚线行解析为水平线:
.
---
---
.
<hr />
<hr />
.
.
- foo
-----
.
<ul>
<li>foo</li>
</ul>
<hr />
.
.
foo
---
.
<pre><code>foo
</code></pre>
<hr />
.
.
> foo
-----
.
<blockquote>
<p>foo</p>
</blockquote>
<hr />
.
内容行想包含 `> foo`,使用反斜杠转义:
.
\> foo
------
.
<h2>> foo</h2>
.
## 缩进式代码块
[缩进式代码块](@indented-code-block)由空行隔开的数个[缩进块]组成。
[缩进块](@indented-chunk)是数个非空行,每行缩进四个或多个空格。代码块的内容
是这些行的字面内容,包含末尾的[行结束符],不包含四个空格的缩进。
缩进式代码块没有[信息字符串]。
缩进式代码块不能中断段落,当它跟在段落后面时,两者之间需要空行。
不过,当它在段落前面时,两者之间不需要用空行。
.
a simple
indented code block
.
<pre><code>a simple
indented code block
</code></pre>
.
内容是字面上的,不会以 Markdown 语法解析:
.
<a/>
*hi*
- one
.
<pre><code><a/>
*hi*
- one
</code></pre>
.
下面三块以空行隔开:
.
chunk1
chunk2
chunk3
.
<pre><code>chunk1
chunk2
chunk3
</code></pre>
.
头部四个空格之后的空格,甚至是内部的空行,计入代码块的内容:
.
chunk1
chunk2
.
<pre><code>chunk1
chunk2
</code></pre>
.
缩进式代码块不能中断段落,这样可以悬挂缩进等等。
.
Foo
bar
.
<p>Foo
bar</p>
.
不过,头部少于四个空格的非空行将直接结束代码块。故段落可以紧跟在它后面:
.
foo
bar
.
<pre><code>foo
</code></pre>
<p>bar</p>
.
缩进式代码块可直接位于其它类型块的前后:
.
# Header
foo
Header
------
foo
----
.
<h1>Header</h1>
<pre><code>foo
</code></pre>
<h2>Header</h2>
<pre><code>foo
</code></pre>
<hr />