providers/markdown: Create a default markdown provider

This commit is contained in:
Sasha Koshka 2024-12-05 21:29:37 -05:00
parent adc39a8a4f
commit 44f3be2c4f

View File

@ -6,20 +6,39 @@ import "strings"
import "html/template"
import "github.com/yuin/goldmark"
import "github.com/yuin/goldmark/parser"
import "github.com/yuin/goldmark/renderer"
import "github.com/yuin/goldmark/extension"
import "git.tebibyte.media/sashakoshka/step"
import "github.com/yuin/goldmark/renderer/html"
var _ step.FuncProvider = new(Provider)
// Provider provides Markdown functions.
type Provider struct {
// Options contains parse options that are passed to the converter.
Options []parser.ParseOption
Extensions []goldmark.Extender
ParserOptions []parser.Option
RendererOptions []renderer.Option
}
// Default returns a provider with the default configuration.
func Default () *Provider {
return &Provider {
Extensions: []goldmark.Extender { extension.GFM },
ParserOptions: []parser.Option { parser.WithAutoHeadingID() },
RendererOptions: []renderer.Option {
html.WithXHTML(),
html.WithUnsafe(),
},
}
}
// FuncMap fulfills the step.FuncProvider interface.
func (this *Provider) FuncMap () template.FuncMap {
stat := &state {
options: this.Options,
md: goldmark.New (
goldmark.WithExtensions(this.Extensions...),
goldmark.WithParserOptions(this.ParserOptions...),
goldmark.WithRendererOptions(this.RendererOptions...)),
}
return template.FuncMap {
"markdown": stat.funcMarkdown,
@ -27,12 +46,12 @@ func (this *Provider) FuncMap () template.FuncMap {
}
type state struct {
options []parser.ParseOption
md goldmark.Markdown
}
func (this *state) funcMarkdown (input any) (template.HTML, error) {
builder := strings.Builder { }
err := goldmark.Convert(toBytes(input), &builder, this.options...)
err := this.md.Convert(toBytes(input), &builder)
if err != nil { return "", nil }
return template.HTML(builder.String()), nil
}