fontcustom 0.1.4 → 1.0.0.pre

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.
Files changed (42) hide show
  1. data/CHANGELOG.md +14 -0
  2. data/CONTRIBUTING.md +15 -8
  3. data/Rakefile +4 -6
  4. data/bin/fontcustom +1 -1
  5. data/fontcustom.gemspec +2 -7
  6. data/lib/fontcustom.rb +6 -21
  7. data/lib/fontcustom/cli.rb +46 -18
  8. data/lib/fontcustom/error.rb +4 -0
  9. data/lib/fontcustom/generator/font.rb +101 -0
  10. data/lib/fontcustom/generator/template.rb +80 -0
  11. data/lib/fontcustom/options.rb +20 -0
  12. data/lib/fontcustom/scripts/generate.py +22 -6
  13. data/lib/fontcustom/templates/_fontcustom.scss +72 -0
  14. data/lib/fontcustom/templates/fontcustom-ie7.css +10 -10
  15. data/lib/fontcustom/templates/fontcustom.css +19 -19
  16. data/lib/fontcustom/templates/fontcustom.html +119 -0
  17. data/lib/fontcustom/templates/fontcustom.yml +23 -0
  18. data/lib/fontcustom/util.rb +89 -0
  19. data/lib/fontcustom/version.rb +1 -1
  20. data/lib/fontcustom/watcher.rb +50 -25
  21. data/spec/fixtures/empty-data/.fontcustom-data +0 -0
  22. data/spec/fixtures/fontcustom.yml +1 -0
  23. data/spec/fixtures/mixed-output/.fontcustom-data +17 -0
  24. data/spec/fixtures/mixed-output/another-font.ttf +0 -0
  25. data/spec/fixtures/mixed-output/dont-delete-me.bro +0 -0
  26. data/spec/fixtures/mixed-output/fontcustom-cc5ce52f2ae4f9ce2e7ee8131bbfee1e.eot +0 -0
  27. data/spec/fixtures/mixed-output/fontcustom-cc5ce52f2ae4f9ce2e7ee8131bbfee1e.svg +102 -0
  28. data/spec/fixtures/mixed-output/fontcustom-cc5ce52f2ae4f9ce2e7ee8131bbfee1e.ttf +0 -0
  29. data/spec/fixtures/mixed-output/fontcustom-cc5ce52f2ae4f9ce2e7ee8131bbfee1e.woff +0 -0
  30. data/spec/fixtures/mixed-output/fontcustom.css +108 -0
  31. data/spec/fixtures/not-a-dir +0 -0
  32. data/spec/fontcustom/generator/font_spec.rb +183 -0
  33. data/spec/fontcustom/generator/template_spec.rb +106 -0
  34. data/spec/fontcustom/util_spec.rb +109 -0
  35. data/spec/fontcustom/watcher_spec.rb +68 -0
  36. data/spec/spec_helper.rb +32 -22
  37. metadata +47 -100
  38. data/lib/fontcustom/generator.rb +0 -105
  39. data/lib/fontcustom/templates/test.html +0 -100
  40. data/spec/fontcustom/fontcustom_spec.rb +0 -42
  41. data/spec/fontcustom/generator_spec.rb +0 -75
  42. data/spec/fontcustom/watcher_spec.rb.off +0 -34
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 1.0.0-RC1 (4/4/2013)
2
+
3
+ * Improved preview html to show glyphs at various sizes
4
+ * Added support for fontcustom.yml config file ([#49](https://github.com/FontCustom/fontcustom/issues/49))
5
+ * Added support for .fontcustom-data file ([#55](https://github.com/FontCustom/fontcustom/pull/55))
6
+ * Added support for custom templates ([#39](https://github.com/FontCustom/fontcustom/pull/39), [#48](https://github.com/FontCustom/fontcustom/issues/48))
7
+ * Added support for custom CSS selector namespaces ([#32](https://github.com/FontCustom/fontcustom/issues/32))
8
+ * Added support for --verbose=false ([#54](https://github.com/FontCustom/fontcustom/pull/54))
9
+ * Improved ascent/decent heights ([#33](https://github.com/FontCustom/fontcustom/issues/33))
10
+ * Fixed bug where watcher could fall into an infinite loop
11
+ * Added error messages for faulty input
12
+ * Refactored gem internals to reflect saner usage of Thor
13
+ * Refactored tests
14
+
1
15
  ## 0.1.4 (2/19/2013)
2
16
 
3
17
  * Instructions for stopping watcher ([#46](https://github.com/FontCustom/fontcustom/issues/46))
data/CONTRIBUTING.md CHANGED
@@ -1,11 +1,18 @@
1
- # FontCustom Contributing Checklist
1
+ # FontCustom Contributing Guidelines
2
2
 
3
- First, thanks for your interest in making FontCustom better! This project was born out of an over-heard conversation between two devs in a coffee shop — it's come a long ways thanks to the support of kind folks like you.
3
+ Thanks for helping make FontCustom better! This project was born out of an over-heard conversation between two devs in a coffee shop — it's come a long ways thanks to the support of folks like you.
4
4
 
5
- ## A short list to help you get started:
5
+ ## Conventions
6
6
 
7
- * Check out [issues]() for ideas. Is someone else working on something similar?
8
- * Fork the repo and work out of a named topic branch, a la `git checkout -b my_sweet_contribution`. Please don't work directly off `master`.
9
- * Run tests with `guard`.
10
- * Add/improve tests for your contributions.
11
- * Submit a pull request!
7
+ We try to follow the [Github ruby styleguide](https://github.com/styleguide/ruby) as much as possible.
8
+
9
+ If you catch a typo or a particularly unsightly piece of code — please _do_ let us know. No such thing as too small of an improvement.
10
+
11
+ ## Process
12
+
13
+ * Visit [issues](https://github.com/FontCustom/fontcustom/issues) for ideas.
14
+ * Fork the repo if you haven't done so already.
15
+ * Create a topic branch. `git checkout -b my_sweet_feature`
16
+ * Add tests. Run tests with `rake`.
17
+ * Develop your feature.
18
+ * Once all tests are passing, submit a pull request!
data/Rakefile CHANGED
@@ -1,10 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
- require 'rake/testtask'
2
+ require 'rspec/core/rake_task'
3
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
4
+ RSpec::Core::RakeTask.new 'spec' do |s|
5
+ s.rspec_opts = '--color --format documentation'
8
6
  end
9
7
 
10
- task :default => :test
8
+ task :default => :spec
data/bin/fontcustom CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'fontcustom/cli'
4
4
 
5
- Fontcustom::CLI.start
5
+ Fontcustom::CLI.start(ARGV)
data/fontcustom.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |gem|
9
9
  gem.authors = ["Yifei Zhang", "Joshua Gross"]
10
10
  gem.email = ["yz@yifei.co", "joshua@gross.is"]
11
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/"
12
+ gem.description = %q{Transforms EPS and SVG vectors into icon webfonts. Generates CSS (or your preferred alternative) for easy inclusion in your projects.}
13
+ gem.homepage = "http://fontcustom.com"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -24,9 +24,4 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency 'rake'
25
25
  gem.add_development_dependency 'bundler'
26
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
27
  end
data/lib/fontcustom.rb CHANGED
@@ -1,21 +1,6 @@
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
1
+ require "fontcustom/version"
2
+ require "fontcustom/options"
3
+ require "fontcustom/error"
4
+ require "fontcustom/util"
5
+ require "fontcustom/generator/font"
6
+ require "fontcustom/generator/template"
@@ -1,27 +1,55 @@
1
- require 'thor'
2
- require 'fontcustom'
1
+ require "thor"
2
+ require "thor/actions"
3
+ require "fontcustom"
4
+ require "fontcustom/watcher"
3
5
 
4
6
  module Fontcustom
5
7
  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 :font_path, :aliases => '-f', :desc => 'Specify a path for fonts in css @font-face declaration. Default: none'
10
- class_option :nohash, :type => :boolean, :default => false, :desc => 'Disable filename hashes. Default: false'
11
- class_option :debug, :type => :boolean, :default => false, :desc => 'Display debug messages. Default: false'
12
- class_option :html, :type => :boolean, :default => false, :desc => 'Generate html page with icons'
8
+ include Thor::Actions
13
9
 
14
- desc 'compile DIR [options]', 'Generates webfonts and CSS from *.svg and *.eps files in DIR.'
15
- def compile(*args)
16
- # workaround to pass arguments from one Thor class to another
17
- ARGV.shift
18
- Fontcustom.compile(*ARGV)
10
+ # Actual defaults are stored in Fontcustom::DEFAULT_OPTIONS instead of Thor
11
+ class_option :output, :aliases => "-o", :desc => "The output directory (will be created if it doesn't exist). Default: INPUT/fontcustom/"
12
+ class_option :config, :aliases => "-c", :desc => "Path to or containing directory of the config file. Default: INPUT/fontcustom.yml"
13
+ class_option :templates, :aliases => "-t", :type => :array, :desc => "List of templates to compile alongside fonts. Accepts 'css', 'css-ie7', 'scss', 'preview' or arbitrary paths (relative to INPUT or PWD). Default: 'css preview'"
14
+ class_option :font_name, :aliases => "-n", :desc => "The font name used in your templates (automatically normalized to lowercase spinal case). Default: 'fontcustom'"
15
+ class_option :file_hash, :aliases => "-h", :type => :boolean, :desc => "Generate font files with asset-busting hashes. Default: true"
16
+ class_option :css_prefix, :aliases => "-p", :desc => "The prefix for each glyph's CSS class. Default: 'icon-'"
17
+ class_option :debug, :aliases => "-d", :type => :boolean, :desc => "Display debug messages from fontforge. Default: false"
18
+ class_option :verbose, :aliases => "-v", :type => :boolean, :desc => "Display output messages. Default: true"
19
+
20
+ # Required for Thor::Actions#template
21
+ def self.source_root
22
+ File.join Fontcustom::Util.gem_lib_path, "templates"
23
+ end
24
+
25
+ desc "compile [INPUT]", "Generates webfonts and CSS from *.svg and *.eps files in INPUT."
26
+ def compile(input)
27
+ opts = options.merge :input => input
28
+ opts = Fontcustom::Util.collect_options opts
29
+ Fontcustom::Generator::Font.start [opts]
30
+ Fontcustom::Generator::Template.start [opts]
31
+ rescue Fontcustom::Error => e
32
+ puts "ERROR: #{e.message}"
33
+ end
34
+
35
+ desc "watch [INPUT]", "Watches INPUT for changes and regenerates webfonts and CSS automatically. Ctrl + C to stop."
36
+ method_option :skip_first, :aliases => "-s", :type => :boolean, :desc => "Compile immediately upon watching. Default: false"
37
+ def watch(input)
38
+ opts = options.merge :input => input, :skip_first => !! options[:skip_first]
39
+ opts = Fontcustom::Util.collect_options opts
40
+ Fontcustom::Watcher.new(opts).watch
41
+ rescue Fontcustom::Error => e
42
+ puts "ERROR: #{e.message}"
43
+ end
44
+
45
+ desc "config [INPUT]", "Adds an annotated fontcustom.yml to INPUT (created if it doesn't exists)."
46
+ def config(input)
47
+ template "fontcustom.yml", File.join(input, "fontcustom.yml")
19
48
  end
20
49
 
21
- desc 'watch DIR [options]', 'Watches DIR for changes and regenerates webfonts and CSS automatically. Ctrl + C to stop.'
22
- def watch(*args)
23
- ARGV.shift
24
- Fontcustom.watch(*ARGV)
50
+ desc "version", "Shows the version information."
51
+ def version
52
+ puts "fontcustom-#{Fontcustom::VERSION}"
25
53
  end
26
54
  end
27
55
  end
@@ -0,0 +1,4 @@
1
+ module Fontcustom
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,101 @@
1
+ require "json"
2
+ require "thor"
3
+ require "thor/group"
4
+ require "thor/actions"
5
+
6
+ module Fontcustom
7
+ module Generator
8
+ class Font < Thor::Group
9
+ include Thor::Actions
10
+
11
+ # Instead of passing each option individually we're passing the entire options hash as an argument.
12
+ # This is DRYier, easier to maintain.
13
+ argument :opts
14
+
15
+ def check_input
16
+ if ! File.directory? opts[:input]
17
+ raise Fontcustom::Error, "#{opts[:input]} doesn't exist or isn't a directory."
18
+ elsif Dir[File.join(opts[:input], "*.{svg,eps}")].empty?
19
+ raise Fontcustom::Error, "#{opts[:input]} doesn't contain any vectors (*.svg or *.eps files)."
20
+ end
21
+ end
22
+
23
+ def check_output
24
+ if File.exists? File.join(opts[:output], ".fontcustom-data")
25
+ # Skip ahead, everything is in order
26
+ elsif File.exists?(opts[:output]) && ! File.directory?(opts[:output])
27
+ raise Fontcustom::Error, "#{opts[:output]} already exists but isn't a directory."
28
+ else
29
+ # creates opts[:output] as well
30
+ add_file File.join(opts[:output], ".fontcustom-data"), :verbose => opts[:verbose]
31
+ end
32
+ end
33
+
34
+ def get_data
35
+ # file has already been verified/created
36
+ data = File.read File.join(opts[:output], ".fontcustom-data")
37
+ data = JSON.parse(data, :symbolize_names => true) unless data.empty?
38
+ @data = data.is_a?(Hash) ? data : Fontcustom::DATA_MODEL.dup
39
+ rescue JSON::ParserError
40
+ raise Fontcustom::Error, "The .fontcustom-data file in #{opts[:output]} is corrupted. Fix the JSON or delete the file to start from scratch."
41
+ end
42
+
43
+ def reset_output
44
+ return if @data[:fonts].empty?
45
+ begin
46
+ deleted = []
47
+ @data[:fonts].each do |file|
48
+ remove_file File.join(opts[:output], file), :verbose => opts[:verbose]
49
+ deleted << file
50
+ end
51
+ ensure
52
+ @data[:fonts] = @data[:fonts] - deleted
53
+ json = JSON.pretty_generate @data
54
+ file = File.join(opts[:output], ".fontcustom-data")
55
+ Fontcustom::Util.clear_file(file)
56
+ append_to_file file, json, :verbose => false # clear data file silently
57
+ end
58
+ end
59
+
60
+ def generate
61
+ # TODO align option naming conventions with python script
62
+ # TODO remove name arg if default is already set in python (or rm from python)
63
+ name = opts[:font_name] ? " --name " + opts[:font_name] : ""
64
+ hash = opts[:file_hash] ? "" : " --nohash"
65
+ cmd = "fontforge -script #{Fontcustom::Util.gem_lib_path}/scripts/generate.py #{opts[:input]} #{opts[:output] + name + hash} 2>&1"
66
+
67
+ output = `#{cmd}`.split("\n")
68
+ @json = output[3] # JSON
69
+ output = output[4..-1] # Strip fontforge message
70
+
71
+ if opts[:debug]
72
+ shell.say "DEBUG: (raw output from fontforge)"
73
+ shell.say output
74
+ end
75
+
76
+ unless output.empty? # correct output should be []
77
+ raise Fontcustom::Error, "Compilation failed unexpectedly. Check your options and try again with --debug get more details."
78
+ end
79
+ end
80
+
81
+ def collect_data
82
+ @json = JSON.parse(@json, :symbolize_names => true)
83
+ @data.merge! @json
84
+ @data[:glyphs].map! { |glyph| glyph.gsub(/\W/, "-").downcase }
85
+ end
86
+
87
+ def announce_files
88
+ if opts[:verbose]
89
+ @data[:fonts].each { |file| shell.say_status(:create, File.join(opts[:output], file)) }
90
+ end
91
+ end
92
+
93
+ def save_data
94
+ json = JSON.pretty_generate @data
95
+ file = File.join(opts[:output], ".fontcustom-data")
96
+ Fontcustom::Util.clear_file(file)
97
+ append_to_file file, json, :verbose => opts[:verbose]
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,80 @@
1
+ require "json"
2
+ require "thor"
3
+ require "thor/group"
4
+ require "thor/actions"
5
+
6
+ module Fontcustom
7
+ module Generator
8
+ class Template < Thor::Group
9
+ include Thor::Actions
10
+
11
+ # Instead of passing each option individually we're passing the entire options hash as an argument.
12
+ # This is DRYier, easier to maintain.
13
+ argument :opts
14
+
15
+ # Required for Thor::Actions#template
16
+ def self.source_root
17
+ File.join Fontcustom::Util.gem_lib_path, "templates"
18
+ end
19
+
20
+ def get_data
21
+ data = File.join(opts[:output], ".fontcustom-data")
22
+ if File.exists? data
23
+ @data = JSON.parse(File.read(data), :symbolize_names => true)
24
+ else
25
+ raise Fontcustom::Error, "There's no .fontcustom-data file in #{opts[:output]}. Try again?"
26
+ end
27
+ rescue JSON::ParserError
28
+ # Catches both empty and and malformed files
29
+ raise Fontcustom::Error, "The .fontcustom-data file in #{opts[:output]} is empty or corrupted. Try deleting the file and running Fontcustom::Generator::Font again to regenerate .fontcustom-data."
30
+ end
31
+
32
+ def check_templates
33
+ if opts[:templates].empty?
34
+ raise Fontcustom::Error, "No templates were specified. Check your options and try again?"
35
+ end
36
+ end
37
+
38
+ def update_source_paths
39
+ source_paths # assigns @source_paths
40
+ @source_paths.unshift(opts[:input], Dir.pwd)
41
+ end
42
+
43
+ def reset_output
44
+ return if @data[:templates].empty?
45
+ begin
46
+ deleted = []
47
+ @data[:templates].each do |file|
48
+ remove_file File.join(opts[:output], file), :verbose => opts[:verbose]
49
+ deleted << file
50
+ end
51
+ ensure
52
+ @data[:templates] = @data[:templates] - deleted
53
+ json = JSON.pretty_generate @data
54
+ file = File.join(opts[:output], ".fontcustom-data")
55
+ Fontcustom::Util.clear_file(file)
56
+ append_to_file file, json, :verbose => false # clear data file silently
57
+ end
58
+ end
59
+
60
+ def generate
61
+ @opts = opts # make available to templates
62
+ begin
63
+ created = []
64
+ opts[:templates].each do |source|
65
+ name = File.basename source
66
+ destination = File.join opts[:output], name
67
+ template source, destination, :verbose => opts[:verbose]
68
+ created << name
69
+ end
70
+ ensure
71
+ @data[:templates] = (@data[:templates] + created).uniq # TODO better way of cleaning up templates
72
+ json = JSON.pretty_generate @data
73
+ file = File.join(opts[:output], ".fontcustom-data")
74
+ Fontcustom::Util.clear_file(file)
75
+ append_to_file file, json, :verbose => opts[:verbose]
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,20 @@
1
+ module Fontcustom
2
+ DEFAULT_OPTIONS = {
3
+ :input => Dir.pwd,
4
+ :output => false, # used to assign default, if necessary
5
+ :config => false,
6
+ :templates => %w|css preview|,
7
+ :font_name => "fontcustom",
8
+ :file_hash => true,
9
+ :css_prefix => "icon-",
10
+ :debug => false,
11
+ :verbose => true
12
+ }
13
+
14
+ DATA_MODEL = {
15
+ :fonts => [],
16
+ :templates => [],
17
+ :file_name => "",
18
+ :glyphs => []
19
+ }
20
+ end
@@ -1,8 +1,9 @@
1
1
  import fontforge
2
2
  import os
3
3
  import md5
4
- import json
5
4
  import subprocess
5
+ import tempfile
6
+ import json
6
7
 
7
8
  try:
8
9
  import argparse
@@ -27,6 +28,10 @@ except ImportError:
27
28
 
28
29
  f = fontforge.font()
29
30
  f.encoding = 'UnicodeFull'
31
+ f.design_size = 16
32
+ f.em = 512
33
+ f.ascent = 448
34
+ f.descent = 64
30
35
 
31
36
  m = md5.new()
32
37
  cp = 0xf100
@@ -44,6 +49,7 @@ for dirname, dirnames, filenames in os.walk(indir):
44
49
  if ext in ['.svg']:
45
50
  # hack removal of <switch> </switch> tags
46
51
  svgfile = open(filePath, 'r+')
52
+ tmpsvgfile = tempfile.NamedTemporaryFile(suffix=ext, delete=False)
47
53
  svgtext = svgfile.read()
48
54
  svgfile.seek(0)
49
55
 
@@ -51,19 +57,25 @@ for dirname, dirnames, filenames in os.walk(indir):
51
57
  svgtext = svgtext.replace('<switch>', '')
52
58
  svgtext = svgtext.replace('</switch>', '')
53
59
 
54
- # remove all contents of file so that we can write out the new contents
55
- svgfile.truncate()
56
- svgfile.write(svgtext)
60
+ tmpsvgfile.file.write(svgtext)
57
61
 
58
62
  svgfile.close()
63
+ tmpsvgfile.file.close()
64
+
65
+ filePath = tmpsvgfile.name
59
66
  # end hack
60
67
 
61
68
  m.update(filename + str(size) + ';')
62
69
  glyph = f.createChar(cp)
63
70
  glyph.importOutlines(filePath)
64
71
 
65
- glyph.left_side_bearing = KERNING
66
- glyph.right_side_bearing = KERNING
72
+ # if we created a temporary file, let's clean it up
73
+ if tmpsvgfile:
74
+ os.unlink(tmpsvgfile.name)
75
+
76
+ # glyph.left_side_bearing = KERNING
77
+ # glyph.right_side_bearing = KERNING
78
+ glyph.width = 512
67
79
 
68
80
  # possible optimization?
69
81
  # glyph.simplify()
@@ -107,3 +119,7 @@ subprocess.call('mv ' + fontfile + '.eotlite ' + fontfile + '.eot', shell=True)
107
119
 
108
120
  # Hint the TTF file
109
121
  subprocess.call('ttfautohint -s -n ' + fontfile + '.ttf ' + fontfile + '-hinted.ttf > /dev/null 2>&1 && mv ' + fontfile + '-hinted.ttf ' + fontfile + '.ttf', shell=True)
122
+
123
+ # Describe output in JSON
124
+ outname = os.path.basename(fontfile)
125
+ print json.dumps({'fonts': [outname + '.ttf', outname + '.woff', outname + '.eot', outname + '.svg'], 'glyphs': files, 'file_name': outname})