mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-29 22:29:56 +02:00
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
This commit is contained in:
@@ -54,7 +54,7 @@ func (p provide) New(cfg converter.ProviderConfig) (converter.Provider, error) {
|
||||
cfg: cfg,
|
||||
md: md,
|
||||
sanitizeAnchorName: func(s string) string {
|
||||
return sanitizeAnchorNameString(s, cfg.MarkupConfig.Goldmark.Parser.AutoHeadingIDType)
|
||||
return sanitizeAnchorNameString(s, cfg.MarkupConfig().Goldmark.Parser.AutoHeadingIDType)
|
||||
},
|
||||
}, nil
|
||||
}), nil
|
||||
@@ -75,8 +75,8 @@ func (c *goldmarkConverter) SanitizeAnchorName(s string) string {
|
||||
}
|
||||
|
||||
func newMarkdown(pcfg converter.ProviderConfig) goldmark.Markdown {
|
||||
mcfg := pcfg.MarkupConfig
|
||||
cfg := pcfg.MarkupConfig.Goldmark
|
||||
mcfg := pcfg.MarkupConfig()
|
||||
cfg := mcfg.Goldmark
|
||||
var rendererOptions []renderer.Option
|
||||
|
||||
if cfg.Renderer.HardWraps {
|
||||
@@ -265,7 +265,7 @@ func (c *goldmarkConverter) Supports(feature identity.Identity) bool {
|
||||
}
|
||||
|
||||
func (c *goldmarkConverter) newParserContext(rctx converter.RenderContext) *parserContext {
|
||||
ctx := parser.NewContext(parser.WithIDs(newIDFactory(c.cfg.MarkupConfig.Goldmark.Parser.AutoHeadingIDType)))
|
||||
ctx := parser.NewContext(parser.WithIDs(newIDFactory(c.cfg.MarkupConfig().Goldmark.Parser.AutoHeadingIDType)))
|
||||
ctx.Set(tocEnableKey, rctx.RenderTOC)
|
||||
return &parserContext{
|
||||
Context: ctx,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Hugo Authors. All rights reserved.
|
||||
// Copyright 2023 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -11,37 +11,52 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package goldmark
|
||||
package goldmark_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
"github.com/gohugoio/hugo/markup/converter/hooks"
|
||||
"github.com/gohugoio/hugo/markup/goldmark/goldmark_config"
|
||||
"github.com/gohugoio/hugo/markup/goldmark"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/highlight"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/markup_config"
|
||||
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
func convert(c *qt.C, mconf markup_config.Config, content string) converter.ResultRender {
|
||||
p, err := Provider.New(
|
||||
converter.ProviderConfig{
|
||||
MarkupConfig: mconf,
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
},
|
||||
var cfgStrHighlichgtNoClasses = `
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noclasses=false
|
||||
`
|
||||
|
||||
func convert(c *qt.C, conf config.AllProvider, content string) converter.ResultRender {
|
||||
pconf := converter.ProviderConfig{
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
Conf: conf,
|
||||
}
|
||||
|
||||
p, err := goldmark.Provider.New(
|
||||
pconf,
|
||||
)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
mconf := pconf.MarkupConfig()
|
||||
|
||||
h := highlight.New(mconf.Highlight)
|
||||
|
||||
getRenderer := func(t hooks.RendererType, id any) any {
|
||||
@@ -140,11 +155,17 @@ description
|
||||
|
||||
// Code fences
|
||||
content = strings.Replace(content, "§§§", "```", -1)
|
||||
mconf := markup_config.Default
|
||||
mconf.Highlight.NoClasses = false
|
||||
mconf.Goldmark.Renderer.Unsafe = true
|
||||
|
||||
b := convert(c, mconf, content)
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noClasses = false
|
||||
[markup.goldmark.renderer]
|
||||
unsafe = true
|
||||
|
||||
`)
|
||||
|
||||
b := convert(c, testconfig.GetTestConfig(nil, cfg), content)
|
||||
got := string(b.Bytes())
|
||||
|
||||
fmt.Println(got)
|
||||
@@ -193,9 +214,17 @@ func TestConvertAutoIDAsciiOnly(t *testing.T) {
|
||||
content := `
|
||||
## God is Good: 神真美好
|
||||
`
|
||||
mconf := markup_config.Default
|
||||
mconf.Goldmark.Parser.AutoHeadingIDType = goldmark_config.AutoHeadingIDTypeGitHubAscii
|
||||
b := convert(c, mconf, content)
|
||||
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.goldmark]
|
||||
[markup.goldmark.parser]
|
||||
autoHeadingIDType = 'github-ascii'
|
||||
|
||||
`)
|
||||
|
||||
b := convert(c, testconfig.GetTestConfig(nil, cfg), content)
|
||||
|
||||
got := string(b.Bytes())
|
||||
|
||||
c.Assert(got, qt.Contains, "<h2 id=\"god-is-good-\">")
|
||||
@@ -208,9 +237,16 @@ func TestConvertAutoIDBlackfriday(t *testing.T) {
|
||||
## Let's try this, shall we?
|
||||
|
||||
`
|
||||
mconf := markup_config.Default
|
||||
mconf.Goldmark.Parser.AutoHeadingIDType = goldmark_config.AutoHeadingIDTypeBlackfriday
|
||||
b := convert(c, mconf, content)
|
||||
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.goldmark]
|
||||
[markup.goldmark.parser]
|
||||
autoHeadingIDType = 'blackfriday'
|
||||
`)
|
||||
|
||||
b := convert(c, testconfig.GetTestConfig(nil, cfg), content)
|
||||
|
||||
got := string(b.Bytes())
|
||||
|
||||
c.Assert(got, qt.Contains, "<h2 id=\"let-s-try-this-shall-we\">")
|
||||
@@ -356,7 +392,13 @@ func TestConvertAttributes(t *testing.T) {
|
||||
if test.withConfig != nil {
|
||||
test.withConfig(&mconf)
|
||||
}
|
||||
b := convert(c, mconf, test.input)
|
||||
data, err := toml.Marshal(mconf)
|
||||
c.Assert(err, qt.IsNil)
|
||||
m := maps.Params{
|
||||
"markup": config.FromTOMLConfigString(string(data)).Get(""),
|
||||
}
|
||||
conf := testconfig.GetTestConfig(nil, config.NewFrom(m))
|
||||
b := convert(c, conf, test.input)
|
||||
got := string(b.Bytes())
|
||||
|
||||
for _, s := range cast.ToStringSlice(test.expect) {
|
||||
@@ -378,7 +420,7 @@ func TestConvertIssues(t *testing.T) {
|
||||
</custom-element>
|
||||
`
|
||||
|
||||
b := convert(c, mconf, input)
|
||||
b := convert(c, unsafeConf(), input)
|
||||
got := string(b.Bytes())
|
||||
|
||||
c.Assert(got, qt.Contains, "<custom-element>\n <div>This will be \"slotted\" into the custom element.</div>\n</custom-element>\n")
|
||||
@@ -395,18 +437,18 @@ LINE4
|
||||
LINE5
|
||||
`
|
||||
|
||||
convertForConfig := func(c *qt.C, conf highlight.Config, code, language string) string {
|
||||
mconf := markup_config.Default
|
||||
mconf.Highlight = conf
|
||||
|
||||
p, err := Provider.New(
|
||||
converter.ProviderConfig{
|
||||
MarkupConfig: mconf,
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
},
|
||||
convertForConfig := func(c *qt.C, confStr, code, language string) string {
|
||||
cfg := config.FromTOMLConfigString(confStr)
|
||||
conf := testconfig.GetTestConfig(nil, cfg)
|
||||
pcfg := converter.ProviderConfig{
|
||||
Conf: conf,
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
}
|
||||
p, err := goldmark.Provider.New(
|
||||
pcfg,
|
||||
)
|
||||
|
||||
h := highlight.New(conf)
|
||||
h := highlight.New(pcfg.MarkupConfig().Highlight)
|
||||
|
||||
getRenderer := func(t hooks.RendererType, id any) any {
|
||||
if t == hooks.CodeBlockRendererType {
|
||||
@@ -427,75 +469,92 @@ LINE5
|
||||
}
|
||||
|
||||
c.Run("Basic", func(c *qt.C) {
|
||||
cfg := highlight.DefaultConfig
|
||||
cfg.NoClasses = false
|
||||
confStr := `
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noclasses=false
|
||||
`
|
||||
|
||||
result := convertForConfig(c, cfg, `echo "Hugo Rocks!"`, "bash")
|
||||
result := convertForConfig(c, confStr, `echo "Hugo Rocks!"`, "bash")
|
||||
// TODO(bep) there is a whitespace mismatch (\n) between this and the highlight template func.
|
||||
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>")
|
||||
result = convertForConfig(c, cfg, `echo "Hugo Rocks!"`, "unknown")
|
||||
result = convertForConfig(c, confStr, `echo "Hugo Rocks!"`, "unknown")
|
||||
c.Assert(result, qt.Equals, "<pre tabindex=\"0\"><code class=\"language-unknown\" data-lang=\"unknown\">echo "Hugo Rocks!"\n</code></pre>")
|
||||
})
|
||||
|
||||
c.Run("Highlight lines, default config", func(c *qt.C) {
|
||||
cfg := highlight.DefaultConfig
|
||||
cfg.NoClasses = false
|
||||
|
||||
result := convertForConfig(c, cfg, lines, `bash {linenos=table,hl_lines=[2 "4-5"],linenostart=3}`)
|
||||
result := convertForConfig(c, cfgStrHighlichgtNoClasses, lines, `bash {linenos=table,hl_lines=[2 "4-5"],linenostart=3}`)
|
||||
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")
|
||||
c.Assert(result, qt.Contains, "<span class=\"hl\"><span class=\"lnt\">4")
|
||||
|
||||
result = convertForConfig(c, cfg, lines, "bash {linenos=inline,hl_lines=[2]}")
|
||||
result = convertForConfig(c, cfgStrHighlichgtNoClasses, lines, "bash {linenos=inline,hl_lines=[2]}")
|
||||
c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span></span>")
|
||||
c.Assert(result, qt.Not(qt.Contains), "<table")
|
||||
|
||||
result = convertForConfig(c, cfg, lines, "bash {linenos=true,hl_lines=[2]}")
|
||||
result = convertForConfig(c, cfgStrHighlichgtNoClasses, lines, "bash {linenos=true,hl_lines=[2]}")
|
||||
c.Assert(result, qt.Contains, "<table")
|
||||
c.Assert(result, qt.Contains, "<span class=\"hl\"><span class=\"lnt\">2\n</span>")
|
||||
})
|
||||
|
||||
c.Run("Highlight lines, linenumbers default on", func(c *qt.C) {
|
||||
cfg := highlight.DefaultConfig
|
||||
cfg.NoClasses = false
|
||||
cfg.LineNos = true
|
||||
confStr := `
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noclasses=false
|
||||
linenos=true
|
||||
`
|
||||
|
||||
result := convertForConfig(c, cfg, lines, "bash")
|
||||
result := convertForConfig(c, confStr, lines, "bash")
|
||||
c.Assert(result, qt.Contains, "<span class=\"lnt\">2\n</span>")
|
||||
|
||||
result = convertForConfig(c, cfg, lines, "bash {linenos=false,hl_lines=[2]}")
|
||||
result = convertForConfig(c, confStr, lines, "bash {linenos=false,hl_lines=[2]}")
|
||||
c.Assert(result, qt.Not(qt.Contains), "class=\"lnt\"")
|
||||
})
|
||||
|
||||
c.Run("Highlight lines, linenumbers default on, linenumbers in table default off", func(c *qt.C) {
|
||||
cfg := highlight.DefaultConfig
|
||||
cfg.NoClasses = false
|
||||
cfg.LineNos = true
|
||||
cfg.LineNumbersInTable = false
|
||||
confStr := `
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noClasses = false
|
||||
lineNos = true
|
||||
lineNumbersInTable = false
|
||||
`
|
||||
|
||||
result := convertForConfig(c, cfg, lines, "bash")
|
||||
result := convertForConfig(c, confStr, lines, "bash")
|
||||
c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span>")
|
||||
result = convertForConfig(c, cfg, lines, "bash {linenos=table}")
|
||||
result = convertForConfig(c, confStr, lines, "bash {linenos=table}")
|
||||
c.Assert(result, qt.Contains, "<span class=\"lnt\">1\n</span>")
|
||||
})
|
||||
|
||||
c.Run("No language", func(c *qt.C) {
|
||||
confStr := `
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noClasses = false
|
||||
lineNos = true
|
||||
lineNumbersInTable = false
|
||||
`
|
||||
cfg := highlight.DefaultConfig
|
||||
cfg.NoClasses = false
|
||||
cfg.LineNos = true
|
||||
cfg.LineNumbersInTable = false
|
||||
|
||||
result := convertForConfig(c, cfg, lines, "")
|
||||
result := convertForConfig(c, confStr, lines, "")
|
||||
c.Assert(result, qt.Contains, "<pre tabindex=\"0\"><code>LINE1\n")
|
||||
})
|
||||
|
||||
c.Run("No language, guess syntax", func(c *qt.C) {
|
||||
cfg := highlight.DefaultConfig
|
||||
cfg.NoClasses = false
|
||||
cfg.GuessSyntax = true
|
||||
cfg.LineNos = true
|
||||
cfg.LineNumbersInTable = false
|
||||
confStr := `
|
||||
[markup]
|
||||
[markup.highlight]
|
||||
noClasses = false
|
||||
lineNos = true
|
||||
lineNumbersInTable = false
|
||||
guessSyntax = true
|
||||
`
|
||||
|
||||
result := convertForConfig(c, cfg, lines, "")
|
||||
result := convertForConfig(c, confStr, lines, "")
|
||||
c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span></span>")
|
||||
})
|
||||
}
|
||||
@@ -506,11 +565,41 @@ func TestTypographerConfig(t *testing.T) {
|
||||
content := `
|
||||
A "quote" and 'another quote' and a "quote with a 'nested' quote" and a 'quote with a "nested" quote' and an ellipsis...
|
||||
`
|
||||
mconf := markup_config.Default
|
||||
mconf.Goldmark.Extensions.Typographer.LeftDoubleQuote = "«"
|
||||
mconf.Goldmark.Extensions.Typographer.RightDoubleQuote = "»"
|
||||
b := convert(c, mconf, content)
|
||||
|
||||
confStr := `
|
||||
[markup]
|
||||
[markup.goldmark]
|
||||
[markup.goldmark.extensions]
|
||||
[markup.goldmark.extensions.typographer]
|
||||
leftDoubleQuote = "«"
|
||||
rightDoubleQuote = "»"
|
||||
`
|
||||
|
||||
cfg := config.FromTOMLConfigString(confStr)
|
||||
conf := testconfig.GetTestConfig(nil, cfg)
|
||||
|
||||
b := convert(c, conf, content)
|
||||
got := string(b.Bytes())
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
func unsafeConf() config.AllProvider {
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.goldmark.renderer]
|
||||
unsafe = true
|
||||
`)
|
||||
return testconfig.GetTestConfig(nil, cfg)
|
||||
|
||||
}
|
||||
|
||||
func safeConf() config.AllProvider {
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.goldmark.renderer]
|
||||
unsafe = false
|
||||
`)
|
||||
return testconfig.GetTestConfig(nil, cfg)
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Hugo Authors. All rights reserved.
|
||||
// Copyright 2023 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -11,15 +11,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package goldmark converts Markdown to HTML using Goldmark.
|
||||
package goldmark
|
||||
package goldmark_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
"github.com/gohugoio/hugo/markup/converter/hooks"
|
||||
"github.com/gohugoio/hugo/markup/markup_config"
|
||||
"github.com/gohugoio/hugo/markup/goldmark"
|
||||
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
|
||||
@@ -53,10 +53,10 @@ And then some.
|
||||
#### First H4
|
||||
|
||||
`
|
||||
p, err := Provider.New(
|
||||
p, err := goldmark.Provider.New(
|
||||
converter.ProviderConfig{
|
||||
MarkupConfig: markup_config.Default,
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
Conf: testconfig.GetTestConfig(nil, nil),
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
})
|
||||
c.Assert(err, qt.IsNil)
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
@@ -83,23 +83,15 @@ And then some.
|
||||
func TestEscapeToc(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
defaultConfig := markup_config.Default
|
||||
|
||||
safeConfig := defaultConfig
|
||||
unsafeConfig := defaultConfig
|
||||
|
||||
safeConfig.Goldmark.Renderer.Unsafe = false
|
||||
unsafeConfig.Goldmark.Renderer.Unsafe = true
|
||||
|
||||
safeP, _ := Provider.New(
|
||||
safeP, _ := goldmark.Provider.New(
|
||||
converter.ProviderConfig{
|
||||
MarkupConfig: safeConfig,
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
Conf: safeConf(),
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
})
|
||||
unsafeP, _ := Provider.New(
|
||||
unsafeP, _ := goldmark.Provider.New(
|
||||
converter.ProviderConfig{
|
||||
MarkupConfig: unsafeConfig,
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
Conf: unsafeConf(),
|
||||
Logger: loggers.NewErrorLogger(),
|
||||
})
|
||||
safeConv, _ := safeP.New(converter.DocumentContext{})
|
||||
unsafeConv, _ := unsafeP.New(converter.DocumentContext{})
|
||||
|
Reference in New Issue
Block a user