all repos — emoji @ 4136fb5e07d3ad3c86a6918b5a039e12503861b6

A minimalistic emoji package for Go (golang)

parser.go (view raw)

  1package emoji
  2
  3import (
  4	"fmt"
  5	"regexp"
  6	"strings"
  7	"unicode"
  8)
  9
 10var (
 11	flagRegex = regexp.MustCompile(`^:flag-([a-zA-Z]{2}):$`)
 12)
 13
 14// Parse replaces emoji aliases (:pizza:) with unicode representation.
 15func Parse(input string) string {
 16	var matched strings.Builder
 17	var output strings.Builder
 18
 19	for _, r := range input {
 20		// when it's not `:`, it might be inner or outer of the emoji alias
 21		if r != ':' {
 22			// if matched is empty, it's the outer of the emoji alias
 23			if matched.Len() == 0 {
 24				output.WriteRune(r)
 25				continue
 26			}
 27
 28			matched.WriteRune(r)
 29
 30			// if it's space, the alias's not valid.
 31			// reset matched for breaking the emoji alias
 32			if unicode.IsSpace(r) {
 33				output.WriteString(matched.String())
 34				matched.Reset()
 35			}
 36			continue
 37		}
 38
 39		// r is `:` now
 40		// if matched is empty, it's the beginning of the emoji alias
 41		if matched.Len() == 0 {
 42			matched.WriteRune(r)
 43			continue
 44		}
 45
 46		// it's the end of the emoji alias
 47		match := matched.String()
 48		alias := match + ":"
 49
 50		// check for emoji alias
 51		if code, ok := Find(alias); ok {
 52			output.WriteString(code)
 53			matched.Reset()
 54			continue
 55		}
 56
 57		// not found any emoji
 58		output.WriteString(match)
 59		// it might be the beginning of the another emoji alias
 60		matched.Reset()
 61		matched.WriteRune(r)
 62
 63	}
 64
 65	// if matched not empty, add it to output
 66	if matched.Len() != 0 {
 67		output.WriteString(matched.String())
 68		matched.Reset()
 69	}
 70
 71	return output.String()
 72}
 73
 74// Map returns the emojis map.
 75// Key is the alias of the emoji.
 76// Value is the code of the emoji.
 77func Map() map[string]string {
 78	return emojiMap
 79}
 80
 81// AppendAlias adds new emoji pair to the emojis map.
 82func AppendAlias(alias, code string) error {
 83	if c, ok := emojiMap[alias]; ok {
 84		return fmt.Errorf("emoji already exist: %q => %+q", alias, c)
 85	}
 86
 87	for _, r := range alias {
 88		if unicode.IsSpace(r) {
 89			return fmt.Errorf("emoji alias is not valid: %q", alias)
 90		}
 91	}
 92
 93	emojiMap[alias] = code
 94
 95	return nil
 96}
 97
 98// Exist checks existence of the emoji by alias.
 99func Exist(alias string) bool {
100	_, ok := Find(alias)
101
102	return ok
103}
104
105// Find returns the emoji code by alias.
106func Find(alias string) (string, bool) {
107	if code, ok := emojiMap[alias]; ok {
108		return code, true
109	}
110
111	if flag := checkFlag(alias); len(flag) > 0 {
112		return flag, true
113	}
114
115	return "", false
116}
117
118// checkFlag finds flag emoji for `flag-[CODE]` pattern
119func checkFlag(alias string) string {
120	if matches := flagRegex.FindStringSubmatch(alias); len(matches) == 2 {
121		flag, _ := CountryFlag(matches[1])
122
123		return flag.String()
124	}
125
126	return ""
127}