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