go/pkg/markdown/convert.go

54 lines
1.3 KiB
Go

package markdown
import (
"bytes"
"github.com/avelino/awesome-go/pkg/slug"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/util"
)
// ToHTML converts markdown byte slice to a HTML byte slice
func ToHTML(markdown []byte) ([]byte, error) {
md := goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(), // generate heading IDs for content navigation
),
goldmark.WithRendererOptions(
html.WithXHTML(),
html.WithUnsafe(), // allow inline HTML
),
)
ctx := parser.NewContext(
parser.WithIDs(&IDGenerator{}), // register custom ID generator
)
var buf bytes.Buffer
if err := md.Convert(markdown, &buf, parser.WithContext(ctx)); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// IDGenerator for goldmark to provide IDs more similar to GitHub's IDs on markdown parsing
type IDGenerator struct {
used map[string]bool
}
// Generate an ID
func (g *IDGenerator) Generate(value []byte, _ ast.NodeKind) []byte {
return []byte(slug.Generate(string(value)))
}
// Put an ID to the list of already used IDs
func (g *IDGenerator) Put(value []byte) {
g.used[util.BytesToReadOnlyString(value)] = true
}