2019-02-06 03:52:49 +00:00
|
|
|
package slackapp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"unicode/utf8"
|
|
|
|
)
|
|
|
|
|
|
|
|
// fixText strips all of the Slack-specific annotations from message text,
|
|
|
|
// replacing it with the equivalent display form.
|
|
|
|
// Currently it:
|
|
|
|
// • Replaces user mentions like <@U124356> with @ followed by the user's nick.
|
|
|
|
// This uses the lookupUser function, which must map U1243456 to the nick.
|
|
|
|
// • Replaces user mentions like <U123456|nick> with the user's nick.
|
|
|
|
// • Strips < and > surrounding links.
|
|
|
|
//
|
|
|
|
// This was directly bogarted from velour/chat with emoji conversion removed.
|
2019-09-19 20:30:59 +00:00
|
|
|
func fixText(findUser func(id, defaultName string) string, text string) string {
|
2019-02-06 03:52:49 +00:00
|
|
|
var output []rune
|
|
|
|
for len(text) > 0 {
|
|
|
|
r, i := utf8.DecodeRuneInString(text)
|
|
|
|
text = text[i:]
|
|
|
|
switch {
|
|
|
|
case r == '<':
|
|
|
|
var tag []rune
|
|
|
|
for {
|
|
|
|
r, i := utf8.DecodeRuneInString(text)
|
|
|
|
text = text[i:]
|
|
|
|
switch {
|
|
|
|
case r == '>':
|
|
|
|
if t, ok := fixTag(findUser, tag); ok {
|
|
|
|
output = append(output, t...)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
fallthrough
|
|
|
|
case len(text) == 0:
|
|
|
|
output = append(output, '<')
|
|
|
|
output = append(output, tag...)
|
|
|
|
output = append(output, r)
|
|
|
|
default:
|
|
|
|
tag = append(tag, r)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
output = append(output, r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return string(output)
|
|
|
|
}
|
|
|
|
|
2019-09-19 20:30:59 +00:00
|
|
|
func fixTag(findUser func(string, string) string, tag []rune) ([]rune, bool) {
|
2019-02-06 03:52:49 +00:00
|
|
|
switch {
|
|
|
|
case hasPrefix(tag, "@U"):
|
|
|
|
if i := indexRune(tag, '|'); i >= 0 {
|
|
|
|
return tag[i+1:], true
|
|
|
|
}
|
|
|
|
if findUser != nil {
|
2019-09-19 20:30:59 +00:00
|
|
|
u := findUser(string(tag[1:]), "unknown")
|
|
|
|
return []rune(u), true
|
2019-02-06 03:52:49 +00:00
|
|
|
}
|
|
|
|
return tag, true
|
|
|
|
|
|
|
|
case hasPrefix(tag, "#C"):
|
|
|
|
if i := indexRune(tag, '|'); i >= 0 {
|
|
|
|
return append([]rune{'#'}, tag[i+1:]...), true
|
|
|
|
}
|
|
|
|
|
|
|
|
case hasPrefix(tag, "http"):
|
|
|
|
if i := indexRune(tag, '|'); i >= 0 {
|
|
|
|
tag = tag[:i]
|
|
|
|
}
|
|
|
|
return tag, true
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
|
|
|
func hasPrefix(text []rune, prefix string) bool {
|
|
|
|
for _, r := range prefix {
|
|
|
|
if len(text) == 0 || text[0] != r {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
text = text[1:]
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func indexRune(text []rune, find rune) int {
|
|
|
|
for i, r := range text {
|
|
|
|
if r == find {
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|