fontcustomtoadstool 0.1.2

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/*
@@ -0,0 +1,12 @@
1
+ ## 0.1.0 (12/2/2012)
2
+
3
+ * Changed API to use Thor `class_option`s
4
+ * Added option to change the name of the font and generated files ([#6](https://github.com/endtwist/fontcustom/issues/6))
5
+ * Added option to disable the file name hash ([#13](https://github.com/endtwist/fontcustom/issues/13))
6
+ * `fontcustom watch` compiles automatically on the first run
7
+ * Better help messages
8
+
9
+ ## 0.0.2 (11/26/2012)
10
+
11
+ * Fixed gemspec dependency bug ([#2](https://github.com/endtwist/fontcustom/pull/2))
12
+ * Fixed Windows Chrome PUA bug ([#1](https://github.com/endtwist/fontcustom/issues/1))
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,60 @@
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
+ sfnt2woff
28
+
29
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
30
+
31
+ The contents of this file are subject to the Mozilla Public License Version
32
+ 1.1 (the "License"); you may not use this file except in compliance with
33
+ the License. You may obtain a copy of the License at
34
+ http://www.mozilla.org/MPL/
35
+
36
+ Software distributed under the License is distributed on an "AS IS" basis,
37
+ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
38
+ for the specific language governing rights and limitations under the
39
+ License.
40
+
41
+ The Original Code is WOFF font packaging code.
42
+
43
+ The Initial Developer of the Original Code is Mozilla Corporation.
44
+ Portions created by the Initial Developer are Copyright (C) 2009
45
+ the Initial Developer. All Rights Reserved.
46
+
47
+ Contributor(s):
48
+ Jonathan Kew <jfkthame@gmail.com>
49
+
50
+ Alternatively, the contents of this file may be used under the terms of
51
+ either the GNU General Public License Version 2 or later (the "GPL"), or
52
+ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
53
+ in which case the provisions of the GPL or the LGPL are applicable instead
54
+ of those above. If you wish to allow use of your version of this file only
55
+ under the terms of either the GPL or the LGPL, and not to allow others to
56
+ use your version of this file under the terms of the MPL, indicate your
57
+ decision by deleting the provisions above and replace them with the notice
58
+ and other provisions required by the GPL or the LGPL. If you do not delete
59
+ the provisions above, a recipient may use your version of this file under
60
+ the terms of any one of the MPL, the GPL or the LGPL.
@@ -0,0 +1,28 @@
1
+ #FontCustom v0.1.2
2
+
3
+ **Generate custom icon webfonts from the comfort of the command line.**
4
+
5
+ [Full documentation](http://endtwist.github.com/fontcustom/)<br/>
6
+ [Feedback and issues](https://github.com/endtwist/fontcustom/issues) to the core app.
7
+
8
+
9
+ ##What is FontCustom.sass?
10
+ There are two difference between FontCustom and FontCustom.sass. The main difference is that I converted the [template files](http://goo.gl/GZ53q) from old vanilla CSS to Sass. Nothing really magical there.
11
+
12
+ The next difference is that I beat up on the [generator.rb](http://goo.gl/IGZi0) file so that this better suits the Toadstool framework. Specific placement of the generated font files and a generated Sass partial as well.
13
+
14
+ ##Installation
15
+ ```sh
16
+ # Requires FontForge
17
+ brew install fontforge eot-utils ttfautohint
18
+ gem install fontcustom
19
+ ```
20
+
21
+ ##Usage
22
+ ```sh
23
+ fontcustom compile path/to/vectors # Compile icons and css to path/to/fontcustom/*
24
+ fontcustom watch path/to/vectors # Watch for changes
25
+ ```
26
+
27
+ ##To-do
28
+ See [project issues](http://goo.gl/RfCKl) for an updated list.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs = t.libs + ['lib/fontcustom', 'spec', 'spec/fixtures']
6
+ t.test_files = FileList['spec/fontcustom/*_spec.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,32 @@
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 = "fontcustomtoadstool"
8
+ gem.version = Fontcustomtoadstool::VERSION
9
+ gem.authors = ["Yifei Zhang", "Joshua Gross", "Dale Sande"]
10
+ gem.email = ["yz@yifei.co", "joshua@gross.is", "dale.sande@gmail.com"]
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 compatible CSS for Toadstool framework}
13
+ gem.homepage = "https://github.com/blackfalcon/fontcustom.sass"
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
+ gem.add_dependency 'listen'
23
+
24
+ gem.add_development_dependency 'rake'
25
+ gem.add_development_dependency 'bundler'
26
+ gem.add_development_dependency 'rspec'
27
+ gem.add_development_dependency 'fakefs'
28
+ gem.add_development_dependency 'spork'
29
+ gem.add_development_dependency 'guard-spork'
30
+ gem.add_development_dependency 'guard-rspec'
31
+ gem.add_development_dependency 'rb-fsevent', '~> 0.9.1'
32
+ end
@@ -0,0 +1,21 @@
1
+ require 'fontcustom/version'
2
+ require 'fontcustom/generator'
3
+ require 'fontcustom/watcher'
4
+
5
+ module Fontcustom
6
+ # Usage:
7
+ # Fontcustom.compile 'path/to/vectors', '-o', 'path/to/output'
8
+ def compile(*args)
9
+ Fontcustom::Generator.start(args) # as array
10
+ end
11
+
12
+ def watch(*args)
13
+ Fontcustom::Watcher.watch(*args)
14
+ end
15
+
16
+ def stop
17
+ Fontcustom::Watcher.stop
18
+ end
19
+
20
+ module_function :compile, :watch, :stop
21
+ end
@@ -0,0 +1,24 @@
1
+ require 'thor'
2
+ require 'fontcustom'
3
+
4
+ module Fontcustom
5
+ class CLI < Thor
6
+ # duplicated from Fontcustom::Generator so as to also appear under `fontcustom help` command
7
+ class_option :output, :aliases => '-o', :desc => 'Specify an output directory. Default: $DIR/fontcustom'
8
+ class_option :name, :aliases => '-n', :desc => 'Specify a font name. This will be used in the generated fonts and CSS. Default: fontcustom'
9
+ class_option :nohash, :type => :boolean, :default => false, :desc => 'Disable filename hashes. Default: false'
10
+
11
+ desc 'compile DIR [options]', 'Generates webfonts and CSS from *.svg and *.eps files in DIR.'
12
+ def compile(*args)
13
+ # workaround to pass arguments from one Thor class to another
14
+ ARGV.shift
15
+ Fontcustom.compile(*ARGV)
16
+ end
17
+
18
+ desc 'watch DIR [options]', 'Watches DIR for changes and regenerates webfonts and CSS automatically.'
19
+ def watch(*args)
20
+ ARGV.shift
21
+ Fontcustom.watch(*ARGV)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,87 @@
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
+ class_option :output, :aliases => '-o'
12
+ class_option :name, :aliases => '-n'
13
+ class_option :nohash, :type => :boolean, :default => false
14
+
15
+ def self.source_root
16
+ File.dirname(__FILE__)
17
+ end
18
+
19
+ def verify_fontforge
20
+ if `which fontforge` == ''
21
+ raise Thor::Error, 'Please install fontforge first.'
22
+ end
23
+ end
24
+
25
+ def verify_input_dir
26
+ if ! File.directory?(input)
27
+ raise Thor::Error, "#{input} doesn't exist or isn't a directory."
28
+ elsif Dir[File.join(input, '*.{svg,eps}')].empty?
29
+ raise Thor::Error, "#{input} doesn't contain any vectors (*.svg or *.eps files)."
30
+ end
31
+ end
32
+
33
+ def verify_or_create_output_dir
34
+ @output = options.output.nil? ? File.join(File.dirname(input), 'public/fonts/') : options.output
35
+ empty_directory(@output) unless File.directory?(@output)
36
+ end
37
+
38
+ def normalize_name
39
+ @name = if options.name
40
+ options.name.gsub(/\W/, '-').downcase
41
+ else
42
+ 'fontcustom'
43
+ end
44
+ end
45
+
46
+ def cleanup_output_dir
47
+ css = File.join(@output, 'fontcustom.scss')
48
+ old_name = if File.exists? css
49
+ line = IO.readlines(css)[5] # font-family: "Example Font";
50
+ line.scan(/".+"/)[0][1..-2].gsub(/\W/, '-').downcase # => 'example-font'
51
+ else
52
+ 'fontcustom'
53
+ end
54
+
55
+ old_files = Dir[File.join(@output, old_name + '-*.{woff,ttf,eot,svg}')]
56
+ old_files << css if File.exists?(css)
57
+ old_files.each {|file| remove_file file }
58
+ end
59
+
60
+ def generate
61
+ gem_file_path = File.expand_path(File.join(File.dirname(__FILE__)))
62
+ name = options.name ? ' --name ' + @name : ''
63
+ nohash = options.nohash ? ' --nohash' : ''
64
+
65
+ # suppress fontforge message
66
+ # TODO get font name and classes from script (without showing fontforge message)
67
+ `fontforge -script #{gem_file_path}/scripts/generate.py #{input} #{@output + name + nohash} > /dev/null 2>&1`
68
+ end
69
+
70
+ def show_paths
71
+ file = Dir[File.join(@output, @name + '*.ttf')].first
72
+ @path = file.chomp('.ttf')
73
+
74
+ ['woff','ttf','eot','svg'].each do |type|
75
+ say_status(:create, @path + '.' + type)
76
+ end
77
+ end
78
+
79
+ def create_stylesheet
80
+ files = Dir[File.join(input, '*.{svg,eps}')]
81
+ @classes = files.map {|file| File.basename(file)[0..-5].gsub(/\W/, '-').downcase }
82
+ @path = File.basename(@path)
83
+
84
+ template('templates/fontcustom.scss', File.join(@output, '../../sass/typography/_fontcustom.scss'))
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,78 @@
1
+ import fontforge
2
+ import os
3
+ import argparse
4
+ import md5
5
+ import json
6
+ import subprocess
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=2, help='directory of vector files')
10
+ parser.add_argument('--name', metavar='fontname', type=unicode, nargs='?', default='fontcustom', help='reference name of the font (no spaces)')
11
+ parser.add_argument('--nohash', '-n', action='store_true', help='disable hash fingerprinting of font files')
12
+ args = parser.parse_args()
13
+
14
+ f = fontforge.font()
15
+ f.encoding = 'UnicodeFull'
16
+
17
+ m = md5.new()
18
+ cp = 0xf100
19
+ files = []
20
+
21
+ KERNING = 15
22
+
23
+ for dirname, dirnames, filenames in os.walk(args.dir[0]):
24
+ for filename in filenames:
25
+ name, ext = os.path.splitext(filename)
26
+ filePath = os.path.join(dirname, filename)
27
+ size = os.path.getsize(filePath)
28
+
29
+ if ext in ['.svg', '.eps']:
30
+ m.update(filename + str(size) + ';')
31
+ glyph = f.createChar(cp)
32
+ glyph.importOutlines(filePath)
33
+
34
+ glyph.left_side_bearing = KERNING
35
+ glyph.right_side_bearing = KERNING
36
+
37
+ # possible optimization?
38
+ # glyph.simplify()
39
+ # glyph.round()
40
+
41
+ files.append(name)
42
+ cp += 1
43
+
44
+ if args.nohash:
45
+ fontfile = args.dir[1] + '/' + args.name
46
+ else:
47
+ hashStr = m.hexdigest()
48
+ fontfile = args.dir[1] + '/' + args.name + '-' + hashStr
49
+
50
+ f.fontname = args.name
51
+ f.familyname = args.name
52
+ f.fullname = args.name
53
+ f.generate(fontfile + '.ttf')
54
+ f.generate(fontfile + '.svg')
55
+
56
+ # Fix SVG header for webkit
57
+ # from: https://github.com/fontello/font-builder/blob/master/bin/fontconvert.py
58
+ svgfile = open(fontfile + '.svg', 'r+')
59
+ svgtext = svgfile.read()
60
+ svgfile.seek(0)
61
+ svgfile.write(svgtext.replace('''<svg>''', '''<svg xmlns="http://www.w3.org/2000/svg">'''))
62
+ svgfile.close()
63
+
64
+ scriptPath = os.path.dirname(os.path.realpath(__file__))
65
+ p = subprocess.Popen([scriptPath + '/sfnt2woff', fontfile + '.ttf'], stdout=subprocess.PIPE)
66
+ out, err = p.communicate()
67
+ if err is not None:
68
+ out += err
69
+ # If the local version of sfnt2woff fails (i.e., on Linux), try to use the
70
+ # global version. This allows us to avoid forcing OS X users to compile
71
+ # sfnt2woff from source, simplifying install.
72
+ if 'OSError' in out:
73
+ subprocess.call(['sfnt2woff', fontfile + '.ttf'])
74
+
75
+ subprocess.call('mkeot ' + fontfile + '.ttf > ' + fontfile + '.eot', shell=True)
76
+
77
+ # Hint the TTF file
78
+ subprocess.call('ttfautohint -s -n ' + fontfile + '.ttf ' + fontfile + '-hinted.ttf && mv ' + fontfile + '-hinted.ttf ' + fontfile + '.ttf', shell=True)
@@ -0,0 +1,72 @@
1
+ /*
2
+ Font Custom - icon webfonts made simple
3
+ */
4
+
5
+ @font-face {
6
+ font-family: "<%= @name %>";
7
+ src: url("<%= @path %>.eot?#iefix") format("embedded-opentype"),
8
+ url("<%= @path %>.woff") format("woff"),
9
+ url("<%= @path %>.ttf") format("truetype"),
10
+ url("<%= @path %>.svg#<%= @name %>") 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: "<%= @name %>";
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
+ <% @classes.each_with_index do |name, index| %>
72
+ .icon-<%= name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
@@ -0,0 +1,65 @@
1
+ // *Font Custom - icon webfonts made simple */
2
+
3
+ @font-face {
4
+ font-family: "<%= @name %>";
5
+ src: url("public/fonts/<%= @path %>.eot?#iefix") format("embedded-opentype"),
6
+ url("public/fonts/<%= @path %>.woff") format("woff"),
7
+ url("public/fonts/<%= @path %>.ttf") format("truetype"),
8
+ url("public/fonts/<%= @path %>.svg#<%= @name %>") format("svg");
9
+ font-weight: normal;
10
+ font-style: normal;
11
+ }
12
+
13
+
14
+ [class^="icon-"]:before, [class*=" icon-"]:before {
15
+ font-family: "<%= @name %>";
16
+ font-weight: normal;
17
+ font-style: normal;
18
+ display: inline-block;
19
+ text-decoration: inherit;
20
+ }
21
+
22
+ a [class^="icon-"], a [class*=" icon-"] {
23
+ display: inline-block;
24
+ text-decoration: inherit;
25
+ }
26
+
27
+ // * makes the font 33% larger relative to the icon container */
28
+ // .icon-large:before {
29
+ // vertical-align: top;
30
+ // font-size: 1.333em;
31
+ // }
32
+
33
+ // * keeps button heights with and without icons the same */
34
+ // .btn [class^="icon-"], .btn [class*=" icon-"] {
35
+ // line-height: 0.9em;
36
+ // }
37
+
38
+ // li [class^="icon-"], li [class*=" icon-"] {
39
+ // display: inline-block;
40
+ // width: 1.25em;
41
+ // text-align: center;
42
+ // }
43
+
44
+ // * 1.5 increased font size for icon-large * 1.25 width */
45
+ // li .icon-large[class^="icon-"], li .icon-large[class*=" icon-"] {
46
+ // width: 1.875em;
47
+ // }
48
+
49
+ // li[class^="icon-"], li[class*=" icon-"] {
50
+ // margin-left: 0;
51
+ // list-style-type: none;
52
+ // }
53
+
54
+ // li[class^="icon-"]:before, li[class*=" icon-"]:before {
55
+ // text-indent: -2em;
56
+ // text-align: center;
57
+ // }
58
+
59
+ // li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before {
60
+ // text-indent: -1.333em;
61
+ // }
62
+
63
+ // *Icon Classes */
64
+ <% @classes.each_with_index do |name, index| %>
65
+ %icon-<%= name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
@@ -0,0 +1,3 @@
1
+ module Fontcustomtoadstool
2
+ VERSION = "0.1.2"
3
+ end
@@ -0,0 +1,36 @@
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
+ Fontcustom.compile(*args)
21
+ @listener.start()
22
+
23
+ # Catches Cmd/Ctrl + C
24
+ # Does listen gem have a better way of handling this?
25
+ rescue SignalException
26
+ stop
27
+ end
28
+ end
29
+
30
+ def self.stop
31
+ # Newline exists so message is not prepended with ^C on SIGTERM
32
+ puts "\nFontcustom is signing off. Goodnight and good luck."
33
+ @listener.stop
34
+ end
35
+ end
36
+ end
@@ -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,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,42 @@
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
+ # originals
12
+ Fontcustom.compile(input_dir, '-o', output_dir, '-n', 'Original Font')
13
+ FileUtils.touch(fake_file, :verbose => true)
14
+ @original_fonts = Dir[output_dir + '/fontcustom-*.{woff,eot,ttf,svg}']
15
+ @original_css = File.read(output_dir + '/fontcustom.css')
16
+
17
+ FileUtils.mv(input_dir + '/C.svg', input_dir + '/E.svg', :verbose => true)
18
+ Fontcustom.compile(input_dir, '-o', output_dir)
19
+ end
20
+
21
+ after(:all) do
22
+ cleanup(output_dir)
23
+ FileUtils.mv(input_dir + '/E.svg', input_dir + '/C.svg', :verbose => true)
24
+ end
25
+
26
+ it 'should delete previous fontcustom generated files' do
27
+ new_files = Dir[output_dir + '/*']
28
+ @original_fonts.each do |original|
29
+ new_files.should_not include(original)
30
+ end
31
+ end
32
+
33
+ it 'should not delete non-fontcustom generated files' do
34
+ File.exists?(fake_file).should be_true
35
+ end
36
+
37
+ it 'should generate different css' do
38
+ new_css = File.read(output_dir + '/fontcustom.css')
39
+ new_css.should_not equal(@original_css)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,75 @@
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, '-o', 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)[0..-5].gsub(/\W/, '-').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, '-o', 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
+
56
+ context 'when flags are passed' do
57
+ it 'should save output files with a custom name' do
58
+ Fontcustom::Generator.start([input_dir, '-o', output_dir, '-n', 'customname'])
59
+
60
+ file = Dir[File.join(output_dir, 'customname-*.ttf')].first
61
+ File.exists?(file).should be_true
62
+
63
+ cleanup(output_dir)
64
+ end
65
+
66
+ it 'should exclude the filename hash' do
67
+ Fontcustom::Generator.start([input_dir, '-o', output_dir, '--nohash'])
68
+
69
+ file = File.join(output_dir, 'fontcustom.ttf')
70
+ File.exists?(file).should be_true
71
+
72
+ cleanup(output_dir)
73
+ end
74
+ end
75
+ 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,261 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fontcustomtoadstool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yifei Zhang
9
+ - Joshua Gross
10
+ - Dale Sande
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-12-05 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: json
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: thor
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: listen
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: rake
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: bundler
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rspec
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: fakefs
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ - !ruby/object:Gem::Dependency
129
+ name: spork
130
+ requirement: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ - !ruby/object:Gem::Dependency
145
+ name: guard-spork
146
+ requirement: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ - !ruby/object:Gem::Dependency
161
+ name: guard-rspec
162
+ requirement: !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ! '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ - !ruby/object:Gem::Dependency
177
+ name: rb-fsevent
178
+ requirement: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ~>
182
+ - !ruby/object:Gem::Version
183
+ version: 0.9.1
184
+ type: :development
185
+ prerelease: false
186
+ version_requirements: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ~>
190
+ - !ruby/object:Gem::Version
191
+ version: 0.9.1
192
+ description: Transforms EPS and SVG vectors into icon webfonts. Generates compatible
193
+ CSS for Toadstool framework
194
+ email:
195
+ - yz@yifei.co
196
+ - joshua@gross.is
197
+ - dale.sande@gmail.com
198
+ executables:
199
+ - fontcustom
200
+ extensions: []
201
+ extra_rdoc_files: []
202
+ files:
203
+ - .gitignore
204
+ - CHANGELOG.md
205
+ - Gemfile
206
+ - Guardfile
207
+ - LICENSES.txt
208
+ - README.md
209
+ - Rakefile
210
+ - bin/fontcustom
211
+ - fontcustomToadstool.gemspec
212
+ - lib/fontcustom.rb
213
+ - lib/fontcustom/cli.rb
214
+ - lib/fontcustom/generator.rb
215
+ - lib/fontcustom/scripts/generate.py
216
+ - lib/fontcustom/scripts/sfnt2woff
217
+ - lib/fontcustom/templates/fontcustom.css
218
+ - lib/fontcustom/templates/fontcustom.scss
219
+ - lib/fontcustom/version.rb
220
+ - lib/fontcustom/watcher.rb
221
+ - spec/fixtures/empty/no_vectors_here.txt
222
+ - spec/fixtures/vectors/C.svg
223
+ - spec/fixtures/vectors/D.svg
224
+ - spec/fixtures/vectors/a_R3ally-eXotic f1Le Name.svg
225
+ - spec/fontcustom/fontcustom_spec.rb
226
+ - spec/fontcustom/generator_spec.rb
227
+ - spec/fontcustom/watcher_spec.rb.off
228
+ - spec/spec_helper.rb
229
+ homepage: https://github.com/blackfalcon/fontcustom.sass
230
+ licenses: []
231
+ post_install_message:
232
+ rdoc_options: []
233
+ require_paths:
234
+ - lib
235
+ required_ruby_version: !ruby/object:Gem::Requirement
236
+ none: false
237
+ requirements:
238
+ - - ! '>='
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ required_rubygems_version: !ruby/object:Gem::Requirement
242
+ none: false
243
+ requirements:
244
+ - - ! '>='
245
+ - !ruby/object:Gem::Version
246
+ version: '0'
247
+ requirements: []
248
+ rubyforge_project:
249
+ rubygems_version: 1.8.24
250
+ signing_key:
251
+ specification_version: 3
252
+ summary: Generate custom icon webfonts from the comfort of the command line.
253
+ test_files:
254
+ - spec/fixtures/empty/no_vectors_here.txt
255
+ - spec/fixtures/vectors/C.svg
256
+ - spec/fixtures/vectors/D.svg
257
+ - spec/fixtures/vectors/a_R3ally-eXotic f1Le Name.svg
258
+ - spec/fontcustom/fontcustom_spec.rb
259
+ - spec/fontcustom/generator_spec.rb
260
+ - spec/fontcustom/watcher_spec.rb.off
261
+ - spec/spec_helper.rb