fontist 1.11.6 → 1.13.1
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/.github/workflows/rspec.yml +9 -1
- data/.rubocop.yml +1 -18
- data/README.adoc +54 -3
- data/fontist.gemspec +3 -1
- data/lib/fontist/cli.rb +51 -14
- data/lib/fontist/errors.rb +10 -0
- data/lib/fontist/font.rb +60 -14
- data/lib/fontist/formula.rb +66 -4
- data/lib/fontist/formula_picker.rb +126 -0
- data/lib/fontist/import/create_formula.rb +16 -10
- data/lib/fontist/import/files/font_detector.rb +4 -2
- data/lib/fontist/import/formula_builder.rb +24 -15
- data/lib/fontist/import/google/skiplist.yml +1 -0
- data/lib/fontist/import/macos.rb +148 -0
- data/lib/fontist/import/manual_formula_builder.rb +24 -0
- data/lib/fontist/import/recursive_extraction.rb +2 -0
- data/lib/fontist/import_cli.rb +19 -0
- data/lib/fontist/indexes/default_family_font_index.rb +4 -1
- data/lib/fontist/style_version.rb +39 -0
- data/lib/fontist/system.yml +1 -0
- data/lib/fontist/update.rb +9 -4
- data/lib/fontist/utils/downloader.rb +5 -8
- data/lib/fontist/utils/system.rb +10 -0
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +9 -1
- metadata +49 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f376e0b45e530b28be9d60c132b3840d4485103995fc435c0512b07bf6e20435
|
4
|
+
data.tar.gz: b8c8aa1f3de0b627bcaffe09b45398dd60a0ba2a3a2163599263461acb179292
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 157c06d56119a5e94a7a15b33b7b1e65695eb94af595f618bbbcf382f8d201d8db7f1a51ed2e3b20cf56d0339a7bd33dc2be82900de1851e29ee31225d2f8054
|
7
|
+
data.tar.gz: 3fabd78041974540dc3504c293e335cfd39d241c5cd80da8fd0eef2b6b0a0e6a49701baf4c13e4c151ff397c8aaa6d9d542b37a45b52610ca404bb0abcef004a
|
data/.github/workflows/rspec.yml
CHANGED
@@ -33,7 +33,15 @@ jobs:
|
|
33
33
|
env:
|
34
34
|
TEST_ENV: CI
|
35
35
|
|
36
|
-
- if: matrix.os
|
36
|
+
- if: matrix.os == 'windows-latest' && matrix.ruby == '2.4'
|
37
|
+
run: curl -O https://curl.se/ca/cacert.pem
|
38
|
+
|
39
|
+
- if: matrix.os == 'windows-latest' && matrix.ruby == '2.4'
|
40
|
+
run: bundle exec rspec --tag ~dev
|
41
|
+
env:
|
42
|
+
SSL_CERT_FILE: cacert.pem
|
43
|
+
|
44
|
+
- if: matrix.os != 'macos-latest' || matrix.os == 'windows-latest' && matrix.ruby == '2.4'
|
37
45
|
run: bundle exec rspec --tag ~dev
|
38
46
|
env:
|
39
47
|
TEST_ENV: CI
|
data/.rubocop.yml
CHANGED
@@ -2,21 +2,4 @@ inherit_from:
|
|
2
2
|
- 'https://raw.githubusercontent.com/fontist/oss-guides/master/ci/rubocop.yml'
|
3
3
|
|
4
4
|
AllCops:
|
5
|
-
|
6
|
-
- 'lib/fontist/import/google/fonts_public.pb.rb'
|
7
|
-
- 'lib/fontist/formula_template.rb'
|
8
|
-
|
9
|
-
Rails:
|
10
|
-
Enabled: false
|
11
|
-
|
12
|
-
Layout/LineLength:
|
13
|
-
Exclude:
|
14
|
-
- 'lib/fontist/formulas/**/*.rb'
|
15
|
-
|
16
|
-
Layout/FirstHashElementIndentation:
|
17
|
-
Exclude:
|
18
|
-
- 'lib/fontist/formulas/**/*.rb'
|
19
|
-
|
20
|
-
Layout/HeredocIndentation:
|
21
|
-
Exclude:
|
22
|
-
- 'lib/fontist/formulas/**/*.rb'
|
5
|
+
SuggestExtensions: false
|
data/README.adoc
CHANGED
@@ -117,6 +117,25 @@ NOTE: Specifying the formula's name or the font's filename is not supported.
|
|
117
117
|
|
118
118
|
NOTE: The `install` command is similar to the `Font.install` library call.
|
119
119
|
|
120
|
+
If there are several formulas with a requested font, then `fontist` searches
|
121
|
+
for the newest version of the font among formulas with size below a limit
|
122
|
+
(300 MB). This behavior can be changed with options.
|
123
|
+
|
124
|
+
NOTE: If styles of a font are spread among several formulas, then all
|
125
|
+
available formulas would be installed.
|
126
|
+
|
127
|
+
Supported options:
|
128
|
+
|
129
|
+
-f, [--force]:: Install even if it's already installed in system
|
130
|
+
-a, [--accept-all-licenses]:: Accept all license agreements
|
131
|
+
-h, [--hide-licenses]:: Hide license texts
|
132
|
+
-p, [--no-progress]:: Hide download progress
|
133
|
+
-V, [--version=VERSION]:: Install particular version of a font
|
134
|
+
-s, [--smallest]:: Install the smallest formula
|
135
|
+
-n, [--newest]:: Install the newest version of a font
|
136
|
+
-S, [--size-limit=N]:: Specify size limit for a formula to be installed
|
137
|
+
(default is 300 MB)
|
138
|
+
|
120
139
|
=== Uninstall fonts
|
121
140
|
|
122
141
|
Uninstalls any font supported by Fontist.
|
@@ -618,7 +637,7 @@ repository https://github.com/fontist/formulas[formulas]:
|
|
618
637
|
|
619
638
|
[source,sh]
|
620
639
|
----
|
621
|
-
cd ~/.fontist/versions/
|
640
|
+
cd ~/.fontist/versions/{last_version}/formulas
|
622
641
|
git add Formulas/google
|
623
642
|
git commit -m "Google Fonts update"
|
624
643
|
git push
|
@@ -640,12 +659,44 @@ They can be updated with:
|
|
640
659
|
[source,sh]
|
641
660
|
----
|
642
661
|
fontist import-sil
|
643
|
-
cd ~/.fontist/formulas
|
644
|
-
git add Formulas/sil
|
662
|
+
cd ~/.fontist/versions/{last_version}/formulas
|
663
|
+
git add Formulas/sil
|
645
664
|
git commit -m "SIL fonts update"
|
646
665
|
git push
|
647
666
|
----
|
648
667
|
|
668
|
+
=== Dynamically importing formulas from macOS
|
669
|
+
|
670
|
+
macOS provides https://support.apple.com/en-om/HT211240#download[fonts] which
|
671
|
+
can be manually downloaded with the Font Book app. When such font is requested,
|
672
|
+
fontist prints information on how to install it.
|
673
|
+
|
674
|
+
In order to know which fonts are available in a current version of macOS,
|
675
|
+
for each version there is a formula containing all supported fonts.
|
676
|
+
|
677
|
+
A new formula can be generated with:
|
678
|
+
|
679
|
+
[source,sh]
|
680
|
+
----
|
681
|
+
fontist import macos --name "Big Sur" --fonts-link "https://support.apple.com/en-om/HT211240#download"
|
682
|
+
cd ~/.fontist/versions/{last_version}/formulas
|
683
|
+
git add Formulas/macos
|
684
|
+
git commit -m "Add Big Sur macOS formula"
|
685
|
+
git push
|
686
|
+
----
|
687
|
+
|
688
|
+
Here `--fonts-link` is a link to a page containing a list of available fonts
|
689
|
+
in the Font Book app.
|
690
|
+
|
691
|
+
If the import is run on a different version of macOS, then a proper version
|
692
|
+
should be set in the `platforms` attribute of the generated formula:
|
693
|
+
|
694
|
+
[source,yaml]
|
695
|
+
----
|
696
|
+
platforms:
|
697
|
+
- macos-20
|
698
|
+
----
|
699
|
+
|
649
700
|
|
650
701
|
== Development
|
651
702
|
|
data/fontist.gemspec
CHANGED
@@ -29,15 +29,17 @@ Gem::Specification.new do |spec|
|
|
29
29
|
|
30
30
|
spec.add_runtime_dependency "down", "~> 5.0"
|
31
31
|
spec.add_runtime_dependency "extract_ttc", "~> 0.1"
|
32
|
+
spec.add_runtime_dependency "nokogiri", "~> 1.0"
|
33
|
+
spec.add_runtime_dependency "sys-uname", "~> 1.2"
|
32
34
|
spec.add_runtime_dependency "thor", "~> 1.0.1"
|
33
35
|
spec.add_runtime_dependency "git", "~> 1.0"
|
34
36
|
spec.add_runtime_dependency "ttfunk", "~> 1.6"
|
37
|
+
spec.add_runtime_dependency "plist", "~> 3.0"
|
35
38
|
spec.add_runtime_dependency "excavate", "~> 0.1"
|
36
39
|
|
37
40
|
spec.add_development_dependency "pry"
|
38
41
|
spec.add_development_dependency "bundler", "~> 2.0"
|
39
42
|
spec.add_development_dependency "gem-release"
|
40
|
-
spec.add_development_dependency "nokogiri", "~> 1.0"
|
41
43
|
spec.add_development_dependency "rake", "~> 13"
|
42
44
|
spec.add_development_dependency "rspec", "~> 3.0"
|
43
45
|
spec.add_development_dependency "rspec-benchmark", "~> 0.6"
|
data/lib/fontist/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "fontist/repo_cli"
|
3
|
+
require "fontist/import_cli"
|
3
4
|
require "fontist/google_cli"
|
4
5
|
|
5
6
|
module Fontist
|
@@ -15,14 +16,25 @@ module Fontist
|
|
15
16
|
STATUS_REPO_NOT_FOUND = 8
|
16
17
|
STATUS_MAIN_REPO_NOT_FOUND = 9
|
17
18
|
STATUS_REPO_COULD_NOT_BE_UPDATED = 10
|
19
|
+
STATUS_MANUAL_FONT_ERROR = 11
|
20
|
+
STATUS_SIZE_LIMIT_ERROR = 12
|
18
21
|
|
19
22
|
ERROR_TO_STATUS = {
|
20
23
|
Fontist::Errors::UnsupportedFontError => [STATUS_NON_SUPPORTED_FONT_ERROR],
|
21
24
|
Fontist::Errors::MissingFontError => [STATUS_MISSING_FONT_ERROR],
|
25
|
+
Fontist::Errors::SizeLimitError => [
|
26
|
+
STATUS_SIZE_LIMIT_ERROR,
|
27
|
+
:append,
|
28
|
+
"Please specify higher `--size-limit`, or use the `--newest` or " \
|
29
|
+
"`--smallest` options.",
|
30
|
+
],
|
31
|
+
Fontist::Errors::ManualFontError => [STATUS_MANUAL_FONT_ERROR],
|
22
32
|
Fontist::Errors::LicensingError => [STATUS_LICENSING_ERROR],
|
23
33
|
Fontist::Errors::ManifestCouldNotBeFoundError => [STATUS_MANIFEST_COULD_NOT_BE_FOUND_ERROR,
|
34
|
+
:overwrite,
|
24
35
|
"Manifest could not be found."],
|
25
36
|
Fontist::Errors::ManifestCouldNotBeReadError => [STATUS_MANIFEST_COULD_NOT_BE_READ_ERROR,
|
37
|
+
:overwrite,
|
26
38
|
"Manifest could not be read."],
|
27
39
|
Fontist::Errors::FontIndexCorrupted => [STATUS_FONT_INDEX_CORRUPTED],
|
28
40
|
Fontist::Errors::RepoNotFoundError => [STATUS_REPO_NOT_FOUND],
|
@@ -40,18 +52,27 @@ module Fontist
|
|
40
52
|
desc "install FONT", "Install font"
|
41
53
|
option :force, type: :boolean, aliases: :f,
|
42
54
|
desc: "Install even if it's already installed in system"
|
43
|
-
option :accept_all_licenses, type: :boolean,
|
44
|
-
|
45
|
-
|
55
|
+
option :accept_all_licenses, type: :boolean,
|
56
|
+
aliases: ["--confirm-license", :a],
|
57
|
+
desc: "Accept all license agreements"
|
58
|
+
option :hide_licenses, type: :boolean, aliases: :h,
|
59
|
+
desc: "Hide license texts"
|
60
|
+
option :no_progress, type: :boolean, aliases: :p,
|
61
|
+
desc: "Hide download progress"
|
62
|
+
option :version, type: :string, aliases: :V,
|
63
|
+
desc: "Specify particular version of a font"
|
64
|
+
option :smallest, type: :boolean, aliases: :s,
|
65
|
+
desc: "Install the smallest formula if several"
|
66
|
+
option :newest, type: :boolean, aliases: :n,
|
67
|
+
desc: "Install the newest version of a font if several"
|
68
|
+
option :size_limit,
|
69
|
+
type: :numeric, aliases: :S,
|
70
|
+
desc: "Specify size limit for formula " \
|
71
|
+
"(default is #{Fontist.formula_size_limit_in_megabytes} MB)"
|
46
72
|
def install(font)
|
47
73
|
handle_class_options(options)
|
48
|
-
|
49
|
-
|
50
|
-
force: options[:force],
|
51
|
-
confirmation: options[:accept_all_licenses] ? "yes" : "no",
|
52
|
-
hide_licenses: options[:hide_licenses],
|
53
|
-
no_progress: options[:no_progress]
|
54
|
-
)
|
74
|
+
confirmation = options[:accept_all_licenses] ? "yes" : "no"
|
75
|
+
Fontist::Font.install(font, options.merge(confirmation: confirmation))
|
55
76
|
success
|
56
77
|
rescue Fontist::Errors::GeneralError => e
|
57
78
|
handle_error(e)
|
@@ -167,6 +188,9 @@ module Fontist
|
|
167
188
|
desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
|
168
189
|
subcommand "repo", Fontist::RepoCLI
|
169
190
|
|
191
|
+
desc "import SUBCOMMAND ...ARGS", "Manage imports"
|
192
|
+
subcommand "import", Fontist::ImportCLI
|
193
|
+
|
170
194
|
desc "google SUBCOMMAND ...ARGS", "Manage Google formulas"
|
171
195
|
subcommand "google", Fontist::GoogleCLI
|
172
196
|
|
@@ -181,10 +205,18 @@ module Fontist
|
|
181
205
|
end
|
182
206
|
|
183
207
|
def handle_error(exception)
|
184
|
-
status, message = ERROR_TO_STATUS[exception.class]
|
208
|
+
status, mode, message = ERROR_TO_STATUS[exception.class]
|
185
209
|
raise exception unless status
|
186
210
|
|
187
|
-
|
211
|
+
text = if message && mode == :overwrite
|
212
|
+
message
|
213
|
+
elsif message
|
214
|
+
"#{exception.message} #{message}"
|
215
|
+
else
|
216
|
+
exception.message
|
217
|
+
end
|
218
|
+
|
219
|
+
error(text, status)
|
188
220
|
end
|
189
221
|
|
190
222
|
def error(message, status)
|
@@ -205,10 +237,15 @@ module Fontist
|
|
205
237
|
Fontist.ui.say(" #{font.name}")
|
206
238
|
|
207
239
|
styles.each do |style, installed|
|
240
|
+
opts = []
|
241
|
+
opts << "manual" if formula.manual?
|
242
|
+
opts << (installed ? "installed" : "uninstalled")
|
243
|
+
msg = " #{style.type} (#{opts.join(', ')})"
|
244
|
+
|
208
245
|
if installed
|
209
|
-
Fontist.ui.success(
|
246
|
+
Fontist.ui.success(msg)
|
210
247
|
else
|
211
|
-
Fontist.ui.error(
|
248
|
+
Fontist.ui.error(msg)
|
212
249
|
end
|
213
250
|
end
|
214
251
|
end
|
data/lib/fontist/errors.rb
CHANGED
@@ -28,6 +28,8 @@ module Fontist
|
|
28
28
|
|
29
29
|
class RepoCouldNotBeUpdatedError < GeneralError; end
|
30
30
|
|
31
|
+
class SizeLimitError < GeneralError; end
|
32
|
+
|
31
33
|
class TamperedFileError < GeneralError; end
|
32
34
|
|
33
35
|
class TimeoutError < GeneralError; end
|
@@ -72,6 +74,14 @@ module Fontist
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
77
|
+
class ManualFontError < FontError
|
78
|
+
def initialize(font, formula)
|
79
|
+
msg = "'#{font}' font is missing.\n\n#{formula.instructions}"
|
80
|
+
|
81
|
+
super(msg, font)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
75
85
|
class UnsupportedFontError < FontError
|
76
86
|
def initialize(font)
|
77
87
|
msg = <<~MSG.chomp
|
data/lib/fontist/font.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "fontist/font_installer"
|
2
2
|
require "fontist/font_path"
|
3
|
+
require "fontist/formula_picker"
|
3
4
|
|
4
5
|
module Fontist
|
5
6
|
class Font
|
@@ -9,6 +10,10 @@ module Fontist
|
|
9
10
|
@hide_licenses = options[:hide_licenses]
|
10
11
|
@no_progress = options[:no_progress] || false
|
11
12
|
@force = options[:force] || false
|
13
|
+
@version = options[:version]
|
14
|
+
@smallest = options[:smallest]
|
15
|
+
@newest = options[:newest]
|
16
|
+
@size_limit = options[:size_limit]
|
12
17
|
|
13
18
|
check_or_create_fontist_path!
|
14
19
|
end
|
@@ -38,21 +43,25 @@ module Fontist
|
|
38
43
|
end
|
39
44
|
|
40
45
|
def find
|
41
|
-
find_system_font || downloadable_font ||
|
46
|
+
find_system_font || downloadable_font || manual_font ||
|
47
|
+
raise_non_supported_font
|
42
48
|
end
|
43
49
|
|
44
50
|
def install
|
45
|
-
(find_system_font unless @force) || download_font ||
|
51
|
+
(find_system_font unless @force) || download_font || manual_font ||
|
52
|
+
raise_non_supported_font
|
46
53
|
end
|
47
54
|
|
48
55
|
def uninstall
|
49
|
-
uninstall_font || downloadable_font ||
|
56
|
+
uninstall_font || downloadable_font || manual_font ||
|
57
|
+
raise_non_supported_font
|
50
58
|
end
|
51
59
|
|
52
60
|
def status
|
53
61
|
return installed_paths unless @name
|
54
62
|
|
55
|
-
find_system_font || downloadable_font ||
|
63
|
+
find_system_font || downloadable_font || manual_font ||
|
64
|
+
raise_non_supported_font
|
56
65
|
end
|
57
66
|
|
58
67
|
def list
|
@@ -62,7 +71,7 @@ module Fontist
|
|
62
71
|
end
|
63
72
|
|
64
73
|
def all
|
65
|
-
|
74
|
+
all_formulas.map(&:fonts).flatten
|
66
75
|
end
|
67
76
|
|
68
77
|
private
|
@@ -98,24 +107,47 @@ module Fontist
|
|
98
107
|
FontInstaller.new(formula, no_progress: @no_progress)
|
99
108
|
end
|
100
109
|
|
101
|
-
def
|
102
|
-
@
|
110
|
+
def sufficient_formulas
|
111
|
+
@sufficient_formulas ||=
|
112
|
+
FormulaPicker.new(@name,
|
113
|
+
size_limit: @size_limit,
|
114
|
+
version: @version,
|
115
|
+
smallest: @smallest,
|
116
|
+
newest: @newest)
|
117
|
+
.call(downloadable_formulas)
|
118
|
+
end
|
119
|
+
|
120
|
+
def downloadable_formulas
|
121
|
+
@downloadable_formulas ||= formulas.select(&:downloadable?)
|
122
|
+
end
|
123
|
+
|
124
|
+
def manual_formulas
|
125
|
+
@manual_formulas ||= formulas.reject(&:downloadable?)
|
103
126
|
end
|
104
127
|
|
105
128
|
def formulas
|
106
129
|
@formulas ||= Fontist::Formula.find_many(name)
|
130
|
+
.select { |f| supported_formula?(f) }
|
107
131
|
end
|
108
132
|
|
109
|
-
def
|
110
|
-
if formula
|
111
|
-
|
133
|
+
def supported_formula?(formula)
|
134
|
+
return true if formula.platforms.nil?
|
135
|
+
|
136
|
+
formula.platforms.any? do |platform|
|
137
|
+
Utils::System.match?(platform)
|
112
138
|
end
|
113
139
|
end
|
114
140
|
|
141
|
+
def downloadable_font
|
142
|
+
return if downloadable_formulas.empty?
|
143
|
+
|
144
|
+
raise Fontist::Errors::MissingFontError.new(name)
|
145
|
+
end
|
146
|
+
|
115
147
|
def download_font
|
116
|
-
return if
|
148
|
+
return if sufficient_formulas.empty?
|
117
149
|
|
118
|
-
|
150
|
+
sufficient_formulas.flat_map do |formula|
|
119
151
|
confirmation = check_and_confirm_required_license(formula)
|
120
152
|
paths = font_installer(formula).install(confirmation: confirmation)
|
121
153
|
|
@@ -165,6 +197,12 @@ module Fontist
|
|
165
197
|
MSG
|
166
198
|
end
|
167
199
|
|
200
|
+
def manual_font
|
201
|
+
return if manual_formulas.empty?
|
202
|
+
|
203
|
+
raise Fontist::Errors::ManualFontError.new(name, manual_formulas.first)
|
204
|
+
end
|
205
|
+
|
168
206
|
def uninstall_font
|
169
207
|
paths = find_fontist_paths
|
170
208
|
return unless paths
|
@@ -190,7 +228,7 @@ module Fontist
|
|
190
228
|
end
|
191
229
|
|
192
230
|
def all_formulas
|
193
|
-
Fontist::Formula.all
|
231
|
+
Fontist::Formula.all.select { |f| supported_formula?(f) }
|
194
232
|
end
|
195
233
|
|
196
234
|
def path(style)
|
@@ -215,7 +253,7 @@ module Fontist
|
|
215
253
|
|
216
254
|
def list_styles(formulas)
|
217
255
|
map_to_hash(formulas) do |formula|
|
218
|
-
map_to_hash(formula.fonts) do |font|
|
256
|
+
map_to_hash(requested_fonts(formula.fonts)) do |font|
|
219
257
|
map_to_hash(font.styles) do |style|
|
220
258
|
installed(style)
|
221
259
|
end
|
@@ -227,6 +265,14 @@ module Fontist
|
|
227
265
|
elements.map { |e| [e, yield(e)] }.to_h
|
228
266
|
end
|
229
267
|
|
268
|
+
def requested_fonts(fonts)
|
269
|
+
return fonts unless @name
|
270
|
+
|
271
|
+
fonts.select do |font|
|
272
|
+
font.name.casecmp?(name)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
230
276
|
def installed(style)
|
231
277
|
path(style) ? true : false
|
232
278
|
end
|
data/lib/fontist/formula.rb
CHANGED
@@ -59,6 +59,14 @@ module Fontist
|
|
59
59
|
Indexes::IndexFormula.new(path)
|
60
60
|
end
|
61
61
|
|
62
|
+
def manual?
|
63
|
+
!downloadable?
|
64
|
+
end
|
65
|
+
|
66
|
+
def downloadable?
|
67
|
+
@data.key?("resources")
|
68
|
+
end
|
69
|
+
|
62
70
|
def path
|
63
71
|
@path
|
64
72
|
end
|
@@ -91,16 +99,36 @@ module Fontist
|
|
91
99
|
@data["requires_license_agreement"] ? true : false
|
92
100
|
end
|
93
101
|
|
102
|
+
def platforms
|
103
|
+
@data["platforms"]
|
104
|
+
end
|
105
|
+
|
94
106
|
def extract
|
95
107
|
Helpers.parse_to_object(@data["extract"])
|
96
108
|
end
|
97
109
|
|
110
|
+
def file_size
|
111
|
+
return unless @data["resources"]
|
112
|
+
|
113
|
+
@data["resources"].values.first["file_size"]&.to_i
|
114
|
+
end
|
115
|
+
|
98
116
|
def resources
|
99
|
-
Helpers.parse_to_object(@data["resources"]
|
117
|
+
Helpers.parse_to_object(@data["resources"]&.values)
|
118
|
+
end
|
119
|
+
|
120
|
+
def instructions
|
121
|
+
@data["instructions"]
|
122
|
+
end
|
123
|
+
|
124
|
+
def fonts_by_name(name)
|
125
|
+
fonts.select do |font|
|
126
|
+
font.name.casecmp?(name)
|
127
|
+
end
|
100
128
|
end
|
101
129
|
|
102
130
|
def fonts
|
103
|
-
@fonts ||= Helpers.parse_to_object(
|
131
|
+
@fonts ||= Helpers.parse_to_object(fonts_by_family)
|
104
132
|
end
|
105
133
|
|
106
134
|
def digest
|
@@ -114,6 +142,41 @@ module Fontist
|
|
114
142
|
@path.sub(Regexp.new("^" + escaped), "").sub(/\.yml$/, "")
|
115
143
|
end
|
116
144
|
|
145
|
+
def fonts_by_family
|
146
|
+
return hash_all_fonts unless Fontist.preferred_family?
|
147
|
+
|
148
|
+
preferred_family_fonts
|
149
|
+
end
|
150
|
+
|
151
|
+
def preferred_family_fonts
|
152
|
+
groups = preferred_family_styles.group_by do |style|
|
153
|
+
style["family_name"]
|
154
|
+
end
|
155
|
+
|
156
|
+
groups.map do |font_name, font_styles|
|
157
|
+
{ "name" => font_name, "styles" => font_styles }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def preferred_family_styles
|
162
|
+
hash_all_fonts.flat_map do |font|
|
163
|
+
font["styles"].map do |style|
|
164
|
+
style.merge(preferred_style(style))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def preferred_style(style)
|
170
|
+
{ "family_name" => style["preferred_family_name"] || style["family_name"],
|
171
|
+
"type" => style["preferred_type"] || style["type"],
|
172
|
+
"default_family_name" => style["family_name"],
|
173
|
+
"default_type" => style["type"] }
|
174
|
+
end
|
175
|
+
|
176
|
+
def hash_all_fonts
|
177
|
+
hash_collection_fonts + hash_fonts
|
178
|
+
end
|
179
|
+
|
117
180
|
def hash_collection_fonts
|
118
181
|
return [] unless @data["font_collections"]
|
119
182
|
|
@@ -122,8 +185,7 @@ module Fontist
|
|
122
185
|
"source_font" => coll["source_filename"] }
|
123
186
|
|
124
187
|
coll["fonts"].map do |font|
|
125
|
-
|
126
|
-
"styles" => font["styles"].map { |s| filenames.merge(s) } }
|
188
|
+
font.merge("styles" => font["styles"].map { |s| filenames.merge(s) })
|
127
189
|
end
|
128
190
|
end
|
129
191
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require "fontist/style_version"
|
2
|
+
|
3
|
+
module Fontist
|
4
|
+
class FormulaPicker
|
5
|
+
def initialize(font_name, size_limit:, version:, smallest:, newest:)
|
6
|
+
@font_name = font_name
|
7
|
+
@size_limit = size_limit || Fontist.formula_size_limit_in_megabytes
|
8
|
+
@version = version
|
9
|
+
@smallest = smallest
|
10
|
+
@newest = newest
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(formulas)
|
14
|
+
return [] if formulas.size.zero?
|
15
|
+
return formulas if contain_different_styles?(formulas)
|
16
|
+
return by_version(formulas) if version_is_passed?
|
17
|
+
return newest(formulas) if newest_is_passed?
|
18
|
+
return smallest(formulas) if smallest_is_passed?
|
19
|
+
|
20
|
+
default_way(formulas)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def version_is_passed?
|
26
|
+
!@version.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def by_version(formulas)
|
30
|
+
formulas.each do |formula|
|
31
|
+
fonts = formula.fonts_by_name(@font_name)
|
32
|
+
fonts.each do |font|
|
33
|
+
font.styles.each do |style|
|
34
|
+
version = StyleVersion.new(style.version)
|
35
|
+
return [formula] if version == passed_version
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
|
43
|
+
def passed_version
|
44
|
+
@passed_version ||= StyleVersion.new(@version)
|
45
|
+
end
|
46
|
+
|
47
|
+
def newest_is_passed?
|
48
|
+
@newest
|
49
|
+
end
|
50
|
+
|
51
|
+
def newest(formulas)
|
52
|
+
newest_formulas = filter_by_max_version(formulas)
|
53
|
+
smallest(newest_formulas)
|
54
|
+
end
|
55
|
+
|
56
|
+
def smallest_is_passed?
|
57
|
+
@smallest
|
58
|
+
end
|
59
|
+
|
60
|
+
def smallest(formulas)
|
61
|
+
[choose_smallest_formula(formulas)]
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_way(formulas)
|
65
|
+
size_limited_formulas = filter_by_size_limit(formulas)
|
66
|
+
raise_size_limit_error if size_limited_formulas.empty?
|
67
|
+
newest(size_limited_formulas)
|
68
|
+
end
|
69
|
+
|
70
|
+
def contain_different_styles?(formulas)
|
71
|
+
styles_by_formula = formulas.map do |formula|
|
72
|
+
fonts = formula.fonts_by_name(@font_name)
|
73
|
+
styles = fonts.flat_map do |font|
|
74
|
+
font.styles.map(&:type)
|
75
|
+
end
|
76
|
+
|
77
|
+
styles.uniq.sort
|
78
|
+
end
|
79
|
+
|
80
|
+
styles_by_formula.uniq.size > 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def filter_by_size_limit(formulas)
|
84
|
+
formulas.select do |formula|
|
85
|
+
formula.file_size.nil? || formula.file_size < size_limit_in_bytes
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def size_limit_in_bytes
|
90
|
+
@size_limit_in_bytes ||= @size_limit * 1024 * 1024
|
91
|
+
end
|
92
|
+
|
93
|
+
def raise_size_limit_error
|
94
|
+
raise Errors::SizeLimitError,
|
95
|
+
"There are only formulas above the size limit " \
|
96
|
+
"(#{@size_limit} MB)."
|
97
|
+
end
|
98
|
+
|
99
|
+
def filter_by_max_version(formulas)
|
100
|
+
formulas_with_version = detect_formula_version(formulas)
|
101
|
+
max_version = formulas_with_version.map(&:first).max
|
102
|
+
formulas_with_version.select do |version, _formula|
|
103
|
+
version == max_version
|
104
|
+
end.map(&:last)
|
105
|
+
end
|
106
|
+
|
107
|
+
def detect_formula_version(formulas)
|
108
|
+
formulas.map do |formula|
|
109
|
+
fonts = formula.fonts_by_name(@font_name)
|
110
|
+
versions = fonts.flat_map do |font|
|
111
|
+
font.styles.map do |style|
|
112
|
+
StyleVersion.new(style.version)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
[versions.max, formula]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def choose_smallest_formula(formulas)
|
121
|
+
formulas.min_by do |formula|
|
122
|
+
formula.file_size || 0
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|