-
Notifications
You must be signed in to change notification settings - Fork 22
/
emoji.go
88 lines (72 loc) · 1.67 KB
/
emoji.go
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
// Package emoji is designed to recognize and parse
// every individual Unicode Emoji characters from a string.
//
// Unicode Emoji Documents: https://www.unicode.org/Public/emoji/
package emoji
import (
"bytes"
"github.com/Andrew-M-C/go.emoji/internal/official"
)
// ReplaceAllEmojiFunc searches string and find all emojis.
func ReplaceAllEmojiFunc(s string, f func(emoji string) string) string {
buff := bytes.Buffer{}
nextIndex := 0
for i, r := range s {
if i < nextIndex {
continue
}
match, length := official.AllSequences.HasEmojiPrefix(s[i:])
if !match {
buff.WriteRune(r)
continue
}
nextIndex = i + length
if f != nil {
buff.WriteString(f(s[i : i+length]))
}
}
return buff.String()
}
// IterateChars iterates a string, and extract every characters.
func IterateChars(s string) CharIterator {
it := &charIteratorImpl{
orig: []rune(s),
}
return it
}
// CharIterator is used in RangeChars
type CharIterator interface {
Current() string
CurrentIsEmoji() bool
Next() bool
}
type charIteratorImpl struct {
orig []rune
curr struct {
index int
r string
emoji bool
}
}
func (it *charIteratorImpl) Current() string {
return it.curr.r
}
func (it *charIteratorImpl) Next() bool {
if it.curr.index >= len(it.orig) {
return false
}
match, length := official.AllSequences.HasEmojiPrefixRunes(it.orig[it.curr.index:])
if !match {
it.curr.r = string(it.orig[it.curr.index])
it.curr.emoji = false
it.curr.index++
return true
}
it.curr.r = string(it.orig[it.curr.index : it.curr.index+length])
it.curr.index += length
it.curr.emoji = true
return true
}
func (it *charIteratorImpl) CurrentIsEmoji() bool {
return it.curr.emoji
}