mirror of
https://invent.kde.org/plasma/plasma-desktop.git
synced 2026-11-03 14:49:44 -09:00
emojier: Use consistent emoji order
Most emojis and their variants in the "People" category follow the order "Person, Man, Woman". But for a few, the order is random. Also, for the "Select Variant" pop-up feature, Emojier expects variants with mixed skin tones to be placed near the base emoji or variants with only one skin tone. Emoji Version 17 adds six emojis that do not follow this ordering, breaking the feature. Sort the emojis by this pattern.
This commit is contained in:
parent
e32130d158
commit
5b8c6a28c6
3 changed files with 102 additions and 0 deletions
|
|
@ -67,6 +67,13 @@ class EmojierTest(unittest.TestCase):
|
|||
self.driver.find_element(AppiumBy.NAME, "Recent").click()
|
||||
self.driver.find_element(AppiumBy.NAME, "grinning face")
|
||||
|
||||
def test_3_select_variant(self) -> None:
|
||||
self.driver.find_element(AppiumBy.NAME, "All").click()
|
||||
self.driver.find_element(AppiumBy.NAME, "Search").send_keys("handshake")
|
||||
self.driver.find_element(AppiumBy.NAME, "Select Variant of \"handshake\"").click()
|
||||
self.driver.find_element(AppiumBy.NAME, "handshake: light skin tone, medium skin tone").click()
|
||||
time.sleep(1)
|
||||
self.assertEqual(self.driver.get_clipboard_text(), "🫱🏻🫲🏽")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -24,6 +24,21 @@ CLDR_URL = f"https://unicode.org/Public/cldr/{CLDR_VERSION}/{CLDR_FILE}"
|
|||
CLDR_ANNOTATIONS_DIR = "common/annotations"
|
||||
CLDR_ANNOTATIONS_DERIVED_DIR = "common/annotationsDerived"
|
||||
|
||||
SKIN_TONES = {
|
||||
b"light skin tone",
|
||||
b"medium-light skin tone",
|
||||
b"medium skin tone",
|
||||
b"medium-dark skin tone",
|
||||
b"dark skin tone",
|
||||
}
|
||||
|
||||
GENDER_SYMBOLS = {
|
||||
"\u200D♂️",
|
||||
"👨",
|
||||
"\u200D♀️",
|
||||
"👩",
|
||||
}
|
||||
|
||||
class EmojiAnnotation(object):
|
||||
def __init__(self):
|
||||
self.description = ""
|
||||
|
|
@ -35,6 +50,42 @@ class EmojiParser(object):
|
|||
self.categoryNames = []
|
||||
self.emojis = collections.OrderedDict()
|
||||
|
||||
self.descriptionEmojiMap = {}
|
||||
self.skinToneMap = collections.defaultdict(list)
|
||||
self.genderMap = collections.defaultdict(lambda: [None, None, None])
|
||||
self.genderAndSkinToneVariants = set()
|
||||
|
||||
def addToGenderMap(self, emoji):
|
||||
isMale = "👨" in emoji or "\u200D♂️" in emoji
|
||||
isFemale = "👩" in emoji or "\u200D♀️" in emoji
|
||||
|
||||
if isMale and isFemale:
|
||||
genderIndex = 0
|
||||
elif isMale:
|
||||
genderIndex = 1
|
||||
else:
|
||||
genderIndex = 2
|
||||
|
||||
neutralEmoji = emoji.replace("\u200D♂️", "")
|
||||
neutralEmoji = neutralEmoji.replace("👨", "🧑")
|
||||
neutralEmoji = neutralEmoji.replace("\u200D♀️", "")
|
||||
neutralEmoji = neutralEmoji.replace("👩", "🧑")
|
||||
|
||||
if neutralEmoji not in self.emojis:
|
||||
return
|
||||
|
||||
self.genderMap[neutralEmoji][genderIndex] = emoji
|
||||
self.genderAndSkinToneVariants.add(emoji)
|
||||
|
||||
def getSkinToneVariantsDict(self, emoji):
|
||||
if emoji is None:
|
||||
return {}
|
||||
|
||||
skinToneVariants = {emoji: self.emojis[emoji]}
|
||||
for variant in self.skinToneMap[emoji]:
|
||||
skinToneVariants[variant] = self.emojis[variant]
|
||||
return skinToneVariants
|
||||
|
||||
def parseEmojiTest(self, emojiTestData):
|
||||
descriptionMapping = dict()
|
||||
currentGroup = 0;
|
||||
|
|
@ -69,6 +120,11 @@ class EmojiParser(object):
|
|||
if status == b"fully-qualified":
|
||||
self.emojis[emoji] = currentGroup
|
||||
descriptionMapping[description] = emoji
|
||||
|
||||
# description format: "version emoji name: modifiers"
|
||||
versionNameDelimiter = description.index(b" ")
|
||||
descriptionWithoutVersion = description[versionNameDelimiter+1:]
|
||||
self.descriptionEmojiMap[descriptionWithoutVersion] = emoji
|
||||
else:
|
||||
fullyQualified = descriptionMapping.get(description, None);
|
||||
if fullyQualified:
|
||||
|
|
@ -76,6 +132,45 @@ class EmojiParser(object):
|
|||
except e:
|
||||
pass
|
||||
|
||||
for description, emoji in self.descriptionEmojiMap.items():
|
||||
# description format: "emoji name: modifier 1, modifier 2, ..., modifier n"
|
||||
nameAndModifiers = description.split(b": ")
|
||||
if len(nameAndModifiers) == 2:
|
||||
name, modifiers = nameAndModifiers
|
||||
|
||||
if any(skinTone in modifiers for skinTone in SKIN_TONES):
|
||||
modifiers = modifiers.split(b", ")
|
||||
modifiersWithoutSkinTone = b", ".join(mod for mod in modifiers if mod not in SKIN_TONES and mod != b"person")
|
||||
descriptionWithoutSkinTone = name + (b": " + modifiersWithoutSkinTone if modifiersWithoutSkinTone else b"")
|
||||
|
||||
try:
|
||||
neutralEmoji = self.descriptionEmojiMap[descriptionWithoutSkinTone]
|
||||
self.skinToneMap[neutralEmoji].append(emoji)
|
||||
self.genderAndSkinToneVariants.add(emoji)
|
||||
except:
|
||||
pass
|
||||
elif any(gender in emoji for gender in GENDER_SYMBOLS):
|
||||
self.addToGenderMap(emoji)
|
||||
elif any(gender in emoji for gender in GENDER_SYMBOLS):
|
||||
self.addToGenderMap(emoji)
|
||||
|
||||
self.genderMap["🧑🤝🧑"] = ["👫", "👬", "👭"]
|
||||
self.genderAndSkinToneVariants.update(["👫", "👬", "👭"])
|
||||
|
||||
sortedEmojis = {}
|
||||
for emoji, group in self.emojis.items():
|
||||
if emoji in self.genderAndSkinToneVariants:
|
||||
pass
|
||||
elif emoji in self.genderMap:
|
||||
for genderEmoji in [emoji] + self.genderMap[emoji]:
|
||||
sortedEmojis.update(self.getSkinToneVariantsDict(genderEmoji))
|
||||
elif emoji in self.skinToneMap:
|
||||
sortedEmojis.update(self.getSkinToneVariantsDict(emoji))
|
||||
else:
|
||||
sortedEmojis[emoji] = group
|
||||
|
||||
self.emojis = sortedEmojis
|
||||
|
||||
def parseCldr(self, cldrList):
|
||||
annotations = dict()
|
||||
for data in cldrList:
|
||||
|
|
|
|||
Loading…
Reference in a new issue