emoji-datasource 14.0.0 → 14.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -1
- data/lib/emoji_datasource/emoji.rb +57 -10
- data/lib/emoji_datasource/version.rb +1 -1
- data/lib/emoji_datasource.rb +61 -6
- metadata +2 -3
- data/lib/emoji_datasource/short_name_to_char.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b821544f15170c9489e0ce8938978549829e3c925d3ec6444dfacb7c125b94ca
|
4
|
+
data.tar.gz: bf4e9c21d3c5ea9de80132de4aa56bfec68c705aba979863151d650facc73f77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03d5041a86c4d7bccde94965634abffd3194c7cc3dcfa70e1de6f573ea1b6d444c6382cc0275b88165597247dd1e97f1ced2050ca671c51183fcb62412a8dcea
|
7
|
+
data.tar.gz: 994db50c5e4221bf51ed491d108d0b3fb48dea1fae2837d3129d39586d8eb7d080e0423bec5aac775eba4ffc0360299bd20cb64b607f4333c0b9f36a6b2805f2
|
data/README.md
CHANGED
@@ -22,6 +22,21 @@ Find emoji by short name
|
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
EmojiDatasource.find_by_short_name('+1')
|
25
|
+
#=> EmojiDatasource::Emoji: :+1: (👍)
|
26
|
+
```
|
27
|
+
|
28
|
+
Find emoji by raw string:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
EmojiDatasource.find_by_char('👍🏾')
|
32
|
+
#=> EmojiDatasource::Emoji: :+1::skin-tone-5: (👍🏾)
|
33
|
+
```
|
34
|
+
|
35
|
+
Find emoji by unicode hex character code:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
EmojiDatasource.find_by_unified("1F469-200D-2764-FE0F-200D-1F468")
|
39
|
+
#=> EmojiDatasource::Emoji: :woman-heart-man: (👩❤️👨)
|
25
40
|
```
|
26
41
|
|
27
42
|
Convert emoji short name to character
|
@@ -33,9 +48,17 @@ EmojiDatasource.short_name_to_char('+1') # => 👍
|
|
33
48
|
this also supports skin variations
|
34
49
|
|
35
50
|
```ruby
|
36
|
-
EmojiDatasource.short_name_to_char('+1::skin-tone-2') # =>
|
51
|
+
EmojiDatasource.short_name_to_char('+1::skin-tone-2') # => 👍🏻
|
37
52
|
```
|
38
53
|
|
54
|
+
Get base emoji for skin variation:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
emoji = EmojiDatasource.find_by_short_name(':+1::skin-tone-5:')
|
58
|
+
#=> EmojiDatasource::Emoji: :+1::skin-tone-5: (👍🏾)
|
59
|
+
emoji.base
|
60
|
+
#=> EmojiDatasource::Emoji: :+1: (👍)
|
61
|
+
```
|
39
62
|
|
40
63
|
## Supported Ruby Versions
|
41
64
|
|
@@ -2,38 +2,75 @@
|
|
2
2
|
|
3
3
|
module EmojiDatasource
|
4
4
|
class Emoji
|
5
|
-
attr_reader :data
|
5
|
+
attr_reader :data, :unified
|
6
6
|
|
7
|
-
def initialize(data)
|
7
|
+
def initialize(data, variation: nil)
|
8
8
|
@data = data
|
9
|
+
@variation = variation
|
10
|
+
@unified = variation ? @data.dig('skin_variations', variation, 'unified') : @data['unified']
|
9
11
|
end
|
10
12
|
|
13
|
+
# Raw emoji string
|
11
14
|
def to_char
|
12
|
-
EmojiDatasource.unified_to_char(
|
15
|
+
EmojiDatasource.unified_to_char(unified)
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
# Official emoji name (pretty long)
|
19
|
+
def name
|
20
|
+
return @data['name'] unless @variation
|
17
21
|
|
18
|
-
@data[
|
22
|
+
"#{@data['name']} (#{variation_emojis.map(&:name).join(', ')})"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Short code that often can be used to find emoji in pickers and chat apps
|
26
|
+
def short_name
|
27
|
+
return @data['short_name'] unless @variation
|
28
|
+
|
29
|
+
"#{@data['short_name']}::#{variation_emojis.map(&:short_name).join('::')}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# All known short names (base +short_name+ and maybe some aliases)
|
33
|
+
def short_names
|
34
|
+
return @data['short_names'] unless @variation
|
35
|
+
|
36
|
+
@data['short_names'].map do |short_name|
|
37
|
+
"#{short_name}::#{variation_emojis.map(&:short_name).join('::')}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# All known skin tone variations
|
42
|
+
def variations
|
43
|
+
return @variations = [] if @variation
|
44
|
+
|
45
|
+
@variations ||= @data.fetch('skin_variations', {}).each_key.map do |key|
|
46
|
+
self.class.new(data, variation: key)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Base emoji, without variations applied.
|
51
|
+
# E.g. for `:+1::skin-tone-2:` base will be just `:+1:`
|
52
|
+
def base
|
53
|
+
return self unless @variation
|
54
|
+
|
55
|
+
EmojiDatasource.find_by_unified(@data['unified'])
|
19
56
|
end
|
20
57
|
|
21
58
|
def method_missing(method_name, *arguments, &block)
|
22
|
-
if @data.key?(method_name)
|
23
|
-
@data[method_name]
|
59
|
+
if @data.key?(method_name.to_s)
|
60
|
+
@data[method_name.to_s]
|
24
61
|
else
|
25
62
|
super
|
26
63
|
end
|
27
64
|
end
|
28
65
|
|
29
66
|
def respond_to_missing?(method_name, include_private = false)
|
30
|
-
return true if @data.key?(method_name)
|
67
|
+
return true if @data.key?(method_name.to_s)
|
31
68
|
|
32
69
|
super
|
33
70
|
end
|
34
71
|
|
35
72
|
def inspect
|
36
|
-
"#{self.class.name}:#{short_name}"
|
73
|
+
"#{self.class.name}: :#{short_name}: (#{to_char})"
|
37
74
|
end
|
38
75
|
|
39
76
|
def to_s
|
@@ -47,5 +84,15 @@ module EmojiDatasource
|
|
47
84
|
def to_json(**args)
|
48
85
|
@data.to_json(**args)
|
49
86
|
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def variation_emojis
|
91
|
+
return [] unless @variation
|
92
|
+
|
93
|
+
@variation.split('-').map do |unified|
|
94
|
+
EmojiDatasource.find_by_unified(unified)
|
95
|
+
end
|
96
|
+
end
|
50
97
|
end
|
51
98
|
end
|
data/lib/emoji_datasource.rb
CHANGED
@@ -4,23 +4,50 @@ require 'json'
|
|
4
4
|
|
5
5
|
require_relative 'emoji_datasource/version'
|
6
6
|
require_relative 'emoji_datasource/emoji'
|
7
|
-
require_relative 'emoji_datasource/short_name_to_char'
|
8
7
|
|
9
8
|
module EmojiDatasource
|
10
9
|
class Error < StandardError; end
|
11
10
|
|
12
11
|
EMOJI_DATA_PATH = File.join(__dir__, '..', 'vendor', 'emoji-datasource', 'emoji.json')
|
13
12
|
|
13
|
+
# @example
|
14
|
+
# short_name_to_char('+1') #=> "👍"
|
14
15
|
def self.short_name_to_char(name)
|
15
|
-
|
16
|
+
find_by_short_name(name)&.to_char
|
16
17
|
end
|
17
18
|
|
19
|
+
# Finds emoji by short code (e.g. `+1`, `:+1:`, `:+1::skin-tone-5:`)
|
20
|
+
# @param name [String] short code with or without wrapping colons.
|
21
|
+
# @return [EmojiDatasource::Emoji] if there is an emoji matching +name+
|
22
|
+
# @return [nil] if there are no emojis matching +name+
|
23
|
+
# @example
|
24
|
+
# find_by_short_name('+1') #=> EmojiDatasource::Emoji: :+1: (👍)
|
18
25
|
def self.find_by_short_name(name)
|
19
26
|
return unless name
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
name = name.delete_prefix(':').delete_suffix(':') # Allow to find `+1` by `:+1:`
|
29
|
+
name.delete_suffix!('::skin-tone-1') # special case for default skin tone
|
30
|
+
short_name_lookup_map[name]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Finds emoji by unified hex representation of Unicode codepoints
|
34
|
+
# @param unified [String] Dash separated hexadecimal Unicode character codes for a single emoji
|
35
|
+
# @return [EmojiDatasource::Emoji] if given Unicode codepoints is a known emoji
|
36
|
+
# @return [nil] if there are no emojis with given codepoints in the dataset
|
37
|
+
# @example
|
38
|
+
# short_name_to_char('1F44D') #=> EmojiDatasource::Emoji: :+1: (👍)
|
39
|
+
def self.find_by_unified(unified)
|
40
|
+
unified_lookup_map[unified.upcase]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Find emoji object by raw Unicode string with a single emoji in it
|
44
|
+
# @param raw_emoji [String] Single emoji
|
45
|
+
# @return [EmojiDatasource::Emoji] if given string contains a single known emoji
|
46
|
+
# @return [nil] if there are no such emoji in the dataset
|
47
|
+
# @example
|
48
|
+
# find_by_char('👍') #=> EmojiDatasource::Emoji: :+1: (👍)
|
49
|
+
def self.find_by_char(raw_emoji)
|
50
|
+
find_by_unified(char_to_unified(raw_emoji))
|
24
51
|
end
|
25
52
|
|
26
53
|
def self.unified_to_char(unified_name)
|
@@ -29,10 +56,38 @@ module EmojiDatasource
|
|
29
56
|
unified_name.split('-').map(&:hex).pack('U*')
|
30
57
|
end
|
31
58
|
|
59
|
+
def self.char_to_unified(raw_emoji)
|
60
|
+
return unless raw_emoji
|
61
|
+
|
62
|
+
raw_emoji.unpack('U*').map { |c| c.to_s(16).upcase }.join('-')
|
63
|
+
end
|
64
|
+
|
32
65
|
def self.data
|
33
|
-
@data ||= JSON.parse(File.read(EMOJI_DATA_PATH)
|
66
|
+
@data ||= JSON.parse(File.read(EMOJI_DATA_PATH))
|
34
67
|
.map { |emoji_data| EmojiDatasource::Emoji.new(emoji_data) }
|
35
68
|
end
|
69
|
+
|
70
|
+
# Utility hash map to search by emoji short code, including variants
|
71
|
+
# @api private
|
72
|
+
def self.short_name_lookup_map
|
73
|
+
@short_name_lookup_map ||= data.each_with_object({}) do |emoji, result|
|
74
|
+
emoji.short_names.each { |short_name| result[short_name] = emoji }
|
75
|
+
emoji.variations.each do |emoji_variant|
|
76
|
+
emoji_variant.short_names.each { |short_name| result[short_name] = emoji_variant }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Utility hash map to search by unicode character sequence hex codes, including variants
|
82
|
+
# @api private
|
83
|
+
def self.unified_lookup_map
|
84
|
+
@unified_lookup_map ||= data.each_with_object({}) do |emoji, result|
|
85
|
+
result[emoji.unified] = emoji
|
86
|
+
emoji.variations.each do |emoji_variant|
|
87
|
+
result[emoji_variant.unified] = emoji_variant
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
36
91
|
end
|
37
92
|
|
38
93
|
# Preload emojies on startup
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emoji-datasource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 14.0.
|
4
|
+
version: 14.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justas Palumickas
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -104,7 +104,6 @@ files:
|
|
104
104
|
- lib/emoji-datasource.rb
|
105
105
|
- lib/emoji_datasource.rb
|
106
106
|
- lib/emoji_datasource/emoji.rb
|
107
|
-
- lib/emoji_datasource/short_name_to_char.rb
|
108
107
|
- lib/emoji_datasource/version.rb
|
109
108
|
- package.json
|
110
109
|
- vendor/emoji-datasource/emoji.json
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EmojiDatasource
|
4
|
-
class ShortNameToChar
|
5
|
-
def self.generate(name)
|
6
|
-
new(name).call
|
7
|
-
end
|
8
|
-
|
9
|
-
attr_reader :short_name
|
10
|
-
|
11
|
-
def initialize(short_name)
|
12
|
-
@short_name = short_name
|
13
|
-
end
|
14
|
-
|
15
|
-
def call
|
16
|
-
return unless short_name
|
17
|
-
return EmojiDatasource.find_by_short_name(short_name)&.to_char unless skin_tone_matches
|
18
|
-
|
19
|
-
emoji = EmojiDatasource.find_by_short_name(skin_tone_matches[1])
|
20
|
-
return unless emoji
|
21
|
-
return emoji.to_char if skin_tone_level == 1
|
22
|
-
|
23
|
-
char_with_skin_tone(emoji)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def char_with_skin_tone(emoji)
|
29
|
-
return unless skin_tone_emoji
|
30
|
-
|
31
|
-
skin_variation = emoji.skin_variations && emoji.skin_variations[skin_tone_emoji.unified]
|
32
|
-
return unless skin_variation
|
33
|
-
|
34
|
-
EmojiDatasource.unified_to_char(skin_variation[:unified])
|
35
|
-
end
|
36
|
-
|
37
|
-
def skin_tone_emoji
|
38
|
-
EmojiDatasource.find_by_short_name("skin-tone-#{skin_tone_level}")
|
39
|
-
end
|
40
|
-
|
41
|
-
def skin_tone_level
|
42
|
-
skin_tone_matches[2].to_i
|
43
|
-
end
|
44
|
-
|
45
|
-
def skin_tone_matches
|
46
|
-
short_name.match(/:?(.+)::skin-tone-(\d+):?/)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|