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