123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package emoji
- import (
- "fmt"
- "regexp"
- "strings"
- "unicode"
- )
- var (
- flagRegex = regexp.MustCompile(`^:flag-([a-zA-Z]{2}):$`)
- )
- // Parse replaces emoji aliases (:pizza:) with unicode representation.
- func Parse(input string) string {
- var matched strings.Builder
- var output strings.Builder
- for _, r := range input {
- // when it's not `:`, it might be inner or outer of the emoji alias
- if r != ':' {
- // if matched is empty, it's the outer of the emoji alias
- if matched.Len() == 0 {
- output.WriteRune(r)
- continue
- }
- matched.WriteRune(r)
- // if it's space, the alias's not valid.
- // reset matched for breaking the emoji alias
- if unicode.IsSpace(r) {
- output.WriteString(matched.String())
- matched.Reset()
- }
- continue
- }
- // r is `:` now
- // if matched is empty, it's the beginning of the emoji alias
- if matched.Len() == 0 {
- matched.WriteRune(r)
- continue
- }
- // it's the end of the emoji alias
- match := matched.String()
- alias := match + ":"
- // check for emoji alias
- if code, ok := Find(alias); ok {
- output.WriteString(code)
- matched.Reset()
- continue
- }
- // not found any emoji
- output.WriteString(match)
- // it might be the beginning of the another emoji alias
- matched.Reset()
- matched.WriteRune(r)
- }
- // if matched not empty, add it to output
- if matched.Len() != 0 {
- output.WriteString(matched.String())
- matched.Reset()
- }
- return output.String()
- }
- // Map returns the emojis map.
- // Key is the alias of the emoji.
- // Value is the code of the emoji.
- func Map() map[string]string {
- return emojiMap
- }
- // AppendAlias adds new emoji pair to the emojis map.
- func AppendAlias(alias, code string) error {
- if c, ok := emojiMap[alias]; ok {
- return fmt.Errorf("emoji already exist: %q => %+q", alias, c)
- }
- for _, r := range alias {
- if unicode.IsSpace(r) {
- return fmt.Errorf("emoji alias is not valid: %q", alias)
- }
- }
- emojiMap[alias] = code
- return nil
- }
- // Exist checks existence of the emoji by alias.
- func Exist(alias string) bool {
- _, ok := Find(alias)
- return ok
- }
- // Find returns the emoji code by alias.
- func Find(alias string) (string, bool) {
- if code, ok := emojiMap[alias]; ok {
- return code, true
- }
- if flag := checkFlag(alias); len(flag) > 0 {
- return flag, true
- }
- return "", false
- }
- // checkFlag finds flag emoji for `flag-[CODE]` pattern
- func checkFlag(alias string) string {
- if matches := flagRegex.FindStringSubmatch(alias); len(matches) == 2 {
- flag, _ := CountryFlag(matches[1])
- return flag.String()
- }
- return ""
- }
|