github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/russross/blackfriday/inline_test.go (about) 1 // 2 // Blackfriday Markdown Processor 3 // Available at http://yougam/libraries/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 inline parsing 12 // 13 14 package blackfriday 15 16 import ( 17 "regexp" 18 "strings" 19 "testing" 20 ) 21 22 func runMarkdownInline(input string, opts Options, htmlFlags int, params HtmlRendererParameters) string { 23 opts.Extensions |= EXTENSION_AUTOLINK 24 opts.Extensions |= EXTENSION_STRIKETHROUGH 25 26 htmlFlags |= HTML_USE_XHTML 27 28 renderer := HtmlRendererWithParameters(htmlFlags, "", "", params) 29 30 return string(MarkdownOptions([]byte(input), renderer, opts)) 31 } 32 33 func doTestsInline(t *testing.T, tests []string) { 34 doTestsInlineParam(t, tests, Options{}, 0, HtmlRendererParameters{}) 35 } 36 37 func doLinkTestsInline(t *testing.T, tests []string) { 38 doTestsInline(t, tests) 39 40 prefix := "http://localhost" 41 params := HtmlRendererParameters{AbsolutePrefix: prefix} 42 transformTests := transformLinks(tests, prefix) 43 doTestsInlineParam(t, transformTests, Options{}, 0, params) 44 doTestsInlineParam(t, transformTests, Options{}, commonHtmlFlags, params) 45 } 46 47 func doSafeTestsInline(t *testing.T, tests []string) { 48 doTestsInlineParam(t, tests, Options{}, HTML_SAFELINK, HtmlRendererParameters{}) 49 50 // All the links in this test should not have the prefix appended, so 51 // just rerun it with different parameters and the same expectations. 52 prefix := "http://localhost" 53 params := HtmlRendererParameters{AbsolutePrefix: prefix} 54 transformTests := transformLinks(tests, prefix) 55 doTestsInlineParam(t, transformTests, Options{}, HTML_SAFELINK, params) 56 } 57 58 func doTestsInlineParam(t *testing.T, tests []string, opts Options, htmlFlags int, 59 params HtmlRendererParameters) { 60 // catch and report panics 61 var candidate string 62 /* 63 defer func() { 64 if err := recover(); err != nil { 65 t.Errorf("\npanic while processing [%#v] (%v)\n", candidate, err) 66 } 67 }() 68 */ 69 70 for i := 0; i+1 < len(tests); i += 2 { 71 input := tests[i] 72 candidate = input 73 expected := tests[i+1] 74 actual := runMarkdownInline(candidate, opts, htmlFlags, params) 75 if actual != expected { 76 t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]", 77 candidate, expected, actual) 78 } 79 80 // now test every substring to stress test bounds checking 81 if !testing.Short() { 82 for start := 0; start < len(input); start++ { 83 for end := start + 1; end <= len(input); end++ { 84 candidate = input[start:end] 85 _ = runMarkdownInline(candidate, opts, htmlFlags, params) 86 } 87 } 88 } 89 } 90 } 91 92 func transformLinks(tests []string, prefix string) []string { 93 newTests := make([]string, len(tests)) 94 anchorRe := regexp.MustCompile(`<a href="/(.*?)"`) 95 imgRe := regexp.MustCompile(`<img src="/(.*?)"`) 96 for i, test := range tests { 97 if i%2 == 1 { 98 test = anchorRe.ReplaceAllString(test, `<a href="`+prefix+`/$1"`) 99 test = imgRe.ReplaceAllString(test, `<img src="`+prefix+`/$1"`) 100 } 101 newTests[i] = test 102 } 103 return newTests 104 } 105 106 func TestEmphasis(t *testing.T) { 107 var tests = []string{ 108 "nothing inline\n", 109 "<p>nothing inline</p>\n", 110 111 "simple *inline* test\n", 112 "<p>simple <em>inline</em> test</p>\n", 113 114 "*at the* beginning\n", 115 "<p><em>at the</em> beginning</p>\n", 116 117 "at the *end*\n", 118 "<p>at the <em>end</em></p>\n", 119 120 "*try two* in *one line*\n", 121 "<p><em>try two</em> in <em>one line</em></p>\n", 122 123 "over *two\nlines* test\n", 124 "<p>over <em>two\nlines</em> test</p>\n", 125 126 "odd *number of* markers* here\n", 127 "<p>odd <em>number of</em> markers* here</p>\n", 128 129 "odd *number\nof* markers* here\n", 130 "<p>odd <em>number\nof</em> markers* here</p>\n", 131 132 "simple _inline_ test\n", 133 "<p>simple <em>inline</em> test</p>\n", 134 135 "_at the_ beginning\n", 136 "<p><em>at the</em> beginning</p>\n", 137 138 "at the _end_\n", 139 "<p>at the <em>end</em></p>\n", 140 141 "_try two_ in _one line_\n", 142 "<p><em>try two</em> in <em>one line</em></p>\n", 143 144 "over _two\nlines_ test\n", 145 "<p>over <em>two\nlines</em> test</p>\n", 146 147 "odd _number of_ markers_ here\n", 148 "<p>odd <em>number of</em> markers_ here</p>\n", 149 150 "odd _number\nof_ markers_ here\n", 151 "<p>odd <em>number\nof</em> markers_ here</p>\n", 152 153 "mix of *markers_\n", 154 "<p>mix of *markers_</p>\n", 155 156 "*What is A\\* algorithm?*\n", 157 "<p><em>What is A* algorithm?</em></p>\n", 158 159 "some para_graph with _emphasised_ text.\n", 160 "<p>some para_graph with <em>emphasised</em> text.</p>\n", 161 162 "some paragraph with _emphasised_ te_xt.\n", 163 "<p>some paragraph with <em>emphasised</em> te_xt.</p>\n", 164 165 "some paragraph with t_wo bi_ts of _emphasised_ text.\n", 166 "<p>some paragraph with t<em>wo bi</em>ts of <em>emphasised</em> text.</p>\n", 167 168 "un*frigging*believable\n", 169 "<p>un<em>frigging</em>believable</p>\n", 170 } 171 doTestsInline(t, tests) 172 } 173 174 func TestNoIntraEmphasis(t *testing.T) { 175 tests := []string{ 176 "some para_graph with _emphasised_ text.\n", 177 "<p>some para_graph with <em>emphasised</em> text.</p>\n", 178 179 "un*frigging*believable\n", 180 "<p>un*frigging*believable</p>\n", 181 } 182 doTestsInlineParam(t, tests, Options{ 183 Extensions: EXTENSION_NO_INTRA_EMPHASIS}, 184 0, HtmlRendererParameters{}) 185 } 186 187 func TestReferenceOverride(t *testing.T) { 188 var tests = []string{ 189 "test [ref1][]\n", 190 "<p>test <a href=\"http://www.ref1.com/\" title=\"Reference 1\">ref1</a></p>\n", 191 192 "test [my ref][ref1]\n", 193 "<p>test <a href=\"http://www.ref1.com/\" title=\"Reference 1\">my ref</a></p>\n", 194 195 "test [ref2][]\n\n[ref2]: http://www.leftalone.com/ (Ref left alone)\n", 196 "<p>test <a href=\"http://www.overridden.com/\" title=\"Reference Overridden\">ref2</a></p>\n", 197 198 "test [ref3][]\n\n[ref3]: http://www.leftalone.com/ (Ref left alone)\n", 199 "<p>test <a href=\"http://www.leftalone.com/\" title=\"Ref left alone\">ref3</a></p>\n", 200 201 "test [ref4][]\n\n[ref4]: http://zombo.com/ (You can do anything)\n", 202 "<p>test [ref4][]</p>\n", 203 204 "test [!(*http.ServeMux).ServeHTTP][] complicated ref\n", 205 "<p>test <a href=\"http://localhost:6060/pkg/net/http/#ServeMux.ServeHTTP\" title=\"ServeHTTP docs\">!(*http.ServeMux).ServeHTTP</a> complicated ref</p>\n", 206 207 "test [ref5][]\n", 208 "<p>test <a href=\"http://www.ref5.com/\" title=\"Reference 5\">Moo</a></p>\n", 209 } 210 doTestsInlineParam(t, tests, Options{ 211 ReferenceOverride: func(reference string) (rv *Reference, overridden bool) { 212 switch reference { 213 case "ref1": 214 // just an overriden reference exists without definition 215 return &Reference{ 216 Link: "http://www.ref1.com/", 217 Title: "Reference 1"}, true 218 case "ref2": 219 // overridden exists and reference defined 220 return &Reference{ 221 Link: "http://www.overridden.com/", 222 Title: "Reference Overridden"}, true 223 case "ref3": 224 // not overridden and reference defined 225 return nil, false 226 case "ref4": 227 // overridden missing and defined 228 return nil, true 229 case "!(*http.ServeMux).ServeHTTP": 230 return &Reference{ 231 Link: "http://localhost:6060/pkg/net/http/#ServeMux.ServeHTTP", 232 Title: "ServeHTTP docs"}, true 233 case "ref5": 234 return &Reference{ 235 Link: "http://www.ref5.com/", 236 Title: "Reference 5", 237 Text: "Moo", 238 }, true 239 } 240 return nil, false 241 }}, 0, HtmlRendererParameters{}) 242 } 243 244 func TestStrong(t *testing.T) { 245 var tests = []string{ 246 "nothing inline\n", 247 "<p>nothing inline</p>\n", 248 249 "simple **inline** test\n", 250 "<p>simple <strong>inline</strong> test</p>\n", 251 252 "**at the** beginning\n", 253 "<p><strong>at the</strong> beginning</p>\n", 254 255 "at the **end**\n", 256 "<p>at the <strong>end</strong></p>\n", 257 258 "**try two** in **one line**\n", 259 "<p><strong>try two</strong> in <strong>one line</strong></p>\n", 260 261 "over **two\nlines** test\n", 262 "<p>over <strong>two\nlines</strong> test</p>\n", 263 264 "odd **number of** markers** here\n", 265 "<p>odd <strong>number of</strong> markers** here</p>\n", 266 267 "odd **number\nof** markers** here\n", 268 "<p>odd <strong>number\nof</strong> markers** here</p>\n", 269 270 "simple __inline__ test\n", 271 "<p>simple <strong>inline</strong> test</p>\n", 272 273 "__at the__ beginning\n", 274 "<p><strong>at the</strong> beginning</p>\n", 275 276 "at the __end__\n", 277 "<p>at the <strong>end</strong></p>\n", 278 279 "__try two__ in __one line__\n", 280 "<p><strong>try two</strong> in <strong>one line</strong></p>\n", 281 282 "over __two\nlines__ test\n", 283 "<p>over <strong>two\nlines</strong> test</p>\n", 284 285 "odd __number of__ markers__ here\n", 286 "<p>odd <strong>number of</strong> markers__ here</p>\n", 287 288 "odd __number\nof__ markers__ here\n", 289 "<p>odd <strong>number\nof</strong> markers__ here</p>\n", 290 291 "mix of **markers__\n", 292 "<p>mix of **markers__</p>\n", 293 294 "**`/usr`** : this folder is named `usr`\n", 295 "<p><strong><code>/usr</code></strong> : this folder is named <code>usr</code></p>\n", 296 297 "**`/usr`** :\n\n this folder is named `usr`\n", 298 "<p><strong><code>/usr</code></strong> :</p>\n\n<p>this folder is named <code>usr</code></p>\n", 299 } 300 doTestsInline(t, tests) 301 } 302 303 func TestEmphasisMix(t *testing.T) { 304 var tests = []string{ 305 "***triple emphasis***\n", 306 "<p><strong><em>triple emphasis</em></strong></p>\n", 307 308 "***triple\nemphasis***\n", 309 "<p><strong><em>triple\nemphasis</em></strong></p>\n", 310 311 "___triple emphasis___\n", 312 "<p><strong><em>triple emphasis</em></strong></p>\n", 313 314 "***triple emphasis___\n", 315 "<p>***triple emphasis___</p>\n", 316 317 "*__triple emphasis__*\n", 318 "<p><em><strong>triple emphasis</strong></em></p>\n", 319 320 "__*triple emphasis*__\n", 321 "<p><strong><em>triple emphasis</em></strong></p>\n", 322 323 "**improper *nesting** is* bad\n", 324 "<p><strong>improper *nesting</strong> is* bad</p>\n", 325 326 "*improper **nesting* is** bad\n", 327 "<p>*improper <strong>nesting* is</strong> bad</p>\n", 328 } 329 doTestsInline(t, tests) 330 } 331 332 func TestEmphasisLink(t *testing.T) { 333 var tests = []string{ 334 "[first](before) *text[second] (inside)text* [third](after)\n", 335 "<p><a href=\"before\">first</a> <em>text<a href=\"inside\">second</a>text</em> <a href=\"after\">third</a></p>\n", 336 337 "*incomplete [link] definition*\n", 338 "<p><em>incomplete [link] definition</em></p>\n", 339 340 "*it's [emphasis*] (not link)\n", 341 "<p><em>it's [emphasis</em>] (not link)</p>\n", 342 343 "*it's [emphasis*] and *[asterisk]\n", 344 "<p><em>it's [emphasis</em>] and *[asterisk]</p>\n", 345 } 346 doTestsInline(t, tests) 347 } 348 349 func TestStrikeThrough(t *testing.T) { 350 var tests = []string{ 351 "nothing inline\n", 352 "<p>nothing inline</p>\n", 353 354 "simple ~~inline~~ test\n", 355 "<p>simple <del>inline</del> test</p>\n", 356 357 "~~at the~~ beginning\n", 358 "<p><del>at the</del> beginning</p>\n", 359 360 "at the ~~end~~\n", 361 "<p>at the <del>end</del></p>\n", 362 363 "~~try two~~ in ~~one line~~\n", 364 "<p><del>try two</del> in <del>one line</del></p>\n", 365 366 "over ~~two\nlines~~ test\n", 367 "<p>over <del>two\nlines</del> test</p>\n", 368 369 "odd ~~number of~~ markers~~ here\n", 370 "<p>odd <del>number of</del> markers~~ here</p>\n", 371 372 "odd ~~number\nof~~ markers~~ here\n", 373 "<p>odd <del>number\nof</del> markers~~ here</p>\n", 374 } 375 doTestsInline(t, tests) 376 } 377 378 func TestCodeSpan(t *testing.T) { 379 var tests = []string{ 380 "`source code`\n", 381 "<p><code>source code</code></p>\n", 382 383 "` source code with spaces `\n", 384 "<p><code>source code with spaces</code></p>\n", 385 386 "` source code with spaces `not here\n", 387 "<p><code>source code with spaces</code>not here</p>\n", 388 389 "a `single marker\n", 390 "<p>a `single marker</p>\n", 391 392 "a single multi-tick marker with ``` no text\n", 393 "<p>a single multi-tick marker with ``` no text</p>\n", 394 395 "markers with ` ` a space\n", 396 "<p>markers with a space</p>\n", 397 398 "`source code` and a `stray\n", 399 "<p><code>source code</code> and a `stray</p>\n", 400 401 "`source *with* _awkward characters_ in it`\n", 402 "<p><code>source *with* _awkward characters_ in it</code></p>\n", 403 404 "`split over\ntwo lines`\n", 405 "<p><code>split over\ntwo lines</code></p>\n", 406 407 "```multiple ticks``` for the marker\n", 408 "<p><code>multiple ticks</code> for the marker</p>\n", 409 410 "```multiple ticks `with` ticks inside```\n", 411 "<p><code>multiple ticks `with` ticks inside</code></p>\n", 412 } 413 doTestsInline(t, tests) 414 } 415 416 func TestLineBreak(t *testing.T) { 417 var tests = []string{ 418 "this line \nhas a break\n", 419 "<p>this line<br />\nhas a break</p>\n", 420 421 "this line \ndoes not\n", 422 "<p>this line\ndoes not</p>\n", 423 424 "this line\\\ndoes not\n", 425 "<p>this line\\\ndoes not</p>\n", 426 427 "this line\\ \ndoes not\n", 428 "<p>this line\\\ndoes not</p>\n", 429 430 "this has an \nextra space\n", 431 "<p>this has an<br />\nextra space</p>\n", 432 } 433 doTestsInline(t, tests) 434 435 tests = []string{ 436 "this line \nhas a break\n", 437 "<p>this line<br />\nhas a break</p>\n", 438 439 "this line \ndoes not\n", 440 "<p>this line\ndoes not</p>\n", 441 442 "this line\\\nhas a break\n", 443 "<p>this line<br />\nhas a break</p>\n", 444 445 "this line\\ \ndoes not\n", 446 "<p>this line\\\ndoes not</p>\n", 447 448 "this has an \nextra space\n", 449 "<p>this has an<br />\nextra space</p>\n", 450 } 451 doTestsInlineParam(t, tests, Options{ 452 Extensions: EXTENSION_BACKSLASH_LINE_BREAK}, 453 0, HtmlRendererParameters{}) 454 } 455 456 func TestInlineLink(t *testing.T) { 457 var tests = []string{ 458 "[foo](/bar/)\n", 459 "<p><a href=\"/bar/\">foo</a></p>\n", 460 461 "[foo with a title](/bar/ \"title\")\n", 462 "<p><a href=\"/bar/\" title=\"title\">foo with a title</a></p>\n", 463 464 "[foo with a title](/bar/\t\"title\")\n", 465 "<p><a href=\"/bar/\" title=\"title\">foo with a title</a></p>\n", 466 467 "[foo with a title](/bar/ \"title\" )\n", 468 "<p><a href=\"/bar/\" title=\"title\">foo with a title</a></p>\n", 469 470 "[foo with a title](/bar/ title with no quotes)\n", 471 "<p><a href=\"/bar/ title with no quotes\">foo with a title</a></p>\n", 472 473 "[foo]()\n", 474 "<p>[foo]()</p>\n", 475 476 "\n", 477 "<p><img src=\"/bar/\" alt=\"foo\" /></p>\n", 478 479 "\n", 480 "<p><img src=\"/bar/\" alt=\"foo with a title\" title=\"title\" /></p>\n", 481 482 "\n", 483 "<p><img src=\"/bar/\" alt=\"foo with a title\" title=\"title\" /></p>\n", 484 485 "\n", 486 "<p><img src=\"/bar/\" alt=\"foo with a title\" title=\"title\" /></p>\n", 487 488 "\n", 489 "<p><img src=\"/bar/ title with no quotes\" alt=\"foo with a title\" /></p>\n", 490 491 "\n", 492 "<p><img src=\"img.jpg\" alt=\"\" /></p>\n", 493 494 "[link](url)\n", 495 "<p><a href=\"url\">link</a></p>\n", 496 497 "![foo]()\n", 498 "<p>![foo]()</p>\n", 499 500 "[a link]\t(/with_a_tab/)\n", 501 "<p><a href=\"/with_a_tab/\">a link</a></p>\n", 502 503 "[a link] (/with_spaces/)\n", 504 "<p><a href=\"/with_spaces/\">a link</a></p>\n", 505 506 "[text (with) [[nested] (brackets)]](/url/)\n", 507 "<p><a href=\"/url/\">text (with) [[nested] (brackets)]</a></p>\n", 508 509 "[text (with) [broken nested] (brackets)]](/url/)\n", 510 "<p>[text (with) <a href=\"brackets\">broken nested</a>]](/url/)</p>\n", 511 512 "[text\nwith a newline](/link/)\n", 513 "<p><a href=\"/link/\">text\nwith a newline</a></p>\n", 514 515 "[text in brackets] [followed](/by a link/)\n", 516 "<p>[text in brackets] <a href=\"/by a link/\">followed</a></p>\n", 517 518 "[link with\\] a closing bracket](/url/)\n", 519 "<p><a href=\"/url/\">link with] a closing bracket</a></p>\n", 520 521 "[link with\\[ an opening bracket](/url/)\n", 522 "<p><a href=\"/url/\">link with[ an opening bracket</a></p>\n", 523 524 "[link with\\) a closing paren](/url/)\n", 525 "<p><a href=\"/url/\">link with) a closing paren</a></p>\n", 526 527 "[link with\\( an opening paren](/url/)\n", 528 "<p><a href=\"/url/\">link with( an opening paren</a></p>\n", 529 530 "[link]( with whitespace)\n", 531 "<p><a href=\"with whitespace\">link</a></p>\n", 532 533 "[link]( with whitespace )\n", 534 "<p><a href=\"with whitespace\">link</a></p>\n", 535 536 "[](with image)\n", 537 "<p><a href=\"with image\"><img src=\"someimage\" alt=\"image\" /></a></p>\n", 538 539 "[link](url \"one quote)\n", 540 "<p><a href=\"url "one quote\">link</a></p>\n", 541 542 "[link](url 'one quote)\n", 543 "<p><a href=\"url 'one quote\">link</a></p>\n", 544 545 "[link](<url>)\n", 546 "<p><a href=\"url\">link</a></p>\n", 547 548 "[link & ampersand](/url/)\n", 549 "<p><a href=\"/url/\">link & ampersand</a></p>\n", 550 551 "[link & ampersand](/url/)\n", 552 "<p><a href=\"/url/\">link & ampersand</a></p>\n", 553 554 "[link](/url/&query)\n", 555 "<p><a href=\"/url/&query\">link</a></p>\n", 556 557 "[[t]](/t)\n", 558 "<p><a href=\"/t\">[t]</a></p>\n", 559 560 "[link](</>)\n", 561 "<p><a href=\"/\">link</a></p>\n", 562 563 "[link](<./>)\n", 564 "<p><a href=\"./\">link</a></p>\n", 565 566 "[link](<../>)\n", 567 "<p><a href=\"../\">link</a></p>\n", 568 569 // Issue 116 in blackfriday 570 ".jpg)", 571 "<p><img src=\"http://www.broadgate.co.uk/Content/Upload/DetailImages/Cyclus700(1).jpg\" alt=\"\" /></p>\n", 572 573 // no closing ), autolinking detects the url next 574 "[disambiguation](http://en.wikipedia.org/wiki/Disambiguation_(disambiguation) is the", 575 "<p>[disambiguation](<a href=\"http://en.wikipedia.org/wiki/Disambiguation_(disambiguation\">http://en.wikipedia.org/wiki/Disambiguation_(disambiguation</a>) is the</p>\n", 576 577 "[disambiguation](http://en.wikipedia.org/wiki/Disambiguation_(disambiguation)) is the", 578 "<p><a href=\"http://en.wikipedia.org/wiki/Disambiguation_(disambiguation)\">disambiguation</a> is the</p>\n", 579 580 "[disambiguation](http://en.wikipedia.org/wiki/Disambiguation_(disambiguation))", 581 "<p><a href=\"http://en.wikipedia.org/wiki/Disambiguation_(disambiguation)\">disambiguation</a></p>\n", 582 } 583 doLinkTestsInline(t, tests) 584 585 } 586 587 func TestRelAttrLink(t *testing.T) { 588 var nofollowTests = []string{ 589 "[foo](http://bar.com/foo/)\n", 590 "<p><a href=\"http://bar.com/foo/\" rel=\"nofollow\">foo</a></p>\n", 591 592 "[foo](/bar/)\n", 593 "<p><a href=\"/bar/\">foo</a></p>\n", 594 595 "[foo](/)\n", 596 "<p><a href=\"/\">foo</a></p>\n", 597 598 "[foo](./)\n", 599 "<p><a href=\"./\">foo</a></p>\n", 600 601 "[foo](../)\n", 602 "<p><a href=\"../\">foo</a></p>\n", 603 604 "[foo](../bar)\n", 605 "<p><a href=\"../bar\">foo</a></p>\n", 606 } 607 doTestsInlineParam(t, nofollowTests, Options{}, HTML_SAFELINK|HTML_NOFOLLOW_LINKS, 608 HtmlRendererParameters{}) 609 610 var noreferrerTests = []string{ 611 "[foo](http://bar.com/foo/)\n", 612 "<p><a href=\"http://bar.com/foo/\" rel=\"noreferrer\">foo</a></p>\n", 613 614 "[foo](/bar/)\n", 615 "<p><a href=\"/bar/\">foo</a></p>\n", 616 } 617 doTestsInlineParam(t, noreferrerTests, Options{}, HTML_SAFELINK|HTML_NOREFERRER_LINKS, 618 HtmlRendererParameters{}) 619 620 var nofollownoreferrerTests = []string{ 621 "[foo](http://bar.com/foo/)\n", 622 "<p><a href=\"http://bar.com/foo/\" rel=\"nofollow noreferrer\">foo</a></p>\n", 623 624 "[foo](/bar/)\n", 625 "<p><a href=\"/bar/\">foo</a></p>\n", 626 } 627 doTestsInlineParam(t, nofollownoreferrerTests, Options{}, HTML_SAFELINK|HTML_NOFOLLOW_LINKS|HTML_NOREFERRER_LINKS, 628 HtmlRendererParameters{}) 629 } 630 631 func TestHrefTargetBlank(t *testing.T) { 632 var tests = []string{ 633 // internal link 634 "[foo](/bar/)\n", 635 "<p><a href=\"/bar/\">foo</a></p>\n", 636 637 "[foo](/)\n", 638 "<p><a href=\"/\">foo</a></p>\n", 639 640 "[foo](./)\n", 641 "<p><a href=\"./\">foo</a></p>\n", 642 643 "[foo](./bar)\n", 644 "<p><a href=\"./bar\">foo</a></p>\n", 645 646 "[foo](../)\n", 647 "<p><a href=\"../\">foo</a></p>\n", 648 649 "[foo](../bar)\n", 650 "<p><a href=\"../bar\">foo</a></p>\n", 651 652 "[foo](http://example.com)\n", 653 "<p><a href=\"http://example.com\" target=\"_blank\">foo</a></p>\n", 654 } 655 doTestsInlineParam(t, tests, Options{}, HTML_SAFELINK|HTML_HREF_TARGET_BLANK, HtmlRendererParameters{}) 656 } 657 658 func TestSafeInlineLink(t *testing.T) { 659 var tests = []string{ 660 "[foo](/bar/)\n", 661 "<p><a href=\"/bar/\">foo</a></p>\n", 662 663 "[foo](/)\n", 664 "<p><a href=\"/\">foo</a></p>\n", 665 666 "[foo](./)\n", 667 "<p><a href=\"./\">foo</a></p>\n", 668 669 "[foo](../)\n", 670 "<p><a href=\"../\">foo</a></p>\n", 671 672 "[foo](http://bar/)\n", 673 "<p><a href=\"http://bar/\">foo</a></p>\n", 674 675 "[foo](https://bar/)\n", 676 "<p><a href=\"https://bar/\">foo</a></p>\n", 677 678 "[foo](ftp://bar/)\n", 679 "<p><a href=\"ftp://bar/\">foo</a></p>\n", 680 681 "[foo](mailto://bar/)\n", 682 "<p><a href=\"mailto://bar/\">foo</a></p>\n", 683 684 // Not considered safe 685 "[foo](baz://bar/)\n", 686 "<p><tt>foo</tt></p>\n", 687 } 688 doSafeTestsInline(t, tests) 689 } 690 691 func TestReferenceLink(t *testing.T) { 692 var tests = []string{ 693 "[link][ref]\n", 694 "<p>[link][ref]</p>\n", 695 696 "[link][ref]\n [ref]: /url/ \"title\"\n", 697 "<p><a href=\"/url/\" title=\"title\">link</a></p>\n", 698 699 "[link][ref]\n [ref]: /url/\n", 700 "<p><a href=\"/url/\">link</a></p>\n", 701 702 " [ref]: /url/\n", 703 "", 704 705 " [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n", 706 "", 707 708 " [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n [4spaces]: /url/\n", 709 "<pre><code>[4spaces]: /url/\n</code></pre>\n", 710 711 "[hmm](ref2)\n [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n", 712 "<p><a href=\"ref2\">hmm</a></p>\n", 713 714 "[ref]\n", 715 "<p>[ref]</p>\n", 716 717 "[ref]\n [ref]: /url/ \"title\"\n", 718 "<p><a href=\"/url/\" title=\"title\">ref</a></p>\n", 719 720 "[ref]\n [ref]: ../url/ \"title\"\n", 721 "<p><a href=\"../url/\" title=\"title\">ref</a></p>\n", 722 723 "[link][ref]\n [ref]: /url/", 724 "<p><a href=\"/url/\">link</a></p>\n", 725 726 // Issue 172 in blackfriday 727 "[]:<", 728 "<p>[]:<</p>\n", 729 } 730 doLinkTestsInline(t, tests) 731 } 732 733 func TestTags(t *testing.T) { 734 var tests = []string{ 735 "a <span>tag</span>\n", 736 "<p>a <span>tag</span></p>\n", 737 738 "<span>tag</span>\n", 739 "<p><span>tag</span></p>\n", 740 741 "<span>mismatch</spandex>\n", 742 "<p><span>mismatch</spandex></p>\n", 743 744 "a <singleton /> tag\n", 745 "<p>a <singleton /> tag</p>\n", 746 } 747 doTestsInline(t, tests) 748 } 749 750 func TestAutoLink(t *testing.T) { 751 var tests = []string{ 752 "http://foo.com/\n", 753 "<p><a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 754 755 "1 http://foo.com/\n", 756 "<p>1 <a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 757 758 "1http://foo.com/\n", 759 "<p>1<a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 760 761 "1.http://foo.com/\n", 762 "<p>1.<a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 763 764 "1. http://foo.com/\n", 765 "<ol>\n<li><a href=\"http://foo.com/\">http://foo.com/</a></li>\n</ol>\n", 766 767 "-http://foo.com/\n", 768 "<p>-<a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 769 770 "- http://foo.com/\n", 771 "<ul>\n<li><a href=\"http://foo.com/\">http://foo.com/</a></li>\n</ul>\n", 772 773 "_http://foo.com/\n", 774 "<p>_<a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 775 776 "令狐http://foo.com/\n", 777 "<p>令狐<a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 778 779 "令狐 http://foo.com/\n", 780 "<p>令狐 <a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 781 782 "ahttp://foo.com/\n", 783 "<p>ahttp://foo.com/</p>\n", 784 785 ">http://foo.com/\n", 786 "<blockquote>\n<p><a href=\"http://foo.com/\">http://foo.com/</a></p>\n</blockquote>\n", 787 788 "> http://foo.com/\n", 789 "<blockquote>\n<p><a href=\"http://foo.com/\">http://foo.com/</a></p>\n</blockquote>\n", 790 791 "go to <http://foo.com/>\n", 792 "<p>go to <a href=\"http://foo.com/\">http://foo.com/</a></p>\n", 793 794 "a secure <https://link.org>\n", 795 "<p>a secure <a href=\"https://link.org\">https://link.org</a></p>\n", 796 797 "an email <mailto:some@one.com>\n", 798 "<p>an email <a href=\"mailto:some@one.com\">some@one.com</a></p>\n", 799 800 "an email <mailto://some@one.com>\n", 801 "<p>an email <a href=\"mailto://some@one.com\">some@one.com</a></p>\n", 802 803 "an email <some@one.com>\n", 804 "<p>an email <a href=\"mailto:some@one.com\">some@one.com</a></p>\n", 805 806 "an ftp <ftp://old.com>\n", 807 "<p>an ftp <a href=\"ftp://old.com\">ftp://old.com</a></p>\n", 808 809 "an ftp <ftp:old.com>\n", 810 "<p>an ftp <a href=\"ftp:old.com\">ftp:old.com</a></p>\n", 811 812 "a link with <http://new.com?query=foo&bar>\n", 813 "<p>a link with <a href=\"http://new.com?query=foo&bar\">" + 814 "http://new.com?query=foo&bar</a></p>\n", 815 816 "quotes mean a tag <http://new.com?query=\"foo\"&bar>\n", 817 "<p>quotes mean a tag <http://new.com?query=\"foo\"&bar></p>\n", 818 819 "quotes mean a tag <http://new.com?query='foo'&bar>\n", 820 "<p>quotes mean a tag <http://new.com?query='foo'&bar></p>\n", 821 822 "unless escaped <http://new.com?query=\\\"foo\\\"&bar>\n", 823 "<p>unless escaped <a href=\"http://new.com?query="foo"&bar\">" + 824 "http://new.com?query="foo"&bar</a></p>\n", 825 826 "even a > can be escaped <http://new.com?q=\\>&etc>\n", 827 "<p>even a > can be escaped <a href=\"http://new.com?q=>&etc\">" + 828 "http://new.com?q=>&etc</a></p>\n", 829 830 "<a href=\"http://fancy.com\">http://fancy.com</a>\n", 831 "<p><a href=\"http://fancy.com\">http://fancy.com</a></p>\n", 832 833 "<a href=\"http://fancy.com\">This is a link</a>\n", 834 "<p><a href=\"http://fancy.com\">This is a link</a></p>\n", 835 836 "<a href=\"http://www.fancy.com/A_B.pdf\">http://www.fancy.com/A_B.pdf</a>\n", 837 "<p><a href=\"http://www.fancy.com/A_B.pdf\">http://www.fancy.com/A_B.pdf</a></p>\n", 838 839 "(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (\n", 840 "<p>(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (</p>\n", 841 842 "(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (part two: <a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a>)).\n", 843 "<p>(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (part two: <a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a>)).</p>\n", 844 845 "http://www.foo.com<br />\n", 846 "<p><a href=\"http://www.foo.com\">http://www.foo.com</a><br /></p>\n", 847 848 "http://foo.com/viewtopic.php?f=18&t=297", 849 "<p><a href=\"http://foo.com/viewtopic.php?f=18&t=297\">http://foo.com/viewtopic.php?f=18&t=297</a></p>\n", 850 851 "http://foo.com/viewtopic.php?param="18"zz", 852 "<p><a href=\"http://foo.com/viewtopic.php?param="18"zz\">http://foo.com/viewtopic.php?param="18"zz</a></p>\n", 853 854 "http://foo.com/viewtopic.php?param="18"", 855 "<p><a href=\"http://foo.com/viewtopic.php?param="18"\">http://foo.com/viewtopic.php?param="18"</a></p>\n", 856 } 857 doLinkTestsInline(t, tests) 858 } 859 860 var footnoteTests = []string{ 861 "testing footnotes.[^a]\n\n[^a]: This is the note\n", 862 `<p>testing footnotes.<sup class="footnote-ref" id="fnref:a"><a rel="footnote" href="#fn:a">1</a></sup></p> 863 <div class="footnotes"> 864 865 <hr /> 866 867 <ol> 868 <li id="fn:a">This is the note 869 </li> 870 </ol> 871 </div> 872 `, 873 874 `testing long[^b] notes. 875 876 [^b]: Paragraph 1 877 878 Paragraph 2 879 880 ` + "```\n\tsome code\n\t```" + ` 881 882 Paragraph 3 883 884 No longer in the footnote 885 `, 886 `<p>testing long<sup class="footnote-ref" id="fnref:b"><a rel="footnote" href="#fn:b">1</a></sup> notes.</p> 887 888 <p>No longer in the footnote</p> 889 <div class="footnotes"> 890 891 <hr /> 892 893 <ol> 894 <li id="fn:b"><p>Paragraph 1</p> 895 896 <p>Paragraph 2</p> 897 898 <p><code> 899 some code 900 </code></p> 901 902 <p>Paragraph 3</p> 903 </li> 904 </ol> 905 </div> 906 `, 907 908 `testing[^c] multiple[^d] notes. 909 910 [^c]: this is [note] c 911 912 913 omg 914 915 [^d]: this is note d 916 917 what happens here 918 919 [note]: /link/c 920 921 `, 922 `<p>testing<sup class="footnote-ref" id="fnref:c"><a rel="footnote" href="#fn:c">1</a></sup> multiple<sup class="footnote-ref" id="fnref:d"><a rel="footnote" href="#fn:d">2</a></sup> notes.</p> 923 924 <p>omg</p> 925 926 <p>what happens here</p> 927 <div class="footnotes"> 928 929 <hr /> 930 931 <ol> 932 <li id="fn:c">this is <a href="/link/c">note</a> c 933 </li> 934 <li id="fn:d">this is note d 935 </li> 936 </ol> 937 </div> 938 `, 939 940 "testing inline^[this is the note] notes.\n", 941 `<p>testing inline<sup class="footnote-ref" id="fnref:this-is-the-note"><a rel="footnote" href="#fn:this-is-the-note">1</a></sup> notes.</p> 942 <div class="footnotes"> 943 944 <hr /> 945 946 <ol> 947 <li id="fn:this-is-the-note">this is the note</li> 948 </ol> 949 </div> 950 `, 951 952 "testing multiple[^1] types^[inline note] of notes[^2]\n\n[^2]: the second deferred note\n[^1]: the first deferred note\n\n\twhich happens to be a block\n", 953 `<p>testing multiple<sup class="footnote-ref" id="fnref:1"><a rel="footnote" href="#fn:1">1</a></sup> types<sup class="footnote-ref" id="fnref:inline-note"><a rel="footnote" href="#fn:inline-note">2</a></sup> of notes<sup class="footnote-ref" id="fnref:2"><a rel="footnote" href="#fn:2">3</a></sup></p> 954 <div class="footnotes"> 955 956 <hr /> 957 958 <ol> 959 <li id="fn:1"><p>the first deferred note</p> 960 961 <p>which happens to be a block</p> 962 </li> 963 <li id="fn:inline-note">inline note</li> 964 <li id="fn:2">the second deferred note 965 </li> 966 </ol> 967 </div> 968 `, 969 970 `This is a footnote[^1]^[and this is an inline footnote] 971 972 [^1]: the footnote text. 973 974 may be multiple paragraphs. 975 `, 976 `<p>This is a footnote<sup class="footnote-ref" id="fnref:1"><a rel="footnote" href="#fn:1">1</a></sup><sup class="footnote-ref" id="fnref:and-this-is-an-i"><a rel="footnote" href="#fn:and-this-is-an-i">2</a></sup></p> 977 <div class="footnotes"> 978 979 <hr /> 980 981 <ol> 982 <li id="fn:1"><p>the footnote text.</p> 983 984 <p>may be multiple paragraphs.</p> 985 </li> 986 <li id="fn:and-this-is-an-i">and this is an inline footnote</li> 987 </ol> 988 </div> 989 `, 990 991 "empty footnote[^]\n\n[^]: fn text", 992 "<p>empty footnote<sup class=\"footnote-ref\" id=\"fnref:\"><a rel=\"footnote\" href=\"#fn:\">1</a></sup></p>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:\">fn text\n</li>\n</ol>\n</div>\n", 993 994 "Some text.[^note1]\n\n[^note1]: fn1", 995 "<p>Some text.<sup class=\"footnote-ref\" id=\"fnref:note1\"><a rel=\"footnote\" href=\"#fn:note1\">1</a></sup></p>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:note1\">fn1\n</li>\n</ol>\n</div>\n", 996 997 "Some text.[^note1][^note2]\n\n[^note1]: fn1\n[^note2]: fn2\n", 998 "<p>Some text.<sup class=\"footnote-ref\" id=\"fnref:note1\"><a rel=\"footnote\" href=\"#fn:note1\">1</a></sup><sup class=\"footnote-ref\" id=\"fnref:note2\"><a rel=\"footnote\" href=\"#fn:note2\">2</a></sup></p>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:note1\">fn1\n</li>\n<li id=\"fn:note2\">fn2\n</li>\n</ol>\n</div>\n", 999 1000 `Bla bla [^1] [WWW][w3] 1001 1002 [^1]: This is a footnote 1003 1004 [w3]: http://www.w3.org/ 1005 `, 1006 `<p>Bla bla <sup class="footnote-ref" id="fnref:1"><a rel="footnote" href="#fn:1">1</a></sup> <a href="http://www.w3.org/">WWW</a></p> 1007 <div class="footnotes"> 1008 1009 <hr /> 1010 1011 <ol> 1012 <li id="fn:1">This is a footnote 1013 </li> 1014 </ol> 1015 </div> 1016 `, 1017 1018 `This is exciting![^fn1] 1019 1020 [^fn1]: Fine print 1021 `, 1022 `<p>This is exciting!<sup class="footnote-ref" id="fnref:fn1"><a rel="footnote" href="#fn:fn1">1</a></sup></p> 1023 <div class="footnotes"> 1024 1025 <hr /> 1026 1027 <ol> 1028 <li id="fn:fn1">Fine print 1029 </li> 1030 </ol> 1031 </div> 1032 `, 1033 } 1034 1035 func TestFootnotes(t *testing.T) { 1036 doTestsInlineParam(t, footnoteTests, Options{Extensions: EXTENSION_FOOTNOTES}, 0, HtmlRendererParameters{}) 1037 } 1038 1039 func TestFootnotesWithParameters(t *testing.T) { 1040 tests := make([]string, len(footnoteTests)) 1041 1042 prefix := "testPrefix" 1043 returnText := "ret" 1044 re := regexp.MustCompile(`(?ms)<li id="fn:(\S+?)">(.*?)</li>`) 1045 1046 // Transform the test expectations to match the parameters we're using. 1047 for i, test := range footnoteTests { 1048 if i%2 == 1 { 1049 test = strings.Replace(test, "fn:", "fn:"+prefix, -1) 1050 test = strings.Replace(test, "fnref:", "fnref:"+prefix, -1) 1051 test = re.ReplaceAllString(test, `<li id="fn:$1">$2 <a class="footnote-return" href="#fnref:$1">ret</a></li>`) 1052 } 1053 tests[i] = test 1054 } 1055 1056 params := HtmlRendererParameters{ 1057 FootnoteAnchorPrefix: prefix, 1058 FootnoteReturnLinkContents: returnText, 1059 } 1060 1061 doTestsInlineParam(t, tests, Options{Extensions: EXTENSION_FOOTNOTES}, HTML_FOOTNOTE_RETURN_LINKS, params) 1062 } 1063 1064 func TestNestedFootnotes(t *testing.T) { 1065 var tests = []string{ 1066 `Paragraph.[^fn1] 1067 1068 [^fn1]: 1069 Asterisk[^fn2] 1070 1071 [^fn2]: 1072 Obelisk`, 1073 `<p>Paragraph.<sup class="footnote-ref" id="fnref:fn1"><a rel="footnote" href="#fn:fn1">1</a></sup></p> 1074 <div class="footnotes"> 1075 1076 <hr /> 1077 1078 <ol> 1079 <li id="fn:fn1">Asterisk<sup class="footnote-ref" id="fnref:fn2"><a rel="footnote" href="#fn:fn2">2</a></sup> 1080 </li> 1081 <li id="fn:fn2">Obelisk 1082 </li> 1083 </ol> 1084 </div> 1085 `, 1086 } 1087 doTestsInlineParam(t, tests, Options{Extensions: EXTENSION_FOOTNOTES}, 0, 1088 HtmlRendererParameters{}) 1089 } 1090 1091 func TestInlineComments(t *testing.T) { 1092 var tests = []string{ 1093 "Hello <!-- there ->\n", 1094 "<p>Hello <!— there –></p>\n", 1095 1096 "Hello <!-- there -->\n", 1097 "<p>Hello <!-- there --></p>\n", 1098 1099 "Hello <!-- there -->", 1100 "<p>Hello <!-- there --></p>\n", 1101 1102 "Hello <!---->\n", 1103 "<p>Hello <!----></p>\n", 1104 1105 "Hello <!-- there -->\na", 1106 "<p>Hello <!-- there -->\na</p>\n", 1107 1108 "* list <!-- item -->\n", 1109 "<ul>\n<li>list <!-- item --></li>\n</ul>\n", 1110 1111 "<!-- Front --> comment\n", 1112 "<p><!-- Front --> comment</p>\n", 1113 1114 "blahblah\n<!--- foo -->\nrhubarb\n", 1115 "<p>blahblah\n<!--- foo -->\nrhubarb</p>\n", 1116 } 1117 doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{}) 1118 } 1119 1120 func TestSmartDoubleQuotes(t *testing.T) { 1121 var tests = []string{ 1122 "this should be normal \"quoted\" text.\n", 1123 "<p>this should be normal “quoted” text.</p>\n", 1124 "this \" single double\n", 1125 "<p>this “ single double</p>\n", 1126 "two pair of \"some\" quoted \"text\".\n", 1127 "<p>two pair of “some” quoted “text”.</p>\n"} 1128 1129 doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS, HtmlRendererParameters{}) 1130 } 1131 1132 func TestSmartAngledDoubleQuotes(t *testing.T) { 1133 var tests = []string{ 1134 "this should be angled \"quoted\" text.\n", 1135 "<p>this should be angled «quoted» text.</p>\n", 1136 "this \" single double\n", 1137 "<p>this « single double</p>\n", 1138 "two pair of \"some\" quoted \"text\".\n", 1139 "<p>two pair of «some» quoted «text».</p>\n"} 1140 1141 doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES, HtmlRendererParameters{}) 1142 } 1143 1144 func TestSmartFractions(t *testing.T) { 1145 var tests = []string{ 1146 "1/2, 1/4 and 3/4; 1/4th and 3/4ths\n", 1147 "<p>½, ¼ and ¾; ¼th and ¾ths</p>\n", 1148 "1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n", 1149 "<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"} 1150 1151 doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS, HtmlRendererParameters{}) 1152 1153 tests = []string{ 1154 "1/2, 2/3, 81/100 and 1000000/1048576.\n", 1155 "<p><sup>1</sup>⁄<sub>2</sub>, <sup>2</sup>⁄<sub>3</sub>, <sup>81</sup>⁄<sub>100</sub> and <sup>1000000</sup>⁄<sub>1048576</sub>.</p>\n", 1156 "1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n", 1157 "<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"} 1158 1159 doTestsInlineParam(t, tests, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_FRACTIONS, HtmlRendererParameters{}) 1160 } 1161 1162 func TestDisableSmartDashes(t *testing.T) { 1163 doTestsInlineParam(t, []string{ 1164 "foo - bar\n", 1165 "<p>foo - bar</p>\n", 1166 "foo -- bar\n", 1167 "<p>foo -- bar</p>\n", 1168 "foo --- bar\n", 1169 "<p>foo --- bar</p>\n", 1170 }, Options{}, 0, HtmlRendererParameters{}) 1171 doTestsInlineParam(t, []string{ 1172 "foo - bar\n", 1173 "<p>foo – bar</p>\n", 1174 "foo -- bar\n", 1175 "<p>foo — bar</p>\n", 1176 "foo --- bar\n", 1177 "<p>foo —– bar</p>\n", 1178 }, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_DASHES, HtmlRendererParameters{}) 1179 doTestsInlineParam(t, []string{ 1180 "foo - bar\n", 1181 "<p>foo - bar</p>\n", 1182 "foo -- bar\n", 1183 "<p>foo – bar</p>\n", 1184 "foo --- bar\n", 1185 "<p>foo — bar</p>\n", 1186 }, Options{}, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES|HTML_SMARTYPANTS_DASHES, 1187 HtmlRendererParameters{}) 1188 doTestsInlineParam(t, []string{ 1189 "foo - bar\n", 1190 "<p>foo - bar</p>\n", 1191 "foo -- bar\n", 1192 "<p>foo -- bar</p>\n", 1193 "foo --- bar\n", 1194 "<p>foo --- bar</p>\n", 1195 }, Options{}, 1196 HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_LATEX_DASHES, 1197 HtmlRendererParameters{}) 1198 }