fontist 1.11.3 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +10 -2
- data/.rubocop.yml +0 -17
- data/README.adoc +37 -5
- data/fontist.gemspec +3 -1
- data/lib/fontist/cli.rb +13 -2
- data/lib/fontist/errors.rb +8 -0
- data/lib/fontist/font.rb +45 -14
- data/lib/fontist/font_installer.rb +17 -3
- data/lib/fontist/formula.rb +17 -1
- 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 +18 -13
- 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/repo.rb +13 -1
- data/lib/fontist/system.yml +1 -0
- data/lib/fontist/system_font.rb +1 -1
- data/lib/fontist/update.rb +11 -31
- data/lib/fontist/utils/downloader.rb +26 -13
- data/lib/fontist/utils/system.rb +10 -0
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +5 -1
- metadata +47 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 709582759b1009bae25d302ab0590ed5f6fe92fe55d68d1cb57c918942b4f005
|
4
|
+
data.tar.gz: 165f75a0625995d8fcc388d46a26168008383d98d2705cb1ea5ed519abe41e80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd3d62de512ff44e1d9b47c192889fdcefa5db9abea1f0966ac3d761c4ef5567fa547b7d57b4eda52720040d3ca82a03eec2e3d72b24d1f9522dbde1e092c625
|
7
|
+
data.tar.gz: 3adf2dcebf7714cc81fc3a6955ac69fdf7affe3e90a845f011f52d284332c856112bef7f8e98cf6d96175c043df299ad0965148ef96308b38c6eace46547ef52
|
data/.github/workflows/rspec.yml
CHANGED
@@ -14,7 +14,7 @@ jobs:
|
|
14
14
|
fail-fast: false
|
15
15
|
matrix:
|
16
16
|
ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
|
17
|
-
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
17
|
+
os: [ ubuntu-18.04, ubuntu-latest, windows-latest, macos-latest ]
|
18
18
|
experimental: [ false ]
|
19
19
|
|
20
20
|
steps:
|
@@ -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
@@ -1,22 +1,5 @@
|
|
1
1
|
inherit_from:
|
2
2
|
- 'https://raw.githubusercontent.com/fontist/oss-guides/master/ci/rubocop.yml'
|
3
3
|
|
4
|
-
AllCops:
|
5
|
-
Exclude:
|
6
|
-
- 'lib/fontist/import/google/fonts_public.pb.rb'
|
7
|
-
- 'lib/fontist/formula_template.rb'
|
8
|
-
|
9
4
|
Rails:
|
10
5
|
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'
|
data/README.adoc
CHANGED
@@ -618,7 +618,7 @@ repository https://github.com/fontist/formulas[formulas]:
|
|
618
618
|
|
619
619
|
[source,sh]
|
620
620
|
----
|
621
|
-
cd ~/.fontist/versions/
|
621
|
+
cd ~/.fontist/versions/{last_version}/formulas
|
622
622
|
git add Formulas/google
|
623
623
|
git commit -m "Google Fonts update"
|
624
624
|
git push
|
@@ -640,12 +640,44 @@ They can be updated with:
|
|
640
640
|
[source,sh]
|
641
641
|
----
|
642
642
|
fontist import-sil
|
643
|
-
cd ~/.fontist/formulas
|
644
|
-
git add Formulas/sil
|
643
|
+
cd ~/.fontist/versions/{last_version}/formulas
|
644
|
+
git add Formulas/sil
|
645
645
|
git commit -m "SIL fonts update"
|
646
646
|
git push
|
647
647
|
----
|
648
648
|
|
649
|
+
=== Dynamically importing formulas from macOS
|
650
|
+
|
651
|
+
macOS provides https://support.apple.com/en-om/HT211240#download[fonts] which
|
652
|
+
can be manually downloaded with the Font Book app. When such font is requested,
|
653
|
+
fontist prints information on how to install it.
|
654
|
+
|
655
|
+
In order to know which fonts are available in a current version of macOS,
|
656
|
+
for each version there is a formula containing all supported fonts.
|
657
|
+
|
658
|
+
A new formula can be generated with:
|
659
|
+
|
660
|
+
[source,sh]
|
661
|
+
----
|
662
|
+
fontist import macos --name "Big Sur" --fonts-link "https://support.apple.com/en-om/HT211240#download"
|
663
|
+
cd ~/.fontist/versions/{last_version}/formulas
|
664
|
+
git add Formulas/macos
|
665
|
+
git commit -m "Add Big Sur macOS formula"
|
666
|
+
git push
|
667
|
+
----
|
668
|
+
|
669
|
+
Here `--fonts-link` is a link to a page containing a list of available fonts
|
670
|
+
in the Font Book app.
|
671
|
+
|
672
|
+
If the import is run on a different version of macOS, then a proper version
|
673
|
+
should be set in the `platforms` attribute of the generated formula:
|
674
|
+
|
675
|
+
[source,yaml]
|
676
|
+
----
|
677
|
+
platforms:
|
678
|
+
- macos-20
|
679
|
+
----
|
680
|
+
|
649
681
|
|
650
682
|
== Development
|
651
683
|
|
@@ -685,8 +717,8 @@ one, please refer to its documentation.
|
|
685
717
|
There is an ability to use private fonts via private Fontist repositories.
|
686
718
|
|
687
719
|
A Fontist repository is a Git repo which contains YAML formula files. Formulas can be created
|
688
|
-
manually (see https://github.com/fontist/formulas/tree/master/Formulas
|
689
|
-
or
|
720
|
+
manually (see https://github.com/fontist/formulas/tree/master/Formulas[examples]),
|
721
|
+
or xref:Authoring Fontist formulas[auto-generated from an archive].
|
690
722
|
|
691
723
|
A repository can be either a HTTPS or SSH Git repo. In case of SSH, a
|
692
724
|
corresponding SSH key should be setup with `ssh-agent` in order to access this
|
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,10 +16,12 @@ 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
|
18
20
|
|
19
21
|
ERROR_TO_STATUS = {
|
20
22
|
Fontist::Errors::UnsupportedFontError => [STATUS_NON_SUPPORTED_FONT_ERROR],
|
21
23
|
Fontist::Errors::MissingFontError => [STATUS_MISSING_FONT_ERROR],
|
24
|
+
Fontist::Errors::ManualFontError => [STATUS_MANUAL_FONT_ERROR],
|
22
25
|
Fontist::Errors::LicensingError => [STATUS_LICENSING_ERROR],
|
23
26
|
Fontist::Errors::ManifestCouldNotBeFoundError => [STATUS_MANIFEST_COULD_NOT_BE_FOUND_ERROR,
|
24
27
|
"Manifest could not be found."],
|
@@ -167,6 +170,9 @@ module Fontist
|
|
167
170
|
desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
|
168
171
|
subcommand "repo", Fontist::RepoCLI
|
169
172
|
|
173
|
+
desc "import SUBCOMMAND ...ARGS", "Manage imports"
|
174
|
+
subcommand "import", Fontist::ImportCLI
|
175
|
+
|
170
176
|
desc "google SUBCOMMAND ...ARGS", "Manage Google formulas"
|
171
177
|
subcommand "google", Fontist::GoogleCLI
|
172
178
|
|
@@ -205,10 +211,15 @@ module Fontist
|
|
205
211
|
Fontist.ui.say(" #{font.name}")
|
206
212
|
|
207
213
|
styles.each do |style, installed|
|
214
|
+
opts = []
|
215
|
+
opts << "manual" if formula.manual?
|
216
|
+
opts << (installed ? "installed" : "uninstalled")
|
217
|
+
msg = " #{style.type} (#{opts.join(', ')})"
|
218
|
+
|
208
219
|
if installed
|
209
|
-
Fontist.ui.success(
|
220
|
+
Fontist.ui.success(msg)
|
210
221
|
else
|
211
|
-
Fontist.ui.error(
|
222
|
+
Fontist.ui.error(msg)
|
212
223
|
end
|
213
224
|
end
|
214
225
|
end
|
data/lib/fontist/errors.rb
CHANGED
@@ -72,6 +72,14 @@ module Fontist
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
class ManualFontError < FontError
|
76
|
+
def initialize(font, formula)
|
77
|
+
msg = "'#{font}' font is missing.\n\n#{formula.instructions}"
|
78
|
+
|
79
|
+
super(msg, font)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
75
83
|
class UnsupportedFontError < FontError
|
76
84
|
def initialize(font)
|
77
85
|
msg = <<~MSG.chomp
|
data/lib/fontist/font.rb
CHANGED
@@ -38,21 +38,25 @@ module Fontist
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def find
|
41
|
-
find_system_font || downloadable_font ||
|
41
|
+
find_system_font || downloadable_font || manual_font ||
|
42
|
+
raise_non_supported_font
|
42
43
|
end
|
43
44
|
|
44
45
|
def install
|
45
|
-
(find_system_font unless @force) || download_font ||
|
46
|
+
(find_system_font unless @force) || download_font || manual_font ||
|
47
|
+
raise_non_supported_font
|
46
48
|
end
|
47
49
|
|
48
50
|
def uninstall
|
49
|
-
uninstall_font || downloadable_font ||
|
51
|
+
uninstall_font || downloadable_font || manual_font ||
|
52
|
+
raise_non_supported_font
|
50
53
|
end
|
51
54
|
|
52
55
|
def status
|
53
56
|
return installed_paths unless @name
|
54
57
|
|
55
|
-
find_system_font || downloadable_font ||
|
58
|
+
find_system_font || downloadable_font || manual_font ||
|
59
|
+
raise_non_supported_font
|
56
60
|
end
|
57
61
|
|
58
62
|
def list
|
@@ -62,7 +66,7 @@ module Fontist
|
|
62
66
|
end
|
63
67
|
|
64
68
|
def all
|
65
|
-
|
69
|
+
all_formulas.map(&:fonts).flatten
|
66
70
|
end
|
67
71
|
|
68
72
|
private
|
@@ -98,24 +102,37 @@ module Fontist
|
|
98
102
|
FontInstaller.new(formula, no_progress: @no_progress)
|
99
103
|
end
|
100
104
|
|
101
|
-
def
|
102
|
-
@
|
105
|
+
def downloadable_formulas
|
106
|
+
@downloadable_formulas ||= formulas.select(&:downloadable?)
|
107
|
+
end
|
108
|
+
|
109
|
+
def manual_formulas
|
110
|
+
@manual_formulas ||= formulas.reject(&:downloadable?)
|
103
111
|
end
|
104
112
|
|
105
113
|
def formulas
|
106
114
|
@formulas ||= Fontist::Formula.find_many(name)
|
115
|
+
.select { |f| supported_formula?(f) }
|
107
116
|
end
|
108
117
|
|
109
|
-
def
|
110
|
-
if formula
|
111
|
-
|
118
|
+
def supported_formula?(formula)
|
119
|
+
return true if formula.platforms.nil?
|
120
|
+
|
121
|
+
formula.platforms.any? do |platform|
|
122
|
+
Utils::System.match?(platform)
|
112
123
|
end
|
113
124
|
end
|
114
125
|
|
126
|
+
def downloadable_font
|
127
|
+
return if downloadable_formulas.empty?
|
128
|
+
|
129
|
+
raise Fontist::Errors::MissingFontError.new(name)
|
130
|
+
end
|
131
|
+
|
115
132
|
def download_font
|
116
|
-
return if
|
133
|
+
return if downloadable_formulas.empty?
|
117
134
|
|
118
|
-
|
135
|
+
downloadable_formulas.flat_map do |formula|
|
119
136
|
confirmation = check_and_confirm_required_license(formula)
|
120
137
|
paths = font_installer(formula).install(confirmation: confirmation)
|
121
138
|
|
@@ -165,6 +182,12 @@ module Fontist
|
|
165
182
|
MSG
|
166
183
|
end
|
167
184
|
|
185
|
+
def manual_font
|
186
|
+
return if manual_formulas.empty?
|
187
|
+
|
188
|
+
raise Fontist::Errors::ManualFontError.new(name, manual_formulas.first)
|
189
|
+
end
|
190
|
+
|
168
191
|
def uninstall_font
|
169
192
|
paths = find_fontist_paths
|
170
193
|
return unless paths
|
@@ -190,7 +213,7 @@ module Fontist
|
|
190
213
|
end
|
191
214
|
|
192
215
|
def all_formulas
|
193
|
-
Fontist::Formula.all
|
216
|
+
Fontist::Formula.all.select { |f| supported_formula?(f) }
|
194
217
|
end
|
195
218
|
|
196
219
|
def path(style)
|
@@ -215,7 +238,7 @@ module Fontist
|
|
215
238
|
|
216
239
|
def list_styles(formulas)
|
217
240
|
map_to_hash(formulas) do |formula|
|
218
|
-
map_to_hash(formula.fonts) do |font|
|
241
|
+
map_to_hash(requested_fonts(formula.fonts)) do |font|
|
219
242
|
map_to_hash(font.styles) do |style|
|
220
243
|
installed(style)
|
221
244
|
end
|
@@ -227,6 +250,14 @@ module Fontist
|
|
227
250
|
elements.map { |e| [e, yield(e)] }.to_h
|
228
251
|
end
|
229
252
|
|
253
|
+
def requested_fonts(fonts)
|
254
|
+
return fonts unless @name
|
255
|
+
|
256
|
+
fonts.select do |font|
|
257
|
+
font.name.casecmp?(name)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
230
261
|
def installed(style)
|
231
262
|
path(style) ? true : false
|
232
263
|
end
|
@@ -54,16 +54,30 @@ module Fontist
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def download_file(source)
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
errors = []
|
58
|
+
source.urls.each do |request|
|
59
|
+
url = request.respond_to?(:url) ? request.url : request
|
60
|
+
Fontist.ui.say(%(Downloading font "#{@formula.key}" from #{url}))
|
60
61
|
|
62
|
+
result = try_download_file(request, source)
|
63
|
+
return result unless result.is_a?(Errors::InvalidResourceError)
|
64
|
+
|
65
|
+
errors << result
|
66
|
+
end
|
67
|
+
|
68
|
+
raise Errors::InvalidResourceError, errors.join(" ")
|
69
|
+
end
|
70
|
+
|
71
|
+
def try_download_file(request, source)
|
61
72
|
Fontist::Utils::Downloader.download(
|
62
73
|
request,
|
63
74
|
sha: source.sha256,
|
64
75
|
file_size: source.file_size,
|
65
76
|
progress_bar: !@no_progress
|
66
77
|
)
|
78
|
+
rescue Errors::InvalidResourceError => e
|
79
|
+
Fontist.ui.say(e.message)
|
80
|
+
e
|
67
81
|
end
|
68
82
|
|
69
83
|
def font_file?(path)
|
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,12 +99,20 @@ 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
|
|
98
110
|
def resources
|
99
|
-
Helpers.parse_to_object(@data["resources"]
|
111
|
+
Helpers.parse_to_object(@data["resources"]&.values)
|
112
|
+
end
|
113
|
+
|
114
|
+
def instructions
|
115
|
+
@data["instructions"]
|
100
116
|
end
|
101
117
|
|
102
118
|
def fonts
|
@@ -1,7 +1,5 @@
|
|
1
1
|
require "fontist/import"
|
2
2
|
require_relative "recursive_extraction"
|
3
|
-
require_relative "otf/font_file"
|
4
|
-
require_relative "files/collection_file"
|
5
3
|
require_relative "helpers/hash_helper"
|
6
4
|
require_relative "formula_builder"
|
7
5
|
|
@@ -14,21 +12,29 @@ module Fontist
|
|
14
12
|
end
|
15
13
|
|
16
14
|
def call
|
17
|
-
save(
|
15
|
+
save(builder)
|
18
16
|
end
|
19
17
|
|
20
18
|
private
|
21
19
|
|
22
|
-
def
|
20
|
+
def builder
|
23
21
|
builder = FormulaBuilder.new
|
24
|
-
builder
|
22
|
+
setup_strings(builder, archive)
|
23
|
+
setup_files(builder)
|
24
|
+
builder
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_strings(builder, archive)
|
25
28
|
builder.archive = archive
|
26
|
-
builder.
|
29
|
+
builder.url = @url
|
27
30
|
builder.options = @options
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_files(builder)
|
34
|
+
builder.extractor = extractor
|
28
35
|
builder.font_files = extractor.font_files
|
29
36
|
builder.font_collection_files = extractor.font_collection_files
|
30
37
|
builder.license_text = extractor.license_text
|
31
|
-
builder.formula
|
32
38
|
end
|
33
39
|
|
34
40
|
def extractor
|
@@ -48,10 +54,10 @@ module Fontist
|
|
48
54
|
Fontist::Utils::Downloader.download(url, progress_bar: true).path
|
49
55
|
end
|
50
56
|
|
51
|
-
def save(
|
52
|
-
filename = Import.name_to_filename(
|
57
|
+
def save(builder)
|
58
|
+
filename = Import.name_to_filename(builder.name)
|
53
59
|
path = @options[:formula_dir] ? File.join(@options[:formula_dir], filename) : filename
|
54
|
-
yaml = YAML.dump(Helpers::HashHelper.stringify_keys(
|
60
|
+
yaml = YAML.dump(Helpers::HashHelper.stringify_keys(builder.formula))
|
55
61
|
File.write(path, yaml)
|
56
62
|
path
|
57
63
|
end
|
@@ -9,11 +9,13 @@ module Fontist
|
|
9
9
|
FONT_LABELS = ["OpenType font data",
|
10
10
|
"TrueType Font data"].freeze
|
11
11
|
|
12
|
-
|
12
|
+
COLLECTION_LABELS = ["OpenType font collection data",
|
13
|
+
"TrueType font collection data"].freeze
|
13
14
|
|
14
15
|
FONT_EXTENSIONS = {
|
15
16
|
"OpenType font data" => "otf",
|
16
17
|
"TrueType Font data" => "ttf",
|
18
|
+
"OpenType font collection data" => "ttc",
|
17
19
|
"TrueType font collection data" => "ttc",
|
18
20
|
}.freeze
|
19
21
|
|
@@ -22,7 +24,7 @@ module Fontist
|
|
22
24
|
|
23
25
|
if brief.start_with?(*FONT_LABELS)
|
24
26
|
:font
|
25
|
-
elsif brief.start_with?(
|
27
|
+
elsif brief.start_with?(*COLLECTION_LABELS)
|
26
28
|
:collection
|
27
29
|
else
|
28
30
|
:other
|
@@ -4,36 +4,41 @@ require_relative "text_helper"
|
|
4
4
|
module Fontist
|
5
5
|
module Import
|
6
6
|
class FormulaBuilder
|
7
|
-
FORMULA_ATTRIBUTES = %i[
|
7
|
+
FORMULA_ATTRIBUTES = %i[description homepage resources
|
8
8
|
font_collections fonts extract copyright
|
9
9
|
license_url open_license digest command].freeze
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
attr_writer :archive,
|
12
|
+
:url,
|
13
|
+
:extractor,
|
14
|
+
:options,
|
15
|
+
:font_files,
|
16
|
+
:font_collection_files,
|
17
|
+
:license_text,
|
18
|
+
:homepage
|
18
19
|
|
19
20
|
def initialize
|
20
21
|
@options = {}
|
21
22
|
end
|
22
23
|
|
23
24
|
def formula
|
24
|
-
|
25
|
+
formula_attributes.map { |name| [name, send(name)] }.to_h.compact
|
25
26
|
end
|
26
27
|
|
27
|
-
private
|
28
|
-
|
29
28
|
def name
|
30
|
-
return options[:name] if options[:name]
|
29
|
+
return @options[:name] if @options[:name]
|
31
30
|
|
32
31
|
unique_names = both_fonts.map(&:family_name).uniq
|
33
32
|
TextHelper.longest_common_prefix(unique_names) ||
|
34
33
|
both_fonts.first.family_name
|
35
34
|
end
|
36
35
|
|
36
|
+
private
|
37
|
+
|
38
|
+
def formula_attributes
|
39
|
+
FORMULA_ATTRIBUTES
|
40
|
+
end
|
41
|
+
|
37
42
|
def both_fonts
|
38
43
|
@both_fonts ||= group_fonts
|
39
44
|
end
|
@@ -50,7 +55,7 @@ module Fontist
|
|
50
55
|
end
|
51
56
|
|
52
57
|
def homepage
|
53
|
-
both_fonts.map(&:homepage).compact.first
|
58
|
+
@options[:homepage] || both_fonts.map(&:homepage).compact.first
|
54
59
|
end
|
55
60
|
|
56
61
|
def resources
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require "plist"
|
2
|
+
require "nokogiri"
|
3
|
+
require "fontist/import"
|
4
|
+
require_relative "recursive_extraction"
|
5
|
+
require_relative "helpers/hash_helper"
|
6
|
+
require_relative "manual_formula_builder"
|
7
|
+
|
8
|
+
module Fontist
|
9
|
+
module Import
|
10
|
+
class Macos
|
11
|
+
FONT_XML = "/System/Library/AssetsV2/com_apple_MobileAsset_Font6/com_apple_MobileAsset_Font6.xml".freeze # rubocop:disable Layout/LineLength
|
12
|
+
DESCRIPTION = "Fonts included with macOS %<name>s".freeze
|
13
|
+
|
14
|
+
INSTRUCTIONS = <<~INSTRUCTIONS.freeze
|
15
|
+
To download and enable any of these fonts:
|
16
|
+
|
17
|
+
1. Open Font Book, which is in your Applications folder.
|
18
|
+
2. Select All Fonts in the sidebar, or use the Search field to find the font that you want to download. Fonts that are not already downloaded appear dimmed in the list of fonts.
|
19
|
+
3. Select the dimmed font and choose Edit > Download, or Control-click it and choose Download from the pop-up menu.
|
20
|
+
INSTRUCTIONS
|
21
|
+
|
22
|
+
def initialize(options = {})
|
23
|
+
@options = options
|
24
|
+
end
|
25
|
+
|
26
|
+
def call
|
27
|
+
downloadable_fonts = fetch_fonts_list
|
28
|
+
links = fetch_links(downloadable_fonts)
|
29
|
+
archives = download(links)
|
30
|
+
store_in_dir(archives) do |dir|
|
31
|
+
create_formula(dir)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def fetch_fonts_list
|
38
|
+
html = Net::HTTP.get(URI.parse(@options[:fonts_link]))
|
39
|
+
|
40
|
+
document = Nokogiri::HTML.parse(html)
|
41
|
+
document.css("#sections div.grid2col:nth-of-type(3) div ul > li",
|
42
|
+
"#sections div.grid2col:nth-of-type(4) div ul > li")
|
43
|
+
.map(&:text)
|
44
|
+
end
|
45
|
+
|
46
|
+
def fetch_links(downloadable_fonts)
|
47
|
+
data = Plist.parse_xml(FONT_XML)
|
48
|
+
assets = downloadable_assets(data, downloadable_fonts)
|
49
|
+
assets_links(assets)
|
50
|
+
end
|
51
|
+
|
52
|
+
def downloadable_assets(data, downloadable_fonts)
|
53
|
+
data["Assets"].select do |x|
|
54
|
+
x["FontInfo4"].any? do |i|
|
55
|
+
downloadable_fonts.find do |d|
|
56
|
+
d.start_with?(i["FontFamilyName"])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def assets_links(assets)
|
63
|
+
assets.map do |x|
|
64
|
+
x.values_at("__BaseURL", "__RelativePath").join
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def download(links)
|
69
|
+
links.map do |url|
|
70
|
+
Fontist::Utils::Downloader.download(url, progress_bar: true).path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def store_in_dir(archives)
|
75
|
+
Dir.mktmpdir do |dir|
|
76
|
+
archives.each do |archive|
|
77
|
+
FileUtils.ln(archive, dir)
|
78
|
+
end
|
79
|
+
|
80
|
+
yield dir
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_formula(archives_dir)
|
85
|
+
extractor = RecursiveExtraction.new(archives_dir)
|
86
|
+
path = save(formula(archives_dir, extractor))
|
87
|
+
Fontist.ui.success("Formula has been successfully created: #{path}")
|
88
|
+
|
89
|
+
path
|
90
|
+
end
|
91
|
+
|
92
|
+
def formula(archive, extractor)
|
93
|
+
builder = ManualFormulaBuilder.new
|
94
|
+
setup_strings(builder, archive)
|
95
|
+
setup_files(builder, extractor)
|
96
|
+
builder.formula
|
97
|
+
end
|
98
|
+
|
99
|
+
def setup_strings(builder, archive)
|
100
|
+
builder.url = archive
|
101
|
+
builder.archive = archive
|
102
|
+
builder.platforms = platforms
|
103
|
+
builder.instructions = instructions
|
104
|
+
builder.description = description
|
105
|
+
builder.options = builder_options
|
106
|
+
end
|
107
|
+
|
108
|
+
def platforms
|
109
|
+
major_version = Sys::Uname.release.split(".").first
|
110
|
+
|
111
|
+
["macos-#{major_version}"]
|
112
|
+
end
|
113
|
+
|
114
|
+
def instructions
|
115
|
+
INSTRUCTIONS.strip
|
116
|
+
end
|
117
|
+
|
118
|
+
def description
|
119
|
+
format(DESCRIPTION, name: @options[:name])
|
120
|
+
end
|
121
|
+
|
122
|
+
def builder_options
|
123
|
+
@options.merge(homepage: @options[:fonts_link])
|
124
|
+
end
|
125
|
+
|
126
|
+
def setup_files(builder, extractor)
|
127
|
+
builder.extractor = extractor
|
128
|
+
builder.font_files = extractor.font_files
|
129
|
+
builder.font_collection_files = extractor.font_collection_files
|
130
|
+
builder.license_text = extractor.license_text
|
131
|
+
end
|
132
|
+
|
133
|
+
def save(hash)
|
134
|
+
filename = Import.name_to_filename(@options[:name])
|
135
|
+
path = File.join(formula_dir, filename)
|
136
|
+
yaml = YAML.dump(Helpers::HashHelper.stringify_keys(hash))
|
137
|
+
File.write(path, yaml)
|
138
|
+
path
|
139
|
+
end
|
140
|
+
|
141
|
+
def formula_dir
|
142
|
+
@formula_dir ||= Fontist.formulas_path.join("macos").tap do |path|
|
143
|
+
FileUtils.mkdir_p(path) unless File.exist?(path)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "formula_builder"
|
2
|
+
|
3
|
+
module Fontist
|
4
|
+
module Import
|
5
|
+
class ManualFormulaBuilder < FormulaBuilder
|
6
|
+
attr_accessor :description,
|
7
|
+
:platforms,
|
8
|
+
:instructions
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def formula_attributes
|
13
|
+
@formula_attributes ||= super.dup.tap do |attrs|
|
14
|
+
attrs.delete(:resources)
|
15
|
+
attrs.delete(:open_license)
|
16
|
+
attrs.delete(:license_url)
|
17
|
+
attrs.delete(:copyright)
|
18
|
+
|
19
|
+
attrs.insert(attrs.index(:homepage) + 1, :platforms, :instructions)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fontist
|
2
|
+
class ImportCLI < Thor
|
3
|
+
desc "macos", "Create formula for on-demand macOS fonts"
|
4
|
+
option :name, desc: "Example: Big Sur", required: true
|
5
|
+
option :fonts_link,
|
6
|
+
desc: "A link to a list of available fonts in a current OS",
|
7
|
+
required: true
|
8
|
+
option :formulas_path, type: :string, desc: "Path to formulas"
|
9
|
+
def macos
|
10
|
+
if options[:formulas_path]
|
11
|
+
Fontist.formulas_path = Pathname.new(options[:formulas_path])
|
12
|
+
end
|
13
|
+
|
14
|
+
require_relative "import/macos"
|
15
|
+
Import::Macos.new(options).call
|
16
|
+
CLI::STATUS_SUCCESS
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/fontist/repo.rb
CHANGED
@@ -15,8 +15,20 @@ module Fontist
|
|
15
15
|
raise(Errors::RepoNotFoundError, "No such repo '#{name}'.")
|
16
16
|
end
|
17
17
|
|
18
|
-
Git.open(path)
|
18
|
+
git = Git.open(path)
|
19
|
+
git.pull("origin", git.current_branch)
|
20
|
+
|
19
21
|
Index.rebuild
|
22
|
+
rescue Git::GitExecuteError => e
|
23
|
+
raise Errors::RepoCouldNotBeUpdatedError.new(<<~MSG.chomp)
|
24
|
+
Formulas repo '#{name}' could not be updated.
|
25
|
+
Please consider reinitializing it with:
|
26
|
+
fontist remove #{name}
|
27
|
+
fontist setup #{name} REPO_URL
|
28
|
+
|
29
|
+
Git error:
|
30
|
+
#{e.message}
|
31
|
+
MSG
|
20
32
|
end
|
21
33
|
|
22
34
|
def remove(name)
|
data/lib/fontist/system.yml
CHANGED
@@ -14,6 +14,7 @@ system:
|
|
14
14
|
- /System/Library/Fonts/**/**.{ttf,ttc}
|
15
15
|
- /Users/{username}/Library/Fonts/**.{ttf,ttc}
|
16
16
|
- /Applications/Microsoft**/Contents/Resources/**/**.{ttf,ttc}
|
17
|
+
- /System/Library/AssetsV2/com_apple_MobileAsset_Font6/**/**.{ttf,ttc}
|
17
18
|
|
18
19
|
unix:
|
19
20
|
paths:
|
data/lib/fontist/system_font.rb
CHANGED
data/lib/fontist/update.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Fontist
|
2
2
|
class Update
|
3
|
-
VERSION = "v2".freeze
|
4
|
-
|
5
3
|
def self.call
|
6
|
-
new(
|
4
|
+
new(Fontist.formulas_version).call
|
7
5
|
end
|
8
6
|
|
9
7
|
def initialize(branch = "main")
|
@@ -30,7 +28,14 @@ module Fontist
|
|
30
28
|
depth: 1)
|
31
29
|
end
|
32
30
|
|
33
|
-
git =
|
31
|
+
git = if Dir.exist?(Fontist.formulas_repo_path.join(".git"))
|
32
|
+
Git.open(Fontist.formulas_repo_path)
|
33
|
+
else
|
34
|
+
Git.init(Fontist.formulas_repo_path.to_s).tap do |g|
|
35
|
+
g.add_remote("origin", Fontist.formulas_repo_url)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
34
39
|
return git.pull("origin", @branch) if git.current_branch == @branch
|
35
40
|
|
36
41
|
git.config("remote.origin.fetch",
|
@@ -41,36 +46,11 @@ module Fontist
|
|
41
46
|
end
|
42
47
|
|
43
48
|
def update_private_repos
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def update_repo(path)
|
50
|
-
Git.open(path).pull
|
51
|
-
rescue Git::GitExecuteError => e
|
52
|
-
name = repo_name(path)
|
53
|
-
raise Errors::RepoCouldNotBeUpdatedError.new(<<~MSG.chomp)
|
54
|
-
Formulas repo '#{name}' could not be updated.
|
55
|
-
Please consider reinitializing it with:
|
56
|
-
fontist remove #{name}
|
57
|
-
fontist setup #{name} REPO_URL
|
58
|
-
|
59
|
-
Git error:
|
60
|
-
#{e.message}
|
61
|
-
MSG
|
62
|
-
end
|
63
|
-
|
64
|
-
def private_repos
|
65
|
-
Dir.glob(Fontist.private_formulas_path.join("*")).select do |path|
|
66
|
-
File.directory?(path)
|
49
|
+
Repo.list.each do |name|
|
50
|
+
Repo.update(name)
|
67
51
|
end
|
68
52
|
end
|
69
53
|
|
70
|
-
def repo_name(path)
|
71
|
-
File.basename(path)
|
72
|
-
end
|
73
|
-
|
74
54
|
def rebuild_index
|
75
55
|
Index.rebuild
|
76
56
|
end
|
@@ -15,7 +15,7 @@ module Fontist
|
|
15
15
|
@file = file
|
16
16
|
@sha = [sha].flatten.compact
|
17
17
|
@file_size = file_size.to_i if file_size
|
18
|
-
@progress_bar =
|
18
|
+
@progress_bar = progress_bar
|
19
19
|
@cache = Cache.new
|
20
20
|
end
|
21
21
|
|
@@ -54,35 +54,48 @@ module Fontist
|
|
54
54
|
options[:download_path] || Fontist.root_path.join("tmp")
|
55
55
|
end
|
56
56
|
|
57
|
-
def
|
58
|
-
|
57
|
+
def download_file
|
58
|
+
tries = tries ? tries + 1 : 1
|
59
|
+
do_download_file
|
60
|
+
rescue Down::Error => e
|
61
|
+
retry if tries < 3
|
62
|
+
|
63
|
+
raise Fontist::Errors::InvalidResourceError,
|
64
|
+
"Invalid URL: #{@file}. Error: #{e.inspect}."
|
65
|
+
end
|
66
|
+
|
67
|
+
def do_download_file
|
68
|
+
progress_bar = create_progress_bar
|
69
|
+
file = do_download_file_with_progress_bar(progress_bar)
|
70
|
+
progress_bar.finish
|
71
|
+
file
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_progress_bar
|
75
|
+
if @progress_bar
|
59
76
|
ProgressBar.new(@file_size)
|
60
77
|
else
|
61
78
|
NullProgressBar.new(@file_size)
|
62
79
|
end
|
63
80
|
end
|
64
81
|
|
65
|
-
|
66
|
-
|
82
|
+
# rubocop:disable Metrics/MethodLength
|
83
|
+
def do_download_file_with_progress_bar(progress_bar)
|
84
|
+
Down.download(
|
67
85
|
url,
|
68
86
|
open_timeout: 10,
|
69
87
|
read_timeout: 10,
|
70
88
|
max_redirects: 10,
|
71
89
|
headers: headers,
|
72
90
|
content_length_proc: ->(content_length) {
|
73
|
-
|
91
|
+
progress_bar.total = content_length if content_length
|
74
92
|
},
|
75
93
|
progress_proc: -> (progress) {
|
76
|
-
|
94
|
+
progress_bar.increment(progress)
|
77
95
|
}
|
78
96
|
)
|
79
|
-
|
80
|
-
@progress_bar.finish
|
81
|
-
|
82
|
-
file
|
83
|
-
rescue Down::NotFound
|
84
|
-
raise(Fontist::Errors::InvalidResourceError.new("Invalid URL: #{@file}"))
|
85
97
|
end
|
98
|
+
# rubocop:enable Metrics/MethodLength
|
86
99
|
|
87
100
|
def url
|
88
101
|
@file.respond_to?(:url) ? @file.url : @file
|
data/lib/fontist/utils/system.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "sys/uname"
|
2
|
+
|
1
3
|
module Fontist
|
2
4
|
module Utils
|
3
5
|
module System
|
@@ -18,6 +20,14 @@ module Fontist
|
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
23
|
+
|
24
|
+
def self.user_os_with_version
|
25
|
+
"#{user_os}-#{Sys::Uname.release}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.match?(platform)
|
29
|
+
user_os_with_version.start_with?(platform)
|
30
|
+
end
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
data/lib/fontist/version.rb
CHANGED
data/lib/fontist.rb
CHANGED
@@ -44,7 +44,11 @@ module Fontist
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.fontist_version_path
|
47
|
-
Fontist.fontist_path.join("versions",
|
47
|
+
Fontist.fontist_path.join("versions", formulas_version)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.formulas_version
|
51
|
+
"v3"
|
48
52
|
end
|
49
53
|
|
50
54
|
def self.formulas_repo_url
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fontist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: down
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sys-uname
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.2'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: thor
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +108,20 @@ dependencies:
|
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '1.6'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: plist
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.0'
|
83
125
|
- !ruby/object:Gem::Dependency
|
84
126
|
name: excavate
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,20 +178,6 @@ dependencies:
|
|
136
178
|
- - ">="
|
137
179
|
- !ruby/object:Gem::Version
|
138
180
|
version: '0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: nokogiri
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '1.0'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '1.0'
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: rake
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -293,6 +321,8 @@ files:
|
|
293
321
|
- lib/fontist/import/google_import.rb
|
294
322
|
- lib/fontist/import/helpers/hash_helper.rb
|
295
323
|
- lib/fontist/import/helpers/system_helper.rb
|
324
|
+
- lib/fontist/import/macos.rb
|
325
|
+
- lib/fontist/import/manual_formula_builder.rb
|
296
326
|
- lib/fontist/import/otf/font_file.rb
|
297
327
|
- lib/fontist/import/otf_parser.rb
|
298
328
|
- lib/fontist/import/otf_style.rb
|
@@ -303,6 +333,7 @@ files:
|
|
303
333
|
- lib/fontist/import/sil_import.rb
|
304
334
|
- lib/fontist/import/template_helper.rb
|
305
335
|
- lib/fontist/import/text_helper.rb
|
336
|
+
- lib/fontist/import_cli.rb
|
306
337
|
- lib/fontist/index.rb
|
307
338
|
- lib/fontist/indexes/base_index.rb
|
308
339
|
- lib/fontist/indexes/default_family_font_index.rb
|