diff --git a/go.mod b/go.mod
index 18866e8..3c666be 100644
--- a/go.mod
+++ b/go.mod
@@ -36,6 +36,7 @@ require (
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/x448/float16 v0.8.4 // indirect
+ github.com/yuin/goldmark v1.8.5 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/crypto v0.47.0 // indirect
diff --git a/go.sum b/go.sum
index 4ef7f61..5895126 100644
--- a/go.sum
+++ b/go.sum
@@ -124,6 +124,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
+github.com/yuin/goldmark v1.8.5/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
diff --git a/renderer/markdown.go b/renderer/markdown.go
index aa24f11..6c491f4 100644
--- a/renderer/markdown.go
+++ b/renderer/markdown.go
@@ -17,6 +17,7 @@
package renderer
import (
+ "bytes"
"fmt"
"io/fs"
"os"
@@ -24,6 +25,11 @@ import (
"strings"
"text/template"
+ "github.com/yuin/goldmark"
+ "github.com/yuin/goldmark/extension"
+ "github.com/yuin/goldmark/parser"
+ "github.com/yuin/goldmark/renderer/html"
+
"github.com/Masterminds/sprig/v3"
"github.com/elastic/crd-ref-docs/config"
"github.com/elastic/crd-ref-docs/templates"
@@ -78,7 +84,9 @@ func (m *MarkdownRenderer) ToFuncMap() template.FuncMap {
"ShouldRenderType": m.ShouldRenderType,
"TypeID": m.TypeID,
"RenderFieldDoc": m.RenderFieldDoc,
+ "RenderFieldHTML": m.RenderFieldHTML,
"RenderDefault": m.RenderDefault,
+ "RenderValidation": m.RenderValidation,
"TemplateValue": m.TemplateValue,
}
}
@@ -186,9 +194,74 @@ func (m *MarkdownRenderer) RenderFieldDoc(text string) string {
return strings.ReplaceAll(out, "
", "
")
}
+// RenderFieldHTML renders a field whose docs are written in Markdown themselves
+// as a single line of formatted HTML, that can be included in a Markdown table.
+func (m *MarkdownRenderer) RenderFieldHTML(text string) string {
+ out := m.RewriteLinks(text)
+
+ md := goldmark.New(
+ goldmark.WithExtensions(extension.GFM),
+ goldmark.WithParserOptions(
+ parser.WithAutoHeadingID(),
+ ),
+ goldmark.WithRendererOptions(
+ html.WithXHTML(),
+ ),
+ )
+
+ var buf bytes.Buffer
+ docstringBytes := []byte(text)
+
+ if err := md.Convert(docstringBytes, &buf); err != nil {
+ panic(err)
+ }
+
+ out = buf.String()
+
+ // Escape the pipe character, which has special meaning for Markdown as a way to format tables
+ // so that including | in a comment does not result in wonky tables.
+ out = strings.ReplaceAll(out, "|", "\\|")
+
+ // Escape the curly bracket character.
+ out = strings.ReplaceAll(out, "{", "\\{")
+ out = strings.ReplaceAll(out, "}", "\\}")
+
+ // Replace any newlines that are left with spaces.
+ out = strings.ReplaceAll(out, "\n", " ")
+ // and remove double newline generated for empty lines
+ // empty line is still rendered in the table, without removing the duplicate
+ // newline it would be rendered as two empty lines
+ return strings.ReplaceAll(out, "
", "
")
+}
+
func (m *MarkdownRenderer) RenderDefault(text string) string {
- return strings.NewReplacer(
- "{", "\\{",
- "}", "\\}",
- ).Replace(text)
+ out := text
+
+ if strings.Contains(out, "{") ||
+ strings.Contains(out, "[") {
+ out = fmt.Sprintf("`%s`", out)
+ }
+
+ return out
+}
+
+// RenderValidation renders validation with special handling
+// for Required and Optional validations.
+func (m *MarkdownRenderer) RenderValidation(text string) string {
+ out := text
+
+ if strings.HasPrefix(out, "Optional") {
+ return "_Optional_"
+ }
+
+ if strings.HasPrefix(out, "Required") {
+ return "_Required_"
+ }
+
+ out = strings.ReplaceAll(out, "|", "\\|")
+ // Escape the curly bracket character.
+ out = strings.ReplaceAll(out, "{", "\\{")
+ out = strings.ReplaceAll(out, "}", "\\}")
+
+ return out
}