fontist 1.8.12 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,10 +3,9 @@ require_relative "formula_paths"
3
3
 
4
4
  module Fontist
5
5
  class SystemFont
6
- def initialize(font:, style: nil, sources: nil)
6
+ def initialize(font:, style: nil)
7
7
  @font = font
8
8
  @style = style
9
- @user_sources = sources || []
10
9
  end
11
10
 
12
11
  def self.font_paths
@@ -36,8 +35,8 @@ module Fontist
36
35
  Dir.glob(Fontist.fonts_path.join("**"))
37
36
  end
38
37
 
39
- def self.find(font, sources: [])
40
- new(font: font, sources: sources).find
38
+ def self.find(font)
39
+ new(font: font).find
41
40
  end
42
41
 
43
42
  def self.find_styles(font, style)
@@ -57,18 +56,14 @@ module Fontist
57
56
 
58
57
  private
59
58
 
60
- attr_reader :font, :style, :user_sources
59
+ attr_reader :font, :style
61
60
 
62
61
  def find_by_index
63
- SystemIndex.new(all_paths).find(font, style)
62
+ SystemIndex.system_index.find(font, style)
64
63
  end
65
64
 
66
65
  def find_by_formulas
67
- FormulaPaths.new(all_paths).find(font, style)
68
- end
69
-
70
- def all_paths
71
- @all_paths ||= Dir.glob(user_sources) + self.class.font_paths
66
+ FormulaPaths.new(self.class.font_paths).find(font, style)
72
67
  end
73
68
  end
74
69
  end
@@ -4,22 +4,73 @@ module Fontist
4
4
  class SystemIndex
5
5
  include Utils::Locking
6
6
 
7
+ class DefaultFamily
8
+ def family_name(name)
9
+ name.font_family
10
+ end
11
+
12
+ def type(name)
13
+ name.font_subfamily
14
+ end
15
+ end
16
+
17
+ class PreferredFamily
18
+ def family_name(name)
19
+ return name.font_family if name.preferred_family.empty?
20
+
21
+ name.preferred_family
22
+ end
23
+
24
+ def type(name)
25
+ return name.font_subfamily if name.preferred_subfamily.empty?
26
+
27
+ name.preferred_subfamily
28
+ end
29
+ end
30
+
31
+ PLATFORM_MACINTOSH = 1
32
+ PLATFORM_MICROSOFT = 3
33
+
34
+ ENCODING_MAC_ROMAN = 0
35
+ ENCODING_MS_UNICODE_BMP = 1
36
+
37
+ LANGUAGE_MAC_ENGLISH = 0
38
+ LANGUAGE_MS_ENGLISH_AMERICAN = 0x409
39
+
7
40
  attr_reader :font_paths
8
41
 
9
- def self.find(font, style)
10
- new(SystemFont.font_paths).find(font, style)
42
+ def self.system_index
43
+ if Fontist.preferred_family?
44
+ new(Fontist.system_preferred_family_index_path,
45
+ SystemFont.font_paths,
46
+ PreferredFamily.new)
47
+ else
48
+ new(Fontist.system_index_path,
49
+ SystemFont.font_paths,
50
+ DefaultFamily.new)
51
+ end
11
52
  end
12
53
 
13
- def self.rebuild
14
- new(SystemFont.font_paths).rebuild
54
+ def self.fontist_index
55
+ if Fontist.preferred_family?
56
+ new(Fontist.fontist_preferred_family_index_path,
57
+ SystemFont.fontist_font_paths,
58
+ PreferredFamily.new)
59
+ else
60
+ new(Fontist.fontist_index_path,
61
+ SystemFont.fontist_font_paths,
62
+ DefaultFamily.new)
63
+ end
15
64
  end
16
65
 
17
- def initialize(font_paths)
66
+ def initialize(index_path, font_paths, family)
67
+ @index_path = index_path
18
68
  @font_paths = font_paths
69
+ @family = family
19
70
  end
20
71
 
