-
-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathexmoji.ex
156 lines (124 loc) · 4.67 KB
/
exmoji.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
defmodule Exmoji do
@moduledoc """
An Elixir/Erlang library providing low level operations for dealing with Emoji
glyphs in the Unicode standard.
Exmoji is like a swiss-army knife for dealing with Emoji encoding issues. If
all you need to do is translate `:poop:` into a smiling poop glyph, then there
are plenty of other libs out there that will probably do what you want. But
once you are dealing with Emoji as a fundamental part of your application, and
you start to realize the nightmare of doublebyte encoding or variants, then
this library may be your new best friend.
"""
alias Exmoji.EmojiChar
#
# Read and parse the Emoji library from our vendored data file.
#
vendor_data_file = "vendor/emoji-data/emoji.json"
@external_resource vendor_data_file
rawfile = File.read! vendor_data_file
rawdata = Jazz.Decode.it! rawfile, keys: :atoms
emoji_chars = for char <- rawdata do
%EmojiChar{
name: char.name,
unified: char.unified,
variations: char.variations,
short_name: char.short_name,
short_names: char.short_names,
text: char.text
}
end
@emoji_chars emoji_chars
@doc """
Returns a list of all #{Enum.count @emoji_chars} Emoji characters as `EmojiChar`.
"""
def all, do: @emoji_chars
@doc """
Returns a list of all `EmojiChar` that are represented as doublebyte encoding.
"""
@all_doublebyte_cache Enum.filter(@emoji_chars, &EmojiChar.doublebyte?/1)
def all_doublebyte, do: @all_doublebyte_cache
@doc """
Returns a list of all `EmojiChar` that have at least one variant encoding.
"""
@all_variant_cache Enum.filter(@emoji_chars, &EmojiChar.variant?/1)
def all_with_variants, do: @all_variant_cache
@doc """
Returns a list of all known Emoji characters rendered as Unicode bitstrings.
By default, the default rendering options for this library will be used.
However, if you pass the option of `include_variants: true` then all possible
renderings of a single glyph will be included, meaning that:
1. You will have "duplicate" emojis in your list.
2. This list is now suitable for exhaustably matching against in a search.
"""
def chars(opts \\ []) do
case Keyword.get(opts, :include_variants, false) do
false ->
Enum.map(@emoji_chars, &EmojiChar.render/1)
true ->
Enum.map(@emoji_chars, &EmojiChar.chars/1)
|> List.flatten
end
end
@doc """
Returns a list of all known codepoints representing Emoji characters.
This function also accepts the `include_variants` option, for details on its
significance, see similar discussion for the `Exmoji.chars/1` function.
"""
def codepoints(opts \\ []) do
case Keyword.get(opts, :include_variants, false) do
false ->
Enum.map(@emoji_chars, &(&1.unified))
true ->
Enum.map(@emoji_chars, &EmojiChar.codepoint_ids/1)
|> List.flatten
end
end
@doc """
Finds any `EmojiChar` that contains given string in its official name.
## Examples
iex> Exmoji.find_by_name "father"
[%Exmoji.EmojiChar{name: "FATHER CHRISTMAS", short_name: "santa",
short_names: ["santa"], text: nil, unified: "1F385", variations: []}]
iex> for t <- Exmoji.find_by_name("tree"), do: t.name
["EVERGREEN TREE", "DECIDUOUS TREE", "PALM TREE", "CHRISTMAS TREE",
"TANABATA TREE"]
"""
def find_by_name(name) do
name = String.upcase(name)
@emoji_chars |> Enum.filter( fn x -> String.contains?(x.name, name) end )
end
@doc """
Find all `EmojiChar` that match substring in any of their associated short
name keywords.
"""
def find_by_short_name(sname) do
target = String.downcase(sname)
@emoji_chars |> Enum.filter( &(_matches_short_name(&1, target)) )
end
defp _matches_short_name(%EmojiChar{short_names: short_names}, target) do
Enum.any? short_names, fn(sn) -> String.contains?(sn, target) end
end
@doc """
Finds an `EmojiChar` based on its short name keyword.
Case insensitive. Otherwise must match exactly. Do not include the `:colon:`
identifiers if you are parsing text that uses them to indicate the presence of
a keyword.
"""
def from_short_name(sname) do
sname |> String.downcase |> _from_short_name
end
for ec <- @emoji_chars, sn <- ec.short_names do
defp _from_short_name( unquote(sn) ), do: unquote(Macro.escape(ec))
end
defp _from_short_name(_), do: nil
@doc """
Finds a specific `EmojiChar` based on the unified codepoint ID.
"""
def from_unified(uid) do
uid |> String.upcase |> _from_unified
end
for ec <- @emoji_chars, cp <- EmojiChar.codepoint_ids(ec) do
defp _from_unified( unquote(cp) ), do: unquote(Macro.escape(ec))
end
defp _from_unified(_), do: nil
end