package render import ( "bytes" "fmt" chromahtml "github.com/alecthomas/chroma/v2/formatters/html" "github.com/yuin/goldmark" highlighting "github.com/yuin/goldmark-highlighting/v2" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer/html" ) // Renderer converts markdown to HTML using goldmark. type Renderer struct { md goldmark.Markdown } // New creates a Renderer with GFM, syntax highlighting, and heading anchors. func New() *Renderer { md := goldmark.New( goldmark.WithExtensions( extension.GFM, highlighting.NewHighlighting( highlighting.WithStyle("github"), highlighting.WithFormatOptions( chromahtml.WithClasses(true), ), ), ), goldmark.WithParserOptions( parser.WithAutoHeadingID(), ), goldmark.WithRendererOptions( html.WithUnsafe(), ), ) return &Renderer{md: md} } // Render converts markdown source to HTML. func (r *Renderer) Render(source []byte) (string, error) { var buf bytes.Buffer if err := r.md.Convert(source, &buf); err != nil { return "", fmt.Errorf("render markdown: %w", err) } return buf.String(), nil }