fontcustom 1.3.0.beta3 → 1.3.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a863f3b75e4669343c50c8f137aaae1c5c5df1fd
4
- data.tar.gz: 4997708bd8b627e3ec060c32fa0c06a7a6de4835
3
+ metadata.gz: 83ae4b0585895308ea825062bedefd5f52e1601f
4
+ data.tar.gz: 94f1938fe393cd56761d7facc448c73f01131a9f
5
5
  SHA512:
6
- metadata.gz: 3743b80862699178d2c6754a198af545c38358db18563d3ffe5110b777c7350e47a1e505720e14a8620b1ae03f048e34dc091ad60ec15f224b934b56ef2368f6
7
- data.tar.gz: 8f977e595ebf6232b06d7e69b2aead55be38727c104092340fcf20617b3b691d1f6bdf6a31d6c3a1c37a6c3080467eceb4e2f7524509c5c35a4c9d3ba643950e
6
+ metadata.gz: a57e93b5b0b0fed46f13d4d246747de4e6a241d684f4736bb5ac25598e2cf1b8108d0ffc32e08731fa74e3e903567da4c9658dc4979f6507b23fd1d6967d4571
7
+ data.tar.gz: 94c7d261fabc35340808134ca63a422d986befff99fdc816a6067f1bca6f563606a6a969dbfde5ded65866d8c217960b18d6fcc03db5da8e2f723d8002672819
data/TODO.md CHANGED
@@ -2,17 +2,19 @@
2
2
 
3
3
  ### 1.3.0
4
4
 
5
- * store relative paths in manifest (rebuild in generator/util)
6
-
5
+ * update manifest content in spec_helper
6
+ * fix failing travis-ci specs
7
7
  * reactivate watcher
8
- * Detect old manifest / show error message
9
-
10
- * Add more travis CLI rubies / thor versions?
11
- * documentation for template helpers
8
+ * more helpful messages when running without INPUT
12
9
  * redirect fontcustom.com to github repo (use wiki for documentation)
13
10
 
14
11
  ### Future
15
12
 
13
+ * Include fontcustom version in manifest / checksum
14
+ * Error message if using the wrong version of ruby
15
+ * Add more travis CLI rubies / thor versions?
16
+ * Detect old manifest / show error message
17
+ * Template helper that returns a hash of glyphs and pre-formatted codes
16
18
  * conserve code points: http://stackoverflow.com/questions/8794430/ruby-finding-lowest-free-id-in-an-id-array
17
19
  * strip /fill: rgba(...)/ from SVGs so that transparent SVGs don't fail
18
20
  * more flexible input/ouput hashes (regex or file extensions)
@@ -20,5 +22,3 @@
20
22
  * less template with variables
21
23
  * more robust fontforge check than `which`
22
24
  * remove redundant requires
23
- * rename options for succintness (e.g. :project_root => :root)
24
- * trim options specs down
@@ -17,22 +17,18 @@ module Fontcustom
17
17
  # Hack to get Thor to show more helpful defaults in `fontcustom help`. These
18
18
  # are overwritten in Fontcustom::Options.
19
19
  EXAMPLE_OPTIONS = {
20
- :project_root => "`pwd`",
21
- :output => "PROJECT_ROOT/FONT_NAME",
22
- :config => "PROJECT_ROOT/fontcustom.yml -or- PROJECT_ROOT/config/fontcustom.yml",
23
- :templates => "css preview",
24
- :manifest => "CONFIG_DIR/.fontcustom-manifest.json -or- PROJECT_ROOT/.fontcustom-manifest.json"
20
+ :output => "./FONT_NAME",
21
+ :config => "./fontcustom.yml -or- ./config/fontcustom.yml",
22
+ :templates => "css preview"
25
23
  }
26
24
 
