fontcustom 0.0.1

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.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec/fixtures/fontcustom/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fontcustom.gemspec
4
+ gemspec
@@ -0,0 +1,15 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'spork' do
5
+ watch('Gemfile.lock')
6
+ watch('spec/spec_helper.rb') { :rspec }
7
+ end
8
+
9
+ guard 'rspec', :cli => '--color --drb' do
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^lib/fontcustom/(.+)\.rb$}) { |m| "spec/fontcustom/#{m[1]}_spec.rb" }
12
+ watch('lib/fontcustom.rb') { 'spec/fontcustom/fontcustom_spec.rb' }
13
+ watch('lib/fontcustom/core.rb') { 'spec/fontcustom/fontcustom_spec.rb' }
14
+ watch('spec/spec_helper.rb') { 'spec' }
15
+ end
@@ -0,0 +1,66 @@
1
+ fontcustom
2
+
3
+ Copyright (c) 2012 Yifei Zhang, Joshua Gross
4
+
5
+ MIT License
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ "Software"), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+
27
+ ttf2eot
28
+
29
+ Author: taviso@sdf.lonestar.org 15-Mar-2009
30
+ License: Derived from WebKit, so BSD/LGPL 2/LGPL 2.1.
31
+
32
+
33
+ sfnt2woff
34
+
35
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
36
+
37
+ The contents of this file are subject to the Mozilla Public License Version
38
+ 1.1 (the "License"); you may not use this file except in compliance with
39
+ the License. You may obtain a copy of the License at
40
+ http://www.mozilla.org/MPL/
41
+
42
+ Software distributed under the License is distributed on an "AS IS" basis,
43
+ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
44
+ for the specific language governing rights and limitations under the
45
+ License.
46
+
47
+ The Original Code is WOFF font packaging code.
48
+
49
+ The Initial Developer of the Original Code is Mozilla Corporation.
50
+ Portions created by the Initial Developer are Copyright (C) 2009
51
+ the Initial Developer. All Rights Reserved.
52
+
53
+ Contributor(s):
54
+ Jonathan Kew <jfkthame@gmail.com>
55
+
56
+ Alternatively, the contents of this file may be used under the terms of
57
+ either the GNU General Public License Version 2 or later (the "GPL"), or
58
+ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
59
+ in which case the provisions of the GPL or the LGPL are applicable instead
60
+ of those above. If you wish to allow use of your version of this file only
61
+ under the terms of either the GPL or the LGPL, and not to allow others to
62
+ use your version of this file under the terms of the MPL, indicate your
63
+ decision by deleting the provisions above and replace them with the notice
64
+ and other provisions required by the GPL or the LGPL. If you do not delete
65
+ the provisions above, a recipient may use your version of this file under
66
+ the terms of any one of the MPL, the GPL or the LGPL.
@@ -0,0 +1,28 @@
1
+ FontCustom v0.0.1
2
+ ==========
3
+
4
+ **Generate custom icon webfonts from the comfort of the command line.**
5
+
6
+ [Full documentation](http://endtwist.github.com/fontcustom/)<br/>
7
+ [Feedback and issues](https://github.com/endtwist/fontcustom/issues)
8
+
9
+
10
+ Installation
11
+ ------------
12
+
13
+ ```sh
14
+ # Requires FontForge
15
+ brew install fontforge
16
+ gem install fontcustom
17
+ ```
18
+
19
+
20
+ Usage
21
+ -----
22
+
23
+ ```sh
24
+ fontcustom compile path/to/vectors # Compile icons and css to path/to/fontcustom/*
25
+ fontcustom watch path/to/vectors # Watch for changes
26
+ ```
27
+
28
+ Optional second parameter allows you to specify an output directory.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'lib/fontcustom'
6
+ t.test_files = FileList['test/lib/fontcustom/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fontcustom/cli'
4
+
5
+ Fontcustom::CLI.start
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fontcustom/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "fontcustom"
8
+ gem.version = Fontcustom::VERSION
9
+ gem.authors = ["Yifei Zhang", "Joshua Gross"]
10
+ gem.email = ["yz@yifei.co", "joshua@gross.is"]
11
+ gem.summary = %q{Generate custom icon webfonts from the comfort of the command line.}
12
+ gem.description = %q{Transforms EPS and SVG vectors into icon webfonts. Generates Bootstrap compatible CSS for easy inclusion in your projects.}
13
+ gem.homepage = "http://endtwist.github.com/fontcustom/"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'json'
21
+ gem.add_dependency 'thor'
22
+
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'bundler'
25
+ gem.add_development_dependency 'rspec'
26
+ gem.add_development_dependency 'fakefs'
27
+ gem.add_development_dependency 'spork'
28
+ gem.add_development_dependency 'guard-spork'
29
+ gem.add_development_dependency 'guard-rspec'
30
+ gem.add_development_dependency 'rb-fsevent', '~> 0.9.1'
31
+ end
@@ -0,0 +1,25 @@
1
+ require 'fontcustom/version'
2
+ require 'fontcustom/generator'
3
+ require 'fontcustom/watcher'
4
+
5
+ module Fontcustom
6
+ # Both .compile and .watch take the following arguments:
7
+ #
8
+ # @param [String] the input dir
9
+ # @param [String] the output dir (optional, defaults to fontcustom/ adjacent to the input dir)
10
+ # @param [Hash] options for Thor (not working)
11
+ def compile(*args)
12
+ config = args.last.is_a?(::Hash) ? args.pop : {}
13
+ Fontcustom::Generator.start(args, config)
14
+ end
15
+
16
+ def watch(*args)
17
+ Fontcustom::Watcher.watch(*args)
18
+ end
19
+
20
+ def stop
21
+ Fontcustom::Watcher.stop
22
+ end
23
+
24
+ module_function :compile, :watch, :stop
25
+ end
@@ -0,0 +1,16 @@
1
+ require 'thor'
2
+ require 'fontcustom'
3
+
4
+ module Fontcustom
5
+ class CLI < Thor
6
+ desc 'compile INPUT_DIR [OUTPUT_DIR]', 'Generates icon webfonts and a corresponding CSS file from a collection of vector images.'
7
+ def compile(input, output = nil)
8
+ Fontcustom.compile(input, output)
9
+ end
10
+
11
+ desc 'watch INPUT_DIR [OUTPUT_DIR]', 'Watches a directory of vector images for changes and regenerates icon webfonts and CSS when there are.'
12
+ def watch(input, output = nil)
13
+ Fontcustom.watch(input, output)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,55 @@
1
+ require 'json'
2
+ require 'thor/group'
3
+
4
+ module Fontcustom
5
+ class Generator < Thor::Group
6
+ include Thor::Actions
7
+
8
+ desc 'Generates webfonts from given directory of vectors.'
9
+
10
+ argument :input, :type => :string
11
+ argument :output, :type => :string, :optional => true
12
+
13
+ def self.source_root
14
+ File.dirname(__FILE__)
15
+ end
16
+
17
+ def verify_input_dir
18
+ if ! File.directory?(input)
19
+ raise Thor::Error, "#{input} doesn't exist or isn't a directory."
20
+ elsif Dir[File.join(input, '*.{svg,eps}')].empty?
21
+ raise Thor::Error, "#{input} doesn't contain any vectors (*.svg or *.eps files)."
22
+ end
23
+ end
24
+
25
+ def verify_or_create_output_dir
26
+ @output = output.nil? ? File.join(File.dirname(input), 'fontcustom') : output
27
+ empty_directory(@output) unless File.directory?(@output)
28
+ end
29
+
30
+ def cleanup_output_dir
31
+ originals = Dir[File.join(@output, 'fontcustom*.{css,woff,ttf,eot,svg}')]
32
+ originals.each do |file|
33
+ remove_file file
34
+ end
35
+ end
36
+
37
+ def generate
38
+ gem_file_path = File.expand_path(File.join(File.dirname(__FILE__)))
39
+ @font = %x| fontforge -script #{gem_file_path}/scripts/generate.py #{input} #{@output} 2>&1 /dev/null |
40
+ @font = JSON.parse(@font.split("\n").last)
41
+ end
42
+
43
+ def show_paths
44
+ path = @font['file']
45
+ ['woff','ttf','eot','svg'].each do |type|
46
+ say_status(:create, path + '.' + type)
47
+ end
48
+ end
49
+
50
+ def create_stylesheet
51
+ @font['file'] = File.basename(@font['file'])
52
+ template('templates/fontcustom.css', File.join(@output, 'fontcustom.css'))
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,63 @@
1
+ import fontforge
2
+ import os
3
+ import argparse
4
+ import md5
5
+ import json
6
+ from subprocess import call
7
+
8
+ parser = argparse.ArgumentParser(description='Convert a directory of svg and eps files into a unified font file.')
9
+ parser.add_argument('dir', metavar='directory', type=unicode, nargs='+', help='directory of vector files')
10
+ args = parser.parse_args()
11
+
12
+ f = fontforge.font()
13
+ f.encoding = 'UnicodeFull'
14
+
15
+ m = md5.new()
16
+ cp = 0xf000
17
+ files = []
18
+
19
+ KERNING = 15
20
+
21
+ for dirname, dirnames, filenames in os.walk(args.dir[0]):
22
+ for filename in filenames:
23
+ name, ext = os.path.splitext(filename)
24
+ filePath = os.path.join(dirname, filename)
25
+ size = os.path.getsize(filePath)
26
+
27
+ if ext in ['.svg', '.eps']:
28
+ m.update(filename + str(size) + ';')
29
+ glyph = f.createChar(cp)
30
+ glyph.importOutlines(filePath)
31
+
32
+ glyph.left_side_bearing = KERNING
33
+ glyph.right_side_bearing = KERNING
34
+
35
+ # possible optimization?
36
+ # glyph.simplify()
37
+ # glyph.round()
38
+
39
+ files.append(name)
40
+ cp += 1
41
+
42
+ hashStr = m.hexdigest()
43
+ fontfile = args.dir[1] + '/fontcustom-' + hashStr
44
+
45
+ f.fontname = 'fontcustom'
46
+ f.generate(fontfile + '.ttf')
47
+ f.generate(fontfile + '.svg')
48
+
49
+ # Fix SVG header for webkit (from: https://github.com/fontello/font-builder/blob/master/bin/fontconvert.py)
50
+ svgfile = open(fontfile + '.svg', 'r+')
51
+ svgtext = svgfile.read()
52
+ svgfile.seek(0)
53
+ svgfile.write(svgtext.replace('''<svg>''', '''<svg xmlns="http://www.w3.org/2000/svg">'''))
54
+ svgfile.close()
55
+
56
+ scriptPath = os.path.dirname(os.path.realpath(__file__))
57
+ call([scriptPath + '/sfnt2woff', fontfile + '.ttf'])
58
+ call(scriptPath + '/ttf2eot ' + fontfile + '.ttf > ' + fontfile + '.eot', shell=True)
59
+
60
+ # Hint the TTF file
61
+ call(scriptPath + '/ttfautohint -s -n ' + fontfile + '.ttf ' + fontfile + '-hinted.ttf && mv ' + fontfile + '-hinted.ttf ' + fontfile + '.ttf', shell=True)
62
+
63
+ print json.dumps({'file': fontfile, 'names': files})
@@ -0,0 +1,72 @@
1
+ /*
2
+ Font Custom - icon webfonts made simple
3
+ */
4
+
5
+ @font-face {
6
+ font-family: "fontcustom";
7
+ src: url("<%= @font['file'] %>.eot?#iefix") format("embedded-opentype"),
8
+ url("<%= @font['file'] %>.woff") format("woff"),
9
+ url("<%= @font['file'] %>.ttf") format("truetype"),
10
+ url("<%= @font['file'] %>.svg#fontcustom") format("svg");
11
+ font-weight: normal;
12
+ font-style: normal;
13
+ }
14
+
15
+ /*
16
+ Bootstrap Overrides
17
+ */
18
+
19
+ [class^="icon-"]:before, [class*=" icon-"]:before {
20
+ font-family: "fontcustom";
21
+ font-weight: normal;
22
+ font-style: normal;
23
+ display: inline-block;
24
+ text-decoration: inherit;
25
+ }
26
+
27
+ a [class^="icon-"], a [class*=" icon-"] {
28
+ display: inline-block;
29
+ text-decoration: inherit;
30
+ }
31
+
32
+ /* makes the font 33% larger relative to the icon container */
33
+ .icon-large:before {
34
+ vertical-align: top;
35
+ font-size: 1.333em;
36
+ }
37
+
38
+ /* keeps button heights with and without icons the same */
39
+ .btn [class^="icon-"], .btn [class*=" icon-"] {
40
+ line-height: 0.9em;
41
+ }
42
+
43
+ li [class^="icon-"], li [class*=" icon-"] {
44
+ display: inline-block;
45
+ width: 1.25em;
46
+ text-align: center;
47
+ }
48
+
49
+ /* 1.5 increased font size for icon-large * 1.25 width */
50
+ li .icon-large[class^="icon-"], li .icon-large[class*=" icon-"] {
51
+ width: 1.875em;
52
+ }
53
+
54
+ li[class^="icon-"], li[class*=" icon-"] {
55
+ margin-left: 0;
56
+ list-style-type: none;
57
+ }
58
+
59
+ li[class^="icon-"]:before, li[class*=" icon-"]:before {
60
+ text-indent: -2em;
61
+ text-align: center;
62
+ }
63
+
64
+ li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before {
65
+ text-indent: -1.333em;
66
+ }
67
+
68
+ /*
69
+ Icon Classes
70
+ */
71
+ <% @font['names'].each_with_index do |name, index| %>
72
+ .icon-<%= name.downcase %>:before { content: "\<%= (61440+index).to_s(16) %>"; }<% end %>
@@ -0,0 +1,3 @@
1
+ module Fontcustom
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,35 @@
1
+ require 'listen'
2
+
3
+ module Fontcustom
4
+ class Watcher
5
+ def self.watch(*args)
6
+ callback = Proc.new do |modified, added, removed|
7
+ puts ' >> Changed: ' + modified.join(' ') unless modified.empty?
8
+ puts ' >> Added: ' + added.join(' ') unless added.empty?
9
+ puts ' >> Removed: ' + removed.join(' ') unless removed.empty?
10
+
11
+ changed = modified + added + removed
12
+ Fontcustom.compile(*args) unless changed.empty?
13
+ end
14
+
15
+ dir = args.first
16
+ @listener = Listen.to(dir).filter(/\.(eps|svg)$/).change(&callback)
17
+
18
+ begin
19
+ puts "Fontcustom is watching your icons at " + dir
20
+ @listener.start()
21
+
22
+ # Catches Cmd/Ctrl + C
23
+ # Does listen gem have a better way of handling this?
24
+ rescue SignalException
25
+ stop
26
+ end
27
+ end
28
+
29
+ def self.stop
30
+ # Newline exists so message is not prepended with ^C on SIGTERM
31
+ puts "\nFontcustom is signing off. Goodnight and good luck."
32
+ @listener.stop
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.2" baseProfile="tiny" id="Layer_1" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" xml:space="preserve">
2
+ <path fill="#000000" d="M96.897,37.513c1.921,0,3.478-1.558,3.478-3.479c0-1.92-1.557-3.478-3.478-3.478s-3.478,1.558-3.478,3.478 c0,0.422,0.079,0.825,0.217,1.2l-10.153,8.649l-12.864-7.567c0.073-0.297,0.116-0.607,0.116-0.927c0-2.142-1.736-3.878-3.878-3.878 c-0.869,0-1.668,0.289-2.314,0.772L52.92,23.054c0.054-0.22,0.086-0.448,0.086-0.684c0-1.581-1.281-2.861-2.861-2.861 s-2.861,1.281-2.861,2.861c0,0.729,0.275,1.393,0.724,1.898l-5.835,12.488c-0.26-0.045-0.526-0.074-0.8-0.074 c-0.86,0-1.662,0.239-2.351,0.647l-15.438-6.915c0.036-0.225,0.06-0.454,0.06-0.689c0-2.38-1.929-4.309-4.309-4.309 c-2.379,0-4.309,1.929-4.309,4.309s1.929,4.309,4.309,4.309c1.352,0,2.556-0.623,3.346-1.596l14.682,6.576 c-0.384,0.674-0.607,1.452-0.607,2.284c0,0.852,0.293,1.605,0.694,2.29l-8.233,8.237c-1.136-0.811-2.506-1.294-4.003-1.294 c-2.642,0-4.915,1.501-6.082,3.684l-0.096-0.032c-0.001,0.012-0.004,0.023-0.005,0.035L7.553,49.002 c0.016-0.134,0.025-0.271,0.025-0.409c0-1.989-1.612-3.601-3.601-3.601s-3.601,1.612-3.601,3.601s1.612,3.601,3.601,3.601 c1.054,0,1.999-0.455,2.657-1.177l11.723,5.329c-0.005,0.013-0.009,0.025-0.015,0.037l0.056,0.019 c-0.054,0.348-0.108,0.694-0.108,1.055c0,1.954,0.813,3.716,2.115,4.975l-0.017,0.013c0.004,0.005,0.008,0.01,0.012,0.014 l-5.973,8.802c-0.155-0.027-0.314-0.044-0.478-0.044c-1.479,0-2.678,1.198-2.678,2.678c0,1.479,1.199,2.678,2.678,2.678 c1.479,0,2.678-1.199,2.678-2.678c0-0.501-0.14-0.969-0.38-1.37l5.364-7.904l0.71-0.877c0.881,0.407,1.859,0.641,2.894,0.641 c1.902,0,3.629-0.771,4.883-2.016l6.993,4.991c-0.199,0.514-0.334,1.06-0.334,1.641c0,2.548,2.065,4.617,4.617,4.617 c2.159,0,3.965-1.483,4.471-3.482l15.916-4.923c0.977,1.815,2.893,3.05,5.099,3.05c1.273,0,2.447-0.417,3.403-1.114l7.12,6.611 c-0.038,0.193-0.059,0.393-0.059,0.597c0,1.734,1.406,3.14,3.14,3.14s3.139-1.405,3.139-3.14c0-1.733-1.405-3.139-3.139-3.139 c-0.707,0-1.358,0.236-1.883,0.631l-6.811-6.323c0.552-0.887,0.893-1.93,0.893-3.05c0-2.815-1.661-5.16-4.661-5.677V39.104 c1-0.172,1.082-0.478,1.513-0.878l13.332,7.848l11.179,15.655c-0.092,0.23-0.146,0.481-0.146,0.745c0,1.125,0.91,2.037,2.035,2.037 s2.037-0.912,2.037-2.037s-0.913-2.037-2.038-2.037c-0.03,0-0.06,0.003-0.09,0.005L85.094,45.422l9.931-8.459 C95.565,37.31,96.207,37.513,96.897,37.513z M61.07,62.474c0,0.21,0.013,0.416,0.035,0.62l-15.275,4.724 c-0.522-1.975-2.316-3.435-4.458-3.435c-1.123,0-2.114,0.451-2.913,1.113l-7.038-5.022c0.447-0.92,0.717-1.93,0.717-3.017 c0-1.492-0.487-2.871-1.29-3.999l8.233-8.237c0.686,0.401,1.438,0.694,2.291,0.694c1.642,0,3.079-0.857,3.897-2.147l17.222,14.914 C61.609,59.699,61.07,61.022,61.07,62.474z M66,56.797c-1,0.1-1.135,0.273-1.596,0.502l-18.36-15.846 c0.002-0.052-0.023-0.102-0.023-0.154c0-1.485-0.718-2.802-1.806-3.646l5.799-12.428c0.046,0.002,0.088,0.007,0.134,0.007 c0.53,0,1.023-0.147,1.449-0.399l11.621,9.229c-0.151,0.415-0.113,0.861-0.113,1.328c0,1.757,0.895,3.238,2.895,3.715V56.797z"/>
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
2
+ <path d="M50,0C22.389,0,0,22.383,0,49.994V100h100V49.994C100,22.383,77.617,0,50,0z M96.667,96.667H3.333V49.994 c0-25.729,20.938-46.66,46.667-46.66c25.729,0,46.667,20.931,46.667,46.66V96.667z"/>
3
+ <path d="M50,10c-22.083,0-40,17.91-40,39.994V90l30-30V50c0-5.521,4.479-10,10-10c5.521,0,10,4.479,10,10v10l30,30V49.994 C90,27.91,72.09,10,50,10z"/>
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
2
+ <path style="fill:#010101;" d="M87.5,75c-3.039,0-5.725,1.221-7.886,3.016l-19.056-13.6c1.209-2.49,1.941-5.225,1.941-8.166 c0-4.041-1.318-7.775-3.491-10.828l22.29-22.302C83.154,24.207,85.193,25,87.5,25c6.909,0,12.5-5.591,12.5-12.5S94.409,0,87.5,0 S75,5.591,75,12.5c0,2.307,0.793,4.346,1.88,6.201L54.59,41.004c-3.076-2.197-6.787-3.504-10.84-3.504 c-7.153,0-13.306,4.064-16.467,9.973l-15.052-5.029C11.621,39.637,9.24,37.5,6.25,37.5C2.795,37.5,0,40.295,0,43.75 S2.795,50,6.25,50c1.574,0,2.979-0.635,4.077-1.6l14.966,4.993C25.146,54.334,25,55.273,25,56.25C25,66.602,33.398,75,43.75,75 c5.151,0,9.826-2.088,13.221-5.457l18.933,13.514C75.366,84.448,75,85.926,75,87.5c0,6.896,5.591,12.5,12.5,12.5 S100,94.396,100,87.5S94.409,75,87.5,75z"/>
3
+ </svg>
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fontcustom do
4
+ let(:input_dir) { 'spec/fixtures/vectors' }
5
+ let(:output_dir) { 'tmp' }
6
+ let(:fake_file) { output_dir + '/non-vector.txt' }
7
+
8
+ context 'when ouput_dir already contains files' do
9
+ # Compile, add non-fontcustom file, change input vectors, recompile
10
+ before(:all) do
11
+ Fontcustom.compile(input_dir, output_dir)
12
+ FileUtils.touch(fake_file, :verbose => true)
13
+ @original_fonts = Dir[output_dir + '/fontcustom-*.{woff,eot,ttf,svg}']
14
+ @original_css = File.read(output_dir + '/fontcustom.css')
15
+ FileUtils.mv(input_dir + '/B.svg', input_dir + '/E.svg', :verbose => true)
16
+ Fontcustom.compile(input_dir, output_dir)
17
+ end
18
+
19
+ after(:all) do
20
+ cleanup(output_dir)
21
+ FileUtils.mv(input_dir + '/E.svg', input_dir + '/B.svg', :verbose => true)
22
+ end
23
+
24
+ it 'should delete previous fontcustom generated files' do
25
+ new_files = Dir[output_dir + '/*']
26
+ @original_fonts.each do |original|
27
+ new_files.should_not include(original)
28
+ end
29
+ end
30
+
31
+ it 'should not delete non-fontcustom generated files' do
32
+ File.exists?(fake_file).should be_true
33
+ end
34
+
35
+ it 'should generate different css' do
36
+ new_css = File.read(output_dir + '/fontcustom.css')
37
+ new_css.should_not equal(@original_css)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fontcustom::Generator do
4
+ let(:input_dir) { 'spec/fixtures/vectors' }
5
+ let(:output_dir) { 'tmp' }
6
+
7
+ context 'normally' do
8
+ before(:all) { Fontcustom::Generator.start([input_dir, output_dir]) }
9
+ after(:all) { cleanup(output_dir) }
10
+
11
+ it 'should create webfonts' do
12
+ exts = %w( .woff .eot .ttf .svg )
13
+ files = Dir[output_dir + '/*']
14
+ files.map! { |file| File.extname(file) }
15
+
16
+ exts.each { |ext| files.should include(ext) }
17
+ end
18
+
19
+ it 'should print font-face declarations in fontcustom.css' do
20
+ stylesheet = File.read(output_dir + '/fontcustom.css')
21
+ files = Dir[output_dir + '/*.{woff,eot,ttf,svg}']
22
+
23
+ files.each do |file|
24
+ stylesheet.should include(File.basename(file))
25
+ end
26
+ end
27
+
28
+ it 'should print icon-* CSS classes in fontcustom.css' do
29
+ stylesheet = File.read(output_dir + '/fontcustom.css')
30
+ icon_names = Dir[input_dir + '/*'].map { |file| File.basename(file, '.svg').downcase }
31
+
32
+ icon_names.each do |name|
33
+ stylesheet.should include('.icon-' + name)
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'when input_dir does not exist' do
39
+ let(:fake_input_dir) { 'does/not/exist' }
40
+
41
+ it 'should raise an error' do
42
+ results = capture(:stderr) { Fontcustom::Generator.start([fake_input_dir, output_dir]) }
43
+ results.should =~ /doesn't exist or isn't a directory/
44
+ end
45
+ end
46
+
47
+ context 'when input_dir does not contain vectors' do
48
+ let(:empty_input_dir) { 'spec/fixtures/empty' }
49
+
50
+ it 'should raise an error' do
51
+ results = capture(:stderr) { Fontcustom::Generator.start([empty_input_dir, output_dir]) }
52
+ results.should =~ /doesn't contain any vectors/
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fontcustom do
4
+ let (:input_dir) { 'spec/fixtures/vectors' }
5
+ let (:output_dir) { 'tmp' }
6
+ let (:fontcustom) { Fontcustom }
7
+
8
+ before(:all) do
9
+ fontcustom.watch(input_dir, output_dir)
10
+ end
11
+
12
+ context '#watch' do
13
+ it 'should detect when a vector file changes' do
14
+ `mv spec/fixtures/vectors/B.svg spec/fixtures/vectors/E.svg`
15
+ sleep 1
16
+ fontcustom.should_receive(:compile).with(input_dir, output_dir)
17
+ end
18
+
19
+ it 'should detect when a vector file is added' do
20
+ end
21
+
22
+ it 'should detect when a vector file is removed' do
23
+ end
24
+
25
+ it 'should send complain if the dir has no vectors' do
26
+ end
27
+ end
28
+
29
+ after(:all) do
30
+ Fontcustom.stop
31
+ `mv spec/fixtures/vectors/E.svg spec/fixtures/vectors/B.svg`
32
+ cleanup(output_dir)
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ require 'spork'
2
+
3
+ Spork.prefork do
4
+ require 'rspec'
5
+ require 'fileutils'
6
+
7
+ RSpec.configure do |c|
8
+ def cleanup(dir)
9
+ FileUtils.rm_r(dir, :verbose => true) if File.exists?(dir)
10
+ end
11
+
12
+ def capture(stream)
13
+ begin
14
+ stream = stream.to_s
15
+ eval "$#{stream} = StringIO.new"
16
+ yield
17
+ result = eval("$#{stream}").string
18
+ ensure
19
+ eval("$#{stream} = #{stream.upcase}")
20
+ end
21
+
22
+ result
23
+ end
24
+ end
25
+ end
26
+
27
+ Spork.each_run do
28
+ require File.expand_path('../../lib/fontcustom.rb', __FILE__)
29
+ end
metadata ADDED
@@ -0,0 +1,249 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fontcustom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yifei Zhang
9
+ - Joshua Gross
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-11-12 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: thor
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rspec
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: fakefs
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: spork
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: guard-spork
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: guard-rspec
145
+ requirement: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: rb-fsevent
161
+ requirement: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ~>
165
+ - !ruby/object:Gem::Version
166
+ version: 0.9.1
167
+ type: :development
168
+ prerelease: false
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ~>
173
+ - !ruby/object:Gem::Version
174
+ version: 0.9.1
175
+ description: Transforms EPS and SVG vectors into icon webfonts. Generates Bootstrap
176
+ compatible CSS for easy inclusion in your projects.
177
+ email:
178
+ - yz@yifei.co
179
+ - joshua@gross.is
180
+ executables:
181
+ - fontcustom
182
+ extensions: []
183
+ extra_rdoc_files: []
184
+ files:
185
+ - .gitignore
186
+ - Gemfile
187
+ - Guardfile
188
+ - LICENSES.txt
189
+ - README.md
190
+ - Rakefile
191
+ - bin/fontcustom
192
+ - fontcustom.gemspec
193
+ - lib/fontcustom.rb
194
+ - lib/fontcustom/cli.rb
195
+ - lib/fontcustom/generator.rb
196
+ - lib/fontcustom/scripts/generate.py
197
+ - lib/fontcustom/scripts/sfnt2woff
198
+ - lib/fontcustom/scripts/ttf2eot
199
+ - lib/fontcustom/scripts/ttfautohint
200
+ - lib/fontcustom/templates/fontcustom.css
201
+ - lib/fontcustom/version.rb
202
+ - lib/fontcustom/watcher.rb
203
+ - spec/fixtures/empty/no_vectors_here.txt
204
+ - spec/fixtures/vectors/B.svg
205
+ - spec/fixtures/vectors/C.svg
206
+ - spec/fixtures/vectors/D.svg
207
+ - spec/fontcustom/fontcustom_spec.rb
208
+ - spec/fontcustom/generator_spec.rb
209
+ - spec/fontcustom/watcher_spec.rb.off
210
+ - spec/spec_helper.rb
211
+ homepage: http://endtwist.github.com/fontcustom/
212
+ licenses: []
213
+ post_install_message:
214
+ rdoc_options: []
215
+ require_paths:
216
+ - lib
217
+ required_ruby_version: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ segments:
224
+ - 0
225
+ hash: -3323250980931626345
226
+ required_rubygems_version: !ruby/object:Gem::Requirement
227
+ none: false
228
+ requirements:
229
+ - - ! '>='
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ segments:
233
+ - 0
234
+ hash: -3323250980931626345
235
+ requirements: []
236
+ rubyforge_project:
237
+ rubygems_version: 1.8.24
238
+ signing_key:
239
+ specification_version: 3
240
+ summary: Generate custom icon webfonts from the comfort of the command line.
241
+ test_files:
242
+ - spec/fixtures/empty/no_vectors_here.txt
243
+ - spec/fixtures/vectors/B.svg
244
+ - spec/fixtures/vectors/C.svg
245
+ - spec/fixtures/vectors/D.svg
246
+ - spec/fontcustom/fontcustom_spec.rb
247
+ - spec/fontcustom/generator_spec.rb
248
+ - spec/fontcustom/watcher_spec.rb.off
249
+ - spec/spec_helper.rb