block_test.go (view raw)
1//
2// Blackfriday Markdown Processor
3// Available at http://github.com/russross/blackfriday
4//
5// Copyright © 2011 Russ Ross <russ@russross.com>.
6// Distributed under the Simplified BSD License.
7// See README.md for details.
8//
9
10//
11// Unit tests for block parsing
12//
13
14package blackfriday
15
16import (
17 "testing"
18)
19
20func runMarkdownBlock(input string, extensions int) string {
21 htmlFlags := 0
22 htmlFlags |= HTML_USE_XHTML
23
24 renderer := HtmlRenderer(htmlFlags, "", "")
25
26 return string(Markdown([]byte(input), renderer, extensions))
27}
28
29func doTestsBlock(t *testing.T, tests []string, extensions int) {
30 // catch and report panics
31 var candidate string
32 defer func() {
33 if err := recover(); err != nil {
34 t.Errorf("\npanic while processing [%#v]\n", candidate)
35 }
36 }()
37
38 for i := 0; i+1 < len(tests); i += 2 {
39 input := tests[i]
40 candidate = input
41 expected := tests[i+1]
42 actual := runMarkdownBlock(candidate, extensions)
43 if actual != expected {
44 t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]",
45 candidate, expected, actual)
46 }
47
48 // now test every substring to stress test bounds checking
49 if !testing.Short() {
50 for start := 0; start < len(input); start++ {
51 for end := start + 1; end <= len(input); end++ {
52 candidate = input[start:end]
53 _ = runMarkdownBlock(candidate, extensions)
54 }
55 }
56 }
57 }
58}
59
60func TestPrefixHeaderNoExtensions(t *testing.T) {
61 var tests = []string{
62 "# Header 1\n",
63 "<h1>Header 1</h1>\n",
64
65 "## Header 2\n",
66 "<h2>Header 2</h2>\n",
67
68 "### Header 3\n",
69 "<h3>Header 3</h3>\n",
70
71 "#### Header 4\n",
72 "<h4>Header 4</h4>\n",
73
74 "##### Header 5\n",
75 "<h5>Header 5</h5>\n",
76
77 "###### Header 6\n",
78 "<h6>Header 6</h6>\n",
79
80 "####### Header 7\n",
81 "<h6># Header 7</h6>\n",
82
83 "#Header 1\n",
84 "<h1>Header 1</h1>\n",
85
86 "##Header 2\n",
87 "<h2>Header 2</h2>\n",
88
89 "###Header 3\n",
90 "<h3>Header 3</h3>\n",
91
92 "####Header 4\n",
93 "<h4>Header 4</h4>\n",
94
95 "#####Header 5\n",
96 "<h5>Header 5</h5>\n",
97
98 "######Header 6\n",
99 "<h6>Header 6</h6>\n",
100
101 "#######Header 7\n",
102 "<h6>#Header 7</h6>\n",
103
104 "Hello\n# Header 1\nGoodbye\n",
105 "<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
106
107 "* List\n# Header\n* List\n",
108 "<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
109
110 "* List\n#Header\n* List\n",
111 "<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
112
113 "* List\n * Nested list\n # Nested header\n",
114 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
115 "<h1>Nested header</h1></li>\n</ul></li>\n</ul>\n",
116 }
117 doTestsBlock(t, tests, 0)
118}
119
120func TestPrefixHeaderSpaceExtension(t *testing.T) {
121 var tests = []string{
122 "# Header 1\n",
123 "<h1>Header 1</h1>\n",
124
125 "## Header 2\n",
126 "<h2>Header 2</h2>\n",
127
128 "### Header 3\n",
129 "<h3>Header 3</h3>\n",
130
131 "#### Header 4\n",
132 "<h4>Header 4</h4>\n",
133
134 "##### Header 5\n",
135 "<h5>Header 5</h5>\n",
136
137 "###### Header 6\n",
138 "<h6>Header 6</h6>\n",
139
140 "####### Header 7\n",
141 "<p>####### Header 7</p>\n",
142
143 "#Header 1\n",
144 "<p>#Header 1</p>\n",
145
146 "##Header 2\n",
147 "<p>##Header 2</p>\n",
148
149 "###Header 3\n",
150 "<p>###Header 3</p>\n",
151
152 "####Header 4\n",
153 "<p>####Header 4</p>\n",
154
155 "#####Header 5\n",
156 "<p>#####Header 5</p>\n",
157
158 "######Header 6\n",
159 "<p>######Header 6</p>\n",
160
161 "#######Header 7\n",
162 "<p>#######Header 7</p>\n",
163
164 "Hello\n# Header 1\nGoodbye\n",
165 "<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
166
167 "* List\n# Header\n* List\n",
168 "<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
169
170 "* List\n#Header\n* List\n",
171 "<ul>\n<li>List\n#Header</li>\n<li>List</li>\n</ul>\n",
172
173 "* List\n * Nested list\n # Nested header\n",
174 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
175 "<h1>Nested header</h1></li>\n</ul></li>\n</ul>\n",
176 }
177 doTestsBlock(t, tests, EXTENSION_SPACE_HEADERS)
178}
179
180func TestUnderlineHeaders(t *testing.T) {
181 var tests = []string{
182 "Header 1\n========\n",
183 "<h1>Header 1</h1>\n",
184
185 "Header 2\n--------\n",
186 "<h2>Header 2</h2>\n",
187
188 "A\n=\n",
189 "<h1>A</h1>\n",
190
191 "B\n-\n",
192 "<h2>B</h2>\n",
193
194 "Paragraph\nHeader\n=\n",
195 "<p>Paragraph</p>\n\n<h1>Header</h1>\n",
196
197 "Header\n===\nParagraph\n",
198 "<h1>Header</h1>\n\n<p>Paragraph</p>\n",
199
200 "Header\n===\nAnother header\n---\n",
201 "<h1>Header</h1>\n\n<h2>Another header</h2>\n",
202
203 " Header\n======\n",
204 "<h1>Header</h1>\n",
205
206 " Code\n========\n",
207 "<pre><code>Code\n</code></pre>\n\n<p>========</p>\n",
208
209 "Header with *inline*\n=====\n",
210 "<h1>Header with <em>inline</em></h1>\n",
211
212 "* List\n * Sublist\n Not a header\n ------\n",
213 "<ul>\n<li>List\n\n<ul>\n<li>Sublist\nNot a header\n------</li>\n</ul></li>\n</ul>\n",
214
215 "Paragraph\n\n\n\n\nHeader\n===\n",
216 "<p>Paragraph</p>\n\n<h1>Header</h1>\n",
217
218 "Trailing space \n==== \n\n",
219 "<h1>Trailing space</h1>\n",
220
221 "Trailing spaces\n==== \n\n",
222 "<h1>Trailing spaces</h1>\n",
223
224 "Double underline\n=====\n=====\n",
225 "<h1>Double underline</h1>\n\n<p>=====</p>\n",
226 }
227 doTestsBlock(t, tests, 0)
228}
229
230func TestHorizontalRule(t *testing.T) {
231 var tests = []string{
232 "-\n",
233 "<p>-</p>\n",
234
235 "--\n",
236 "<p>--</p>\n",
237
238 "---\n",
239 "<hr />\n",
240
241 "----\n",
242 "<hr />\n",
243
244 "*\n",
245 "<p>*</p>\n",
246
247 "**\n",
248 "<p>**</p>\n",
249
250 "***\n",
251 "<hr />\n",
252
253 "****\n",
254 "<hr />\n",
255
256 "_\n",
257 "<p>_</p>\n",
258
259 "__\n",
260 "<p>__</p>\n",
261
262 "___\n",
263 "<hr />\n",
264
265 "____\n",
266 "<hr />\n",
267
268 "-*-\n",
269 "<p>-*-</p>\n",
270
271 "- - -\n",
272 "<hr />\n",
273
274 "* * *\n",
275 "<hr />\n",
276
277 "_ _ _\n",
278 "<hr />\n",
279
280 "-----*\n",
281 "<p>-----*</p>\n",
282
283 " ------ \n",
284 "<hr />\n",
285
286 "Hello\n***\n",
287 "<p>Hello</p>\n\n<hr />\n",
288
289 "---\n***\n___\n",
290 "<hr />\n\n<hr />\n\n<hr />\n",
291 }
292 doTestsBlock(t, tests, 0)
293}
294
295func TestUnorderedList(t *testing.T) {
296 var tests = []string{
297 "* Hello\n",
298 "<ul>\n<li>Hello</li>\n</ul>\n",
299
300 "* Yin\n* Yang\n",
301 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
302
303 "* Ting\n* Bong\n* Goo\n",
304 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
305
306 "* Yin\n\n* Yang\n",
307 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
308
309 "* Ting\n\n* Bong\n* Goo\n",
310 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
311
312 "+ Hello\n",
313 "<ul>\n<li>Hello</li>\n</ul>\n",
314
315 "+ Yin\n+ Yang\n",
316 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
317
318 "+ Ting\n+ Bong\n+ Goo\n",
319 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
320
321 "+ Yin\n\n+ Yang\n",
322 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
323
324 "+ Ting\n\n+ Bong\n+ Goo\n",
325 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
326
327 "- Hello\n",
328 "<ul>\n<li>Hello</li>\n</ul>\n",
329
330 "- Yin\n- Yang\n",
331 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
332
333 "- Ting\n- Bong\n- Goo\n",
334 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
335
336 "- Yin\n\n- Yang\n",
337 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
338
339 "- Ting\n\n- Bong\n- Goo\n",
340 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
341
342 "*Hello\n",
343 "<p>*Hello</p>\n",
344
345 "* Hello \n",
346 "<ul>\n<li>Hello</li>\n</ul>\n",
347
348 "* Hello \n Next line \n",
349 "<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
350
351 "Paragraph\n* No linebreak\n",
352 "<p>Paragraph\n* No linebreak</p>\n",
353
354 "Paragraph\n\n* Linebreak\n",
355 "<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
356
357 "* List\n * Nested list\n",
358 "<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
359
360 "* List\n\n * Nested list\n",
361 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
362
363 "* List\n Second line\n\n + Nested\n",
364 "<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
365
366 "* List\n + Nested\n\n Continued\n",
367 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
368
369 "* List\n * shallow indent\n",
370 "<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
371
372 "* List\n" +
373 " * shallow indent\n" +
374 " * part of second list\n" +
375 " * still second\n" +
376 " * almost there\n" +
377 " * third level\n",
378 "<ul>\n" +
379 "<li>List\n\n" +
380 "<ul>\n" +
381 "<li>shallow indent</li>\n" +
382 "<li>part of second list</li>\n" +
383 "<li>still second</li>\n" +
384 "<li>almost there\n\n" +
385 "<ul>\n" +
386 "<li>third level</li>\n" +
387 "</ul></li>\n" +
388 "</ul></li>\n" +
389 "</ul>\n",
390
391 "* List\n extra indent, same paragraph\n",
392 "<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n",
393
394 "* List\n\n code block\n",
395 "<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
396
397 "* List\n\n code block with spaces\n",
398 "<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n",
399
400 "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
401 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>sublist</li>\n</ul>\n\n<p>normal text</p>\n\n<ul>\n<li>another sublist</li>\n</ul></li>\n</ul>\n",
402 }
403 doTestsBlock(t, tests, 0)
404}
405
406func TestOrderedList(t *testing.T) {
407 var tests = []string{
408 "1. Hello\n",
409 "<ol>\n<li>Hello</li>\n</ol>\n",
410
411 "1. Yin\n2. Yang\n",
412 "<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
413
414 "1. Ting\n2. Bong\n3. Goo\n",
415 "<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
416
417 "1. Yin\n\n2. Yang\n",
418 "<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
419
420 "1. Ting\n\n2. Bong\n3. Goo\n",
421 "<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
422
423 "1 Hello\n",
424 "<p>1 Hello</p>\n",
425
426 "1.Hello\n",
427 "<p>1.Hello</p>\n",
428
429 "1. Hello \n",
430 "<ol>\n<li>Hello</li>\n</ol>\n",
431
432 "1. Hello \n Next line \n",
433 "<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
434
435 "Paragraph\n1. No linebreak\n",
436 "<p>Paragraph\n1. No linebreak</p>\n",
437
438 "Paragraph\n\n1. Linebreak\n",
439 "<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
440
441 "1. List\n 1. Nested list\n",
442 "<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
443
444 "1. List\n\n 1. Nested list\n",
445 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
446
447 "1. List\n Second line\n\n 1. Nested\n",
448 "<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
449
450 "1. List\n 1. Nested\n\n Continued\n",
451 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
452
453 "1. List\n 1. shallow indent\n",
454 "<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
455
456 "1. List\n" +
457 " 1. shallow indent\n" +
458 " 2. part of second list\n" +
459 " 3. still second\n" +
460 " 4. almost there\n" +
461 " 1. third level\n",
462 "<ol>\n" +
463 "<li>List\n\n" +
464 "<ol>\n" +
465 "<li>shallow indent</li>\n" +
466 "<li>part of second list</li>\n" +
467 "<li>still second</li>\n" +
468 "<li>almost there\n\n" +
469 "<ol>\n" +
470 "<li>third level</li>\n" +
471 "</ol></li>\n" +
472 "</ol></li>\n" +
473 "</ol>\n",
474
475 "1. List\n extra indent, same paragraph\n",
476 "<ol>\n<li>List\n extra indent, same paragraph</li>\n</ol>\n",
477
478 "1. List\n\n code block\n",
479 "<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
480
481 "1. List\n\n code block with spaces\n",
482 "<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
483
484 "1. List\n * Mixted list\n",
485 "<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
486
487 "1. List\n * Mixed list\n",
488 "<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
489
490 "* Start with unordered\n 1. Ordered\n",
491 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
492
493 "* Start with unordered\n 1. Ordered\n",
494 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
495
496 "1. numbers\n1. are ignored\n",
497 "<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
498 }
499 doTestsBlock(t, tests, 0)
500}
501
502func TestPreformattedHtml(t *testing.T) {
503 var tests = []string{
504 "<div></div>\n",
505 "<div></div>\n",
506
507 "<div>\n</div>\n",
508 "<div>\n</div>\n",
509
510 "<div>\n</div>\nParagraph\n",
511 "<p><div>\n</div>\nParagraph</p>\n",
512
513 "<div class=\"foo\">\n</div>\n",
514 "<div class=\"foo\">\n</div>\n",
515
516 "<div>\nAnything here\n</div>\n",
517 "<div>\nAnything here\n</div>\n",
518
519 "<div>\n Anything here\n</div>\n",
520 "<div>\n Anything here\n</div>\n",
521
522 "<div>\nAnything here\n </div>\n",
523 "<div>\nAnything here\n </div>\n",
524
525 "<div>\nThis is *not* &proceessed\n</div>\n",
526 "<div>\nThis is *not* &proceessed\n</div>\n",
527
528 "<faketag>\n Something\n</faketag>\n",
529 "<p><faketag>\n Something\n</faketag></p>\n",
530
531 "<div>\n Something here\n</divv>\n",
532 "<p><div>\n Something here\n</divv></p>\n",
533
534 "Paragraph\n<div>\nHere? >&<\n</div>\n",
535 "<p>Paragraph\n<div>\nHere? >&<\n</div></p>\n",
536
537 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
538 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
539
540 "Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
541 "<p>Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?</p>\n",
542
543 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
544 "<p>Paragraph</p>\n\n<p><div>\nHow about here? >&<\n</div>\nAnd here?</p>\n",
545
546 "Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
547 "<p>Paragraph\n<div>\nHere? >&<\n</div></p>\n\n<p>And here?</p>\n",
548
549 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
550 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
551 }
552 doTestsBlock(t, tests, 0)
553}
554
555func TestPreformattedHtmlLax(t *testing.T) {
556 var tests = []string{
557 "Paragraph\n<div>\nHere? >&<\n</div>\n",
558 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n",
559
560 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
561 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
562
563 "Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
564 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
565
566 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
567 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
568
569 "Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
570 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
571
572 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
573 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
574 }
575 doTestsBlock(t, tests, EXTENSION_LAX_HTML_BLOCKS)
576}
577
578func TestFencedCodeBlock(t *testing.T) {
579 var tests = []string{
580 "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
581 "<pre><code class=\"go\">func foo() bool {\n return true;\n}\n</code></pre>\n",
582
583 "``` c\n/* special & char < > \" escaping */\n```\n",
584 "<pre><code class=\"c\">/* special & char < > " escaping */\n</code></pre>\n",
585
586 "``` c\nno *inline* processing ~~of text~~\n```\n",
587 "<pre><code class=\"c\">no *inline* processing ~~of text~~\n</code></pre>\n",
588
589 "```\nNo language\n```\n",
590 "<pre><code>No language\n</code></pre>\n",
591
592 "``` {ocaml}\nlanguage in braces\n```\n",
593 "<pre><code class=\"ocaml\">language in braces\n</code></pre>\n",
594
595 "``` {ocaml} \nwith extra whitespace\n```\n",
596 "<pre><code class=\"ocaml\">with extra whitespace\n</code></pre>\n",
597
598 "```{ ocaml }\nwith extra whitespace\n```\n",
599 "<pre><code class=\"ocaml\">with extra whitespace\n</code></pre>\n",
600
601 "~ ~~ java\nWith whitespace\n~~~\n",
602 "<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
603
604 "~~\nonly two\n~~\n",
605 "<p>~~\nonly two\n~~</p>\n",
606
607 "```` python\nextra\n````\n",
608 "<pre><code class=\"python\">extra\n</code></pre>\n",
609
610 "~~~ perl\nthree to start, four to end\n~~~~\n",
611 "<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
612
613 "~~~~ perl\nfour to start, three to end\n~~~\n",
614 "<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
615
616 "~~~ bash\ntildes\n~~~\n",
617 "<pre><code class=\"bash\">tildes\n</code></pre>\n",
618
619 "``` lisp\nno ending\n",
620 "<p>``` lisp\nno ending</p>\n",
621
622 "~~~ lisp\nend with language\n~~~ lisp\n",
623 "<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
624
625 "```\nmismatched begin and end\n~~~\n",
626 "<p>```\nmismatched begin and end\n~~~</p>\n",
627
628 "~~~\nmismatched begin and end\n```\n",
629 "<p>~~~\nmismatched begin and end\n```</p>\n",
630
631 " ``` oz\nleading spaces\n```\n",
632 "<pre><code class=\"oz\">leading spaces\n</code></pre>\n",
633
634 " ``` oz\nleading spaces\n ```\n",
635 "<pre><code class=\"oz\">leading spaces\n</code></pre>\n",
636
637 " ``` oz\nleading spaces\n ```\n",
638 "<pre><code class=\"oz\">leading spaces\n</code></pre>\n",
639
640 "``` oz\nleading spaces\n ```\n",
641 "<pre><code class=\"oz\">leading spaces\n</code></pre>\n",
642
643 " ``` oz\nleading spaces\n ```\n",
644 "<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces\n ```</p>\n",
645 }
646 doTestsBlock(t, tests, EXTENSION_FENCED_CODE)
647}
648
649func TestTable(t *testing.T) {
650 var tests = []string{
651 "a | b\n---|---\nc | d\n",
652 "<table>\n<thead>\n<tr>\n<td>a</td>\n<td>b</td>\n</tr>\n</thead>\n\n" +
653 "<tbody>\n<tr>\n<td>c</td>\n<td>d</td>\n</tr>\n</tbody>\n</table>\n",
654
655 "a | b\n---|--\nc | d\n",
656 "<p>a | b\n---|--\nc | d</p>\n",
657
658 "|a|b|c|d|\n|----|----|----|---|\n|e|f|g|h|\n",
659 "<table>\n<thead>\n<tr>\n<td>a</td>\n<td>b</td>\n<td>c</td>\n<td>d</td>\n</tr>\n</thead>\n\n" +
660 "<tbody>\n<tr>\n<td>e</td>\n<td>f</td>\n<td>g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
661
662 "*a*|__b__|[c](C)|d\n---|---|---|---\ne|f|g|h\n",
663 "<table>\n<thead>\n<tr>\n<td><em>a</em></td>\n<td><strong>b</strong></td>\n<td><a href=\"C\">c</a></td>\n<td>d</td>\n</tr>\n</thead>\n\n" +
664 "<tbody>\n<tr>\n<td>e</td>\n<td>f</td>\n<td>g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
665
666 "a|b|c\n---|---|---\nd|e|f\ng|h\ni|j|k|l|m\nn|o|p\n",
667 "<table>\n<thead>\n<tr>\n<td>a</td>\n<td>b</td>\n<td>c</td>\n</tr>\n</thead>\n\n" +
668 "<tbody>\n<tr>\n<td>d</td>\n<td>e</td>\n<td>f</td>\n</tr>\n\n" +
669 "<tr>\n<td>g</td>\n<td>h</td>\n<td></td>\n</tr>\n\n" +
670 "<tr>\n<td>i</td>\n<td>j</td>\n<td>k</td>\n</tr>\n\n" +
671 "<tr>\n<td>n</td>\n<td>o</td>\n<td>p</td>\n</tr>\n</tbody>\n</table>\n",
672
673 "a|b|c\n---|---|---\n*d*|__e__|f\n",
674 "<table>\n<thead>\n<tr>\n<td>a</td>\n<td>b</td>\n<td>c</td>\n</tr>\n</thead>\n\n" +
675 "<tbody>\n<tr>\n<td><em>d</em></td>\n<td><strong>e</strong></td>\n<td>f</td>\n</tr>\n</tbody>\n</table>\n",
676
677 "a|b|c|d\n:--|--:|:-:|---\ne|f|g|h\n",
678 "<table>\n<thead>\n<tr>\n<td align=\"left\">a</td>\n<td align=\"right\">b</td>\n" +
679 "<td align=\"center\">c</td>\n<td>d</td>\n</tr>\n</thead>\n\n" +
680 "<tbody>\n<tr>\n<td align=\"left\">e</td>\n<td align=\"right\">f</td>\n" +
681 "<td align=\"center\">g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
682
683 "a|b|c\n---|---|---\n",
684 "<table>\n<thead>\n<tr>\n<td>a</td>\n<td>b</td>\n<td>c</td>\n</tr>\n</thead>\n\n<tbody>\n</tbody>\n</table>\n",
685
686 "a| b|c | d | e\n---|---|---|---|---\nf| g|h | i |j\n",
687 "<table>\n<thead>\n<tr>\n<td>a</td>\n<td>b</td>\n<td>c</td>\n<td>d</td>\n<td>e</td>\n</tr>\n</thead>\n\n" +
688 "<tbody>\n<tr>\n<td>f</td>\n<td>g</td>\n<td>h</td>\n<td>i</td>\n<td>j</td>\n</tr>\n</tbody>\n</table>\n",
689 }
690 doTestsBlock(t, tests, EXTENSION_TABLES)
691}