gkh-fontcustom 1.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +20 -0
  4. data/CHANGELOG.md +137 -0
  5. data/CONTRIBUTING.md +50 -0
  6. data/Gemfile +4 -0
  7. data/LICENSES.txt +60 -0
  8. data/README.md +112 -0
  9. data/Rakefile +8 -0
  10. data/bin/fontcustom +5 -0
  11. data/fontcustom.gemspec +28 -0
  12. data/gemfiles/Gemfile.listen_1 +6 -0
  13. data/lib/fontcustom.rb +43 -0
  14. data/lib/fontcustom/base.rb +54 -0
  15. data/lib/fontcustom/cli.rb +110 -0
  16. data/lib/fontcustom/error.rb +4 -0
  17. data/lib/fontcustom/generator/font.rb +109 -0
  18. data/lib/fontcustom/generator/template.rb +222 -0
  19. data/lib/fontcustom/manifest.rb +75 -0
  20. data/lib/fontcustom/options.rb +192 -0
  21. data/lib/fontcustom/scripts/eotlitetool.py +466 -0
  22. data/lib/fontcustom/scripts/generate.py +128 -0
  23. data/lib/fontcustom/scripts/sfnt2woff +0 -0
  24. data/lib/fontcustom/templates/_fontcustom-rails.scss +14 -0
  25. data/lib/fontcustom/templates/_fontcustom.scss +16 -0
  26. data/lib/fontcustom/templates/fontcustom-preview.html +174 -0
  27. data/lib/fontcustom/templates/fontcustom.css +14 -0
  28. data/lib/fontcustom/templates/fontcustom.yml +96 -0
  29. data/lib/fontcustom/utility.rb +117 -0
  30. data/lib/fontcustom/version.rb +3 -0
  31. data/lib/fontcustom/watcher.rb +90 -0
  32. data/spec/fixtures/example/_example-rails.scss +50 -0
  33. data/spec/fixtures/example/example-preview.html +253 -0
  34. data/spec/fixtures/example/example.css +50 -0
  35. data/spec/fixtures/example/example.eot +0 -0
  36. data/spec/fixtures/example/example.svg +75 -0
  37. data/spec/fixtures/example/example.ttf +0 -0
  38. data/spec/fixtures/example/example.woff +0 -0
  39. data/spec/fixtures/generators/.fontcustom-manifest-corrupted.json +25 -0
  40. data/spec/fixtures/generators/.fontcustom-manifest-empty.json +0 -0
  41. data/spec/fixtures/generators/.fontcustom-manifest.json +52 -0
  42. data/spec/fixtures/generators/fontcustom.yml +1 -0
  43. data/spec/fixtures/generators/mixed-output/another-font.ttf +0 -0
  44. data/spec/fixtures/generators/mixed-output/dont-delete-me.bro +0 -0
  45. data/spec/fixtures/generators/mixed-output/fontcustom.css +108 -0
  46. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.eot +0 -0
  47. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.svg +56 -0
  48. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.ttf +0 -0
  49. data/spec/fixtures/generators/mixed-output/fontcustom_82a59e769bc60192484f2620570bbb59.woff +0 -0
  50. data/spec/fixtures/options/any-file-name.yml +1 -0
  51. data/spec/fixtures/options/config-is-in-dir/fontcustom.yml +1 -0
  52. data/spec/fixtures/options/fontcustom-empty.yml +1 -0
  53. data/spec/fixtures/options/fontcustom-malformed.yml +1 -0
  54. data/spec/fixtures/options/fontcustom.yml +1 -0
  55. data/spec/fixtures/options/no-config-here/.gitkeep +0 -0
  56. data/spec/fixtures/options/rails-like/config/fontcustom.yml +1 -0
  57. data/spec/fixtures/shared/not-a-dir +0 -0
  58. data/spec/fixtures/shared/templates/custom.css +4 -0
  59. data/spec/fixtures/shared/templates/regular.css +4 -0
  60. data/spec/fixtures/shared/vectors-empty/no_vectors_here.txt +0 -0
  61. data/spec/fixtures/shared/vectors/C.svg +14 -0
  62. data/spec/fixtures/shared/vectors/D.svg +15 -0
  63. data/spec/fixtures/shared/vectors/a_R3ally-eXotic f1Le Name.svg +6 -0
  64. data/spec/fontcustom/base_spec.rb +45 -0
  65. data/spec/fontcustom/cli_spec.rb +30 -0
  66. data/spec/fontcustom/generator/font_spec.rb +72 -0
  67. data/spec/fontcustom/generator/template_spec.rb +99 -0
  68. data/spec/fontcustom/manifest_spec.rb +17 -0
  69. data/spec/fontcustom/options_spec.rb +315 -0
  70. data/spec/fontcustom/utility_spec.rb +82 -0
  71. data/spec/fontcustom/watcher_spec.rb +121 -0
  72. data/spec/spec_helper.rb +103 -0
  73. metadata +252 -0
