Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55bb37afa4 | ||
|
|
64cd0e9ccf | ||
|
|
0f2f9ce047 | ||
|
|
b1c7878afe | ||
|
|
ce6c4ab12a | ||
|
|
4c47a26900 | ||
|
|
2a97e7e98c | ||
|
|
f6fa963350 | ||
|
|
2eb30abcd1 | ||
|
|
59ef859169 | ||
|
|
be99618db3 | ||
|
|
3675a8781f | ||
|
|
7f6550fe73 | ||
|
|
5361b5639f | ||
|
|
955be747f2 | ||
|
|
d98617abf2 | ||
|
|
bf598c57fc | ||
|
|
d371b81198 | ||
|
|
cefc4b015e | ||
|
|
d1002aa48c | ||
|
|
3cde479627 | ||
|
|
cbf7fb30b9 | ||
|
|
59b3fde91e | ||
|
|
f9e41a8739 |
34
.github/workflows/test.yml
vendored
Normal file
34
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
ruby: ["2.3", "2.4", "2.5", "2.6", "2.7"]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: ${{matrix.ruby}}
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor/bundle
|
||||
key: bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('Gemfile') }}
|
||||
restore-keys: |
|
||||
bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: bundle install --path vendor/bundle --jobs 4
|
||||
|
||||
- name: Run tests
|
||||
run: bundle exec rake
|
||||
1
Gemfile
1
Gemfile
@@ -2,5 +2,6 @@ source "https://rubygems.org"
|
||||
|
||||
gem "rake", "~> 10.3.2"
|
||||
gem "minitest", "~> 5.3.5"
|
||||
gem "i18n", "~> 1.8.5"
|
||||
|
||||
gemspec
|
||||
|
||||
25
Gemfile.lock
Normal file
25
Gemfile.lock
Normal file
@@ -0,0 +1,25 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
gemoji (4.0.0.rc3)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
concurrent-ruby (1.1.7)
|
||||
i18n (1.8.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
minitest (5.3.5)
|
||||
rake (10.3.2)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
gemoji!
|
||||
i18n (~> 1.8.5)
|
||||
minitest (~> 5.3.5)
|
||||
rake (~> 10.3.2)
|
||||
|
||||
BUNDLED WITH
|
||||
2.0.2
|
||||
2
Rakefile
2
Rakefile
@@ -20,5 +20,5 @@ namespace :db do
|
||||
end
|
||||
|
||||
file 'vendor/unicode-emoji-test.txt' do |t|
|
||||
system 'curl', '-fsSL', 'http://unicode.org/Public/emoji/12.0/emoji-test.txt', '-o', t.name
|
||||
system 'curl', '-fsSL', 'http://unicode.org/Public/emoji/13.1/emoji-test.txt', '-o', t.name
|
||||
end
|
||||
|
||||
28
db/dump.rb
28
db/dump.rb
@@ -1,9 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "i18n"
|
||||
require 'emoji'
|
||||
require 'json'
|
||||
require_relative './emoji-test-parser'
|
||||
|
||||
I18n.config.available_locales = :en
|
||||
items = []
|
||||
|
||||
_, categories = EmojiTestParser.parse(File.expand_path("../../vendor/unicode-emoji-test.txt", __FILE__))
|
||||
@@ -12,34 +14,32 @@ seen_existing = {}
|
||||
for category in categories
|
||||
for sub_category in category[:emoji]
|
||||
for emoji_item in sub_category[:emoji]
|
||||
unicodes = emoji_item[:sequences].sort_by(&:bytesize)
|
||||
existing_emoji = nil
|
||||
unicodes.detect do |raw|
|
||||
existing_emoji = Emoji.find_by_unicode(raw)
|
||||
raw = emoji_item[:sequences][0]
|
||||
existing_emoji = Emoji.find_by_unicode(raw) || Emoji.find_by_unicode("#{raw}\u{fe0f}")
|
||||
if seen_existing.key?(existing_emoji)
|
||||
existing_emoji = nil
|
||||
else
|
||||
seen_existing[existing_emoji] = true
|
||||
end
|
||||
existing_emoji = nil if seen_existing.key?(existing_emoji)
|
||||
description = emoji_item[:description].sub(/^E\d+(\.\d+)? /, '')
|
||||
output_item = {
|
||||
emoji: unicodes[0],
|
||||
description: emoji_item[:description],
|
||||
emoji: raw,
|
||||
description: description,
|
||||
category: category[:name],
|
||||
}
|
||||
if existing_emoji
|
||||
eu = existing_emoji.unicode_aliases
|
||||
preferred_raw = eu.size == 2 && eu[0] == "#{eu[1]}\u{fe0f}" ? eu[1] : eu[0]
|
||||
output_item.update(
|
||||
emoji: preferred_raw,
|
||||
aliases: existing_emoji.aliases,
|
||||
tags: existing_emoji.tags,
|
||||
unicode_version: existing_emoji.unicode_version,
|
||||
ios_version: existing_emoji.ios_version,
|
||||
)
|
||||
seen_existing[existing_emoji] = true
|
||||
else
|
||||
output_item.update(
|
||||
aliases: [emoji_item[:description].gsub(/\W+/, '_').downcase],
|
||||
aliases: [I18n.transliterate(description).gsub(/\W+/, '_').downcase],
|
||||
tags: [],
|
||||
unicode_version: "12.0",
|
||||
ios_version: "13.0",
|
||||
unicode_version: "13.1",
|
||||
ios_version: "14.5",
|
||||
)
|
||||
end
|
||||
output_item[:skin_tones] = true if emoji_item[:skin_tones]
|
||||
|
||||
@@ -9,12 +9,8 @@ module EmojiTestParser
|
||||
"\u{1F3FE}", # medium-dark skin tone
|
||||
"\u{1F3FF}", # dark skin tone
|
||||
]
|
||||
HAIR_MODIFIERS = [
|
||||
"\u{1F9B0}", # red-haired
|
||||
"\u{1F9B1}", # curly-haired
|
||||
"\u{1F9B2}", # bald
|
||||
"\u{1F9B3}", # white-haired
|
||||
]
|
||||
SKIN_TONES_RE = /(#{SKIN_TONES.join("|")})/o
|
||||
SKIP_TYPES = ["unqualified", "component"]
|
||||
|
||||
module_function
|
||||
|
||||
@@ -52,12 +48,12 @@ module EmojiTestParser
|
||||
else
|
||||
row, desc = line.split("#", 2)
|
||||
desc = desc.strip.split(" ", 2)[1]
|
||||
codepoints, _ = row.split(";", 2)
|
||||
codepoints, qualification = row.split(";", 2)
|
||||
next if SKIP_TYPES.include?(qualification.strip)
|
||||
emoji_raw = codepoints.strip.split.map { |c| c.hex }.pack("U*")
|
||||
next if HAIR_MODIFIERS.include?(emoji_raw)
|
||||
emoji_normalized = emoji_raw
|
||||
.gsub(VARIATION_SELECTOR_16, "")
|
||||
.gsub(/(#{SKIN_TONES.join("|")})/o, "")
|
||||
.gsub(SKIN_TONES_RE, "")
|
||||
emoji_item = emoji_map[emoji_normalized]
|
||||
if SKIN_TONES.any? { |s| emoji_raw.include?(s) }
|
||||
emoji_item[:skin_tones] = true if emoji_item
|
||||
@@ -91,7 +87,7 @@ if $0 == __FILE__
|
||||
html_output = true
|
||||
end
|
||||
|
||||
_, categories = EmojiTestParser.parse
|
||||
_, categories = EmojiTestParser.parse(File.expand_path("../../vendor/unicode-emoji-test.txt", __FILE__))
|
||||
|
||||
trap(:PIPE) { abort }
|
||||
|
||||
|
||||
2069
db/emoji.json
2069
db/emoji.json
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "gemoji"
|
||||
s.version = "4.0.0.pre0"
|
||||
s.version = "4.0.0.rc3"
|
||||
s.summary = "Unicode emoji library"
|
||||
s.description = "Character information and metadata for Unicode emoji."
|
||||
|
||||
|
||||
76
lib/emoji.rb
76
lib/emoji.rb
@@ -68,82 +68,6 @@ module Emoji
|
||||
"\u{00ae}", # registered
|
||||
"\u{2122}", # trade mark
|
||||
"\u{3030}", # wavy dash
|
||||
"\u{263a}", # smiling face
|
||||
"\u{261D}", # index pointing up
|
||||
"\u{270C}", # victory hand
|
||||
"\u{270D}", # writing hand
|
||||
"\u{2764}", # red heart
|
||||
"\u{2763}", # heavy heart exclamation
|
||||
"\u{2668}", # hot springs
|
||||
"\u{2708}", # airplane
|
||||
"\u{2600}", # sun
|
||||
"\u{2601}", # cloud
|
||||
"\u{2602}", # umbrella
|
||||
"\u{2744}", # snowflake
|
||||
"\u{2603}", # snowman
|
||||
"\u{2660}", # spade suit
|
||||
"\u{2665}", # heart suit
|
||||
"\u{2666}", # diamond suit
|
||||
"\u{2663}", # club suit
|
||||
"\u{260e}", # telephone
|
||||
"\u{2709}", # envelope
|
||||
"\u{270F}", # pencil
|
||||
"\u{2712}", # black nib
|
||||
"\u{2702}", # scissors
|
||||
"\u{26a0}", # warning
|
||||
"\u{2B06}", # up arrow
|
||||
"\u{2197}", # up-right arrow
|
||||
"\u{27A1}", # right arrow
|
||||
"\u{2198}", # down-right arrow
|
||||
"\u{2B07}", # down arrow
|
||||
"\u{2199}", # down-left arrow
|
||||
"\u{2B05}", # left arrow
|
||||
"\u{2196}", # up-left arrow
|
||||
"\u{2195}", # up-down arrow
|
||||
"\u{2194}", # left-right arrow
|
||||
"\u{21A9}", # right arrow curving left
|
||||
"\u{21AA}", # left arrow curving right
|
||||
"\u{2934}", # right arrow curving up
|
||||
"\u{2935}", # right arrow curving down
|
||||
"\u{2721}", # star of David
|
||||
"\u{262F}", # yin yang
|
||||
"\u{271D}", # latin cross
|
||||
"\u{25B6}", # play button
|
||||
"\u{25C0}", # reverse button
|
||||
"\u{23CF}", # eject button
|
||||
"\u{2640}", # female sign
|
||||
"\u{2642}", # male sign
|
||||
"\u{267B}", # recycling symbol
|
||||
"\u{2611}", # ballot box with check
|
||||
"\u{2714}", # heavy check mark
|
||||
"\u{2716}", # heavy multiplication x
|
||||
"\u{303D}", # part alternation mark
|
||||
"\u{2733}", # eight-spoked asterisk
|
||||
"\u{2734}", # eight-pointed star
|
||||
"\u{2747}", # sparkle
|
||||
"\u{203C}", # double exclamation mark
|
||||
"\u{2049}", # exclamation question mark
|
||||
"\u{23}\u{20E3}", # keycap: #
|
||||
"\u{2A}\u{20E3}", # keycap: *
|
||||
"\u{30}\u{20E3}", # keycap: 0
|
||||
"\u{31}\u{20E3}", # keycap: 1
|
||||
"\u{32}\u{20E3}", # keycap: 2
|
||||
"\u{33}\u{20E3}", # keycap: 3
|
||||
"\u{34}\u{20E3}", # keycap: 4
|
||||
"\u{35}\u{20E3}", # keycap: 5
|
||||
"\u{36}\u{20E3}", # keycap: 6
|
||||
"\u{37}\u{20E3}", # keycap: 7
|
||||
"\u{38}\u{20E3}", # keycap: 8
|
||||
"\u{39}\u{20E3}", # keycap: 9
|
||||
"\u{2139}", # information
|
||||
"\u{24C2}", # circled M
|
||||
"\u{1F17F}", # P button
|
||||
"\u{3297}", # Japanese “congratulations” button
|
||||
"\u{3299}", # Japanese “secret” button
|
||||
"\u{25AA}", # black small square
|
||||
"\u{25AB}", # white small square
|
||||
"\u{25FB}", # white medium square
|
||||
"\u{25FC}", # black medium square
|
||||
].freeze
|
||||
|
||||
private_constant :VARIATION_SELECTOR_16, :TEXT_GLYPHS
|
||||
|
||||
@@ -50,7 +50,6 @@ class EmojiTest < TestCase
|
||||
GENDER_EXCEPTIONS = [
|
||||
"man_with_gua_pi_mao",
|
||||
"woman_with_headscarf",
|
||||
"man_in_tuxedo",
|
||||
"pregnant_woman",
|
||||
"isle_of_man",
|
||||
"blonde_woman",
|
||||
@@ -91,18 +90,14 @@ class EmojiTest < TestCase
|
||||
test "missing or incorrect unicodes" do
|
||||
emoji_map, _ = EmojiTestParser.parse(File.expand_path("../../vendor/unicode-emoji-test.txt", __FILE__))
|
||||
source_unicode_emoji = emoji_map.values
|
||||
supported_sequences = Emoji.all.flat_map(&:unicode_aliases)
|
||||
text_glyphs = Emoji.const_get(:TEXT_GLYPHS)
|
||||
|
||||
missing = 0
|
||||
message = "Missing or incorrect unicodes:\n"
|
||||
source_unicode_emoji.each do |emoji|
|
||||
emoji[:sequences].each do |raw|
|
||||
found = Emoji.find_by_unicode(raw)
|
||||
if text_glyphs.include?(raw)
|
||||
assert_nil found, Emoji::Character.hex_inspect(raw)
|
||||
next
|
||||
end
|
||||
next if found
|
||||
next if text_glyphs.include?(raw) || Emoji.find_by_unicode(raw)
|
||||
message << "%s (%s)" % [Emoji::Character.hex_inspect(raw), emoji[:description]]
|
||||
if found = Emoji.find_by_unicode(raw.gsub("\u{fe0f}", ""))
|
||||
message << " - could be %s (:%s:)" % [found.hex_inspect, found.name]
|
||||
@@ -115,13 +110,6 @@ class EmojiTest < TestCase
|
||||
assert_equal 0, missing, message
|
||||
end
|
||||
|
||||
test "raw representation does not include VARIATION SELECTOR 16 unless necessary" do
|
||||
emoji = Emoji.all.select do |emoji|
|
||||
!emoji.custom? && emoji.raw.end_with?("\u{fe0f}") && emoji.unicode_aliases.size == 2
|
||||
end
|
||||
assert_equal [], emoji
|
||||
end
|
||||
|
||||
test "emoji have category" do
|
||||
missing = Emoji.all.select { |e| e.category.to_s.empty? }
|
||||
assert_equal [], missing.map(&:name), "some emoji don't have a category"
|
||||
|
||||
8480
vendor/unicode-emoji-test.txt
vendored
8480
vendor/unicode-emoji-test.txt
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user