fontist 1.21.4 → 2.0.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -0
  3. data/Gemfile +11 -0
  4. data/README.adoc +6 -6
  5. data/docs/guide/api-ruby.md +8 -9
  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 +14 -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/import/formula_serializer.rb +4 -4
  21. data/lib/fontist/import/google_import.rb +1 -1
  22. data/lib/fontist/index.rb +47 -8
  23. data/lib/fontist/indexes/default_family_font_index.rb +28 -9
  24. data/lib/fontist/indexes/filename_index.rb +45 -8
  25. data/lib/fontist/indexes/font_index.rb +3 -3
  26. data/lib/fontist/indexes/formula_key_to_path.rb +35 -0
  27. data/lib/fontist/indexes/index_mixin.rb +109 -0
  28. data/lib/fontist/indexes/preferred_family_font_index.rb +28 -9
  29. data/lib/fontist/manifest.rb +144 -2
  30. data/lib/fontist/manifest_request.rb +64 -0
  31. data/lib/fontist/manifest_response.rb +66 -0
  32. data/lib/fontist/repo.rb +1 -1
  33. data/lib/fontist/system_font.rb +7 -25
  34. data/lib/fontist/system_index.rb +137 -126
  35. data/lib/fontist/utils/cache.rb +54 -4
  36. data/lib/fontist/version.rb +1 -1
  37. data/lib/fontist.rb +33 -13
  38. metadata +16 -136
  39. data/lib/fontist/indexes/base_index.rb +0 -92
  40. data/lib/fontist/indexes/index_formula.rb +0 -36
  41. data/lib/fontist/manifest/install.rb +0 -35
  42. data/lib/fontist/manifest/locations.rb +0 -84
data/lib/fontist/cli.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require "thor"
2
- require "fontist/cli/class_options"
3
- require "fontist/cli/thor_ext"
4
- require "fontist/repo_cli"
5
- require "fontist/cache_cli"
6
- require "fontist/import_cli"
7
- require "fontist/fontconfig_cli"
8
- require "fontist/config_cli"
2
+ require_relative "../fontist"
3
+ require_relative "cli/class_options"
4
+ require_relative "cli/thor_ext"
5
+ require_relative "repo_cli"
6
+ require_relative "cache_cli"
7
+ require_relative "import_cli"
8
+ require_relative "fontconfig_cli"
9
+ require_relative "config_cli"
9
10
 
10
11
  module Fontist
11
12
  class CLI < Thor
@@ -143,8 +144,8 @@ module Fontist
143
144
  "Get locations of fonts from MANIFEST (yaml)"
144
145
  def manifest_locations(manifest)
145
146
  handle_class_options(options)
146
- paths = Fontist::Manifest::Locations.from_file(manifest)
147
- print_yaml(paths)
147
+ paths = Fontist::Manifest.from_file(manifest, locations: true)
148
+ print_yaml(paths.to_hash)
148
149
  success
149
150
  rescue Fontist::Errors::GeneralError => e
150
151
  handle_error(e)
@@ -159,13 +160,12 @@ module Fontist
159
160
  desc: "Hide license texts"
160
161
  def manifest_install(manifest)
161
162
  handle_class_options(options)
