fontcustom 1.3.0.beta3 → 1.3.0.beta4

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.
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