File: parser.go

package info (click to toggle)
golang-github-enescakir-emoji 1.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid
  • size: 472 kB
  • sloc: makefile: 3
file content (127 lines) | stat: -rw-r--r-- 2,556 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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 ""
}