gkh-fontcustom 1.3.7

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