mirror of https://github.com/mautrix/go.git
74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
// Copyright (c) 2024 Tulir Asokan
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package mdext
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/yuin/goldmark"
|
|
"github.com/yuin/goldmark/ast"
|
|
"github.com/yuin/goldmark/renderer"
|
|
"github.com/yuin/goldmark/util"
|
|
)
|
|
|
|
type extCustomEmoji struct{}
|
|
type customEmojiRenderer struct {
|
|
funcs functionCapturer
|
|
}
|
|
|
|
// CustomEmoji is an extension that converts certain markdown images into Matrix custom emojis.
|
|
var CustomEmoji = &extCustomEmoji{}
|
|
|
|
type functionCapturer struct {
|
|
renderImage renderer.NodeRendererFunc
|
|
renderText renderer.NodeRendererFunc
|
|
renderString renderer.NodeRendererFunc
|
|
}
|
|
|
|
func (fc *functionCapturer) Register(kind ast.NodeKind, rendererFunc renderer.NodeRendererFunc) {
|
|
switch kind {
|
|
case ast.KindImage:
|
|
fc.renderImage = rendererFunc
|
|
case ast.KindText:
|
|
fc.renderText = rendererFunc
|
|
case ast.KindString:
|
|
fc.renderString = rendererFunc
|
|
}
|
|
}
|
|
|
|
var (
|
|
_ renderer.NodeRendererFuncRegisterer = (*functionCapturer)(nil)
|
|
_ renderer.Option = (*functionCapturer)(nil)
|
|
)
|
|
|
|
func (fc *functionCapturer) SetConfig(cfg *renderer.Config) {
|
|
cfg.NodeRenderers[0].Value.(renderer.NodeRenderer).RegisterFuncs(fc)
|
|
}
|
|
|
|
func (eeh *extCustomEmoji) Extend(m goldmark.Markdown) {
|
|
var fc functionCapturer
|
|
m.Renderer().AddOptions(&fc)
|
|
m.Renderer().AddOptions(renderer.WithNodeRenderers(util.Prioritized(&customEmojiRenderer{fc}, 0)))
|
|
}
|
|
|
|
func (cer *customEmojiRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
|
|
reg.Register(ast.KindImage, cer.renderImage)
|
|
}
|
|
|
|
var emojiPrefix = []byte("Emoji: ")
|
|
var mxcPrefix = []byte("mxc://")
|
|
|
|
func (cer *customEmojiRenderer) renderImage(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
|
n, ok := node.(*ast.Image)
|
|
if ok && entering && bytes.HasPrefix(n.Title, emojiPrefix) && bytes.HasPrefix(n.Destination, mxcPrefix) {
|
|
n.Title = bytes.TrimPrefix(n.Title, emojiPrefix)
|
|
n.SetAttributeString("data-mx-emoticon", nil)
|
|
n.SetAttributeString("height", "32")
|
|
}
|
|
return cer.funcs.renderImage(w, source, node, entering)
|
|
}
|