Add initial Matrix->Discord HTML conversion
This commit is contained in:
63
formatter.go
Normal file
63
formatter.go
Normal file
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
go.mod
2
go.mod
@@ -11,7 +11,7 @@ require (
|
|||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
github.com/yuin/goldmark v1.4.12
|
github.com/yuin/goldmark v1.4.12
|
||||||
maunium.net/go/maulogger/v2 v2.3.2
|
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 (
|
require (
|
||||||
|
|||||||
4
go.sum
4
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/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 h1:1XmIYmMd3PoQfp9J+PaHhpt80zpfmMqaShzUTC7FwY0=
|
||||||
maunium.net/go/maulogger/v2 v2.3.2/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
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.20220529123139-5bc36b2978c1 h1:HNntVQh0XVyWDAsSQA/0Rk2++1cGOzmm7tH8xILSsak=
|
||||||
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/go.mod h1:CiKpMhAx5QZFHK03jpWb0iKI3sGU8x6+LfsOjDrcO8I=
|
||||||
|
|||||||
20
portal.go
20
portal.go
@@ -3,16 +3,11 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/yuin/goldmark"
|
|
||||||
|
|
||||||
"maunium.net/go/mautrix/format"
|
|
||||||
"maunium.net/go/mautrix/format/mdext"
|
|
||||||
"maunium.net/go/mautrix/util/variationselector"
|
"maunium.net/go/mautrix/util/variationselector"
|
||||||
|
|
||||||
"github.com/bwmarrin/discordgo"
|
"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) {
|
func (portal *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Message, thread *Thread) {
|
||||||
if portal.MXID == "" {
|
if portal.MXID == "" {
|
||||||
portal.log.Warnln("handle message called without a valid portal")
|
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 {
|
if edits != nil {
|
||||||
// we don't have anything to save for the update message right now
|
// we don't have anything to save for the update message right now
|
||||||
// as we're not tracking edited timestamps.
|
// 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 {
|
if err != nil {
|
||||||
portal.log.Errorln("Failed to update message %s: %v", edits.DiscordID, err)
|
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:
|
case event.MsgAudio, event.MsgFile, event.MsgImage, event.MsgVideo:
|
||||||
data, err := portal.downloadMatrixAttachment(evt.ID, content)
|
data, err := portal.downloadMatrixAttachment(evt.ID, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user