-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathString+Emoji.swift
More file actions
164 lines (147 loc) · 5.27 KB
/
Copy pathString+Emoji.swift
File metadata and controls
164 lines (147 loc) · 5.27 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//
// String+Emoji.swift
// StringFormat
//
// Created by coderyi on 2020/12/12.
//
import Foundation
import CoreText
import AVFoundation
public extension UnicodeScalar {
var isEmoji: Bool {
switch self.value {
case 0x1F600...0x1F64F, 0x1F300...0x1F5FF, 0x1F680...0x1F6FF, 0x1F1E6...0x1F1FF, 0xE0020...0xE007F, 0xFE00...0xFE0F, 0x1F900...0x1F9FF, 0x1F018...0x1F0F5, 0x1F200...0x1F270, 65024...65039, 9100...9300, 8400...8447, 0x1F004, 0x1F18E, 0x1F191...0x1F19A, 0x1F5E8, 0x1FA70...0x1FA73, 0x1FA78...0x1FA7A, 0x1FA80...0x1FA82, 0x1FA90...0x1FA95:
return true
case 0x2603, 0x265F, 0x267E, 0x2692, 0x26C4, 0x26C8, 0x26CE, 0x26CF, 0x26D1...0x26D3, 0x26E9, 0x26F0...0x26F9, 0x2705, 0x270A, 0x270B, 0x2728, 0x274E, 0x2753...0x2755, 0x274C, 0x2795...0x2797, 0x27B0, 0x27BF:
return true
default:
return false
}
}
var maybeEmoji: Bool {
switch self.value {
case 0x2A, 0x23, 0x30...0x39, 0xA9, 0xAE:
return true
case 0x2600...0x26FF, 0x2700...0x27BF, 0x1F100...0x1F1FF:
return true
case 0x203C, 0x2049, 0x2122, 0x2194...0x2199, 0x21A9, 0x21AA, 0x2139, 0x2328, 0x231A, 0x231B, 0x24C2, 0x25AA, 0x25AB, 0x25B6, 0x25FB...0x25FE, 0x25C0, 0x2934, 0x2935, 0x2B05...0x2B07, 0x2B1B...0x2B1E, 0x2B50, 0x2B55, 0x3030, 0x3297, 0x3299:
return true
default:
return false
}
}
static var ZeroWidthJoiner: Unicode.Scalar? = UnicodeScalar(0x200D)
static var VariationSelector: Unicode.Scalar? = UnicodeScalar(0xFE0F)
}
private final class FrameworkClass: NSObject {
}
public extension String {
func trimmingTrailingSpaces() -> String {
var t = self
while t.hasSuffix(" ") {
t = "" + t.dropLast()
}
return t
}
var isSingleEmoji: Bool {
return self.emojis.count == 1 && self.containsEmoji
}
var containsEmoji: Bool {
return self.unicodeScalars.contains { $0.isEmoji }
}
var containsOnlyEmoji: Bool {
guard !self.isEmpty else {
return false
}
var nextShouldBeVariationSelector = false
for scalar in self.unicodeScalars {
if nextShouldBeVariationSelector {
if scalar == UnicodeScalar.VariationSelector {
nextShouldBeVariationSelector = false
continue
} else {
return false
}
}
if !scalar.isEmoji && scalar.maybeEmoji {
nextShouldBeVariationSelector = true
}
else if !scalar.isEmoji && scalar != UnicodeScalar.ZeroWidthJoiner {
return false
}
}
return !nextShouldBeVariationSelector
}
var emojis: [String] {
var emojis: [String] = []
self.enumerateSubstrings(in: self.startIndex ..< self.endIndex, options: .byComposedCharacterSequences) { substring, _, _, _ in
if let substring = substring {
emojis.append(substring)
}
}
return emojis
}
var trimmingEmojis: String {
var string: String = ""
self.enumerateSubstrings(in: self.startIndex ..< self.endIndex, options: .byComposedCharacterSequences) { substring, _, _, _ in
if let substring = substring, !substring.containsEmoji {
string.append(substring)
}
}
return string
}
var normalizedEmoji: String {
var string = ""
guard let variationSelector = UnicodeScalar.VariationSelector else {
return string
}
var nextShouldBeVariationSelector = false
for scalar in self.unicodeScalars {
if nextShouldBeVariationSelector {
if scalar != variationSelector {
string.unicodeScalars.append(variationSelector)
}
nextShouldBeVariationSelector = false
}
string.unicodeScalars.append(scalar)
if !scalar.isEmoji && scalar.maybeEmoji {
nextShouldBeVariationSelector = true
}
}
if nextShouldBeVariationSelector {
string.unicodeScalars.append(variationSelector)
}
return string
}
var basicEmoji: (String, String?) {
let fitzCodes: [UInt32] = [
0x1f3fb,
0x1f3fc,
0x1f3fd,
0x1f3fe,
0x1f3ff
]
var string = ""
var fitzModifier: String?
for scalar in self.unicodeScalars {
if fitzCodes.contains(scalar.value) {
fitzModifier = String(scalar)
continue
}
string.unicodeScalars.append(scalar)
if scalar.value == 0x2764, self.unicodeScalars.count > 1, self.emojis.count == 1 {
break
}
}
return (string, fitzModifier)
}
var strippedEmoji: String {
var string = ""
for scalar in self.unicodeScalars {
if scalar.value != 0xfe0f {
string.unicodeScalars.append(scalar)
}
}
return string
}
}