diff --git a/formatter.go b/formatter.go new file mode 100644 index 0000000..b59ef5d --- /dev/null +++ b/formatter.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "regexp" + "strings" + + "github.com/yuin/goldmark" + + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/format" + "maunium.net/go/mautrix/format/mdext" +) + +var mdRenderer = goldmark.New(format.Extensions, format.HTMLOptions, + goldmark.WithExtensions(mdext.EscapeHTML, mdext.SimpleSpoiler, mdext.DiscordUnderline)) +var escapeFixer = regexp.MustCompile(`\\(__[^_]|\*\*[^*])`) + +func renderDiscordMarkdown(text string) event.MessageEventContent { + text = escapeFixer.ReplaceAllStringFunc(text, func(s string) string { + return s[:2] + `\` + s[2:] + }) + return format.RenderMarkdownCustom(text, mdRenderer) +} + +var matrixHTMLParser = &format.HTMLParser{ + PillConverter: nil, + TabsToSpaces: 4, + Newline: "\n", + HorizontalLine: "\n---\n", + ItalicConverter: func(s string, context format.Context) string { + return fmt.Sprintf("*%s*", s) + }, + UnderlineConverter: func(s string, context format.Context) string { + return fmt.Sprintf("__%s__", s) + }, + TextConverter: func(s string, context format.Context) string { + return discordMarkdownEscaper.Replace(s) + }, + SpoilerConverter: func(text, reason string, ctx format.Context) string { + if reason != "" { + return fmt.Sprintf("(%s) ||%s||", reason, text) + } + return fmt.Sprintf("||%s||", text) + }, +} + +var discordMarkdownEscaper = strings.NewReplacer( + `\`, `\\`, + `_`, `\_`, + `*`, `\*`, + `~`, `\~`, + "`", "\\`", + `|`, `\|`, +) + +func parseMatrixHTML(content *event.MessageEventContent) string { + if content.Format == event.FormatHTML && len(content.FormattedBody) > 0 { + return matrixHTMLParser.Parse(content.FormattedBody, make(format.Context)) + } else { + return discordMarkdownEscaper.Replace(content.Body) + } +} diff --git a/go.mod b/go.mod index 4bcb659..5fa3bfc 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/yuin/goldmark v1.4.12 maunium.net/go/maulogger/v2 v2.3.2 - maunium.net/go/mautrix v0.11.1-0.20220529105558-04789fc73b32 + maunium.net/go/mautrix v0.11.1-0.20220529123139-5bc36b2978c1 ) require ( diff --git a/go.sum b/go.sum index 299c495..a0df833 100644 --- a/go.sum +++ b/go.sum @@ -58,5 +58,5 @@ maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= maunium.net/go/maulogger/v2 v2.3.2 h1:1XmIYmMd3PoQfp9J+PaHhpt80zpfmMqaShzUTC7FwY0= maunium.net/go/maulogger/v2 v2.3.2/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A= -maunium.net/go/mautrix v0.11.1-0.20220529105558-04789fc73b32 h1:uAYLJ44nuGvR84XAUYGVrwFRhix30CTKgDIIyVHPD6U= -maunium.net/go/mautrix v0.11.1-0.20220529105558-04789fc73b32/go.mod h1:CiKpMhAx5QZFHK03jpWb0iKI3sGU8x6+LfsOjDrcO8I= +maunium.net/go/mautrix v0.11.1-0.20220529123139-5bc36b2978c1 h1:HNntVQh0XVyWDAsSQA/0Rk2++1cGOzmm7tH8xILSsak= +maunium.net/go/mautrix v0.11.1-0.20220529123139-5bc36b2978c1/go.mod h1:CiKpMhAx5QZFHK03jpWb0iKI3sGU8x6+LfsOjDrcO8I= diff --git a/portal.go b/portal.go index d133bef..a2e316e 100644 --- a/portal.go +++ b/portal.go @@ -3,16 +3,11 @@ package main import ( "bytes" "fmt" - "regexp" "strconv" "strings" "sync" "time" - "github.com/yuin/goldmark" - - "maunium.net/go/mautrix/format" - "maunium.net/go/mautrix/format/mdext" "maunium.net/go/mautrix/util/variationselector" "github.com/bwmarrin/discordgo" @@ -543,17 +538,6 @@ func (portal *Portal) handleDiscordAttachment(intent *appservice.IntentAPI, msgI } } -var mdRenderer = goldmark.New(format.Extensions, format.HTMLOptions, - goldmark.WithExtensions(mdext.EscapeHTML, mdext.SimpleSpoiler, mdext.DiscordUnderline)) -var escapeFixer = regexp.MustCompile(`\\(__[^_]|\*\*[^*])`) - -func renderDiscordMarkdown(text string) event.MessageEventContent { - text = escapeFixer.ReplaceAllStringFunc(text, func(s string) string { - return s[:2] + `\` + s[2:] - }) - return format.RenderMarkdownCustom(text, mdRenderer) -} - func (portal *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Message, thread *Thread) { if portal.MXID == "" { portal.log.Warnln("handle message called without a valid portal") @@ -947,7 +931,7 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) { if edits != nil { // we don't have anything to save for the update message right now // as we're not tracking edited timestamps. - _, err := sender.Session.ChannelMessageEdit(edits.DiscordProtoChannelID(), edits.DiscordID, content.NewContent.Body) + _, err := sender.Session.ChannelMessageEdit(edits.DiscordProtoChannelID(), edits.DiscordID, parseMatrixHTML(content.NewContent)) if err != nil { portal.log.Errorln("Failed to update message %s: %v", edits.DiscordID, err) } @@ -982,7 +966,7 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) { } } } - sendReq.Content = content.Body + sendReq.Content = parseMatrixHTML(content) case event.MsgAudio, event.MsgFile, event.MsgImage, event.MsgVideo: data, err := portal.downloadMatrixAttachment(evt.ID, content) if err != nil {