fontist 1.21.4 → 2.0.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -0
  3. data/Gemfile +11 -0
  4. data/README.adoc +77 -11
  5. data/docs/guide/api-ruby.md +10 -11
  6. data/fontist.gemspec +14 -24
  7. data/formula_filename_index.yml +6210 -0
  8. data/formula_index.yml +2568 -0
  9. data/lib/fontist/cli.rb +16 -14
  10. data/lib/fontist/config.rb +75 -14
  11. data/lib/fontist/errors.rb +2 -0
  12. data/lib/fontist/extract.rb +25 -0
  13. data/lib/fontist/font.rb +6 -8
  14. data/lib/fontist/font_collection.rb +16 -0
  15. data/lib/fontist/font_installer.rb +4 -4
  16. data/lib/fontist/font_model.rb +15 -0
  17. data/lib/fontist/font_path.rb +1 -1
  18. data/lib/fontist/font_style.rb +37 -0
  19. data/lib/fontist/formula.rb +169 -112
  20. data/lib/fontist/helpers.rb +5 -4
  21. data/lib/fontist/import/create_formula.rb +2 -1
  22. data/lib/fontist/import/files/collection_file.rb +5 -15
  23. data/lib/fontist/import/font_style.rb +22 -0
  24. data/lib/fontist/import/formula_serializer.rb +4 -4
  25. data/lib/fontist/import/google_import.rb +1 -1
  26. data/lib/fontist/import/otf/font_file.rb +8 -3
  27. data/lib/fontist/import/otf_style.rb +3 -1
  28. data/lib/fontist/import/recursive_extraction.rb +9 -4
  29. data/lib/fontist/index.rb +47 -8
  30. data/lib/fontist/indexes/default_family_font_index.rb +28 -9
  31. data/lib/fontist/indexes/filename_index.rb +45 -8
  32. data/lib/fontist/indexes/font_index.rb +3 -3
  33. data/lib/fontist/indexes/formula_key_to_path.rb +35 -0
  34. data/lib/fontist/indexes/index_mixin.rb +109 -0
  35. data/lib/fontist/indexes/preferred_family_font_index.rb +28 -9
  36. data/lib/fontist/manifest.rb +144 -2
  37. data/lib/fontist/manifest_request.rb +64 -0
  38. data/lib/fontist/manifest_response.rb +66 -0
  39. data/lib/fontist/repo.rb +1 -1
  40. data/lib/fontist/resources/archive_resource.rb +3 -2
  41. data/lib/fontist/system_font.rb +7 -25
  42. data/lib/fontist/system_index.rb +137 -126
  43. data/lib/fontist/utils/cache.rb +54 -4
  44. data/lib/fontist/utils/downloader.rb +6 -4
  45. data/lib/fontist/version.rb +1 -1
  46. data/lib/fontist.rb +33 -13
  47. metadata +23 -148
  48. data/lib/fontist/indexes/base_index.rb +0 -92
  49. data/lib/fontist/indexes/index_formula.rb +0 -36
  50. data/lib/fontist/manifest/install.rb +0 -35
  51. data/lib/fontist/manifest/locations.rb +0 -84
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.21.4
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-07-24 00:00:00.000000000 Z
11
+ date: 2025-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.1'
33
+ version: 0.3.7
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.1'
40
+ version: 0.3.7
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: fuzzy_match
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -114,20 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '1.2'
118
- - - ">="
119
- - !ruby/object:Gem::Version
120
- version: 1.2.1
117
+ version: '1.4'
121
118
  type: :runtime
122
119
  prerelease: false
123
120
  version_requirements: !ruby/object:Gem::Requirement
124
121
  requirements:
125
122
  - - "~>"
126
123
  - !ruby/object:Gem::Version
127
- version: '1.2'
128
- - - ">="
129
- - !ruby/object:Gem::Version
130
- version: 1.2.1
124
+ version: '1.4'
131
125
  - !ruby/object:Gem::Dependency
