...

Source file src/github.com/russross/blackfriday/v2/block_test.go

Documentation: github.com/russross/blackfriday/v2

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

View as plain text