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]Emote // 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]Emote, len(emotes)) for _, e := range emotes { m[e.Name] = e } 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 has an empty ID. func (p Parser) Next(text string) (emote Emote, 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 = "" } em := p.m[word] if em.ID != "" { return em, following } text = following } // No emote found. return Emote{}, "" }