132
126
  name: git
133
127
  requirement: !ruby/object:Gem::Requirement
@@ -179,7 +173,7 @@ dependencies:
179
173
  version: '0.3'
180
174
  - - ">="
181
175
  - !ruby/object:Gem::Version
182
- version: 0.3.4
176
+ version: 0.3.8
183
177
  type: :runtime
184
178
  prerelease: false
185
179
  version_requirements: !ruby/object:Gem::Requirement
@@ -189,7 +183,7 @@ dependencies:
189
183
  version: '0.3'
190
184
  - - ">="
191
185
  - !ruby/object:Gem::Version
192
- version: 0.3.4
186
+ version: 0.3.8
193
187
  - !ruby/object:Gem::Dependency
194
188
  name: socksify
195
189
  requirement: !ruby/object:Gem::Requirement
@@ -205,145 +199,19 @@ dependencies:
205
199
  - !ruby/object:Gem::Version
206
200
  version: '1.7'
207
201
  - !ruby/object:Gem::Dependency
208
- name: pry
209
- requirement: !ruby/object:Gem::Requirement
210
- requirements:
211
- - - "~>"
212
- - !ruby/object:Gem::Version
213
- version: '0.14'
214
- type: :development
215
- prerelease: false
216
- version_requirements: !ruby/object:Gem::Requirement
217
- requirements:
218
- - - "~>"
219
- - !ruby/object:Gem::Version
220
- version: '0.14'
221
- - !ruby/object:Gem::Dependency
222
- name: bundler
223
- requirement: !ruby/object:Gem::Requirement
224
- requirements:
225
- - - "~>"
226
- - !ruby/object:Gem::Version
227
- version: '2.3'
228
- type: :development
229
- prerelease: false
230
- version_requirements: !ruby/object:Gem::Requirement
231
- requirements:
232
- - - "~>"
233
- - !ruby/object:Gem::Version
234
- version: '2.3'
235
- - !ruby/object:Gem::Dependency
236
- name: rake
202
+ name: lutaml-model
237
203
  requirement: !ruby/object:Gem::Requirement
238
204
  requirements:
239
205
  - - "~>"
240
206
  - !ruby/object:Gem::Version
241
- version: '13'
242
- type: :development
243
- prerelease: false
244
- version_requirements: !ruby/object:Gem::Requirement
245
- requirements:
246
- - - "~>"
247
- - !ruby/object:Gem::Version
248
- version: '13'
249
- - !ruby/object:Gem::Dependency
250
- name: rspec
251
- requirement: !ruby/object:Gem::Requirement
252
- requirements:
253
- - - "~>"
254
- - !ruby/object:Gem::Version
255
- version: '3.0'
256
- type: :development
257
- prerelease: false
258
- version_requirements: !ruby/object:Gem::Requirement
259
- requirements:
260
- - - "~>"
261
- - !ruby/object:Gem::Version
262
- version: '3.0'
263
- - !ruby/object:Gem::Dependency
264
- name: rspec-benchmark
265
- requirement: !ruby/object:Gem::Requirement
266
- requirements:
267
- - - "~>"
268
- - !ruby/object:Gem::Version
269
- version: '0.6'
270
- type: :development
271
- prerelease: false
272
- version_requirements: !ruby/object:Gem::Requirement
273
- requirements:
274
- - - "~>"
275
- - !ruby/object:Gem::Version
276
- version: '0.6'
277
- - !ruby/object:Gem::Dependency
278
- name: rubocop
279
- requirement: !ruby/object:Gem::Requirement
280
- requirements:
281
- - - "~>"
282
- - !ruby/object:Gem::Version
283
- version: 1.22.1
284
- type: :development
285
- prerelease: false
286
- version_requirements: !ruby/object:Gem::Requirement
287
- requirements:
288
- - - "~>"
289
- - !ruby/object:Gem::Version
290
- version: 1.22.1
291
- - !ruby/object:Gem::Dependency
292
- name: rubocop-rails
293
- requirement: !ruby/object:Gem::Requirement
294
- requirements:
295
- - - "~>"
296
- - !ruby/object:Gem::Version
297
- version: '2.9'
298
- type: :development
299
- prerelease: false
300
- version_requirements: !ruby/object:Gem::Requirement
301
- requirements:
302
- - - "~>"
303
- - !ruby/object:Gem::Version
304
- version: '2.9'
305
- - !ruby/object:Gem::Dependency
306
- name: rubocop-performance
307
- requirement: !ruby/object:Gem::Requirement
308
- requirements:
309
- - - "~>"
310
- - !ruby/object:Gem::Version
311
- version: '1.10'
312
- type: :development
207
+ version: '0.7'
208
+ type: :runtime
313
209
  prerelease: false
