emote: add emote parsing engine
This commit is contained in:
65
emote/emote.go
Normal file
65
emote/emote.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package emote
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Emote is the information Kaiyan needs about an emote.
|
||||
type Emote struct {
|
||||
// ID is the emote ID per the source.
|
||||
ID string
|
||||
// Name is the text of the emote as would be parsed from message text.
|
||||
Name string
|
||||
// Source is the name of the emote source, e.g. "7TV", "Twitch:cirno_tv", &c.
|
||||
Source string
|
||||
// Link is a hyperlink to manage the emote.
|
||||
Link string
|
||||
// Image is a hyperlink to the emote image of any size.
|
||||
Image string
|
||||
}
|
||||
|
||||
// Parser finds emotes in a message.
|
||||
//
|
||||
// Parser assumes that emotes are bound by whitespace.
|
||||
type Parser struct {
|
||||
m map[string]string
|
||||
// TODO(branden): more efficient data structure; trie?
|
||||
}
|
||||
|
||||
// NewParser creates a Parser for the given list of emotes.
|
||||
func NewParser(emotes ...Emote) Parser {
|
||||
m := make(map[string]string, len(emotes))
|
||||
for _, e := range emotes {
|
||||
m[e.Name] = e.ID
|
||||
}
|
||||
return Parser{m}
|
||||
}
|
||||
|
||||
// Next parses the next emote instance from the message and returns the
|
||||
// remainder of the message text following it.
|
||||
// If there is no emote in the message the returned emote is the empty string.
|
||||
func (p Parser) Next(text string) (name, id, following string) {
|
||||
for text != "" {
|
||||
// First trim any existing space.
|
||||
text = strings.TrimSpace(text)
|
||||
// Then look for the next space.
|
||||
// If there is none, this is the last word of the message; we still
|
||||
// need to look it up.
|
||||
k := strings.IndexFunc(text, unicode.IsSpace)
|
||||
word := text
|
||||
if k >= 0 {
|
||||
word = text[:k]
|
||||
following = text[k:]
|
||||
} else {
|
||||
following = ""
|
||||
}
|
||||
id = p.m[word]
|
||||
if id != "" {
|
||||
return word, id, following
|
||||
}
|
||||
text = following
|
||||
}
|
||||
// No emote found.
|
||||
return "", "", ""
|
||||
}
|
Reference in New Issue
Block a user