home/internal/templateutil/transform/transform.go

83 lines
1.7 KiB
Go

package transform
import (
"bytes"
"errors"
"fmt"
"html/template"
"reflect"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark-emoji"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
renderer "github.com/yuin/goldmark/renderer/html"
)
type Namespace struct {
markdown goldmark.Markdown
}
var ErrMarkdownify error = errors.New("unsupported input type for Markdownify")
func New() *Namespace {
md := goldmark.New(
// goldmark.WithParser(),
// goldmark.WithRenderer(),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
parser.WithAttribute(),
),
goldmark.WithRendererOptions(
renderer.WithUnsafe(),
),
goldmark.WithExtensions(
extension.Table,
extension.Strikethrough,
extension.Linkify,
extension.TaskList,
extension.DefinitionList,
extension.Footnote,
extension.NewTypographer(
extension.WithTypographicSubstitutions(extension.TypographicSubstitutions{
extension.LeftDoubleQuote: []byte(``),
extension.LeftAngleQuote: []byte(`«`),
extension.RightDoubleQuote: []byte(``),
extension.RightAngleQuote: []byte(`»`),
}),
),
emoji.Emoji,
),
)
return &Namespace{
markdown: md,
}
}
func (ns *Namespace) Markdownify(v reflect.Value) (template.HTML, error) {
var err error
buf := bytes.NewBuffer(nil)
switch v.Kind() {
default:
return "", ErrMarkdownify
case reflect.Slice:
switch v.Type().Elem().Kind() {
default:
return "", ErrMarkdownify
case reflect.Uint8:
err = ns.markdown.Convert(v.Bytes(), buf)
}
case reflect.String:
err = ns.markdown.Convert(v.Bytes(), buf)
}
if err != nil {
return "", fmt.Errorf("cannot convert input into markdown: %w", err)
}
return template.HTML(buf.String()), nil
}