fontist 1.10.0 → 1.11.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +804 -0
- data/exe/fontist +24 -2
- data/fontist.gemspec +4 -2
- data/lib/fontist/cli.rb +5 -10
- data/lib/fontist/formula.rb +4 -0
- data/lib/fontist/google_cli.rb +29 -0
- data/lib/fontist/import/files/collection_file.rb +10 -1
- data/lib/fontist/import/formula_builder.rb +25 -4
- data/lib/fontist/import/google/new_fonts_fetcher.rb +44 -33
- data/lib/fontist/import/google.rb +18 -0
- data/lib/fontist/import/google_check.rb +0 -7
- data/lib/fontist/import/google_import.rb +26 -142
- data/lib/fontist/import/helpers/system_helper.rb +1 -1
- data/lib/fontist/import/otf/font_file.rb +5 -1
- data/lib/fontist/import/otf_parser.rb +2 -0
- data/lib/fontist/import/recursive_extraction.rb +4 -1
- data/lib/fontist/index.rb +0 -27
- data/lib/fontist/system_font.rb +9 -6
- data/lib/fontist/system_index.rb +43 -29
- data/lib/fontist/update.rb +21 -7
- data/lib/fontist/utils/downloader.rb +15 -6
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +21 -15
- metadata +38 -28
- data/.github/workflows/check_google.yml +0 -28
- data/README.md +0 -570
- data/lib/fontist/formula_paths.rb +0 -44
- data/lib/fontist/import/google/fonts_public.md +0 -10
- data/lib/fontist/import/google/fonts_public.pb.rb +0 -71
- data/lib/fontist/import/google/fonts_public.proto +0 -46
data/exe/fontist
CHANGED
@@ -3,5 +3,27 @@
|
|
3
3
|
require "fontist"
|
4
4
|
require "fontist/cli"
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
fontist_cli = proc {
|
7
|
+
status_code = Fontist::CLI.start(ARGV)
|
8
|
+
exit status_code.is_a?(Integer) ? status_code : 1
|
9
|
+
}
|
10
|
+
|
11
|
+
if ENV["SOCKS_PROXY"]
|
12
|
+
require "socksify"
|
13
|
+
require "uri"
|
14
|
+
begin
|
15
|
+
proxy = URI.parse(ENV["SOCKS_PROXY"])
|
16
|
+
if proxy.userinfo
|
17
|
+
user, pass = proxy.userinfo.split(":")
|
18
|
+
TCPSocket::socks_username = user
|
19
|
+
TCPSocket::socks_password = pass
|
20
|
+
end
|
21
|
+
Socksify::proxy(proxy.host, proxy.port, &fontist_cli)
|
22
|
+
rescue URI::InvalidURIError
|
23
|
+
warn "Value of ENV.SOCKS_PROXY=#{ENV['SOCKS_PROXY']} is invalid! Droping it"
|
24
|
+
ENV.delete("SOCKS_PROXY")
|
25
|
+
fontist_cli.call
|
26
|
+
end
|
27
|
+
else
|
28
|
+
fontist_cli.call
|
29
|
+
end
|
data/fontist.gemspec
CHANGED
@@ -28,20 +28,22 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
29
29
|
|
30
30
|
spec.add_runtime_dependency "down", "~> 5.0"
|
31
|
+
spec.add_runtime_dependency "extract_ttc", "~> 0.1"
|
31
32
|
spec.add_runtime_dependency "thor", "~> 1.0.1"
|
32
33
|
spec.add_runtime_dependency "git", "~> 1.0"
|
33
34
|
spec.add_runtime_dependency "ttfunk", "~> 1.6"
|
34
35
|
spec.add_runtime_dependency "excavate", "~> 0.1"
|
35
36
|
|
36
|
-
spec.add_development_dependency "extract_ttc", "~> 0.1"
|
37
37
|
spec.add_development_dependency "pry"
|
38
38
|
spec.add_development_dependency "bundler", "~> 2.0"
|
39
39
|
spec.add_development_dependency "gem-release"
|
40
40
|
spec.add_development_dependency "nokogiri", "~> 1.0"
|
41
41
|
spec.add_development_dependency "rake", "~> 13"
|
42
42
|
spec.add_development_dependency "rspec", "~> 3.0"
|
43
|
+
spec.add_development_dependency "rspec-benchmark", "~> 0.6"
|
43
44
|
spec.add_development_dependency "rubocop", "1.5.2"
|
44
45
|
spec.add_development_dependency "rubocop-rails"
|
45
46
|
spec.add_development_dependency "rubocop-performance"
|
46
|
-
|
47
|
+
|
48
|
+
spec.add_runtime_dependency "socksify"
|
47
49
|
end
|
data/lib/fontist/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "fontist/repo_cli"
|
3
|
+
require "fontist/google_cli"
|
3
4
|
|
4
5
|
module Fontist
|
5
6
|
class CLI < Thor
|
@@ -149,18 +150,9 @@ module Fontist
|
|
149
150
|
It is done automatically when formulas are updated, or private formulas
|
150
151
|
are set up.
|
151
152
|
LONGDESC
|
152
|
-
option :main_repo, type: :boolean,
|
153
|
-
desc: "Updates indexes in the main repo (for backward " \
|
154
|
-
"compatibility with versions prior to 1.9)"
|
155
153
|
def rebuild_index
|
156
154
|
handle_class_options(options)
|
157
|
-
|
158
|
-
if options[:main_repo]
|
159
|
-
Fontist::Index.rebuild_for_main_repo
|
160
|
-
else
|
161
|
-
Fontist::Index.rebuild
|
162
|
-
end
|
163
|
-
|
155
|
+
Fontist::Index.rebuild
|
164
156
|
Fontist.ui.say("Formula index has been rebuilt.")
|
165
157
|
STATUS_SUCCESS
|
166
158
|
end
|
@@ -175,6 +167,9 @@ module Fontist
|
|
175
167
|
desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
|
176
168
|
subcommand "repo", Fontist::RepoCLI
|
177
169
|
|
170
|
+
desc "google SUBCOMMAND ...ARGS", "Manage Google formulas"
|
171
|
+
subcommand "google", Fontist::GoogleCLI
|
172
|
+
|
178
173
|
private
|
179
174
|
|
180
175
|
def handle_class_options(options)
|
data/lib/fontist/formula.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Fontist
|
2
|
+
class GoogleCLI < Thor
|
3
|
+
class_option :formulas_path, type: :string, desc: "Path to formulas"
|
4
|
+
|
5
|
+
desc "check", "Check Google fonts for updates"
|
6
|
+
def check
|
7
|
+
handle_class_options(options)
|
8
|
+
require "fontist/import/google_check"
|
9
|
+
Fontist::Import::GoogleCheck.new.call
|
10
|
+
CLI::STATUS_SUCCESS
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "import", "Import Google fonts"
|
14
|
+
def import
|
15
|
+
handle_class_options(options)
|
16
|
+
require "fontist/import/google_import"
|
17
|
+
Fontist::Import::GoogleImport.new.call
|
18
|
+
CLI::STATUS_SUCCESS
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def handle_class_options(options)
|
24
|
+
if options[:formulas_path]
|
25
|
+
Fontist.formulas_path = Pathname.new(options[:formulas_path])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -11,7 +11,7 @@ module Fontist
|
|
11
11
|
def initialize(path)
|
12
12
|
@path = path
|
13
13
|
@fonts = read
|
14
|
-
@extension =
|
14
|
+
@extension = detect_extension
|
15
15
|
end
|
16
16
|
|
17
17
|
def filename
|
@@ -46,6 +46,15 @@ module Fontist
|
|
46
46
|
File.join(tmp_dir, filename)
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
def detect_extension
|
51
|
+
base_extension = "ttc"
|
52
|
+
|
53
|
+
file_extension = File.extname(File.basename(@path)).sub(/^\./, "")
|
54
|
+
return file_extension if file_extension.casecmp?(base_extension)
|
55
|
+
|
56
|
+
base_extension
|
57
|
+
end
|
49
58
|
end
|
50
59
|
end
|
51
60
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "shellwords"
|
1
2
|
require_relative "text_helper"
|
2
3
|
|
3
4
|
module Fontist
|
@@ -5,7 +6,7 @@ module Fontist
|
|
5
6
|
class FormulaBuilder
|
6
7
|
FORMULA_ATTRIBUTES = %i[name description homepage resources
|
7
8
|
font_collections fonts extract copyright
|
8
|
-
license_url open_license].freeze
|
9
|
+
license_url open_license digest command].freeze
|
9
10
|
|
10
11
|
attr_accessor :archive,
|
11
12
|
:url,
|
@@ -49,7 +50,7 @@ module Fontist
|
|
49
50
|
end
|
50
51
|
|
51
52
|
def homepage
|
52
|
-
both_fonts.first
|
53
|
+
both_fonts.map(&:homepage).compact.first
|
53
54
|
end
|
54
55
|
|
55
56
|
def resources
|
@@ -59,6 +60,18 @@ module Fontist
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def resource_options
|
63
|
+
if @options[:skip_sha]
|
64
|
+
resource_options_without_sha
|
65
|
+
else
|
66
|
+
resource_options_with_sha
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def resource_options_without_sha
|
71
|
+
{ urls: [@url] + mirrors }
|
72
|
+
end
|
73
|
+
|
74
|
+
def resource_options_with_sha
|
62
75
|
urls = []
|
63
76
|
sha = []
|
64
77
|
downloads do |url, path|
|
@@ -146,11 +159,11 @@ module Fontist
|
|
146
159
|
end
|
147
160
|
|
148
161
|
def copyright
|
149
|
-
both_fonts.first
|
162
|
+
both_fonts.map(&:copyright).compact.first
|
150
163
|
end
|
151
164
|
|
152
165
|
def license_url
|
153
|
-
both_fonts.first
|
166
|
+
both_fonts.map(&:license_url).compact.first
|
154
167
|
end
|
155
168
|
|
156
169
|
def open_license
|
@@ -165,6 +178,14 @@ module Fontist
|
|
165
178
|
|
166
179
|
TextHelper.cleanup(@license_text)
|
167
180
|
end
|
181
|
+
|
182
|
+
def digest
|
183
|
+
@options[:digest]
|
184
|
+
end
|
185
|
+
|
186
|
+
def command
|
187
|
+
Shellwords.shelljoin(ARGV)
|
188
|
+
end
|
168
189
|
end
|
169
190
|
end
|
170
191
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require_relative "fonts_public.pb"
|
2
1
|
require_relative "../google"
|
3
2
|
require_relative "../otf_parser"
|
4
3
|
|
@@ -6,7 +5,7 @@ module Fontist
|
|
6
5
|
module Import
|
7
6
|
module Google
|
8
7
|
class NewFontsFetcher
|
9
|
-
REPO_PATH = Fontist.
|
8
|
+
REPO_PATH = Fontist.fontist_path.join("google", "fonts")
|
10
9
|
REPO_URL = "https://github.com/google/fonts.git".freeze
|
11
10
|
SKIPLIST_PATH = File.expand_path("skiplist.yml", __dir__)
|
12
11
|
|
@@ -25,7 +24,8 @@ module Fontist
|
|
25
24
|
if Dir.exist?(REPO_PATH)
|
26
25
|
`cd #{REPO_PATH} && git pull`
|
27
26
|
else
|
28
|
-
|
27
|
+
FileUtils.mkdir_p(File.dirname(REPO_PATH))
|
28
|
+
`git clone --depth 1 #{REPO_URL} #{REPO_PATH}`
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -53,23 +53,11 @@ module Fontist
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def new?(path)
|
56
|
-
|
57
|
-
return unless
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
def fetch_metadata(path)
|
63
|
-
metadata_path = File.join(path, "METADATA.pb")
|
64
|
-
return unless File.exists?(metadata_path)
|
65
|
-
|
66
|
-
::Google::Fonts::FamilyProto.parse_from_text(File.read(metadata_path))
|
67
|
-
end
|
68
|
-
|
69
|
-
def font_new?(metadata, path)
|
70
|
-
return if in_skiplist?(metadata.name)
|
71
|
-
return if up_to_date?(metadata, path)
|
72
|
-
return unless downloadable?(metadata.name)
|
56
|
+
metadata_name = Google.metadata_name(path)
|
57
|
+
return unless metadata_name
|
58
|
+
return if in_skiplist?(metadata_name)
|
59
|
+
return if up_to_date?(metadata_name, path)
|
60
|
+
return unless downloadable?(metadata_name)
|
73
61
|
|
74
62
|
true
|
75
63
|
end
|
@@ -79,29 +67,47 @@ module Fontist
|
|
79
67
|
@skiplist.include?(name)
|
80
68
|
end
|
81
69
|
|
82
|
-
def up_to_date?(
|
83
|
-
formula = formula(
|
70
|
+
def up_to_date?(metadata_name, path)
|
71
|
+
formula = formula(metadata_name)
|
84
72
|
return false unless formula
|
85
73
|
|
86
|
-
|
74
|
+
repo_digest_up_to_date?(formula, path) ||
|
75
|
+
fonts_up_to_date?(formula, path)
|
76
|
+
end
|
77
|
+
|
78
|
+
def repo_digest_up_to_date?(formula, path)
|
79
|
+
return unless formula.digest
|
87
80
|
|
88
|
-
|
89
|
-
|
81
|
+
formula.digest == Google.digest(path)
|
82
|
+
end
|
83
|
+
|
84
|
+
def fonts_up_to_date?(formula, path)
|
85
|
+
styles = formula_styles(formula)
|
86
|
+
repo_fonts(path).all? do |font|
|
87
|
+
style = styles.find { |s| s.font == repo_to_archive_name(font) }
|
88
|
+
return false unless style
|
89
|
+
|
90
|
+
otfinfo_version(font) == style.version
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
93
|
-
def formula
|
94
|
-
|
95
|
-
@formulas ||= Fontist::Formula.all
|
96
|
-
@formulas["Fontist::Formulas::#{klass}Font"]
|
94
|
+
def formula_styles(formula)
|
95
|
+
formula.fonts.map(&:styles).flatten
|
97
96
|
end
|
98
97
|
|
99
|
-
def
|
100
|
-
File.join(
|
98
|
+
def repo_fonts(path)
|
99
|
+
Dir.glob(File.join(path, "*.{ttf,otf}"))
|
101
100
|
end
|
102
101
|
|
103
|
-
def
|
104
|
-
|
102
|
+
def repo_to_archive_name(font_path)
|
103
|
+
File.basename(font_path)
|
104
|
+
.sub("[wght]", "-VariableFont_wght")
|
105
|
+
.sub("[opsz]", "-Regular-VariableFont_opsz")
|
106
|
+
end
|
107
|
+
|
108
|
+
def formula(font_name)
|
109
|
+
path = Fontist::Import::Google.formula_path(font_name)
|
110
|
+
Formula.new_from_file(path) if File.exist?(path)
|
105
111
|
end
|
106
112
|
|
107
113
|
def otfinfo_version(path)
|
@@ -110,10 +116,15 @@ module Fontist
|
|
110
116
|
end
|
111
117
|
|
112
118
|
def downloadable?(name)
|
119
|
+
retries ||= 0
|
120
|
+
retries += 1
|
113
121
|
Down.open("https://fonts.google.com/download?family=#{name}")
|
114
122
|
true
|
115
123
|
rescue Down::NotFound
|
116
124
|
false
|
125
|
+
rescue Down::TimeoutError
|
126
|
+
retry unless retries >= 3
|
127
|
+
false
|
117
128
|
end
|
118
129
|
end
|
119
130
|
end
|
@@ -1,11 +1,29 @@
|
|
1
1
|
module Fontist
|
2
2
|
module Import
|
3
3
|
module Google
|
4
|
+
def self.metadata_name(path)
|
5
|
+
metadata_path = File.join(path, "METADATA.pb")
|
6
|
+
return unless File.exists?(metadata_path)
|
7
|
+
|
8
|
+
File.foreach(metadata_path) do |line|
|
9
|
+
name = line.match(/^name: "(.+)"/)
|
10
|
+
return name[1] if name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
4
14
|
def self.formula_path(name)
|
5
15
|
filename = name.downcase.gsub(" ", "_") + ".yml"
|
6
16
|
Fontist.formulas_path.join("google", filename)
|
7
17
|
end
|
8
18
|
|
19
|
+
def self.digest(path)
|
20
|
+
checksums = Dir.glob(File.join(path, "*.{ttf,otf,ttc}"))
|
21
|
+
.sort
|
22
|
+
.map { |x| Digest::SHA256.file(x).to_s }
|
23
|
+
|
24
|
+
Digest::SHA256.hexdigest(checksums.to_s)
|
25
|
+
end
|
26
|
+
|
9
27
|
def self.style_version(text)
|
10
28
|
return unless text
|
11
29
|
|
@@ -4,17 +4,12 @@ module Fontist
|
|
4
4
|
module Import
|
5
5
|
class GoogleCheck
|
6
6
|
def call
|
7
|
-
fetch_formulas
|
8
7
|
fonts = new_fonts
|
9
8
|
indicate(fonts)
|
10
9
|
end
|
11
10
|
|
12
11
|
private
|
13
12
|
|
14
|
-
def fetch_formulas
|
15
|
-
Formula.update_formulas_repo
|
16
|
-
end
|
17
|
-
|
18
13
|
def new_fonts
|
19
14
|
Fontist::Import::Google::NewFontsFetcher.new(logging: true).call
|
20
15
|
end
|
@@ -26,8 +21,6 @@ module Fontist
|
|
26
21
|
new_paths.each do |path|
|
27
22
|
puts path
|
28
23
|
end
|
29
|
-
|
30
|
-
abort
|
31
24
|
end
|
32
25
|
end
|
33
26
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
require "erb"
|
2
2
|
require_relative "google"
|
3
3
|
require_relative "google/new_fonts_fetcher"
|
4
|
-
require_relative "
|
5
|
-
require_relative "template_helper"
|
6
|
-
require_relative "text_helper"
|
7
|
-
require_relative "otf_parser"
|
8
|
-
require_relative "otf_style"
|
4
|
+
require_relative "create_formula"
|
9
5
|
|
10
6
|
module Fontist
|
11
7
|
module Import
|
@@ -13,6 +9,7 @@ module Fontist
|
|
13
9
|
def call
|
14
10
|
fonts = new_fonts
|
15
11
|
create_formulas(fonts)
|
12
|
+
rebuild_index
|
16
13
|
end
|
17
14
|
|
18
15
|
private
|
@@ -22,161 +19,48 @@ module Fontist
|
|
22
19
|
end
|
23
20
|
|
24
21
|
def create_formulas(fonts)
|
22
|
+
return puts("Nothing to update") if fonts.empty?
|
23
|
+
|
25
24
|
puts "Creating formulas..."
|
26
25
|
fonts.each do |path|
|
27
26
|
create_formula(path)
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
def create_formula(
|
32
|
-
puts
|
33
|
-
metadata = fetch_metadata(path)
|
34
|
-
font = build_font(metadata, path)
|
35
|
-
save_formula(font)
|
36
|
-
end
|
30
|
+
def create_formula(font_path)
|
31
|
+
puts font_path
|
37
32
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
33
|
+
path = Fontist::Import::CreateFormula.new(
|
34
|
+
url(font_path),
|
35
|
+
name: Google.metadata_name(font_path),
|
36
|
+
formula_dir: formula_dir,
|
37
|
+
skip_sha: variable_style?(font_path),
|
38
|
+
digest: Google.digest(font_path),
|
39
|
+
).call
|
42
40
|
|
43
|
-
|
44
|
-
h = from_metadata(metadata)
|
45
|
-
.merge(from_otfinfo(path))
|
46
|
-
.merge(styles: styles_from_otfinfo(path, metadata.fonts))
|
47
|
-
.merge(from_license(path))
|
48
|
-
|
49
|
-
OpenStruct.new(h)
|
41
|
+
Fontist.ui.success("Formula has been successfully created: #{path}")
|
50
42
|
end
|
51
43
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
Hash.new.tap do |h|
|
56
|
-
h[:fullname] = metadata.name
|
57
|
-
h[:cleanname] = metadata.name.gsub(/ /, "")
|
58
|
-
h[:sha256] = sha256(metadata.name) unless variable_style?(metadata)
|
59
|
-
h[:copyright] = Fontist::Import::TextHelper.cleanup(copyright)
|
60
|
-
end
|
44
|
+
def url(path)
|
45
|
+
name = Google.metadata_name(path)
|
46
|
+
"https://fonts.google.com/download?family=#{ERB::Util.url_encode(name)}"
|
61
47
|
end
|
62
48
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
49
|
+
def formula_dir
|
50
|
+
@formula_dir ||= Fontist.formulas_path.join("google").tap do |path|
|
51
|
+
FileUtils.mkdir_p(path) unless File.exist?(path)
|
66
52
|
end
|
67
53
|
end
|
68
54
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Digest::SHA256.file(file).to_s
|
75
|
-
end
|
76
|
-
|
77
|
-
def from_license(path)
|
78
|
-
file = Dir.glob(File.join(path, "{OFL.txt,UFL.txt,LICENSE.txt}")).first
|
79
|
-
print "warn, no license, " unless file
|
80
|
-
return { license: "" } unless file
|
81
|
-
|
82
|
-
{ license: cleanup_text(File.read(file)) }
|
83
|
-
end
|
84
|
-
|
85
|
-
def cleanup_text(text)
|
86
|
-
text.rstrip
|
87
|
-
.gsub("\r\n", "\n")
|
88
|
-
.lines
|
89
|
-
.map(&:rstrip)
|
90
|
-
.drop_while(&:empty?)
|
91
|
-
.join("\n")
|
92
|
-
end
|
93
|
-
|
94
|
-
def from_otfinfo(path)
|
95
|
-
font_file = Dir.glob(File.join(path, "*.ttf")).first
|
96
|
-
otf = OtfParser.new(font_file).call
|
97
|
-
|
98
|
-
{ homepage: otf["Vendor URL"],
|
99
|
-
license_url: otf["License URL"] }
|
100
|
-
end
|
101
|
-
|
102
|
-
def styles_from_otfinfo(path, fonts)
|
103
|
-
fonts.map do |f|
|
104
|
-
file_path = File.join(path, f.filename)
|
105
|
-
info = OtfParser.new(file_path).call
|
106
|
-
OtfStyle.new(info, file_path).call
|
55
|
+
def variable_style?(path)
|
56
|
+
fonts = Dir.glob(File.join(path, "*.{ttf,otf}"))
|
57
|
+
fonts.any? do |font|
|
58
|
+
File.basename(font).match?(/\[(.+,)?(wght|opsz)\]/)
|
107
59
|
end
|
108
60
|
end
|
109
61
|
|
110
|
-
def
|
111
|
-
|
112
|
-
path = formula_path(font.fullname)
|
113
|
-
save_to_path(hash, path)
|
114
|
-
end
|
115
|
-
|
116
|
-
def formula_hash(font)
|
117
|
-
stringify_keys(name: font.cleanname.sub(/\S/, &:upcase),
|
118
|
-
description: font.fullname,
|
119
|
-
homepage: font.homepage,
|
120
|
-
resources: formula_resource(font),
|
121
|
-
fonts: [yaml_font(font)],
|
122
|
-
extract: { format: :zip },
|
123
|
-
copyright: font.copyright,
|
124
|
-
license_url: font.license_url,
|
125
|
-
open_license: font.license)
|
126
|
-
end
|
127
|
-
|
128
|
-
def stringify_keys(hash)
|
129
|
-
JSON.parse(hash.to_json)
|
130
|
-
end
|
131
|
-
|
132
|
-
def formula_resource(font)
|
133
|
-
encoded_name = ERB::Util.url_encode(font.fullname)
|
134
|
-
url = "https://fonts.google.com/download?family=#{encoded_name}"
|
135
|
-
|
136
|
-
options = {}
|
137
|
-
options[:urls] = [url]
|
138
|
-
options[:sha256] = font.sha256 if font.sha256
|
139
|
-
|
140
|
-
{ "#{font.cleanname}.zip" => options }
|
141
|
-
end
|
142
|
-
|
143
|
-
def yaml_font(font)
|
144
|
-
{ name: font.fullname,
|
145
|
-
styles: yaml_styles(font.styles) }
|
146
|
-
end
|
147
|
-
|
148
|
-
def yaml_styles(styles)
|
149
|
-
styles.map do |s|
|
150
|
-
yaml_style(s)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def yaml_style(style)
|
155
|
-
Hash.new.tap do |h|
|
156
|
-
h.merge!(family_name: style.family_name,
|
157
|
-
type: style.style,
|
158
|
-
full_name: style.full_name)
|
159
|
-
if style.preferred_family_name
|
160
|
-
h[:preferred_family_name] = style.preferred_family_name
|
161
|
-
end
|
162
|
-
h[:preferred_type] = style.preferred_style if style.preferred_style
|
163
|
-
h.merge!(style.to_h.select do |k, _|
|
164
|
-
%i(post_script_name version description copyright).include?(k)
|
165
|
-
end.compact)
|
166
|
-
h.merge!(font: fix_variable_filename(style.filename))
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def fix_variable_filename(filename)
|
171
|
-
filename.sub("[wght]", "-VariableFont_wght")
|
172
|
-
end
|
173
|
-
|
174
|
-
def formula_path(name)
|
175
|
-
Fontist::Import::Google.formula_path(name)
|
176
|
-
end
|
177
|
-
|
178
|
-
def save_to_path(hash, path)
|
179
|
-
File.write(path, YAML.dump(hash))
|
62
|
+
def rebuild_index
|
63
|
+
Fontist::Index.rebuild
|
180
64
|
end
|
181
65
|
end
|
182
66
|
end
|