fontist 1.8.13 → 1.10.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.
@@ -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)
@@ -98,7 +151,9 @@ 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)
103
158
  rescue StandardError
104
159
  warn $!.message
@@ -111,6 +166,9 @@ module Fontist
111
166
  parse_font(file, path)
112
167
  end
113
168
  end
169
+ rescue StandardError
170
+ warn $!.message
171
+ warn "Warning: File at #{path} not recognized as a font file."
114
172
  end
115
173
 
116
174
  def parse_font(file, path)
@@ -118,20 +176,42 @@ module Fontist
118
176
 
119
177
  {
120
178
  path: path,
121
- full_name: parse_text(x.font_name.first),
122
- family_name: parse_text(x.preferred_family.first || x.font_family.first),
123
- 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)),
124
182
  }
125
183
  end
126
184
 
127
- 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)
128
208
  text.gsub(/[^[:print:]]/, "").to_s
129
209
  end
130
210
 
131
211
  def save_index(index)
132
- dir = File.dirname(Fontist.system_index_path)
212
+ dir = File.dirname(@index_path)
133
213
  FileUtils.mkdir_p(dir) unless File.exist?(dir)
134
- File.write(Fontist.system_index_path, YAML.dump(index))
214
+ File.write(@index_path, YAML.dump(index))
135
215
  end
136
216
  end
137
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.13".freeze
2
+ VERSION = "1.10.1".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.13
4
+ version: 1.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-13 00:00:00.000000000 Z
11
+ date: 2021-07-27 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
@@ -234,6 +234,20 @@ dependencies:
234
234
  - - "~>"
235
235
  - !ruby/object:Gem::Version
236
236
  version: '1.0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: socksify
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
237
251
  description: Install openly-licensed fonts on Windows, Linux and Mac!
238
252
  email:
239
253
  - open.source@ribose.com
@@ -252,6 +266,7 @@ files:
252
266
  - ".rubocop.yml"
253
267
  - Gemfile
254
268
  - LICENSE.txt
269
+ - README.adoc
255
270
  - README.md
256
271
  - Rakefile
257
272
  - exe/fontist
@@ -262,7 +277,6 @@ files:
262
277
  - lib/fontist/font.rb
263
278
  - lib/fontist/font_installer.rb
264
279
  - lib/fontist/font_path.rb
265
- - lib/fontist/fontist_font.rb
266
280
  - lib/fontist/formula.rb
267
281
  - lib/fontist/formula_paths.rb
268
282
  - lib/fontist/helpers.rb
@@ -296,15 +310,20 @@ files:
296
310
  - lib/fontist/import/text_helper.rb
297
311
  - lib/fontist/index.rb
298
312
  - lib/fontist/indexes/base_index.rb
313
+ - lib/fontist/indexes/default_family_font_index.rb
299
314
  - lib/fontist/indexes/filename_index.rb
300
315
  - lib/fontist/indexes/font_index.rb
301
316
  - lib/fontist/indexes/index_formula.rb
317
+ - lib/fontist/indexes/preferred_family_font_index.rb
302
318
  - lib/fontist/manifest.rb
303
319
  - lib/fontist/manifest/install.rb
304
320
  - lib/fontist/manifest/locations.rb
321
+ - lib/fontist/repo.rb
322
+ - lib/fontist/repo_cli.rb
305
323
  - lib/fontist/system.yml
306
324
  - lib/fontist/system_font.rb
307
325
  - lib/fontist/system_index.rb
326
+ - lib/fontist/update.rb
308
327
  - lib/fontist/utils.rb
309
328
  - lib/fontist/utils/cache.rb
310
329
  - lib/fontist/utils/downloader.rb
@@ -337,8 +356,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
337
356
  - !ruby/object:Gem::Version
338
357
  version: '0'
339
358
  requirements: []
340
- rubygems_version: 3.0.3
341
- signing_key:
359
+ rubygems_version: 3.0.3.1
360
+ signing_key:
342
361
  specification_version: 4
343
362
  summary: Install openly-licensed fonts on Windows, Linux and Mac!
344
363
  test_files: []