21
72
  def find(font, style)
22
- fonts = system_index.select do |file|
73
+ fonts = index.select do |file|
23
74
  file[:family_name].casecmp?(font) &&
24
75
  (style.nil? || file[:type].casecmp?(style))
25
76
  end
@@ -28,27 +79,27 @@ module Fontist
28
79
  end
29
80
 
30
81
  def rebuild
31
- build_system_index
82
+ build_index
32
83
  end
33
84
 
34
85
  private
35
86
 
36
- def system_index
37
- @system_index ||= build_system_index
87
+ def index
88
+ @index ||= build_index
38
89
  end
39
90
 
40
- def build_system_index
91
+ def build_index
41
92
  lock(lock_path) do
42
- do_build_system_index
93
+ do_build_index
43
94
  end
44
95
  end
45
96
 
46
97
  def lock_path
47
- Fontist.system_index_path.to_s + ".lock"
98
+ "#{@index_path}.lock"
48
99
  end
49
100
 
50
- def do_build_system_index
51
- previous_index = load_system_index
101
+ def do_build_index
102
+ previous_index = load_index
52
103
  updated_index = detect_paths(font_paths, previous_index)
53
104
  updated_index.tap do |index|
54
105
  save_index(index) if changed?(updated_index, previous_index)
@@ -59,21 +110,23 @@ module Fontist
59
110
  this.map { |x| x[:path] }.uniq.sort != other.map { |x| x[:path] }.uniq.sort
60
111
  end
61
112
 
62
- def load_system_index
63
- index = File.exist?(Fontist.system_index_path) ? YAML.load_file(Fontist.system_index_path) : []
113
+ def load_index
114
+ index = File.exist?(@index_path) ? YAML.load_file(@index_path) : []
115
+ check_index(index)
116
+ index
117
+ end
64
118
 
119
+ def check_index(index)
65
120
  index.each do |item|
66
121
  missing_keys = %i[path full_name family_name type] - item.keys
67
122
  unless missing_keys.empty?
68
123
  raise(Errors::FontIndexCorrupted, <<~MSG.chomp)
69
124
  Font index is corrupted.
70
125
  Item #{item.inspect} misses required attributes: #{missing_keys.join(', ')}.
