marmot 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/LICENSE +8 -0
- data/README.md +97 -0
- data/bin/marmot +120 -0
- data/doc/js-snippet.js +5 -0
- data/doc/js-snippet.png +0 -0
- data/lib/marmot/client.rb +230 -0
- data/lib/marmot/options_sanitizer.rb +97 -0
- data/lib/marmot/version.rb +3 -0
- data/lib/marmot.rb +7 -0
- data/marmot.gemspec +23 -0
- data/spec/client_spec.rb +31 -0
- data/spec/options_sanitizer_spec.rb +72 -0
- data/spec/test-files/Averia/Averia-Regular.ttf +0 -0
- data/spec/test-files/Averia/FONTLOG.txt +67 -0
- data/spec/test-files/Averia/OFL-FAQ.txt +369 -0
- data/spec/test-files/Averia/OFL.txt +94 -0
- data/spec/test-files/generator_config.txt +5 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7d63183e8ca618db1c3f5535b9694aecf03817ca
|
4
|
+
data.tar.gz: ef58b0b863574c9c726464e5d956d26d695fe4f6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aa524f16170c0bb2d8bf02e23176c6a2be79bbb30eed21d1583e256c2baa52f173ba0a56b0cef7f6970be7bac1633b136d9e7638dc18df0b6df3e73ef5289c66
|
7
|
+
data.tar.gz: 97de6003b10518817cf24ef71cae79e5cb0bc07806e962bbd3308c7c7b92fb72bee37965cdac0934ef9649bc74cf9cec3503413d0202888fa42209529e6a1f4c
|
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Copyright (c) 2013 Dmitry Filimonov
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
8
|
+
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Marmot — Unofficial [FontSquirrel Webfont Generator](https://github.com/petethepig/) Client
|
2
|
+
|
3
|
+
Marmot automates font-face generation, making it easier and faster:
|
4
|
+
|
5
|
+
marmot Averia-Regular.ttf # ls . => webfontkit.zip
|
6
|
+
|
7
|
+
Marmot supports FontSquirrel configuration files:
|
8
|
+
|
9
|
+
marmot -c generator-config.txt font.otf
|
10
|
+
|
11
|
+
It is especially useful when it comes to your own icon fonts:
|
12
|
+
|
13
|
+
marmot -c config.txt my-icon-font.otf my-icon-font.zip
|
14
|
+
|
15
|
+
###Great, how do I install Marmot?
|
16
|
+
|
17
|
+
Marmot is a ruby gem:
|
18
|
+
|
19
|
+
gem install marmot
|
20
|
+
|
21
|
+
###Okay, how do I configure it?
|
22
|
+
|
23
|
+
FontSquirrel Webfont Generator has **a lot of** options and by default Marmot will use default ones.
|
24
|
+
|
25
|
+
Every FontSquirrel webfont kit comes with a text file called **generator_config.txt**. Marmot can read it:
|
26
|
+
|
27
|
+
marmot -c generator-config.txt font.otf
|
28
|
+
|
29
|
+
Since the config is actually just a JSON file, you can write your own configs. I use this one for my icons:
|
30
|
+
```json
|
31
|
+
{
|
32
|
+
"formats":["ttf", "woff", "svg"],
|
33
|
+
"fallback":"none",
|
34
|
+
"subset_custom_range":"E000-F8FF",
|
35
|
+
"emsquare":"1000"
|
36
|
+
}
|
37
|
+
```
|
38
|
+
|
39
|
+
You can do the same thing from the command line:
|
40
|
+
|
41
|
+
marmot --no-add-hyphens --formats=ttf,woff font.otf
|
42
|
+
|
43
|
+
Here is a full list of options:
|
44
|
+
|
45
|
+
```bash
|
46
|
+
--mode <s>
|
47
|
+
--formats <s>
|
48
|
+
--tt-instructor <s>
|
49
|
+
--fix-vertical-metrics
|
50
|
+
--fix-gasp
|
51
|
+
--remove-kerning
|
52
|
+
--add-spaces
|
53
|
+
--add-hyphens
|
54
|
+
--fallback <s>
|
55
|
+
--fallback-custom <i>
|
56
|
+
--webonly
|
57
|
+
--options-subset <s>
|
58
|
+
--subset-range <s>
|
59
|
+
--subset-custom <s>
|
60
|
+
--subset-custom-range <s>
|
61
|
+
--base64
|
62
|
+
--style-link
|
63
|
+
--css-stylesheet <s>
|
64
|
+
--ot-features <s>
|
65
|
+
--filename-suffix <s>
|
66
|
+
--emsquare <i>
|
67
|
+
--spacing-adjustment <i>
|
68
|
+
--agreement
|
69
|
+
```
|
70
|
+
|
71
|
+
###Oh, this is great, but what is "tt-instuctor" or "subset-custom"?
|
72
|
+
|
73
|
+
Some option names can be confusing. Go to [generator's page](http://www.fontsquirrel.com/tools/webfont-generator) and run this in the console:
|
74
|
+
|
75
|
+
```js
|
76
|
+
$("input[value='expert'], input[value='advanced']").click();
|
77
|
+
$("table input").each(function(){
|
78
|
+
$(this).after($("<div style='color:red;'>"+$(this).attr("name")+" : "+$(this).attr("value")+"</div>"));
|
79
|
+
});
|
80
|
+
```
|
81
|
+
|
82
|
+
###What else?
|
83
|
+
Since Marmot is a ruby gem, you can use it in your ruby projects:
|
84
|
+
```ruby
|
85
|
+
require 'marmot'
|
86
|
+
|
87
|
+
client = Marmot::Client.new
|
88
|
+
client.convert File.new("font.ttf"), {
|
89
|
+
formats: ["ttf", "woff"]
|
90
|
+
}
|
91
|
+
```
|
92
|
+
|
93
|
+
###I found a lousy bug, what do I do?
|
94
|
+
|
95
|
+
Marmot is only a couple days old, so this can happen. Please, report on the [Issues page](https://github.com/petethepig/marmot/issues).
|
96
|
+
|
97
|
+
Or [contact me on Twitter](https://twitter.com/dmi3f)
|
data/bin/marmot
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'trollop'
|
3
|
+
require 'marmot'
|
4
|
+
|
5
|
+
#Delegator pattern
|
6
|
+
class CustomLogger < Logger
|
7
|
+
extend Forwardable
|
8
|
+
attr_accessor :stderr_logger
|
9
|
+
def_delegators :@stderr_logger, :fatal, :error
|
10
|
+
|
11
|
+
def initialize logdev, shift_age = 0, shift_size = 1048576
|
12
|
+
super logdev, shift_age, shift_size
|
13
|
+
@stderr_logger = Logger.new STDERR, shift_age, shift_size
|
14
|
+
@stderr_logger.formatter = self.formatter = proc do |severity, datetime, progname, msg|
|
15
|
+
"#{msg}\n"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class Marmot::CLI
|
22
|
+
|
23
|
+
BANNER = <<-EOF
|
24
|
+
Usage: marmot [options] input [output]
|
25
|
+
|
26
|
+
Description:
|
27
|
+
Convert font files to a webfont kit using FontSquirrel Webfont Generator
|
28
|
+
|
29
|
+
Example:
|
30
|
+
marmot -v font.ttf
|
31
|
+
marmot font.ttf archive.zip
|
32
|
+
marmot -c config.txt font.ttf
|
33
|
+
marmot --formats=ttf,woff font.ttf
|
34
|
+
marmot --add-spaces --no-add-hyphens font.ttf
|
35
|
+
|
36
|
+
Options:
|
37
|
+
EOF
|
38
|
+
|
39
|
+
MAPPING = {
|
40
|
+
:array => :string,
|
41
|
+
:radio => :string,
|
42
|
+
:string => :string,
|
43
|
+
:number => :int,
|
44
|
+
:checkbox => :flag
|
45
|
+
}
|
46
|
+
|
47
|
+
def bail str=""
|
48
|
+
Trollop::die str.to_s
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
|
52
|
+
def start
|
53
|
+
options = Trollop::options do
|
54
|
+
version "Marmot #{Marmot::VERSION} (c) 2013 Dmitry Filimonov https://github.com/petethepig/marmot"
|
55
|
+
banner BANNER
|
56
|
+
opt :verbose, 'Enable verbose mode', short: 'v', type: :flag
|
57
|
+
opt :debug, 'Enable debug mode', short: 'd', type: :flag
|
58
|
+
opt :config, 'Config file', short: 'c', type: :io
|
59
|
+
opt :output, 'Output file', short: 'o', type: :io
|
60
|
+
|
61
|
+
Marmot::OptionsSanitizer::OPTIONS.each_pair do |key, value|
|
62
|
+
type = MAPPING[value[0]]
|
63
|
+
opt key, key.to_s, type: type, short: :none unless key==:id
|
64
|
+
end
|
65
|
+
end.to_h
|
66
|
+
|
67
|
+
options.delete_if do |k,v|
|
68
|
+
!options["#{k}_given".to_sym]
|
69
|
+
end
|
70
|
+
|
71
|
+
#logger
|
72
|
+
logger = CustomLogger.new(STDOUT)
|
73
|
+
logger.sev_threshold = if options[:debug]
|
74
|
+
Logger::DEBUG
|
75
|
+
elsif options[:verbose]
|
76
|
+
Logger::INFO
|
77
|
+
else
|
78
|
+
Logger::ERROR
|
79
|
+
end
|
80
|
+
|
81
|
+
logger.debug "Command line options:\n#{options.collect{|k,v| "#{k}: #{v.inspect}" }.join("\n")}"
|
82
|
+
|
83
|
+
#files
|
84
|
+
input_file_path = ARGV.first
|
85
|
+
output_file_path = options.delete(:output)
|
86
|
+
output_file_path ||= ARGV.last if ARGV.first != ARGV.last
|
87
|
+
config_file_path = options.delete :config
|
88
|
+
|
89
|
+
if !input_file_path
|
90
|
+
bail "Error: option 'input' is missing."
|
91
|
+
end
|
92
|
+
|
93
|
+
begin
|
94
|
+
input_file = File.new(input_file_path)
|
95
|
+
output_file = File.new(output_file_path,"wb") if output_file_path
|
96
|
+
config_file = File.new(config_file_path) if config_file_path
|
97
|
+
rescue StandardError => e
|
98
|
+
bail e.message
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
if(config_file)
|
103
|
+
options = JSON.parse(config_file.read.gsub /^#.*$/, '').merge options
|
104
|
+
end
|
105
|
+
if(output_file)
|
106
|
+
options[:output_io] = output_file
|
107
|
+
end
|
108
|
+
|
109
|
+
#finally, convert the font
|
110
|
+
begin
|
111
|
+
client = Marmot::Client.new
|
112
|
+
client.logger = logger
|
113
|
+
client.convert input_file, options
|
114
|
+
rescue Marmot::MarmotError => e
|
115
|
+
bail e.message
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
Marmot::CLI.new.start
|
data/doc/js-snippet.js
ADDED
data/doc/js-snippet.png
ADDED
Binary file
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'httmultiparty'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Marmot
|
6
|
+
class Client
|
7
|
+
include HTTMultiParty
|
8
|
+
|
9
|
+
base_uri 'www.fontsquirrel.com'
|
10
|
+
attr_accessor :logger
|
11
|
+
attr_reader :params
|
12
|
+
@@headers_set = false
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
logger = Logger.new("/dev/null")
|
16
|
+
logger.close
|
17
|
+
end
|
18
|
+
|
19
|
+
# Convert a font file to a webfont kit
|
20
|
+
#
|
21
|
+
# @param [String] input_io Input IO. Examples: File.new("font.ttf"), STDOUT
|
22
|
+
#
|
23
|
+
# @param [Hash] options Options
|
24
|
+
#
|
25
|
+
# @option options
|
26
|
+
# [String] :output_io
|
27
|
+
# Output IO
|
28
|
+
# Default is a File with the name like "webfontkit-20130312-200144.zip"
|
29
|
+
#
|
30
|
+
# @option options
|
31
|
+
# [IO] :output_stream
|
32
|
+
# Custom output stream, like STDOUT
|
33
|
+
#
|
34
|
+
# @option options
|
35
|
+
# [Hash] :custom_options
|
36
|
+
# Options that will bypass sanitization. Make sure you know what you do before trying it out.
|
37
|
+
#
|
38
|
+
# @option options [Array or String] :formats
|
39
|
+
# Allowed values are: "ttf", "woff", "svg", "eotz", "eot". Default is ["ttf","woff","svg","eotz"]
|
40
|
+
#
|
41
|
+
# @option options
|
42
|
+
# [String] :mode
|
43
|
+
# Generator mode: "optimal", "basic", "expert". Default is "optimal"
|
44
|
+
#
|
45
|
+
# @option options
|
46
|
+
# [String] :tt_instructor
|
47
|
+
# Truetype hinting: "default", "keep"
|
48
|
+
#
|
49
|
+
# @option options
|
50
|
+
# [Boolean] :fix_vertical_metrics
|
51
|
+
# Rendering option. Fix Vertical Metrics (Normalize across browsers). Default is true
|
52
|
+
#
|
53
|
+
# @option options
|
54
|
+
# [Boolean] :fix_gasp
|
55
|
+
# Rendering option. Fix GASP Table (Better DirectWrite Rendering). Default is true
|
56
|
+
#
|
57
|
+
# @option options
|
58
|
+
# [Boolean] :remove_kerning
|
59
|
+
# Rendering option. Remove Kerning (Strip kerning data). Default is false
|
60
|
+
#
|
61
|
+
# @option options
|
62
|
+
# [Boolean] :add_spaces
|
63
|
+
# Fix missing glyphs option. Fix spaces. Default is true
|
64
|
+
#
|
65
|
+
# @option options
|
66
|
+
# [Boolean] :add_hyphens
|
67
|
+
# Fix missing glyphs option. Fix hyphens. Default is true
|
68
|
+
#
|
69
|
+
# @option options
|
70
|
+
# [String] :fallback
|
71
|
+
# X-height matching: "none", "arial", "verdana", "trebuchet", "georgia", "times", "courier", "custom"
|
72
|
+
#
|
73
|
+
# @option options
|
74
|
+
# [String] :fallback_custom
|
75
|
+
# Custom x-height matching, in percents. Default is "100%". Only applies when :fallback is "custom"
|
76
|
+
#
|
77
|
+
# @option options
|
78
|
+
# [Boolean] :webonly
|
79
|
+
# Disable desktop use. Default is false
|
80
|
+
#
|
81
|
+
# @option options
|
82
|
+
# [String] :options_subset
|
83
|
+
# Subsetting options: "basic", "advanced", "none". Default is "basic"
|
84
|
+
#
|
85
|
+
# @option options
|
86
|
+
# [Array] :subset_range
|
87
|
+
# Custom subsetting options. Only applies when :options_subset is "advanced".
|
88
|
+
# Allowed values are: "macroman", "lowercase", "uppercase", "numbers", "punctuation", "currency",
|
89
|
+
# "typographics", "math", "altpunctuation", "accentedlower", "accentedupper", "diacriticals",
|
90
|
+
# "albanian", "bosnian", "catalan", "croatian", "cyrillic", "czech", "danish", "dutch", "english",
|
91
|
+
# "esperanto", "estonian", "faroese", "french", "german", "greek", "hebrew", "hungarian", "icelandic",
|
92
|
+
# "italian", "latvian", "lithuanian", "malagasy", "maltese", "norwegian", "polish", "portuguese",
|
93
|
+
# "romanian", "serbian", "slovak", "slovenian", "spanish", "swedish", "turkish", "ubasic", "ulatin1",
|
94
|
+
# "ucurrency", "upunctuation", "ulatina", "ulatinb", "ulatinaddl"
|
95
|
+
#
|
96
|
+
# @option options
|
97
|
+
# [String] :subset_custom
|
98
|
+
# Single characters. Only applies when :options_subset is "advanced". Default is ""
|
99
|
+
#
|
100
|
+
# @option options
|
101
|
+
# [String] :subset_custom_range
|
102
|
+
# Unicode Ranges. Only applies when :options_subset is "advanced".
|
103
|
+
# Comma separated values. Can be single hex values and/or ranges separated with hyphens.
|
104
|
+
# Example: "0021-007E,00E7,00EB,00C7,00CB"
|
105
|
+
#
|
106
|
+
# @option options
|
107
|
+
# [Boolean] :base64
|
108
|
+
# CSS option. Base64 encode (Embed font in CSS). Default is false
|
109
|
+
#
|
110
|
+
# @option options
|
111
|
+
# [Boolean] :style_link
|
112
|
+
# CSS option. Style link (Family support in CSS). Default is false
|
113
|
+
#
|
114
|
+
# @option options
|
115
|
+
# [String] :css_stylesheet
|
116
|
+
# CSS Filename. Default is "stylesheet.css"
|
117
|
+
#
|
118
|
+
# @option options
|
119
|
+
# [String] :ot_features
|
120
|
+
# OpenType Options. If the features are available, the generator will fold them into the font.
|
121
|
+
# Allowed values: "onum", "lnum", "tnum", "pnum", "zero", "ss01", "ss02", "ss03", "ss04", "ss05"
|
122
|
+
#
|
123
|
+
# @option options
|
124
|
+
# [String] :filename_suffix
|
125
|
+
# Filename suffix. Default is "-webfont"
|
126
|
+
#
|
127
|
+
# @option options
|
128
|
+
# [String] :emsquare
|
129
|
+
# Em Square Value. In units of the em square. Default is 2048
|
130
|
+
#
|
131
|
+
# @option options
|
132
|
+
# [String] :spacing_adjustment
|
133
|
+
# Adjust Glyph Spacing. In units of the em square. Default is 0
|
134
|
+
#
|
135
|
+
# @option options
|
136
|
+
# [Boolean] :agreement
|
137
|
+
# Agreement option. The fonts You're uploading are legally eligible for web embedding. Default is true.
|
138
|
+
#
|
139
|
+
# @see http://www.fontsquirrel.com/tools/webfont-generator more info about parameters @ www.fontsquirrel.com
|
140
|
+
# @return [String]
|
141
|
+
def convert input_io, options={}
|
142
|
+
@exception = nil
|
143
|
+
#1
|
144
|
+
iam "Retrieving cookies... ", false do
|
145
|
+
response = self.class.get '/tools/webfont-generator'
|
146
|
+
@cookies = (response.headers.get_fields("Set-Cookie") || []).join(";")
|
147
|
+
fail "Failed to retrieve cookies" if @cookies.empty?
|
148
|
+
self.class.headers({"Cookie" => @cookies})
|
149
|
+
@@headers_set = true
|
150
|
+
response
|
151
|
+
end unless @@headers_set
|
152
|
+
|
153
|
+
#2
|
154
|
+
iam "Uploading font... " do
|
155
|
+
response = self.class.post '/uploadify/fontfacegen_uploadify.php', :query => {
|
156
|
+
"Filedata" => File.new(input_io)
|
157
|
+
}
|
158
|
+
@path_data = response.body
|
159
|
+
@id, @original_filename = @path_data.split("|")
|
160
|
+
fail "Failed to upload the file. Is it a valid font?" if @id.nil? || @original_filename.nil?
|
161
|
+
response
|
162
|
+
end
|
163
|
+
|
164
|
+
#3
|
165
|
+
iam "Confirming upload... " do
|
166
|
+
response = self.class.post "/tools/insert", :query => {
|
167
|
+
"original_filename" => @original_filename,
|
168
|
+
"path_data" => @path_data
|
169
|
+
}
|
170
|
+
json = JSON.parse response.body
|
171
|
+
fail (json["message"] || "Failed to confirm the upload. Is it a valid font?") if !json["name"] || !json["id"]
|
172
|
+
response
|
173
|
+
end
|
174
|
+
|
175
|
+
#4
|
176
|
+
iam "Generating webfont... " do
|
177
|
+
custom_options = options.delete :custom_options
|
178
|
+
options[:id] = @id
|
179
|
+
@params = OptionsSanitizer.sanitize(options, custom_options)
|
180
|
+
logger.debug "HTTP Params:\n#{@params.collect{|k,v| "#{k}: #{v.inspect}" }.join("\n")}"
|
181
|
+
response = self.class.post "/tools/generate", :query => @params
|
182
|
+
fail "Failed to generate webfont kit" if !response.body.empty?
|
183
|
+
response
|
184
|
+
end
|
185
|
+
|
186
|
+
#5
|
187
|
+
counter = 0
|
188
|
+
while response = self.class.get("/tools/progress/#{@id}") do
|
189
|
+
p = JSON.parse(response.body)["progress"].to_i
|
190
|
+
logger.info "Progress: #{p} "
|
191
|
+
if p == 100
|
192
|
+
break
|
193
|
+
elsif p == 0
|
194
|
+
fail "Progress timeout" if (counter += 1) > 10
|
195
|
+
end
|
196
|
+
sleep 2
|
197
|
+
end
|
198
|
+
|
199
|
+
#6
|
200
|
+
iam "Downloading fonts... ", false do
|
201
|
+
response = self.class.post "/tools/download", :query => @params
|
202
|
+
end
|
203
|
+
|
204
|
+
#7
|
205
|
+
if !options[:output_io]
|
206
|
+
filename = response.headers["Content-Disposition"].gsub(/attachment; filename=\"(.*)\"/,'\1')
|
207
|
+
options[:output_io] = File.new(filename, "wb")
|
208
|
+
end
|
209
|
+
options[:output_io] << response.response.body
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
protected
|
214
|
+
|
215
|
+
def iam desc, log_body=true
|
216
|
+
logger.info desc
|
217
|
+
response = yield
|
218
|
+
logger.info response.message
|
219
|
+
logger.debug "Response body: #{response.body}" if log_body
|
220
|
+
if @exception
|
221
|
+
raise @exception
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def fail str
|
226
|
+
@exception = MarmotError.new str
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Marmot
|
2
|
+
class OptionsSanitizer
|
3
|
+
OPTIONS = {
|
4
|
+
:id => [:string, ""],
|
5
|
+
:mode => [:radio, "optimal", "basic", "expert"],
|
6
|
+
:formats => [:array, "ttf", "woff", "svg", "eotz", "eot"],
|
7
|
+
:tt_instructor => [:radio, "default", "keep"],
|
8
|
+
:fix_vertical_metrics => [:checkbox, "Y"],
|
9
|
+
:fix_gasp => [:checkbox, "xy"],
|
10
|
+
:remove_kerning => [:checkbox, nil, "Y"],
|
11
|
+
:add_spaces => [:checkbox, "Y"],
|
12
|
+
:add_hyphens => [:checkbox, "Y"],
|
13
|
+
:fallback => [:radio, "none", "arial", "verdana", "trebuchet", "georgia", "times", "courier", "custom"],
|
14
|
+
:fallback_custom => [:number, 100],
|
15
|
+
:webonly => [:checkbox, nil, "Y"],
|
16
|
+
:options_subset => [:radio, "basic", "advanced", "none"],
|
17
|
+
:subset_range => [:array, "macroman", "lowercase", "uppercase", "numbers", "punctuation", "currency",
|
18
|
+
"typographics", "math", "altpunctuation", "accentedlower", "accentedupper",
|
19
|
+
"diacriticals", "albanian", "bosnian", "catalan", "croatian", "cyrillic",
|
20
|
+
"czech", "danish", "dutch", "english", "esperanto", "estonian", "faroese",
|
21
|
+
"french", "german", "greek", "hebrew", "hungarian", "icelandic", "italian",
|
22
|
+
"latvian", "lithuanian", "malagasy", "maltese", "norwegian", "polish",
|
23
|
+
"portuguese", "romanian", "serbian", "slovak", "slovenian", "spanish",
|
24
|
+
"swedish", "turkish", "ubasic", "ulatin1", "ucurrency", "upunctuation",
|
25
|
+
"ulatina", "ulatinb", "ulatinaddl"],
|
26
|
+
:subset_custom => [:string, ""],
|
27
|
+
:subset_custom_range => [:string, ""],
|
28
|
+
:base64 => [:checkbox, nil, "Y"],
|
29
|
+
:style_link => [:checkbox, nil, "Y"],
|
30
|
+
:css_stylesheet => [:string, "stylesheet.css"],
|
31
|
+
:ot_features => [:array, "onum", "lnum", "tnum", "pnum", "zero", "ss01", "ss02", "ss03", "ss04", "ss05"],
|
32
|
+
:filename_suffix => [:string, "-webfont"],
|
33
|
+
:emsquare => [:number, 2048],
|
34
|
+
:spacing_adjustment => [:number, 0],
|
35
|
+
:agreement => [:checkbox, "Y"]
|
36
|
+
}
|
37
|
+
|
38
|
+
NON_EXPERT_OPTIONS = [:id, :agreement, :mode]
|
39
|
+
SUBSET_OPTIONS = [:subset_range, :subset_custom, :subset_custom_range]
|
40
|
+
|
41
|
+
# Sanitize options
|
42
|
+
def self.sanitize options, custom_options={}
|
43
|
+
options = options.clone
|
44
|
+
custom_options ||= {}
|
45
|
+
result = {}
|
46
|
+
OPTIONS.each_pair do |key,array|
|
47
|
+
type = array[0]
|
48
|
+
allowed_values = array[1..999]
|
49
|
+
user_value = options[key].nil? ? options[key.to_s] : options[key]
|
50
|
+
user_value = user_value.to_s unless user_value.nil?
|
51
|
+
|
52
|
+
if !user_value.nil? && OPTIONS.has_key?(key) && !NON_EXPERT_OPTIONS.include?(key)
|
53
|
+
options[:mode] = result[:mode] = "expert" if options[:mode].nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
if !user_value.nil? && OPTIONS.has_key?(key) && SUBSET_OPTIONS.include?(key)
|
58
|
+
options[:options_subset] = result[:options_subset] = "advanced" if options[:options_subset].nil?
|
59
|
+
end
|
60
|
+
|
61
|
+
case type
|
62
|
+
when :array
|
63
|
+
if !user_value.kind_of?(Array)
|
64
|
+
if user_value.kind_of?(String)
|
65
|
+
user_value = user_value.split(",").map{|v| v.strip}
|
66
|
+
else
|
67
|
+
user_value = [user_value]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
user_value = user_value.delete_if {|val| !allowed_values.include? val }
|
72
|
+
|
73
|
+
result[key] = user_value unless user_value.empty?
|
74
|
+
when :number
|
75
|
+
result[key] = (user_value || allowed_values[0]).to_i
|
76
|
+
when :string
|
77
|
+
result[key] = user_value || allowed_values[0]
|
78
|
+
when :checkbox
|
79
|
+
if user_value == true
|
80
|
+
result[key] = allowed_values.last
|
81
|
+
elsif user_value == "false"
|
82
|
+
#nil
|
83
|
+
else
|
84
|
+
result[key] = allowed_values.include?(user_value) ? (user_value) : (allowed_values[0])
|
85
|
+
end
|
86
|
+
when :radio
|
87
|
+
result[key] = allowed_values.include?(user_value) ? (user_value) : (allowed_values[0])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
result[:formats] = ["ttf", "woff", "svg", "eotz"] if result[:formats].nil?
|
92
|
+
result[:dirname] = [result[:id]]
|
93
|
+
result.merge!(custom_options).delete_if { |k, v| v.nil? }
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
data/lib/marmot.rb
ADDED
data/marmot.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "marmot/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "marmot"
|
7
|
+
s.version = Marmot::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Dmitry Filimonov"]
|
10
|
+
s.email = ["me@dfilimonov.com"]
|
11
|
+
s.homepage = "http://github.com/petethepig/marmot"
|
12
|
+
s.summary = %q{Unofficial Font Squirrel webfont generator client}
|
13
|
+
s.description = %q{Unofficial Font Squirrel webfont generator client}
|
14
|
+
s.license = "MIT"
|
15
|
+
|
16
|
+
s.add_dependency 'trollop'
|
17
|
+
s.add_dependency 'httmultiparty'
|
18
|
+
s.add_dependency 'json'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
require_relative "../lib/marmot"
|
3
|
+
|
4
|
+
|
5
|
+
describe Marmot::Client do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@client = Marmot::Client.new
|
9
|
+
@client.logger = Logger.new(STDOUT)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "successfully performs conversion" do
|
13
|
+
file = @client.convert File.expand_path("../test-files/Averia/Averia-Regular.ttf", __FILE__)
|
14
|
+
File.exist?(file).should == true
|
15
|
+
File.delete(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "raises exception because there is no such file" do
|
19
|
+
expect {
|
20
|
+
@client.convert File.expand_path("../test-files/Averia/Averia-ExtraBold.ttf", __FILE__)
|
21
|
+
}.to raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it "raises exception because file is not a font" do
|
25
|
+
expect {
|
26
|
+
@client.convert File.expand_path("../test-files/Averia/FONTLOG.txt", __FILE__)
|
27
|
+
}.to raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|