fontist 1.5.0 → 1.7.2
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/README.md +46 -18
- data/bin/fontist +0 -1
- data/fontist.gemspec +1 -0
- data/lib/fontist.rb +5 -1
- data/lib/fontist/cli.rb +22 -10
- data/lib/fontist/errors.rb +1 -0
- data/lib/fontist/font.rb +17 -3
- data/lib/fontist/font_formula.rb +58 -16
- data/lib/fontist/formula.rb +13 -53
- data/lib/fontist/formula_template.rb +16 -2
- data/lib/fontist/import/create_formula.rb +15 -30
- data/lib/fontist/import/files/collection_file.rb +6 -1
- data/lib/fontist/import/files/file_requirement.rb +17 -0
- data/lib/fontist/import/files/font_detector.rb +48 -0
- data/lib/fontist/import/formula_builder.rb +14 -4
- data/lib/fontist/import/google/skiplist.yml +2 -0
- data/lib/fontist/import/otf/font_file.rb +20 -4
- data/lib/fontist/import/recursive_extraction.rb +99 -15
- data/lib/fontist/manifest/install.rb +5 -9
- data/lib/fontist/manifest/locations.rb +51 -4
- data/lib/fontist/system_font.rb +44 -44
- data/lib/fontist/system_index.rb +92 -0
- data/lib/fontist/utils.rb +1 -0
- data/lib/fontist/utils/cache.rb +27 -8
- data/lib/fontist/utils/downloader.rb +54 -10
- data/lib/fontist/utils/dsl.rb +4 -0
- data/lib/fontist/utils/dsl/collection_font.rb +36 -0
- data/lib/fontist/utils/dsl/font.rb +2 -1
- data/lib/fontist/utils/exe_extractor.rb +19 -9
- data/lib/fontist/utils/ui.rb +4 -0
- data/lib/fontist/utils/zip_extractor.rb +20 -11
- data/lib/fontist/version.rb +1 -1
- metadata +20 -3
- data/lib/fontist/manifest/common.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 035a1318895900d90f27d2b5db8f08b86c64e6eb5e172ef81038c55305258756
|
4
|
+
data.tar.gz: 5a748c9632995e504b448508d56d0e292a7429b1eaa86d08978bf6e54d67f9e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1558eb54750ed4efaabe694b79e23a00ce3a51d6c026641ab58796737ff609cce23b92dd141524e90c8d7e55f11cc0537fe405ca849b9d0309e65e47d1b672fe
|
7
|
+
data.tar.gz: 371d9283fa520c1dd036e22f600a5804a75af10b3a2d90bfe775432036ab51c12466696bb33a6614954c4de974889087255cdf2705b91731b6a0afa7ce9bef88
|
data/README.md
CHANGED
@@ -109,7 +109,7 @@ fonts in your system.
|
|
109
109
|
#### Find formula fonts
|
110
110
|
|
111
111
|
Normally, each font name can be associated with multiple styles or collection, for
|
112
|
-
example the `Calibri` font might contains a `regular`, `
|
112
|
+
example the `Calibri` font might contains a `regular`, `bold` or `italic` styles
|
113
113
|
fonts and if you want a interface that can return the complete list then this is
|
114
114
|
your friend. You can use it as following:
|
115
115
|
|
@@ -153,11 +153,14 @@ Fontist::Manifest::Locations.call(manifest_path)
|
|
153
153
|
```
|
154
154
|
|
155
155
|
```ruby
|
156
|
-
{"Segoe UI"=>
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
156
|
+
{"Segoe UI"=> {
|
157
|
+
"Regular"=>{"full_name"=>"Segoe UI",
|
158
|
+
"paths"=>["/Users/user/.fontist/fonts/SEGOEUI.TTF"]},
|
159
|
+
"Bold"=>{"full_name"=>"Segoe UI Bold",
|
160
|
+
"paths"=>["/Users/user/.fontist/fonts/SEGOEUIB.TTF"]}},
|
161
|
+
"Roboto Mono"=> {
|
162
|
+
"Regular"=>{"full_name"=>nil,
|
163
|
+
"paths"=>[]}}}
|
161
164
|
```
|
162
165
|
|
163
166
|
#### Install
|
@@ -172,11 +175,14 @@ Fontist::Manifest::Install.call(manifest, confirmation: "yes")
|
|
172
175
|
It will install fonts and return their locations:
|
173
176
|
|
174
177
|
```ruby
|
175
|
-
{"Segoe UI"=>
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
178
|
+
{"Segoe UI"=> {
|
179
|
+
"Regular"=>{"full_name"=>"Segoe UI",
|
180
|
+
"paths"=>["/Users/user/.fontist/fonts/SEGOEUI.TTF"]},
|
181
|
+
"Bold"=>{"full_name"=>"Segoe UI Bold",
|
182
|
+
"paths"=>["/Users/user/.fontist/fonts/SEGOEUIB.TTF"]}},
|
183
|
+
"Roboto Mono"=> {
|
184
|
+
"Regular"=>{"full_name"=>"Roboto Mono Regular",
|
185
|
+
"paths"=>["/Users/user/.fontist/fonts/RobotoMono-VariableFont_wght.ttf"]}}}
|
180
186
|
```
|
181
187
|
|
182
188
|
### CLI
|
@@ -191,7 +197,8 @@ All searches are case-insensitive for ease of use.
|
|
191
197
|
|
192
198
|
The `install` command is similar to the `Font.install` call. It first checks
|
193
199
|
whether this font is already installed, and if not, then installs the font and
|
194
|
-
returns its paths.
|
200
|
+
returns its paths. Only font name (not formula name, nor font filename) could
|
201
|
+
be used as a parameter.
|
195
202
|
|
196
203
|
```
|
197
204
|
$ fontist install "segoe ui"
|
@@ -274,11 +281,17 @@ $ fontist manifest-locations manifest.yml
|
|
274
281
|
---
|
275
282
|
Segoe UI:
|
276
283
|
Regular:
|
277
|
-
|
284
|
+
full_name: Segoe UI
|
285
|
+
paths:
|
286
|
+
- "/Users/user/.fontist/fonts/SEGOEUI.TTF"
|
278
287
|
Bold:
|
279
|
-
|
288
|
+
full_name: Segoe UI Bold
|
289
|
+
paths:
|
290
|
+
- "/Users/user/.fontist/fonts/SEGOEUIB.TTF"
|
280
291
|
Roboto Mono:
|
281
|
-
Regular:
|
292
|
+
Regular:
|
293
|
+
full_name:
|
294
|
+
paths: []
|
282
295
|
```
|
283
296
|
|
284
297
|
Since Segoe UI is installed, but Roboto Mono is not.
|
@@ -292,12 +305,18 @@ $ fontist manifest-install --confirm-license manifest.yml
|
|
292
305
|
---
|
293
306
|
Segoe UI:
|
294
307
|
Regular:
|
295
|
-
|
308
|
+
full_name: Segoe UI
|
309
|
+
paths:
|
310
|
+
- "/Users/user/.fontist/fonts/SEGOEUI.TTF"
|
296
311
|
Bold:
|
297
|
-
|
312
|
+
full_name: Segoe UI Bold
|
313
|
+
paths:
|
314
|
+
- "/Users/user/.fontist/fonts/SEGOEUIB.TTF"
|
298
315
|
Roboto Mono:
|
299
316
|
Regular:
|
300
|
-
|
317
|
+
full_name: Roboto Mono Regular
|
318
|
+
paths:
|
319
|
+
- "/Users/user/.fontist/fonts/RobotoMono-VariableFont_wght.ttf"
|
301
320
|
```
|
302
321
|
|
303
322
|
#### Help
|
@@ -308,6 +327,15 @@ List of all commands could be seen by:
|
|
308
327
|
fontist help
|
309
328
|
```
|
310
329
|
|
330
|
+
### Configuration
|
331
|
+
|
332
|
+
By default Fontist uses the `~/.fontist` directory to store fonts and its
|
333
|
+
files. It could be changed with the `FONTIST_PATH` environment variable.
|
334
|
+
|
335
|
+
```sh
|
336
|
+
FONTIST_PATH=~/.fontist_new fontist update
|
337
|
+
```
|
338
|
+
|
311
339
|
## Development
|
312
340
|
|
313
341
|
We are following Sandi Metz's Rules for this gem, you can read the
|
data/bin/fontist
CHANGED
data/fontist.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_runtime_dependency "ruby-ole", "~> 1.0"
|
35
35
|
spec.add_runtime_dependency "thor", "~> 1.0.1"
|
36
36
|
spec.add_runtime_dependency "git", "~> 1.0"
|
37
|
+
spec.add_runtime_dependency "ttfunk", "~> 1.0"
|
37
38
|
|
38
39
|
spec.add_development_dependency "extract_ttc", "~> 0.1"
|
39
40
|
spec.add_development_dependency "pry"
|
data/lib/fontist.rb
CHANGED
@@ -29,7 +29,7 @@ module Fontist
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.fontist_path
|
32
|
-
Pathname.new(Dir.home
|
32
|
+
Pathname.new(ENV["FONTIST_PATH"] || File.join(Dir.home, ".fontist"))
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.fonts_path
|
@@ -55,4 +55,8 @@ module Fontist
|
|
55
55
|
def self.system_file_path
|
56
56
|
Fontist.lib_path.join("fontist", "system.yml")
|
57
57
|
end
|
58
|
+
|
59
|
+
def self.system_index_path
|
60
|
+
Fontist.fontist_path.join("system_index.yml")
|
61
|
+
end
|
58
62
|
end
|
data/lib/fontist/cli.rb
CHANGED
@@ -9,17 +9,19 @@ module Fontist
|
|
9
9
|
false
|
10
10
|
end
|
11
11
|
|
12
|
-
desc "install FONT", "Install font
|
12
|
+
desc "install FONT", "Install font"
|
13
13
|
option :force, type: :boolean, aliases: :f,
|
14
14
|
desc: "Install even if it's already installed in system"
|
15
|
+
option :confirm_license, type: :boolean, desc: "Confirm license agreement"
|
15
16
|
def install(font)
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
Fontist::Font.install(
|
18
|
+
font,
|
19
|
+
force: options[:force],
|
20
|
+
confirmation: options[:confirm_license] ? "yes" : "no"
|
21
|
+
)
|
19
22
|
STATUS_SUCCESS
|
20
23
|
rescue Fontist::Errors::NonSupportedFontError
|
21
|
-
|
22
|
-
STATUS_ERROR
|
24
|
+
could_not_find_font(font)
|
23
25
|
end
|
24
26
|
|
25
27
|
desc "uninstall/remove FONT", "Uninstall font by font or formula"
|
@@ -32,8 +34,7 @@ module Fontist
|
|
32
34
|
Fontist.ui.error(e.message)
|
33
35
|
STATUS_ERROR
|
34
36
|
rescue Fontist::Errors::NonSupportedFontError
|
35
|
-
|
36
|
-
STATUS_ERROR
|
37
|
+
could_not_find_font(font)
|
37
38
|
end
|
38
39
|
map remove: :uninstall
|
39
40
|
|
@@ -47,7 +48,7 @@ module Fontist
|
|
47
48
|
rescue Fontist::Errors::MissingFontError => e
|
48
49
|
error(e.message)
|
49
50
|
rescue Fontist::Errors::NonSupportedFontError
|
50
|
-
|
51
|
+
could_not_find_font(font)
|
51
52
|
end
|
52
53
|
|
53
54
|
desc "list [FONT]", "List installation status of FONT or fonts in fontist"
|
@@ -56,7 +57,7 @@ module Fontist
|
|
56
57
|
print_list(formulas)
|
57
58
|
success
|
58
59
|
rescue Fontist::Errors::NonSupportedFontError
|
59
|
-
|
60
|
+
could_not_find_font(font)
|
60
61
|
end
|
61
62
|
|
62
63
|
desc "update", "Update formulas"
|
@@ -97,6 +98,8 @@ module Fontist
|
|
97
98
|
desc "create-formula URL", "Create a new formula with fonts from URL"
|
98
99
|
option :name, desc: "Example: Times New Roman"
|
99
100
|
option :mirror, repeatable: true
|
101
|
+
option :subarchive, desc: "Subarchive to choose when there are several ones"
|
102
|
+
option :subdir, desc: "Subdirectory to take fonts from"
|
100
103
|
def create_formula(url)
|
101
104
|
require "fontist/import/create_formula"
|
102
105
|
name = Fontist::Import::CreateFormula.new(url, options).call
|
@@ -110,6 +113,15 @@ module Fontist
|
|
110
113
|
STATUS_SUCCESS
|
111
114
|
end
|
112
115
|
|
116
|
+
def could_not_find_font(font)
|
117
|
+
error("Font '#{font}' not found locally nor available in the Fontist " \
|
118
|
+
"formula repository.\n" \
|
119
|
+
"Perhaps it is available at the latest Fontist formula " \
|
120
|
+
"repository.\n" \
|
121
|
+
"You can update the formula repository using the command " \
|
122
|
+
"`fontist update` and try again.")
|
123
|
+
end
|
124
|
+
|
113
125
|
def error(message)
|
114
126
|
Fontist.ui.error(message)
|
115
127
|
STATUS_ERROR
|
data/lib/fontist/errors.rb
CHANGED
@@ -7,6 +7,7 @@ module Fontist
|
|
7
7
|
class InvalidResourceError < StandardError; end
|
8
8
|
class TimeoutError < StandardError; end
|
9
9
|
class MissingAttributeError < StandardError; end
|
10
|
+
class UnknownFontTypeError < StandardError; end
|
10
11
|
class FontNotFoundError < StandardError; end
|
11
12
|
class BinaryCallError < StandardError; end
|
12
13
|
class ManifestCouldNotBeReadError < StandardError; end
|
data/lib/fontist/font.rb
CHANGED
@@ -81,7 +81,16 @@ module Fontist
|
|
81
81
|
attr_reader :name, :confirmation
|
82
82
|
|
83
83
|
def find_system_font
|
84
|
-
Fontist::SystemFont.find(name)
|
84
|
+
paths = Fontist::SystemFont.find(name)
|
85
|
+
unless paths
|
86
|
+
Fontist.ui.say(%(Font "#{name}" not found locally.))
|
87
|
+
return
|
88
|
+
end
|
89
|
+
|
90
|
+
Fontist.ui.say("Fonts found at:")
|
91
|
+
paths.each do |path|
|
92
|
+
Fontist.ui.say("- #{path}")
|
93
|
+
end
|
85
94
|
end
|
86
95
|
|
87
96
|
def check_or_create_fontist_path!
|
@@ -113,7 +122,13 @@ module Fontist
|
|
113
122
|
def download_font
|
114
123
|
if formula
|
115
124
|
check_and_confirm_required_license(formula)
|
116
|
-
font_installer(formula).fetch_font(name,
|
125
|
+
paths = font_installer(formula).fetch_font(name,
|
126
|
+
confirmation: confirmation)
|
127
|
+
|
128
|
+
Fontist.ui.say("Fonts installed at:")
|
129
|
+
paths.each do |path|
|
130
|
+
Fontist.ui.say("- #{path}")
|
131
|
+
end
|
117
132
|
end
|
118
133
|
end
|
119
134
|
|
@@ -232,6 +247,5 @@ module Fontist
|
|
232
247
|
def installed(style)
|
233
248
|
path(style) ? true : false
|
234
249
|
end
|
235
|
-
|
236
250
|
end
|
237
251
|
end
|
data/lib/fontist/font_formula.rb
CHANGED
@@ -83,34 +83,50 @@ module Fontist
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def match_fonts(
|
87
|
-
|
88
|
-
|
89
|
-
@matched_fonts.push(
|
86
|
+
def match_fonts(fonts_paths, font_name)
|
87
|
+
filenames = filenames_by_font_name(font_name)
|
88
|
+
paths = search_for_filenames(fonts_paths, filenames)
|
89
|
+
@matched_fonts.push(*paths)
|
90
90
|
|
91
|
-
|
91
|
+
paths
|
92
92
|
end
|
93
93
|
|
94
|
-
def
|
95
|
-
|
94
|
+
def filenames_by_font_name(font_name)
|
95
|
+
fonts.map do |f|
|
96
|
+
if f[:name].casecmp?(font_name)
|
97
|
+
f[:styles].map do |s|
|
98
|
+
s[:font]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end.flatten.compact
|
102
|
+
end
|
96
103
|
|
97
|
-
|
98
|
-
|
99
|
-
|
104
|
+
def search_for_filenames(paths, filenames)
|
105
|
+
paths.select do |path|
|
106
|
+
filenames.any? do |filename|
|
107
|
+
File.basename(path) == filename
|
100
108
|
end
|
101
109
|
end
|
102
110
|
end
|
103
111
|
|
104
|
-
def
|
105
|
-
|
106
|
-
fonts = fonts.map { |font| font.styles.map(&:font) }.flatten if fonts
|
112
|
+
def extract_from_collection(options)
|
113
|
+
styles = options.fetch(:extract_styles_from_collection, [])
|
107
114
|
|
108
|
-
|
115
|
+
unless styles.empty?
|
116
|
+
styles.map do |attributes|
|
117
|
+
filenames = temp_resource.slice(:filename, :source_filename)
|
118
|
+
Fontist::Utils::Dsl::CollectionFont.new(attributes.merge(filenames))
|
119
|
+
.attributes
|
120
|
+
end
|
121
|
+
end
|
109
122
|
end
|
110
123
|
|
111
124
|
def download_file(source)
|
125
|
+
url = source[:urls].first
|
126
|
+
Fontist.ui.say(%(Downloading font "#{key}" from #{url}))
|
127
|
+
|
112
128
|
downloaded_file = Fontist::Utils::Downloader.download(
|
113
|
-
|
129
|
+
url,
|
114
130
|
sha: source[:sha256],
|
115
131
|
file_size: source[:file_size],
|
116
132
|
progress_bar: is_progress_bar_enabled
|
@@ -121,7 +137,33 @@ module Fontist
|
|
121
137
|
end
|
122
138
|
|
123
139
|
def is_progress_bar_enabled
|
124
|
-
options.nil? ?
|
140
|
+
options.nil? ? true : options.fetch(:progress_bar, true)
|
141
|
+
end
|
142
|
+
|
143
|
+
def font_file?(filename)
|
144
|
+
source_files.include?(filename)
|
145
|
+
end
|
146
|
+
|
147
|
+
def source_files
|
148
|
+
@source_files ||= fonts.flat_map do |font|
|
149
|
+
font[:styles].map do |style|
|
150
|
+
style[:source_font] || style[:font]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def target_filename(source_filename)
|
156
|
+
target_filenames[source_filename]
|
157
|
+
end
|
158
|
+
|
159
|
+
def target_filenames
|
160
|
+
@target_filenames ||= fonts.flat_map do |font|
|
161
|
+
font[:styles].map do |style|
|
162
|
+
source = style[:source_font] || style[:font]
|
163
|
+
target = style[:font]
|
164
|
+
[source, target]
|
165
|
+
end
|
166
|
+
end.to_h
|
125
167
|
end
|
126
168
|
end
|
127
169
|
end
|
data/lib/fontist/formula.rb
CHANGED
@@ -28,79 +28,39 @@ module Fontist
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def find
|
31
|
-
|
31
|
+
formulas.values.detect do |formula|
|
32
|
+
formula.fonts.any? do |f|
|
33
|
+
f.name.casecmp?(font_name)
|
34
|
+
end
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
def find_fonts
|
35
|
-
formulas
|
36
|
-
|
37
|
-
|
39
|
+
formulas.values.map do |formula|
|
40
|
+
formula.fonts.select do |f|
|
41
|
+
f.name.casecmp?(font_name)
|
42
|
+
end
|
43
|
+
end.flatten
|
38
44
|
end
|
39
45
|
|
40
46
|
def find_styles
|
41
|
-
formulas.values.
|
42
|
-
formula.fonts.
|
47
|
+
formulas.values.map do |formula|
|
48
|
+
formula.fonts.map do |f|
|
43
49
|
f.styles.select do |s|
|
44
50
|
f.name.casecmp?(font_name) && s.type.casecmp?(style_name)
|
45
51
|
end
|
46
52
|
end
|
47
|
-
end
|
53
|
+
end.flatten
|
48
54
|
end
|
49
55
|
|
50
56
|
private
|
51
57
|
|
52
58
|
attr_reader :font_name, :style_name
|
53
59
|
|
54
|
-
def find_formula
|
55
|
-
find_by_key || find_by_font_name || find_by_font || []
|
56
|
-
end
|
57
|
-
|
58
60
|
def formulas
|
59
61
|
@formulas ||= all.to_h
|
60
62
|
end
|
61
63
|
|
62
|
-
def take_fonts(formulas)
|
63
|
-
formulas.map(&:fonts).flatten
|
64
|
-
end
|
65
|
-
|
66
|
-
def find_by_key
|
67
|
-
matched_formulas = formulas.select do |key, _value|
|
68
|
-
key.to_s.casecmp?(font_name)
|
69
|
-
end
|
70
|
-
|
71
|
-
matched_formulas.empty? ? nil : matched_formulas.values
|
72
|
-
end
|
73
|
-
|
74
|
-
def find_by_font_name
|
75
|
-
matched_formulas = formulas.select do |key, value|
|
76
|
-
!value.fonts.map(&:name).grep(/#{font_name}/i).empty?
|
77
|
-
end
|
78
|
-
|
79
|
-
matched_formulas.empty? ? nil : matched_formulas.values
|
80
|
-
end
|
81
|
-
|
82
|
-
# Note
|
83
|
-
#
|
84
|
-
# These interface recursively look into every single font styles,
|
85
|
-
# so ideally try to avoid using it when possible, and that's why
|
86
|
-
# we've added it as last option in formula finder.
|
87
|
-
#
|
88
|
-
def find_by_font
|
89
|
-
matched_formulas = formulas.select do |key, value|
|
90
|
-
match_in_font_styles?(value[:fonts])
|
91
|
-
end
|
92
|
-
|
93
|
-
matched_formulas.empty? ? nil : matched_formulas.values
|
94
|
-
end
|
95
|
-
|
96
|
-
def match_in_font_styles?(fonts)
|
97
|
-
styles = fonts.select do |font|
|
98
|
-
!font.styles.map(&:font).grep(/#{font_name}/i).empty?
|
99
|
-
end
|
100
|
-
|
101
|
-
styles.empty? ? false : true
|
102
|
-
end
|
103
|
-
|
104
64
|
def check_and_register_font_formulas
|
105
65
|
$check_and_register_font_formulas ||= Fontist::Formulas.register_formulas
|
106
66
|
end
|