From 7cf9c53f8a0f4413345e7ffe7853006df07316c3 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Fri, 10 Nov 2023 02:14:15 +0600 Subject: [PATCH] :sparkles: Created markdownify transform template util --- go.mod | 4 + go.sum | 5 ++ internal/templateutil/transform/transform.go | 82 ++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 internal/templateutil/transform/transform.go diff --git a/go.mod b/go.mod index bb8cfd4..851aa9c 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,10 @@ require ( require github.com/google/go-cmp v0.6.0 +require github.com/yuin/goldmark v1.6.0 + +require github.com/yuin/goldmark-emoji v1.0.2 + require ( github.com/BurntSushi/toml v0.3.1 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index e42b668..1b9e005 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,11 @@ github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68= +github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s= +github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= diff --git a/internal/templateutil/transform/transform.go b/internal/templateutil/transform/transform.go new file mode 100644 index 0000000..f3bfa53 --- /dev/null +++ b/internal/templateutil/transform/transform.go @@ -0,0 +1,82 @@ +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 +}