emojisum/emoji/map.go

97 lines
2.5 KiB
Go

package emoji
import (
"encoding/hex"
"fmt"
"strconv"
"strings"
)
// Map returns the emoji at the provided position.
// This list is from 0-255
func Map(b byte) Words {
return mapGen.EmojiWords[int(b)]
}
// Version returns the version of the emojisum document currently compiled
// against
func Version() string {
return mapGen.Version
}
var mapGen VersionedMap
// VersionedMap is the structure used for the `emojimap.json` document
type VersionedMap struct {
Description string `json:"description"`
Version string `json:"version"`
// these are an ordered list, referened by a byte (each byte of a checksum digest)
EmojiWords []Words `json:"emojiwords"`
}
// Words are a set of options to represent an emoji.
// Possible options could be the ":colon_notation:", a "U+26CF" style
// codepoint, or the unicode value itself.
type Words []string
// IsColonNotation checks for whether a word is the :colon_notation: of emoji
func IsColonNotation(word string) bool {
return strings.HasPrefix(word, ":") && strings.HasSuffix(word, ":")
}
// IsCodepoint checks for whether a word is the "U+1234" codepoint style of emoji. Codepoints can sometimes be a combo, like flags
func IsCodepoint(word string) bool {
return strings.HasPrefix(strings.ToUpper(word), "U+")
}
var unicodeURL = `http://www.unicode.org/emoji/charts/full-emoji-list.html`
// UnicodeLinkURL returns a link to unicode.org list for CodePoint, or just the
// full list if not a codepoint
func UnicodeLinkURL(word string) string {
if !IsCodepoint(word) {
return unicodeURL
}
return fmt.Sprintf("%s#%s", unicodeURL, strings.Join(strings.Split(strings.TrimPrefix(strings.ToLower(word), "u+"), "u+"), "_"))
}
// CodepointToUnicode takes a "U+26CF" style word and returns the `\U00026CF` formated unicode string
func CodepointToUnicode(word string) string {
if !IsCodepoint(word) {
return word
}
var ret string
for _, chunk := range strings.Split(strings.TrimPrefix(strings.ToUpper(word), "U+"), "U+") {
c, err := strconv.ParseInt(chunk, 16, 64)
if err != nil {
return ret
}
ret = fmt.Sprintf("%s%c", ret, c)
}
return ret
}
// FromHexString parses string s as two character byte of hexadecimal into
// Unicode Codepoint
func FromHexString(s string) (string, error) {
d, err := hex.DecodeString(s)
if err != nil {
return "", err
}
var ret string
for _, b := range d {
for _, e := range Map(b) {
// use the first colon notation word and continue
if IsCodepoint(e) {
ret = ret + CodepointToUnicode(e)
break
}
}
}
return ret, nil
}