package emoji import ( "fmt" "html" "strings" ) // Base attributes const ( unicodeFlagBaseIndex = 127397 ) // Skin tone colors const ( Default Tone = "" Light Tone = "\U0001F3FB" MediumLight Tone = "\U0001F3FC" Medium Tone = "\U0001F3FD" MediumDark Tone = "\U0001F3FE" Dark Tone = "\U0001F3FF" ) // Emoji defines an emoji object. type Emoji string // String returns string representation of the emoji. func (e Emoji) String() string { return string(e) } // EmojiWithTone defines an emoji object that has skin tone options. type EmojiWithTone Emoji // String returns string representation of the emoji with default skin tone. func (e EmojiWithTone) String() string { return strings.ReplaceAll(string(e), "@", Default.String()) } // Tone returns string representation of the emoji with given skin tones. func (e EmojiWithTone) Tone(tones ...Tone) string { str := string(e) // if no given tones, return with default skin tone if len(tones) == 0 { return e.String() } // replace tone one by one for _, t := range tones { str = strings.Replace(str, "@", t.String(), 1) } // if skin tone count is not enough, fill with last tone. if strings.Count(str, "@") > 0 { last := tones[len(tones)-1] str = strings.ReplaceAll(str, "@", last.String()) } return str } // Tone defines skin tone options for emojis. type Tone string // String returns string representation of the skin tone. func (t Tone) String() string { return string(t) } // CountryFlag returns a country flag emoji from given country code. // Full list of country codes: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 func CountryFlag(code string) (Emoji, error) { if len(code) != 2 { return "", fmt.Errorf("not valid country code: %q", code) } code = strings.ToUpper(code) flag := countryCodeLetter(code[0]) + countryCodeLetter(code[1]) return Emoji(flag), nil } // countryCodeLetter shifts given letter byte as unicodeFlagBaseIndex and changes encoding func countryCodeLetter(l byte) string { shifted := unicodeFlagBaseIndex + int(l) return html.UnescapeString(fmt.Sprintf("&#%v;", shifted)) }