@@ -30,9 +30,17 @@ class DisplayWidth
30
30
rgi_at : :REGEX_INCLUDE_MQE_UQE ,
31
31
possible : :REGEX_WELL_FORMED ,
32
32
}
33
- REGEX_EMOJI_BASIC_OR_KEYCAP = Regexp . union ( Unicode ::Emoji ::REGEX_BASIC , Unicode ::Emoji ::REGEX_EMOJI_KEYCAP )
34
- REGEX_EMOJI_ALL_SEQUENCES = Regexp . union ( /.[\u{1F3FB} -\u{1F3FF} \u{FE0F} ]?(\u{200D} .[\u{1F3FB} -\u{1F3FF} \u{FE0F} ]?)+/ , Unicode ::Emoji ::REGEX_EMOJI_KEYCAP )
35
33
REGEX_EMOJI_NOT_POSSIBLE = /\A [#*0-9]\z /
34
+ REGEX_EMOJI_VS16 = Regexp . union (
35
+ Regexp . compile (
36
+ Unicode ::Emoji ::REGEX_TEXT_PRESENTATION . source +
37
+ "(?<![#*0-9])" +
38
+ "\u{FE0F} "
39
+ ) ,
40
+ Unicode ::Emoji ::REGEX_EMOJI_KEYCAP
41
+ )
42
+ REGEX_EMOJI_ALL_SEQUENCES = Regexp . union ( /.[\u{1F3FB} -\u{1F3FF} \u{FE0F} ]?(\u{200D} .[\u{1F3FB} -\u{1F3FF} \u{FE0F} ]?)+/ , Unicode ::Emoji ::REGEX_EMOJI_KEYCAP )
43
+ REGEX_EMOJI_ALL_SEQUENCES_AND_VS16 = Regexp . union ( REGEX_EMOJI_ALL_SEQUENCES , REGEX_EMOJI_VS16 )
36
44
37
45
# Returns monospace display width of string
38
46
def self . of ( string , ambiguous = nil , overwrite = nil , old_options = { } , **options )
@@ -177,45 +185,23 @@ def self.emoji_width(string, mode = :all, ambiguous = DEFAULT_AMBIGUOUS)
177
185
mode == :rgi_at ,
178
186
ambiguous ,
179
187
)
188
+
180
189
elsif mode == :all_no_vs16
181
- emoji_width_all ( string )
190
+ no_emoji_string = string . gsub ( REGEX_EMOJI_ALL_SEQUENCES ) { res += 2 ; "" }
191
+ [ res , no_emoji_string ]
192
+
182
193
elsif mode == :vs16
183
- emoji_width_basic ( string )
194
+ no_emoji_string = string . gsub ( REGEX_EMOJI_VS16 ) { res += 2 ; "" }
195
+ [ res , no_emoji_string ]
196
+
184
197
elsif mode == :all
185
- res_all , string = emoji_width_all ( string )
186
- res_basic , string = emoji_width_basic ( string )
187
- [ res_all + res_basic , string ]
198
+ no_emoji_string = string . gsub ( REGEX_EMOJI_ALL_SEQUENCES_AND_VS16 ) { res += 2 ; "" }
199
+ [ res , no_emoji_string ]
200
+
188
201
else
189
202
[ 0 , string ]
190
- end
191
- end
192
-
193
- # Ensure all explicit VS16 sequences have width 2
194
- def self . emoji_width_basic ( string )
195
- res = 0
196
203
197
- no_emoji_string = string . gsub ( REGEX_EMOJI_BASIC_OR_KEYCAP ) { |basic_emoji |
198
- if basic_emoji . size >= 2 # VS16 present
199
- res += 2
200
- ""
201
- else
202
- basic_emoji
203
- end
204
- }
205
-
206
- [ res , no_emoji_string ]
207
- end
208
-
209
- # Use simplistic ZWJ/modifier/kecap sequence matching
210
- def self . emoji_width_all ( string )
211
- res = 0
212
-
213
- no_emoji_string = string . gsub ( REGEX_EMOJI_ALL_SEQUENCES ) {
214
- res += 2
215
- ""
216
- }
217
-
218
- [ res , no_emoji_string ]
204
+ end
219
205
end
220
206
221
207
# Match possible Emoji first, then refine
@@ -241,14 +227,7 @@ def self.emoji_width_via_possible(string, emoji_set_regex, strict_eaw = false, a
241
227
else
242
228
if !strict_eaw
243
229
# Ensure all explicit VS16 sequences have width 2
244
- emoji_candidate . gsub! ( Unicode ::Emoji ::REGEX_BASIC ) { |basic_emoji |
245
- if basic_emoji . size == 2 # VS16 present
246
- res += 2
247
- ""
248
- else
249
- basic_emoji
250
- end
251
- }
230
+ emoji_candidate . gsub! ( REGEX_EMOJI_VS16 ) { res += 2 ; "" }
252
231
end
253
232
254
233
emoji_candidate
0 commit comments