diff --git a/markdown.go b/markdown.go index 85d8928..86f0493 100644 --- a/markdown.go +++ b/markdown.go @@ -6,9 +6,12 @@ import ( "github.com/yuin/goldmark" "github.com/yuin/goldmark-emoji" "github.com/yuin/goldmark-emoji/definition" + "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/util" "strings" "sync" ) @@ -32,8 +35,10 @@ func initMarkdown() { extension.Typographer, // Emojis emoji.New( - emoji.WithEmojis(EmojiGoLib()), + emoji.WithEmojis(emojiGoLib()), ), + // Links + newLinkExtension(), ), ) } @@ -45,7 +50,10 @@ func renderMarkdown(source string) (content []byte, err error) { return } -func EmojiGoLib() definition.Emojis { +// Extensions etc... + +// All emojis from emoji lib +func emojiGoLib() definition.Emojis { emojiOnce.Do(func() { var emojis []definition.Emoji for shotcode, e := range kemoji.CodeMap() { @@ -55,3 +63,55 @@ func EmojiGoLib() definition.Emojis { }) return emojilib } + +// Links +type linkExtension struct{} + +func newLinkExtension() goldmark.Extender { + return &linkExtension{} +} + +func (l *linkExtension) Extend(m goldmark.Markdown) { + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(newLinkRenderer(), 500), + )) +} + +type linkRenderer struct{} + +func (l *linkRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) { + r.Register(ast.KindLink, l.renderLink) +} + +func (l *linkRenderer) renderLink(w util.BufWriter, _ []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.Link) + if entering { + // Make URL absolute if it's relative + newDestination := string(util.URLEscape(n.Destination, true)) + if strings.HasPrefix(newDestination, "/") { + newDestination = appConfig.Server.PublicAddress + newDestination + } + // Write URL + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("") + } + return ast.WalkContinue, nil +} + +func newLinkRenderer() renderer.NodeRenderer { + return &linkRenderer{} +}