71
- You can remove the index file (#{Fontist.system_index_path}) and try again.
126
+ You can remove the index file (#{@index_path}) and try again.
72
127
  MSG
73
128
  end
74
129
  end
75
-
76
- index
77
130
  end
78
131
 
79
132
  def detect_paths(paths, index)
@@ -83,7 +136,7 @@ module Fontist
83
136
  next by_path[path] if by_path[path]
84
137
 
85
138
  detect_fonts(path)
86
- end
139
+ end.compact
87
140
  end
88
141
 
89
142
  def detect_fonts(path)
@@ -98,8 +151,13 @@ module Fontist
98
151
  end
99
152
 
100
153
  def detect_file_font(path)
101
- file = TTFunk::File.open(path)
154
+ content = File.read(path, mode: "rb")
155
+ file = TTFunk::File.new(content)
156
+
102
157
  parse_font(file, path)
158
+ rescue StandardError
159
+ warn $!.message
160
+ warn "Warning: File at #{path} not recognized as a font file."
103
161
  end
104
162
 
105
163
  def detect_collection_fonts(path)
@@ -108,6 +166,9 @@ module Fontist
108
166
  parse_font(file, path)
109
167
  end
110
168
  end
169
+ rescue StandardError
170
+ warn $!.message
171
+ warn "Warning: File at #{path} not recognized as a font file."
111
172
  end
112
173
 
113
174
  def parse_font(file, path)
@@ -115,20 +176,42 @@ module Fontist
115
176
 
116
177
  {
117
178
  path: path,
118
- full_name: parse_text(x.font_name.first),
119
- family_name: parse_text(x.preferred_family.first || x.font_family.first),
120
- type: parse_text(x.preferred_subfamily.first || x.font_subfamily.first),
179
+ full_name: english_name(x.font_name),
180
+ family_name: english_name(@family.family_name(x)),
181
+ type: english_name(@family.type(x)),
121
182
  }
122
183
  end
123
184
 
124
- def parse_text(text)
185
+ def english_name(name)
186
+ visible_characters(find_english(name))
187
+ end
188
+
189
+ def find_english(name)
190
+ name.find { |x| microsoft_english?(x) } ||
191
+ name.find { |x| mac_english?(x) } ||
192
+ name.last
193
+ end
194
+
195
+ def microsoft_english?(string)
196
+ string.platform_id == PLATFORM_MICROSOFT &&
197
+ string.encoding_id == ENCODING_MS_UNICODE_BMP &&
198
+ string.language_id == LANGUAGE_MS_ENGLISH_AMERICAN
199
+ end
200
+
201
+ def mac_english?(string)
202
+ string.platform_id == PLATFORM_MACINTOSH &&
203
+ string.encoding_id == ENCODING_MAC_ROMAN &&
204
+ string.language_id == LANGUAGE_MAC_ENGLISH
205
+ end
206
+
207
+ def visible_characters(text)
125
208
  text.gsub(/[^[:print:]]/, "").to_s
126
209
  end
127
210
 
128
211
  def save_index(index)
129
- dir = File.dirname(Fontist.system_index_path)
212
+ dir = File.dirname(@index_path)
130
213
  FileUtils.mkdir_p(dir) unless File.exist?(dir)
131
- File.write(Fontist.system_index_path, YAML.dump(index))
214
+ File.write(@index_path, YAML.dump(index))
132
215
  end
133
216
  end
134
217
  end
@@ -0,0 +1,64 @@
1
+ module Fontist
2
+ class Update
3
+ def self.call
4
+ new.call
5
+ end
6
+
7
+ def call
8
+ update_main_repo
9
+ update_private_repos
10
+ ensure
11
+ rebuild_index
12
+ end
13
+
14
+ private
15
+
16
+ def update_main_repo
17
+ dir = File.dirname(Fontist.formulas_repo_path)
18
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
19
+
20
+ if Dir.exist?(Fontist.formulas_repo_path)
21
+ Git.open(Fontist.formulas_repo_path).pull
22
+ else
23
+ Git.clone(Fontist.formulas_repo_url,
24
+ Fontist.formulas_repo_path,
25
+ depth: 1)
26
+ end
27
+ end
28
+
29
+ def update_private_repos
30
+ private_repos.each do |path|
31
+ update_repo(path)
32
+ end
33
+ end
34
+
35
+ def update_repo(path)
36
+ Git.open(path).pull
37
+ rescue Git::GitExecuteError => e
38
+ name = repo_name(path)
39
+ raise Errors::RepoCouldNotBeUpdatedError.new(<<~MSG.chomp)
40
+ Formulas repo '#{name}' could not be updated.
41
+ Please consider reinitializing it with:
42
+ fontist remove #{name}
43
+ fontist setup #{name} REPO_URL
44
+
45
+ Git error:
46
+ #{e.message}
47
+ MSG
48
+ end
49
+
50
+ def private_repos
51
+ Dir.glob(Fontist.private_formulas_path.join("*")).select do |path|
52
+ File.directory?(path)
53
+ end
54
+ end
55
+
56
+ def repo_name(path)
57
+ File.basename(path)
58
+ end
59
+
60
+ def rebuild_index
61
+ Index.rebuild
62
+ end
63
+ end
64
+ end
@@ -20,7 +20,7 @@ module Fontist
20
20
  end
21
21
 
22
22
  def download
23
- file = @cache.fetch(@file) do
23
+ file = @cache.fetch(url) do
24
24
  download_file
25
25
  end
26
26
 
@@ -56,9 +56,10 @@ module Fontist
56
56
 
57
57
  def download_file
58
58
  file = Down.download(
59
- @file,
59
+ url,
60
60
  open_timeout: 10,
61
61
  read_timeout: 10,
62
+ headers: headers,
62
63
  content_length_proc: ->(content_length) {
63
64
  @progress_bar.total = content_length if content_length
64
65
  },
@@ -73,6 +74,17 @@ module Fontist
73
74
  rescue Down::NotFound
74
75
  raise(Fontist::Errors::InvalidResourceError.new("Invalid URL: #{@file}"))
75
76
  end
77
+
78
+ def url
79
+ @file.respond_to?(:url) ? @file.url : @file
80
+ end
81
+
82
+ def headers
83
+ @file.respond_to?(:headers) &&
84
+ @file.headers &&
85
+ @file.headers.to_h.map { |k, v| [k.to_s, v] }.to_h || # rubocop:disable Style/HashTransformKeys, Metrics/LineLength
86
+ {}
87
+ end
76
88
  end
77
89
 
78
90
  class ProgressBar
@@ -11,6 +11,7 @@ module Fontist
11
11
  yield
12
12
  ensure
13
13
  f.flock(File::LOCK_UN)
14
+ f.close
14
15
  end
15
16
  end
16
17
  end
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "1.8.12".freeze
2
+ VERSION = "1.10.0".freeze
3
3
  end
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.8.12
4
+ version: 1.10.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-03-22 00:00:00.000000000 Z
11
+ date: 2021-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - '='
186
186
  - !ruby/object:Gem::Version
187
- version: 0.75.0
187
+ version: 1.5.2
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - '='
193
193
  - !ruby/object:Gem::Version
194
- version: 0.75.0
194
+ version: 1.5.2
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: rubocop-rails
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -243,6 +243,7 @@ extensions: []
243
243
  extra_rdoc_files: []
244
244
  files:
245
245
  - ".github/workflows/check_google.yml"
246
+ - ".github/workflows/metanorma.yml"
246
247
  - ".github/workflows/release.yml"
247
248
  - ".github/workflows/rspec.yml"
248
249
  - ".gitignore"
@@ -261,7 +262,6 @@ files:
261
262
  - lib/fontist/font.rb
262
263
  - lib/fontist/font_installer.rb
263
264
  - lib/fontist/font_path.rb
264
- - lib/fontist/fontist_font.rb
265
265
  - lib/fontist/formula.rb
266
266
  - lib/fontist/formula_paths.rb
267
267
  - lib/fontist/helpers.rb
@@ -295,15 +295,20 @@ files:
295
295
  - lib/fontist/import/text_helper.rb
296
296
  - lib/fontist/index.rb
297
297
  - lib/fontist/indexes/base_index.rb
298
+ - lib/fontist/indexes/default_family_font_index.rb
298
299
  - lib/fontist/indexes/filename_index.rb
299
300
  - lib/fontist/indexes/font_index.rb
300
301
  - lib/fontist/indexes/index_formula.rb
302
+ - lib/fontist/indexes/preferred_family_font_index.rb
301
303
  - lib/fontist/manifest.rb
302
304
  - lib/fontist/manifest/install.rb
303
305
  - lib/fontist/manifest/locations.rb
306
+ - lib/fontist/repo.rb
307
+ - lib/fontist/repo_cli.rb
304
308
  - lib/fontist/system.yml
305
309
  - lib/fontist/system_font.rb
306
310
  - lib/fontist/system_index.rb
311
+ - lib/fontist/update.rb
307
312
  - lib/fontist/utils.rb
308
313
  - lib/fontist/utils/cache.rb
309
314
  - lib/fontist/utils/downloader.rb
@@ -336,7 +341,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
336
341
  - !ruby/object:Gem::Version
337
342
  version: '0'
338
343
  requirements: []
339
- rubygems_version: 3.0.3
344
+ rubygems_version: 3.0.3.1
340
345
  signing_key:
341
346
  specification_version: 4
342
347
  summary: Install openly-licensed fonts on Windows, Linux and Mac!