logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git
commit: 01d396585e428ea1ca7e21868d7303a0bd8ffd6f
parent d39f803bddb04a4c0a9e0742a437fd07f461c615
Author: Hélène <pleroma-dev@helene.moe>
Date:   Mon, 25 Jul 2022 16:20:12 +0200

Emoji: implement full-qualifier using combinations

This implements fully_qualify_emoji/1, which will return the
fully-qualified version of an emoji if it knows of one, or return the
emoji unmodified if not.
This code generates combinations per emoji: for each FE0F, all possible
combinations of the character being removed or staying will be
generated. This is made as an attempt to find all partially-qualified
and unqualified versions of a fully-qualified emoji.

I have found *no cases* for which this would be a problem, after
browsing the entire emoji list in emoji-test.txt. This is safe, and,
sadly, most likely the sanest too.

Diffstat:

Mlib/pleroma/emoji.ex45+++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+), 0 deletions(-)

diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex @@ -137,4 +137,49 @@ defmodule Pleroma.Emoji do end def is_unicode_emoji?(_), do: false + + # FE0F is the emoji variation sequence. It is used for fully-qualifying + # emoji, and that includes emoji combinations. + # This code generates combinations per emoji: for each FE0F, all possible + # combinations of the character being removed or staying will be generated. + # This is made as an attempt to find all partially-qualified and unqualified + # versions of a fully-qualified emoji. + # I have found *no cases* for which this would be a problem, after browsing + # the entire emoji list in emoji-test.txt. This is safe, and, sadly, most + # likely sane too. + emoji_qualification_map = + emojis + |> Enum.filter(&String.contains?(&1, "\uFE0F")) + |> Enum.map(fn emoji -> + combinate = fn x, combinate -> + case x do + [] -> + [[]] + + ["\uFE0F" | tail] -> + combinate.(tail, combinate) + |> Enum.flat_map(fn x -> [x, ["\uFE0F" | x]] end) + + [codepoint | tail] -> + combinate.(tail, combinate) + |> Enum.map(fn x -> [codepoint | x] end) + end + end + + unqualified_list = + emoji + |> String.codepoints() + |> combinate.(combinate) + |> Enum.map(&List.to_string/1) + + {emoji, unqualified_list} + end) + + for {qualified, unqualified_list} <- emoji_qualification_map do + for unqualified <- unqualified_list do + def fully_qualify_emoji(unquote(unqualified)), do: unquote(qualified) + end + end + + def fully_qualify_emoji(emoji), do: emoji end