summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-04-12 10:15:02 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-04-12 14:41:32 +0200
commit5596dc24a0adc8907f52886a8e035e1bcd66dd8d (patch)
tree372bece1601ed69fc92e3925e6183b6a1b9293e2
parentd01731d53c7c9492cb9666a1223419691a95006c (diff)
markup/goldmark: Add config options for the typographer extension
Note that the config per language part of this will be handled in #10602. Updates #9772
-rw-r--r--markup/goldmark/convert.go26
-rw-r--r--markup/goldmark/convert_test.go15
-rw-r--r--markup/goldmark/goldmark_config/config.go43
-rw-r--r--markup/markup_config/config.go33
-rw-r--r--markup/markup_config/config_test.go34
5 files changed, 139 insertions, 12 deletions
diff --git a/markup/goldmark/convert.go b/markup/goldmark/convert.go
index 3c8dbb299..efcfb7142 100644
--- a/markup/goldmark/convert.go
+++ b/markup/goldmark/convert.go
@@ -20,6 +20,7 @@ import (
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/markup/goldmark/codeblocks"
+ "github.com/gohugoio/hugo/markup/goldmark/goldmark_config"
"github.com/gohugoio/hugo/markup/goldmark/images"
"github.com/gohugoio/hugo/markup/goldmark/internal/extensions/attributes"
"github.com/gohugoio/hugo/markup/goldmark/internal/render"
@@ -120,8 +121,11 @@ func newMarkdown(pcfg converter.ProviderConfig) goldmark.Markdown {
extensions = append(extensions, extension.TaskList)
}
- if cfg.Extensions.Typographer {
- extensions = append(extensions, extension.Typographer)
+ if !cfg.Extensions.Typographer.Disable {
+ t := extension.NewTypographer(
+ extension.WithTypographicSubstitutions(toTypographicPunctuationMap(cfg.Extensions.Typographer)),
+ )
+ extensions = append(extensions, t)
}
if cfg.Extensions.DefinitionList {
@@ -278,3 +282,21 @@ func (p *parserContext) TableOfContents() *tableofcontents.Fragments {
}
return nil
}
+
+// Note: It's tempting to put this in the config package, but that doesn't work.
+// TODO(bep) create upstream issue.
+func toTypographicPunctuationMap(t goldmark_config.Typographer) map[extension.TypographicPunctuation][]byte {
+ return map[extension.TypographicPunctuation][]byte{
+ extension.LeftSingleQuote: []byte(t.LeftSingleQuote),
+ extension.RightSingleQuote: []byte(t.RightSingleQuote),
+ extension.LeftDoubleQuote: []byte(t.LeftDoubleQuote),
+ extension.RightDoubleQuote: []byte(t.RightDoubleQuote),
+ extension.EnDash: []byte(t.EnDash),
+ extension.EmDash: []byte(t.EmDash),
+ extension.Ellipsis: []byte(t.Ellipsis),
+ extension.LeftAngleQuote: []byte(t.LeftAngleQuote),
+ extension.RightAngleQuote: []byte(t.RightAngleQuote),
+ extension.Apostrophe: []byte(t.Apostrophe),
+ }
+
+}
diff --git a/markup/goldmark/convert_test.go b/markup/goldmark/convert_test.go
index 647ffce58..e92c651fc 100644
--- a/markup/goldmark/convert_test.go
+++ b/markup/goldmark/convert_test.go
@@ -499,3 +499,18 @@ LINE5
c.Assert(result, qt.Contains, "<span class=\"ln\">2</span><span class=\"cl\">LINE2\n</span></span>")
})
}
+
+func TestTypographerConfig(t *testing.T) {
+ c := qt.New(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 = "&laquo;"
+ mconf.Goldmark.Extensions.Typographer.RightDoubleQuote = "&raquo;"
+ b := convert(c, mconf, content)
+ got := string(b.Bytes())
+
+ 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")
+}
diff --git a/markup/goldmark/goldmark_config/config.go b/markup/goldmark/goldmark_config/config.go
index ff0b6bbef..f35427ac1 100644
--- a/markup/goldmark/goldmark_config/config.go
+++ b/markup/goldmark/goldmark_config/config.go
@@ -23,7 +23,19 @@ const (
// DefaultConfig holds the default Goldmark configuration.
var Default = Config{
Extensions: Extensions{
- Typographer: true,
+ Typographer: Typographer{
+ Disable: false,
+ LeftSingleQuote: "&lsquo;",
+ RightSingleQuote: "&rsquo;",
+ LeftDoubleQuote: "&ldquo;",
+ RightDoubleQuote: "&rdquo;",
+ EnDash: "&ndash;",
+ EmDash: "&mdash;",
+ Ellipsis: "&hellip;",
+ LeftAngleQuote: "&laquo;",
+ RightAngleQuote: "&raquo;",
+ Apostrophe: "&rsquo;",
+ },
Footnote: true,
DefinitionList: true,
Table: true,
@@ -54,7 +66,7 @@ type Config struct {
}
type Extensions struct {
- Typographer bool
+ Typographer Typographer
Footnote bool
DefinitionList bool
@@ -66,6 +78,33 @@ type Extensions struct {
TaskList bool
}
+// Typographer holds typographer configuration.
+type Typographer struct {
+ // Whether to disable typographer.
+ Disable bool
+
+ // Value used for left single quote.
+ LeftSingleQuote string
+ // Value used for right single quote.
+ RightSingleQuote string
+ // Value used for left double quote.
+ LeftDoubleQuote string
+ // Value used for right double quote.
+ RightDoubleQuote string
+ // Value used for en dash.
+ EnDash string
+ // Value used for em dash.
+ EmDash string
+ // Value used for ellipsis.
+ Ellipsis string
+ // Value used for left angle quote.
+ LeftAngleQuote string
+ // Value used for right angle quote.
+ RightAngleQuote string
+ // Value used for apostrophe.
+ Apostrophe string
+}
+
type Renderer struct {
// Whether softline breaks should be rendered as '<br>'
HardWraps bool
diff --git a/markup/markup_config/config.go b/markup/markup_config/config.go
index e254ba7a0..60446b9bc 100644
--- a/markup/markup_config/config.go
+++ b/markup/markup_config/config.go
@@ -62,15 +62,32 @@ func Decode(cfg config.Provider) (conf Config, err error) {
func normalizeConfig(m map[string]any) {
v, err := maps.GetNestedParam("goldmark.parser", ".", m)
- if err != nil {
- return
+ if err == nil {
+ vm := maps.ToStringMap(v)
+ // Changed from a bool in 0.81.0
+ if vv, found := vm["attribute"]; found {
+ if vvb, ok := vv.(bool); ok {
+ vm["attribute"] = goldmark_config.ParserAttribute{
+ Title: vvb,
+ }
+ }
+ }
}
- vm := maps.ToStringMap(v)
- // Changed from a bool in 0.81.0
- if vv, found := vm["attribute"]; found {
- if vvb, ok := vv.(bool); ok {
- vm["attribute"] = goldmark_config.ParserAttribute{
- Title: vvb,
+
+ // Changed from a bool in 0.112.0.
+ v, err = maps.GetNestedParam("goldmark.extensions", ".", m)
+ if err == nil {
+ vm := maps.ToStringMap(v)
+ const typographerKey = "typographer"
+ if vv, found := vm[typographerKey]; found {
+ if vvb, ok := vv.(bool); ok {
+ if !vvb {
+ vm[typographerKey] = goldmark_config.Typographer{
+ Disable: true,
+ }
+ } else {
+ delete(vm, typographerKey)
+ }
}
}
}
diff --git a/markup/markup_config/config_test.go b/markup/markup_config/config_test.go
index a320e6912..782cedbc9 100644
--- a/markup/markup_config/config_test.go
+++ b/markup/markup_config/config_test.go
@@ -52,4 +52,38 @@ func TestConfig(t *testing.T) {
c.Assert(conf.AsciidocExt.Extensions[0], qt.Equals, "asciidoctor-html5s")
})
+ c.Run("Decode legacy typographer", func(c *qt.C) {
+ c.Parallel()
+ v := config.New()
+
+ // typographer was changed from a bool to a struct in 0.112.0.
+ v.Set("markup", map[string]any{
+ "goldmark": map[string]any{
+ "extensions": map[string]any{
+ "typographer": false,
+ },
+ },
+ })
+
+ conf, err := Decode(v)
+
+ c.Assert(err, qt.IsNil)
+ c.Assert(conf.Goldmark.Extensions.Typographer.Disable, qt.Equals, true)
+
+ v.Set("markup", map[string]any{
+ "goldmark": map[string]any{
+ "extensions": map[string]any{
+ "typographer": true,
+ },
+ },
+ })
+
+ conf, err = Decode(v)
+
+ c.Assert(err, qt.IsNil)
+ c.Assert(conf.Goldmark.Extensions.Typographer.Disable, qt.Equals, false)
+ c.Assert(conf.Goldmark.Extensions.Typographer.Ellipsis, qt.Equals, "&hellip;")
+
+ })
+
}