github.com/anakojm/hugo-katex@v0.0.0-20231023141351-42d6f5de9c0b/markup/goldmark/convert_test.go (about) 1 // Copyright 2023 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package goldmark_test 15 16 import ( 17 "fmt" 18 "strings" 19 "testing" 20 21 "github.com/pelletier/go-toml/v2" 22 "github.com/spf13/cast" 23 24 "github.com/gohugoio/hugo/config" 25 "github.com/gohugoio/hugo/config/testconfig" 26 "github.com/gohugoio/hugo/markup/converter/hooks" 27 "github.com/gohugoio/hugo/markup/goldmark" 28 29 "github.com/gohugoio/hugo/markup/highlight" 30 31 "github.com/gohugoio/hugo/markup/markup_config" 32 33 "github.com/gohugoio/hugo/common/loggers" 34 "github.com/gohugoio/hugo/common/maps" 35 36 "github.com/gohugoio/hugo/markup/converter" 37 38 qt "github.com/frankban/quicktest" 39 ) 40 41 var cfgStrHighlichgtNoClasses = ` 42 [markup] 43 [markup.highlight] 44 noclasses=false 45 ` 46 47 func convert(c *qt.C, conf config.AllProvider, content string) converter.ResultRender { 48 pconf := converter.ProviderConfig{ 49 Logger: loggers.NewDefault(), 50 Conf: conf, 51 } 52 53 p, err := goldmark.Provider.New( 54 pconf, 55 ) 56 c.Assert(err, qt.IsNil) 57 58 mconf := pconf.MarkupConfig() 59 60 h := highlight.New(mconf.Highlight) 61 62 getRenderer := func(t hooks.RendererType, id any) any { 63 if t == hooks.CodeBlockRendererType { 64 return h 65 } 66 return nil 67 } 68 69 conv, err := p.New(converter.DocumentContext{DocumentID: "thedoc"}) 70 c.Assert(err, qt.IsNil) 71 b, err := conv.Convert(converter.RenderContext{RenderTOC: true, Src: []byte(content), GetRenderer: getRenderer}) 72 c.Assert(err, qt.IsNil) 73 74 return b 75 } 76 77 func TestConvert(t *testing.T) { 78 c := qt.New(t) 79 80 // Smoke test of the default configuration. 81 content := ` 82 ## Links 83 84 https://github.com/gohugoio/hugo/issues/6528 85 [Live Demo here!](https://docuapi.netlify.com/) 86 87 [I'm an inline-style link with title](https://www.google.com "Google's Homepage") 88 <https://foo.bar/> 89 https://bar.baz/ 90 <fake@example.com> 91 <mailto:fake2@example.com> 92 93 94 ## Code Fences 95 96 §§§bash 97 LINE1 98 §§§ 99 100 ## Code Fences No Lexer 101 102 §§§moo 103 LINE1 104 §§§ 105 106 ## Custom ID {#custom} 107 108 ## Auto ID 109 110 * Autolink: https://gohugo.io/ 111 * Strikethrough:~~Hi~~ Hello, world! 112 113 ## Table 114 115 | foo | bar | 116 | --- | --- | 117 | baz | bim | 118 119 ## Task Lists (default on) 120 121 - [x] Finish my changes[^1] 122 - [ ] Push my commits to GitHub 123 - [ ] Open a pull request 124 125 126 ## Smartypants (default on) 127 128 * Straight double "quotes" and single 'quotes' into “curly” quote HTML entities 129 * Dashes (“--” and “---”) into en- and em-dash entities 130 * Three consecutive dots (“...”) into an ellipsis entity 131 * Apostrophes are also converted: "That was back in the '90s, that's a long time ago" 132 133 ## Footnotes 134 135 That's some text with a footnote.[^1] 136 137 ## Definition Lists 138 139 date 140 : the datetime assigned to this page. 141 142 description 143 : the description for the content. 144 145 146 ## 神真美好 147 148 ## 神真美好 149 150 ## 神真美好 151 152 [^1]: And that's the footnote. 153 154 ` 155 156 // Code fences 157 content = strings.Replace(content, "§§§", "```", -1) 158 159 cfg := config.FromTOMLConfigString(` 160 [markup] 161 [markup.highlight] 162 noClasses = false 163 [markup.goldmark.renderer] 164 unsafe = true 165 166 `) 167 168 b := convert(c, testconfig.GetTestConfig(nil, cfg), content) 169 got := string(b.Bytes()) 170 171 fmt.Println(got) 172 173 // Links 174 c.Assert(got, qt.Contains, `<a href="https://docuapi.netlify.com/">Live Demo here!</a>`) 175 c.Assert(got, qt.Contains, `<a href="https://foo.bar/">https://foo.bar/</a>`) 176 c.Assert(got, qt.Contains, `<a href="https://bar.baz/">https://bar.baz/</a>`) 177 c.Assert(got, qt.Contains, `<a href="mailto:fake@example.com">fake@example.com</a>`) 178 c.Assert(got, qt.Contains, `<a href="mailto:fake2@example.com">mailto:fake2@example.com</a></p>`) 179 180 // Header IDs 181 c.Assert(got, qt.Contains, `<h2 id="custom">Custom ID</h2>`, qt.Commentf(got)) 182 c.Assert(got, qt.Contains, `<h2 id="auto-id">Auto ID</h2>`, qt.Commentf(got)) 183 c.Assert(got, qt.Contains, `<h2 id="神真美好">神真美好</h2>`, qt.Commentf(got)) 184 c.Assert(got, qt.Contains, `<h2 id="神真美好-1">神真美好</h2>`, qt.Commentf(got)) 185 c.Assert(got, qt.Contains, `<h2 id="神真美好-2">神真美好</h2>`, qt.Commentf(got)) 186 187 // Code fences 188 c.Assert(got, qt.Contains, "<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">LINE1\n</span></span></code></pre></div>") 189 c.Assert(got, qt.Contains, "Code Fences No Lexer</h2>\n<pre tabindex=\"0\"><code class=\"language-moo\" data-lang=\"moo\">LINE1\n</code></pre>") 190 191 // Extensions 192 c.Assert(got, qt.Contains, `Autolink: <a href="https://gohugo.io/">https://gohugo.io/</a>`) 193 c.Assert(got, qt.Contains, `Strikethrough:<del>Hi</del> Hello, world`) 194 c.Assert(got, qt.Contains, `<th>foo</th>`) 195 c.Assert(got, qt.Contains, `<li><input disabled="" type="checkbox"> Push my commits to GitHub</li>`) 196 197 c.Assert(got, qt.Contains, `Straight double “quotes” and single ‘quotes’`) 198 c.Assert(got, qt.Contains, `Dashes (“–” and “—”) `) 199 c.Assert(got, qt.Contains, `Three consecutive dots (“…”)`) 200 c.Assert(got, qt.Contains, `“That was back in the ’90s, that’s a long time ago”`) 201 c.Assert(got, qt.Contains, `footnote.<sup id="fnref1:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>`) 202 c.Assert(got, qt.Contains, `<div class="footnotes" role="doc-endnotes">`) 203 c.Assert(got, qt.Contains, `<dt>date</dt>`) 204 205 toc, ok := b.(converter.TableOfContentsProvider) 206 c.Assert(ok, qt.Equals, true) 207 tocString := string(toc.TableOfContents().ToHTML(1, 2, false)) 208 c.Assert(tocString, qt.Contains, "TableOfContents") 209 } 210 211 func TestConvertAutoIDAsciiOnly(t *testing.T) { 212 c := qt.New(t) 213 214 content := ` 215 ## God is Good: 神真美好 216 ` 217 218 cfg := config.FromTOMLConfigString(` 219 [markup] 220 [markup.goldmark] 221 [markup.goldmark.parser] 222 autoHeadingIDType = 'github-ascii' 223 224 `) 225 226 b := convert(c, testconfig.GetTestConfig(nil, cfg), content) 227 228 got := string(b.Bytes()) 229 230 c.Assert(got, qt.Contains, "<h2 id=\"god-is-good-\">") 231 } 232 233 func TestConvertAutoIDBlackfriday(t *testing.T) { 234 c := qt.New(t) 235 236 content := ` 237 ## Let's try this, shall we? 238 239 ` 240 241 cfg := config.FromTOMLConfigString(` 242 [markup] 243 [markup.goldmark] 244 [markup.goldmark.parser] 245 autoHeadingIDType = 'blackfriday' 246 `) 247 248 b := convert(c, testconfig.GetTestConfig(nil, cfg), content) 249 250 got := string(b.Bytes()) 251 252 c.Assert(got, qt.Contains, "<h2 id=\"let-s-try-this-shall-we\">") 253 } 254 255 func TestConvertAttributes(t *testing.T) { 256 c := qt.New(t) 257 258 withBlockAttributes := func(conf *markup_config.Config) { 259 conf.Goldmark.Parser.Attribute.Block = true 260 conf.Goldmark.Parser.Attribute.Title = false 261 } 262 263 withTitleAndBlockAttributes := func(conf *markup_config.Config) { 264 conf.Goldmark.Parser.Attribute.Block = true 265 conf.Goldmark.Parser.Attribute.Title = true 266 } 267 268 for _, test := range []struct { 269 name string 270 withConfig func(conf *markup_config.Config) 271 input string 272 expect any 273 }{ 274 { 275 "Title", 276 nil, 277 "## heading {#id .className attrName=attrValue class=\"class1 class2\"}", 278 "<h2 id=\"id\" class=\"className class1 class2\" attrName=\"attrValue\">heading</h2>\n", 279 }, 280 { 281 "Blockquote", 282 withBlockAttributes, 283 "> foo\n> bar\n{#id .className attrName=attrValue class=\"class1 class2\"}\n", 284 "<blockquote id=\"id\" class=\"className class1 class2\"><p>foo\nbar</p>\n</blockquote>\n", 285 }, 286 /*{ 287 // TODO(bep) this needs an upstream fix, see https://github.com/yuin/goldmark/issues/195 288 "Code block, CodeFences=false", 289 func(conf *markup_config.Config) { 290 withBlockAttributes(conf) 291 conf.Highlight.CodeFences = false 292 }, 293 "```bash\necho 'foo';\n```\n{.myclass}", 294 "TODO", 295 },*/ 296 { 297 "Code block, CodeFences=true", 298 func(conf *markup_config.Config) { 299 withBlockAttributes(conf) 300 conf.Highlight.CodeFences = true 301 }, 302 "```bash {.myclass id=\"myid\"}\necho 'foo';\n````\n", 303 "<div class=\"highlight myclass\" id=\"myid\"><pre style", 304 }, 305 { 306 "Code block, CodeFences=true,linenos=table", 307 func(conf *markup_config.Config) { 308 withBlockAttributes(conf) 309 conf.Highlight.CodeFences = true 310 }, 311 "```bash {linenos=table .myclass id=\"myid\"}\necho 'foo';\n````\n{ .adfadf }", 312 []string{ 313 "div class=\"highlight myclass\" id=\"myid\"><div s", 314 "table style", 315 }, 316 }, 317 { 318 "Code block, CodeFences=true,lineanchors", 319 func(conf *markup_config.Config) { 320 withBlockAttributes(conf) 321 conf.Highlight.CodeFences = true 322 conf.Highlight.NoClasses = false 323 }, 324 "```bash {linenos=table, anchorlinenos=true, lineanchors=org-coderef--xyz}\necho 'foo';\n```", 325 "<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre tabindex=\"0\" class=\"chroma\"><code><span class=\"lnt\" id=\"org-coderef--xyz-1\"><a href=\"#org-coderef--xyz-1\">1</a>\n</span></code></pre></td>\n<td class=\"lntd\">\n<pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo</span> <span class=\"s1\">'foo'</span><span class=\"p\">;</span>\n</span></span></code></pre></td></tr></table>\n</div>\n</div>", 326 }, 327 { 328 "Code block, CodeFences=true,lineanchors, default ordinal", 329 func(conf *markup_config.Config) { 330 withBlockAttributes(conf) 331 conf.Highlight.CodeFences = true 332 conf.Highlight.NoClasses = false 333 }, 334 "```bash {linenos=inline, anchorlinenos=true}\necho 'foo';\nnecho 'bar';\n```\n\n```bash {linenos=inline, anchorlinenos=true}\necho 'baz';\nnecho 'qux';\n```", 335 []string{ 336 "<span class=\"ln\" id=\"hl-0-1\"><a class=\"lnlinks\" href=\"#hl-0-1\">1</a></span><span class=\"cl\"><span class=\"nb\">echo</span> <span class=\"s1\">'foo'</span>", 337 "<span class=\"ln\" id=\"hl-0-2\"><a class=\"lnlinks\" href=\"#hl-0-2\">2</a></span><span class=\"cl\">necho <span class=\"s1\">'bar'</span>", 338 "<span class=\"ln\" id=\"hl-1-2\"><a class=\"lnlinks\" href=\"#hl-1-2\">2</a></span><span class=\"cl\">necho <span class=\"s1\">'qux'</span>", 339 }, 340 }, 341 { 342 "Paragraph", 343 withBlockAttributes, 344 "\nHi there.\n{.myclass }", 345 "<p class=\"myclass\">Hi there.</p>\n", 346 }, 347 { 348 "Ordered list", 349 withBlockAttributes, 350 "\n1. First\n2. Second\n{.myclass }", 351 "<ol class=\"myclass\">\n<li>First</li>\n<li>Second</li>\n</ol>\n", 352 }, 353 { 354 "Unordered list", 355 withBlockAttributes, 356 "\n* First\n* Second\n{.myclass }", 357 "<ul class=\"myclass\">\n<li>First</li>\n<li>Second</li>\n</ul>\n", 358 }, 359 { 360 "Unordered list, indented", 361 withBlockAttributes, 362 `* Fruit 363 * Apple 364 * Orange 365 * Banana 366 {.fruits} 367 * Dairy 368 * Milk 369 * Cheese 370 {.dairies} 371 {.list}`, 372 []string{"<ul class=\"list\">\n<li>Fruit\n<ul class=\"fruits\">", "<li>Dairy\n<ul class=\"dairies\">"}, 373 }, 374 { 375 "Table", 376 withBlockAttributes, 377 `| A | B | 378 | ------------- |:-------------:| -----:| 379 | AV | BV | 380 {.myclass }`, 381 "<table class=\"myclass\">\n<thead>", 382 }, 383 { 384 "Title and Blockquote", 385 withTitleAndBlockAttributes, 386 "## heading {#id .className attrName=attrValue class=\"class1 class2\"}\n> foo\n> bar\n{.myclass}", 387 "<h2 id=\"id\" class=\"className class1 class2\" attrName=\"attrValue\">heading</h2>\n<blockquote class=\"myclass\"><p>foo\nbar</p>\n</blockquote>\n", 388 }, 389 } { 390 c.Run(test.name, func(c *qt.C) { 391 mconf := markup_config.Default 392 if test.withConfig != nil { 393 test.withConfig(&mconf) 394 } 395 data, err := toml.Marshal(mconf) 396 c.Assert(err, qt.IsNil) 397 m := maps.Params{ 398 "markup": config.FromTOMLConfigString(string(data)).Get(""), 399 } 400 conf := testconfig.GetTestConfig(nil, config.NewFrom(m)) 401 b := convert(c, conf, test.input) 402 got := string(b.Bytes()) 403 404 for _, s := range cast.ToStringSlice(test.expect) { 405 c.Assert(got, qt.Contains, s) 406 } 407 }) 408 } 409 } 410 411 func TestConvertIssues(t *testing.T) { 412 c := qt.New(t) 413 414 // https://github.com/gohugoio/hugo/issues/7619 415 c.Run("Hyphen in HTML attributes", func(c *qt.C) { 416 mconf := markup_config.Default 417 mconf.Goldmark.Renderer.Unsafe = true 418 input := `<custom-element> 419 <div>This will be "slotted" into the custom element.</div> 420 </custom-element> 421 ` 422 423 b := convert(c, unsafeConf(), input) 424 got := string(b.Bytes()) 425 426 c.Assert(got, qt.Contains, "<custom-element>\n <div>This will be \"slotted\" into the custom element.</div>\n</custom-element>\n") 427 }) 428 } 429 430 func TestCodeFence(t *testing.T) { 431 c := qt.New(t) 432 433 lines := `LINE1 434 LINE2 435 LINE3 436 LINE4 437 LINE5 438 ` 439 440 convertForConfig := func(c *qt.C, confStr, code, language string) string { 441 cfg := config.FromTOMLConfigString(confStr) 442 conf := testconfig.GetTestConfig(nil, cfg) 443 pcfg := converter.ProviderConfig{ 444 Conf: conf, 445 Logger: loggers.NewDefault(), 446 } 447 p, err := goldmark.Provider.New( 448 pcfg, 449 ) 450 451 h := highlight.New(pcfg.MarkupConfig().Highlight) 452 453 getRenderer := func(t hooks.RendererType, id any) any { 454 if t == hooks.CodeBlockRendererType { 455 return h 456 } 457 return nil 458 } 459 460 content := "```" + language + "\n" + code + "\n```" 461 462 c.Assert(err, qt.IsNil) 463 conv, err := p.New(converter.DocumentContext{}) 464 c.Assert(err, qt.IsNil) 465 b, err := conv.Convert(converter.RenderContext{Src: []byte(content), GetRenderer: getRenderer}) 466 c.Assert(err, qt.IsNil) 467 468 return string(b.Bytes()) 469 } 470 471 c.Run("Basic", func(c *qt.C) { 472 confStr := ` 473 [markup] 474 [markup.highlight] 475 noclasses=false 476 ` 477 478 result := convertForConfig(c, confStr, `echo "Hugo Rocks!"`, "bash") 479 // TODO(bep) there is a whitespace mismatch (\n) between this and the highlight template func. 480 c.Assert(result, qt.Equals, "<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo</span> <span class=\"s2\">"Hugo Rocks!"</span>\n</span></span></code></pre></div>") 481 result = convertForConfig(c, confStr, `echo "Hugo Rocks!"`, "unknown") 482 c.Assert(result, qt.Equals, "<pre tabindex=\"0\"><code class=\"language-unknown\" data-lang=\"unknown\">echo "Hugo Rocks!"\n</code></pre>") 483 }) 484 485 c.Run("Highlight lines, default config", func(c *qt.C) { 486 487 result := convertForConfig(c, cfgStrHighlichgtNoClasses, lines, `bash {linenos=table,hl_lines=[2 "4-5"],linenostart=3}`) 488 c.Assert(result, qt.Contains, "<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre tabindex=\"0\" class=\"chroma\"><code><span class") 489 c.Assert(result, qt.Contains, "<span class=\"hl\"><span class=\"lnt\">4") 490 491 result = convertForConfig(c, cfgStrHighlichgtNoClasses, lines, "bash {linenos=inline,hl_lines=[2]}") 492 c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span></span>") 493 c.Assert(result, qt.Not(qt.Contains), "<table") 494 495 result = convertForConfig(c, cfgStrHighlichgtNoClasses, lines, "bash {linenos=true,hl_lines=[2]}") 496 c.Assert(result, qt.Contains, "<table") 497 c.Assert(result, qt.Contains, "<span class=\"hl\"><span class=\"lnt\">2\n</span>") 498 }) 499 500 c.Run("Highlight lines, linenumbers default on", func(c *qt.C) { 501 confStr := ` 502 [markup] 503 [markup.highlight] 504 noclasses=false 505 linenos=true 506 ` 507 508 result := convertForConfig(c, confStr, lines, "bash") 509 c.Assert(result, qt.Contains, "<span class=\"lnt\">2\n</span>") 510 511 result = convertForConfig(c, confStr, lines, "bash {linenos=false,hl_lines=[2]}") 512 c.Assert(result, qt.Not(qt.Contains), "class=\"lnt\"") 513 }) 514 515 c.Run("Highlight lines, linenumbers default on, linenumbers in table default off", func(c *qt.C) { 516 confStr := ` 517 [markup] 518 [markup.highlight] 519 noClasses = false 520 lineNos = true 521 lineNumbersInTable = false 522 ` 523 524 result := convertForConfig(c, confStr, lines, "bash") 525 c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span>") 526 result = convertForConfig(c, confStr, lines, "bash {linenos=table}") 527 c.Assert(result, qt.Contains, "<span class=\"lnt\">1\n</span>") 528 }) 529 530 c.Run("No language", func(c *qt.C) { 531 confStr := ` 532 [markup] 533 [markup.highlight] 534 noClasses = false 535 lineNos = true 536 lineNumbersInTable = false 537 ` 538 cfg := highlight.DefaultConfig 539 cfg.NoClasses = false 540 cfg.LineNos = true 541 cfg.LineNumbersInTable = false 542 543 result := convertForConfig(c, confStr, lines, "") 544 c.Assert(result, qt.Contains, "<pre tabindex=\"0\"><code>LINE1\n") 545 }) 546 547 c.Run("No language, guess syntax", func(c *qt.C) { 548 confStr := ` 549 [markup] 550 [markup.highlight] 551 noClasses = false 552 lineNos = true 553 lineNumbersInTable = false 554 guessSyntax = true 555 ` 556 557 result := convertForConfig(c, confStr, lines, "") 558 c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span></span>") 559 }) 560 } 561 562 func TestTypographerConfig(t *testing.T) { 563 c := qt.New(t) 564 565 content := ` 566 A "quote" and 'another quote' and a "quote with a 'nested' quote" and a 'quote with a "nested" quote' and an ellipsis... 567 ` 568 569 confStr := ` 570 [markup] 571 [markup.goldmark] 572 [markup.goldmark.extensions] 573 [markup.goldmark.extensions.typographer] 574 leftDoubleQuote = "«" 575 rightDoubleQuote = "»" 576 ` 577 578 cfg := config.FromTOMLConfigString(confStr) 579 conf := testconfig.GetTestConfig(nil, cfg) 580 581 b := convert(c, conf, content) 582 got := string(b.Bytes()) 583 584 c.Assert(got, qt.Contains, "<p>A «quote» and ‘another quote’ and a «quote with a ’nested’ quote» and a ‘quote with a «nested» quote’ and an ellipsis…</p>\n") 585 } 586 587 // Issue #11045 588 func TestTypographerImageAltText(t *testing.T) { 589 c := qt.New(t) 590 591 content := ` 592  593 ` 594 595 confStr := ` 596 [markup] 597 [markup.goldmark] 598 599 ` 600 601 cfg := config.FromTOMLConfigString(confStr) 602 conf := testconfig.GetTestConfig(nil, cfg) 603 604 b := convert(c, conf, content) 605 got := string(b.Bytes()) 606 607 c.Assert(got, qt.Contains, "“They didn’t even say ‘hello’!” I exclaimed.") 608 } 609 610 func unsafeConf() config.AllProvider { 611 cfg := config.FromTOMLConfigString(` 612 [markup] 613 [markup.goldmark.renderer] 614 unsafe = true 615 `) 616 return testconfig.GetTestConfig(nil, cfg) 617 618 } 619 620 func safeConf() config.AllProvider { 621 cfg := config.FromTOMLConfigString(` 622 [markup] 623 [markup.goldmark.renderer] 624 unsafe = false 625 `) 626 return testconfig.GetTestConfig(nil, cfg) 627 628 } 629 630 func TestConvertCJK(t *testing.T) { 631 c := qt.New(t) 632 633 content := ` 634 私は太郎です。 635 プログラミングが好きです。\ 運動が苦手です。 636 ` 637 638 confStr := ` 639 [markup] 640 [markup.goldmark] 641 ` 642 643 cfg := config.FromTOMLConfigString(confStr) 644 conf := testconfig.GetTestConfig(nil, cfg) 645 646 b := convert(c, conf, content) 647 got := string(b.Bytes()) 648 649 c.Assert(got, qt.Contains, "<p>私は太郎です。\nプログラミングが好きです。\\ 運動が苦手です。</p>\n") 650 } 651 652 func TestConvertCJKWithExtensionWithEastAsianLineBreaksOption(t *testing.T) { 653 c := qt.New(t) 654 655 content := ` 656 私は太郎です。 657 プログラミングが好きで、 658 運動が苦手です。 659 ` 660 661 confStr := ` 662 [markup] 663 [markup.goldmark] 664 [markup.goldmark.extensions.CJK] 665 enable=true 666 eastAsianLineBreaks=true 667 ` 668 669 cfg := config.FromTOMLConfigString(confStr) 670 conf := testconfig.GetTestConfig(nil, cfg) 671 672 b := convert(c, conf, content) 673 got := string(b.Bytes()) 674 675 c.Assert(got, qt.Contains, "<p>私は太郎です。プログラミングが好きで、運動が苦手です。</p>\n") 676 } 677 678 func TestConvertCJKWithExtensionWithEscapedSpaceOption(t *testing.T) { 679 c := qt.New(t) 680 681 content := ` 682 私は太郎です。 683 プログラミングが好きです。\ 運動が苦手です。 684 ` 685 686 confStr := ` 687 [markup] 688 [markup.goldmark] 689 [markup.goldmark.extensions.CJK] 690 enable=true 691 escapedSpace=true 692 ` 693 694 cfg := config.FromTOMLConfigString(confStr) 695 conf := testconfig.GetTestConfig(nil, cfg) 696 697 b := convert(c, conf, content) 698 got := string(b.Bytes()) 699 700 c.Assert(got, qt.Contains, "<p>私は太郎です。\nプログラミングが好きです。運動が苦手です。</p>\n") 701 }