@@ -0,0 +1,128 @@
1
+ import fontforge
2
+ import os
3
+ import subprocess
4
+ import tempfile
5
+ import json
6
+
7
+ #
8
+ # Manifest / Options
9
+ # Older Pythons don't have argparse, so we use optparse instead
10
+ #
11
+
12
+ try:
13
+ import argparse
14
+ parser = argparse.ArgumentParser()
15
+ parser.add_argument('manifest', help='Path to .fontcustom-manifest.json')
16
+ args = parser.parse_args()
17
+ manifestfile = open(args.manifest, 'r+')
18
+ except ImportError:
19
+ import optparse
20
+ parser = optparse.OptionParser()
21
+ (nothing, args) = parser.parse_args()
22
+ manifestfile = open(args[0], 'r+')
23
+
24
+ manifest = json.load(manifestfile)
25
+ options = manifest['options']
26
+
27
+ #
28
+ # Font
29
+ #
30
+
31
+ design_px = options['font_em'] / options['font_design_size']
32
+
33
+ font = fontforge.font()
34
+ font.encoding = 'UnicodeFull'
35
+ font.design_size = options['font_design_size']
36
+ font.em = options['font_em']
37
+ font.ascent = options['font_ascent']
38
+ font.descent = options['font_descent']
39
+ font.fontname = options['font_name']
40
+ font.familyname = options['font_name']
41
+ font.fullname = options['font_name']
42
+ if options['autowidth']:
43
+ font.autoWidth(0, 0, options['font_em'])
44
+
45
+ #
46
+ # Glyphs
47
+ #
48
+
49
+ def removeSwitchFromSvg( file ):
50
+ svgfile = open(file, 'r')
51
+ svgtext = svgfile.read()
52
+ svgfile.close()
53
+ tmpsvgfile = tempfile.NamedTemporaryFile(suffix=".svg", delete=False)
54
+ svgtext = svgtext.replace('<switch>', '')
55
+ svgtext = svgtext.replace('</switch>', '')
56
+ tmpsvgfile.file.write(svgtext)
57
+ tmpsvgfile.file.close()
58
+
59
+ return tmpsvgfile.name
60
+
61
+ def createGlyph( name, source, code ):
62
+ frag, ext = os.path.splitext(source)
63
+
64
+ if ext == '.svg':
65
+ temp = removeSwitchFromSvg(source)
66
+ glyph = font.createChar(code)
67
+ glyph.importOutlines(temp)
68
+ os.unlink(temp)
69
+
70
+ if options['autowidth']:
71
+ glyph.left_side_bearing = glyph.right_side_bearing = 0
72
+ glyph.round()
73
+ else:
74
+ glyph.width = options['font_em']
75
+ width = glyph.width - glyph.left_side_bearing - glyph.right_side_bearing
76
+ aligned_to_pixel_grid = (width % design_px == 0)
77
+ if (aligned_to_pixel_grid):
78
+ shift = glyph.left_side_bearing % design_px
79
+ glyph.left_side_bearing = glyph.left_side_bearing - shift
80
+ glyph.right_side_bearing = glyph.right_side_bearing + shift
81
+
82
+ for glyph, data in manifest['glyphs'].iteritems():
83
+ name = createGlyph(glyph, data['source'], data['codepoint'])
84
+
85
+ #
86
+ # Generate Files
87
+ #
88
+
89
+ try:
90
+ fontfile = options['output']['fonts'] + '/' + options['font_name']
91
+ if not options['no_hash']:
92
+ fontfile += '_' + manifest['checksum']['current'][:32]
93
+
94
+ # Generate TTF and SVG
95
+ font.generate(fontfile + '.ttf')
96
+ font.generate(fontfile + '.svg')
97
+ manifest['fonts'].append(fontfile + '.ttf')
98
+ manifest['fonts'].append(fontfile + '.svg')
99
+
100
+ # Fix SVG header for webkit
101
+ # from: https://github.com/fontello/font-builder/blob/master/bin/fontconvert.py
102
+ svgfile = open(fontfile + '.svg', 'r+')
103
+ svgtext = svgfile.read()
104
+ svgfile.seek(0)
105
+ svgfile.write(svgtext.replace('''<svg>''', '''<svg xmlns="http://www.w3.org/2000/svg">'''))
106
+ svgfile.close()
107
+
108
+ # Convert WOFF
109
+ scriptPath = os.path.dirname(os.path.realpath(__file__))
110
+ try:
111
+ subprocess.Popen([scriptPath + '/sfnt2woff', fontfile + '.ttf'], stdout=subprocess.PIPE)
112
+ except OSError:
113
+ # If the local version of sfnt2woff fails (i.e., on Linux), try to use the
114
+ # global version. This allows us to avoid forcing OS X users to compile
115
+ # sfnt2woff from source, simplifying install.
116
+ subprocess.call(['sfnt2woff', fontfile + '.ttf'])
117
+ manifest['fonts'].append(fontfile + '.woff')
118
+
119
+ # Convert EOT for IE7
120
+ subprocess.call('python ' + scriptPath + '/eotlitetool.py ' + fontfile + '.ttf -o ' + fontfile + '.eot', shell=True)
121
+ subprocess.call('mv ' + fontfile + '.eotlite ' + fontfile + '.eot', shell=True)
122
+ manifest['fonts'].append(fontfile + '.eot')
123
+
124
+ finally:
125
+ manifestfile.seek(0)
126
+ manifestfile.write(json.dumps(manifest, indent=2, sort_keys=True))
127
+ manifestfile.truncate()
128
+ manifestfile.close()
@@ -0,0 +1,14 @@
1
+ //
2
+ // Icon Font: <%= font_name %>
3
+ //
4
+
5
+ <%= font_face(url: "font-url", path: @font_path_alt) %>
6
+
7
+ [data-icon]:before { content: attr(data-icon); }
8
+
9
+ [data-icon]:before,
10
+ <%= glyph_selectors %> {
11
+ <%= glyph_properties %>
12
+ }
13
+
14
+ <%= glyphs %>
@@ -0,0 +1,16 @@
1
+ //
2
+ // Icon Font: <%= font_name %>
3
+ //
4
+
5
+ <%= font_face(path: @font_path_alt) %>
6
+
7
+ [data-icon]:before { content: attr(data-icon); }
8
+
9
+ [data-icon]:before,
10
+ <%= glyph_selectors %> {
11
+ <%= glyph_properties %>
12
+ }
13
+
14
+ <%= glyphs %>
15
+ <% @glyphs.each do |name, value| %>
16
+ $font-<%= font_name.gsub(/[^\w\d_]/, '-') %>-<%= name.to_s %>: "\<%= value[:codepoint].to_s(16) %>";<% end %>
@@ -0,0 +1,174 @@
1
+ <% scale = %w|12 14 16 18 21 24 36 48 60 72| %><!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= font_name %> glyphs preview</title>
5
+
6
+ <style>
7
+ /* Page Styles */
8
+
9
+ * {
10
+ -moz-box-sizing: border-box;
11
+ -webkit-box-sizing: border-box;
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ body {
18
+ background: #fff;
19
+ color: #444;
20
+ font: 16px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
21
+ }
22
+
23
+ a,
24
+ a:visited {
25
+ color: #888;
26
+ text-decoration: underline;
27
+ }
28
+ a:hover,
29
+ a:focus { color: #000; }
30
+
31
+ header {
32
+ border-bottom: 2px solid #ddd;
33
+ margin-bottom: 20px;
34
+ overflow: hidden;
35
+ padding: 20px 0;
36
+ }
37
+
38
+ header h1 {
39
+ color: #888;
40
+ float: left;
41
+ font-size: 36px;
42
+ font-weight: 300;
43
+ }
44
+
45
+ header a {
46
+ float: right;
47
+ font-size: 14px;
48
+ }
49
+
50
+ .container {
51
+ margin: 0 auto;
52
+ max-width: 1200px;
53
+ min-width: 960px;
54
+ padding: 0 40px;
55
+ width: 90%;
56
+ }
57
+
58
+ .glyph {
59
+ border-bottom: 1px dotted #ccc;
60
+ padding: 10px 0 20px;
61
+ margin-bottom: 20px;
62
+ }
63
+
64
+ .preview-glyphs { vertical-align: bottom; }
65
+
66
+ .preview-scale {
67
+ color: #888;
68
+ font-size: 12px;
69
+ margin-top: 5px;
70
+ }
71
+
72
+ .step {
73
+ display: inline-block;
74
+ line-height: 1;
75
+ position: relative;
76
+ width: 10%;
77
+ }
78
+
79
+ .step .letters,
80
+ .step i {
81
+ -webkit-transition: opacity .3s;
82
+ -moz-transition: opacity .3s;
83
+ -ms-transition: opacity .3s;
84
+ -o-transition: opacity .3s;
85
+ transition: opacity .3s;
86
+ }
87
+
88
+ .step:hover .letters { opacity: 1; }
89
+ .step:hover i { opacity: .3; }
90
+
91
+ .letters {
92
+ opacity: .3;
93
+ position: absolute;
94
+ }
95
+
96
+ .characters-off .letters { display: none; }
97
+ .characters-off .step:hover i { opacity: 1; }
98
+
99
+ <% scale.each do |n| %>
100
+ .size-<%= n %> { font-size: <%= n %>px; }
101
+ <% end %>
102
+
103
+ .usage { margin-top: 10px; }
104
+
105
+ .usage input {
106
+ font-family: monospace;
107
+ margin-right: 3px;
108
+ padding: 2px 5px;
109
+ text-align: center;
110
+ }
111
+
112
+ .usage .point { width: 150px; }
113
+
114
+ .usage .class { width: 250px; }
115
+
116
+ footer {
117
+ color: #888;
118
+ font-size: 12px;
119
+ padding: 20px 0;
120
+ }
121
+
122
+ /* Icon Font: <%= font_name %> */
123
+
124
+ <%= font_face(path: @font_path_preview) %>
125
+
126
+ [data-icon]:before { content: attr(data-icon); }
127
+
128
+ [data-icon]:before,
129
+ <%= glyph_selectors %> {
130
+ <%= glyph_properties %>
131
+ }
132
+
133
+ <%= glyphs %>
134
+ </style>
135
+
136
+ <!--[if lte IE 8]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
137
+
138
+ <script>
139
+ function toggleCharacters() {
140
+ var body = document.getElementsByTagName('body')[0];
141
+ body.className = body.className === 'characters-off' ? '' : 'characters-off';
142
+ }
143
+ </script>
144
+ </head>
145
+
146
+ <body class="characters-off">
147
+ <div id="page" class="container">
148
+ <header>
149
+ <h1><%= font_name %> contains <%= @glyphs.length %> glyphs:</h1>
150
+ <a onclick="toggleCharacters(); return false;" href="#">Toggle Preview Characters</a>
151
+ </header>
152
+
153
+ <% @glyphs.each do |name, value|
154
+ selector = @options[:css_selector].sub('{{glyph}}', name.to_s) %>
155
+ <div class="glyph">
156
+ <div class="preview-glyphs">
157
+ <% scale.each do |n| %><span class="step size-<%= n %>"><span class="letters">Pp</span><i id="<%= selector[1..-1] %>" class="<%= selector[1..-1].gsub('.', ' ') %>"></i></span><% end %>
158
+ </div>
159
+ <div class="preview-scale">
160
+ <% scale.each do |n| %><span class="step"><%= n %></span><% end %>
161
+ </div>
162
+ <div class="usage">
163
+ <input class="class" type="text" readonly="readonly" onClick="this.select();" value="<%= selector %>" />
164
+ <input class="point" type="text" readonly="readonly" onClick="this.select();" value="&amp;#x<%= value[:codepoint].to_s(16) %>;" />
165
+ </div>
166
+ </div>
167
+ <% end %>
168
+
169
+ <footer>
170
+ Made with love using <a href="http://fontcustom.com">Font Custom</a>.
171
+ </footer>
172
+ </div>
173
+ </body>
174
+ </html>
@@ -0,0 +1,14 @@
1
+ /*
2
+ Icon Font: <%= font_name %>
3
+ */
4
+
5
+ <%= font_face %>
6
+
7
+ [data-icon]:before { content: attr(data-icon); }
8
+
9
+ [data-icon]:before,
10
+ <%= glyph_selectors %> {
11
+ <%= glyph_properties %>
12
+ }
13
+
14
+ <%= glyphs %>
@@ -0,0 +1,96 @@
1
+ # =============================================================================
2
+ # Font Custom Configuration
3
+ # This file should live in the directory where you run `fontcustom compile`.
4
+ # For more info, visit <https://github.com/FontCustom/fontcustom>.
5
+ # =============================================================================
6
+
7
+
8
+ # -----------------------------------------------------------------------------
9
+ # Project Info
10
+ # -----------------------------------------------------------------------------
11
+
12
+ # The font's name. Also determines the file names of generated templates.
13
+ #font_name: icons
14
+
15
+ # Format of CSS selectors. {{glyph}} is substituted for the glyph name.
16
+ #css_selector: .i-{{glyph}}
17
+
18
+ # Generate fonts without asset-busting hashes.
19
+ #no_hash: true
20
+
21
+ # Encode WOFF fonts into the generated CSS.
22
+ #base64: true
23
+
24
+ # Forces compilation, even if inputs have not changed
25
+ #force: true
26
+
27
+ # Display (possibly useful) debugging messages.
28
+ #debug: true
29
+
30
+ # Hide status messages.
31
+ #quiet: true
32
+
33
+
34
+ # -----------------------------------------------------------------------------
35
+ # Input / Output Locations
36
+ # You can save generated fonts, CSS, and other files to different locations
37
+ # here. Font Custom can also read input vectors and templates from different
38
+ # places.
39
+ #
40
+ # NOTE:
41
+ # - Be sure to preserve the whitespace in these YAML hashes.
42
+ # - INPUT[:vectors] and OUTPUT[:fonts] are required. Everything else is
43
+ # optional.
44
+ # - Specify output locations for custom templates by including their file
45
+ # names as the key.
46
+ # -----------------------------------------------------------------------------
47
+
48
+ #input:
49
+ # vectors: my/vectors
50
+ # templates: my/templates
51
+
52
+ #output:
53
+ # fonts: app/assets/fonts
54
+ # css: app/assets/stylesheets
55
+ # preview: app/views/styleguide
56
+ # my-custom-template.yml: path/to/template/output
57
+
58
+
59
+ # -----------------------------------------------------------------------------
60
+ # Templates
61
+ # A YAML array of templates and files to generate alongside fonts. Custom
62
+ # templates should be saved in the INPUT[:templates] directory and referenced
63
+ # by their base file name.
64
+ #
65
+ # For Rails and Compass templates, set `preprocessor_path` as the relative
66
+ # path from OUTPUT[:css] to OUTPUT[:fonts]. By default, these are the same
67
+ # directory.
68
+ #
69
+ # Included in Font Custom: preview, css, scss, scss-rails
70
+ # Default: css, preview
71
+ # -----------------------------------------------------------------------------
72
+
73
+ #templates:
74
+ #- scss-rails
75
+ #- preview
76
+ #- my-custom-template.yml
77
+
78
+ #preprocessor_path: ../fonts/
79
+
80
+
81
+ # -----------------------------------------------------------------------------
82
+ # Font Settings (defaults shown)
83
+ # -----------------------------------------------------------------------------
84
+
85
+ # Size (in pica points) for which your font is designed.
86
+ #font_design_size: 16
87
+
88
+ # The em size. Setting this will scale the entire font to the given size.
89
+ #font_em: 512
90
+
91
+ # The font's descent and descent. Used to calculate the baseline.
92
+ #font_ascent: 448
93
+ #font_descent: 64
94
+
95
+ # Horizontally fit glyphs to their individual vector widths.
96
+ #autowidth: false