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 +4 -4
- data/TODO.md +8 -8
- data/lib/fontcustom.rb +3 -7
- data/lib/fontcustom/base.rb +13 -17
- data/lib/fontcustom/cli.rb +0 -8
- data/lib/fontcustom/generator/font.rb +17 -15
- data/lib/fontcustom/generator/template.rb +50 -32
- data/lib/fontcustom/manifest.rb +52 -19
- data/lib/fontcustom/options.rb +31 -77
- data/lib/fontcustom/utility.rb +22 -58
- data/lib/fontcustom/version.rb +1 -1
- data/spec/fontcustom/base_spec.rb +12 -24
- data/spec/fontcustom/cli_spec.rb +1 -1
- data/spec/fontcustom/generator/font_spec.rb +17 -19
- data/spec/fontcustom/generator/template_spec.rb +5 -3
- data/spec/fontcustom/manifest_spec.rb +7 -6
- data/spec/fontcustom/options_spec.rb +108 -189
- data/spec/fontcustom/utility_spec.rb +3 -84
- data/spec/spec_helper.rb +10 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83ae4b0585895308ea825062bedefd5f52e1601f
|
4
|
+
data.tar.gz: 94f1938fe393cd56761d7facc448c73f01131a9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
*
|
6
|
-
|
5
|
+
* update manifest content in spec_helper
|
6
|
+
* fix failing travis-ci specs
|
7
7
|
* reactivate watcher
|
8
|
-
*
|
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
|
data/lib/fontcustom.rb
CHANGED
@@ -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
|
-
:
|
21
|
-
:
|
22
|
-
:
|
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,
|
data/lib/fontcustom/base.rb
CHANGED
@@ -4,20 +4,22 @@ module Fontcustom
|
|
4
4
|
class Base
|
5
5
|
include Utility
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@cli_options = cli_options
|
7
|
+
def initialize(raw_options)
|
9
8
|
check_fontforge
|
10
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
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
|
19
|
-
@manifest
|
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(@
|
53
|
-
Fontcustom::Generator::Template.new(@
|
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
|
data/lib/fontcustom/cli.rb
CHANGED
@@ -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 =
|
13
|
-
@options = @manifest
|
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 =>
|
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
|
-
|
36
|
+
@manifest.delete :fonts
|
36
37
|
end
|
37
38
|
|
38
39
|
def set_glyph_info
|
39
|
-
|
40
|
-
|
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, "`#{
|
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
|
62
|
-
data[: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 #{@
|
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
|
88
|
-
say_changed :create, @manifest
|
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 =
|
13
|
-
@options = @manifest
|
12
|
+
@manifest = Fontcustom::Manifest.new manifest
|
13
|
+
@options = @manifest.get :options
|
14
14
|
end
|
15
15
|
|
16
16
|
def generate
|
17
|
-
if ! @manifest
|
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
|
-
|
29
|
+
@manifest.delete :templates
|
30
30
|
end
|
31
31
|
|
32
32
|
def set_relative_paths
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
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
|
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
|
-
|
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
|
58
|
-
save_manifest
|
58
|
+
@manifest.set :templates, (existing + created).uniq
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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?(
|
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
|
-
|
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
|
data/lib/fontcustom/manifest.rb
CHANGED
@@ -2,41 +2,74 @@ module Fontcustom
|
|
2
2
|
class Manifest
|
3
3
|
include Utility
|
4
4
|
|
5
|
-
|
5
|
+
attr_reader :manifest
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
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
|
23
|
-
|
24
|
-
if
|
25
|
-
|
26
|
-
|
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
|
-
|
31
|
-
|
62
|
+
private
|
63
|
+
|
64
|
+
def create_manifest(options)
|
65
|
+
defaults = {
|
32
66
|
:checksum => { :current => "", :previous => "" },
|
33
67
|
:fonts => [],
|
34
68
|
:glyphs => {},
|
35
|
-
:options =>
|
69
|
+
:options => options,
|
36
70
|
:templates => []
|
37
71
|
}
|
38
|
-
|
39
|
-
write_file @options[:manifest], json, :create
|
72
|
+
set :all, defaults, :create
|
40
73
|
end
|
41
74
|
end
|
42
75
|
end
|