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, SpaceHeadings)
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, HeadingIDs)
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 HeadingIDPrefix: "PRE:",
252 HeadingIDSuffix: ":POST",
253 }
254
255 doTestsParam(t, tests, TestParams{
256 extensions: HeadingIDs,
257 HTMLFlags: UseXHTML,
258 HTMLRendererParameters: parameters,
259 })
260}
261
262func TestPrefixAutoHeaderIdExtension(t *testing.T) {
263 var tests = []string{
264 "# Header 1\n",
265 "<h1 id=\"header-1\">Header 1</h1>\n",
266
267 "# Header 1 \n",
268 "<h1 id=\"header-1\">Header 1</h1>\n",
269
270 "## Header 2\n",
271 "<h2 id=\"header-2\">Header 2</h2>\n",
272
273 "### Header 3\n",
274 "<h3 id=\"header-3\">Header 3</h3>\n",
275
276 "#### Header 4\n",
277 "<h4 id=\"header-4\">Header 4</h4>\n",
278
279 "##### Header 5\n",
280 "<h5 id=\"header-5\">Header 5</h5>\n",
281
282 "###### Header 6\n",
283 "<h6 id=\"header-6\">Header 6</h6>\n",
284
285 "####### Header 7\n",
286 "<h6 id=\"header-7\"># Header 7</h6>\n",
287
288 "Hello\n# Header 1\nGoodbye\n",
289 "<p>Hello</p>\n\n<h1 id=\"header-1\">Header 1</h1>\n\n<p>Goodbye</p>\n",
290
291 "* List\n# Header\n* List\n",
292 "<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
293
294 "* List\n#Header\n* List\n",
295 "<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
296
297 "* List\n * Nested list\n # Nested header\n",
298 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
299 "<h1 id=\"nested-header\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
300
301 "# Header\n\n# Header\n",
302 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n",
303
304 "# Header 1\n\n# Header 1",
305 "<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
306
307 "# Header\n\n# Header 1\n\n# Header\n\n# Header",
308 "<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",
309 }
310 doTestsBlock(t, tests, AutoHeadingIDs)
311}
312
313func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
314 var tests = []string{
315 "# Header 1\n",
316 "<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n",
317
318 "# Header 1 \n",
319 "<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n",
320
321 "## Header 2\n",
322 "<h2 id=\"PRE:header-2:POST\">Header 2</h2>\n",
323
324 "### Header 3\n",
325 "<h3 id=\"PRE:header-3:POST\">Header 3</h3>\n",
326
327 "#### Header 4\n",
328 "<h4 id=\"PRE:header-4:POST\">Header 4</h4>\n",
329
330 "##### Header 5\n",
331 "<h5 id=\"PRE:header-5:POST\">Header 5</h5>\n",
332
333 "###### Header 6\n",
334 "<h6 id=\"PRE:header-6:POST\">Header 6</h6>\n",
335
336 "####### Header 7\n",
337 "<h6 id=\"PRE:header-7:POST\"># Header 7</h6>\n",
338
339 "Hello\n# Header 1\nGoodbye\n",
340 "<p>Hello</p>\n\n<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<p>Goodbye</p>\n",
341
342 "* List\n# Header\n* List\n",
343 "<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",
344
345 "* List\n#Header\n* List\n",
346 "<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",
347
348 "* List\n * Nested list\n # Nested header\n",
349 "<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
350 "<h1 id=\"PRE:nested-header:POST\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
351
352 "# Header\n\n# Header\n",
353 "<h1 id=\"PRE:header:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1:POST\">Header</h1>\n",
354
355 "# Header 1\n\n# Header 1",
356 "<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<h1 id=\"PRE:header-1-1:POST\">Header 1</h1>\n",
357
358 "# Header\n\n# Header 1\n\n# Header\n\n# Header",
359 "<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",
360 }
361
362 parameters := HTMLRendererParameters{
363 HeadingIDPrefix: "PRE:",
364 HeadingIDSuffix: ":POST",
365 }
366
367 doTestsParam(t, tests, TestParams{
368 extensions: AutoHeadingIDs,
369 HTMLFlags: UseXHTML,
370 HTMLRendererParameters: parameters,
371 })
372}
373
374func TestPrefixHeaderLevelOffset(t *testing.T) {
375 var offsetTests = []struct {
376 offset int
377 tests []string
378 }{{
379 offset: 0,
380 tests: []string{
381 "# Header 1\n",
382 "<h1>Header 1</h1>\n",
383
384 "## Header 2\n",
385 "<h2>Header 2</h2>\n",
386
387 "### Header 3\n",
388 "<h3>Header 3</h3>\n",
389
390 "#### Header 4\n",
391 "<h4>Header 4</h4>\n",
392
393 "##### Header 5\n",
394 "<h5>Header 5</h5>\n",
395
396 "###### Header 6\n",
397 "<h6>Header 6</h6>\n",
398
399 "####### Header 7\n",
400 "<h6># Header 7</h6>\n",
401 },
402 }, {
403 offset: 1,
404 tests: []string{
405 "# Header 1\n",
406 "<h2>Header 1</h2>\n",
407
408 "## Header 2\n",
409 "<h3>Header 2</h3>\n",
410
411 "### Header 3\n",
412 "<h4>Header 3</h4>\n",
413
414 "#### Header 4\n",
415 "<h5>Header 4</h5>\n",
416
417 "##### Header 5\n",
418 "<h6>Header 5</h6>\n",
419
420 "###### Header 6\n",
421 "<h6>Header 6</h6>\n",
422
423 "####### Header 7\n",
424 "<h6># Header 7</h6>\n",
425 },
426 }, {
427 offset: -1,
428 tests: []string{
429 "# Header 1\n",
430 "<h1>Header 1</h1>\n",
431
432 "## Header 2\n",
433 "<h1>Header 2</h1>\n",
434
435 "### Header 3\n",
436 "<h2>Header 3</h2>\n",
437
438 "#### Header 4\n",
439 "<h3>Header 4</h3>\n",
440
441 "##### Header 5\n",
442 "<h4>Header 5</h4>\n",
443
444 "###### Header 6\n",
445 "<h5>Header 6</h5>\n",
446
447 "####### Header 7\n",
448 "<h5># Header 7</h5>\n",
449 },
450 }}
451 for _, offsetTest := range offsetTests {
452 offset := offsetTest.offset
453 tests := offsetTest.tests
454 doTestsParam(t, tests, TestParams{
455 HTMLRendererParameters: HTMLRendererParameters{HeadingLevelOffset: offset},
456 })
457 }
458}
459
460func TestPrefixMultipleHeaderExtensions(t *testing.T) {
461 var tests = []string{
462 "# Header\n\n# Header {#header}\n\n# Header 1",
463 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
464 }
465 doTestsBlock(t, tests, AutoHeadingIDs|HeadingIDs)
466}
467
468func TestUnderlineHeaders(t *testing.T) {
469 var tests = []string{
470 "Header 1\n========\n",
471 "<h1>Header 1</h1>\n",
472
473 "Header 2\n--------\n",
474 "<h2>Header 2</h2>\n",
475
476 "A\n=\n",
477 "<h1>A</h1>\n",
478
479 "B\n-\n",
480 "<h2>B</h2>\n",
481
482 "Paragraph\nHeader\n=\n",
483 "<p>Paragraph</p>\n\n<h1>Header</h1>\n",
484
485 "Header\n===\nParagraph\n",
486 "<h1>Header</h1>\n\n<p>Paragraph</p>\n",
487
488 "Header\n===\nAnother header\n---\n",
489 "<h1>Header</h1>\n\n<h2>Another header</h2>\n",
490
491 " Header\n======\n",
492 "<h1>Header</h1>\n",
493
494 " Code\n========\n",
495 "<pre><code>Code\n</code></pre>\n\n<p>========</p>\n",
496
497 "Header with *inline*\n=====\n",
498 "<h1>Header with <em>inline</em></h1>\n",
499
500 "* List\n * Sublist\n Not a header\n ------\n",
501 "<ul>\n<li>List\n\n<ul>\n<li>Sublist\nNot a header\n------</li>\n</ul></li>\n</ul>\n",
502
503 "Paragraph\n\n\n\n\nHeader\n===\n",
504 "<p>Paragraph</p>\n\n<h1>Header</h1>\n",
505
506 "Trailing space \n==== \n\n",
507 "<h1>Trailing space</h1>\n",
508
509 "Trailing spaces\n==== \n\n",
510 "<h1>Trailing spaces</h1>\n",
511
512 "Double underline\n=====\n=====\n",
513 "<h1>Double underline</h1>\n\n<p>=====</p>\n",
514 }
515 doTestsBlock(t, tests, 0)
516}
517
518func TestUnderlineHeadersAutoIDs(t *testing.T) {
519 var tests = []string{
520 "Header 1\n========\n",
521 "<h1 id=\"header-1\">Header 1</h1>\n",
522
523 "Header 2\n--------\n",
524 "<h2 id=\"header-2\">Header 2</h2>\n",
525
526 "A\n=\n",
527 "<h1 id=\"a\">A</h1>\n",
528
529 "B\n-\n",
530 "<h2 id=\"b\">B</h2>\n",
531
532 "Paragraph\nHeader\n=\n",
533 "<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n",
534
535 "Header\n===\nParagraph\n",
536 "<h1 id=\"header\">Header</h1>\n\n<p>Paragraph</p>\n",
537
538 "Header\n===\nAnother header\n---\n",
539 "<h1 id=\"header\">Header</h1>\n\n<h2 id=\"another-header\">Another header</h2>\n",
540
541 " Header\n======\n",
542 "<h1 id=\"header\">Header</h1>\n",
543
544 "Header with *inline*\n=====\n",
545 "<h1 id=\"header-with-inline\">Header with <em>inline</em></h1>\n",
546
547 "Paragraph\n\n\n\n\nHeader\n===\n",
548 "<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n",
549
550 "Trailing space \n==== \n\n",
551 "<h1 id=\"trailing-space\">Trailing space</h1>\n",
552
553 "Trailing spaces\n==== \n\n",
554 "<h1 id=\"trailing-spaces\">Trailing spaces</h1>\n",
555
556 "Double underline\n=====\n=====\n",
557 "<h1 id=\"double-underline\">Double underline</h1>\n\n<p>=====</p>\n",
558
559 "Header\n======\n\nHeader\n======\n",
560 "<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n",
561
562 "Header 1\n========\n\nHeader 1\n========\n",
563 "<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
564 }
565 doTestsBlock(t, tests, AutoHeadingIDs)
566}
567
568func TestHorizontalRule(t *testing.T) {
569 var tests = []string{
570 "-\n",
571 "<p>-</p>\n",
572
573 "--\n",
574 "<p>--</p>\n",
575
576 "---\n",
577 "<hr />\n",
578
579 "----\n",
580 "<hr />\n",
581
582 "*\n",
583 "<p>*</p>\n",
584
585 "**\n",
586 "<p>**</p>\n",
587
588 "***\n",
589 "<hr />\n",
590
591 "****\n",
592 "<hr />\n",
593
594 "_\n",
595 "<p>_</p>\n",
596
597 "__\n",
598 "<p>__</p>\n",
599
600 "___\n",
601 "<hr />\n",
602
603 "____\n",
604 "<hr />\n",
605
606 "-*-\n",
607 "<p>-*-</p>\n",
608
609 "- - -\n",
610 "<hr />\n",
611
612 "* * *\n",
613 "<hr />\n",
614
615 "_ _ _\n",
616 "<hr />\n",
617
618 "-----*\n",
619 "<p>-----*</p>\n",
620
621 " ------ \n",
622 "<hr />\n",
623
624 "Hello\n***\n",
625 "<p>Hello</p>\n\n<hr />\n",
626
627 "---\n***\n___\n",
628 "<hr />\n\n<hr />\n\n<hr />\n",
629 }
630 doTestsBlock(t, tests, 0)
631}
632
633func TestUnorderedList(t *testing.T) {
634 var tests = []string{
635 "* Hello\n",
636 "<ul>\n<li>Hello</li>\n</ul>\n",
637
638 "* Yin\n* Yang\n",
639 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
640
641 "* Ting\n* Bong\n* Goo\n",
642 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
643
644 "* Yin\n\n* Yang\n",
645 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
646
647 "* Ting\n\n* Bong\n* Goo\n",
648 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
649
650 "+ Hello\n",
651 "<ul>\n<li>Hello</li>\n</ul>\n",
652
653 "+ Yin\n+ Yang\n",
654 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
655
656 "+ Ting\n+ Bong\n+ Goo\n",
657 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
658
659 "+ Yin\n\n+ Yang\n",
660 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
661
662 "+ Ting\n\n+ Bong\n+ Goo\n",
663 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
664
665 "- Hello\n",
666 "<ul>\n<li>Hello</li>\n</ul>\n",
667
668 "- Yin\n- Yang\n",
669 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
670
671 "- Ting\n- Bong\n- Goo\n",
672 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
673
674 "- Yin\n\n- Yang\n",
675 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
676
677 "- Ting\n\n- Bong\n- Goo\n",
678 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
679
680 "*Hello\n",
681 "<p>*Hello</p>\n",
682
683 "* Hello \n",
684 "<ul>\n<li>Hello</li>\n</ul>\n",
685
686 "* Hello \n Next line \n",
687 "<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
688
689 "Paragraph\n* No linebreak\n",
690 "<p>Paragraph\n* No linebreak</p>\n",
691
692 "Paragraph\n\n* Linebreak\n",
693 "<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
694
695 "* List\n * Nested list\n",
696 "<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
697
698 "* List\n\n * Nested list\n",
699 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
700
701 "* List\n Second line\n\n + Nested\n",
702 "<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
703
704 "* List\n + Nested\n\n Continued\n",
705 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
706
707 "* List\n * shallow indent\n",
708 "<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
709
710 "* List\n" +
711 " * shallow indent\n" +
712 " * part of second list\n" +
713 " * still second\n" +
714 " * almost there\n" +
715 " * third level\n",
716 "<ul>\n" +
717 "<li>List\n\n" +
718 "<ul>\n" +
719 "<li>shallow indent</li>\n" +
720 "<li>part of second list</li>\n" +
721 "<li>still second</li>\n" +
722 "<li>almost there\n\n" +
723 "<ul>\n" +
724 "<li>third level</li>\n" +
725 "</ul></li>\n" +
726 "</ul></li>\n" +
727 "</ul>\n",
728
729 "* List\n extra indent, same paragraph\n",
730 "<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n",
731
732 "* List\n\n code block\n",
733 "<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
734
735 "* List\n\n code block with spaces\n",
736 "<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n",
737
738 "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
739 "<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",
740 }
741 doTestsBlock(t, tests, 0)
742}
743
744func TestOrderedList(t *testing.T) {
745 var tests = []string{
746 "1. Hello\n",
747 "<ol>\n<li>Hello</li>\n</ol>\n",
748
749 "1. Yin\n2. Yang\n",
750 "<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
751
752 "1. Ting\n2. Bong\n3. Goo\n",
753 "<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
754
755 "1. Yin\n\n2. Yang\n",
756 "<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
757
758 "1. Ting\n\n2. Bong\n3. Goo\n",
759 "<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
760
761 "1 Hello\n",
762 "<p>1 Hello</p>\n",
763
764 "1.Hello\n",
765 "<p>1.Hello</p>\n",
766
767 "1. Hello \n",
768 "<ol>\n<li>Hello</li>\n</ol>\n",
769
770 "1. Hello \n Next line \n",
771 "<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
772
773 "Paragraph\n1. No linebreak\n",
774 "<p>Paragraph\n1. No linebreak</p>\n",
775
776 "Paragraph\n\n1. Linebreak\n",
777 "<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
778
779 "1. List\n 1. Nested list\n",
780 "<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
781
782 "1. List\n\n 1. Nested list\n",
783 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
784
785 "1. List\n Second line\n\n 1. Nested\n",
786 "<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
787
788 "1. List\n 1. Nested\n\n Continued\n",
789 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
790
791 "1. List\n 1. shallow indent\n",
792 "<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
793
794 "1. List\n" +
795 " 1. shallow indent\n" +
796 " 2. part of second list\n" +
797 " 3. still second\n" +
798 " 4. almost there\n" +
799 " 1. third level\n",
800 "<ol>\n" +
801 "<li>List\n\n" +
802 "<ol>\n" +
803 "<li>shallow indent</li>\n" +
804 "<li>part of second list</li>\n" +
805 "<li>still second</li>\n" +
806 "<li>almost there\n\n" +
807 "<ol>\n" +
808 "<li>third level</li>\n" +
809 "</ol></li>\n" +
810 "</ol></li>\n" +
811 "</ol>\n",
812
813 "1. List\n extra indent, same paragraph\n",
814 "<ol>\n<li>List\n extra indent, same paragraph</li>\n</ol>\n",
815
816 "1. List\n\n code block\n",
817 "<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
818
819 "1. List\n\n code block with spaces\n",
820 "<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
821
822 "1. List\n * Mixted list\n",
823 "<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
824
825 "1. List\n * Mixed list\n",
826 "<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
827
828 "* Start with unordered\n 1. Ordered\n",
829 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
830
831 "* Start with unordered\n 1. Ordered\n",
832 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
833
834 "1. numbers\n1. are ignored\n",
835 "<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
836 }
837 doTestsBlock(t, tests, 0)
838}
839
840func TestDefinitionList(t *testing.T) {
841 var tests = []string{
842 "Term 1\n: Definition a\n",
843 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
844
845 "Term 1\n: Definition a \n",
846 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
847
848 "Term 1\n: Definition a\n: Definition b\n",
849 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n<dd>Definition b</dd>\n</dl>\n",
850
851 "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n",
852 "<dl>\n" +
853 "<dt>Term 1</dt>\n" +
854 "<dd>Definition a</dd>\n" +
855 "<dt>Term 2</dt>\n" +
856 "<dd>Definition b</dd>\n" +
857 "</dl>\n",
858
859 "Term 1\n: Definition a\n\nTerm 2\n: Definition b\n\nTerm 3\n: Definition c\n",
860 "<dl>\n" +
861 "<dt>Term 1</dt>\n" +
862 "<dd>Definition a</dd>\n" +
863 "<dt>Term 2</dt>\n" +
864 "<dd>Definition b</dd>\n" +
865 "<dt>Term 3</dt>\n" +
866 "<dd>Definition c</dd>\n" +
867 "</dl>\n",
868
869 "Term 1\n: Definition a\n: Definition b\n\nTerm 2\n: Definition c\n",
870 "<dl>\n" +
871 "<dt>Term 1</dt>\n" +
872 "<dd>Definition a</dd>\n" +
873 "<dd>Definition b</dd>\n" +
874 "<dt>Term 2</dt>\n" +
875 "<dd>Definition c</dd>\n" +
876 "</dl>\n",
877
878 "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n",
879 "<dl>\n" +
880 "<dt>Term 1</dt>\n" +
881 "<dd><p>Definition a</p></dd>\n" +
882 "<dt>Term 2</dt>\n" +
883 "<dd><p>Definition b</p></dd>\n" +
884 "</dl>\n",
885
886 "Term 1\n\n: Definition a\n\n: Definition b\n\nTerm 2\n\n: Definition c\n",
887 "<dl>\n" +
888 "<dt>Term 1</dt>\n" +
889 "<dd><p>Definition a</p></dd>\n" +
890 "<dd><p>Definition b</p></dd>\n" +
891 "<dt>Term 2</dt>\n" +
892 "<dd><p>Definition c</p></dd>\n" +
893 "</dl>\n",
894
895 "Term 1\n: Definition a\nNext line\n",
896 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a\nNext line</dd>\n</dl>\n",
897
898 "Term 1\n: Definition a\n Next line\n",
899 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a\nNext line</dd>\n</dl>\n",
900
901 "Term 1\n: Definition a \n Next line \n",
902 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a\nNext line</dd>\n</dl>\n",
903
904 "Term 1\n: Definition a\nNext line\n\nTerm 2\n: Definition b",
905 "<dl>\n" +
906 "<dt>Term 1</dt>\n" +
907 "<dd>Definition a\nNext line</dd>\n" +
908 "<dt>Term 2</dt>\n" +
909 "<dd>Definition b</dd>\n" +
910 "</dl>\n",
911
912 "Term 1\n: Definition a\n",
913 "<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
914
915 "Term 1\n:Definition a\n",
916 "<p>Term 1\n:Definition a</p>\n",
917
918 "Term 1\n\n: Definition a\n\nTerm 2\n\n: Definition b\n\nText 1",
919 "<dl>\n" +
920 "<dt>Term 1</dt>\n" +
921 "<dd><p>Definition a</p></dd>\n" +
922 "<dt>Term 2</dt>\n" +
923 "<dd><p>Definition b</p></dd>\n" +
924 "</dl>\n" +
925 "\n<p>Text 1</p>\n",
926
927 "Term 1\n\n: Definition a\n\nText 1\n\nTerm 2\n\n: Definition b\n\nText 2",
928 "<dl>\n" +
929 "<dt>Term 1</dt>\n" +
930 "<dd><p>Definition a</p></dd>\n" +
931 "</dl>\n" +
932 "\n<p>Text 1</p>\n" +
933 "\n<dl>\n" +
934 "<dt>Term 2</dt>\n" +
935 "<dd><p>Definition b</p></dd>\n" +
936 "</dl>\n" +
937 "\n<p>Text 2</p>\n",
938 }
939 doTestsBlock(t, tests, DefinitionLists)
940}
941
942func TestConsecutiveLists(t *testing.T) {
943 var tests = []string{
944 "1. Hello\n\n* Hello\n\nTerm 1\n: Definition a\n",
945 "<ol>\n<li>Hello</li>\n</ol>\n\n<ul>\n<li>Hello</li>\n</ul>\n\n<dl>\n<dt>Term 1</dt>\n<dd>Definition a</dd>\n</dl>\n",
946
947 "1. Not nested\n2. ordered list\n\n\t1. nested\n\t2. ordered list\n\n\t* nested\n\t* unordered list\n* Not nested\n* unordered list",
948 "<ol>\n<li><p>Not nested</p></li>\n\n<li><p>ordered list</p>\n\n<ol>\n<li>nested</li>\n<li>ordered list</li>\n</ol>\n\n<ul>\n<li>nested</li>\n<li>unordered list</li>\n</ul></li>\n</ol>\n\n<ul>\n<li>Not nested</li>\n<li>unordered list</li>\n</ul>\n",
949 }
950 doTestsBlock(t, tests, DefinitionLists)
951}
952
953func TestPreformattedHtml(t *testing.T) {
954 var tests = []string{
955 "<div></div>\n",
956 "<div></div>\n",
957
958 "<div>\n</div>\n",
959 "<div>\n</div>\n",
960
961 "<div>\n</div>\nParagraph\n",
962 "<p><div>\n</div>\nParagraph</p>\n",
963
964 "<div class=\"foo\">\n</div>\n",
965 "<div class=\"foo\">\n</div>\n",
966
967 "<div>\nAnything here\n</div>\n",
968 "<div>\nAnything here\n</div>\n",
969
970 "<div>\n Anything here\n</div>\n",
971 "<div>\n Anything here\n</div>\n",
972
973 "<div>\nAnything here\n </div>\n",
974 "<div>\nAnything here\n </div>\n",
975
976 "<div>\nThis is *not* &proceessed\n</div>\n",
977 "<div>\nThis is *not* &proceessed\n</div>\n",
978
979 "<faketag>\n Something\n</faketag>\n",
980 "<p><faketag>\n Something\n</faketag></p>\n",
981
982 "<div>\n Something here\n</divv>\n",
983 "<p><div>\n Something here\n</divv></p>\n",
984
985 "Paragraph\n<div>\nHere? >&<\n</div>\n",
986 "<p>Paragraph\n<div>\nHere? >&<\n</div></p>\n",
987
988 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
989 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
990
991 "Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
992 "<p>Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?</p>\n",
993
994 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
995 "<p>Paragraph</p>\n\n<p><div>\nHow about here? >&<\n</div>\nAnd here?</p>\n",
996
997 "Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
998 "<p>Paragraph\n<div>\nHere? >&<\n</div></p>\n\n<p>And here?</p>\n",
999
1000 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
1001 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
1002 }
1003 doTestsBlock(t, tests, 0)
1004}
1005
1006func TestPreformattedHtmlLax(t *testing.T) {
1007 var tests = []string{
1008 "Paragraph\n<div>\nHere? >&<\n</div>\n",
1009 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n",
1010
1011 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
1012 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
1013
1014 "Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
1015 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
1016
1017 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
1018 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
1019
1020 "Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
1021 "<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
1022
1023 "Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
1024 "<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
1025 }
1026 doTestsBlock(t, tests, LaxHTMLBlocks)
1027}
1028
1029func TestFencedCodeBlock(t *testing.T) {
1030 var tests = []string{
1031 "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
1032 "<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
1033
1034 "``` go foo bar\nfunc foo() bool {\n\treturn true;\n}\n```\n",
1035 "<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
1036
1037 "``` c\n/* special & char < > \" escaping */\n```\n",
1038 "<pre><code class=\"language-c\">/* special & char < > " escaping */\n</code></pre>\n",
1039
1040 "``` c\nno *inline* processing ~~of text~~\n```\n",
1041 "<pre><code class=\"language-c\">no *inline* processing ~~of text~~\n</code></pre>\n",
1042
1043 "```\nNo language\n```\n",
1044 "<pre><code>No language\n</code></pre>\n",
1045
1046 "``` {ocaml}\nlanguage in braces\n```\n",
1047 "<pre><code class=\"language-ocaml\">language in braces\n</code></pre>\n",
1048
1049 "``` {ocaml} \nwith extra whitespace\n```\n",
1050 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
1051
1052 "```{ ocaml }\nwith extra whitespace\n```\n",
1053 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
1054
1055 "~ ~~ java\nWith whitespace\n~~~\n",
1056 "<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
1057
1058 "~~\nonly two\n~~\n",
1059 "<p>~~\nonly two\n~~</p>\n",
1060
1061 "```` python\nextra\n````\n",
1062 "<pre><code class=\"language-python\">extra\n</code></pre>\n",
1063
1064 "~~~ perl\nthree to start, four to end\n~~~~\n",
1065 "<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
1066
1067 "~~~~ perl\nfour to start, three to end\n~~~\n",
1068 "<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
1069
1070 "~~~ bash\ntildes\n~~~\n",
1071 "<pre><code class=\"language-bash\">tildes\n</code></pre>\n",
1072
1073 "``` lisp\nno ending\n",
1074 "<p>``` lisp\nno ending</p>\n",
1075
1076 "~~~ lisp\nend with language\n~~~ lisp\n",
1077 "<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
1078
1079 "```\nmismatched begin and end\n~~~\n",
1080 "<p>```\nmismatched begin and end\n~~~</p>\n",
1081
1082 "~~~\nmismatched begin and end\n```\n",
1083 "<p>~~~\nmismatched begin and end\n```</p>\n",
1084
1085 " ``` oz\nleading spaces\n```\n",
1086 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1087
1088 " ``` oz\nleading spaces\n ```\n",
1089 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1090
1091 " ``` oz\nleading spaces\n ```\n",
1092 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1093
1094 "``` oz\nleading spaces\n ```\n",
1095 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1096
1097 " ``` oz\nleading spaces\n ```\n",
1098 "<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces\n ```</p>\n",
1099
1100 "Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n",
1101 "<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",
1102
1103 "Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nAnd some text after a fenced code block",
1104 "<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",
1105
1106 "`",
1107 "<p>`</p>\n",
1108
1109 "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",
1110 "<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",
1111
1112 "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",
1113 "<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",
1114
1115 "```\n[]:()\n```\n",
1116 "<pre><code>[]:()\n</code></pre>\n",
1117
1118 "```\n[]:()\n[]:)\n[]:(\n[]:x\n[]:testing\n[:testing\n\n[]:\nlinebreak\n[]()\n\n[]:\n[]()\n```",
1119 "<pre><code>[]:()\n[]:)\n[]:(\n[]:x\n[]:testing\n[:testing\n\n[]:\nlinebreak\n[]()\n\n[]:\n[]()\n</code></pre>\n",
1120 }
1121 doTestsBlock(t, tests, FencedCode)
1122}
1123
1124func TestFencedCodeInsideBlockquotes(t *testing.T) {
1125 cat := func(s ...string) string { return strings.Join(s, "\n") }
1126 var tests = []string{
1127 cat("> ```go",
1128 "package moo",
1129 "",
1130 "```",
1131 ""),
1132 `<blockquote>
1133<pre><code class="language-go">package moo
1134
1135</code></pre>
1136</blockquote>
1137`,
1138 // -------------------------------------------
1139 cat("> foo",
1140 "> ",
1141 "> ```go",
1142 "package moo",
1143 "```",
1144 "> ",
1145 "> goo.",
1146 ""),
1147 `<blockquote>
1148<p>foo</p>
1149
1150<pre><code class="language-go">package moo
1151</code></pre>
1152
1153<p>goo.</p>
1154</blockquote>
1155`,
1156 // -------------------------------------------
1157 cat("> foo",
1158 "> ",
1159 "> quote",
1160 "continues",
1161 "```",
1162 ""),
1163 `<blockquote>
1164<p>foo</p>
1165
1166<p>quote
1167continues
1168` + "```" + `</p>
1169</blockquote>
1170`,
1171 // -------------------------------------------
1172 cat("> foo",
1173 "> ",
1174 "> ```go",
1175 "package moo",
1176 "```",
1177 "> ",
1178 "> goo.",
1179 "> ",
1180 "> ```go",
1181 "package zoo",
1182 "```",
1183 "> ",
1184 "> woo.",
1185 ""),
1186 `<blockquote>
1187<p>foo</p>
1188
1189<pre><code class="language-go">package moo
1190</code></pre>
1191
1192<p>goo.</p>
1193
1194<pre><code class="language-go">package zoo
1195</code></pre>
1196
1197<p>woo.</p>
1198</blockquote>
1199`,
1200 }
1201
1202 // These 2 alternative forms of blockquoted fenced code blocks should produce same output.
1203 forms := [2]string{
1204 cat("> plain quoted text",
1205 "> ```fenced",
1206 "code",
1207 " with leading single space correctly preserved",
1208 "okay",
1209 "```",
1210 "> rest of quoted text"),
1211 cat("> plain quoted text",
1212 "> ```fenced",
1213 "> code",
1214 "> with leading single space correctly preserved",
1215 "> okay",
1216 "> ```",
1217 "> rest of quoted text"),
1218 }
1219 want := `<blockquote>
1220<p>plain quoted text</p>
1221
1222<pre><code class="language-fenced">code
1223 with leading single space correctly preserved
1224okay
1225</code></pre>
1226
1227<p>rest of quoted text</p>
1228</blockquote>
1229`
1230 tests = append(tests, forms[0], want)
1231 tests = append(tests, forms[1], want)
1232
1233 doTestsBlock(t, tests, FencedCode)
1234}
1235
1236func TestTable(t *testing.T) {
1237 var tests = []string{
1238 "a | b\n---|---\nc | d\n",
1239 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n\n" +
1240 "<tbody>\n<tr>\n<td>c</td>\n<td>d</td>\n</tr>\n</tbody>\n</table>\n",
1241
1242 "a | b\n---|--\nc | d\n",
1243 "<p>a | b\n---|--\nc | d</p>\n",
1244
1245 "|a|b|c|d|\n|----|----|----|---|\n|e|f|g|h|\n",
1246 "<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" +
1247 "<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",
1248
1249 "*a*|__b__|[c](C)|d\n---|---|---|---\ne|f|g|h\n",
1250 "<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" +
1251 "<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",
1252
1253 "a|b|c\n---|---|---\nd|e|f\ng|h\ni|j|k|l|m\nn|o|p\n",
1254 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n" +
1255 "<tbody>\n<tr>\n<td>d</td>\n<td>e</td>\n<td>f</td>\n</tr>\n\n" +
1256 "<tr>\n<td>g</td>\n<td>h</td>\n<td></td>\n</tr>\n\n" +
1257 "<tr>\n<td>i</td>\n<td>j</td>\n<td>k</td>\n</tr>\n\n" +
1258 "<tr>\n<td>n</td>\n<td>o</td>\n<td>p</td>\n</tr>\n</tbody>\n</table>\n",
1259
1260 "a|b|c\n---|---|---\n*d*|__e__|f\n",
1261 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n" +
1262 "<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",
1263
1264 "a|b|c|d\n:--|--:|:-:|---\ne|f|g|h\n",
1265 "<table>\n<thead>\n<tr>\n<th align=\"left\">a</th>\n<th align=\"right\">b</th>\n" +
1266 "<th align=\"center\">c</th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
1267 "<tbody>\n<tr>\n<td align=\"left\">e</td>\n<td align=\"right\">f</td>\n" +
1268 "<td align=\"center\">g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
1269
1270 "a|b|c\n---|---|---\n",
1271 "<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",
1272
1273 "a| b|c | d | e\n---|---|---|---|---\nf| g|h | i |j\n",
1274 "<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" +
1275 "<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",
1276
1277 "a|b\\|c|d\n---|---|---\nf|g\\|h|i\n",
1278 "<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",
1279 }
1280 doTestsBlock(t, tests, Tables)
1281}
1282
1283func TestUnorderedListWith_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
1284 var tests = []string{
1285 "* Hello\n",
1286 "<ul>\n<li>Hello</li>\n</ul>\n",
1287
1288 "* Yin\n* Yang\n",
1289 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
1290
1291 "* Ting\n* Bong\n* Goo\n",
1292 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
1293
1294 "* Yin\n\n* Yang\n",
1295 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
1296
1297 "* Ting\n\n* Bong\n* Goo\n",
1298 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
1299
1300 "+ Hello\n",
1301 "<ul>\n<li>Hello</li>\n</ul>\n",
1302
1303 "+ Yin\n+ Yang\n",
1304 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
1305
1306 "+ Ting\n+ Bong\n+ Goo\n",
1307 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
1308
1309 "+ Yin\n\n+ Yang\n",
1310 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
1311
1312 "+ Ting\n\n+ Bong\n+ Goo\n",
1313 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
1314
1315 "- Hello\n",
1316 "<ul>\n<li>Hello</li>\n</ul>\n",
1317
1318 "- Yin\n- Yang\n",
1319 "<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
1320
1321 "- Ting\n- Bong\n- Goo\n",
1322 "<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
1323
1324 "- Yin\n\n- Yang\n",
1325 "<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
1326
1327 "- Ting\n\n- Bong\n- Goo\n",
1328 "<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
1329
1330 "*Hello\n",
1331 "<p>*Hello</p>\n",
1332
1333 "* Hello \n",
1334 "<ul>\n<li>Hello</li>\n</ul>\n",
1335
1336 "* Hello \n Next line \n",
1337 "<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
1338
1339 "Paragraph\n* No linebreak\n",
1340 "<p>Paragraph</p>\n\n<ul>\n<li>No linebreak</li>\n</ul>\n",
1341
1342 "Paragraph\n\n* Linebreak\n",
1343 "<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
1344
1345 "* List\n * Nested list\n",
1346 "<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
1347
1348 "* List\n\n * Nested list\n",
1349 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
1350
1351 "* List\n Second line\n\n + Nested\n",
1352 "<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
1353
1354 "* List\n + Nested\n\n Continued\n",
1355 "<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
1356
1357 "* List\n * shallow indent\n",
1358 "<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
1359
1360 "* List\n" +
1361 " * shallow indent\n" +
1362 " * part of second list\n" +
1363 " * still second\n" +
1364 " * almost there\n" +
1365 " * third level\n",
1366 "<ul>\n" +
1367 "<li>List\n\n" +
1368 "<ul>\n" +
1369 "<li>shallow indent</li>\n" +
1370 "<li>part of second list</li>\n" +
1371 "<li>still second</li>\n" +
1372 "<li>almost there\n\n" +
1373 "<ul>\n" +
1374 "<li>third level</li>\n" +
1375 "</ul></li>\n" +
1376 "</ul></li>\n" +
1377 "</ul>\n",
1378
1379 "* List\n extra indent, same paragraph\n",
1380 "<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n",
1381
1382 "* List\n\n code block\n",
1383 "<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
1384
1385 "* List\n\n code block with spaces\n",
1386 "<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n",
1387
1388 "* List\n\n * sublist\n\n normal text\n\n * another sublist\n",
1389 "<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",
1390 }
1391 doTestsBlock(t, tests, NoEmptyLineBeforeBlock)
1392}
1393
1394func TestOrderedList_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
1395 var tests = []string{
1396 "1. Hello\n",
1397 "<ol>\n<li>Hello</li>\n</ol>\n",
1398
1399 "1. Yin\n2. Yang\n",
1400 "<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
1401
1402 "1. Ting\n2. Bong\n3. Goo\n",
1403 "<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
1404
1405 "1. Yin\n\n2. Yang\n",
1406 "<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
1407
1408 "1. Ting\n\n2. Bong\n3. Goo\n",
1409 "<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
1410
1411 "1 Hello\n",
1412 "<p>1 Hello</p>\n",
1413
1414 "1.Hello\n",
1415 "<p>1.Hello</p>\n",
1416
1417 "1. Hello \n",
1418 "<ol>\n<li>Hello</li>\n</ol>\n",
1419
1420 "1. Hello \n Next line \n",
1421 "<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
1422
1423 "Paragraph\n1. No linebreak\n",
1424 "<p>Paragraph</p>\n\n<ol>\n<li>No linebreak</li>\n</ol>\n",
1425
1426 "Paragraph\n\n1. Linebreak\n",
1427 "<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
1428
1429 "1. List\n 1. Nested list\n",
1430 "<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
1431
1432 "1. List\n\n 1. Nested list\n",
1433 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
1434
1435 "1. List\n Second line\n\n 1. Nested\n",
1436 "<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
1437
1438 "1. List\n 1. Nested\n\n Continued\n",
1439 "<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
1440
1441 "1. List\n 1. shallow indent\n",
1442 "<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
1443
1444 "1. List\n" +
1445 " 1. shallow indent\n" +
1446 " 2. part of second list\n" +
1447 " 3. still second\n" +
1448 " 4. almost there\n" +
1449 " 1. third level\n",
1450 "<ol>\n" +
1451 "<li>List\n\n" +
1452 "<ol>\n" +
1453 "<li>shallow indent</li>\n" +
1454 "<li>part of second list</li>\n" +
1455 "<li>still second</li>\n" +
1456 "<li>almost there\n\n" +
1457 "<ol>\n" +
1458 "<li>third level</li>\n" +
1459 "</ol></li>\n" +
1460 "</ol></li>\n" +
1461 "</ol>\n",
1462
1463 "1. List\n extra indent, same paragraph\n",
1464 "<ol>\n<li>List\n extra indent, same paragraph</li>\n</ol>\n",
1465
1466 "1. List\n\n code block\n",
1467 "<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
1468
1469 "1. List\n\n code block with spaces\n",
1470 "<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
1471
1472 "1. List\n * Mixted list\n",
1473 "<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
1474
1475 "1. List\n * Mixed list\n",
1476 "<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
1477
1478 "* Start with unordered\n 1. Ordered\n",
1479 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
1480
1481 "* Start with unordered\n 1. Ordered\n",
1482 "<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
1483
1484 "1. numbers\n1. are ignored\n",
1485 "<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
1486 }
1487 doTestsBlock(t, tests, NoEmptyLineBeforeBlock)
1488}
1489
1490func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
1491 var tests = []string{
1492 "``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
1493 "<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
1494
1495 "``` go foo bar\nfunc foo() bool {\n\treturn true;\n}\n```\n",
1496 "<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
1497
1498 "``` c\n/* special & char < > \" escaping */\n```\n",
1499 "<pre><code class=\"language-c\">/* special & char < > " escaping */\n</code></pre>\n",
1500
1501 "``` c\nno *inline* processing ~~of text~~\n```\n",
1502 "<pre><code class=\"language-c\">no *inline* processing ~~of text~~\n</code></pre>\n",
1503
1504 "```\nNo language\n```\n",
1505 "<pre><code>No language\n</code></pre>\n",
1506
1507 "``` {ocaml}\nlanguage in braces\n```\n",
1508 "<pre><code class=\"language-ocaml\">language in braces\n</code></pre>\n",
1509
1510 "``` {ocaml} \nwith extra whitespace\n```\n",
1511 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
1512
1513 "```{ ocaml }\nwith extra whitespace\n```\n",
1514 "<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
1515
1516 "~ ~~ java\nWith whitespace\n~~~\n",
1517 "<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
1518
1519 "~~\nonly two\n~~\n",
1520 "<p>~~\nonly two\n~~</p>\n",
1521
1522 "```` python\nextra\n````\n",
1523 "<pre><code class=\"language-python\">extra\n</code></pre>\n",
1524
1525 "~~~ perl\nthree to start, four to end\n~~~~\n",
1526 "<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
1527
1528 "~~~~ perl\nfour to start, three to end\n~~~\n",
1529 "<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
1530
1531 "~~~ bash\ntildes\n~~~\n",
1532 "<pre><code class=\"language-bash\">tildes\n</code></pre>\n",
1533
1534 "``` lisp\nno ending\n",
1535 "<p>``` lisp\nno ending</p>\n",
1536
1537 "~~~ lisp\nend with language\n~~~ lisp\n",
1538 "<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
1539
1540 "```\nmismatched begin and end\n~~~\n",
1541 "<p>```\nmismatched begin and end\n~~~</p>\n",
1542
1543 "~~~\nmismatched begin and end\n```\n",
1544 "<p>~~~\nmismatched begin and end\n```</p>\n",
1545
1546 " ``` oz\nleading spaces\n```\n",
1547 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1548
1549 " ``` oz\nleading spaces\n ```\n",
1550 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1551
1552 " ``` oz\nleading spaces\n ```\n",
1553 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1554
1555 "``` oz\nleading spaces\n ```\n",
1556 "<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
1557
1558 " ``` oz\nleading spaces\n ```\n",
1559 "<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces</p>\n\n<pre><code>```\n</code></pre>\n",
1560 }
1561 doTestsBlock(t, tests, FencedCode|NoEmptyLineBeforeBlock)
1562}
1563
1564func TestListWithFencedCodeBlock(t *testing.T) {
1565 var tests = []string{
1566 "1. one\n\n ```\n code\n ```\n\n2. two\n",
1567 "<ol>\n<li><p>one</p>\n\n<pre><code>code\n</code></pre></li>\n\n<li><p>two</p></li>\n</ol>\n",
1568 // https://github.com/russross/blackfriday/issues/239
1569 "1. one\n\n ```\n - code\n ```\n\n2. two\n",
1570 "<ol>\n<li><p>one</p>\n\n<pre><code>- code\n</code></pre></li>\n\n<li><p>two</p></li>\n</ol>\n",
1571 }
1572 doTestsBlock(t, tests, FencedCode)
1573}
1574
1575func TestListWithMalformedFencedCodeBlock(t *testing.T) {
1576 // Ensure that in the case of an unclosed fenced code block in a list,
1577 // no source gets ommitted (even if it is malformed).
1578 // See russross/blackfriday#372 for context.
1579 var tests = []string{
1580 "1. one\n\n ```\n code\n\n2. two\n",
1581 "<ol>\n<li>one\n```\ncode\n2. two</li>\n</ol>\n",
1582
1583 "1. one\n\n ```\n - code\n\n2. two\n",
1584 "<ol>\n<li>one\n```\n- code\n2. two</li>\n</ol>\n",
1585 }
1586 doTestsBlock(t, tests, FencedCode)
1587}
1588
1589func TestListWithFencedCodeBlockNoExtensions(t *testing.T) {
1590 // If there is a fenced code block in a list, and FencedCode is not set,
1591 // lists should be processed normally.
1592 var tests = []string{
1593 "1. one\n\n ```\n code\n ```\n\n2. two\n",
1594 "<ol>\n<li><p>one</p>\n\n<p><code>\ncode\n</code></p></li>\n\n<li><p>two</p></li>\n</ol>\n",
1595
1596 "1. one\n\n ```\n - code\n ```\n\n2. two\n",
1597 "<ol>\n<li><p>one</p>\n\n<p>```</p>\n\n<ul>\n<li>code\n```</li>\n</ul></li>\n\n<li><p>two</p></li>\n</ol>\n",
1598 }
1599 doTestsBlock(t, tests, 0)
1600}
1601
1602func TestTitleBlock_EXTENSION_TITLEBLOCK(t *testing.T) {
1603 var tests = []string{
1604 "% Some title\n" +
1605 "% Another title line\n" +
1606 "% Yep, more here too\n",
1607 "<h1 class=\"title\">" +
1608 "Some title\n" +
1609 "Another title line\n" +
1610 "Yep, more here too" +
1611 "</h1>\n",
1612 }
1613 doTestsBlock(t, tests, Titleblock)
1614}
1615
1616func TestBlockComments(t *testing.T) {
1617 var tests = []string{
1618 "Some text\n\n<!-- comment -->\n",
1619 "<p>Some text</p>\n\n<!-- comment -->\n",
1620
1621 "Some text\n\n<!--\n\nmultiline\ncomment\n-->\n",
1622 "<p>Some text</p>\n\n<!--\n\nmultiline\ncomment\n-->\n",
1623
1624 "Some text\n\n<!--\n\n<div><p>Commented</p>\n<span>html</span></div>\n-->\n",
1625 "<p>Some text</p>\n\n<!--\n\n<div><p>Commented</p>\n<span>html</span></div>\n-->\n",
1626 }
1627 doTestsBlock(t, tests, 0)
1628}
1629
1630func TestTOC(t *testing.T) {
1631 var tests = []string{
1632 "# Title\n\n##Subtitle1\n\n##Subtitle2",
1633 //"<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",
1634 `<nav>
1635
1636<ul>
1637<li><a href="#toc_0">Title</a>
1638<ul>
1639<li><a href="#toc_1">Subtitle1</a></li>
1640
1641<li><a href="#toc_2">Subtitle2</a></li>
1642</ul></li>
1643</ul>
1644
1645</nav>
1646
1647<h1 id="toc_0">Title</h1>
1648
1649<h2 id="toc_1">Subtitle1</h2>
1650
1651<h2 id="toc_2">Subtitle2</h2>
1652`,
1653
1654 "# Title\n\n##Subtitle\n\n#Title2",
1655 //"<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",
1656 `<nav>
1657
1658<ul>
1659<li><a href="#toc_0">Title</a>
1660<ul>
1661<li><a href="#toc_1">Subtitle</a></li>
1662</ul></li>
1663
1664<li><a href="#toc_2">Title2</a></li>
1665</ul>
1666
1667</nav>
1668
1669<h1 id="toc_0">Title</h1>
1670
1671<h2 id="toc_1">Subtitle</h2>
1672
1673<h1 id="toc_2">Title2</h1>
1674`,
1675
1676 "## Subtitle\n\n# Title",
1677 `<nav>
1678
1679<ul>
1680<li>
1681<ul>
1682<li><a href="#toc_0">Subtitle</a></li>
1683</ul></li>
1684
1685<li><a href="#toc_1">Title</a></li>
1686</ul>
1687
1688</nav>
1689
1690<h2 id="toc_0">Subtitle</h2>
1691
1692<h1 id="toc_1">Title</h1>
1693`,
1694
1695 "# Title 1\n\n## Subtitle 1\n\n### Subsubtitle 1\n\n# Title 2\n\n### Subsubtitle 2",
1696 `<nav>
1697
1698<ul>
1699<li><a href="#toc_0">Title 1</a>
1700<ul>
1701<li><a href="#toc_1">Subtitle 1</a>
1702<ul>
1703<li><a href="#toc_2">Subsubtitle 1</a></li>
1704</ul></li>
1705</ul></li>
1706
1707<li><a href="#toc_3">Title 2</a>
1708<ul>
1709<li>
1710<ul>
1711<li><a href="#toc_4">Subsubtitle 2</a></li>
1712</ul></li>
1713</ul></li>
1714</ul>
1715
1716</nav>
1717
1718<h1 id="toc_0">Title 1</h1>
1719
1720<h2 id="toc_1">Subtitle 1</h2>
1721
1722<h3 id="toc_2">Subsubtitle 1</h3>
1723
1724<h1 id="toc_3">Title 2</h1>
1725
1726<h3 id="toc_4">Subsubtitle 2</h3>
1727`,
1728
1729 "# Title with `code`",
1730 `<nav>
1731
1732<ul>
1733<li><a href="#toc_0">Title with <code>code</code></a></li>
1734</ul>
1735
1736</nav>
1737
1738<h1 id="toc_0">Title with <code>code</code></h1>
1739`,
1740
1741 // Trigger empty TOC
1742 "#",
1743 "",
1744 }
1745 doTestsParam(t, tests, TestParams{
1746 HTMLFlags: UseXHTML | TOC,
1747 })
1748}
1749
1750func TestCompletePage(t *testing.T) {
1751 var tests = []string{
1752 "*foo*",
1753 `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1754<html xmlns="http://www.w3.org/1999/xhtml">
1755<head>
1756 <title></title>
1757 <meta name="GENERATOR" content="Blackfriday Markdown Processor v2.0" />
1758 <meta charset="utf-8" />
1759</head>
1760<body>
1761
1762<p><em>foo</em></p>
1763
1764</body>
1765</html>
1766`,
1767 }
1768 doTestsParam(t, tests, TestParams{HTMLFlags: UseXHTML | CompletePage})
1769}
1770
1771func TestIsFenceLine(t *testing.T) {
1772 tests := []struct {
1773 data []byte
1774 infoRequested bool
1775 wantEnd int
1776 wantMarker string
1777 wantInfo string
1778 }{
1779 {
1780 data: []byte("```"),
1781 wantEnd: 3,
1782 wantMarker: "```",
1783 },
1784 {
1785 data: []byte("```\nstuff here\n"),
1786 wantEnd: 4,
1787 wantMarker: "```",
1788 },
1789 {
1790 data: []byte("```\nstuff here\n"),
1791 infoRequested: true,
1792 wantEnd: 4,
1793 wantMarker: "```",
1794 },
1795 {
1796 data: []byte("stuff here\n```\n"),
1797 wantEnd: 0,
1798 },
1799 {
1800 data: []byte("```"),
1801 infoRequested: true,
1802 wantEnd: 3,
1803 wantMarker: "```",
1804 },
1805 {
1806 data: []byte("``` go"),
1807 infoRequested: true,
1808 wantEnd: 6,
1809 wantMarker: "```",
1810 wantInfo: "go",
1811 },
1812 {
1813 data: []byte("``` go foo bar"),
1814 infoRequested: true,
1815 wantEnd: 14,
1816 wantMarker: "```",
1817 wantInfo: "go foo bar",
1818 },
1819 {
1820 data: []byte("``` go foo bar "),
1821 infoRequested: true,
1822 wantEnd: 16,
1823 wantMarker: "```",
1824 wantInfo: "go foo bar",
1825 },
1826 }
1827
1828 for _, test := range tests {
1829 var info *string
1830 if test.infoRequested {
1831 info = new(string)
1832 }
1833 end, marker := isFenceLine(test.data, info, "```")
1834 if got, want := end, test.wantEnd; got != want {
1835 t.Errorf("got end %v, want %v", got, want)
1836 }
1837 if got, want := marker, test.wantMarker; got != want {
1838 t.Errorf("got marker %q, want %q", got, want)
1839 }
1840 if test.infoRequested {
1841 if got, want := *info, test.wantInfo; got != want {
1842 t.Errorf("got info string %q, want %q", got, want)
1843 }
1844 }
1845 }
1846}