27
25
  DEFAULT_OPTIONS = {
28
- :project_root => nil,
29
26
  :input => nil,
30
27
  :output => nil,
31
28
  :config => nil,
32
29
  :templates => %w|css preview|,
33
30
  :font_name => "fontcustom",
34
31
  :css_selector => ".icon-{{glyph}}",
35
- :manifest => nil,
36
32
  :preprocessor_path => nil,
37
33
  :autowidth => false,
38
34
  :no_hash => false,
@@ -4,20 +4,22 @@ module Fontcustom
4
4
  class Base
5
5
  include Utility
6
6
 
7
- def initialize(cli_options)
8
- @cli_options = cli_options
7
+ def initialize(raw_options)
9
8
  check_fontforge
10
- init_manifest
9
+ manifest = ".fontcustom-manifest.json"
10
+ raw_options[:manifest] = manifest
11
+ @options = Fontcustom::Options.new(raw_options).options
12
+ @manifest = Fontcustom::Manifest.new(manifest, @options)
11
13
  end
12
14
 
13
15
  def compile
14
- @manifest[:checksum][:current] = checksum
15
- if @options[:force] || @manifest[:checksum][:current] != @manifest[:checksum][:previous]
16
- save_manifest
16
+ current = checksum
17
+ previous = @manifest.get(:checksum)[:previous]
18
+ if @options[:force] || current != previous
19
+ @manifest.set :checksum, {:previous => previous, :current => current}
17
20
  start_generators
18
- @manifest = get_manifest
19
- @manifest[:checksum][:previous] = @manifest[:checksum][:current]
20
- save_manifest
21
+ @manifest.reload
22
+ @manifest.set :checksum, {:previous => current, :current => current}
21
23
  else
22
24
  say_message :status, "No changes detected. Skipping compilation."
23
25
  end
@@ -32,12 +34,6 @@ module Fontcustom
32
34
  end
33
35
  end
34
36
 
35
- def init_manifest
36
- file = @cli_options[:manifest] || File.join(Dir.pwd, ".fontcustom-manifest.json")
37
- @options = Fontcustom::Options.new(@cli_options).options
38
- @manifest = Fontcustom::Manifest.new(@options).manifest
39
- end
40
-
41
37
  # Calculates a hash of vectors, options, and templates (content and filenames)
42
38
  def checksum
43
39
  files = Dir.glob File.join(@options[:input][:vectors], "*.svg")
@@ -49,8 +45,8 @@ module Fontcustom
49
45
  end
50
46
 
51
47
  def start_generators
52
- Fontcustom::Generator::Font.new(@options[:manifest]).generate
53
- Fontcustom::Generator::Template.new(@options[:manifest]).generate
48
+ Fontcustom::Generator::Font.new(@manifest.manifest).generate
49
+ Fontcustom::Generator::Template.new(@manifest.manifest).generate
54
50
  end
55
51
  end
56
52
  end
@@ -9,10 +9,6 @@ module Fontcustom
9
9
 
10
10
  default_task :show_help
11
11
 
12
- class_option :project_root, :aliases => "-r", :type => :string,
13
- :desc => "The root context for relative paths (INPUT, OUTPUT, CONFIG).",
14
- :default => EXAMPLE_OPTIONS[:project_root]
15
-
16
12
  class_option :output, :aliases => "-o", :type => :string,
17
13
  :desc => "Where generated files are saved. Set different locations for different file types via a configuration file.",
18
14
  :default => EXAMPLE_OPTIONS[:output]
@@ -34,10 +30,6 @@ module Fontcustom
34
30
  :desc => "Format of generated CSS selector. \"{{glyph}}\" is substituted for the glyph name.",
35
31
  :default => DEFAULT_OPTIONS[:css_selector]
36
32
 
37
- class_option :manifest, :aliases => "-m", :type => :string,
38
- :desc => "Path to a manifest of generated files. Used for garbage collection.",
39
- :default => EXAMPLE_OPTIONS[:manifest]
40
-
41
33
  class_option :preprocessor_path, :aliases => "-p", :type => :string,
42
34
  :desc => "Optional font path for CSS proprocessor templates."
43
35
 
@@ -9,8 +9,8 @@ module Fontcustom
9
9
  attr_reader :manifest, :options
10
10
 
11
11
  def initialize(manifest)
12
- @manifest = get_manifest(manifest)
13
- @options = @manifest[:options]
12
+ @manifest = Fontcustom::Manifest.new manifest
13
+ @options = @manifest.get :options
14
14
  end
15
15
 
16
16
  def generate
@@ -26,20 +26,24 @@ module Fontcustom
26
26
  dirs = @options[:output].values.uniq
27
27
  dirs.each do |dir|
28
28
  unless File.directory? dir
29
- empty_directory dir, :verbose => ! @options[:quiet]
29
+ empty_directory dir, :verbose => false
30
+ say_message :create, dir
30
31
  end
31
32
  end
32
33
  end
33
34
 
34
35
  def delete_old_fonts
35
- delete_from_manifest(:fonts)
36
+ @manifest.delete :fonts
36
37
  end
37
38
 
38
39
  def set_glyph_info
39
- codepoint = if ! @manifest[:glyphs].empty?
40
- codepoints = @manifest[:glyphs].values.map { |data| data[:codepoint] }
40
+ manifest_glyphs = @manifest.get :glyphs
41
+ codepoint = if ! manifest_glyphs.empty?
42
+ codepoints = manifest_glyphs.values.map { |data| data[:codepoint] }
41
43
  codepoints.max + 1
42
44
  else
45
+ # Offset to work around Chrome Windows bug
46
+ # https://github.com/FontCustom/fontcustom/issues/1
43
47
  0xf100
44
48
  end
45
49
 
@@ -50,7 +54,7 @@ module Fontcustom
50
54
  name = name.strip.gsub(/\W/, "-")
51
55
  glyphs[name.to_sym] = { :source => file }
52
56
  if File.read(file).include? "rgba"
53
- say_message :warn, "`#{relative_path(file)}` contains transparency and will be skipped."
57
+ say_message :warn, "`#{file}` contains transparency and will be skipped."
54
58
  end
55
59
  end
56
60
 
@@ -58,20 +62,18 @@ module Fontcustom
58
62
  # version/platform, so we have to sort it first
59
63
  glyphs = Hash[glyphs.sort_by { |key, val| key.to_s }]
60
64
  glyphs.each do |name, data|
61
- if @manifest[:glyphs].has_key? name
62
- data[:codepoint] = @manifest[:glyphs][name][:codepoint]
65
+ if manifest_glyphs.has_key? name
66
+ data[:codepoint] = manifest_glyphs[name][:codepoint]
63
67
  else
64
68
  data[:codepoint] = codepoint
65
69
  codepoint = codepoint + 1
66
70
  end
67
71
  end
68
-
69
- @manifest[:glyphs] = glyphs
70
- save_manifest
72
+ @manifest.set :glyphs, glyphs
71
73
  end
72
74
 
73
75
  def create_fonts
74
- cmd = "fontforge -script #{Fontcustom.gem_lib}/scripts/generate.py #{@options[:manifest]}"
76
+ cmd = "fontforge -script #{Fontcustom.gem_lib}/scripts/generate.py #{@manifest.manifest}"
75
77
  stdout, stderr, status = Open3::capture3(cmd)
76
78
  stdout = stdout.split("\n")
77
79
  stdout = stdout[1..-1] if stdout[0] == "CreateAllPyModules()"
@@ -84,8 +86,8 @@ module Fontcustom
84
86
  end
85
87
 
86
88
  if status.success?
87
- @manifest = get_manifest
88
- say_changed :create, @manifest[:fonts]
89
+ @manifest.reload
90
+ say_changed :create, @manifest.get(:fonts)
89
91
  else
90
92
  raise Fontcustom::Error, "`fontforge` compilation failed.#{debug_msg}"
91
93
  end
@@ -9,12 +9,12 @@ module Fontcustom
9
9
  attr_reader :manifest, :options
10
10
 
11
11
  def initialize(manifest)
12
- @manifest = get_manifest(manifest)
13
- @options = @manifest[:options]
12
+ @manifest = Fontcustom::Manifest.new manifest
13
+ @options = @manifest.get :options
14
14
  end
15
15
 
16
16
  def generate
17
- if ! @manifest[:fonts].empty?
17
+ if ! @manifest.get(:fonts).empty?
18
18
  delete_old_templates
19
19
  set_relative_paths
20
20
  create_files
@@ -26,59 +26,77 @@ module Fontcustom
26
26
  private
27
27
 
28
28
  def delete_old_templates
29
- delete_from_manifest(:templates)
29
+ @manifest.delete :templates
30
30
  end
31
31
 
32
32
  def set_relative_paths
33
- name = File.basename @manifest[:fonts].first, File.extname(@manifest[:fonts].first)
34
- fonts = Pathname.new @options[:output][:fonts]
35
- css = Pathname.new @options[:output][:css]
36
- preview = Pathname.new @options[:output][:preview]
37
- @font_path = File.join fonts.relative_path_from(css).to_s, name
33
+ fonts = @manifest.get :fonts
34
+ name = File.basename fonts.first, File.extname(fonts.first)
35
+ fonts_path = Pathname.new @options[:output][:fonts]
36
+ css_path = Pathname.new @options[:output][:css]
37
+ preview_path = Pathname.new @options[:output][:preview]
38
+ @font_path = File.join fonts_path.relative_path_from(css_path).to_s, name
38
39
  @font_path_alt = @options[:preprocessor_path].nil? ? @font_path : File.join(@options[:preprocessor_path], name)
39
- @font_path_preview = File.join fonts.relative_path_from(preview).to_s, name
40
+ @font_path_preview = File.join fonts_path.relative_path_from(preview_path).to_s, name
40
41
  end
41
42
 
42
43
  def create_files
43
- @glyphs = @manifest[:glyphs]
44
+ @glyphs = @manifest.get :glyphs
45
+ existing = @manifest.get :templates
44
46
  created = []
45
47
  begin
46
48
  @options[:templates].each do |source|
47
49
  begin
48
- target = template_target source
50
+ source = get_source_path(source)
51
+ target = get_target_path(source)
49
52
  template source, target, :verbose => false, :force => true
50
- rescue => e
51
- raise Fontcustom::Error, "Could not generate template `#{relative_path(source)}`:#{line_break + e.message}"
52
53
  end
53
54
  created << target
54
55
  end
55
56
  ensure
56
57
  say_changed :create, created
57
- @manifest[:templates] = (@manifest[:templates] + created).uniq
58
- save_manifest
58
+ @manifest.set :templates, (existing + created).uniq
59
59
  end
60
60
  end
61
61
 
62
- def template_target(source)
63
- packaged = %w|fontcustom.css _fontcustom.scss _fontcustom-rails.scss fontcustom-preview.html|
64
- css_exts = %w|.css .scss .sass .less .stylus|
65
- name = File.basename source
62
+ def get_source_path(template)
63
+ template_path = File.join Fontcustom.gem_lib, "templates"
64
+
65
+ case template
66
+ when "preview"
67
+ File.join template_path, "fontcustom-preview.html"
68
+ when "css"
69
+ File.join template_path, "fontcustom.css"
70
+ when "scss"
71
+ File.join template_path, "_fontcustom.scss"
72
+ when "scss-rails"
73
+ File.join template_path, "_fontcustom-rails.scss"
74
+ else
75
+ File.join @options[:input][:templates], template
76
+ end
77
+ end
78
+
79
+ def get_target_path(source)
66
80
  ext = File.extname source
67
- target = name.dup
81
+ base = File.basename source
82
+ css_exts = %w|.css .scss .sass .less .stylus|
83
+ packaged = %w|fontcustom-preview.html fontcustom.css _fontcustom.scss _fontcustom-rails.scss|
84
+
85
+ target = if @options[:output].keys.include? base.to_sym
86
+ File.join @options[:output][base.to_sym], source
87
+ elsif ext && css_exts.include?(ext)
88
+ File.join @options[:output][:css], base
89
+ elsif source.match(/fontcustom-preview\.html/)
90
+ File.join @options[:output][:preview], base
91
+ else
92
+ File.join @options[:output][:fonts], base
93
+ end
68
94
 
69
- if packaged.include?(name) && @options[:font_name] != DEFAULT_OPTIONS[:font_name]
95
+ if packaged.include?(base) && @options[:font_name] != DEFAULT_OPTIONS[:font_name]
70
96
  target.sub! DEFAULT_OPTIONS[:font_name], @options[:font_name]
71
97
  end
72
98
 
73
- if @options[:output].keys.include? name.to_sym
74
- File.join @options[:output][name.to_sym], target
75
- elsif css_exts.include? ext
76
- File.join @options[:output][:css], target
77
- elsif name == "fontcustom-preview.html"
78
- File.join @options[:output][:preview], target
79
- else
80
- File.join @options[:output][:fonts], target
81
- end
99
+ target
82
100
  end
83
101
 
84
102
  #
@@ -122,7 +140,7 @@ module Fontcustom
122
140
 
123
141
  def glyphs
124
142
  output = @glyphs.map do |name, value|
125
- %Q|#{@options[:css_selector].sub('{{glyph}}', name.to_s)}:before { content: "\\#{value[:codepoint].to_s(16)}\" }|
143
+ %Q|#{@options[:css_selector].sub('{{glyph}}', name.to_s)}:before { content: "\\#{value[:codepoint].to_s(16)}"; }|
126
144
  end
127
145
  output.join "\n"
128
146
  end
@@ -2,41 +2,74 @@ module Fontcustom
2
2
  class Manifest
3
3
  include Utility
4
4
 
5
- attr_accessor :manifest
5
+ attr_reader :manifest
6
6
 
7
- def initialize(options)
8
- @options = options
9
- update_or_create_manifest
7
+ def initialize(manifest, cli_options = {})
8
+ @manifest = manifest
9
+ @cli_options = symbolize_hash cli_options
10
+ if File.exists? @manifest
11
+ reload
12
+ if ! @cli_options.empty? && get(:options) != @cli_options
13
+ set :options, @cli_options
14
+ end
15
+ else
16
+ create_manifest @cli_options
17
+ end
10
18
  end
11
19
 
12
- def update_or_create_manifest
13
- if File.exists? @options[:manifest]
14
- update_manifest
20
+ # TODO convert paths to absolute
21
+ def get(key)
22
+ @data[key]
23
+ end
24
+
25
+ # TODO convert paths to relative
26
+ def set(key, value, status = nil)
27
+ if key == :all
28
+ @data = value
15
29
  else
16
- create_manifest
30
+ @data[key] = value
17
31
  end
32
+ json = JSON.pretty_generate @data
33
+ write_file @manifest, json, status
18
34
  end
19
35
 
20
- private
36
+ def reload
37
+ begin
38
+ json = File.read @manifest
39
+ @data = JSON.parse json, :symbolize_names => true
40
+ rescue JSON::ParserError
41
+ raise Fontcustom::Error,
42
+ "Couldn't parse `#{@manifest}`. Fix any invalid "\
43
+ "JSON or delete the file to start from scratch."
44
+ end
45
+ end
21
46
 
22
- def update_manifest
23
- @manifest = get_manifest
24
- if @manifest[:options] != @options
25
- @manifest[:options] = @options
26
- save_manifest
47
+ def delete(key)
48
+ files = get(key)
49
+ return if files.empty?
50
+ begin
51
+ deleted = []
52
+ files.each do |file|
53
+ remove_file file, :verbose => false
54
+ deleted << file
55
+ end
56
+ ensure
57
+ set key, files - deleted
58
+ say_changed :delete, deleted
27
59
  end
28
60
  end
29
61
 
30
- def create_manifest
31
- @manifest = {
62
+ private
63
+
64
+ def create_manifest(options)
65
+ defaults = {
32
66
  :checksum => { :current => "", :previous => "" },
33
67
  :fonts => [],
34
68
  :glyphs => {},
35
- :options => @options,
69
+ :options => options,
36
70
  :templates => []
37
71
  }
38
- json = JSON.pretty_generate @manifest
39
- write_file @options[:manifest], json, :create
72
+ set :all, defaults, :create
40
73
  end
41
74
  end
42
75
  end