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