From d0d2c6795e0870bf96d167700a475737a17ea005 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Sat, 6 Jan 2024 08:53:24 -0800 Subject: [PATCH] markup/goldmark: Support passthrough extension Fixes #10894 --- go.mod | 1 + go.sum | 2 + markup/goldmark/convert.go | 28 ++++++ markup/goldmark/goldmark_config/config.go | 30 +++++++ markup/goldmark/integration_test.go | 100 ++++++++++++++++++++++ 5 files changed, 161 insertions(+) diff --git a/go.mod b/go.mod index 3dbd300da39..bc782e01279 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/gobuffalo/flect v1.0.2 github.com/gobwas/glob v0.2.3 github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e + github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.1.0 github.com/gohugoio/locales v0.14.0 github.com/gohugoio/localescompressed v1.0.1 github.com/gohugoio/testmodBuilder/mods v0.0.0-20190520184928-c56af20f2e95 diff --git a/go.sum b/go.sum index 212ec6457a6..ccad130bad0 100644 --- a/go.sum +++ b/go.sum @@ -166,6 +166,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e h1:QArsSubW7eDh8APMXkByjQWvuljwPGAGQpJEFn0F0wY= github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e/go.mod h1:3Ltoo9Banwq0gOtcOwxuHG6omk+AwsQPADyw2vQYOJQ= +github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.1.0 h1:oFQ3f1M3Ook6amHmbqVu/uBRrQ6yjMDFkIv4HQr0f1Y= +github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.1.0/go.mod h1:g9CCh+Ci2IMbPUrVJuXbBTrA+rIIx5+hDQ4EXYaQDoM= github.com/gohugoio/locales v0.14.0 h1:Q0gpsZwfv7ATHMbcTNepFd59H7GoykzWJIxi113XGDc= github.com/gohugoio/locales v0.14.0/go.mod h1:ip8cCAv/cnmVLzzXtiTpPwgJ4xhKZranqNqtoIu0b/4= github.com/gohugoio/localescompressed v1.0.1 h1:KTYMi8fCWYLswFyJAeOtuk/EkXR/KPTHHNN9OS+RTxo= diff --git a/markup/goldmark/convert.go b/markup/goldmark/convert.go index 6ebcd8a7779..56cc56fcdd4 100644 --- a/markup/goldmark/convert.go +++ b/markup/goldmark/convert.go @@ -19,6 +19,7 @@ import ( "github.com/gohugoio/hugo/identity" + "github.com/gohugoio/hugo-goldmark-extensions/passthrough" "github.com/gohugoio/hugo/markup/goldmark/codeblocks" "github.com/gohugoio/hugo/markup/goldmark/goldmark_config" "github.com/gohugoio/hugo/markup/goldmark/images" @@ -154,6 +155,33 @@ func newMarkdown(pcfg converter.ProviderConfig) goldmark.Markdown { extensions = append(extensions, c) } + if cfg.Extensions.Passthrough.Enable { + configuredInlines := cfg.Extensions.Passthrough.Delimiters.Inline + configuredBlocks := cfg.Extensions.Passthrough.Delimiters.Block + + inlineDelimiters := make([]passthrough.Delimiters, len(configuredInlines)) + blockDelimiters := make([]passthrough.Delimiters, len(configuredBlocks)) + + for i, d := range configuredInlines { + inlineDelimiters[i] = passthrough.Delimiters{ + Open: d[0], + Close: d[1], + } + } + + for i, d := range configuredBlocks { + blockDelimiters[i] = passthrough.Delimiters{ + Open: d[0], + Close: d[1], + } + } + + extensions = append(extensions, passthrough.NewPassthroughWithDelimiters( + inlineDelimiters, + blockDelimiters, + )) + } + if pcfg.Conf.EnableEmoji() { extensions = append(extensions, emoji.Emoji) } diff --git a/markup/goldmark/goldmark_config/config.go b/markup/goldmark/goldmark_config/config.go index cdfb4e7cc00..ba1874a184b 100644 --- a/markup/goldmark/goldmark_config/config.go +++ b/markup/goldmark/goldmark_config/config.go @@ -49,6 +49,13 @@ var Default = Config{ EastAsianLineBreaksStyle: "simple", EscapedSpace: false, }, + Passthrough: Passthrough{ + Enable: false, + Delimiters: DelimitersConfig{ + Inline: [][]string{}, + Block: [][]string{}, + }, + }, }, Renderer: Renderer{ Unsafe: false, @@ -75,6 +82,7 @@ type Extensions struct { Typographer Typographer Footnote bool DefinitionList bool + Passthrough Passthrough // GitHub flavored markdown Table bool @@ -112,6 +120,28 @@ type Typographer struct { Apostrophe string } +// Passthrough hold passthrough configuration. +// github.com/hugoio/hugo-goldmark-extensions/passthrough +type Passthrough struct { + // Whether to enable the extension + Enable bool + + // The delimiters to use for inline and block passthroughs. + Delimiters DelimitersConfig +} + +type DelimitersConfig struct { + // The delimiters to use for inline passthroughs. Each entry in the list + // is a size-2 list of strings, where the first string is the opening delimiter + // and the second string is the closing delimiter, e.g., + // + // [["$", "$"], ["\\(", "\\)"]] + Inline [][]string + + // The delimiters to use for block passthroughs. Same format as Inline. + Block [][]string +} + type CJK struct { // Whether to enable CJK support. Enable bool diff --git a/markup/goldmark/integration_test.go b/markup/goldmark/integration_test.go index a2bf1637489..c9c6ef33864 100644 --- a/markup/goldmark/integration_test.go +++ b/markup/goldmark/integration_test.go @@ -711,3 +711,103 @@ echo "hello"; b := hugolib.Test(t, files) b.AssertFileContent("public/index.html", "
\n
") } + +// Issue #10894 +func TestPassthroughInlineFences(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +[markup.goldmark.extensions.passthrough] +enable = true +[markup.goldmark.extensions.passthrough.delimiters] +inline = [['$', '$'], ['\(', '\)']] +-- content/p1.md -- +--- +title: "p1" +--- +## LaTeX test + +Inline equation that would be mangled by default parser: $a^*=x-b^*$ + +-- layouts/_default/single.html -- +{{ .Content }} +` + + b := hugolib.Test(t, files) + b.AssertFileContent("public/p1/index.html", ` + $a^*=x-b^*$ + `) +} + +func TestPassthroughBlockFences(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +[markup.goldmark.extensions.passthrough] +enable = true +[markup.goldmark.extensions.passthrough.delimiters] +block = [['$$', '$$']] +-- content/p1.md -- +--- +title: "p1" +--- +## LaTeX test + +Block equation that would be mangled by default parser: + +$$a^*=x-b^*$$ + +-- layouts/_default/single.html -- +{{ .Content }} +` + + b := hugolib.Test(t, files) + b.AssertFileContent("public/p1/index.html", ` + $$a^*=x-b^*$$ + `) +} + +func TestPassthroughWithAlternativeFences(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +[markup.goldmark.extensions.passthrough] +enable = true +[markup.goldmark.extensions.passthrough.delimiters] +inline = [['(((', ')))']] +block = [['%!%', '%!%']] +-- content/p1.md -- +--- +title: "p1" +--- +## LaTeX test + +Inline equation that would be mangled by default parser: (((a^*=x-b^*))) +Inline equation that should be mangled by default parser: $a^*=x-b^*$ + +Block equation that would be mangled by default parser: + +%!% +a^*=x-b^* +%!% + +-- layouts/_default/single.html -- +{{ .Content }} +` + + b := hugolib.Test(t, files) + b.AssertFileContent("public/p1/index.html", ` + (((a^*=x-b^*))) + `) + b.AssertFileContent("public/p1/index.html", ` + $a^=x-b^$ + `) + b.AssertFileContent("public/p1/index.html", ` +%!% +a^*=x-b^* +%!% + `) +}