diff --git a/pkg/connector/msgconv/mentions.go b/pkg/connector/msgconv/mentions.go
index 3f68d18..0f14d29 100644
--- a/pkg/connector/msgconv/mentions.go
+++ b/pkg/connector/msgconv/mentions.go
@@ -18,6 +18,7 @@ package msgconv
import (
"context"
+ "regexp"
"slices"
//"log"
@@ -42,6 +43,14 @@ func (u UTF16String) String() string {
return string(utf16.Decode(u))
}
+var (
+ META_BOLD_REGEX = regexp.MustCompile(`\*([^*]+)\*`)
+ META_ITALIC_REGEX = regexp.MustCompile(`_([^_]+)_`)
+ META_STRIKE_REGEX = regexp.MustCompile(`~([^~]+)~`)
+ META_MONOSPACE_REGEX = regexp.MustCompile("`([^`]+)`")
+ META_MONOSPACE_BLOCK_REGEX = regexp.MustCompile("```([^`]+)```")
+)
+
func (mc *MessageConverter) metaToMatrixText(ctx context.Context, text string, rawMentions *socket.MentionData, portal *bridgev2.Portal) (content *event.MessageEventContent) {
content = &event.MessageEventContent{
MsgType: event.MsgText,
@@ -52,53 +61,61 @@ func (mc *MessageConverter) metaToMatrixText(ctx context.Context, text string, r
if err != nil {
zerolog.Ctx(ctx).Err(err).Msg("Failed to parse mentions")
}
- if mentions == nil {
- return
- }
- utf16Text := NewUTF16String(text)
- prevEnd := 0
- var output strings.Builder
- for _, mention := range mentions {
- if mention.Offset < prevEnd {
- zerolog.Ctx(ctx).Warn().Msg("Ignoring overlapping mentions in message")
- continue
- } else if mention.Offset >= len(utf16Text) {
- zerolog.Ctx(ctx).Warn().Msg("Ignoring mention outside of message")
- continue
- }
- end := mention.Offset + mention.Length
- if end > len(utf16Text) {
- end = len(utf16Text)
- }
- var mentionLink string
- switch mention.Type {
- case socket.MentionTypePerson:
- info, err := mc.getBasicUserInfo(ctx, portal, ids.MakeUserID(mention.ID))
- if err != nil {
- zerolog.Ctx(ctx).Err(err).Msg("Failed to get user info for mention")
+
+ outputString := text
+
+ if mentions != nil {
+ utf16Text := NewUTF16String(text)
+ prevEnd := 0
+ var output strings.Builder
+ for _, mention := range mentions {
+ if mention.Offset < prevEnd {
+ zerolog.Ctx(ctx).Warn().Msg("Ignoring overlapping mentions in message")
+ continue
+ } else if mention.Offset >= len(utf16Text) {
+ zerolog.Ctx(ctx).Warn().Msg("Ignoring mention outside of message")
continue
}
- if !slices.Contains(content.Mentions.UserIDs, info.MXID) {
- content.Mentions.UserIDs = append(content.Mentions.UserIDs, info.MXID)
+ end := mention.Offset + mention.Length
+ if end > len(utf16Text) {
+ end = len(utf16Text)
}
- mentionLink = info.MXID.URI().MatrixToURL()
- case socket.MentionTypeThread:
- // TODO: how does one send thread mentions?
- }
- if mentionLink == "" {
- continue
+ var mentionLink string
+ switch mention.Type {
+ case socket.MentionTypePerson:
+ info, err := mc.getBasicUserInfo(ctx, portal, ids.MakeUserID(mention.ID))
+ if err != nil {
+ zerolog.Ctx(ctx).Err(err).Msg("Failed to get user info for mention")
+ continue
+ }
+ if !slices.Contains(content.Mentions.UserIDs, info.MXID) {
+ content.Mentions.UserIDs = append(content.Mentions.UserIDs, info.MXID)
+ }
+ mentionLink = info.MXID.URI().MatrixToURL()
+ case socket.MentionTypeThread:
+ // TODO: how does one send thread mentions?
+ }
+ if mentionLink == "" {
+ continue
+ }
+
+ output.WriteString(utf16Text[prevEnd:mention.Offset].String() + `` + utf16Text[mention.Offset:end].String() + ``)
+ prevEnd = end
}
- output.WriteString(utf16Text[prevEnd:mention.Offset].String())
- output.WriteString(``)
- output.WriteString(utf16Text[mention.Offset:end].String())
- output.WriteString(``)
- prevEnd = end
+ output.WriteString(utf16Text[prevEnd:].String())
+
+ outputString = output.String()
}
- output.WriteString(utf16Text[prevEnd:].String())
+
+ // Second parsing pass, replacing other formatting:
+ outputString = META_BOLD_REGEX.ReplaceAllString(outputString, "$1")
+ outputString = META_ITALIC_REGEX.ReplaceAllString(outputString, "$1")
+ outputString = META_STRIKE_REGEX.ReplaceAllString(outputString, "$1")
+ outputString = META_MONOSPACE_REGEX.ReplaceAllString(outputString, "$1
")
+ outputString = META_MONOSPACE_BLOCK_REGEX.ReplaceAllString(outputString, "
$1") + content.Format = event.FormatHTML - content.FormattedBody = output.String() + content.FormattedBody = outputString log := zerolog.Ctx(ctx) log.Debug().Str("text", text).Str("formatted_body", content.FormattedBody).Msg("Converted message to Matrix text")