162
- paths = Fontist::Manifest::Install.from_file(
163
- manifest,
163
+ instance = Fontist::Manifest.from_file(manifest)
164
+ paths = instance.install(
164
165
  confirmation: options[:accept_all_licenses] ? "yes" : "no",
165
- hide_licenses: options[:hide_licenses]
166
+ hide_licenses: options[:hide_licenses],
166
167
  )
167
-
168
- print_yaml(paths)
168
+ print_yaml(paths.to_hash)
169
169
  success
170
170
  rescue Fontist::Errors::GeneralError => e
171
171
  handle_error(e)
@@ -1,9 +1,65 @@
1
+ require "lutaml/model"
2
+
1
3
  module Fontist
2
- class Config
3
- include Singleton
4
+ class Config < Lutaml::Model::Serializable
5
+ attribute :fonts_path, :string
6
+ attribute :google_fonts_key, :string
7
+ attribute :open_timeout, :integer
8
+ attribute :read_timeout, :integer
9
+ attribute :continue_on_checksum_mismatch, :boolean
10
+ attribute :use_system_index, :boolean
11
+ attribute :preferred_family, :boolean
12
+ attribute :update_fontconfig, :boolean
13
+ attribute :no_progress, :boolean
14
+
15
+ key_value do
16
+ map "fonts_path", to: :fonts_path
17
+ map "google_fonts_key", to: :google_fonts_key
18
+ map "open_timeout", to: :open_timeout
19
+ map "read_timeout", to: :read_timeout
20
+ map "continue_on_checksum_mismatch", to: :continue_on_checksum_mismatch
21
+ map "use_system_index", to: :use_system_index
22
+ map "preferred_family", to: :preferred_family
23
+ map "update_fontconfig", to: :update_fontconfig
24
+ map "no_progress", to: :no_progress
25
+ end
4
26
 
5
- def initialize
6
- @custom_values = load_config_file
27
+ class << self
28
+ def instance
29
+ @instance ||= new.tap(&:load)
30
+ end
31
+
32
+ def values
33
+ instance.values
34
+ end
35
+
36
+ def custom_values
37
+ instance.custom_values
38
+ end
39
+
40
+ def set(key, value)
41
+ instance.set(key, value)
42
+ end
43
+
44
+ def delete(key)
45
+ instance.delete(key)
46
+ end
47
+
48
+ def default_value(key)
49
+ instance.default_value(key)
50
+ end
51
+
52
+ def from_file(path)
53
+ return new unless File.exist?(path)
54
+
55
+ content = File.read(path)
56
+ from_yaml(content)
57
+ end
58
+ end
59
+
60
+ def initialize(**attrs)
61
+ @custom_values = {}
62
+ super
7
63
  end
8
64
 
9
65
  def values
@@ -22,18 +78,14 @@ module Fontist
22
78
  end
23
79
 
24
80
  v = normalize_value(value)
25
- if respond_to?("#{attr}=")
26
- public_send("#{attr}=", v)
27
- else
28
- @custom_values[attr] = v
29
- end
81
+ @custom_values[attr] = v
82
+ send("#{attr}=", v) if respond_to?("#{attr}=")
30
83
 
31
84
  persist
32
85
  end
33
86
 
34
87
  def delete(key)
35
88
  @custom_values.delete(key.to_sym)
36
-
37
89
  persist
38
90
  end
39
91
 
@@ -49,9 +101,13 @@ module Fontist
49
101
  end
50
102
 
51
103
  def persist
52
- values = @custom_values.transform_keys(&:to_s)
104
+ config_model = self.class.new
105
+ @custom_values.each do |key, value|
106
+ config_model.send("#{key}=", value) if config_model.respond_to?("#{key}=")
107
+ end
108
+
53
109
  FileUtils.mkdir_p(File.dirname(Fontist.config_path))
54
- File.write(Fontist.config_path, YAML.dump(values))
110
+ config_model.to_file(Fontist.config_path)
55
111
  end
56
112
 
57
113
  def load
@@ -59,7 +115,12 @@ module Fontist
59
115
  end
60
116
 
61
117
  def fonts_path=(value)
62
- @custom_values[:fonts_path] = File.expand_path(value)
118
+ @custom_values[:fonts_path] = File.expand_path(value.to_s)
119
+ @fonts_path = @custom_values[:fonts_path]
120
+ end
121
+
122
+ def to_file(path)
123
+ File.write(path, to_yaml)
63
124
  end
64
125
 
65
126
  private
@@ -67,7 +128,7 @@ module Fontist
67
128
  def load_config_file
68
129
  return {} unless File.exist?(Fontist.config_path)
69
130
 
70
- YAML.load_file(Fontist.config_path).transform_keys(&:to_sym)
131
+ self.class.from_file(Fontist.config_path)&.to_hash&.transform_keys(&:to_sym) || {}
71
132
  end
72
133
 
73
134
  def normalize_value(value)
@@ -28,6 +28,8 @@ module Fontist
28
28
  # it depends on this exception to automatically download formulas
29
29
  class FormulaIndexNotFoundError < GeneralError; end
30
30
 
31
+ class FormulaInvalidError < GeneralError; end
32
+
31
33
  class FormulaNotFoundError < GeneralError
32
34
  def initialize(formula)
33
35
  super(<<~MSG.chomp)
@@ -0,0 +1,25 @@
1
+ require "lutaml/model"
2
+
3
+ module Fontist
4
+ class ExtractOptions < Lutaml::Model::Serializable
5
+ attribute :file, :string
6
+ attribute :fonts_sub_dir, :string
7
+
8
+ key_value do
9
+ map "file", to: :file
10
+ map "fonts_sub_dir", to: :fonts_sub_dir
11
+ end
12
+ end
13
+
14
+ class Extract < Lutaml::Model::Serializable
15
+ attribute :format, :string
16
+ attribute :file, :string
17
+ attribute :options, ExtractOptions, collection: true
18
+
19
+ key_value do
20
+ map "format", to: :format
21
+ map "file", to: :file
22
+ map "options", to: :options
23
+ end
24
+ end
25
+ end
data/lib/fontist/font.rb CHANGED
@@ -228,7 +228,7 @@ module Fontist
228
228
  end
229
229
 
230
230
  def check_and_confirm_required_license(formula)
231
- return @confirmation unless formula.license_required
231
+ return @confirmation unless formula.license_required?
232
232
 
233
233
  show_license(formula) unless @hide_licenses
234
234
  return @confirmation if @confirmation.casecmp?("yes")
@@ -237,7 +237,7 @@ module Fontist
237
237
  return confirmation if confirmation&.casecmp?("yes")
238
238
 
239
239
  raise Fontist::Errors::LicensingError.new(
240
- "Fontist will not download these fonts unless you accept the terms."
240
+ "Fontist will not download these fonts unless you accept the terms.",
241
241
  )
242
242
  end
243
243
 
@@ -248,7 +248,7 @@ module Fontist
248
248
  def ask_for_agreement
249
249
  Fontist.ui.ask(
250
250
  "\nDo you accept all presented font licenses, and want Fontist " \
251
- "to download these fonts for you? => TYPE 'Yes' or 'No':"
251
+ "to download these fonts for you? => TYPE 'Yes' or 'No':",
252
252
  )
253
253
  end
254
254
 
@@ -301,9 +301,7 @@ module Fontist
301
301
  fonts = Fontist::SystemIndex.fontist_index.find(name, nil)
302
302
  return unless fonts
303
303
 
304
- fonts.map do |font|
305
- font[:path]
306
- end
304
+ fonts.map(&:path)
307
305
  end
308
306
 
309
307
  def installed_paths
@@ -336,7 +334,7 @@ module Fontist
336
334
 
337
335
  def list_styles(formulas)
338
336
  map_to_hash(formulas) do |formula|
339
- map_to_hash(requested_fonts(formula.fonts)) do |font|
337
+ map_to_hash(requested_fonts(formula.all_fonts)) do |font|
340
338
  map_to_hash(font.styles) do |style|
341
339
  installed(style)
342
340
  end
@@ -351,7 +349,7 @@ module Fontist
351
349
  def requested_fonts(fonts)
352
350
  return fonts unless @name
353
351
 
354
- fonts.select do |font|
352
+ fonts&.select do |font|
355
353
  font.name.casecmp?(name)
356
354
  end
357
355
  end
@@ -0,0 +1,16 @@
1
+ require "lutaml/model"
2
+ require_relative "font_model"
3
+
4
+ module Fontist
5
+ class FontCollection < Lutaml::Model::Serializable
6
+ attribute :filename, :string
7
+ attribute :source_filename, :string
8
+ attribute :fonts, FontModel, collection: true
9
+
10
+ key_value do
11
+ map "filename", to: :filename
12
+ map "source_filename", to: :source_filename
13
+ map "fonts", to: :fonts
14
+ end
15
+ end
16
+ end
@@ -40,7 +40,7 @@ module Fontist
40
40
  end
41
41
 
42
42
  def license_is_accepted?(confirmation)
43
- return true unless @formula.license_required
43
+ return true unless @formula.license_required?
44
44
 
45
45
  "yes".casecmp?(confirmation)
46
46
  end
@@ -95,7 +95,7 @@ module Fontist
95
95
  end
96
96
 
97
97
  def fonts
98
- @formula.fonts.select do |font|
98
+ @formula.all_fonts.select do |font|
99
99
  @font_name.nil? || font.name.casecmp?(@font_name)
100
100
  end
101
101
  end
@@ -111,7 +111,7 @@ module Fontist
111
111
  end
112
112
 
113
113
  def subdirectories
114
- @subdirectories ||= [@formula.extract].flatten.map(&:options).compact.map(&:fonts_sub_dir).compact
114
+ @subdirectories ||= [@formula.extract].flatten.compact.map(&:options).compact.map(&:fonts_sub_dir).compact
115
115
  end
116
116
 
117
117
  def install_font_file(source)
@@ -126,7 +126,7 @@ module Fontist
126
126
  end
127
127
 
128
128
  def target_filenames
129
- @target_filenames ||= @formula.fonts.flat_map do |font|
129
+ @target_filenames ||= @formula.all_fonts.flat_map do |font|
130
130
  font.styles.map do |style|
131
131
  source = style.source_font || style.font
132
132
  target = style.font
@@ -0,0 +1,15 @@
1
+ require "lutaml/model"
2
+ require_relative "font_style"
3
+
4
+ module Fontist
5
+ class FontModel < Lutaml::Model::Serializable
6
+ attribute :name, :string
7
+ attribute :styles, FontStyle, collection: true
8
+
9
+ key_value do
10
+ map "name", to: :name
11
+ map "styles", to: :styles
12
+ end
13
+
14
+ end
15
+ end
@@ -16,7 +16,7 @@ module Fontist
16
16
 
17
17
  def formulas
18
18
  @formulas ||= if fontist_font?
19
- Indexes::FilenameIndex.from_yaml.load_index_formulas(File.basename(@path)).map(&:name)
19
+ Indexes::FilenameIndex.from_file.load_index_formulas(File.basename(@path)).flat_map(&:name)
20
20
  else
21
21
  []
22
22
  end
@@ -0,0 +1,37 @@
1
+ require "lutaml/model"
2
+
3
+ module Fontist
4
+ class FontStyle < Lutaml::Model::Serializable
5
+ attribute :family_name, :string
6
+ attribute :type, :string
7
+ attribute :full_name, :string
8
+ attribute :post_script_name, :string
9
+ attribute :version, :string
10
+ attribute :description, :string
11
+ attribute :copyright, :string
12
+ attribute :font, :string
13
+ attribute :source_font, :string
14
+ attribute :preferred_family_name, :string
15
+ attribute :preferred_type, :string
16
+ attribute :default_family_name, :string
17
+ attribute :default_type, :string
18
+ attribute :override, :string
19
+
20
+ key_value do
21
+ map "family_name", to: :family_name
22
+ map "type", to: :type
23
+ map "preferred_family_name", to: :preferred_family_name
24
+ map "preferred_type", to: :preferred_type
25
+ map "full_name", to: :full_name
26
+ map "post_script_name", to: :post_script_name
27
+ map "version", to: :version
28
+ map "description", to: :description
29
+ map "copyright", to: :copyright
30
+ map "font", to: :font
31
+ map "source_font", to: :source_font
32
+ map "default_family_name", to: :default_family_name
33
+ map "default_type", to: :default_type
34
+ map "override", to: :override
35
+ end
36
+ end
37
+ end