Skip to content

Commit

Permalink
Improve VS16 matching
Browse files Browse the repository at this point in the history
  • Loading branch information
janlelis committed Nov 19, 2024
1 parent b79047c commit 5d13cb1
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 44 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 3.1.1

- Performance improvements

## 3.1.0

**Improve Emoji support:**
Expand Down
65 changes: 22 additions & 43 deletions lib/unicode/display_width.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ class DisplayWidth
rgi_at: :REGEX_INCLUDE_MQE_UQE,
possible: :REGEX_WELL_FORMED,
}
REGEX_EMOJI_BASIC_OR_KEYCAP = Regexp.union(Unicode::Emoji::REGEX_BASIC, Unicode::Emoji::REGEX_EMOJI_KEYCAP)
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)
REGEX_EMOJI_NOT_POSSIBLE = /\A[#*0-9]\z/
REGEX_EMOJI_VS16 = Regexp.union(
Regexp.compile(
Unicode::Emoji::REGEX_TEXT_PRESENTATION.source +
"(?<![#*0-9])" +
"\u{FE0F}"
),
Unicode::Emoji::REGEX_EMOJI_KEYCAP
)
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)
REGEX_EMOJI_ALL_SEQUENCES_AND_VS16 = Regexp.union(REGEX_EMOJI_ALL_SEQUENCES, REGEX_EMOJI_VS16)

# Returns monospace display width of string
def self.of(string, ambiguous = nil, overwrite = nil, old_options = {}, **options)
Expand Down Expand Up @@ -177,45 +185,23 @@ def self.emoji_width(string, mode = :all, ambiguous = DEFAULT_AMBIGUOUS)
mode == :rgi_at,
ambiguous,
)

elsif mode == :all_no_vs16
emoji_width_all(string)
no_emoji_string = string.gsub(REGEX_EMOJI_ALL_SEQUENCES){ res += 2; "" }
[res, no_emoji_string]

elsif mode == :vs16
emoji_width_basic(string)
no_emoji_string = string.gsub(REGEX_EMOJI_VS16){ res += 2; "" }
[res, no_emoji_string]

elsif mode == :all
res_all, string = emoji_width_all(string)
res_basic, string = emoji_width_basic(string)
[res_all + res_basic, string]
no_emoji_string = string.gsub(REGEX_EMOJI_ALL_SEQUENCES_AND_VS16){ res += 2; "" }
[res, no_emoji_string]

else
[0, string]
end
end

# Ensure all explicit VS16 sequences have width 2
def self.emoji_width_basic(string)
res = 0

no_emoji_string = string.gsub(REGEX_EMOJI_BASIC_OR_KEYCAP){ |basic_emoji|
if basic_emoji.size >= 2 # VS16 present
res += 2
""
else
basic_emoji
end
}

[res, no_emoji_string]
end

# Use simplistic ZWJ/modifier/kecap sequence matching
def self.emoji_width_all(string)
res = 0

no_emoji_string = string.gsub(REGEX_EMOJI_ALL_SEQUENCES){
res += 2
""
}

[res, no_emoji_string]
end
end

# Match possible Emoji first, then refine
Expand All @@ -241,14 +227,7 @@ def self.emoji_width_via_possible(string, emoji_set_regex, strict_eaw = false, a
else
if !strict_eaw
# Ensure all explicit VS16 sequences have width 2
emoji_candidate.gsub!(Unicode::Emoji::REGEX_BASIC){ |basic_emoji|
if basic_emoji.size == 2 # VS16 present
res += 2
""
else
basic_emoji
end
}
emoji_candidate.gsub!(REGEX_EMOJI_VS16){ res += 2; "" }
end

emoji_candidate
Expand Down
4 changes: 4 additions & 0 deletions spec/display_width_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@
it 'counts default-text presentation Emoji with Emoji Presentation (VS16) as 2' do
expect( "❣️".display_width(emoji: :vs16) ).to eq 2
end

it 'works with keycaps: width 2' do
expect( "1️⃣".display_width(emoji: :vs16) ).to eq 2
end
end

describe ':rgi' do
Expand Down
2 changes: 1 addition & 1 deletion unicode-display_width.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Gem::Specification.new do |s|
s.extra_rdoc_files = ["README.md", "MIT-LICENSE.txt", "CHANGELOG.md"]
s.license = 'MIT'
s.required_ruby_version = '>= 2.5.0'
s.add_dependency 'unicode-emoji', '~> 4.0'
s.add_dependency 'unicode-emoji', '~> 4.0', '>= 4.0.4'
s.add_development_dependency 'rspec', '~> 3.4'
s.add_development_dependency 'rake', '~> 13.0'

Expand Down

0 comments on commit 5d13cb1

Please sign in to comment.