all repos — grayfriday @ 6a7bd0d6e94723d834195ff891099d70b5bb23cf

blackfriday fork with a few changes

block_test.go (view raw)

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