gemoji 3.0.1 → 4.0.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/LICENSE +22 -0
- data/README.md +1 -16
- data/db/emoji.json +11832 -7054
- data/lib/emoji.rb +56 -50
- data/lib/emoji/character.rb +2 -0
- data/lib/gemoji.rb +2 -0
- metadata +12 -34
- data/bin/gemoji +0 -5
- data/db/Category-Emoji.json +0 -71
- data/images/basecamp.png +0 -0
- data/images/basecampy.png +0 -0
- data/images/bowtie.png +0 -0
- data/images/feelsgood.png +0 -0
- data/images/finnadie.png +0 -0
- data/images/goberserk.png +0 -0
- data/images/godmode.png +0 -0
- data/images/hurtrealbad.png +0 -0
- data/images/neckbeard.png +0 -0
- data/images/octocat.png +0 -0
- data/images/rage1.png +0 -0
- data/images/rage2.png +0 -0
- data/images/rage3.png +0 -0
- data/images/rage4.png +0 -0
- data/images/shipit.png +0 -0
- data/images/suspect.png +0 -0
- data/images/trollface.png +0 -0
- data/lib/emoji/cli.rb +0 -68
- data/lib/emoji/extractor.rb +0 -190
data/lib/emoji.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require 'emoji/character'
|
3
5
|
require 'json'
|
4
6
|
|
@@ -9,14 +11,6 @@ module Emoji
|
|
9
11
|
File.expand_path('../../db/emoji.json', __FILE__)
|
10
12
|
end
|
11
13
|
|
12
|
-
def apple_palette_file
|
13
|
-
File.expand_path('../../db/Category-Emoji.json', __FILE__)
|
14
|
-
end
|
15
|
-
|
16
|
-
def images_path
|
17
|
-
File.expand_path("../../images", __FILE__)
|
18
|
-
end
|
19
|
-
|
20
14
|
def all
|
21
15
|
return @all if defined? @all
|
22
16
|
@all = []
|
@@ -24,17 +18,6 @@ module Emoji
|
|
24
18
|
@all
|
25
19
|
end
|
26
20
|
|
27
|
-
def apple_palette
|
28
|
-
return @apple_palette if defined? @apple_palette
|
29
|
-
data = File.open(apple_palette_file, 'r:UTF-8') { |f| JSON.parse(f.read) }
|
30
|
-
@apple_palette = data.fetch('EmojiDataArray').each_with_object({}) do |group, all|
|
31
|
-
title = group.fetch('CVDataTitle').split('-', 2)[1]
|
32
|
-
all[title] = group.fetch('CVCategoryData').fetch('Data').split(',').map do |raw|
|
33
|
-
TEXT_GLYPHS.include?(raw) ? raw + VARIATION_SELECTOR_16 : raw
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
21
|
# Public: Initialize an Emoji::Character instance and yield it to the block.
|
39
22
|
# The character is added to the `Emoji.all` set.
|
40
23
|
def create(name)
|
@@ -73,45 +56,68 @@ module Emoji
|
|
73
56
|
|
74
57
|
private
|
75
58
|
VARIATION_SELECTOR_16 = "\u{fe0f}".freeze
|
76
|
-
ZERO_WIDTH_JOINER = "\u{200d}".freeze
|
77
|
-
FEMALE_SYMBOL = "\u{2640}".freeze
|
78
|
-
MALE_SYMBOL = "\u{2642}".freeze
|
79
59
|
|
80
|
-
#
|
81
|
-
TEXT_GLYPHS = [
|
60
|
+
# Characters which must have VARIATION_SELECTOR_16 to render as color emoji:
|
61
|
+
TEXT_GLYPHS = [
|
62
|
+
"\u{1f237}", # Japanese “monthly amount” button
|
63
|
+
"\u{1f202}", # Japanese “service charge” button
|
64
|
+
"\u{1f170}", # A button (blood type)
|
65
|
+
"\u{1f171}", # B button (blood type)
|
66
|
+
"\u{1f17e}", # O button (blood type)
|
67
|
+
"\u{00a9}", # copyright
|
68
|
+
"\u{00ae}", # registered
|
69
|
+
"\u{2122}", # trade mark
|
70
|
+
"\u{3030}", # wavy dash
|
71
|
+
].freeze
|
72
|
+
|
73
|
+
private_constant :VARIATION_SELECTOR_16, :TEXT_GLYPHS
|
82
74
|
|
83
75
|
def parse_data_file
|
84
|
-
data = File.open(data_file, 'r:UTF-8')
|
85
|
-
|
86
|
-
|
87
|
-
raw_emoji.fetch('aliases').each { |name| emoji.add_alias(name) }
|
88
|
-
if raw = raw_emoji['emoji']
|
89
|
-
unicodes = [raw, raw.sub(VARIATION_SELECTOR_16, '') + VARIATION_SELECTOR_16].uniq
|
90
|
-
unicodes.each { |uni| emoji.add_unicode_alias(uni) }
|
91
|
-
end
|
92
|
-
raw_emoji.fetch('tags').each { |tag| emoji.add_tag(tag) }
|
76
|
+
data = File.open(data_file, 'r:UTF-8') do |file|
|
77
|
+
JSON.parse(file.read, symbolize_names: true)
|
78
|
+
end
|
93
79
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
80
|
+
if "".respond_to?(:-@)
|
81
|
+
# Ruby >= 2.3 this is equivalent to .freeze
|
82
|
+
# Ruby >= 2.5 this will freeze and dedup
|
83
|
+
dedup = lambda { |str| -str }
|
84
|
+
else
|
85
|
+
dedup = lambda { |str| str.freeze }
|
86
|
+
end
|
87
|
+
|
88
|
+
append_unicode = lambda do |emoji, raw|
|
89
|
+
unless TEXT_GLYPHS.include?(raw) || emoji.unicode_aliases.include?(raw)
|
90
|
+
emoji.add_unicode_alias(dedup.call(raw))
|
98
91
|
end
|
99
92
|
end
|
100
93
|
|
101
|
-
# Add an explicit gendered variant to emoji that historically imply a gender
|
102
94
|
data.each do |raw_emoji|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
95
|
+
self.create(nil) do |emoji|
|
96
|
+
raw_emoji.fetch(:aliases).each { |name| emoji.add_alias(dedup.call(name)) }
|
97
|
+
if raw = raw_emoji[:emoji]
|
98
|
+
append_unicode.call(emoji, raw)
|
99
|
+
start_pos = 0
|
100
|
+
while found_index = raw.index(VARIATION_SELECTOR_16, start_pos)
|
101
|
+
# register every variant where one VARIATION_SELECTOR_16 is removed
|
102
|
+
raw_alternate = raw.dup
|
103
|
+
raw_alternate[found_index] = ""
|
104
|
+
append_unicode.call(emoji, raw_alternate)
|
105
|
+
start_pos = found_index + 1
|
106
|
+
end
|
107
|
+
if start_pos > 0
|
108
|
+
# register a variant with all VARIATION_SELECTOR_16 removed
|
109
|
+
append_unicode.call(emoji, raw.gsub(VARIATION_SELECTOR_16, ""))
|
110
|
+
else
|
111
|
+
# register a variant where VARIATION_SELECTOR_16 is added
|
112
|
+
append_unicode.call(emoji, "#{raw}#{VARIATION_SELECTOR_16}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
raw_emoji.fetch(:tags).each { |tag| emoji.add_tag(dedup.call(tag)) }
|
116
|
+
|
117
|
+
emoji.category = dedup.call(raw_emoji[:category])
|
118
|
+
emoji.description = dedup.call(raw_emoji[:description])
|
119
|
+
emoji.unicode_version = dedup.call(raw_emoji[:unicode_version])
|
120
|
+
emoji.ios_version = dedup.call(raw_emoji[:ios_version])
|
115
121
|
end
|
116
122
|
end
|
117
123
|
end
|
data/lib/emoji/character.rb
CHANGED
data/lib/gemoji.rb
CHANGED
metadata
CHANGED
@@ -1,53 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gemoji
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0.rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Character information and metadata for
|
13
|
+
description: Character information and metadata for Unicode emoji.
|
14
14
|
email: support@github.com
|
15
|
-
executables:
|
16
|
-
- gemoji
|
15
|
+
executables: []
|
17
16
|
extensions: []
|
18
17
|
extra_rdoc_files: []
|
19
18
|
files:
|
19
|
+
- LICENSE
|
20
20
|
- README.md
|
21
|
-
- bin/gemoji
|
22
|
-
- db/Category-Emoji.json
|
23
21
|
- db/emoji.json
|
24
|
-
- images/basecamp.png
|
25
|
-
- images/basecampy.png
|
26
|
-
- images/bowtie.png
|
27
|
-
- images/feelsgood.png
|
28
|
-
- images/finnadie.png
|
29
|
-
- images/goberserk.png
|
30
|
-
- images/godmode.png
|
31
|
-
- images/hurtrealbad.png
|
32
|
-
- images/neckbeard.png
|
33
|
-
- images/octocat.png
|
34
|
-
- images/rage1.png
|
35
|
-
- images/rage2.png
|
36
|
-
- images/rage3.png
|
37
|
-
- images/rage4.png
|
38
|
-
- images/shipit.png
|
39
|
-
- images/suspect.png
|
40
|
-
- images/trollface.png
|
41
22
|
- lib/emoji.rb
|
42
23
|
- lib/emoji/character.rb
|
43
|
-
- lib/emoji/cli.rb
|
44
|
-
- lib/emoji/extractor.rb
|
45
24
|
- lib/gemoji.rb
|
46
25
|
homepage: https://github.com/github/gemoji
|
47
26
|
licenses:
|
48
27
|
- MIT
|
49
28
|
metadata: {}
|
50
|
-
post_install_message:
|
29
|
+
post_install_message:
|
51
30
|
rdoc_options: []
|
52
31
|
require_paths:
|
53
32
|
- lib
|
@@ -58,13 +37,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
58
37
|
version: '1.9'
|
59
38
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
39
|
requirements:
|
61
|
-
- - "
|
40
|
+
- - ">"
|
62
41
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
42
|
+
version: 1.3.1
|
64
43
|
requirements: []
|
65
|
-
|
66
|
-
|
67
|
-
signing_key:
|
44
|
+
rubygems_version: 3.0.3
|
45
|
+
signing_key:
|
68
46
|
specification_version: 4
|
69
|
-
summary:
|
47
|
+
summary: Unicode emoji library
|
70
48
|
test_files: []
|
data/bin/gemoji
DELETED
data/db/Category-Emoji.json
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"EmojiDataArray" : [
|
3
|
-
{
|
4
|
-
"CVDataTitle" : "EmojiCategory-People",
|
5
|
-
"CVCategoryImage" : "Emoji-HumanImage",
|
6
|
-
"CVCategoryData" : {
|
7
|
-
"CVSkipNullGlyphs" : false,
|
8
|
-
"Data" : "😀,😃,😄,😁,😆,😅,😂,🤣,☺️,😊,😇,🙂,🙃,😉,😌,😍,😘,😗,😙,😚,😋,😜,😝,😛,🤑,🤗,🤓,😎,🤡,🤠,😏,😒,😞,😔,😟,😕,🙁,☹️,😣,😖,😫,😩,😤,😠,😡,😶,😐,😑,😯,😦,😧,😮,😲,😵,😳,😱,😨,😰,😢,😥,🤤,😭,😓,😪,😴,🙄,🤔,🤥,😬,🤐,🤢,🤧,😷,🤒,🤕,😈,👿,👹,👺,💩,👻,💀,☠️,👽,👾,🤖,🎃,😺,😸,😹,😻,😼,😽,🙀,😿,😾,👐,🙌,👏,🙏,🤝,👍,👎,👊,✊,🤛,🤜,🤞,✌️,🤘,👌,👈,👉,👆,👇,☝️,✋,🤚,🖐,🖖,👋,🤙,💪,🖕,✍️,🤳,💅,💍,💄,💋,👄,👅,👂,👃,👣,👁,👀,🗣,👤,👥,👶,👦,👧,👨,👩,👱♀️,👱,👴,👵,👲,👳♀️,👳,👮♀️,👮,👷♀️,👷,💂♀️,💂,🕵️♀️,🕵️,👩⚕️,👨⚕️,👩🌾,👨🌾,👩🍳,👨🍳,👩🎓,👨🎓,👩🎤,👨🎤,👩🏫,👨🏫,👩🏭,👨🏭,👩💻,👨💻,👩💼,👨💼,👩🔧,👨🔧,👩🔬,👨🔬,👩🎨,👨🎨,👩🚒,👨🚒,👩✈️,👨✈️,👩🚀,👨🚀,👩⚖️,👨⚖️,🤶,🎅,👸,🤴,👰,🤵,👼,🤰,🙇♀️,🙇,💁,💁♂️,🙅,🙅♂️,🙆,🙆♂️,🙋,🙋♂️,🤦♀️,🤦♂️,🤷♀️,🤷♂️,🙎,🙎♂️,🙍,🙍♂️,💇,💇♂️,💆,💆♂️,🕴,💃,🕺,👯,👯♂️,🚶♀️,🚶,🏃♀️,🏃,👫,👭,👬,💑,👩❤️👩,👨❤️👨,💏,👩❤️💋👩,👨❤️💋👨,👪,👨👩👧,👨👩👧👦,👨👩👦👦,👨👩👧👧,👩👩👦,👩👩👧,👩👩👧👦,👩👩👦👦,👩👩👧👧,👨👨👦,👨👨👧,👨👨👧👦,👨👨👦👦,👨👨👧👧,👩👦,👩👧,👩👧👦,👩👦👦,👩👧👧,👨👦,👨👧,👨👧👦,👨👦👦,👨👧👧,👚,👕,👖,👔,👗,👙,👘,👠,👡,👢,👞,👟,👒,🎩,🎓,👑,⛑,🎒,👝,👛,👜,💼,👓,🕶,🌂,☂️"
|
9
|
-
}
|
10
|
-
},
|
11
|
-
{
|
12
|
-
"CVDataTitle" : "EmojiCategory-Nature",
|
13
|
-
"CVCategoryImage" : "Emoji-NatureImage",
|
14
|
-
"CVCategoryData" : {
|
15
|
-
"CVSkipNullGlyphs" : false,
|
16
|
-
"Data" : "🐶,🐱,🐭,🐹,🐰,🦊,🐻,🐼,🐨,🐯,🦁,🐮,🐷,🐽,🐸,🐵,🙈,🙉,🙊,🐒,🐔,🐧,🐦,🐤,🐣,🐥,🦆,🦅,🦉,🦇,🐺,🐗,🐴,🦄,🐝,🐛,🦋,🐌,🐚,🐞,🐜,🕷,🕸,🐢,🐍,🦎,🦂,🦀,🦑,🐙,🦐,🐠,🐟,🐡,🐬,🦈,🐳,🐋,🐊,🐆,🐅,🐃,🐂,🐄,🦌,🐪,🐫,🐘,🦏,🦍,🐎,🐖,🐐,🐏,🐑,🐕,🐩,🐈,🐓,🦃,🕊,🐇,🐁,🐀,🐿,🐾,🐉,🐲,🌵,🎄,🌲,🌳,🌴,🌱,🌿,☘️,🍀,🎍,🎋,🍃,🍂,🍁,🍄,🌾,💐,🌷,🌹,🥀,🌻,🌼,🌸,🌺,🌎,🌍,🌏,🌕,🌖,🌗,🌘,🌑,🌒,🌓,🌔,🌚,🌝,🌞,🌛,🌜,🌙,💫,⭐️,🌟,✨,⚡️,🔥,💥,☄️,☀️,🌤,⛅️,🌥,🌦,🌈,☁️,🌧,⛈,🌩,🌨,☃️,⛄️,❄️,🌬,💨,🌪,🌫,🌊,💧,💦,☔️"
|
17
|
-
}
|
18
|
-
},
|
19
|
-
{
|
20
|
-
"CVDataTitle" : "EmojiCategory-Foods",
|
21
|
-
"CVCategoryImage" : "Emoji-FoodsImage",
|
22
|
-
"CVCategoryData" : {
|
23
|
-
"CVSkipNullGlyphs" : false,
|
24
|
-
"Data" : "🍏,🍎,🍐,🍊,🍋,🍌,🍉,🍇,🍓,🍈,🍒,🍑,🍍,🥝,🥑,🍅,🍆,🥒,🥕,🌽,🌶,🥔,🍠,🌰,🥜,🍯,🥐,🍞,🥖,🧀,🥚,🍳,🥓,🥞,🍤,🍗,🍖,🍕,🌭,🍔,🍟,🥙,🌮,🌯,🥗,🥘,🍝,🍜,🍲,🍥,🍣,🍱,🍛,🍚,🍙,🍘,🍢,🍡,🍧,🍨,🍦,🍰,🎂,🍮,🍭,🍬,🍫,🍿,🍩,🍪,🥛,🍼,☕️,🍵,🍶,🍺,🍻,🥂,🍷,🥃,🍸,🍹,🍾,🥄,🍴,🍽"
|
25
|
-
}
|
26
|
-
},
|
27
|
-
{
|
28
|
-
"CVDataTitle" : "EmojiCategory-Activity",
|
29
|
-
"CVCategoryImage" : "Emoji-ActivityImage",
|
30
|
-
"CVCategoryData" : {
|
31
|
-
"CVSkipNullGlyphs" : false,
|
32
|
-
"Data" : "⚽️,🏀,🏈,⚾️,🎾,🏐,🏉,🎱,🏓,🏸,🥅,🏒,🏑,🏏,⛳️,🏹,🎣,🥊,🥋,⛸,🎿,⛷,🏂,🏋️♀️,🏋️,🤺,🤼♀️,🤼♂️,🤸♀️,🤸♂️,⛹️♀️,⛹️,🤾♀️,🤾♂️,🏌️♀️,🏌️,🏄♀️,🏄,🏊♀️,🏊,🤽♀️,🤽♂️,🚣♀️,🚣,🏇,🚴♀️,🚴,🚵♀️,🚵,🎽,🏅,🎖,🥇,🥈,🥉,🏆,🏵,🎗,🎫,🎟,🎪,🤹♀️,🤹♂️,🎭,🎨,🎬,🎤,🎧,🎼,🎹,🥁,🎷,🎺,🎸,🎻,🎲,🎯,🎳,🎮,🎰"
|
33
|
-
}
|
34
|
-
},
|
35
|
-
{
|
36
|
-
"CVDataTitle" : "EmojiCategory-Places",
|
37
|
-
"CVCategoryImage" : "Emoji-PlacesImage",
|
38
|
-
"CVCategoryData" : {
|
39
|
-
"CVSkipNullGlyphs" : false,
|
40
|
-
"Data" : "🚗,🚕,🚙,🚌,🚎,🏎,🚓,🚑,🚒,🚐,🚚,🚛,🚜,🛴,🚲,🛵,🏍,🚨,🚔,🚍,🚘,🚖,🚡,🚠,🚟,🚃,🚋,🚞,🚝,🚄,🚅,🚈,🚂,🚆,🚇,🚊,🚉,🚁,🛩,✈️,🛫,🛬,🚀,🛰,💺,🛶,⛵️,🛥,🚤,🛳,⛴,🚢,⚓️,🚧,⛽️,🚏,🚦,🚥,🗺,🗿,🗽,⛲️,🗼,🏰,🏯,🏟,🎡,🎢,🎠,⛱,🏖,🏝,⛰,🏔,🗻,🌋,🏜,🏕,⛺️,🛤,🛣,🏗,🏭,🏠,🏡,🏘,🏚,🏢,🏬,🏣,🏤,🏥,🏦,🏨,🏪,🏫,🏩,💒,🏛,⛪️,🕌,🕍,🕋,⛩,🗾,🎑,🏞,🌅,🌄,🌠,🎇,🎆,🌇,🌆,🏙,🌃,🌌,🌉,🌁"
|
41
|
-
}
|
42
|
-
},
|
43
|
-
{
|
44
|
-
"CVDataTitle" : "EmojiCategory-Objects",
|
45
|
-
"CVCategoryImage" : "Emoji-ObjectsImage",
|
46
|
-
"CVCategoryData" : {
|
47
|
-
"CVSkipNullGlyphs" : false,
|
48
|
-
"Data" : "⌚️,📱,📲,💻,⌨️,🖥,🖨,🖱,🖲,🕹,🗜,💽,💾,💿,📀,📼,📷,📸,📹,🎥,📽,🎞,📞,☎️,📟,📠,📺,📻,🎙,🎚,🎛,⏱,⏲,⏰,🕰,⌛️,⏳,📡,🔋,🔌,💡,🔦,🕯,🗑,🛢,💸,💵,💴,💶,💷,💰,💳,💎,⚖️,🔧,🔨,⚒,🛠,⛏,🔩,⚙️,⛓,🔫,💣,🔪,🗡,⚔️,🛡,🚬,⚰️,⚱️,🏺,🔮,📿,💈,⚗️,🔭,🔬,🕳,💊,💉,🌡,🚽,🚰,🚿,🛁,🛀,🛎,🔑,🗝,🚪,🛋,🛏,🛌,🖼,🛍,🛒,🎁,🎈,🎏,🎀,🎊,🎉,🎎,🏮,🎐,✉️,📩,📨,📧,💌,📥,📤,📦,🏷,📪,📫,📬,📭,📮,📯,📜,📃,📄,📑,📊,📈,📉,🗒,🗓,📆,📅,📇,🗃,🗳,🗄,📋,📁,📂,🗂,🗞,📰,📓,📔,📒,📕,📗,📘,📙,📚,📖,🔖,🔗,📎,🖇,📐,📏,📌,📍,✂️,🖊,🖋,✒️,🖌,🖍,📝,✏️,🔍,🔎,🔏,🔐,🔒,🔓"
|
49
|
-
}
|
50
|
-
},
|
51
|
-
{
|
52
|
-
"CVDataTitle" : "EmojiCategory-Symbols",
|
53
|
-
"CVCategoryImage" : "Emoji-SymbolImage",
|
54
|
-
"CVCategoryData" : {
|
55
|
-
"CVSkipNullGlyphs" : false,
|
56
|
-
"Data" : "❤️,💛,💚,💙,💜,🖤,💔,❣️,💕,💞,💓,💗,💖,💘,💝,💟,☮️,✝️,☪️,🕉,☸️,✡️,🔯,🕎,☯️,☦️,🛐,⛎,♈️,♉️,♊️,♋️,♌️,♍️,♎️,♏️,♐️,♑️,♒️,♓️,🆔,⚛️,🉑,☢️,☣️,📴,📳,🈶,🈚️,🈸,🈺,🈷️,✴️,🆚,💮,🉐,㊙️,㊗️,🈴,🈵,🈹,🈲,🅰️,🅱️,🆎,🆑,🅾️,🆘,❌,⭕️,🛑,⛔️,📛,🚫,💯,💢,♨️,🚷,🚯,🚳,🚱,🔞,📵,🚭,❗️,❕,❓,❔,‼️,⁉️,🔅,🔆,〽️,⚠️,🚸,🔱,⚜️,🔰,♻️,✅,🈯️,💹,❇️,✳️,❎,🌐,💠,Ⓜ️,🌀,💤,🏧,🚾,♿️,🅿️,🈳,🈂️,🛂,🛃,🛄,🛅,🚹,🚺,🚼,🚻,🚮,🎦,📶,🈁,🔣,ℹ️,🔤,🔡,🔠,🆖,🆗,🆙,🆒,🆕,🆓,0️⃣,1️⃣,2️⃣,3️⃣,4️⃣,5️⃣,6️⃣,7️⃣,8️⃣,9️⃣,🔟,🔢,#️⃣,*️⃣,▶️,⏸,⏯,⏹,⏺,⏭,⏮,⏩,⏪,⏫,⏬,◀️,🔼,🔽,➡️,⬅️,⬆️,⬇️,↗️,↘️,↙️,↖️,↕️,↔️,↪️,↩️,⤴️,⤵️,🔀,🔁,🔂,🔄,🔃,🎵,🎶,➕,➖,➗,✖️,💲,💱,™️,©️,®️,〰️,➰,➿,🔚,🔙,🔛,🔝,🔜,✔️,☑️,🔘,⚪️,⚫️,🔴,🔵,🔺,🔻,🔸,🔹,🔶,🔷,🔳,🔲,▪️,▫️,◾️,◽️,◼️,◻️,⬛️,⬜️,🔈,🔇,🔉,🔊,🔔,🔕,📣,📢,👁🗨,💬,💭,🗯,♠️,♣️,♥️,♦️,🃏,🎴,🀄️,🕐,🕑,🕒,🕓,🕔,🕕,🕖,🕗,🕘,🕙,🕚,🕛,🕜,🕝,🕞,🕟,🕠,🕡,🕢,🕣,🕤,🕥,🕦,🕧"
|
57
|
-
}
|
58
|
-
},
|
59
|
-
{
|
60
|
-
"CVDataTitle" : "EmojiCategory-Flags",
|
61
|
-
"CVCategoryImage" : "Emoji-FlagsImage",
|
62
|
-
"CVCategoryData" : {
|
63
|
-
"CVSkipNullGlyphs" : false,
|
64
|
-
"Data" : "🏳️,🏴,🏁,🚩,🏳️🌈,🇦🇫,🇦🇽,🇦🇱,🇩🇿,🇦🇸,🇦🇩,🇦🇴,🇦🇮,🇦🇶,🇦🇬,🇦🇷,🇦🇲,🇦🇼,🇦🇺,🇦🇹,🇦🇿,🇧🇸,🇧🇭,🇧🇩,🇧🇧,🇧🇾,🇧🇪,🇧🇿,🇧🇯,🇧🇲,🇧🇹,🇧🇴,🇧🇶,🇧🇦,🇧🇼,🇧🇷,🇮🇴,🇻🇬,🇧🇳,🇧🇬,🇧🇫,🇧🇮,🇨🇻,🇰🇭,🇨🇲,🇨🇦,🇮🇨,🇰🇾,🇨🇫,🇹🇩,🇨🇱,🇨🇳,🇨🇽,🇨🇨,🇨🇴,🇰🇲,🇨🇬,🇨🇩,🇨🇰,🇨🇷,🇨🇮,🇭🇷,🇨🇺,🇨🇼,🇨🇾,🇨🇿,🇩🇰,🇩🇯,🇩🇲,🇩🇴,🇪🇨,🇪🇬,🇸🇻,🇬🇶,🇪🇷,🇪🇪,🇪🇹,🇪🇺,🇫🇰,🇫🇴,🇫🇯,🇫🇮,🇫🇷,🇬🇫,🇵🇫,🇹🇫,🇬🇦,🇬🇲,🇬🇪,🇩🇪,🇬🇭,🇬🇮,🇬🇷,🇬🇱,🇬🇩,🇬🇵,🇬🇺,🇬🇹,🇬🇬,🇬🇳,🇬🇼,🇬🇾,🇭🇹,🇭🇳,🇭🇰,🇭🇺,🇮🇸,🇮🇳,🇮🇩,🇮🇷,🇮🇶,🇮🇪,🇮🇲,🇮🇱,🇮🇹,🇯🇲,🇯🇵,🎌,🇯🇪,🇯🇴,🇰🇿,🇰🇪,🇰🇮,🇽🇰,🇰🇼,🇰🇬,🇱🇦,🇱🇻,🇱🇧,🇱🇸,🇱🇷,🇱🇾,🇱🇮,🇱🇹,🇱🇺,🇲🇴,🇲🇰,🇲🇬,🇲🇼,🇲🇾,🇲🇻,🇲🇱,🇲🇹,🇲🇭,🇲🇶,🇲🇷,🇲🇺,🇾🇹,🇲🇽,🇫🇲,🇲🇩,🇲🇨,🇲🇳,🇲🇪,🇲🇸,🇲🇦,🇲🇿,🇲🇲,🇳🇦,🇳🇷,🇳🇵,🇳🇱,🇳🇨,🇳🇿,🇳🇮,🇳🇪,🇳🇬,🇳🇺,🇳🇫,🇲🇵,🇰🇵,🇳🇴,🇴🇲,🇵🇰,🇵🇼,🇵🇸,🇵🇦,🇵🇬,🇵🇾,🇵🇪,🇵🇭,🇵🇳,🇵🇱,🇵🇹,🇵🇷,🇶🇦,🇷🇪,🇷🇴,🇷🇺,🇷🇼,🇧🇱,🇸🇭,🇰🇳,🇱🇨,🇵🇲,🇻🇨,🇼🇸,🇸🇲,🇸🇹,🇸🇦,🇸🇳,🇷🇸,🇸🇨,🇸🇱,🇸🇬,🇸🇽,🇸🇰,🇸🇮,🇸🇧,🇸🇴,🇿🇦,🇬🇸,🇰🇷,🇸🇸,🇪🇸,🇱🇰,🇸🇩,🇸🇷,🇸🇿,🇸🇪,🇨🇭,🇸🇾,🇹🇼,🇹🇯,🇹🇿,🇹🇭,🇹🇱,🇹🇬,🇹🇰,🇹🇴,🇹🇹,🇹🇳,🇹🇷,🇹🇲,🇹🇨,🇹🇻,🇺🇬,🇺🇦,🇦🇪,🇬🇧,🇺🇸,🇻🇮,🇺🇾,🇺🇿,🇻🇺,🇻🇦,🇻🇪,🇻🇳,🇼🇫,🇪🇭,🇾🇪,🇿🇲,🇿🇼"
|
65
|
-
}
|
66
|
-
}
|
67
|
-
],
|
68
|
-
"CVViewFontList" : [
|
69
|
-
"AppleColorEmoji"
|
70
|
-
]
|
71
|
-
}
|
data/images/basecamp.png
DELETED
Binary file
|
data/images/basecampy.png
DELETED
Binary file
|
data/images/bowtie.png
DELETED
Binary file
|
data/images/feelsgood.png
DELETED
Binary file
|
data/images/finnadie.png
DELETED
Binary file
|
data/images/goberserk.png
DELETED
Binary file
|
data/images/godmode.png
DELETED
Binary file
|
data/images/hurtrealbad.png
DELETED
Binary file
|
data/images/neckbeard.png
DELETED
Binary file
|
data/images/octocat.png
DELETED
Binary file
|
data/images/rage1.png
DELETED
Binary file
|
data/images/rage2.png
DELETED
Binary file
|
data/images/rage3.png
DELETED
Binary file
|
data/images/rage4.png
DELETED
Binary file
|
data/images/shipit.png
DELETED
Binary file
|
data/images/suspect.png
DELETED
Binary file
|
data/images/trollface.png
DELETED
Binary file
|
data/lib/emoji/cli.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
require 'emoji/extractor'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'optparse'
|
4
|
-
|
5
|
-
module Emoji
|
6
|
-
module CLI
|
7
|
-
extend self
|
8
|
-
|
9
|
-
InvalidUsage = Class.new(RuntimeError)
|
10
|
-
|
11
|
-
def dispatch(argv)
|
12
|
-
cmd = argv[0]
|
13
|
-
argv = argv[1..-1]
|
14
|
-
|
15
|
-
case cmd
|
16
|
-
when "extract"
|
17
|
-
public_send(cmd, argv)
|
18
|
-
when "help", "--help", "-h"
|
19
|
-
help
|
20
|
-
else
|
21
|
-
raise InvalidUsage
|
22
|
-
end
|
23
|
-
|
24
|
-
return 0
|
25
|
-
rescue InvalidUsage, OptionParser::InvalidArgument, OptionParser::InvalidOption => err
|
26
|
-
unless err.message == err.class.to_s
|
27
|
-
$stderr.puts err.message
|
28
|
-
$stderr.puts
|
29
|
-
end
|
30
|
-
$stderr.puts usage_text
|
31
|
-
return 1
|
32
|
-
end
|
33
|
-
|
34
|
-
def help
|
35
|
-
puts usage_text
|
36
|
-
end
|
37
|
-
|
38
|
-
VALID_SIZES = [ 20, 32, 40, 48, 64, 96, 160 ]
|
39
|
-
|
40
|
-
def extract(argv)
|
41
|
-
size = 64
|
42
|
-
|
43
|
-
OptionParser.new do |opts|
|
44
|
-
opts.on("--size=#{size}", Integer) do |val|
|
45
|
-
if VALID_SIZES.include?(val)
|
46
|
-
size = val
|
47
|
-
else
|
48
|
-
raise InvalidUsage, "size should be one of: #{VALID_SIZES.join(', ')}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end.parse!(argv)
|
52
|
-
|
53
|
-
raise InvalidUsage unless argv.size == 1
|
54
|
-
path = argv[0]
|
55
|
-
|
56
|
-
Emoji::Extractor.new(size, path).extract!
|
57
|
-
Dir["#{Emoji.images_path}/*.png"].each do |png|
|
58
|
-
FileUtils.cp(png, File.join(path, File.basename(png)))
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def usage_text
|
63
|
-
<<EOF
|
64
|
-
Usage: gemoji extract <path> [--size=64]
|
65
|
-
EOF
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
data/lib/emoji/extractor.rb
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
require 'emoji'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module Emoji
|
5
|
-
class Extractor
|
6
|
-
EMOJI_TTF = "/System/Library/Fonts/Apple Color Emoji.ttc"
|
7
|
-
|
8
|
-
attr_reader :size, :images_path
|
9
|
-
|
10
|
-
def initialize(size, images_path)
|
11
|
-
@size = size
|
12
|
-
@images_path = images_path
|
13
|
-
end
|
14
|
-
|
15
|
-
def each(&block)
|
16
|
-
return to_enum(__method__) unless block_given?
|
17
|
-
|
18
|
-
File.open(EMOJI_TTF, 'rb') do |file|
|
19
|
-
font_offsets = parse_ttc(file)
|
20
|
-
file.pos = font_offsets[0]
|
21
|
-
|
22
|
-
tables = parse_tables(file)
|
23
|
-
glyph_index = extract_glyph_index(file, tables)
|
24
|
-
|
25
|
-
each_glyph_bitmap(file, tables, glyph_index, &block)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def extract!
|
30
|
-
each do |glyph_name, type, binread|
|
31
|
-
if emoji = glyph_name_to_emoji(glyph_name)
|
32
|
-
image_filename = "#{images_path}/#{emoji.image_filename}"
|
33
|
-
FileUtils.mkdir_p(File.dirname(image_filename))
|
34
|
-
File.open(image_filename, 'wb') { |f| f.write binread.call }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
GENDER_MAP = {
|
42
|
-
"M" => "\u{2642}",
|
43
|
-
"W" => "\u{2640}",
|
44
|
-
}
|
45
|
-
|
46
|
-
FAMILY_MAP = {
|
47
|
-
"B" => "\u{1f466}",
|
48
|
-
"G" => "\u{1f467}",
|
49
|
-
"M" => "\u{1f468}",
|
50
|
-
"W" => "\u{1f469}",
|
51
|
-
}.freeze
|
52
|
-
|
53
|
-
FAMILY = "1F46A"
|
54
|
-
COUPLE = "1F491"
|
55
|
-
KISS = "1F48F"
|
56
|
-
|
57
|
-
def glyph_name_to_emoji(glyph_name)
|
58
|
-
return if glyph_name =~ /\.[1-5]($|\.)/
|
59
|
-
zwj = Emoji::ZERO_WIDTH_JOINER
|
60
|
-
v16 = Emoji::VARIATION_SELECTOR_16
|
61
|
-
|
62
|
-
if glyph_name =~ /^u(#{FAMILY}|#{COUPLE}|#{KISS})\.([#{FAMILY_MAP.keys.join('')}]+)$/
|
63
|
-
if $1 == FAMILY ? $2 == "MWB" : $2 == "WM"
|
64
|
-
raw = [$1.hex].pack('U')
|
65
|
-
else
|
66
|
-
if $1 == COUPLE
|
67
|
-
middle = "#{zwj}\u{2764}#{v16}#{zwj}" # heavy black heart
|
68
|
-
elsif $1 == KISS
|
69
|
-
middle = "#{zwj}\u{2764}#{v16}#{zwj}\u{1F48B}#{zwj}" # heart + kiss mark
|
70
|
-
else
|
71
|
-
middle = zwj
|
72
|
-
end
|
73
|
-
raw = $2.split('').map { |c| FAMILY_MAP.fetch(c) }.join(middle)
|
74
|
-
end
|
75
|
-
candidates = [raw]
|
76
|
-
else
|
77
|
-
raw = glyph_name.gsub(/(^|_)u([0-9A-F]+)/) { ($1.empty?? $1 : zwj) + [$2.hex].pack('U') }
|
78
|
-
raw.sub!(/\.0\b/, '')
|
79
|
-
raw.sub!(/\.(#{GENDER_MAP.keys.join('|')})$/) { v16 + zwj + GENDER_MAP.fetch($1) }
|
80
|
-
candidates = [raw]
|
81
|
-
candidates << raw.sub(v16, '') if raw.include?(v16)
|
82
|
-
candidates << raw.gsub(zwj, '') if raw.include?(zwj)
|
83
|
-
candidates.dup.each { |c| candidates << (c + v16) }
|
84
|
-
end
|
85
|
-
|
86
|
-
candidates.map { |c| Emoji.find_by_unicode(c) }.compact.first
|
87
|
-
end
|
88
|
-
|
89
|
-
# https://www.microsoft.com/typography/otspec/otff.htm
|
90
|
-
def parse_ttc(io)
|
91
|
-
header_name = io.read(4).unpack('a*')[0]
|
92
|
-
raise unless "ttcf" == header_name
|
93
|
-
header_version, num_fonts = io.read(4*2).unpack('l>N')
|
94
|
-
# parse_version(header_version) #=> 2.0
|
95
|
-
io.read(4 * num_fonts).unpack('N*')
|
96
|
-
end
|
97
|
-
|
98
|
-
def parse_tables(io)
|
99
|
-
sfnt_version, num_tables = io.read(4 + 2*4).unpack('Nn')
|
100
|
-
# sfnt_version #=> 0x00010000
|
101
|
-
num_tables.times.each_with_object({}) do |_, tables|
|
102
|
-
tag, checksum, offset, length = io.read(4 + 4*3).unpack('a4N*')
|
103
|
-
tables[tag] = {
|
104
|
-
checksum: checksum,
|
105
|
-
offset: offset,
|
106
|
-
length: length,
|
107
|
-
}
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
GlyphIndex = Struct.new(:length, :name_index, :names) do
|
112
|
-
def name_for(glyph_id)
|
113
|
-
index = name_index[glyph_id]
|
114
|
-
names[index - 257]
|
115
|
-
end
|
116
|
-
|
117
|
-
def each(&block)
|
118
|
-
length.times(&block)
|
119
|
-
end
|
120
|
-
|
121
|
-
def each_with_name
|
122
|
-
each do |glyph_id|
|
123
|
-
yield glyph_id, name_for(glyph_id)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def extract_glyph_index(io, tables)
|
129
|
-
postscript_table = tables.fetch('post')
|
130
|
-
io.pos = postscript_table[:offset]
|
131
|
-
end_pos = io.pos + postscript_table[:length]
|
132
|
-
|
133
|
-
parse_version(io.read(32).unpack('l>')[0]) #=> 2.0
|
134
|
-
num_glyphs = io.read(2).unpack('n')[0]
|
135
|
-
glyph_name_index = io.read(2*num_glyphs).unpack('n*')
|
136
|
-
|
137
|
-
glyph_names = []
|
138
|
-
while io.pos < end_pos
|
139
|
-
length = io.read(1).unpack('C')[0]
|
140
|
-
glyph_names << io.read(length)
|
141
|
-
end
|
142
|
-
|
143
|
-
GlyphIndex.new(num_glyphs, glyph_name_index, glyph_names)
|
144
|
-
end
|
145
|
-
|
146
|
-
# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
|
147
|
-
def each_glyph_bitmap(io, tables, glyph_index)
|
148
|
-
io.pos = sbix_offset = tables.fetch('sbix')[:offset]
|
149
|
-
strike = extract_sbix_strike(io, glyph_index.length, size)
|
150
|
-
|
151
|
-
glyph_index.each_with_name do |glyph_id, glyph_name|
|
152
|
-
glyph_offset = strike[:glyph_data_offset][glyph_id]
|
153
|
-
next_glyph_offset = strike[:glyph_data_offset][glyph_id + 1]
|
154
|
-
|
155
|
-
if glyph_offset && next_glyph_offset && glyph_offset < next_glyph_offset
|
156
|
-
io.pos = sbix_offset + strike[:offset] + glyph_offset
|
157
|
-
x, y, type = io.read(2*2 + 4).unpack('s2A4')
|
158
|
-
yield glyph_name, type, -> { io.read(next_glyph_offset - glyph_offset - 8) }
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def extract_sbix_strike(io, num_glyphs, image_size)
|
164
|
-
sbix_offset = io.pos
|
165
|
-
version, flags, num_strikes = io.read(2*2 + 4).unpack('n2N')
|
166
|
-
strike_offsets = num_strikes.times.map { io.read(4).unpack('N')[0] }
|
167
|
-
|
168
|
-
strike_offsets.each do |strike_offset|
|
169
|
-
io.pos = sbix_offset + strike_offset
|
170
|
-
ppem, resolution = io.read(4*2).unpack('n2')
|
171
|
-
next unless ppem == size
|
172
|
-
|
173
|
-
data_offsets = io.read(4 * (num_glyphs+1)).unpack('N*')
|
174
|
-
return {
|
175
|
-
ppem: ppem,
|
176
|
-
resolution: resolution,
|
177
|
-
offset: strike_offset,
|
178
|
-
glyph_data_offset: data_offsets,
|
179
|
-
}
|
180
|
-
end
|
181
|
-
return nil
|
182
|
-
end
|
183
|
-
|
184
|
-
def parse_version(num)
|
185
|
-
major = num >> 16
|
186
|
-
minor = num & 0xFFFF
|
187
|
-
"#{major}.#{minor}"
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|