72 lines
1.4 KiB
Go
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
|
|
}
|