diff --git a/common/emotes.go b/common/emotes.go
index 5f1d3ec..fcd3746 100644
--- a/common/emotes.go
+++ b/common/emotes.go
@@ -10,8 +10,12 @@ import (
type EmotesMap map[string]string
var Emotes EmotesMap
+var WrappedEmotesOnly bool = false
-var reStripStatic = regexp.MustCompile(`^(\\|/)?static`)
+var (
+ reStripStatic = regexp.MustCompile(`^(\\|/)?static`)
+ reWrappedEmotes = regexp.MustCompile(`[:\[][^\s:\/\\\?=#\]\[]+[:\]]`)
+)
func init() {
Emotes = NewEmotesMap()
@@ -40,7 +44,6 @@ func (em EmotesMap) Add(fullpath string) EmotesMap {
}
em[code] = fullpath
- //fmt.Printf("Added emote %s at path %q\n", code, fullpath)
return em
}
@@ -48,23 +51,33 @@ func EmoteToHtml(file, title string) string {
return fmt.Sprintf(``, 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(``, val, key)
+ }
+ return key
+}
+
func ParseEmotesArray(words []string) []string {
newWords := []string{}
for _, word := range words {
- // make :emote: and [emote] valid for replacement.
- wordTrimmed := strings.Trim(word, ":[]")
-
found := false
- for key, val := range Emotes {
- if key == wordTrimmed {
- newWords = append(newWords, EmoteToHtml(val, key))
+ 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
}
diff --git a/common/emotes_test.go b/common/emotes_test.go
index bb31646..0e61f87 100644
--- a/common/emotes_test.go
+++ b/common/emotes_test.go
@@ -14,10 +14,18 @@ var data_good = map[string]string{
":two:": ``,
":three:": ``,
+ ":one::one:": ``,
+ ":one:one:": `one:`,
+ "oneone": "oneone",
+ "one:one:": `one`,
+
"[one]": ``,
"[two]": ``,
"[three]": ``,
+ "[one][one]": ``,
+ "[one]one": `one`,
+
":one: two [three]": ` `,
"nope one what": `nope what`,
@@ -25,6 +33,34 @@ var data_good = map[string]string{
"nope [three] what": `nope what`,
}
+var data_wrapped = map[string]string{
+ "one": `one`,
+ "two": `two`,
+ "three": `three`,
+
+ ":one:": ``,
+ ":two:": ``,
+ ":three:": ``,
+
+ ":one::one:": ``,
+ ":one:one:": `one:`,
+ "oneone": "oneone",
+ "one:one:": `one`,
+
+ "[one]": ``,
+ "[two]": ``,
+ "[three]": ``,
+
+ "[one][one]": ``,
+ "[one]one": `one`,
+
+ ":one: two [three]": ` two `,
+
+ "nope one what": `nope one what`,
+ "nope :two: what": `nope what`,
+ "nope [three] what": `nope what`,
+}
+
func TestMain(m *testing.M) {
Emotes = map[string]string{
"one": "/emotes/one.png",
@@ -42,3 +78,12 @@ func TestEmotes_ParseEmotes(t *testing.T) {
}
}
}
+
+func TestEmotes_ParseEmotes_WrappedOnly(t *testing.T) {
+ for input, expected := range data_good {
+ got := ParseEmotes(input)
+ if got != expected {
+ t.Errorf("%s failed to parse into %q. Received: %q", input, expected, got)
+ }
+ }
+}
diff --git a/settings.go b/settings.go
index 18f0512..fd19ac5 100644
--- a/settings.go
+++ b/settings.go
@@ -40,6 +40,8 @@ type Settings struct {
RoomAccessPin string // The current pin
NewPin bool // Auto generate a new pin on start. Overwrites RoomAccessPin if set.
+ WrappedEmotesOnly bool // only allow "wrapped" emotes. eg :Kappa: and [Kappa] but not Kappa
+
// Rate limiting stuff, in seconds
RateLimitChat time.Duration
RateLimitNick time.Duration
@@ -128,6 +130,11 @@ func LoadSettings(filename string) (*Settings, error) {
s.RateLimitDuplicate = 30
}
+ if s.WrappedEmotesOnly {
+ common.LogInfoln("Only allowing wrapped emotes")
+ common.WrappedEmotesOnly = true
+ }
+
// Print this stuff before we multiply it by time.Second
common.LogInfof("RateLimitChat: %v", s.RateLimitChat)
common.LogInfof("RateLimitNick: %v", s.RateLimitNick)
diff --git a/settings_example.json b/settings_example.json
index cd9583c..1352b6f 100644
--- a/settings_example.json
+++ b/settings_example.json
@@ -14,5 +14,6 @@
"RateLimitColor": 60,
"RateLimitAuth": 5,
"RateLimitDuplicate": 30,
- "NoCache": false
+ "NoCache": false,
+ "WrappedEmotesOnly": false
}