fontcustom 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- FontCustom v0.0.1
1
+ FontCustom v0.0.2
2
2
  ==========
3
3
 
4
4
  **Generate custom icon webfonts from the comfort of the command line.**
data/Rakefile CHANGED
@@ -2,8 +2,8 @@ require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new do |t|
5
- t.libs << 'lib/fontcustom'
6
- t.test_files = FileList['test/lib/fontcustom/*_test.rb']
5
+ t.libs = t.libs + ['lib/fontcustom', 'spec', 'spec/fixtures']
6
+ t.test_files = FileList['spec/fontcustom/*_spec.rb']
7
7
  t.verbose = true
8
8
  end
9
9
 
@@ -3,14 +3,10 @@ require 'fontcustom/generator'
3
3
  require 'fontcustom/watcher'
4
4
 
5
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)
6
+ # Usage:
7
+ # Fontcustom.compile 'path/to/vectors', '-o', 'path/to/output'
11
8
  def compile(*args)
12
- config = args.last.is_a?(::Hash) ? args.pop : {}
13
- Fontcustom::Generator.start(args, config)
9
+ Fontcustom::Generator.start(args) # as array
14
10
  end
15
11
 
16
12
  def watch(*args)
@@ -3,14 +3,22 @@ require 'fontcustom'
3
3
 
4
4
  module Fontcustom
5
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)
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)
9
16
  end
10
17
 
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)
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)
14
22
  end
15
23
  end
16
24
  end
@@ -8,12 +8,20 @@ module Fontcustom
8
8
  desc 'Generates webfonts from given directory of vectors.'
9
9
 
10
10
  argument :input, :type => :string
11
- argument :output, :type => :string, :optional => true
11
+ class_option :output, :aliases => '-o'
12
+ class_option :name, :aliases => '-n'
13
+ class_option :nohash, :type => :boolean, :default => false
12
14
 
13
15
  def self.source_root
14
16
  File.dirname(__FILE__)
15
17
  end
16
18
 
19
+ def verify_fontforge
20
+ if `which fontforge` == ''
21
+ raise Thor::Error, 'Please install fontforge first.'
22
+ end
23
+ end
24
+
17
25
  def verify_input_dir
18
26
  if ! File.directory?(input)
19
27
  raise Thor::Error, "#{input} doesn't exist or isn't a directory."
@@ -23,32 +31,56 @@ module Fontcustom
23
31
  end
24
32
 
25
33
  def verify_or_create_output_dir
26
- @output = output.nil? ? File.join(File.dirname(input), 'fontcustom') : output
34
+ @output = options.output.nil? ? File.join(File.dirname(input), 'fontcustom') : options.output
27
35
  empty_directory(@output) unless File.directory?(@output)
28
36
  end
29
37
 
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
38
+ def normalize_name
39
+ @name = if options.name
40
+ options.name.gsub(/\W/, '-').downcase
41
+ else
42
+ 'fontcustom'
34
43
  end
35
44
  end
36
45
 
46
+ def cleanup_output_dir
47
+ css = File.join(@output, 'fontcustom.css')
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
+
37
60
  def generate
