Expand skin tones support
- Lookup emoji by unicode that contains a skin tone modifier - Generate skin tone variants from an emoji
This commit is contained in:
@@ -51,11 +51,12 @@ module Emoji
|
||||
|
||||
# Public: Find an emoji by its unicode character. Return nil if missing.
|
||||
def find_by_unicode(unicode)
|
||||
unicodes_index[unicode]
|
||||
unicodes_index[unicode] || unicodes_index[unicode.sub(SKIN_TONE_RE, "")]
|
||||
end
|
||||
|
||||
private
|
||||
VARIATION_SELECTOR_16 = "\u{fe0f}".freeze
|
||||
SKIN_TONE_RE = /[\u{1F3FB}-\u{1F3FF}]/
|
||||
|
||||
# Characters which must have VARIATION_SELECTOR_16 to render as color emoji:
|
||||
TEXT_GLYPHS = [
|
||||
@@ -70,7 +71,7 @@ module Emoji
|
||||
"\u{3030}", # wavy dash
|
||||
].freeze
|
||||
|
||||
private_constant :VARIATION_SELECTOR_16, :TEXT_GLYPHS
|
||||
private_constant :VARIATION_SELECTOR_16, :TEXT_GLYPHS, :SKIN_TONE_RE
|
||||
|
||||
def parse_data_file
|
||||
data = File.open(data_file, 'r:UTF-8') do |file|
|
||||
|
||||
@@ -43,6 +43,21 @@ module Emoji
|
||||
# Raw Unicode string for an emoji. Nil if emoji is non-standard.
|
||||
def raw() unicode_aliases.first end
|
||||
|
||||
# Raw Unicode strings for each skin tone variant of this emoji.
|
||||
def raw_skin_tone_variants
|
||||
return [] if custom? || !skin_tones?
|
||||
raw_normalized = raw.sub("\u{fe0f}", "") # strip VARIATION_SELECTOR_16
|
||||
idx = raw_normalized.index("\u{200d}") # detect zero-width joiner
|
||||
SKIN_TONES.map do |modifier|
|
||||
if idx
|
||||
# insert modifier before zero-width joiner
|
||||
raw_normalized[...idx] + modifier + raw_normalized[idx..]
|
||||
else
|
||||
raw_normalized + modifier
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_unicode_alias(str)
|
||||
unicode_aliases << str
|
||||
end
|
||||
@@ -82,6 +97,16 @@ module Emoji
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
SKIN_TONES = [
|
||||
"\u{1F3FB}", # light skin tone
|
||||
"\u{1F3FC}", # medium-light skin tone
|
||||
"\u{1F3FD}", # medium skin tone
|
||||
"\u{1F3FE}", # medium-dark skin tone
|
||||
"\u{1F3FF}", # dark skin tone
|
||||
]
|
||||
|
||||
private_constant :SKIN_TONES
|
||||
|
||||
def default_image_filename
|
||||
if custom?
|
||||
|
||||
@@ -155,9 +155,22 @@ class EmojiTest < TestCase
|
||||
test "skin tones" do
|
||||
smiley = Emoji.find_by_alias("smiley")
|
||||
assert_equal false, smiley.skin_tones?
|
||||
assert_equal [], smiley.raw_skin_tone_variants
|
||||
|
||||
wave = Emoji.find_by_alias("wave")
|
||||
assert_equal true, wave.skin_tones?
|
||||
|
||||
wave = Emoji.find_by_unicode("\u{1f44b}\u{1f3ff}") # wave + dark skin tone
|
||||
assert_equal "wave", wave.name
|
||||
|
||||
woman_with_beard = Emoji.find_by_unicode("\u{1f9d4}\u{200d}\u{2640}\u{fe0f}")
|
||||
assert_equal [
|
||||
"1f9d4-1f3fb-200d-2640",
|
||||
"1f9d4-1f3fc-200d-2640",
|
||||
"1f9d4-1f3fd-200d-2640",
|
||||
"1f9d4-1f3fe-200d-2640",
|
||||
"1f9d4-1f3ff-200d-2640",
|
||||
], woman_with_beard.raw_skin_tone_variants.map { |u| Emoji::Character.hex_inspect(u) }
|
||||
end
|
||||
|
||||
test "no custom emojis" do
|
||||
|
||||
Reference in New Issue
Block a user