diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2017-04-26 11:00:38 -0400 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2017-04-26 08:00:38 -0700 |
commit | 8e6141152bd0978bfeb24dbfff05972f4d17fd08 (patch) | |
tree | 44074110174830b5b7604a5f38c4385bab0d01c8 /app/notification.go | |
parent | 3e73adceb58e3a28bf3653b3e12a6a861643c400 (diff) | |
download | chat-8e6141152bd0978bfeb24dbfff05972f4d17fd08.tar.gz chat-8e6141152bd0978bfeb24dbfff05972f4d17fd08.tar.bz2 chat-8e6141152bd0978bfeb24dbfff05972f4d17fd08.zip |
PLT-3915/PLT-5550 Improve handling of Markdown while parsing mentions (#6091)
* PLT-3915 Removed ability to mention users in code blocks
* PLT-3915 Added simple check for potential code blocks before using regexes
* PLT-5550 Improve splitting when parsing mentions to ignore markdown characters
Diffstat (limited to 'app/notification.go')
-rw-r--r-- | app/notification.go | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/app/notification.go b/app/notification.go index 8e7e43d55..62e5e6c82 100644 --- a/app/notification.go +++ b/app/notification.go @@ -12,9 +12,11 @@ import ( "net/http" "net/url" "path/filepath" + "regexp" "sort" "strings" "time" + "unicode" l4g "github.com/alecthomas/log4go" "github.com/mattermost/platform/einterfaces" @@ -660,7 +662,12 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri } } - for _, word := range strings.Fields(message) { + message = removeCodeFromMessage(message) + + for _, word := range strings.FieldsFunc(message, func(c rune) bool { + // Split on whitespace (as strings.Fields normally does) or on Markdown characters + return unicode.IsSpace(c) || c == '*' || c == '~' + }) { isMention := false if word == "@here" { @@ -726,6 +733,27 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri return mentioned, potentialOthersMentioned, hereMentioned, channelMentioned, allMentioned } +// Matches a line containing only ``` and a potential language definition, any number of lines not containing ```, +// and then either a line containing only ``` or the end of the text +var codeBlockPattern = regexp.MustCompile("(?m)^[^\\S\n]*\\`\\`\\`.*$[\\s\\S]+?(^[^\\S\n]*\\`\\`\\`$|\\z)") + +// Matches a backquote, either some text or any number of non-empty lines, and then a final backquote +var inlineCodePattern = regexp.MustCompile("(?m)\\`(?:.+?|.*?\n(.*?\\S.*?\n)*.*?)\\`") + +// Strips pre-formatted text and code blocks from a Markdown string by replacing them with whitespace +func removeCodeFromMessage(message string) string { + if strings.Contains(message, "```") { + message = codeBlockPattern.ReplaceAllString(message, "") + } + + // Replace with a space to prevent cases like "user`code`name" from turning into "username" + if strings.Contains(message, "`") { + message = inlineCodePattern.ReplaceAllString(message, " ") + } + + return message +} + // Given a map of user IDs to profiles, returns a list of mention // keywords for all users in the channel. func GetMentionKeywordsInChannel(profiles map[string]*model.User) map[string][]string { |