fontist 1.9.3 → 1.11.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/.github/workflows/metanorma.yml +1 -1
- data/.github/workflows/rspec.yml +1 -1
- data/README.adoc +804 -0
- data/exe/fontist +24 -2
- data/fontist.gemspec +3 -2
- data/lib/fontist/cli.rb +23 -9
- data/lib/fontist/font.rb +8 -3
- 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 +30 -5
- 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 -138
- data/lib/fontist/import/helpers/system_helper.rb +1 -1
- data/lib/fontist/import/otf/font_file.rb +17 -4
- data/lib/fontist/import/otf_parser.rb +2 -0
- data/lib/fontist/import/otf_style.rb +10 -2
- data/lib/fontist/import/otfinfo/template.erb +6 -0
- data/lib/fontist/import/recursive_extraction.rb +2 -1
- data/lib/fontist/index.rb +4 -28
- data/lib/fontist/indexes/default_family_font_index.rb +21 -0
- data/lib/fontist/indexes/font_index.rb +8 -13
- data/lib/fontist/indexes/preferred_family_font_index.rb +24 -0
- data/lib/fontist/system_font.rb +6 -16
- data/lib/fontist/system_index.rb +108 -29
- data/lib/fontist/update.rb +2 -2
- data/lib/fontist/utils/downloader.rb +14 -6
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +43 -13
- metadata +26 -29
- data/.github/workflows/check_google.yml +0 -28
- data/README.md +0 -570
- data/lib/fontist/fontist_font.rb +0 -24
- 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,12 +28,12 @@ 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"
|
@@ -43,5 +43,6 @@ Gem::Specification.new do |spec|
|
|
43
43
|
spec.add_development_dependency "rubocop", "1.5.2"
|
44
44
|
spec.add_development_dependency "rubocop-rails"
|
45
45
|
spec.add_development_dependency "rubocop-performance"
|
46
|
-
|
46
|
+
|
47
|
+
spec.add_runtime_dependency "socksify"
|
47
48
|
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
|
@@ -32,6 +33,10 @@ module Fontist
|
|
32
33
|
false
|
33
34
|
end
|
34
35
|
|
36
|
+
class_option :preferred_family,
|
37
|
+
type: :boolean,
|
38
|
+
desc: "Use Preferred Family when available"
|
39
|
+
|
35
40
|
desc "install FONT", "Install font"
|
36
41
|
option :force, type: :boolean, aliases: :f,
|
37
42
|
desc: "Install even if it's already installed in system"
|
@@ -39,6 +44,7 @@ module Fontist
|
|
39
44
|
option :hide_licenses, type: :boolean, desc: "Hide license texts"
|
40
45
|
option :no_progress, type: :boolean, desc: "Hide download progress"
|
41
46
|
def install(font)
|
47
|
+
handle_class_options(options)
|
42
48
|
Fontist::Font.install(
|
43
49
|
font,
|
44
50
|
force: options[:force],
|
@@ -53,6 +59,7 @@ module Fontist
|
|
53
59
|
|
54
60
|
desc "uninstall/remove FONT", "Uninstall font by font or formula"
|
55
61
|
def uninstall(font)
|
62
|
+
handle_class_options(options)
|
56
63
|
fonts_paths = Fontist::Font.uninstall(font)
|
57
64
|
Fontist.ui.success("These fonts are removed:")
|
58
65
|
Fontist.ui.success(fonts_paths.join("\n"))
|
@@ -64,6 +71,7 @@ module Fontist
|
|
64
71
|
|
65
72
|
desc "status [FONT]", "Show paths of FONT or all fonts"
|
66
73
|
def status(font = nil)
|
74
|
+
handle_class_options(options)
|
67
75
|
paths = Fontist::Font.status(font)
|
68
76
|
return error("No font is installed.", STATUS_MISSING_FONT_ERROR) if paths.empty?
|
69
77
|
|
@@ -74,6 +82,7 @@ module Fontist
|
|
74
82
|
|
75
83
|
desc "list [FONT]", "List installation status of FONT or fonts in fontist"
|
76
84
|
def list(font = nil)
|
85
|
+
handle_class_options(options)
|
77
86
|
formulas = Fontist::Font.list(font)
|
78
87
|
print_list(formulas)
|
79
88
|
success
|
@@ -83,6 +92,7 @@ module Fontist
|
|
83
92
|
|
84
93
|
desc "update", "Update formulas"
|
85
94
|
def update
|
95
|
+
handle_class_options(options)
|
86
96
|
Formula.update_formulas_repo
|
87
97
|
Fontist.ui.success("Formulas have been successfully updated.")
|
88
98
|
success
|
@@ -94,6 +104,7 @@ module Fontist
|
|
94
104
|
desc "manifest-locations MANIFEST",
|
95
105
|
"Get locations of fonts from MANIFEST (yaml)"
|
96
106
|
def manifest_locations(manifest)
|
107
|
+
handle_class_options(options)
|
97
108
|
paths = Fontist::Manifest::Locations.from_file(manifest)
|
98
109
|
print_yaml(paths)
|
99
110
|
success
|
@@ -105,6 +116,7 @@ module Fontist
|
|
105
116
|
option :accept_all_licenses, type: :boolean, aliases: "--confirm-license", desc: "Accept all license agreements"
|
106
117
|
option :hide_licenses, type: :boolean, desc: "Hide license texts"
|
107
118
|
def manifest_install(manifest)
|
119
|
+
handle_class_options(options)
|
108
120
|
paths = Fontist::Manifest::Install.from_file(
|
109
121
|
manifest,
|
110
122
|
confirmation: options[:accept_all_licenses] ? "yes" : "no",
|
@@ -124,6 +136,7 @@ module Fontist
|
|
124
136
|
option :subdir, desc: "Subdirectory to take fonts from, starting with the " \
|
125
137
|
"root dir, e.g.: stixfonts-2.10/fonts/static_otf. May include `fnmatch` patterns."
|
126
138
|
def create_formula(url)
|
139
|
+
handle_class_options(options)
|
127
140
|
require "fontist/import/create_formula"
|
128
141
|
name = Fontist::Import::CreateFormula.new(url, options).call
|
129
142
|
Fontist.ui.say("#{name} formula has been successfully created")
|
@@ -137,22 +150,16 @@ module Fontist
|
|
137
150
|
It is done automatically when formulas are updated, or private formulas
|
138
151
|
are set up.
|
139
152
|
LONGDESC
|
140
|
-
option :main_repo, type: :boolean,
|
141
|
-
desc: "Updates indexes in the main repo (for backward " \
|
142
|
-
"compatibility with versions prior to 1.9)"
|
143
153
|
def rebuild_index
|
144
|
-
|
145
|
-
|
146
|
-
else
|
147
|
-
Fontist::Index.rebuild
|
148
|
-
end
|
149
|
-
|
154
|
+
handle_class_options(options)
|
155
|
+
Fontist::Index.rebuild
|
150
156
|
Fontist.ui.say("Formula index has been rebuilt.")
|
151
157
|
STATUS_SUCCESS
|
152
158
|
end
|
153
159
|
|
154
160
|
desc "import-sil", "Import formulas from SIL"
|
155
161
|
def import_sil
|
162
|
+
handle_class_options(options)
|
156
163
|
require "fontist/import/sil_import"
|
157
164
|
Fontist::Import::SilImport.new.call
|
158
165
|
end
|
@@ -160,8 +167,15 @@ module Fontist
|
|
160
167
|
desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
|
161
168
|
subcommand "repo", Fontist::RepoCLI
|
162
169
|
|
170
|
+
desc "google SUBCOMMAND ...ARGS", "Manage Google formulas"
|
171
|
+
subcommand "google", Fontist::GoogleCLI
|
172
|
+
|
163
173
|
private
|
164
174
|
|
175
|
+
def handle_class_options(options)
|
176
|
+
Fontist.preferred_family = options[:preferred_family]
|
177
|
+
end
|
178
|
+
|
165
179
|
def success
|
166
180
|
STATUS_SUCCESS
|
167
181
|
end
|
data/lib/fontist/font.rb
CHANGED
@@ -166,7 +166,7 @@ module Fontist
|
|
166
166
|
end
|
167
167
|
|
168
168
|
def uninstall_font
|
169
|
-
paths =
|
169
|
+
paths = find_fontist_paths
|
170
170
|
return unless paths
|
171
171
|
|
172
172
|
paths.each do |path|
|
@@ -176,8 +176,13 @@ module Fontist
|
|
176
176
|
paths
|
177
177
|
end
|
178
178
|
|
179
|
-
def
|
180
|
-
Fontist::
|
179
|
+
def find_fontist_paths
|
180
|
+
fonts = Fontist::SystemIndex.fontist_index.find(name, nil)
|
181
|
+
return unless fonts
|
182
|
+
|
183
|
+
fonts.map do |font|
|
184
|
+
font[:path]
|
185
|
+
end
|
181
186
|
end
|
182
187
|
|
183
188
|
def installed_paths
|
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|
|
@@ -129,7 +142,7 @@ module Fontist
|
|
129
142
|
|
130
143
|
fonts = groups.map do |name, group|
|
131
144
|
{ name: name,
|
132
|
-
styles: group
|
145
|
+
styles: styles_from_files(group, style_type) }
|
133
146
|
end
|
134
147
|
|
135
148
|
fonts.sort_by do |x|
|
@@ -137,16 +150,20 @@ module Fontist
|
|
137
150
|
end
|
138
151
|
end
|
139
152
|
|
153
|
+
def styles_from_files(files, style_type)
|
154
|
+
files.map(&style_type).sort_by { |x| x[:type] }
|
155
|
+
end
|
156
|
+
|
140
157
|
def extract
|
141
158
|
@extractor.operations
|
142
159
|
end
|
143
160
|
|
144
161
|
def copyright
|
145
|
-
both_fonts.first
|
162
|
+
both_fonts.map(&:copyright).compact.first
|
146
163
|
end
|
147
164
|
|
148
165
|
def license_url
|
149
|
-
both_fonts.first
|
166
|
+
both_fonts.map(&:license_url).compact.first
|
150
167
|
end
|
151
168
|
|
152
169
|
def open_license
|
@@ -161,6 +178,14 @@ module Fontist
|
|
161
178
|
|
162
179
|
TextHelper.cleanup(@license_text)
|
163
180
|
end
|
181
|
+
|
182
|
+
def digest
|
183
|
+
@options[:digest]
|
184
|
+
end
|
185
|
+
|
186
|
+
def command
|
187
|
+
Shellwords.shelljoin(ARGV)
|
188
|
+
end
|
164
189
|
end
|
165
190
|
end
|
166
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
|