#!/usr/bin/env ruby gem_name, *gem_ver_reqs = 'gemoji', '~> 3.0.0' gdep = Gem::Dependency.new(gem_name, *gem_ver_reqs) found_gspec = gdep.matching_specs.max_by(&:version) if !found_gspec abort("ERROR: gemoji #{gdep.requirement} is required: `gem install gemoji -v '#{gdep.requirement}'`") end puts "using gemoji #{found_gspec.version}" gem 'gemoji', found_gspec.version require 'emoji' require 'fileutils' require 'json' emoji_path = File.join(File.dirname(__FILE__), 'images', 'emoji') if File.directory? emoji_path FileUtils.remove_dir emoji_path end Dir.mkdir emoji_path Emoji.create('mattermost') FileUtils.cp(File.join(File.dirname(__FILE__), 'images', 'icon64x64.png'), File.join(emoji_path, 'mattermost.png')) custom_aliases = { "ca" => "canada", "pk" => "pakistan", "za" => "south_africa" } custom_aliases.each do |custom, original| emoji = Emoji.find_by_alias original Emoji.edit_emoji(emoji) do |char| char.add_alias custom end end blacklist = ['basecamp', 'basecampy'] categories = [] File.open(File.join(File.dirname(__FILE__), 'utils', 'emoji.jsx'), 'w') do |f| emojis = [] emoji_indices_by_alias = [] emoji_indices_by_unicode = [] emoji_indices_by_category = [] Emoji.all.each do |emoji| if blacklist.include? emoji.name next end emoji.aliases.each do |emoji_alias| emoji_indices_by_alias << [emoji_alias, emojis.length] end emoji.unicode_aliases.each do |unicode_alias| emoji_indices_by_unicode << [emoji.class.hex_inspect(unicode_alias), emojis.length] end category = emoji.category ? emoji.category.downcase : 'custom' if !categories.include? category categories << category emoji_indices_by_category << [category, []] end emoji_indices_by_category[categories.index(category)][1] << emojis.length filename = emoji.custom? ? emoji.name : emoji.hex_inspect emojis << { 'aliases' => emoji.aliases, 'filename' => filename, 'category' => category, } emoji.image_filename = filename + '.png' end f.write("// This file is automatically generated via `make emojis`. Do not modify it manually.\n\n") f.write("/* eslint-disable */\n\n") f.write("export const Emojis = #{JSON.generate emojis};\n\n") f.write("export const EmojiIndicesByAlias = new Map(#{JSON.generate emoji_indices_by_alias});\n\n") f.write("export const EmojiIndicesByUnicode = new Map(#{JSON.generate emoji_indices_by_unicode});\n\n") f.write("export const CategoryNames = #{JSON.generate categories};\n\n") f.write("export const EmojiIndicesByCategory = new Map(#{JSON.generate emoji_indices_by_category});\n\n") f.write("/* eslint-enable */") puts "wrote #{emojis.length} emojis to utils/emoji.jsx" end require 'emoji/extractor' Emoji::Extractor.new(64, emoji_path).extract! Dir["#{Emoji.images_path}/*.png"].each do |png| if blacklist.include? File.basename(png, '.png') next end FileUtils.cp(png, File.join(emoji_path, File.basename(png))) end puts "images written to images/emoji" ### Spritesheet Generation ### ['sprite-factory', 'chunky_png'].each do |name| gdep = Gem::Dependency.new(name, '>1.0') found_gspec = gdep.matching_specs.max_by(&:version) if !found_gspec abort("ERROR: #{name} is required for spritesheet generation: `gem install #{name}'`") end end require 'sprite_factory' css_rules = [ '@charset "UTF-8";', '.emojisprite-preview {', ' @include transform(scale(.55));', ' background-repeat: no-repeat;', ' cursor: pointer;', ' height: 64px;', ' max-width: none;', ' transform-origin: 0 0;', ' width: 64px;', ' padding: 0 10px 0 0;', '}', '.emojisprite {', ' @include transform(scale(.35));', ' background-repeat: no-repeat;', ' border-radius: 18px;', ' cursor: pointer;', ' height: 64px;', ' max-width: none;', ' transform-origin: 0 0;', ' width: 64px;', '}', '.emojisprite-loading {', ' background-image: none !important;', ' @include transform(scale(.35));', ' background-repeat: no-repeat;', ' border-radius: 18px;', ' cursor: pointer;', ' height: 64px;', ' max-width: none;', ' transform-origin: 0 0;', ' width: 64px;', '}', ] spritesheet_path = File.join(File.dirname(__FILE__), 'images', 'emoji-sheets') if File.directory? spritesheet_path FileUtils.remove_dir spritesheet_path end Dir.mkdir spritesheet_path categories.each do |category| count = 0 tmp_directory = File.join(spritesheet_path, 'temp') Dir.mkdir tmp_directory Emoji.all.each do |emoji| if blacklist.include? emoji.name next end if category == (emoji.category ? emoji.category.downcase : 'custom') FileUtils.cp(File.join(emoji_path, emoji.image_filename), File.join(tmp_directory, emoji.image_filename)) count += 1 end end css_rules << ".emoji-category-#{category} { background-image: url('../images/emoji-sheets/#{category}.png'); }" SpriteFactory.run!( tmp_directory, :layout => :packed, :library => 'chunkypng', :output_image => File.join(spritesheet_path, category + '.png'), :nocomments => true, :nocss => true, ) do |images| images.each do |name, image| if image[:cssw] != 64 || image[:cssh] != 64 css_rules << ".emoji-#{name} { background-position: -#{image[:cssx]}px -#{image[:cssy]}px; width: #{image[:cssw]}px; height: #{image[:cssh]}px; }" else css_rules << ".emoji-#{name} { background-position: -#{image[:cssx]}px -#{image[:cssy]}px; }" end end end FileUtils.remove_dir tmp_directory puts "#{count} emojis written to images/emoji-sheets/#{category}.png" end File.write(File.join(File.dirname(__FILE__), 'sass', 'components', '_emojisprite.scss'), css_rules.join("\n")) puts "sprite stylesheet written to sass/components/_emojisprite.scss"