314
210
  version_requirements: !ruby/object:Gem::Requirement
315
211
  requirements:
316
212
  - - "~>"
317
213
  - !ruby/object:Gem::Version
318
- version: '1.10'
319
- - !ruby/object:Gem::Dependency
320
- name: vcr
321
- requirement: !ruby/object:Gem::Requirement
322
- requirements:
323
- - - ">="
324
- - !ruby/object:Gem::Version
325
- version: '0'
326
- type: :development
327
- prerelease: false
328
- version_requirements: !ruby/object:Gem::Requirement
329
- requirements:
330
- - - ">="
331
- - !ruby/object:Gem::Version
332
- version: '0'
333
- - !ruby/object:Gem::Dependency
334
- name: webmock
335
- requirement: !ruby/object:Gem::Requirement
336
- requirements:
337
- - - ">="
338
- - !ruby/object:Gem::Version
339
- version: '0'
340
- type: :development
341
- prerelease: false
342
- version_requirements: !ruby/object:Gem::Requirement
343
- requirements:
344
- - - ">="
345
- - !ruby/object:Gem::Version
346
- version: '0'
214
+ version: '0.7'
347
215
  description: Install openly-licensed fonts on Windows, Linux and Mac!
348
216
  email:
349
217
  - open.source@ribose.com
@@ -382,6 +250,8 @@ files:
382
250
  - docs/reference/index.md
383
251
  - exe/fontist
384
252
  - fontist.gemspec
253
+ - formula_filename_index.yml
254
+ - formula_index.yml
385
255
  - lib/fontist.rb
386
256
  - lib/fontist/cache_cli.rb
387
257
  - lib/fontist/cli.rb
@@ -392,10 +262,14 @@ files:
392
262
  - lib/fontist/config_cli.rb
393
263
  - lib/fontist/errors.rb
394
264
  - lib/fontist/exclude.yml
265
+ - lib/fontist/extract.rb
395
266
  - lib/fontist/font.rb
267
+ - lib/fontist/font_collection.rb
396
268
  - lib/fontist/font_file.rb
397
269
  - lib/fontist/font_installer.rb
270
+ - lib/fontist/font_model.rb
398
271
  - lib/fontist/font_path.rb
272
+ - lib/fontist/font_style.rb
399
273
  - lib/fontist/fontconfig.rb
400
274
  - lib/fontist/fontconfig_cli.rb
401
275
  - lib/fontist/formula.rb
@@ -408,6 +282,7 @@ files:
408
282
  - lib/fontist/import/files/collection_file.rb
409
283
  - lib/fontist/import/files/file_requirement.rb
410
284
  - lib/fontist/import/files/font_detector.rb
285
+ - lib/fontist/import/font_style.rb
411
286
  - lib/fontist/import/formula_builder.rb
412
287
  - lib/fontist/import/formula_serializer.rb
413
288
  - lib/fontist/import/google.rb
@@ -431,15 +306,15 @@ files:
431
306
  - lib/fontist/import/text_helper.rb
