fontcustom 1.1.0.pre → 1.1.0.pre2

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/TODO.md +20 -5
  3. data/lib/fontcustom.rb +42 -4
  4. data/lib/fontcustom/cli.rb +65 -25
  5. data/lib/fontcustom/generator/font.rb +26 -26
  6. data/lib/fontcustom/generator/template.rb +29 -30
  7. data/lib/fontcustom/options.rb +207 -23
  8. data/lib/fontcustom/templates/_fontcustom-bootstrap-ie7.scss +9 -9
  9. data/lib/fontcustom/templates/_fontcustom-bootstrap.scss +19 -19
  10. data/lib/fontcustom/templates/_fontcustom-rails.scss +28 -0
  11. data/lib/fontcustom/templates/_fontcustom.scss +11 -11
  12. data/lib/fontcustom/templates/fontcustom-bootstrap-ie7.css +9 -9
  13. data/lib/fontcustom/templates/fontcustom-bootstrap.css +19 -19
  14. data/lib/fontcustom/templates/fontcustom-preview.html +34 -7
  15. data/lib/fontcustom/templates/fontcustom.css +11 -11
  16. data/lib/fontcustom/templates/fontcustom.yml +11 -6
  17. data/lib/fontcustom/util.rb +38 -159
  18. data/lib/fontcustom/version.rb +1 -1
  19. data/lib/fontcustom/watcher.rb +16 -14
  20. data/spec/fixtures/generators/.fontcustom-data-corrupted +18 -0
  21. data/spec/fixtures/generators/fontcustom.yml +1 -0
  22. data/spec/fixtures/{util/fontcustom.yml → options/any-file-name.yml} +0 -0
  23. data/spec/fixtures/{util → options}/config-is-in-dir/fontcustom.yml +0 -0
  24. data/spec/fixtures/options/fontcustom-empty.yml +1 -0
  25. data/spec/fixtures/{util → options}/fontcustom-malformed.yml +0 -0
  26. data/spec/fixtures/options/fontcustom.yml +1 -0
  27. data/spec/fixtures/options/no-config-here/.gitkeep +0 -0
  28. data/spec/fixtures/{util → options}/rails-like/config/fontcustom.yml +0 -0
  29. data/spec/fontcustom/generator/font_spec.rb +31 -15
  30. data/spec/fontcustom/generator/template_spec.rb +20 -18
  31. data/spec/fontcustom/options_spec.rb +428 -0
  32. data/spec/fontcustom/util_spec.rb +38 -336
  33. data/spec/fontcustom/watcher_spec.rb +7 -2
  34. data/spec/spec_helper.rb +1 -2
  35. metadata +23 -13
  36. data/lib/fontcustom/actions.rb +0 -28
  37. data/spec/fontcustom/actions_spec.rb +0 -22
@@ -1,63 +1,63 @@
1
1
  /*
2
- Icon Font: <%= @opts[:font_name] %>
2
+ Icon Font: <%= @opts.font_name %>
3
3
  Bootstrap Override
4
4
  */
5
5
 
6
6
  @font-face {
7
- font-family: "<%= @opts[:font_name] %>";
8
- src: url("<%= @data[:paths][:css_to_fonts] %>.eot");
9
- src: url("<%= @data[:paths][:css_to_fonts] %>.eot?#iefix") format("embedded-opentype"),
10
- url("<%= @data[:paths][:css_to_fonts] %>.woff") format("woff"),
11
- url("<%= @data[:paths][:css_to_fonts] %>.ttf") format("truetype"),
12
- url("<%= @data[:paths][:css_to_fonts] %>.svg#<%= @opts[:font_name] %>") format("svg");
7
+ font-family: "<%= @opts.font_name %>";
8
+ src: url("<%= @font_path %>.eot");
9
+ src: url("<%= @font_path %>.eot?#iefix") format("embedded-opentype"),
10
+ url("<%= @font_path %>.woff") format("woff"),
11
+ url("<%= @font_path %>.ttf") format("truetype"),
12
+ url("<%= @font_path %>.svg#<%= @opts.font_name %>") format("svg");
13
13
  font-weight: normal;
14
14
  font-style: normal;
15
15
  }
