writekit/internal/markdown/markdown.go
2026-01-09 00:16:46 +02:00

72 lines
1.4 KiB
Go

package markdown
import (
"bytes"
"sync"
"github.com/yuin/goldmark"
emoji "github.com/yuin/goldmark-emoji"
highlighting "github.com/yuin/goldmark-highlighting/v2"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
)
var (
renderers = make(map[string]goldmark.Markdown)
renderersMu sync.RWMutex
)
func getRenderer(codeTheme string) goldmark.Markdown {
if codeTheme == "" {
codeTheme = "github"
}
renderersMu.RLock()
if md, ok := renderers[codeTheme]; ok {
renderersMu.RUnlock()
return md
}
renderersMu.RUnlock()
renderersMu.Lock()
defer renderersMu.Unlock()
if md, ok := renderers[codeTheme]; ok {
return md
}
md := goldmark.New(
goldmark.WithExtensions(
extension.GFM,
extension.Typographer,
emoji.Emoji,
highlighting.NewHighlighting(
highlighting.WithStyle(codeTheme),
),
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
html.WithXHTML(),
html.WithUnsafe(),
),
)
renderers[codeTheme] = md
return md
}
func Render(source string) (string, error) {
return RenderWithTheme(source, "github")
}
func RenderWithTheme(source, codeTheme string) (string, error) {
md := getRenderer(codeTheme)
var buf bytes.Buffer
if err := md.Convert([]byte(source), &buf); err != nil {
return "", err
}
return buf.String(), nil
}