432
307
  - lib/fontist/import_cli.rb
433
308
  - lib/fontist/index.rb
434
- - lib/fontist/indexes/base_index.rb
435
309
  - lib/fontist/indexes/default_family_font_index.rb
436
310
  - lib/fontist/indexes/filename_index.rb
437
311
  - lib/fontist/indexes/font_index.rb
438
- - lib/fontist/indexes/index_formula.rb
312
+ - lib/fontist/indexes/formula_key_to_path.rb
313
+ - lib/fontist/indexes/index_mixin.rb
439
314
  - lib/fontist/indexes/preferred_family_font_index.rb
440
315
  - lib/fontist/manifest.rb
441
- - lib/fontist/manifest/install.rb
442
- - lib/fontist/manifest/locations.rb
316
+ - lib/fontist/manifest_request.rb
317
+ - lib/fontist/manifest_response.rb
443
318
  - lib/fontist/repo.rb
444
319
  - lib/fontist/repo_cli.rb
445
320
  - lib/fontist/resources/archive_resource.rb
@@ -1,92 +0,0 @@
1
- require_relative "index_formula"
2
-
3
- module Fontist
4
- module Indexes
5
- class BaseIndex
6
- def self.from_yaml
7
- @from_yaml ||= begin
8
- unless Dir.exist?(Fontist.formulas_repo_path)
9
- raise Errors::MainRepoNotFoundError.new(
10
- "Please fetch formulas with `fontist update`.",
11
- )
12
- end
13
-
14
- rebuild unless File.exist?(path)
15
-
16
- data = YAML.load_file(path)
17
- new(data)
18
- end
19
- end
20
-
21
- def self.path
22
- raise NotImplementedError, "Please define path of an index"
23
- end
24
-
25
- def self.reset_cache
26
- @from_yaml = nil
27
- end
28
-
29
- def self.rebuild
30
- index = new
31
- index.build
32
- index.to_yaml
33
- end
34
-
35
- def initialize(data = {})
36
- @index = {}
37
-
38
- data.each_pair do |key, paths|
39
- paths.each do |path|
40
- add_index_formula(key, IndexFormula.new(path))
41
- end
42
- end
43
- end
44
-
45
- def build
46
- Formula.all.each do |formula|
47
- add_formula(formula)
48
- end
49
- end
50
-
51
- def add_formula(_formula)
52
- raise NotImplementedError, "Please define how to add formula to an index, use #add_index_formula"
53
- end
54
-
55
- def add_index_formula(key_raw, index_formula)
56
- key = normalize_key(key_raw)
57
- @index[key] ||= []
58
- @index[key] << index_formula unless @index[key].include?(index_formula)
59
- end
60
-
61
- def load_formulas(key)
62
- index_formulas(key).map(&:to_full)
63
- end
64
-
65
- def load_index_formulas(key)
66
- index_formulas(key)
67
- end
68
-
69
- def to_yaml
70
- dir = File.dirname(self.class.path)
71
- FileUtils.mkdir_p(dir) unless File.exist?(dir)
72
- File.write(self.class.path, YAML.dump(to_h))
73
- end
74
-
75
- def to_h
76
- @index.map do |key, index_formulas|
77
- [key, index_formulas.map(&:to_s)]
78
- end.to_h
79
- end
80
-
81
- private
82
-
83
- def index_formulas(key)
84
- @index[normalize_key(key)] || []
85
- end
86
-
87
- def normalize_key(key)
88
- key
89
- end
90
- end
91
- end
92
- end
@@ -1,36 +0,0 @@
1
- module Fontist
2
- module Indexes
3
- class IndexFormula
4
- def initialize(path)
5
- @path = path
6
- end
7
-
8
- def name
9
- normalized.sub(/\.yml$/, "")
10
- end
11
-
12
- def to_s
13
- normalized
14
- end
15
-
16
- def to_full
17
- Formula.new_from_file(full_path)
18
- end
19
-
20
- def ==(other)
21
- to_s == other.to_s
22
- end
23
-
24
- private
25
-
26
- def normalized
27
- escaped = Regexp.escape(Fontist.formulas_path.to_s + "/")
28
- @path.sub(Regexp.new("^" + escaped), "")
29
- end
30
-
31
- def full_path
32
- Fontist.formulas_path.join(normalized).to_s
33
- end
34
- end
35
- end
36
- end
@@ -1,35 +0,0 @@
1
- require_relative "locations"
2
-
3
- module Fontist
4
- module Manifest
5
- class Install < Locations
6
- def initialize(manifest, confirmation: "no", hide_licenses: false, no_progress: false)
7
- super(manifest)
8
- @confirmation = confirmation
9
- @hide_licenses = hide_licenses
10
- @no_progress = no_progress
11
- end
12
-
13
- private
14
-
15
- def file_paths(font, style)
16
- paths = find_font_with_name(font, style)
17
- return paths unless paths.nil?
18
-
19
- install_font(font)
20
-
21
- find_font_with_name(font, style)
22
- end
23
-
24
- def install_font(font)
25
- Fontist::Font.install(
26
- font,
27
- force: true,
28
- confirmation: @confirmation,
29
- hide_licenses: @hide_licenses,
30
- no_progress: @no_progress
31
- )
32
- end
33
- end
34
- end
35
- end
@@ -1,84 +0,0 @@
1
- module Fontist
2
- module Manifest
3
- class Locations
4
- def initialize(manifest)
5
- Fontist.ui.debug("Manifest: #{manifest}")
6
-
7
- @manifest = manifest
8
- end
9
-
10
- def self.from_file(file, **keywords)
11
- raise Fontist::Errors::ManifestCouldNotBeFoundError unless File.exist?(file)
12
-
13
- manifest = YAML.load_file(file)
14
- raise Fontist::Errors::ManifestCouldNotBeReadError unless manifest.is_a?(Hash)
15
-
16
- from_hash(manifest, **keywords)
17
- end
18
-
19
- def self.from_hash(manifest, **keywords)
20
- if keywords.empty?
21
- new(manifest).call
22
- else
23
- new(manifest, **keywords).call
24
- end
25
- end
26
-
27
- def call
28
- font_names.zip(font_paths).to_h
29
- end
30
-
31
- private
32
-
33
- attr_reader :manifest
34
-
35
- def font_names
36
- manifest.keys
37
- end
38
-
39
- def font_paths
40
- manifest.map do |font, styles|
41
- styles_to_ary = [styles].flatten
42
- style_paths_map(font, styles_to_ary)
43
- end
44
- end
45
-
46
- def style_paths_map(font, names)
47
- styles = style_paths(font, names)
48
- group_paths(styles)
49
- end
50
-
51
- def style_paths(font, names)
52
- names.flat_map do |style|
53
- file_paths(font, style) || empty_paths(style)
54
- end
55
- end
56
-
57
- def group_paths(styles)
58
- styles.group_by { |s| s[:type] }
59
- .transform_values { |group| style(group) }
60
- end
61
-
62
- def style(styles)
63
- { "full_name" => styles.first[:full_name],
64
- "paths" => styles.map { |x| x[:path] } }.compact
65
- end
66
-
67
- def file_paths(font, style)
68
- find_font_with_name(font, style).tap do |x|
69
- if x.nil?
70
- raise Errors::MissingFontError.new(font, style)
71
- end
72
- end
73
- end
74
-
75
- def find_font_with_name(font, style)
76
- Fontist::SystemFont.find_styles(font, style)
77
- end
78
-
79
- def empty_paths(style)
80
- [{ "full_name" => nil, "type" => style, "path" => nil }]
81
- end
82
- end
83
- end
84
- end