1.5 KB
markdown.go
package sharing
import (
"bytes"
"github.com/microcosm-cc/bluemonday"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
gmhtml "github.com/yuin/goldmark/renderer/html"
)
// sanitizer is a shared bluemonday policy for sanitizing rendered HTML.
// UGCPolicy allows safe formatting (p, h1-h6, a, img, code, pre, table, etc.)
// but strips script, onclick, iframe, style, and other dangerous elements.
var sanitizer = bluemonday.UGCPolicy()
// RenderMarkdown converts markdown content to sanitized HTML.
// Uses goldmark with WithUnsafe() so HTML in markdown is preserved for
// bluemonday to selectively filter, rather than being escaped wholesale.
func RenderMarkdown(content string) string {
if content == "" {
return ""
}
md := goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithRendererOptions(gmhtml.WithUnsafe()),
)
var buf bytes.Buffer
if err := md.Convert([]byte(content), &buf); err != nil {
return content // Return raw content on error
}
return sanitizer.Sanitize(buf.String())
}
// GetReadme returns the README.md content from the repository.
func GetReadme() (string, error) {
return GetFile("README.md")
}
// GetReadmeHTML returns the README.md content rendered as HTML.
func GetReadmeHTML() string {
content, err := GetReadme()
if err != nil {
return ""
}
return RenderMarkdown(content)
}
// HasReadme returns true if a README.md exists in the repository.
func HasReadme() bool {
_, err := GetFile("README.md")
return err == nil
}