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 "strings"
18 "testing"
19)
20
21func TestPrefixHeaderNoExtensions(t *testing.T) {
22 var tests = []string{
23 "# Header 1\n",
24 "<h1>Header 1</h1>\n",
25
26 "## Header 2\n",
27 "<h2>Header 2</h2>\n",
28
29 "### Header 3\n",
30 "<h3>Header 3</h3>\n",
31
32 "#### Header 4\n",
33 "<h4>Header 4</h4>\n",
34
35 "##### Header 5\n",
36 "<h5>Header 5</h5>\n",
37
38 "###### Header 6\n",
39 "<h6>Header 6</h6>\n",
40
41 "####### Header 7\n",
42 "<h6># Header 7</h6>\n",
43
44 "#Header 1\n",
45 "<h1>Header 1</h1>\n",
46
47 "##Header 2\n",
48 "<h2>Header 2</h2>\n",
49
50 "###Header 3\n",
51 "<h3>Header 3</h3>\n",
52
53 "####Header 4\n",
54 "<h4>Header 4</h4>\n",
55
56 "#####Header 5\n",
57 "<h5>Header 5</h5>\n",
58
59 "######Header 6\n",
60 "<h6>Header 6</h6>\n",
61
62 "#######Header 7\n",
63 "<h6>#Header 7</h6>\n",
64
65 "Hello\n# Header 1\nGoodbye\n",
66 "<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
67
68 "* List\n# Header\n* List\n",
69 "<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
70
71 "* List\n#Header\n* List\n",
72 "<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
73
74 "* List\n * Nested list\n # Nested header\n",
75 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
76 "<h1>Nested header</h1></li>\n</ul></li>\n</ul>\n",
77
78 "#Header 1 \\#\n",
79 "<h1>Header 1 #</h1>\n",
80
81 "#Header 1 \\# foo\n",
82 "<h1>Header 1 # foo</h1>\n",
83
84 "#Header 1 #\\##\n",
85 "<h1>Header 1 ##</h1>\n",
86 }
87 doTestsBlock(t, tests, 0)
88}
89
90func TestPrefixHeaderSpaceExtension(t *testing.T) {
91 var tests = []string{
92 "# Header 1\n",
93 "<h1>Header 1</h1>\n",
94
95 "## Header 2\n",
96 "<h2>Header 2</h2>\n",
97
98 "### Header 3\n",
99 "<h3>Header 3</h3>\n",
100
101 "#### Header 4\n",
102 "<h4>Header 4</h4>\n",
103
104 "##### Header 5\n",
105 "<h5>Header 5</h5>\n",
106
107 "###### Header 6\n",
108 "<h6>Header 6</h6>\n",
109
110 "####### Header 7\n",
111 "<p>####### Header 7</p>\n",
112
113 "#Header 1\n",
114 "<p>#Header 1</p>\n",
115
116 "##Header 2\n",
117 "<p>##Header 2</p>\n",
118
119 "###Header 3\n",
120 "<p>###Header 3</p>\n",
121
122 "####Header 4\n",
123 "<p>####Header 4</p>\n",
124
125 "#####Header 5\n",
126 "<p>#####Header 5</p>\n",
127
128 "######Header 6\n",
129 "<p>######Header 6</p>\n",
130
131 "#######Header 7\n",
132 "<p>#######Header 7</p>\n",
133
134 "Hello\n# Header 1\nGoodbye\n",
135 "<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
136
137 "* List\n# Header\n* List\n",
138 "<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
139
140 "* List\n#Header\n* List\n",
141 "<ul>\n<li>List\n#Header</li>\n<li>List</li>\n</ul>\n",
142
143 "* List\n * Nested list\n # Nested header\n",
144 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
145 "<h1>Nested header</h1></li>\n</ul></li>\n</ul>\n",
146 }
147 doTestsBlock(t, tests, SpaceHeaders)
148}
149
150func TestPrefixHeaderIdExtension(t *testing.T) {
151 var tests = []string{
152 "# Header 1 {#someid}\n",
153 "<h1 id=\"someid\">Header 1</h1>\n",
154
155 "# Header 1 {#someid} \n",
156 "<h1 id=\"someid\">Header 1</h1>\n",
157
158 "# Header 1 {#someid}\n",
159 "<h1 id=\"someid\">Header 1</h1>\n",
160
161 "# Header 1 {#someid\n",
162 "<h1>Header 1 {#someid</h1>\n",
163
164 "# Header 1 {#someid\n",
165 "<h1>Header 1 {#someid</h1>\n",
166
167 "# Header 1 {#someid}}\n",
168 "<h1 id=\"someid\">Header 1</h1>\n\n<p>}</p>\n",
169
170 "## Header 2 {#someid}\n",
171 "<h2 id=\"someid\">Header 2</h2>\n",
172
173 "### Header 3 {#someid}\n",
174 "<h3 id=\"someid\">Header 3</h3>\n",
175
176 "#### Header 4 {#someid}\n",
177 "<h4 id=\"someid\">Header 4</h4>\n",
178
179 "##### Header 5 {#someid}\n",
180 "<h5 id=\"someid\">Header 5</h5>\n",
181
182 "###### Header 6 {#someid}\n",
183 "<h6 id=\"someid\">Header 6</h6>\n",
184
185 "####### Header 7 {#someid}\n",
186 "<h6 id=\"someid\"># Header 7</h6>\n",
187
188 "# Header 1 # {#someid}\n",
189 "<h1 id=\"someid\">Header 1</h1>\n",
190
191 "## Header 2 ## {#someid}\n",
192 "<h2 id=\"someid\">Header 2</h2>\n",
193
194 "Hello\n# Header 1\nGoodbye\n",
195 "<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
196
197 "* List\n# Header {#someid}\n* List\n",
198 "<ul>\n<li><p>List</p>\n\n<h1 id=\"someid\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
199
200 "* List\n#Header {#someid}\n* List\n",
201 "<ul>\n<li><p>List</p>\n\n<h1 id=\"someid\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
202
203 "* List\n * Nested list\n # Nested header {#someid}\n",
204 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
205 "<h1 id=\"someid\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
206 }
207 doTestsBlock(t, tests, HeaderIDs)
208}
209
210func TestPrefixHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
211 var tests = []string{
212 "# header 1 {#someid}\n",
213 "<h1 id=\"PRE:someid:POST\">header 1</h1>\n",
214
215 "## header 2 {#someid}\n",
216 "<h2 id=\"PRE:someid:POST\">header 2</h2>\n",
217
218 "### header 3 {#someid}\n",
219 "<h3 id=\"PRE:someid:POST\">header 3</h3>\n",
220
221 "#### header 4 {#someid}\n",
222 "<h4 id=\"PRE:someid:POST\">header 4</h4>\n",
223
224 "##### header 5 {#someid}\n",
225 "<h5 id=\"PRE:someid:POST\">header 5</h5>\n",
226
227 "###### header 6 {#someid}\n",
228 "<h6 id=\"PRE:someid:POST\">header 6</h6>\n",
229
230 "####### header 7 {#someid}\n",
231 "<h6 id=\"PRE:someid:POST\"># header 7</h6>\n",
232
233 "# header 1 # {#someid}\n",
234 "<h1 id=\"PRE:someid:POST\">header 1</h1>\n",
235
236 "## header 2 ## {#someid}\n",
237 "<h2 id=\"PRE:someid:POST\">header 2</h2>\n",
238
239 "* List\n# Header {#someid}\n* List\n",
240 "<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:someid:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
241
242 "* List\n#Header {#someid}\n* List\n",
243 "<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:someid:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
244
245 "* List\n * Nested list\n # Nested header {#someid}\n",
246 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
247 "<h1 id=\"PRE:someid:POST\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
248 }
249
250 parameters := HTMLRendererParameters{
251 HeaderIDPrefix: "PRE:",
252 HeaderIDSuffix: ":POST",
253 }
254
255 doTestsBlockWithRunner(t, tests, TestParams{
256 Options: Options{Extensions: HeaderIDs},
257 HTMLRendererParameters: parameters,
258 }, runMarkdownBlock)
259}
260
261func TestPrefixAutoHeaderIdExtension(t *testing.T) {
262 var tests = []string{
263 "# Header 1\n",
264 "<h1 id=\"header-1\">Header 1</h1>\n",
265
266 "# Header 1 \n",
267 "<h1 id=\"header-1\">Header 1</h1>\n",
268
269 "## Header 2\n",
270 "<h2 id=\"header-2\">Header 2</h2>\n",
271
272 "### Header 3\n",
273 "<h3 id=\"header-3\">Header 3</h3>\n",
274
275 "#### Header 4\n",
276 "<h4 id=\"header-4\">Header 4</h4>\n",
277
278 "##### Header 5\n",
279 "<h5 id=\"header-5\">Header 5</h5>\n",
280
281 "###### Header 6\n",
282 "<h6 id=\"header-6\">Header 6</h6>\n",
283
284 "####### Header 7\n",
285 "<h6 id=\"header-7\"># Header 7</h6>\n",
286
287 "Hello\n# Header 1\nGoodbye\n",
288 "<p>Hello</p>\n\n<h1 id=\"header-1\">Header 1</h1>\n\n<p>Goodbye</p>\n",
289
290 "* List\n# Header\n* List\n",
291 "<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
292
293 "* List\n#Header\n* List\n",
294 "<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
295
296 "* List\n * Nested list\n # Nested header\n",
297 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
298 "<h1 id=\"nested-header\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
299
300 "# Header\n\n# Header\n",
301 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n",
302
303 "# Header 1\n\n# Header 1",
304 "<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
305
306 "# Header\n\n# Header 1\n\n# Header\n\n# Header",
307 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header</h1>\n\n<h1 id=\"header-1-2\">Header</h1>\n",
308 }
309 doTestsBlock(t, tests, AutoHeaderIDs)
310}
311
312func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
313 var tests = []string{
314 "# Header 1\n",
315 "<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n",
316
317 "# Header 1 \n",
318 "<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n",
319
320 "## Header 2\n",
321 "<h2 id=\"PRE:header-2:POST\">Header 2</h2>\n",
322
323 "### Header 3\n",
324 "<h3 id=\"PRE:header-3:POST\">Header 3</h3>\n",
325
326 "#### Header 4\n",
327 "<h4 id=\"PRE:header-4:POST\">Header 4</h4>\n",
328
329 "##### Header 5\n",
330 "<h5 id=\"PRE:header-5:POST\">Header 5</h5>\n",
331
332 "###### Header 6\n",
333 "<h6 id=\"PRE:header-6:POST\">Header 6</h6>\n",
334
335 "####### Header 7\n",
336 "<h6 id=\"PRE:header-7:POST\"># Header 7</h6>\n",
337
338 "Hello\n# Header 1\nGoodbye\n",
339 "<p>Hello</p>\n\n<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<p>Goodbye</p>\n",
340
341 "* List\n# Header\n* List\n",
342 "<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:header:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
343
344 "* List\n#Header\n* List\n",
345 "<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:header:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
346
347 "* List\n * Nested list\n # Nested header\n",
348 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
349 "<h1 id=\"PRE:nested-header:POST\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
350
351 "# Header\n\n# Header\n",
352 "<h1 id=\"PRE:header:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1:POST\">Header</h1>\n",
353
354 "# Header 1\n\n# Header 1",
355 "<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<h1 id=\"PRE:header-1-1:POST\">Header 1</h1>\n",
356
357 "# Header\n\n# Header 1\n\n# Header\n\n# Header",
358 "<h1 id=\"PRE:header:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<h1 id=\"PRE:header-1-1:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1-2:POST\">Header</h1>\n",
359 }
360
361 parameters := HTMLRendererParameters{
362 HeaderIDPrefix: "PRE:",
363 HeaderIDSuffix: ":POST",
364 }
365
366 doTestsBlockWithRunner(t, tests, TestParams{
367 Options: Options{Extensions: AutoHeaderIDs},
368 HTMLRendererParameters: parameters,
369 }, runMarkdownBlock)
370}
371
372func TestPrefixMultipleHeaderExtensions(t *testing.T) {
373 var tests = []string{
374 "# Header\n\n# Header {#header}\n\n# Header 1",
375 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
376 }
377 doTestsBlock(t, tests, AutoHeaderIDs|HeaderIDs)
378}
379
380func TestUnderlineHeaders(t *testing.T) {
381 var tests = []string{
382 "Header 1\n========\n",
383 "<h1>Header 1</h1>\n",
384
385 "Header 2\n--------\n",
386 "<h2>Header 2</h2>\n",
387
388 "A\n=\n",
389 "<h1>A</h1>\n",
390
391 "B\n-\n",
392 "<h2>B</h2>\n",
393
394 "Paragraph\nHeader\n=\n",
395 "<p>Paragraph</p>\n\n<h1>Header</h1>\n",
396
397 "Header\n===\nParagraph\n",
398 "<h1>Header</h1>\n\n<p>Paragraph</p>\n",
399
400 "Header\n===\nAnother header\n---\n",
401 "<h1>Header</h1>\n\n<h2>Another header</h2>\n",
402
403 " Header\n======\n",
404 "<h1>Header</h1>\n",
405
406 " Code\n========\n",
407 "<pre><code>Code\n</code></pre>\n\n<p>========</p>\n",
408
409 "Header with *inline*\n=====\n",
410 "<h1>Header with <em>inline</em></h1>\n",
411
412 "* List\n * Sublist\n Not a header\n ------\n",
413 "<ul>\n<li>List\n\n<ul>\n<li>Sublist\nNot a header\n------</li>\n</ul></li>\n</ul>\n",
414
415 "Paragraph\n\n\n\n\nHeader\n===\n",
416 "<p>Paragraph</p>\n\n<h1>Header</h1>\n",
417
418 "Trailing space \n==== \n\n",
419 "<h1>Trailing space</h1>\n",
420
421 "Trailing spaces\n==== \n\n",
422 "<h1>Trailing spaces</h1>\n",
423
424 "Double underline\n=====\n=====\n",
425 "<h1>Double underline</h1>\n\n<p>=====</p>\n",
426 }
427 doTestsBlock(t, tests, 0)
428}
429
430func TestUnderlineHeadersAutoIDs(t *testing.T) {
431 var tests = []string{
432 "Header 1\n========\n",
433 "<h1 id=\"header-1\">Header 1</h1>\n",
434
435 "Header 2\n--------\n",
436 "<h2 id=\"header-2\">Header 2</h2>\n",
437
438 "A\n=\n",
439 "<h1 id=\"a\">A</h1>\n",
440
441 "B\n-\n",
442 "<h2 id=\"b\">B</h2>\n",
443
444 "Paragraph\nHeader\n=\n",
445 "<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n",
446
447 "Header\n===\nParagraph\n",
448 "<h1 id=\"header\">Header</h1>\n\n<p>Paragraph</p>\n",
449
450 "Header\n===\nAnother header\n---\n",
451 "<h1 id=\"header\">Header</h1>\n\n<h2 id=\"another-header\">Another header</h2>\n",
452
453 " Header\n======\n",
454 "<h1 id=\"header\">Header</h1>\n",
455
456 "Header with *inline*\n=====\n",
457 "<h1 id=\"header-with-inline\">Header with <em>inline</em></h1>\n",
458
459 "Paragraph\n\n\n\n\nHeader\n===\n",
460 "<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n",
461
462 "Trailing space \n==== \n\n",
463 "<h1 id=\"trailing-space\">Trailing space</h1>\n",
464
465 "Trailing spaces\n==== \n\n",
466 "<h1 id=\"trailing-spaces\">Trailing spaces</h1>\n",
467
468 "Double underline\n=====\n=====\n",
469 "<h1 id=\"double-underline\">Double underline</h1>\n\n<p>=====</p>\n",
470
471 "Header\n======\n\nHeader\n======\n",
472 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n",
473
474 "Header 1\n========\n\nHeader 1\n========\n",
475 "<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
476 }
477 doTestsBlock(t, tests, AutoHeaderIDs)
478}
479
480func TestHorizontalRule(t *testing.T) {
481 var tests = []string{
482 "-\n",
483 "<p>-</p>\n",
484
485 "--\n",
486 "<p>--</p>\n",
487
488 "---\n",
489 "<hr />\n",
490
491 "----\n",
492 "<hr />\n",
493
494 "*\n",
495 "<p>*</p>\n",
496
497 "**\n",
498 "<p>**</p>\n",
499
500 "***\n",
501 "<hr />\n",
502
503 "****\n",
504 "<hr />\n",
505
506 "_\n",
507 "<p>_</p>\n",
508
509 "__\n",
510 "<p>__</p>\n",
511
512 "___\n",
513 "<hr />\n",
514
515 "____\n",
516 "<hr />\n",
517
518 "-*-\n",
519 "<p>-*-</p>\n",
520
521 "- - -\n",
522 "<hr />\n",
523
524 "* * *\n",
525 "<hr />\n",
526
527 "_ _ _\n",
528 "<hr />\n",
529
530 "-----*\n",
531 "<p>-----*</p>\n",
532
533 " ------ \n",
534 "<hr />\n",
535
536 "Hello\n***\n",
537 "<p>Hello</p>\n\n<hr />\n",
538
539 "---\n***\n___\n",
540 "<hr />\n\n<hr />\n\n<hr />\n",
541 }
542 doTestsBlock(t, tests, 0)
543}
544
545func TestUnorderedList(t *testing.T) {
546 var tests = []string{
547 "* Hello\n",
548 "<ul>\n<li>Hello</li>\n</ul>\n",
549
550 "* Yin\n* Yang\n",
551 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
552
553 "* Ting\n* Bong\n* Goo\n",
554 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
555
556 "* Yin\n\n* Yang\n",
557 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
558
559 "* Ting\n\n* Bong\n* Goo\n",
560 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
561
562 "+ Hello\n",
563 "<ul>\n<li>Hello</li>\n</ul>\n",
564
565 "+ Yin\n+ Yang\n",
566 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
567
568 "+ Ting\n+ Bong\n+ Goo\n",
569 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
570
571 "+ Yin\n\n+ Yang\n",
572 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
573
574 "+ Ting\n\n+ Bong\n+ Goo\n",
575 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
576
577 "- Hello\n",
578 "<ul>\n<li>Hello</li>\n</ul>\n",
579
580 "- Yin\n- Yang\n",
581 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
582
583 "- Ting\n- Bong\n- Goo\n",
584 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
585
586 "- Yin\n\n- Yang\n",
587 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
588
589 "- Ting\n\n- Bong\n- Goo\n",
590 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
591
592 "*Hello\n",
593 "<p>*Hello</p>\n",
594
595 "* Hello \n",
596 "<ul>\n<li>Hello</li>\n</ul>\n",
597
598 "* Hello \n Next line \n",
599 "<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
600
601 "Paragraph\n* No linebreak\n",
602 "<p>Paragraph\n* No linebreak</p>\n",
603
604 "Paragraph\n\n* Linebreak\n",
605 "<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
606
607 "* List\n * Nested list\n",
608 "<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
609
610 "* List\n\n * Nested list\n",
611 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
612
613 "* List\n Second line\n\n + Nested\n",
614 "<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
615
616 "* List\n + Nested\n\n Continued\n",
617 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
618
619 "* List\n * shallow indent\n",
620 "<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
621
622 "* List\n" +
623 " * shallow indent\n" +
624 " * part of second list\n" +
625 " * still second\n" +
626 " * almost there\n" +
627 " * third level\n",
628 "<ul>\n" +
629 "<li>List\n\n" +
630 "<ul>\n" +
631 "<li>shallow indent</li>\n" +
632 "<li>part of second list</li>\n" +
633 "<li>still second</li>\n" +
634 "<li>almost there\n\n" +
635 "<ul>\n" +
636 "<li>third level</li>\n" +
637 "</ul></li>\n" +
638 "</ul></li>\n" +
639 "</ul>\n",
640
641 "* List\n extra indent, same paragraph\n",
642 "<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n",
643
644 "* List\n\n code block\n",
645 "<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
646
647 "* List\n\n code block with spaces\n",
648 "<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n",
649
650 "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
651 "<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",
652 }
653 doTestsBlock(t, tests, 0)
654}
655
656func TestOrderedList(t *testing.T) {
657 var tests = []string{
658 "1. Hello\n",
659 "<ol>\n<li>Hello</li>\n</ol>\n",
660
661 "1. Yin\n2. Yang\n",
662 "<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
663
664 "1. Ting\n2. Bong\n3. Goo\n",
665 "<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
666
667 "1. Yin\n\n2. Yang\n",
668 "<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
669
670 "1. Ting\n\n2. Bong\n3. Goo\n",
671 "<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
672
673 "1 Hello\n",
674 "<p>1 Hello</p>\n",
675
676 "1.Hello\n",
677 "<p>1.Hello</p>\n",
678
679 "1. Hello \n",
680 "<ol>\n<li>Hello</li>\n</ol>\n",
681
682 "1. Hello \n Next line \n",
683 "<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
684
685 "Paragraph\n1. No linebreak\n",
686 "<p>Paragraph\n1. No linebreak</p>\n",
687
688 "Paragraph\n\n1. Linebreak\n",
689 "<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
690
691 "1. List\n 1. Nested list\n",
692 "<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
693
694 "1. List\n\n 1. Nested list\n",
695 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
696
697 "1. List\n Second line\n\n 1. Nested\n",
698 "<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
699
700 "1. List\n 1. Nested\n\n Continued\n",
701 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
702
703 "1. List\n 1. shallow indent\n",
704 "<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
705
706 "1. List\n" +
707 " 1. shallow indent\n" +
708 " 2. part of second list\n" +
709 " 3. still second\n" +
710 " 4. almost there\n" +
711 " 1. third level\n",
712 "<ol>\n" +
713 "<li>List\n\n" +
714 "<ol>\n" +
715 "<li>shallow indent</li>\n" +
716 "<li>part of second list</li>\n" +
717 "<li>still second</li>\n" +
718 "<li>almost there\n\n" +
719 "<ol>\n" +
720 "<li>third level</li>\n" +
721 "</ol></li>\n" +
722 "</ol></li>\n" +
723 "</ol>\n",
724
725 "1. List\n extra indent, same paragraph\n",
726 "<ol>\n<li>List\n extra indent, same paragraph</li>\n</ol>\n",
727
728 "1. List\n\n code block\n",
729 "<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
730
731 "1. List\n\n code block with spaces\n",
732 "<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
733
734 "1. List\n * Mixted list\n",
735 "<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
736
737 "1. List\n * Mixed list\n",
738 "<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
739
740 "* Start with unordered\n 1. Ordered\n",
741 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
742
743 "* Start with unordered\n 1. Ordered\n",
744 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
745
746 "1. numbers\n1. are ignored\n",
747 "<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
748 }
749 doTestsBlock(t, tests, 0)
750}
751
752func TestDefinitionList(t *testing.T) {
753 var tests = []string{
754 "Term 1\n: Definition a\n",
755 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
756
757 "Term 1\n: Definition a \n",
758 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
759
760 "Term 1\n: Definition a\n: Definition b\n",
761 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n<dd>Definition b</dd>\n</dl>\n",
762
763 "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n",
764 "<dl>\n" +
765 "<dt>Term 1</dt>\n" +
766 "<dd>Definition a</dd>\n" +
767 "<dt>Term 2</dt>\n" +
768 "<dd>Definition b</dd>\n" +
769 "</dl>\n",
770
771 "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n\nTerm 3\n: Definition c\n",
772 "<dl>\n" +
773 "<dt>Term 1</dt>\n" +
774 "<dd>Definition a</dd>\n" +
775 "<dt>Term 2</dt>\n" +
776 "<dd>Definition b</dd>\n" +
777 "<dt>Term 3</dt>\n" +
778 "<dd>Definition c</dd>\n" +
779 "</dl>\n",
780
781 "Term 1\n: Definition a\n: Definition b\n\nTerm 2\n: Definition c\n",
782 "<dl>\n" +
783 "<dt>Term 1</dt>\n" +
784 "<dd>Definition a</dd>\n" +
785 "<dd>Definition b</dd>\n" +
786 "<dt>Term 2</dt>\n" +
787 "<dd>Definition c</dd>\n" +
788 "</dl>\n",
789
790 "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n",
791 "<dl>\n" +
792 "<dt>Term 1</dt>\n" +
793 "<dd><p>Definition a</p></dd>\n" +
794 "<dt>Term 2</dt>\n" +
795 "<dd><p>Definition b</p></dd>\n" +
796 "</dl>\n",
797
798 "Term 1\n\n: Definition a\n\n: Definition b\n\nTerm 2\n\n: Definition c\n",
799 "<dl>\n" +
800 "<dt>Term 1</dt>\n" +
801 "<dd><p>Definition a</p></dd>\n" +
802 "<dd><p>Definition b</p></dd>\n" +
803 "<dt>Term 2</dt>\n" +
804 "<dd><p>Definition c</p></dd>\n" +
805 "</dl>\n",
806
807 "Term 1\n: Definition a\nNext line\n",
808 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a\nNext line</dd>\n</dl>\n",
809
810 "Term 1\n: Definition a\n Next line\n",
811 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a\nNext line</dd>\n</dl>\n",
812
813 "Term 1\n: Definition a \n Next line \n",
814 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a\nNext line</dd>\n</dl>\n",
815
816 "Term 1\n: Definition a\nNext line\n\nTerm 2\n: Definition b",
817 "<dl>\n" +
818 "<dt>Term 1</dt>\n" +
819 "<dd>Definition a\nNext line</dd>\n" +
820 "<dt>Term 2</dt>\n" +
821 "<dd>Definition b</dd>\n" +
822 "</dl>\n",
823
824 "Term 1\n: Definition a\n",
825 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
826
827 "Term 1\n:Definition a\n",
828 "<p>Term 1\n:Definition a</p>\n",
829
830 "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n\nText 1",
831 "<dl>\n" +
832 "<dt>Term 1</dt>\n" +
833 "<dd><p>Definition a</p></dd>\n" +
834 "<dt>Term 2</dt>\n" +
835 "<dd><p>Definition b</p></dd>\n" +
836 "</dl>\n" +
837 "\n<p>Text 1</p>\n",
838
839 "Term 1\n\n: Definition a\n\nText 1\n\nTerm 2\n\n: Definition b\n\nText 2",
840 "<dl>\n" +
841 "<dt>Term 1</dt>\n" +
842 "<dd><p>Definition a</p></dd>\n" +
843 "</dl>\n" +
844 "\n<p>Text 1</p>\n" +
845 "\n<dl>\n" +
846 "<dt>Term 2</dt>\n" +
847 "<dd><p>Definition b</p></dd>\n" +
848 "</dl>\n" +
849 "\n<p>Text 2</p>\n",
850 }
851 doTestsBlock(t, tests, DefinitionLists)
852}
853
854func TestPreformattedHtml(t *testing.T) {
855 var tests = []string{
856 "<div></div>\n",
857 "<div></div>\n",
858
859 "<div>\n</div>\n",
860 "<div>\n</div>\n",
861
862 "<div>\n</div>\nParagraph\n",
863 "<p><div>\n</div>\nParagraph</p>\n",
864
865 "<div class=\"foo\">\n</div>\n",
866 "<div class=\"foo\">\n</div>\n",
867
868 "<div>\nAnything here\n</div>\n",
869 "<div>\nAnything here\n</div>\n",
870
871 "<div>\n Anything here\n</div>\n",
872 "<div>\n Anything here\n</div>\n",
873
874 "<div>\nAnything here\n </div>\n",
875 "<div>\nAnything here\n </div>\n",
876
877 "<div>\nThis is *not* &proceessed\n</div>\n",
878 "<div>\nThis is *not* &proceessed\n</div>\n",
879
880 "<faketag>\n Something\n</faketag>\n",
881 "<p><faketag>\n Something\n</faketag></p>\n",
882
883 "<div>\n Something here\n</divv>\n",
884 "<p><div>\n Something here\n</divv></p>\n",
885
886 "Paragraph\n<div>\nHere? >&<\n</div>\n",
887 "<p>Paragraph\n<div>\nHere? >&<\n</div></p>\n",
888
889 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
890 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
891
892 "Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
893 "<p>Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?</p>\n",
894
895 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
896 "<p>Paragraph</p>\n\n<p><div>\nHow about here? >&<\n</div>\nAnd here?</p>\n",
897
898 "Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
899 "<p>Paragraph\n<div>\nHere? >&<\n</div></p>\n\n<p>And here?</p>\n",
900
901 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
902 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
903 }
904 doTestsBlock(t, tests, 0)
905}
906
907func TestPreformattedHtmlLax(t *testing.T) {
908 var tests = []string{
909 "Paragraph\n<div>\nHere? >&<\n</div>\n",
910 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n",
911
912 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
913 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
914
915 "Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
916 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
917
918 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
919 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
920
921 "Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
922 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
923
924 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
925 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
926 }
927 doTestsBlock(t, tests, LaxHTMLBlocks)
928}
929
930func TestFencedCodeBlock(t *testing.T) {
931 var tests = []string{
932 "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
933 "<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
934
935 "``` c\n/* special & char < > \" escaping */\n```\n",
936 "<pre><code class=\"language-c\">/* special & char < > " escaping */\n</code></pre>\n",
937
938 "``` c\nno *inline* processing ~~of text~~\n```\n",
939 "<pre><code class=\"language-c\">no *inline* processing ~~of text~~\n</code></pre>\n",
940
941 "```\nNo language\n```\n",
942 "<pre><code>No language\n</code></pre>\n",
943
944 "``` {ocaml}\nlanguage in braces\n```\n",
945 "<pre><code class=\"language-ocaml\">language in braces\n</code></pre>\n",
946
947 "``` {ocaml} \nwith extra whitespace\n```\n",
948 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
949
950 "```{ ocaml }\nwith extra whitespace\n```\n",
951 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
952
953 "~ ~~ java\nWith whitespace\n~~~\n",
954 "<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
955
956 "~~\nonly two\n~~\n",
957 "<p>~~\nonly two\n~~</p>\n",
958
959 "```` python\nextra\n````\n",
960 "<pre><code class=\"language-python\">extra\n</code></pre>\n",
961
962 "~~~ perl\nthree to start, four to end\n~~~~\n",
963 "<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
964
965 "~~~~ perl\nfour to start, three to end\n~~~\n",
966 "<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
967
968 "~~~ bash\ntildes\n~~~\n",
969 "<pre><code class=\"language-bash\">tildes\n</code></pre>\n",
970
971 "``` lisp\nno ending\n",
972 "<p>``` lisp\nno ending</p>\n",
973
974 "~~~ lisp\nend with language\n~~~ lisp\n",
975 "<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
976
977 "```\nmismatched begin and end\n~~~\n",
978 "<p>```\nmismatched begin and end\n~~~</p>\n",
979
980 "~~~\nmismatched begin and end\n```\n",
981 "<p>~~~\nmismatched begin and end\n```</p>\n",
982
983 " ``` oz\nleading spaces\n```\n",
984 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
985
986 " ``` oz\nleading spaces\n ```\n",
987 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
988
989 " ``` oz\nleading spaces\n ```\n",
990 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
991
992 "``` oz\nleading spaces\n ```\n",
993 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
994
995 " ``` oz\nleading spaces\n ```\n",
996 "<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces\n ```</p>\n",
997
998 "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n",
999 "<p>Bla bla</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Bla Bla</p>\n",
1000
1001 "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nAnd some text after a fenced code block",
1002 "<p>Some text before a fenced code block</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>And some text after a fenced code block</p>\n",
1003
1004 "`",
1005 "<p>`</p>\n",
1006
1007 "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n\n``` oz\nmultiple code blocks work okay\n```\n\nBla Bla\n",
1008 "<p>Bla bla</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Bla Bla</p>\n\n<pre><code class=\"language-oz\">multiple code blocks work okay\n</code></pre>\n\n<p>Bla Bla</p>\n",
1009
1010 "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nSome text in between\n``` oz\nmultiple code blocks work okay\n```\nAnd some text after a fenced code block",
1011 "<p>Some text before a fenced code block</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Some text in between</p>\n\n<pre><code class=\"language-oz\">multiple code blocks work okay\n</code></pre>\n\n<p>And some text after a fenced code block</p>\n",
1012 }
1013 doTestsBlock(t, tests, FencedCode)
1014}
1015
1016func TestFencedCodeInsideBlockquotes(t *testing.T) {
1017 cat := func(s ...string) string { return strings.Join(s, "\n") }
1018 var tests = []string{
1019 cat("> ```go",
1020 "package moo",
1021 "",
1022 "```",
1023 ""),
1024 `<blockquote>
1025<pre><code class="language-go">package moo
1026
1027</code></pre>
1028</blockquote>
1029`,
1030 // -------------------------------------------
1031 cat("> foo",
1032 "> ",
1033 "> ```go",
1034 "package moo",
1035 "```",
1036 "> ",
1037 "> goo.",
1038 ""),
1039 `<blockquote>
1040<p>foo</p>
1041
1042<pre><code class="language-go">package moo
1043</code></pre>
1044
1045<p>goo.</p>
1046</blockquote>
1047`,
1048 // -------------------------------------------
1049 cat("> foo",
1050 "> ",
1051 "> quote",
1052 "continues",
1053 "```",
1054 ""),
1055 `<blockquote>
1056<p>foo</p>
1057
1058<p>quote
1059continues
1060` + "```" + `</p>
1061</blockquote>
1062`,
1063 // -------------------------------------------
1064 cat("> foo",
1065 "> ",
1066 "> ```go",
1067 "package moo",
1068 "```",
1069 "> ",
1070 "> goo.",
1071 "> ",
1072 "> ```go",
1073 "package zoo",
1074 "```",
1075 "> ",
1076 "> woo.",
1077 ""),
1078 `<blockquote>
1079<p>foo</p>
1080
1081<pre><code class="language-go">package moo
1082</code></pre>
1083
1084<p>goo.</p>
1085
1086<pre><code class="language-go">package zoo
1087</code></pre>
1088
1089<p>woo.</p>
1090</blockquote>
1091`,
1092 }
1093
1094 // These 2 alternative forms of blockquoted fenced code blocks should produce same output.
1095 forms := [2]string{
1096 cat("> plain quoted text",
1097 "> ```fenced",
1098 "code",
1099 " with leading single space correctly preserved",
1100 "okay",
1101 "```",
1102 "> rest of quoted text"),
1103 cat("> plain quoted text",
1104 "> ```fenced",
1105 "> code",
1106 "> with leading single space correctly preserved",
1107 "> okay",
1108 "> ```",
1109 "> rest of quoted text"),
1110 }
1111 want := `<blockquote>
1112<p>plain quoted text</p>
1113
1114<pre><code class="language-fenced">code
1115 with leading single space correctly preserved
1116okay
1117</code></pre>
1118
1119<p>rest of quoted text</p>
1120</blockquote>
1121`
1122 tests = append(tests, forms[0], want)
1123 tests = append(tests, forms[1], want)
1124
1125 doTestsBlock(t, tests, FencedCode)
1126}
1127
1128func TestTable(t *testing.T) {
1129 var tests = []string{
1130 "a | b\n---|---\nc | d\n",
1131 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n\n" +
1132 "<tbody>\n<tr>\n<td>c</td>\n<td>d</td>\n</tr>\n</tbody>\n</table>\n",
1133
1134 "a | b\n---|--\nc | d\n",
1135 "<p>a | b\n---|--\nc | d</p>\n",
1136
1137 "|a|b|c|d|\n|----|----|----|---|\n|e|f|g|h|\n",
1138 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
1139 "<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",
1140
1141 "*a*|__b__|[c](C)|d\n---|---|---|---\ne|f|g|h\n",
1142 "<table>\n<thead>\n<tr>\n<th><em>a</em></th>\n<th><strong>b</strong></th>\n<th><a href=\"C\">c</a></th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
1143 "<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",
1144
1145 "a|b|c\n---|---|---\nd|e|f\ng|h\ni|j|k|l|m\nn|o|p\n",
1146 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n" +
1147 "<tbody>\n<tr>\n<td>d</td>\n<td>e</td>\n<td>f</td>\n</tr>\n\n" +
1148 "<tr>\n<td>g</td>\n<td>h</td>\n<td></td>\n</tr>\n\n" +
1149 "<tr>\n<td>i</td>\n<td>j</td>\n<td>k</td>\n</tr>\n\n" +
1150 "<tr>\n<td>n</td>\n<td>o</td>\n<td>p</td>\n</tr>\n</tbody>\n</table>\n",
1151
1152 "a|b|c\n---|---|---\n*d*|__e__|f\n",
1153 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n" +
1154 "<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",
1155
1156 "a|b|c|d\n:--|--:|:-:|---\ne|f|g|h\n",
1157 "<table>\n<thead>\n<tr>\n<th align=\"left\">a</th>\n<th align=\"right\">b</th>\n" +
1158 "<th align=\"center\">c</th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
1159 "<tbody>\n<tr>\n<td align=\"left\">e</td>\n<td align=\"right\">f</td>\n" +
1160 "<td align=\"center\">g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
1161
1162 "a|b|c\n---|---|---\n",
1163 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n<tbody>\n</tbody>\n</table>\n",
1164
1165 "a| b|c | d | e\n---|---|---|---|---\nf| g|h | i |j\n",
1166 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n<th>d</th>\n<th>e</th>\n</tr>\n</thead>\n\n" +
1167 "<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",
1168
1169 "a|b\\|c|d\n---|---|---\nf|g\\|h|i\n",
1170 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b|c</th>\n<th>d</th>\n</tr>\n</thead>\n\n<tbody>\n<tr>\n<td>f</td>\n<td>g|h</td>\n<td>i</td>\n</tr>\n</tbody>\n</table>\n",
1171 }
1172 doTestsBlock(t, tests, Tables)
1173}
1174
1175func TestUnorderedListWith_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
1176 var tests = []string{
1177 "* Hello\n",
1178 "<ul>\n<li>Hello</li>\n</ul>\n",
1179
1180 "* Yin\n* Yang\n",
1181 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
1182
1183 "* Ting\n* Bong\n* Goo\n",
1184 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
1185
1186 "* Yin\n\n* Yang\n",
1187 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
1188
1189 "* Ting\n\n* Bong\n* Goo\n",
1190 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
1191
1192 "+ Hello\n",
1193 "<ul>\n<li>Hello</li>\n</ul>\n",
1194
1195 "+ Yin\n+ Yang\n",
1196 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
1197
1198 "+ Ting\n+ Bong\n+ Goo\n",
1199 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
1200
1201 "+ Yin\n\n+ Yang\n",
1202 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
1203
1204 "+ Ting\n\n+ Bong\n+ Goo\n",
1205 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
1206
1207 "- Hello\n",
1208 "<ul>\n<li>Hello</li>\n</ul>\n",
1209
1210 "- Yin\n- Yang\n",
1211 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
1212
1213 "- Ting\n- Bong\n- Goo\n",
1214 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
1215
1216 "- Yin\n\n- Yang\n",
1217 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
1218
1219 "- Ting\n\n- Bong\n- Goo\n",
1220 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
1221
1222 "*Hello\n",
1223 "<p>*Hello</p>\n",
1224
1225 "* Hello \n",
1226 "<ul>\n<li>Hello</li>\n</ul>\n",
1227
1228 "* Hello \n Next line \n",
1229 "<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
1230
1231 "Paragraph\n* No linebreak\n",
1232 "<p>Paragraph</p>\n\n<ul>\n<li>No linebreak</li>\n</ul>\n",
1233
1234 "Paragraph\n\n* Linebreak\n",
1235 "<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
1236
1237 "* List\n * Nested list\n",
1238 "<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
1239
1240 "* List\n\n * Nested list\n",
1241 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
1242
1243 "* List\n Second line\n\n + Nested\n",
1244 "<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
1245
1246 "* List\n + Nested\n\n Continued\n",
1247 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
1248
1249 "* List\n * shallow indent\n",
1250 "<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
1251
1252 "* List\n" +
1253 " * shallow indent\n" +
1254 " * part of second list\n" +
1255 " * still second\n" +
1256 " * almost there\n" +
1257 " * third level\n",
1258 "<ul>\n" +
1259 "<li>List\n\n" +
1260 "<ul>\n" +
1261 "<li>shallow indent</li>\n" +
1262 "<li>part of second list</li>\n" +
1263 "<li>still second</li>\n" +
1264 "<li>almost there\n\n" +
1265 "<ul>\n" +
1266 "<li>third level</li>\n" +
1267 "</ul></li>\n" +
1268 "</ul></li>\n" +
1269 "</ul>\n",
1270
1271 "* List\n extra indent, same paragraph\n",
1272 "<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n",
1273
1274 "* List\n\n code block\n",
1275 "<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
1276
1277 "* List\n\n code block with spaces\n",
1278 "<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n",
1279
1280 "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
1281 "<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",
1282 }
1283 doTestsBlock(t, tests, NoEmptyLineBeforeBlock)
1284}
1285
1286func TestOrderedList_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
1287 var tests = []string{
1288 "1. Hello\n",
1289 "<ol>\n<li>Hello</li>\n</ol>\n",
1290
1291 "1. Yin\n2. Yang\n",
1292 "<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
1293
1294 "1. Ting\n2. Bong\n3. Goo\n",
1295 "<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
1296
1297 "1. Yin\n\n2. Yang\n",
1298 "<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
1299
1300 "1. Ting\n\n2. Bong\n3. Goo\n",
1301 "<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
1302
1303 "1 Hello\n",
1304 "<p>1 Hello</p>\n",
1305
1306 "1.Hello\n",
1307 "<p>1.Hello</p>\n",
1308
1309 "1. Hello \n",
1310 "<ol>\n<li>Hello</li>\n</ol>\n",
1311
1312 "1. Hello \n Next line \n",
1313 "<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
1314
1315 "Paragraph\n1. No linebreak\n",
1316 "<p>Paragraph</p>\n\n<ol>\n<li>No linebreak</li>\n</ol>\n",
1317
1318 "Paragraph\n\n1. Linebreak\n",
1319 "<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
1320
1321 "1. List\n 1. Nested list\n",
1322 "<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
1323
1324 "1. List\n\n 1. Nested list\n",
1325 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
1326
1327 "1. List\n Second line\n\n 1. Nested\n",
1328 "<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
1329
1330 "1. List\n 1. Nested\n\n Continued\n",
1331 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
1332
1333 "1. List\n 1. shallow indent\n",
1334 "<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
1335
1336 "1. List\n" +
1337 " 1. shallow indent\n" +
1338 " 2. part of second list\n" +
1339 " 3. still second\n" +
1340 " 4. almost there\n" +
1341 " 1. third level\n",
1342 "<ol>\n" +
1343 "<li>List\n\n" +
1344 "<ol>\n" +
1345 "<li>shallow indent</li>\n" +
1346 "<li>part of second list</li>\n" +
1347 "<li>still second</li>\n" +
1348 "<li>almost there\n\n" +
1349 "<ol>\n" +
1350 "<li>third level</li>\n" +
1351 "</ol></li>\n" +
1352 "</ol></li>\n" +
1353 "</ol>\n",
1354
1355 "1. List\n extra indent, same paragraph\n",
1356 "<ol>\n<li>List\n extra indent, same paragraph</li>\n</ol>\n",
1357
1358 "1. List\n\n code block\n",
1359 "<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
1360
1361 "1. List\n\n code block with spaces\n",
1362 "<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
1363
1364 "1. List\n * Mixted list\n",
1365 "<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
1366
1367 "1. List\n * Mixed list\n",
1368 "<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
1369
1370 "* Start with unordered\n 1. Ordered\n",
1371 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
1372
1373 "* Start with unordered\n 1. Ordered\n",
1374 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
1375
1376 "1. numbers\n1. are ignored\n",
1377 "<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
1378 }
1379 doTestsBlock(t, tests, NoEmptyLineBeforeBlock)
1380}
1381
1382func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
1383 var tests = []string{
1384 "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
1385 "<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
1386
1387 "``` c\n/* special & char < > \" escaping */\n```\n",
1388 "<pre><code class=\"language-c\">/* special & char < > " escaping */\n</code></pre>\n",
1389
1390 "``` c\nno *inline* processing ~~of text~~\n```\n",
1391 "<pre><code class=\"language-c\">no *inline* processing ~~of text~~\n</code></pre>\n",
1392
1393 "```\nNo language\n```\n",
1394 "<pre><code>No language\n</code></pre>\n",
1395
1396 "``` {ocaml}\nlanguage in braces\n```\n",
1397 "<pre><code class=\"language-ocaml\">language in braces\n</code></pre>\n",
1398
1399 "``` {ocaml} \nwith extra whitespace\n```\n",
1400 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
1401
1402 "```{ ocaml }\nwith extra whitespace\n```\n",
1403 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
1404
1405 "~ ~~ java\nWith whitespace\n~~~\n",
1406 "<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
1407
1408 "~~\nonly two\n~~\n",
1409 "<p>~~\nonly two\n~~</p>\n",
1410
1411 "```` python\nextra\n````\n",
1412 "<pre><code class=\"language-python\">extra\n</code></pre>\n",
1413
1414 "~~~ perl\nthree to start, four to end\n~~~~\n",
1415 "<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
1416
1417 "~~~~ perl\nfour to start, three to end\n~~~\n",
1418 "<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
1419
1420 "~~~ bash\ntildes\n~~~\n",
1421 "<pre><code class=\"language-bash\">tildes\n</code></pre>\n",
1422
1423 "``` lisp\nno ending\n",
1424 "<p>``` lisp\nno ending</p>\n",
1425
1426 "~~~ lisp\nend with language\n~~~ lisp\n",
1427 "<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
1428
1429 "```\nmismatched begin and end\n~~~\n",
1430 "<p>```\nmismatched begin and end\n~~~</p>\n",
1431
1432 "~~~\nmismatched begin and end\n```\n",
1433 "<p>~~~\nmismatched begin and end\n```</p>\n",
1434
1435 " ``` oz\nleading spaces\n```\n",
1436 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1437
1438 " ``` oz\nleading spaces\n ```\n",
1439 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1440
1441 " ``` oz\nleading spaces\n ```\n",
1442 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1443
1444 "``` oz\nleading spaces\n ```\n",
1445 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1446
1447 " ``` oz\nleading spaces\n ```\n",
1448 "<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces</p>\n\n<pre><code>```\n</code></pre>\n",
1449 }
1450 doTestsBlock(t, tests, FencedCode|NoEmptyLineBeforeBlock)
1451}
1452
1453func TestTitleBlock_EXTENSION_TITLEBLOCK(t *testing.T) {
1454 var tests = []string{
1455 "% Some title\n" +
1456 "% Another title line\n" +
1457 "% Yep, more here too\n",
1458 "<h1 class=\"title\">" +
1459 "Some title\n" +
1460 "Another title line\n" +
1461 "Yep, more here too" +
1462 "</h1>\n",
1463 }
1464 doTestsBlock(t, tests, Titleblock)
1465}
1466
1467func TestBlockComments(t *testing.T) {
1468 var tests = []string{
1469 "Some text\n\n<!-- comment -->\n",
1470 "<p>Some text</p>\n\n<!-- comment -->\n",
1471
1472 "Some text\n\n<!--\n\nmultiline\ncomment\n-->\n",
1473 "<p>Some text</p>\n\n<!--\n\nmultiline\ncomment\n-->\n",
1474
1475 "Some text\n\n<!--\n\n<div><p>Commented</p>\n<span>html</span></div>\n-->\n",
1476 "<p>Some text</p>\n\n<!--\n\n<div><p>Commented</p>\n<span>html</span></div>\n-->\n",
1477 }
1478 doTestsBlock(t, tests, 0)
1479}
1480
1481func TestTOC(t *testing.T) {
1482 var tests = []string{
1483 "# Title\n\n##Subtitle1\n\n##Subtitle2",
1484 //"<nav>\n<ul>\n<li><a href=\"#toc_0\">Title</a>\n<ul>\n<li><a href=\"#toc_1\">Subtitle1</a></li>\n<li><a href=\"#toc_2\">Subtitle2</a></li>\n</ul></li>\n</ul>\n</nav>\n\n<h1 id=\"toc_0\">Title</h1>\n\n<h2 id=\"toc_1\">Subtitle1</h2>\n\n<h2 id=\"toc_2\">Subtitle2</h2>\n",
1485 `<nav>
1486
1487<ul>
1488<li><a href="#toc_0">Title</a>
1489<ul>
1490<li><a href="#toc_1">Subtitle1</a></li>
1491
1492<li><a href="#toc_2">Subtitle2</a></li>
1493</ul></li>
1494</ul>
1495
1496</nav>
1497
1498<h1 id="toc_0">Title</h1>
1499
1500<h2 id="toc_1">Subtitle1</h2>
1501
1502<h2 id="toc_2">Subtitle2</h2>
1503`,
1504
1505 "# Title\n\n##Subtitle\n\n#Title2",
1506 //"<nav>\n<ul>\n<li><a href=\"#toc_0\">Title</a>\n<ul>\n<li><a href=\"#toc_1\">Subtitle</a></li>\n</ul></li>\n<li><a href=\"#toc_2\">Title2</a></li>\n</ul>\n</nav>\n\n<h1 id=\"toc_0\">Title</h1>\n\n<h2 id=\"toc_1\">Subtitle</h2>\n\n<h1 id=\"toc_2\">Title2</h1>\n",
1507 `<nav>
1508
1509<ul>
1510<li><a href="#toc_0">Title</a>
1511<ul>
1512<li><a href="#toc_1">Subtitle</a></li>
1513</ul></li>
1514
1515<li><a href="#toc_2">Title2</a></li>
1516</ul>
1517
1518</nav>
1519
1520<h1 id="toc_0">Title</h1>
1521
1522<h2 id="toc_1">Subtitle</h2>
1523
1524<h1 id="toc_2">Title2</h1>
1525`,
1526
1527 // Trigger empty TOC
1528 "#",
1529 "",
1530 }
1531 doTestsBlock(t, tests, TOC)
1532}
1533
1534func TestOmitContents(t *testing.T) {
1535 var tests = []string{
1536 "# Title\n\n##Subtitle\n\n#Title2",
1537 `<nav>
1538
1539<ul>
1540<li><a href="#toc_0">Title</a>
1541<ul>
1542<li><a href="#toc_1">Subtitle</a></li>
1543</ul></li>
1544
1545<li><a href="#toc_2">Title2</a></li>
1546</ul>
1547
1548</nav>
1549`,
1550
1551 // Make sure OmitContents omits even with no TOC
1552 "#\n\nfoo",
1553 "",
1554 }
1555 doTestsBlock(t, tests, TOC|OmitContents)
1556 // Now run again: make sure OmitContents implies TOC
1557 doTestsBlock(t, tests, OmitContents)
1558}