16
16
 
17
- [class^="<%= @opts[:css_prefix] %>"]:before, [class*=" <%= @opts[:css_prefix] %>"]:before {
18
- font-family: "<%= @opts[:font_name] %>";
17
+ [class^="<%= @opts.css_prefix %>"]:before, [class*=" <%= @opts.css_prefix %>"]:before {
18
+ font-family: "<%= @opts.font_name %>";
19
19
  font-weight: normal;
20
20
  font-style: normal;
21
21
  display: inline-block;
22
22
  text-decoration: inherit;
23
23
  }
24
24
 
25
- a [class^="<%= @opts[:css_prefix] %>"], a [class*=" <%= @opts[:css_prefix] %>"] {
25
+ a [class^="<%= @opts.css_prefix %>"], a [class*=" <%= @opts.css_prefix %>"] {
26
26
  display: inline-block;
27
27
  text-decoration: inherit;
28
28
  }
29
29
 
30
- .<%= @opts[:css_prefix] %>large:before {
30
+ .<%= @opts.css_prefix %>large:before {
31
31
  vertical-align: top;
32
32
  font-size: 1.333em;
33
33
  }
34
34
 
35
- .btn [class^="<%= @opts[:css_prefix] %>"], .btn [class*=" <%= @opts[:css_prefix] %>"] {
35
+ .btn [class^="<%= @opts.css_prefix %>"], .btn [class*=" <%= @opts.css_prefix %>"] {
36
36
  line-height: 0.9em;
37
37
  }
38
38
 
39
- li [class^="<%= @opts[:css_prefix] %>"], li [class*=" <%= @opts[:css_prefix] %>"] {
39
+ li [class^="<%= @opts.css_prefix %>"], li [class*=" <%= @opts.css_prefix %>"] {
40
40
  display: inline-block;
41
41
  width: 1.25em;
42
42
  text-align: center;
43
43
  }
44
44
 
45
- li .<%= @opts[:css_prefix] %>large[class^="<%= @opts[:css_prefix] %>"], li .<%= @opts[:css_prefix] %>large[class*=" <%= @opts[:css_prefix] %>"] {
45
+ li .<%= @opts.css_prefix %>large[class^="<%= @opts.css_prefix %>"], li .<%= @opts.css_prefix %>large[class*=" <%= @opts.css_prefix %>"] {
46
46
  width: 1.875em;
47
47
  }
48
48
 
49
- li[class^="<%= @opts[:css_prefix] %>"], li[class*=" <%= @opts[:css_prefix] %>"] {
49
+ li[class^="<%= @opts.css_prefix %>"], li[class*=" <%= @opts.css_prefix %>"] {
50
50
  margin-left: 0;
51
51
  list-style-type: none;
52
52
  }
53
53
 
54
- li[class^="<%= @opts[:css_prefix] %>"]:before, li[class*=" <%= @opts[:css_prefix] %>"]:before {
54
+ li[class^="<%= @opts.css_prefix %>"]:before, li[class*=" <%= @opts.css_prefix %>"]:before {
55
55
  text-indent: -2em;
56
56
  text-align: center;
57
57
  }
58
58
 
59
- li[class^="<%= @opts[:css_prefix] %>"].<%= @opts[:css_prefix] %>large:before, li[class*=" <%= @opts[:css_prefix] %>"].<%= @opts[:css_prefix] %>large:before {
59
+ li[class^="<%= @opts.css_prefix %>"].<%= @opts.css_prefix %>large:before, li[class*=" <%= @opts.css_prefix %>"].<%= @opts.css_prefix %>large:before {
60
60
  text-indent: -1.333em;
61
61
  }
62
- <% @data[:glyphs].each_with_index do |name, index| %>
63
- .<%= @opts[:css_prefix] + name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
62
+ <% @glyphs.each_with_index do |name, index| %>
63
+ .<%= @opts.css_prefix + name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
@@ -1,11 +1,11 @@
1
1
  <% scale = %w|12 14 16 18 21 24 36 48 60 72| %><!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= @opts[:font_name] %> glyphs preview</title>
5
- <link rel="stylesheet" href="<%= @data[:paths][:preview_to_css] %>" />
6
- <!--[if lte IE 7]><link rel="stylesheet" href="fontcustom-ie7.css" /><![endif]-->
4
+ <title><%= @opts.font_name %> glyphs preview</title>
7
5
 
8
6
  <style>
7
+ /* Page Styles */
8
+
9
9
  * {
10
10
  -moz-box-sizing: border-box;
11
11
  -webkit-box-sizing: border-box;
@@ -86,6 +86,33 @@
86
86
  font-size: 12px;
87
87
  padding: 20px 0;
88
88
  }
89
+
90
+ /* Icon Font: <%= @opts.font_name %> */
91
+
92
+ @font-face {
93
+ font-family: "<%= @opts.font_name %>";
94
+ src: url("<%= @data[:paths][:preview_to_fonts] %>.eot");
95
+ src: url("<%= @data[:paths][:preview_to_fonts] %>.eot?#iefix") format("embedded-opentype"),
96
+ url("<%= @data[:paths][:preview_to_fonts] %>.woff") format("woff"),
97
+ url("<%= @data[:paths][:preview_to_fonts] %>.ttf") format("truetype"),
98
+ url("<%= @data[:paths][:preview_to_fonts] %>.svg#<%= @opts.font_name %>") format("svg");
99
+ font-weight: normal;
100
+ font-style: normal;
101
+ }
102
+
103
+ <%= @glyphs.map {|name| ".#{@opts.css_prefix + name}:before"}.join(",\n") %> {
104
+ font-family: "<%= @opts.font_name %>";
105
+ font-style: normal;
106
+ font-weight: normal;
107
+ font-variant: normal;
108
+ text-transform: none;
109
+ line-height: 1;
110
+ -webkit-font-smoothing: antialiased;
111
+ display: inline-block;
112
+ text-decoration: inherit;
113
+ }
114
+ <% @glyphs.each_with_index do |name, index| %>
115
+ .<%= @opts.css_prefix + name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
89
116
  </style>
90
117
 
91
118
  <!--[if lte IE 8]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
@@ -93,18 +120,18 @@
93
120
 
94
121
  <body>
95
122
  <div class="container">
96
- <h1><%= @opts[:font_name] %> contains <%= @data[:glyphs].length %> glyphs:</h1>
123
+ <h1><%= @opts.font_name %> contains <%= @glyphs.length %> glyphs:</h1>
97
124
 
98
- <% @data[:glyphs].each_with_index do |name, index| %>
125
+ <% @glyphs.each_with_index do |name, index| %>
99
126
  <div class="glyph">
100
127
  <div class="preview-glyphs">
101
- <% scale.each do |n| %><i class="step <%= @opts[:css_prefix] + name %> size-<%= n %>"></i><% end %>
128
+ <% scale.each do |n| %><i class="step <%= @opts.css_prefix + name %> size-<%= n %>"></i><% end %>
102
129
  </div>
103
130
  <div class="preview-scale">
104
131
  <% scale.each do |n| %><span class="step"><%= n %></span><% end %>
105
132
  </div>
106
133
  <div class="usage">
107
- <input class="class" type="text" readonly="readonly" onClick="this.select();" value=".<%= @opts[:css_prefix] + name %>" />
134
+ <input class="class" type="text" readonly="readonly" onClick="this.select();" value=".<%= @opts.css_prefix + name %>" />
108
135
  <input class="point" type="text" readonly="readonly" onClick="this.select();" value="&amp;#x<%= (61696+index).to_s(16) %>;" />
109
136
  </div>
110
137
  </div>
@@ -1,20 +1,20 @@
1
1
  /*
2
- Icon Font: <%= @opts[:font_name] %>
2
+ Icon Font: <%= @opts.font_name %>
3
3
  */
4
4
 
5
5
  @font-face {
6
- font-family: "<%= @opts[:font_name] %>";
7
- src: url("<%= @data[:paths][:css_to_fonts] %>.eot");
8
- src: url("<%= @data[:paths][:css_to_fonts] %>.eot?#iefix") format("embedded-opentype"),
9
- url("<%= @data[:paths][:css_to_fonts] %>.woff") format("woff"),
10
- url("<%= @data[:paths][:css_to_fonts] %>.ttf") format("truetype"),
11
- url("<%= @data[:paths][:css_to_fonts] %>.svg#<%= @opts[:font_name] %>") format("svg");
6
+ font-family: "<%= @opts.font_name %>";
7
+ src: url("<%= @font_path %>.eot");
8
+ src: url("<%= @font_path %>.eot?#iefix") format("embedded-opentype"),
9
+ url("<%= @font_path %>.woff") format("woff"),
10
+ url("<%= @font_path %>.ttf") format("truetype"),
11
+ url("<%= @font_path %>.svg#<%= @opts.font_name %>") format("svg");
12
12
  font-weight: normal;
13
13
  font-style: normal;
14
14
  }
15
15
 
16
- <%= @data[:glyphs].map {|name| ".#{@opts[:css_prefix] + name}:before"}.join(",\n") %> {
17
- font-family: "<%= @opts[:font_name] %>";
16
+ <%= @glyphs.map {|name| ".#{@opts.css_prefix + name}:before"}.join(",\n") %> {
17
+ font-family: "<%= @opts.font_name %>";
18
18
  font-style: normal;
19
19
  font-weight: normal;
20
20
  font-variant: normal;
@@ -24,5 +24,5 @@
24
24
  display: inline-block;
25
25
  text-decoration: inherit;
26
26
  }
27
- <% @data[:glyphs].each_with_index do |name, index| %>
28
- .<%= @opts[:css_prefix] + name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
27
+ <% @glyphs.each_with_index do |name, index| %>
28
+ .<%= @opts.css_prefix + name %>:before { content: "\<%= (61696+index).to_s(16) %>"; }<% end %>
@@ -1,23 +1,27 @@
1
1
  # ---------------------------------------------------------------------------- #
2
2
  # Project Info
3
- # Learn more about these options with `fontcustom help`.
3
+ # Learn more about these options by running `fontcustom help` or visit
4
+ # <http://fontcustom.com>.
4
5
  # ---------------------------------------------------------------------------- #
5
6
 
6
7
  #font_name: My Custom Font
7
8
  #file_hash: false
8
9
  #css_prefix: glyph-
9
- #preprocessor_font_path: fonts/fontcustom
10
+ #preprocessor_path: fonts/fontcustom
10
11
  #debug: true
11
12
  #verbose: false
12
13
 
13
14
 
14
15
  # ---------------------------------------------------------------------------- #
15
- # Project Directories
16
+ # Project Paths
16
17
  # All paths are relative to PROJECT_ROOT (default: working directory).
17
- # When assigned a hash, individual components can have their own paths.
18
- # When assigned a string, all components share the same path.
18
+ # PROJECT_ROOT can be configured (absolute path recommended).
19
+ # For finer control, assign INPUT and OUTPUT as hashes instead of a strings.
20
+ # The OUPUT hash can route custom templates according to their filename.
19
21
  # ---------------------------------------------------------------------------- #
20
22
 
23
+ #project_root: some/other/place
24
+
21
25
  #input:
22
26
  # vectors: app/assets/fontcustom/vectors
23
27
  # templates: app/assets/fontcustom/templates
@@ -26,11 +30,12 @@
26
30
  # fonts: app/assets/fonts
27
31
  # css: app/assets/stylesheets
28
32
  # preview: app/views/styleguide
33
+ # my-custom-template.yml: config
29
34
 
30
35
 
31
36
  # ---------------------------------------------------------------------------- #
32
37
  # Templates
33
- # Shortcuts:
38
+ # Included in Font Custom:
34
39
  # preview, css, scss, bootstrap, bootstrap-scss, bootstrap-ie7,
35
40
  # bootstrap-ie7-scss
36
41
  # Custom templates should be saved in the INPUT[:templates] directory.
@@ -1,172 +1,51 @@
1
- require "yaml"
2
- require "thor/core_ext/hash_with_indifferent_access"
3
-
1
+ ##
2
+ # Needs access to @shell and an Options instance
3
+ # (@opts in thor, @cli_options or self in Options)
4
4
  module Fontcustom
5
- class Util
6
- class << self
7
- def check_fontforge
8
- fontforge = `which fontforge`
9
- if fontforge == "" || fontforge == "fontforge not found"
10
- raise Fontcustom::Error, "Please install fontforge first. Visit http://fontcustom.com for more details."
11
- end
12
- end
13
-
14
- # Converts all options into symbol-accessible hashes
15
- # Priority: Passed args > config file > default
16
- def collect_options(args = {})
17
- options = Fontcustom::DEFAULT_OPTIONS.clone
18
- options[:project_root] = args[:project_root] if args[:project_root]
19
-
20
- # Parse fontcustom.yml if it exists
21
- # Deletes :config so that it can't overwrite the output of .get_config_path
22
- options[:config] = args.delete(:config) if args[:config]
23
- options[:config] = get_config_path options
24
-
25
- if options[:config]
26
- begin
27
- config = YAML.load File.open(options[:config])
28
- options.merge! config
29
- rescue
30
- raise Fontcustom::Error, "I couldn't read your configuration file. Please check #{options[:config]} and try again."
31
- end
32
- end
33
-
34
- # Override with passed arguments
35
- args.delete(:input) unless args[:input] # allows nil input from CLI
36
- options.merge! args
37
- options[:font_name] = options[:font_name].strip.gsub(/\W/, '-')
38
-
39
- options[:input] = get_input_paths options
40
- options[:output] = get_output_paths options
41
- options[:templates] = get_templates options
42
- options
5
+ module Util
6
+ def check_fontforge
7
+ fontforge = `which fontforge`
8
+ if fontforge == "" || fontforge == "fontforge not found"
9
+ raise Fontcustom::Error, "Please install fontforge. Visit http://fontcustom.com for instructions."
43
10
  end
11
+ end
44
12
 
45
- def get_config_path(options)
46
- if options[:config]
47
- config = File.expand_path File.join(options[:project_root], options[:config])
48
-
49
- # :config is the path to fontcustom.yml
50
- if File.exists?(config) && ! File.directory?(config)
51
- config
52
-
53
- # :config is a dir containing fontcustom.yml
54
- elsif File.exists? File.join(config, "fontcustom.yml")
55
- File.join config, "fontcustom.yml"
56
-
57
- else
58
- raise Fontcustom::Error, "I couldn't find your configuration file. Check #{config} and try again."
59
- end
60
- else
61
- # fontcustom.yml is in the project_root
62
- if File.exists? File.join(options[:project_root], "fontcustom.yml")
63
- File.join options[:project_root], "fontcustom.yml"
64
-
65
- # config/fontcustom.yml is in the project_root
66
- elsif File.exists? File.join(options[:project_root], "config", "fontcustom.yml")
67
- File.join options[:project_root], "config", "fontcustom.yml"
68
-
69
- else
70
- # TODO helpful warning that no config was found
71
- false
72
- end
73
- end
74
- end
75
-
76
- def get_input_paths(options)
77
- paths = if options[:input].is_a? Hash
78
- input = Thor::CoreExt::HashWithIndifferentAccess.new options[:input]
79
- raise Fontcustom::Error, "INPUT should be a string or a hash containing a \"vectors\" key." unless input[:vectors]
80
-
81
- input[:vectors] = File.expand_path File.join(options[:project_root], input[:vectors])
82
- raise Fontcustom::Error, "INPUT[\"vectors\"] should be a directory. Check #{input[:vectors]} and try again." unless File.directory? input[:vectors]
83
-
84
- if input[:templates]
85
- input[:templates] = File.expand_path File.join(options[:project_root], input[:templates])
86
- raise Fontcustom::Error, "INPUT[\"templates\"] should be a directory. Check #{input[:templates]} and try again." unless File.directory? input[:templates]
87
- else
88
- input[:templates] = input[:vectors]
89
- end
90
- input
91
- elsif options[:input].is_a? String
92
- input = File.join options[:project_root], options[:input]
93
- raise Fontcustom::Error, "INPUT should be a directory. Check #{input} and try again." unless File.directory? input
94
- Thor::CoreExt::HashWithIndifferentAccess.new({
95
- :vectors => input,
96
- :templates => input
97
- })
98
- end
99
-
100
- if Dir[File.join(paths[:vectors], "*.{svg,eps}")].empty?
101
- raise Fontcustom::Error, "#{paths[:vectors]} doesn't contain any vectors (*.svg or *.eps files)."
102
- end
13
+ def say_changed(status, changed)
14
+ return unless base(:verbose)
15
+ message = changed.map { |file| relative_to_root(file) }
16
+ @shell.say_status status, message.join(" ")
17
+ end
103
18
 
104
- paths
105
- end
19
+ def say_message(status, message)
20
+ return unless base(:verbose)
21
+ @shell.say_status status, message
22
+ end
106
23
 
107
- def get_output_paths(options)
108
- if options[:output].is_a? Hash
109
- output = Thor::CoreExt::HashWithIndifferentAccess.new options[:output]
110
- raise Fontcustom::Error, "OUTPUT should be a string or a hash containing a \"fonts\" key." unless output[:fonts]
24
+ def relative_to_root(path)
25
+ path = path.sub(base(:project_root), "")
26
+ path = path[1..-1] if path[0] == "/"
27
+ path
28
+ end
111
29
 
112
- output.each do |key, val|
113
- output[key] = File.expand_path File.join(options[:project_root], val)
114
- end
30
+ def overwrite_file(file, content = "")
31
+ File.open(file, "w") { |f| f.write(content) }
32
+ say_changed :update, [ file ]
33
+ end
115
34
 
116
- output[:css] ||= output[:fonts]
117
- output[:preview] ||= output[:fonts]
118
- output
119
- else
120
- if options[:output].is_a? String
121
- output = File.expand_path File.join(options[:project_root], options[:output])
122
- raise Fontcustom::Error, "OUTPUT should be a directory, not a file. Check #{output} and try again." if File.exists?(output) && ! File.directory?(output)
123
- else
124
- # TODO friendly warning that we're defaulting to pwd/:font_name
125
- output = File.join options[:project_root], options[:font_name]
126
- end
127
- Thor::CoreExt::HashWithIndifferentAccess.new({
128
- :fonts => output,
129
- :css => output,
130
- :preview => output
131
- })
132
- end
133
- end
35
+ private
134
36
 
135
- # Translates shorthand to full path of packages templates, otherwise,
136
- # it checks input and pwd for the template.
137
- #
138
- # Could arguably belong in Generator::Template, however, it's nice to
139
- # be able to catch template errors before any generator runs.
140
- def get_templates(options)
141
- # ensure that preview has plain stylesheet to reference
142
- options[:templates] << "css" if options[:templates].include?("preview") && ! options[:templates].include?("css")
37
+ def base(sym)
38
+ # Generators have @opts
39
+ if @opts
40
+ @opts.send sym
143
41
 
144
- options[:templates].map do |template|
145
- case template
146
- when "preview"
147
- File.join gem_lib_path, "templates", "fontcustom-preview.html"
148
- when "css"
149
- File.join gem_lib_path, "templates", "fontcustom.css"
150
- when "scss"
151
- File.join gem_lib_path, "templates", "_fontcustom.scss"
152
- when "bootstrap"
153
- File.join gem_lib_path, "templates", "fontcustom-bootstrap.css"
154
- when "bootstrap-scss"
155
- File.join gem_lib_path, "templates", "_fontcustom-bootstrap.scss"
156
- when "bootstrap-ie7"
157
- File.join gem_lib_path, "templates", "fontcustom-bootstrap-ie7.css"
158
- when "bootstrap-ie7-scss"
159
- File.join gem_lib_path, "templates", "_fontcustom-bootstrap-ie7.scss"
160
- else
161
- path = File.join options[:input][:templates], template
162
- raise Fontcustom::Error, "We couldn't find your custom template at #{path}. Double check and try again?" unless File.exists? path
163
- path
164
- end
165
- end
166
- end
42
+ # Options (before merge) uses @cli_options
43
+ elsif @cli_options
44
+ @cli_options[sym]
167
45
 
168
- def gem_lib_path
169
- File.expand_path(File.join(File.dirname(__FILE__)))
46
+ # Options (after merge) has its own methods
47
+ else
48
+ send sym
170
49
  end
171
50
  end
172
51
  end