38
61
  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)
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`
41
68
  end
42
69
 
43
70
  def show_paths
44
- path = @font['file']
71
+ file = Dir[File.join(@output, @name + '*.ttf')].first
72
+ @path = file.chomp('.ttf')
73
+
45
74
  ['woff','ttf','eot','svg'].each do |type|
46
- say_status(:create, path + '.' + type)
75
+ say_status(:create, @path + '.' + type)
47
76
  end
48
77
  end
49
78
 
50
79
  def create_stylesheet
51
- @font['file'] = File.basename(@font['file'])
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
+
52
84
  template('templates/fontcustom.css', File.join(@output, 'fontcustom.css'))
53
85
  end
54
86
  end
@@ -6,7 +6,9 @@ import json
6
6
  from subprocess import call
7
7
 
8
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')
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')
10
12
  args = parser.parse_args()
11
13
 
12
14
  f = fontforge.font()
@@ -39,10 +41,15 @@ for dirname, dirnames, filenames in os.walk(args.dir[0]):
39
41
  files.append(name)
40
42
  cp += 1
41
43
 
42
- hashStr = m.hexdigest()
43
- fontfile = args.dir[1] + '/fontcustom-' + hashStr
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
44
49
 
45
- f.fontname = 'fontcustom'
50
+ f.fontname = args.name
51
+ f.familyname = args.name
52
+ f.fullname = args.name
46
53
  f.generate(fontfile + '.ttf')
47
54
  f.generate(fontfile + '.svg')
48
55
 
@@ -59,5 +66,3 @@ call(scriptPath + '/ttf2eot ' + fontfile + '.ttf > ' + fontfile + '.eot', shell=
59
66
 
60
67
  # Hint the TTF file
61
68
  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})
@@ -1,23 +1,23 @@
1
1
  /*
2
- Font Custom - icon webfonts made simple
2
+ Font Custom - icon webfonts made simple
3
3
  */
4
4
 
5
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");
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
11
  font-weight: normal;
12
12
  font-style: normal;
13
13
  }
14
14
 
15
15
  /*
16
- Bootstrap Overrides
16
+ Bootstrap Overrides
17
17
  */
18
18
 
19
19
  [class^="icon-"]:before, [class*=" icon-"]:before {
20
- font-family: "fontcustom";
20
+ font-family: "<%= @name %>";
21
21
  font-weight: normal;
22
22
  font-style: normal;
23
23
  display: inline-block;
@@ -66,7 +66,7 @@ li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before {
66
66
  }
67
67
 
68
68
  /*
69
- Icon Classes
69
+ Icon Classes
70
70
  */
71
- <% @font['names'].each_with_index do |name, index| %>
72
- .icon-<%= name.downcase %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
71
+ <% @classes.each_with_index do |name, index| %>
72
+ .icon-<%= name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
@@ -1,3 +1,3 @@
1
1
  module Fontcustom
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -17,6 +17,7 @@ module Fontcustom
17
17
 
18
18
  begin
19
19
  puts "Fontcustom is watching your icons at " + dir
20
+ Fontcustom.compile(*args)
20
21
  @listener.start()
21
22
 
22
23
  # Catches Cmd/Ctrl + C
@@ -8,17 +8,19 @@ describe Fontcustom do
8
8
  context 'when ouput_dir already contains files' do
9
9
  # Compile, add non-fontcustom file, change input vectors, recompile
10
10
  before(:all) do
11
- Fontcustom.compile(input_dir, output_dir)
11
+ # originals
12
+ Fontcustom.compile(input_dir, '-o', output_dir, '-n', 'Original Font')
12
13
  FileUtils.touch(fake_file, :verbose => true)
13
14
  @original_fonts = Dir[output_dir + '/fontcustom-*.{woff,eot,ttf,svg}']
14
15
  @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)
16
+
17
+ FileUtils.mv(input_dir + '/C.svg', input_dir + '/E.svg', :verbose => true)
18
+ Fontcustom.compile(input_dir, '-o', output_dir)
17
19
  end
18
20
 
19
21
  after(:all) do
20
22
  cleanup(output_dir)
21
- FileUtils.mv(input_dir + '/E.svg', input_dir + '/B.svg', :verbose => true)
23
+ FileUtils.mv(input_dir + '/E.svg', input_dir + '/C.svg', :verbose => true)
22
24
  end
23
25
 
24
26
  it 'should delete previous fontcustom generated files' do
@@ -5,7 +5,7 @@ describe Fontcustom::Generator do
5
5
  let(:output_dir) { 'tmp' }
6
6
 
7
7
  context 'normally' do
8
- before(:all) { Fontcustom::Generator.start([input_dir, output_dir]) }
8
+ before(:all) { Fontcustom::Generator.start([input_dir, '-o', output_dir]) }
9
9
  after(:all) { cleanup(output_dir) }
10
10
 
11
11
  it 'should create webfonts' do
@@ -27,7 +27,7 @@ describe Fontcustom::Generator do
27
27
 
28
28
  it 'should print icon-* CSS classes in fontcustom.css' do
29
29
  stylesheet = File.read(output_dir + '/fontcustom.css')
30
- icon_names = Dir[input_dir + '/*'].map { |file| File.basename(file, '.svg').downcase }
30
+ icon_names = Dir[input_dir + '/*'].map { |file| File.basename(file)[0..-5].gsub(/\W/, '-').downcase }
31
31
 
32
32
  icon_names.each do |name|
33
33
  stylesheet.should include('.icon-' + name)
@@ -39,7 +39,7 @@ describe Fontcustom::Generator do
39
39
  let(:fake_input_dir) { 'does/not/exist' }
40
40
 
41
41
  it 'should raise an error' do
42
- results = capture(:stderr) { Fontcustom::Generator.start([fake_input_dir, output_dir]) }
42
+ results = capture(:stderr) { Fontcustom::Generator.start([fake_input_dir, '-o', output_dir]) }
43
43
  results.should =~ /doesn't exist or isn't a directory/
44
44
  end
45
45
  end
@@ -52,4 +52,24 @@ describe Fontcustom::Generator do
52
52
  results.should =~ /doesn't contain any vectors/
53
53
  end
54
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
55
75
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontcustom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-11-26 00:00:00.000000000 Z
13
+ date: 2012-12-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -199,6 +199,7 @@ extensions: []
199
199
  extra_rdoc_files: []
200
200
  files:
201
201
  - .gitignore
202
+ - CHANGELOG.md
202
203
  - Gemfile
203
204
  - Guardfile
204
205
  - LICENSES.txt
@@ -217,9 +218,9 @@ files:
217
218
  - lib/fontcustom/version.rb
218
219
  - lib/fontcustom/watcher.rb
219
220
  - spec/fixtures/empty/no_vectors_here.txt
220
- - spec/fixtures/vectors/B.svg
221
221
  - spec/fixtures/vectors/C.svg
222
222
  - spec/fixtures/vectors/D.svg
223
+ - spec/fixtures/vectors/a_R3ally-eXotic f1Le Name.svg
223
224
  - spec/fontcustom/fontcustom_spec.rb
224
225
  - spec/fontcustom/generator_spec.rb
225
226
  - spec/fontcustom/watcher_spec.rb.off
@@ -238,7 +239,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
239
  version: '0'
239
240
  segments:
240
241
  - 0
241
- hash: 2573476005248431582
242
+ hash: 4274866861207866495
242
243
  required_rubygems_version: !ruby/object:Gem::Requirement
243
244
  none: false
244
245
  requirements:
@@ -247,7 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
248
  version: '0'
248
249
  segments:
249
250
  - 0
250
- hash: 2573476005248431582
251
+ hash: 4274866861207866495
251
252
  requirements: []
252
253
  rubyforge_project:
253
254
  rubygems_version: 1.8.24
@@ -256,9 +257,9 @@ specification_version: 3
256
257
  summary: Generate custom icon webfonts from the comfort of the command line.
257
258
  test_files:
258
259
  - spec/fixtures/empty/no_vectors_here.txt
259
- - spec/fixtures/vectors/B.svg
260
260
  - spec/fixtures/vectors/C.svg
261
261
  - spec/fixtures/vectors/D.svg
262
+ - spec/fixtures/vectors/a_R3ally-eXotic f1Le Name.svg
262
263
  - spec/fontcustom/fontcustom_spec.rb
263
264
  - spec/fontcustom/generator_spec.rb
264
265
  - spec/fontcustom/watcher_spec.rb.off