Skip to content

Instantly share code, notes, and snippets.

@madpilot madpilot/icons.rake
Created Apr 17, 2015

What would you like to do?
Rake task to generate font icons from a folder full of SVGs
require 'fileutils'
RANGE = (0xe000...0xf8ff);
def map_fonts(src, map_file)
map = {
'meta' => {
'author' => "Redbubble"
'font' => {
'version' => "1.0",
'fontname' => "rb-icons",
'fullname' => "rc-icons",
'familyname' => "rb-icons",
'weight' => 400,
'units-per-em' => 500,
'ascent' => 500,
'descent' => 0
'glyphs' => []
map = YAML.load_file(map_file) if File.exist?(map_file)
used = map['glyphs'].map{ |g| g['code'] }
Dir.glob("#{src}/*.svg").each do |path|
filename = path.split(File::SEPARATOR).last
name = filename.gsub(/\.svg$/, "")
unless map['glyphs'].map{ |g| g['css'] }.include?(name)
next_hex = (RANGE.to_a - used).first
puts "We've run out of private font addresses!" && exit unless next_hex
'css' => name,
'file' => filename,
'code' => next_hex
used << next_hex
File.write map_file, map.to_yaml
def convert_fonts(src, dest, map_file)
map_fonts(src, map_file) unless File.exist?(map_file)
pwd = Rails.root.join('script', 'svg2font', 'node_modules', '.bin').to_s
puts("Please 'run npm install' from #{pwd}") and exit unless Dir.exist?(pwd)
puts `cd #{pwd}/../../ && #{pwd}/svg-font-create --config="#{map_file}" --input_dir="#{src}" --output="#{dest}.svg"`
puts `#{pwd}/svg2ttf #{dest}.svg #{dest}.ttf`
puts `#{pwd}/ttf2woff #{dest}.ttf #{dest}.woff`
puts `#{pwd}/ttf2eot #{dest}.ttf #{dest}.eot`
def generate_scss(scss, map_file)
puts('Please generate a map file') and exit unless File.exist?(map_file)
map = YAML.load_file(map_file)
name = map['font']['fontname']
icons = map['glyphs'].map { |g| "#{g['css']}: '\\#{g['code'].to_s(16)}'" }
output = <<-EOF
// This file is automatically generated. Any changes will be overwritten
$icon-font-family: '#{name}';
@font-face {
font-family: '#{name}';
src: font-url('#{name}.eot');
src: font-url('#{name}.eot#iefix') format('embedded-opentype'),
font-url('#{name}.woff') format('woff'),
font-url('#{name}.ttf') format('truetype'),
font-url('#{name}.svg##{name}') format('svg');
font-weight: normal;
font-style: normal;
$icon-map: (
#{{ |g| " #{g}" }.join(",\n")}
File.write(scss, output)
namespace :icons do
desc "Convert a folder of SVGs into a set of icon font files. Also generates a .scss file with the correct mappings"
task :generate => :environment do
src = Rails.root.join('app', 'assets', 'svgs')
dest = Rails.root.join('app', 'assets', 'fonts', 'rb-icons')
scss = Rails.root.join('app', 'assets', 'stylesheets', 'new_layout', '_icon_map.scss')
map = Rails.root.join('config', 'icon_map.yml')
map_fonts(src, map)
convert_fonts(src, dest, map)
generate_scss(scss, map)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.