diff --git a/README.md b/README.md
index ef74fc9f..f1591780 100644
--- a/README.md
+++ b/README.md
@@ -160,6 +160,7 @@ Parser and Renderer options
| `html.WithHardWraps` | `-` | Render newlines as `
`.|
| `html.WithXHTML` | `-` | Render as XHTML. |
| `html.WithUnsafe` | `-` | By default, goldmark does not render raw HTML or potentially dangerous links. With this option, goldmark renders such content as written. |
+| `html.WithCodeClassPrefix` | `string` | Sets a custom prefix for the `class` attribute of `` elements. An empty string removes the prefix. |
### Built-in extensions
diff --git a/extra_test.go b/extra_test.go
index a2d3d623..9bae4918 100644
--- a/extra_test.go
+++ b/extra_test.go
@@ -219,3 +219,41 @@ func TestDangerousURLStringCase(t *testing.T) {
t.Error("Dangerous URL should ignore cases:\n" + string(testutil.DiffPretty(expected, b.Bytes())))
}
}
+
+func TestCodeClassPrefix(t *testing.T) {
+ cases := []struct {
+ prefix string
+ source string
+ expected string
+ }{
+ {
+ prefix: "language-",
+ source: "```go\ncode\n```",
+ expected: "code\n
\n",
+ },
+ {
+ prefix: "custom-",
+ source: "```go\ncode\n```",
+ expected: "code\n
\n",
+ },
+ {
+ prefix: "",
+ source: "```go\ncode\n```",
+ expected: "code\n
\n",
+ },
+ }
+
+ for _, c := range cases {
+ markdown := New(WithRendererOptions(
+ html.WithCodeClassPrefix(c.prefix),
+ ))
+ var b bytes.Buffer
+ err := markdown.Convert([]byte(c.source), &b)
+ if err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if b.String() != c.expected {
+ t.Errorf("prefix: %q\nsource: %q\nexpected: %q\ngot: %q", c.prefix, c.source, c.expected, b.String())
+ }
+ }
+}
diff --git a/renderer/html/html.go b/renderer/html/html.go
index 903dc680..08308546 100644
--- a/renderer/html/html.go
+++ b/renderer/html/html.go
@@ -20,8 +20,12 @@ type Config struct {
EastAsianLineBreaks EastAsianLineBreaks
XHTML bool
Unsafe bool
+ CodeClassPrefix string
}
+// Default class prefix for elements.
+const DefaultCodeClassPrefix = "language-"
+
// NewConfig returns a new Config with defaults.
func NewConfig() Config {
return Config{
@@ -30,6 +34,7 @@ func NewConfig() Config {
EastAsianLineBreaks: EastAsianLineBreaksNone,
XHTML: false,
Unsafe: false,
+ CodeClassPrefix: DefaultCodeClassPrefix,
}
}
@@ -46,6 +51,8 @@ func (c *Config) SetOption(name renderer.OptionName, value interface{}) {
c.Unsafe = value.(bool)
case optTextWriter:
c.Writer = value.(Writer)
+ case optCodeClassPrefix:
+ c.CodeClassPrefix = value.(string)
}
}
@@ -240,6 +247,29 @@ func WithUnsafe() interface {
return &withUnsafe{}
}
+// CodeClassPrefix is an option name used in WithCodeClassPrefix.
+const optCodeClassPrefix renderer.OptionName = "CodeClassPrefix"
+
+type withCodeClassPrefix struct {
+ value string
+}
+
+func (o *withCodeClassPrefix) SetConfig(c *renderer.Config) {
+ c.Options[optCodeClassPrefix] = o.value
+}
+
+func (o *withCodeClassPrefix) SetHTMLOption(c *Config) {
+ c.CodeClassPrefix = o.value
+}
+
+// WithCodeClassPrefix is a functional option to set the class prefix for elements.
+func WithCodeClassPrefix(prefix string) interface {
+ renderer.Option
+ Option
+} {
+ return &withCodeClassPrefix{prefix}
+}
+
// A Renderer struct is an implementation of renderer.NodeRenderer that renders
// nodes as (X)HTML.
type Renderer struct {
@@ -360,7 +390,8 @@ func (r *Renderer) renderFencedCodeBlock(
_, _ = w.WriteString("