fontist 1.16.0 → 1.17.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/README.adoc +19 -0
- data/fontist.gemspec +1 -1
- data/lib/fontist/cli/class_options.rb +8 -1
- data/lib/fontist/cli.rb +9 -1
- data/lib/fontist/collection_file.rb +46 -0
- data/lib/fontist/errors.rb +4 -0
- data/lib/fontist/font_file.rb +109 -0
- data/lib/fontist/font_installer.rb +29 -3
- data/lib/fontist/formula.rb +4 -0
- data/lib/fontist/formula_picker.rb +91 -39
- data/lib/fontist/import/create_formula.rb +2 -2
- data/lib/fontist/import/otf/font_file.rb +3 -1
- data/lib/fontist/import/recursive_extraction.rb +14 -2
- data/lib/fontist/system_index.rb +18 -53
- data/lib/fontist/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91726c53a66563f2b0a32417d45d246617b85586cc7c9573b24c5b83533c5444
|
4
|
+
data.tar.gz: de8e1aba5de04fb720c85a6c98e708dcbae944bf439c15f4dc29c3f27e4d0831
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d05de7120339d223fc716ad1f99a60c80ec54deb37bbe77692cff0295d3ccc4b7263ae5bc2ed2beae3dc82f18f0684d85b47f01ca4c5730e04ec4cb82357be2c
|
7
|
+
data.tar.gz: 381a74039161a1e9d5ea9b560afbc9c551083c67462002f9c590da83fe69283fd8d0506983554c19d9f0ded9fba33a3b71a5d7db11a82d3689ebd7b885a9cfc2
|
data/README.adoc
CHANGED
@@ -73,6 +73,10 @@ All commands support the following global options:
|
|
73
73
|
NOTE: See <<preferred-family-change>> for the differences between
|
74
74
|
"`preferred family`" and "`default family`".
|
75
75
|
|
76
|
+
`-q, --quiet`:: Print as little information as possible, mostly critical errors.
|
77
|
+
|
78
|
+
`-v, --verbose`:: Set the log level to debug. It prints formulas excluded
|
79
|
+
during installation and information for developers of fontist.
|
76
80
|
|
77
81
|
=== Install fonts: `fontist install`
|
78
82
|
|
@@ -125,6 +129,12 @@ for the newest version of the font among formulas with size below a limit
|
|
125
129
|
NOTE: If styles of a font are spread among several formulas, then all
|
126
130
|
available styles from all formulas would be installed.
|
127
131
|
|
132
|
+
NOTE: Some formulas may have the `min_fontist` attribute, which defines the
|
133
|
+
minimum version of fontist by which they can be installed. If `fontist` is of a
|
134
|
+
older version, then the formula is avoided to use. In order to see which
|
135
|
+
formulas were excluded from the search, the `-v, --verbose` option can be
|
136
|
+
specified.
|
137
|
+
|
128
138
|
Supported options:
|
129
139
|
|
130
140
|
`-f, [--force]`:: Install even if already installed in system
|
@@ -969,6 +979,15 @@ $ fontist install --formula ms_truetype
|
|
969
979
|
|
970
980
|
WARNING: This section is only for Fontist maintainers.
|
971
981
|
|
982
|
+
=== Formulas versioning
|
983
|
+
|
984
|
+
To add a new attribute, change how formula is treated or completely replace the structure, there are 2 ways to change a formula format:
|
985
|
+
|
986
|
+
1. Use the `min_fontist` attribute in a formula. It sets a requirement for fontist to install the formula only if its version is equal or more than a specified version.
|
987
|
+
2. Use a new branch in the formulas repo, e.g. "v2", "v3", "v4", etc. After creating a new branch, it should be defined in https://github.com/fontist/fontist/blob/v1.16.0/lib/fontist.rb#L51[`Fontist.formulas_version`]
|
988
|
+
|
989
|
+
NOTE: Using a new branch would require all users to re-download the entire formulas repo. Since this method has a significant overhead, the former one (`min_fontist`) should be used whenever possible.
|
990
|
+
|
972
991
|
=== Dynamically importing formulas from Google Fonts
|
973
992
|
|
974
993
|
https://fonts.google.com[Google Fonts] provides probably the largest collection
|
data/fontist.gemspec
CHANGED
@@ -38,7 +38,7 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_runtime_dependency "git", "~> 1.0"
|
39
39
|
spec.add_runtime_dependency "ttfunk", "~> 1.6"
|
40
40
|
spec.add_runtime_dependency "plist", "~> 3.0"
|
41
|
-
spec.add_runtime_dependency "excavate", "~> 0.3"
|
41
|
+
spec.add_runtime_dependency "excavate", "~> 0.3", '>= 0.3.4'
|
42
42
|
spec.add_runtime_dependency "socksify", "~> 1.7"
|
43
43
|
|
44
44
|
spec.add_development_dependency "pry", "~> 0.14"
|
@@ -3,12 +3,19 @@ module Fontist
|
|
3
3
|
module ClassOptions
|
4
4
|
def handle_class_options(options)
|
5
5
|
Fontist.preferred_family = options[:preferred_family]
|
6
|
-
Fontist.log_level = options
|
6
|
+
Fontist.log_level = log_level(options)
|
7
7
|
|
8
8
|
if options[:formulas_path]
|
9
9
|
Fontist.formulas_path = Pathname.new(options[:formulas_path])
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
def log_level(options)
|
14
|
+
return :debug if options[:verbose]
|
15
|
+
return :fatal if options[:quiet]
|
16
|
+
|
17
|
+
:info
|
18
|
+
end
|
12
19
|
end
|
13
20
|
end
|
14
21
|
end
|
data/lib/fontist/cli.rb
CHANGED
@@ -25,6 +25,7 @@ module Fontist
|
|
25
25
|
STATUS_FORMULA_NOT_FOUND = 13
|
26
26
|
STATUS_FONTCONFIG_NOT_FOUND = 14
|
27
27
|
STATUS_FONTCONFIG_FILE_NOT_FOUND = 15
|
28
|
+
STATUS_FONTIST_VERSION_ERROR = 15
|
28
29
|
|
29
30
|
ERROR_TO_STATUS = {
|
30
31
|
Fontist::Errors::UnsupportedFontError => [STATUS_NON_SUPPORTED_FONT_ERROR],
|
@@ -50,6 +51,7 @@ module Fontist
|
|
50
51
|
Fontist::Errors::FontconfigNotFoundError => [STATUS_FONTCONFIG_NOT_FOUND],
|
51
52
|
Fontist::Errors::FontconfigFileNotFoundError =>
|
52
53
|
[STATUS_FONTCONFIG_FILE_NOT_FOUND],
|
54
|
+
Fontist::Errors::FontistVersionError => [STATUS_FONTIST_VERSION_ERROR],
|
53
55
|
}.freeze
|
54
56
|
|
55
57
|
def self.exit_on_failure?
|
@@ -65,6 +67,11 @@ module Fontist
|
|
65
67
|
type: :boolean,
|
66
68
|
desc: "Hide all messages"
|
67
69
|
|
70
|
+
class_option :verbose,
|
71
|
+
aliases: :v,
|
72
|
+
type: :boolean,
|
73
|
+
desc: "Print debug messages"
|
74
|
+
|
68
75
|
class_option :formulas_path, type: :string, desc: "Path to formulas"
|
69
76
|
|
70
77
|
desc "install FONT", "Install font"
|
@@ -179,9 +186,10 @@ module Fontist
|
|
179
186
|
desc "create-formula URL", "Create a new formula with fonts from URL"
|
180
187
|
option :name, desc: "Example: Times New Roman"
|
181
188
|
option :mirror, repeatable: true
|
182
|
-
option :subarchive, desc: "Subarchive to choose when there are several ones"
|
183
189
|
option :subdir, desc: "Subdirectory to take fonts from, starting with the " \
|
184
190
|
"root dir, e.g.: stixfonts-2.10/fonts/static_otf. May include `fnmatch` patterns."
|
191
|
+
option :file_pattern, desc: "File pattern, e.g. '*.otf'. " \
|
192
|
+
"Uses `fnmatch` patterns."
|
185
193
|
def create_formula(url)
|
186
194
|
handle_class_options(options)
|
187
195
|
require "fontist/import/create_formula"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "ttfunk"
|
2
|
+
|
3
|
+
module Fontist
|
4
|
+
class CollectionFile
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def from_path(path)
|
9
|
+
io = ::File.new(path, "rb")
|
10
|
+
|
11
|
+
yield new(build_collection(io))
|
12
|
+
ensure
|
13
|
+
io.close
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def build_collection(io)
|
19
|
+
TTFunk::Collection.new(io)
|
20
|
+
rescue StandardError => e
|
21
|
+
raise Errors::FontFileError,
|
22
|
+
"Font file could not be parsed: #{e.inspect}."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(ttfunk_collection)
|
27
|
+
@collection = ttfunk_collection
|
28
|
+
end
|
29
|
+
|
30
|
+
def count
|
31
|
+
@collection.count
|
32
|
+
end
|
33
|
+
|
34
|
+
def each
|
35
|
+
count.times do |index|
|
36
|
+
yield self[index]
|
37
|
+
end
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def [](index)
|
43
|
+
FontFile.from_collection_index(@collection, index)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/fontist/errors.rb
CHANGED
@@ -18,6 +18,10 @@ module Fontist
|
|
18
18
|
|
19
19
|
class FontIndexCorrupted < GeneralError; end
|
20
20
|
|
21
|
+
class FontFileError < GeneralError; end
|
22
|
+
|
23
|
+
class FontistVersionError < GeneralError; end
|
24
|
+
|
21
25
|
class FontNotFoundError < GeneralError; end
|
22
26
|
|
23
27
|
# for backward compatibility with metanorma,
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require "ttfunk"
|
2
|
+
|
3
|
+
module Fontist
|
4
|
+
class FontFile
|
5
|
+
PLATFORM_MACINTOSH = 1
|
6
|
+
PLATFORM_MICROSOFT = 3
|
7
|
+
|
8
|
+
ENCODING_MAC_ROMAN = 0
|
9
|
+
ENCODING_MS_UNICODE_BMP = 1
|
10
|
+
|
11
|
+
LANGUAGE_MAC_ENGLISH = 0
|
12
|
+
LANGUAGE_MS_ENGLISH_AMERICAN = 0x409
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def from_path(path)
|
16
|
+
content = File.read(path, mode: "rb")
|
17
|
+
|
18
|
+
from_content(content)
|
19
|
+
end
|
20
|
+
|
21
|
+
def from_content(content)
|
22
|
+
new(build_font(content))
|
23
|
+
end
|
24
|
+
|
25
|
+
def from_collection_index(collection, index)
|
26
|
+
new(build_font_from_collection_index(collection, index))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def build_font(content)
|
32
|
+
TTFunk::File.new(content)
|
33
|
+
rescue StandardError => e
|
34
|
+
raise_font_file_error(e)
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_font_from_collection_index(collection, index)
|
38
|
+
collection[index]
|
39
|
+
rescue StandardError => e
|
40
|
+
raise_font_file_error(e)
|
41
|
+
end
|
42
|
+
|
43
|
+
def raise_font_file_error(exception)
|
44
|
+
raise Errors::FontFileError,
|
45
|
+
"Font file could not be parsed: #{exception.inspect}."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(ttfunk_file)
|
50
|
+
@file = ttfunk_file
|
51
|
+
end
|
52
|
+
|
53
|
+
def full_name
|
54
|
+
english_name(main_name.font_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def family
|
58
|
+
english_name(main_name.font_family)
|
59
|
+
end
|
60
|
+
|
61
|
+
def subfamily
|
62
|
+
english_name(main_name.font_subfamily)
|
63
|
+
end
|
64
|
+
|
65
|
+
def preferred_family
|
66
|
+
return if main_name.preferred_family.empty?
|
67
|
+
|
68
|
+
english_name(main_name.preferred_family)
|
69
|
+
end
|
70
|
+
|
71
|
+
def preferred_subfamily
|
72
|
+
return if main_name.preferred_subfamily.empty?
|
73
|
+
|
74
|
+
english_name(main_name.preferred_subfamily)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def main_name
|
80
|
+
@main_name ||= @file.name
|
81
|
+
end
|
82
|
+
|
83
|
+
def english_name(name)
|
84
|
+
visible_characters(find_english(name))
|
85
|
+
end
|
86
|
+
|
87
|
+
def find_english(name)
|
88
|
+
name.find { |x| microsoft_english?(x) } ||
|
89
|
+
name.find { |x| mac_english?(x) } ||
|
90
|
+
name.last
|
91
|
+
end
|
92
|
+
|
93
|
+
def microsoft_english?(string)
|
94
|
+
string.platform_id == PLATFORM_MICROSOFT &&
|
95
|
+
string.encoding_id == ENCODING_MS_UNICODE_BMP &&
|
96
|
+
string.language_id == LANGUAGE_MS_ENGLISH_AMERICAN
|
97
|
+
end
|
98
|
+
|
99
|
+
def mac_english?(string)
|
100
|
+
string.platform_id == PLATFORM_MACINTOSH &&
|
101
|
+
string.encoding_id == ENCODING_MAC_ROMAN &&
|
102
|
+
string.language_id == LANGUAGE_MAC_ENGLISH
|
103
|
+
end
|
104
|
+
|
105
|
+
def visible_characters(text)
|
106
|
+
text.gsub(/[^[:print:]]/, "").to_s
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -10,9 +10,8 @@ module Fontist
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def install(confirmation:)
|
13
|
-
|
14
|
-
|
15
|
-
end
|
13
|
+
raise_fontist_version_error unless supported_version?
|
14
|
+
raise_licensing_error unless license_is_accepted?(confirmation)
|
16
15
|
|
17
16
|
install_font
|
18
17
|
end
|
@@ -21,6 +20,33 @@ module Fontist
|
|
21
20
|
|
22
21
|
attr_reader :formula
|
23
22
|
|
23
|
+
def supported_version?
|
24
|
+
return true unless @formula.min_fontist
|
25
|
+
|
26
|
+
fontist_version = Gem::Version.new(Fontist::VERSION)
|
27
|
+
min_fontist_required = Gem::Version.new(@formula.min_fontist)
|
28
|
+
|
29
|
+
fontist_version >= min_fontist_required
|
30
|
+
end
|
31
|
+
|
32
|
+
def raise_fontist_version_error
|
33
|
+
raise Fontist::Errors::FontistVersionError,
|
34
|
+
"Formula requires higher version of fontist. " \
|
35
|
+
"Please upgrade fontist.\n" \
|
36
|
+
"Minimum required version: #{formula.min_fontist}. " \
|
37
|
+
"Current fontist version: #{Fontist::VERSION}."
|
38
|
+
end
|
39
|
+
|
40
|
+
def license_is_accepted?(confirmation)
|
41
|
+
return true unless @formula.license_required
|
42
|
+
|
43
|
+
"yes".casecmp?(confirmation)
|
44
|
+
end
|
45
|
+
|
46
|
+
def raise_licensing_error
|
47
|
+
raise(Fontist::Errors::LicensingError)
|
48
|
+
end
|
49
|
+
|
24
50
|
def install_font
|
25
51
|
fonts_paths = run_in_temp_dir { extract }
|
26
52
|
fonts_paths.empty? ? nil : fonts_paths
|
data/lib/fontist/formula.rb
CHANGED
@@ -5,66 +5,117 @@ module Fontist
|
|
5
5
|
def initialize(font_name, size_limit:, version:, smallest:, newest:)
|
6
6
|
@font_name = font_name
|
7
7
|
@size_limit = size_limit || Fontist.formula_size_limit_in_megabytes
|
8
|
-
|
9
|
-
@
|
10
|
-
@
|
8
|
+
|
9
|
+
@options = {}
|
10
|
+
@version = @options[:version] = version if version
|
11
|
+
@smallest = @options[:smallest] = smallest if smallest
|
12
|
+
@newest = @options[:newest] = newest if newest
|
11
13
|
end
|
12
14
|
|
13
15
|
def call(formulas)
|
14
16
|
return [] if formulas.empty?
|
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
17
|
|
20
|
-
|
18
|
+
list = filter(formulas)
|
19
|
+
return [] if list.empty?
|
20
|
+
|
21
|
+
choose(list)
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
|
-
def
|
26
|
-
|
26
|
+
def filter(formulas)
|
27
|
+
list = formulas
|
28
|
+
|
29
|
+
list = filter_by_passed_version(formulas) if @version
|
30
|
+
return [] if list.empty?
|
31
|
+
|
32
|
+
list = ensure_size_limit(list) if @options.empty?
|
33
|
+
|
34
|
+
ensure_fontist_version(list)
|
27
35
|
end
|
28
36
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
def ensure_fontist_version(formulas)
|
38
|
+
suitable, unsuitable = filter_by_fontist_version(formulas)
|
39
|
+
raise_fontist_version_error(unsuitable) if suitable.empty?
|
40
|
+
|
41
|
+
suitable
|
42
|
+
end
|
43
|
+
|
44
|
+
def filter_by_fontist_version(formulas)
|
45
|
+
suitable, unsuitable = formulas.partition do |f|
|
46
|
+
f.min_fontist.nil? ||
|
47
|
+
Gem::Version.new(Fontist::VERSION) >= Gem::Version.new(f.min_fontist)
|
48
|
+
end
|
49
|
+
|
50
|
+
unless unsuitable.empty?
|
51
|
+
print_formulas_with_unsuitable_fontist_version(unsuitable)
|
52
|
+
end
|
53
|
+
|
54
|
+
[suitable, unsuitable]
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_formulas_with_unsuitable_fontist_version(formulas)
|
58
|
+
Fontist.ui.debug(
|
59
|
+
"Some formulas were excluded from choice, because they require " \
|
60
|
+
"higher version of fontist: #{formulas_versions(formulas)}. " \
|
61
|
+
"Current fontist version: #{Fontist::VERSION}.",
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def raise_fontist_version_error(formulas)
|
66
|
+
raise Fontist::Errors::FontistVersionError,
|
67
|
+
"Suitable formulas require higher version of fontist. " \
|
68
|
+
"Please upgrade fontist.\n" \
|
69
|
+
"Minimum required version: #{formulas_versions(formulas)}. " \
|
70
|
+
"Current fontist version: #{Fontist::VERSION}."
|
71
|
+
end
|
72
|
+
|
73
|
+
def formulas_versions(formulas)
|
74
|
+
formulas.map { |f| "#{f.key} (#{f.min_fontist})" }.join(", ")
|
75
|
+
end
|
76
|
+
|
77
|
+
def filter_by_passed_version(formulas)
|
78
|
+
formulas.select do |formula|
|
79
|
+
contain_passed_version?(formula)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def contain_passed_version?(formula)
|
84
|
+
fonts = formula.fonts_by_name(@font_name)
|
85
|
+
fonts.each do |font|
|
86
|
+
font.styles.each do |style|
|
87
|
+
version = StyleVersion.new(style.version)
|
88
|
+
return true if version == passed_version
|
37
89
|
end
|
38
90
|
end
|
39
91
|
|
40
|
-
|
92
|
+
false
|
41
93
|
end
|
42
94
|
|
43
95
|
def passed_version
|
44
96
|
@passed_version ||= StyleVersion.new(@version)
|
45
97
|
end
|
46
98
|
|
47
|
-
def
|
48
|
-
|
49
|
-
end
|
99
|
+
def choose(formulas)
|
100
|
+
return formulas if contain_different_styles?(formulas)
|
50
101
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
102
|
+
list = formulas
|
103
|
+
|
104
|
+
if @options.empty? || @newest
|
105
|
+
list = choose_max_version(list)
|
106
|
+
end
|
55
107
|
|
56
|
-
|
57
|
-
@smallest
|
108
|
+
smallest(list)
|
58
109
|
end
|
59
110
|
|
60
111
|
def smallest(formulas)
|
61
112
|
[choose_smallest_formula(formulas)]
|
62
113
|
end
|
63
114
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
115
|
+
def choose_smallest_formula(formulas)
|
116
|
+
formulas.min_by do |formula|
|
117
|
+
formula.file_size || 0
|
118
|
+
end
|
68
119
|
end
|
69
120
|
|
70
121
|
def contain_different_styles?(formulas)
|
@@ -80,6 +131,13 @@ module Fontist
|
|
80
131
|
styles_by_formula.uniq.size > 1
|
81
132
|
end
|
82
133
|
|
134
|
+
def ensure_size_limit(formulas)
|
135
|
+
list = filter_by_size_limit(formulas)
|
136
|
+
raise_size_limit_error if list.empty?
|
137
|
+
|
138
|
+
list
|
139
|
+
end
|
140
|
+
|
83
141
|
def filter_by_size_limit(formulas)
|
84
142
|
formulas.select do |formula|
|
85
143
|
formula.file_size.nil? || resources_cached?(formula) ||
|
@@ -97,7 +155,7 @@ module Fontist
|
|
97
155
|
"(#{@size_limit} MB)."
|
98
156
|
end
|
99
157
|
|
100
|
-
def
|
158
|
+
def choose_max_version(formulas)
|
101
159
|
formulas_with_version = detect_formula_version(formulas)
|
102
160
|
max_version = formulas_with_version.map(&:first).max
|
103
161
|
formulas_with_version.select do |version, _formula|
|
@@ -118,12 +176,6 @@ module Fontist
|
|
118
176
|
end
|
119
177
|
end
|
120
178
|
|
121
|
-
def choose_smallest_formula(formulas)
|
122
|
-
formulas.min_by do |formula|
|
123
|
-
formula.file_size || 0
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
179
|
def resources_cached?(formula)
|
128
180
|
Utils::Cache.new.already_fetched?(
|
129
181
|
formula.resources.flat_map(&:urls),
|
@@ -8,9 +8,10 @@ module Fontist
|
|
8
8
|
LICENSE_PATTERN =
|
9
9
|
/(ofl\.txt|ufl\.txt|licenses?\.txt|license(\.md)?|copying)$/i.freeze
|
10
10
|
|
11
|
-
def initialize(archive,
|
11
|
+
def initialize(archive, subdir: nil, file_pattern: nil)
|
12
12
|
@archive = archive
|
13
13
|
@subdir = subdir
|
14
|
+
@file_pattern = file_pattern
|
14
15
|
@operations = {}
|
15
16
|
@font_files = []
|
16
17
|
@collection_files = []
|
@@ -72,10 +73,11 @@ module Fontist
|
|
72
73
|
|
73
74
|
def extract_data(archive)
|
74
75
|
Excavate::Archive.new(path(archive)).files(recursive_packages: true) do |path|
|
76
|
+
Fontist.ui.debug(path)
|
75
77
|
next unless File.file?(path)
|
76
78
|
|
77
79
|
match_license(path)
|
78
|
-
match_font(path) if
|
80
|
+
match_font(path) if font_candidate?(path)
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
@@ -110,6 +112,10 @@ module Fontist
|
|
110
112
|
end
|
111
113
|
end
|
112
114
|
|
115
|
+
def font_candidate?(path)
|
116
|
+
font_directory?(path) && file_pattern?(path)
|
117
|
+
end
|
118
|
+
|
113
119
|
def font_directory?(path)
|
114
120
|
return true unless subdirectory_pattern
|
115
121
|
|
@@ -119,6 +125,12 @@ module Fontist
|
|
119
125
|
def subdirectory_pattern
|
120
126
|
@subdirectory_pattern ||= "*" + @subdir.chomp("/") if @subdir
|
121
127
|
end
|
128
|
+
|
129
|
+
def file_pattern?(path)
|
130
|
+
return true unless @file_pattern
|
131
|
+
|
132
|
+
File.fnmatch?(@file_pattern, File.basename(path))
|
133
|
+
end
|
122
134
|
end
|
123
135
|
end
|
124
136
|
end
|
data/lib/fontist/system_index.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require_relative "font_file"
|
2
|
+
require_relative "collection_file"
|
2
3
|
|
3
4
|
module Fontist
|
4
5
|
class SystemIndex
|
@@ -6,11 +7,11 @@ module Fontist
|
|
6
7
|
|
7
8
|
class DefaultFamily
|
8
9
|
def family_name(name)
|
9
|
-
name.
|
10
|
+
name.family
|
10
11
|
end
|
11
12
|
|
12
13
|
def type(name)
|
13
|
-
name.
|
14
|
+
name.subfamily
|
14
15
|
end
|
15
16
|
|
16
17
|
def transform_override_keys(dict)
|
@@ -20,15 +21,11 @@ module Fontist
|
|
20
21
|
|
21
22
|
class PreferredFamily
|
22
23
|
def family_name(name)
|
23
|
-
|
24
|
-
|
25
|
-
name.preferred_family
|
24
|
+
name.preferred_family || name.family
|
26
25
|
end
|
27
26
|
|
28
27
|
def type(name)
|
29
|
-
|
30
|
-
|
31
|
-
name.preferred_subfamily
|
28
|
+
name.preferred_subfamily || name.subfamily
|
32
29
|
end
|
33
30
|
|
34
31
|
def transform_override_keys(dict)
|
@@ -37,15 +34,6 @@ module Fontist
|
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
40
|
-
PLATFORM_MACINTOSH = 1
|
41
|
-
PLATFORM_MICROSOFT = 3
|
42
|
-
|
43
|
-
ENCODING_MAC_ROMAN = 0
|
44
|
-
ENCODING_MS_UNICODE_BMP = 1
|
45
|
-
|
46
|
-
LANGUAGE_MAC_ENGLISH = 0
|
47
|
-
LANGUAGE_MS_ENGLISH_AMERICAN = 0x409
|
48
|
-
|
49
37
|
ALLOWED_KEYS = %i[path full_name family_name type].freeze
|
50
38
|
|
51
39
|
def self.system_index
|
@@ -174,22 +162,26 @@ module Fontist
|
|
174
162
|
else
|
175
163
|
raise Errors::UnknownFontTypeError.new(path)
|
176
164
|
end
|
177
|
-
rescue
|
165
|
+
rescue Errors::FontFileError => e
|
166
|
+
print_recognition_error(e, path)
|
167
|
+
end
|
168
|
+
|
169
|
+
def print_recognition_error(exception, path)
|
178
170
|
Fontist.ui.error(<<~MSG.chomp)
|
179
|
-
#{
|
171
|
+
#{exception.inspect}
|
180
172
|
Warning: File at #{path} not recognized as a font file.
|
181
173
|
MSG
|
174
|
+
nil
|
182
175
|
end
|
183
176
|
|
184
177
|
def detect_file_font(path)
|
185
|
-
|
186
|
-
file = TTFunk::File.new(content)
|
178
|
+
file = FontFile.from_path(path)
|
187
179
|
|
188
180
|
parse_font(file, path)
|
189
181
|
end
|
190
182
|
|
191
183
|
def detect_collection_fonts(path)
|
192
|
-
|
184
|
+
CollectionFile.from_path(path) do |collection|
|
193
185
|
collection.map do |file|
|
194
186
|
parse_font(file, path)
|
195
187
|
end
|
@@ -197,43 +189,16 @@ module Fontist
|
|
197
189
|
end
|
198
190
|
|
199
191
|
def parse_font(file, path)
|
200
|
-
|
201
|
-
family_name = english_name(@family.family_name(x))
|
192
|
+
family_name = @family.family_name(file)
|
202
193
|
|
203
194
|
{
|
204
195
|
path: path,
|
205
|
-
full_name:
|
196
|
+
full_name: file.full_name,
|
206
197
|
family_name: family_name,
|
207
|
-
type:
|
198
|
+
type: @family.type(file),
|
208
199
|
}.merge(override_font_props(path, family_name))
|
209
200
|
end
|
210
201
|
|
211
|
-
def english_name(name)
|
212
|
-
visible_characters(find_english(name))
|
213
|
-
end
|
214
|
-
|
215
|
-
def find_english(name)
|
216
|
-
name.find { |x| microsoft_english?(x) } ||
|
217
|
-
name.find { |x| mac_english?(x) } ||
|
218
|
-
name.last
|
219
|
-
end
|
220
|
-
|
221
|
-
def microsoft_english?(string)
|
222
|
-
string.platform_id == PLATFORM_MICROSOFT &&
|
223
|
-
string.encoding_id == ENCODING_MS_UNICODE_BMP &&
|
224
|
-
string.language_id == LANGUAGE_MS_ENGLISH_AMERICAN
|
225
|
-
end
|
226
|
-
|
227
|
-
def mac_english?(string)
|
228
|
-
string.platform_id == PLATFORM_MACINTOSH &&
|
229
|
-
string.encoding_id == ENCODING_MAC_ROMAN &&
|
230
|
-
string.language_id == LANGUAGE_MAC_ENGLISH
|
231
|
-
end
|
232
|
-
|
233
|
-
def visible_characters(text)
|
234
|
-
text.gsub(/[^[:print:]]/, "").to_s
|
235
|
-
end
|
236
|
-
|
237
202
|
def override_font_props(path, font_name)
|
238
203
|
override = Formula.find_by_font_file(path)
|
239
204
|
&.style_override(font_name)&.to_h || {}
|
data/lib/fontist/version.rb
CHANGED
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.17.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: down
|
@@ -143,6 +143,9 @@ dependencies:
|
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0.3'
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 0.3.4
|
146
149
|
type: :runtime
|
147
150
|
prerelease: false
|
148
151
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -150,6 +153,9 @@ dependencies:
|
|
150
153
|
- - "~>"
|
151
154
|
- !ruby/object:Gem::Version
|
152
155
|
version: '0.3'
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 0.3.4
|
153
159
|
- !ruby/object:Gem::Dependency
|
154
160
|
name: socksify
|
155
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -299,8 +305,10 @@ files:
|
|
299
305
|
- lib/fontist/cache_cli.rb
|
300
306
|
- lib/fontist/cli.rb
|
301
307
|
- lib/fontist/cli/class_options.rb
|
308
|
+
- lib/fontist/collection_file.rb
|
302
309
|
- lib/fontist/errors.rb
|
303
310
|
- lib/fontist/font.rb
|
311
|
+
- lib/fontist/font_file.rb
|
304
312
|
- lib/fontist/font_installer.rb
|
305
313
|
- lib/fontist/font_path.rb
|
306
314
|
- lib/fontist/fontconfig.rb
|