MovieNight/common/emotes.go
Zorchenhimer fab56e39ea Rework emote parsing to properly handle wrapped emotes
Reworked the emote parsing to properly handle "wrapped" emotes.  A
wrapped emote is one that is wrapped in colons or square braces (eg,
:Kappa: or [Kappa]).  This allows emotes to be input without a space
between them, like is required with non-wrapped emotes.

A new configuration setting has been added to only allow parsing of
wrapped emotes: "WrappedEmotesOnly".  This defaults to False as to not
break current configurations.

The emote autocompletion will only insert non-wrapped emotes.  Setting
"WrappedEmotesOnly" configuration value to True will not change this.

Lastly, made the bare-word emote parsing a bit cleaner by removing a for
loop in favor of a map lookup with a check.  This should in theory be
more efficient.

This change is in response to #111.  The issue should not be considered
resolved until the autocompletion handles the new setting correctly.
2020-04-19 12:26:27 -04:00

88 lines
1.8 KiB
Go

package common
import (
"fmt"
"path/filepath"
"regexp"
"strings"
)
type EmotesMap map[string]string
var Emotes EmotesMap
var WrappedEmotesOnly bool = false
var (
reStripStatic = regexp.MustCompile(`^(\\|/)?static`)
reWrappedEmotes = regexp.MustCompile(`[:\[][^\s:\/\\\?=#\]\[]+[:\]]`)
)
func init() {
Emotes = NewEmotesMap()
}
func NewEmotesMap() EmotesMap {
return map[string]string{}
}
func (em EmotesMap) Add(fullpath string) EmotesMap {
fullpath = reStripStatic.ReplaceAllLiteralString(fullpath, "")
base := filepath.Base(fullpath)
code := base[0 : len(base)-len(filepath.Ext(base))]
_, exists := em[code]
num := 0
for exists {
num += 1
_, exists = em[fmt.Sprintf("%s-%d", code, num)]
}
if num > 0 {
code = fmt.Sprintf("%s-%d", code, num)
}
em[code] = fullpath
return em
}
func EmoteToHtml(file, title string) string {
return fmt.Sprintf(`<img src="%s" height="28px" title="%s" />`, file, title)
}
// Used with a regexp.ReplaceAllStringFunc() call. Needs to lookup the value as it
// cannot be passed in with the regex function call.
func emoteToHmtl2(key string) string {
key = strings.Trim(key, ":[]")
if val, ok := Emotes[key]; ok {
return fmt.Sprintf(`<img src="%s" height="28px" title="%s" />`, val, key)
}
return key
}
func ParseEmotesArray(words []string) []string {
newWords := []string{}
for _, word := range words {
found := false
if !WrappedEmotesOnly {
if val, ok := Emotes[word]; ok {
newWords = append(newWords, EmoteToHtml(val, word))
found = true
}
}
if !found {
word = reWrappedEmotes.ReplaceAllStringFunc(word, emoteToHmtl2)
newWords = append(newWords, word)
}
}
return newWords
}
func ParseEmotes(msg string) string {
words := ParseEmotesArray(strings.Split(msg, " "))
return strings.Join(words, " ")
}