fontist 1.9.3 → 1.11.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/metanorma.yml +1 -1
  3. data/.github/workflows/rspec.yml +1 -1
  4. data/README.adoc +804 -0
  5. data/exe/fontist +24 -2
  6. data/fontist.gemspec +3 -2
  7. data/lib/fontist/cli.rb +23 -9
  8. data/lib/fontist/font.rb +8 -3
  9. data/lib/fontist/formula.rb +4 -0
  10. data/lib/fontist/google_cli.rb +29 -0
  11. data/lib/fontist/import/files/collection_file.rb +10 -1
  12. data/lib/fontist/import/formula_builder.rb +30 -5
  13. data/lib/fontist/import/google/new_fonts_fetcher.rb +44 -33
  14. data/lib/fontist/import/google.rb +18 -0
  15. data/lib/fontist/import/google_check.rb +0 -7
  16. data/lib/fontist/import/google_import.rb +26 -138
  17. data/lib/fontist/import/helpers/system_helper.rb +1 -1
  18. data/lib/fontist/import/otf/font_file.rb +17 -4
  19. data/lib/fontist/import/otf_parser.rb +2 -0
  20. data/lib/fontist/import/otf_style.rb +10 -2
  21. data/lib/fontist/import/otfinfo/template.erb +6 -0
  22. data/lib/fontist/import/recursive_extraction.rb +2 -1
  23. data/lib/fontist/index.rb +4 -28
  24. data/lib/fontist/indexes/default_family_font_index.rb +21 -0
  25. data/lib/fontist/indexes/font_index.rb +8 -13
  26. data/lib/fontist/indexes/preferred_family_font_index.rb +24 -0
  27. data/lib/fontist/system_font.rb +6 -16
  28. data/lib/fontist/system_index.rb +108 -29
  29. data/lib/fontist/update.rb +2 -2
  30. data/lib/fontist/utils/downloader.rb +14 -6
  31. data/lib/fontist/version.rb +1 -1
  32. data/lib/fontist.rb +43 -13
  33. metadata +26 -29
  34. data/.github/workflows/check_google.yml +0 -28
  35. data/README.md +0 -570
  36. data/lib/fontist/fontist_font.rb +0 -24
  37. data/lib/fontist/formula_paths.rb +0 -44
  38. data/lib/fontist/import/google/fonts_public.md +0 -10
  39. data/lib/fontist/import/google/fonts_public.pb.rb +0 -71
  40. data/lib/fontist/import/google/fonts_public.proto +0 -46
@@ -0,0 +1,24 @@
1
+ require_relative "base_index"
2
+
3
+ module Fontist
4
+ module Indexes
5
+ class PreferredFamilyFontIndex < BaseIndex
6
+ def self.path
7
+ Fontist.formula_preferred_family_index_path
8
+ end
9
+
10
+ def add_formula(formula)
11
+ formula.fonts.each do |font|
12
+ font.styles.each do |style|
13
+ font_name = style.preferred_family_name || font.name
14
+ add_index_formula(font_name, formula.to_index_formula)
15
+ end
16
+ end
17
+ end
18
+
19
+ def normalize_key(key)
20
+ key.downcase
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,12 +1,10 @@
1
1
  require_relative "system_index"
2
- require_relative "formula_paths"
3
2
 
4
3
  module Fontist
5
4
  class SystemFont
6
- def initialize(font:, style: nil, sources: nil)
5
+ def initialize(font:, style: nil)
7
6
  @font = font
8
7
  @style = style
9
- @user_sources = sources || []
10
8
  end
11
9
 
12
10
  def self.font_paths
@@ -36,8 +34,8 @@ module Fontist
36
34
  Dir.glob(Fontist.fonts_path.join("**"))
37
35
  end
38
36
 
39
- def self.find(font, sources: [])
40
- new(font: font, sources: sources).find
37
+ def self.find(font)
38
+ new(font: font).find
41
39
  end
42
40
 
43
41
  def self.find_styles(font, style)
@@ -52,23 +50,15 @@ module Fontist
52
50
  end
53
51
 
54
52
  def find_styles
55
- find_by_index || find_by_formulas
53
+ find_by_index
56
54
  end
57
55
 
58
56
  private
59
57
 
60
- attr_reader :font, :style, :user_sources
58
+ attr_reader :font, :style
61
59
 
62
60
  def find_by_index
63
- SystemIndex.new(all_paths).find(font, style)
64
- end
65
-
66
- 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
61
+ SystemIndex.system_index.find(font, style)
72
62
  end
73
63
  end
74
64
  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)
@@ -95,14 +148,18 @@ module Fontist
95
148
  else
96
149
  raise Errors::UnknownFontTypeError.new(path)
97
150
  end
151
+ rescue StandardError
152
+ Fontist.ui.error($!.message)
153
+ Fontist.ui.error(
154
+ "Warning: File at #{path} not recognized as a font file.",
155
+ )
98
156
  end
99
157
 
100
158
  def detect_file_font(path)
101
- file = TTFunk::File.open(path)
159
+ content = File.read(path, mode: "rb")
160
+ file = TTFunk::File.new(content)
161
+
102
162
  parse_font(file, path)
103
- rescue StandardError
104
- warn $!.message
105
- warn "Warning: File at #{path} not recognized as a font file."
106
163
  end
107
164
 
108
165
  def detect_collection_fonts(path)
@@ -118,20 +175,42 @@ module Fontist
118
175
 
119
176
  {
120
177
  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),
178
+ full_name: english_name(x.font_name),
179
+ family_name: english_name(@family.family_name(x)),
180
+ type: english_name(@family.type(x)),
124
181
  }
125
182
  end
126
183
 
127
- def parse_text(text)
184
+ def english_name(name)
185
+ visible_characters(find_english(name))
186
+ end
187
+
188
+ def find_english(name)
189
+ name.find { |x| microsoft_english?(x) } ||
190
+ name.find { |x| mac_english?(x) } ||
191
+ name.last
192
+ end
193
+
194
+ def microsoft_english?(string)
195
+ string.platform_id == PLATFORM_MICROSOFT &&
196
+ string.encoding_id == ENCODING_MS_UNICODE_BMP &&
197
+ string.language_id == LANGUAGE_MS_ENGLISH_AMERICAN
198
+ end
199
+
200
+ def mac_english?(string)
201
+ string.platform_id == PLATFORM_MACINTOSH &&
202
+ string.encoding_id == ENCODING_MAC_ROMAN &&
203
+ string.language_id == LANGUAGE_MAC_ENGLISH
204
+ end
205
+
206
+ def visible_characters(text)
128
207
  text.gsub(/[^[:print:]]/, "").to_s
129
208
  end
130
209
 
131
210
  def save_index(index)
132
- dir = File.dirname(Fontist.system_index_path)
211
+ dir = File.dirname(@index_path)
133
212
  FileUtils.mkdir_p(dir) unless File.exist?(dir)
134
- File.write(Fontist.system_index_path, YAML.dump(index))
213
+ File.write(@index_path, YAML.dump(index))
135
214
  end
136
215
  end
137
216
  end
@@ -1,9 +1,9 @@
1
1
  module Fontist
2
2
  class Update
3
- BRANCH = "master".freeze
3
+ VERSION = "v2".freeze
4
4
 
5
5
  def self.call
6
- new(BRANCH).call
6
+ new(VERSION).call
7
7
  end
8
8
 
9
9
  def initialize(branch = "main")
@@ -24,12 +24,7 @@ module Fontist
24
24
  download_file
25
25
  end
26
26
 
27
- if !sha.empty? && !sha.include?(Digest::SHA256.file(file).to_s)
28
- raise(Fontist::Errors::TamperedFileError.new(
29
- "The downloaded file from #{@file} doesn't " \
30
- "match with the expected sha256 checksum!"
31
- ))
32
- end
27
+ raise_if_tampered(file)
33
28
 
34
29
  file
35
30
  end
@@ -38,6 +33,19 @@ module Fontist
38
33
 
39
34
  attr_reader :file, :sha, :file_size
40
35
 
36
+ def raise_if_tampered(file)
37
+ file_checksum = Digest::SHA256.file(file).to_s
38
+ if !sha.empty? && !sha.include?(file_checksum)
39
+ raise(
40
+ Fontist::Errors::TamperedFileError.new(
41
+ "The downloaded file from #{@file} doesn't " \
42
+ "match with the expected sha256 checksum (#{file_checksum})!\n" \
43
+ "Beginning of content: #{File.read(file, 3000)}",
44
+ ),
45
+ )
46
+ end
47
+ end
48
+
41
49
  def byte_to_megabyte
42
50
  @byte_to_megabyte ||= 1024 * 1024
43
51
  end
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "1.9.3".freeze
2
+ VERSION = "1.11.2".freeze
3
3
  end
data/lib/fontist.rb CHANGED
@@ -11,7 +11,6 @@ require "fontist/repo"
11
11
  require "fontist/font"
12
12
  require "fontist/formula"
13
13
  require "fontist/system_font"
14
- require "fontist/fontist_font"
15
14
  require "fontist/manifest"
16
15
  require "fontist/helpers"
17
16
 
@@ -41,7 +40,11 @@ module Fontist
41
40
  end
42
41
 
43
42
  def self.formulas_repo_path
44
- Fontist.fontist_path.join("formulas")
43
+ Fontist.fontist_version_path.join("formulas")
44
+ end
45
+
46
+ def self.fontist_version_path
47
+ Fontist.fontist_path.join("versions", Update::VERSION)
45
48
  end
46
49
 
47
50
  def self.formulas_repo_url
@@ -49,7 +52,11 @@ module Fontist
49
52
  end
50
53
 
51
54
  def self.formulas_path
52
- Fontist.formulas_repo_path.join("Formulas")
55
+ @formulas_path || Fontist.formulas_repo_path.join("Formulas")
56
+ end
57
+
58
+ def self.formulas_path=(path)
59
+ @formulas_path = path
53
60
  end
54
61
 
55
62
  def self.private_formulas_path
@@ -65,27 +72,50 @@ module Fontist
65
72
  end
66
73
 
67
74
  def self.system_index_path
68
- Fontist.fontist_path.join("system_index.yml")
75
+ Fontist.fontist_path.join("system_index.default_family.yml")
76
+ end
77
+
78
+ def self.system_preferred_family_index_path
79
+ Fontist.fontist_path.join("system_index.preferred_family.yml")
80
+ end
81
+
82
+ def self.fontist_index_path
83
+ Fontist.fontist_path.join("fontist_index.default_family.yml")
84
+ end
85
+
86
+ def self.fontist_preferred_family_index_path
87
+ Fontist.fontist_path.join("fontist_index.preferred_family.yml")
69
88
  end
70
89
 
71
90
  def self.formula_index_path
72
- @formula_index_path || Fontist.formula_index_dir.join("formula_index.yml")
91
+ Fontist.formula_index_dir.join("formula_index.default_family.yml")
73
92
  end
74
93
 
75
- def self.formula_index_path=(path)
76
- @formula_index_path = path
94
+ def self.formula_preferred_family_index_path
95
+ Fontist.formula_index_dir.join("formula_index.preferred_family.yml")
77
96
  end
78
97
 
79
98
  def self.formula_filename_index_path
80
- @formula_filename_index_path ||
81
- Fontist.formula_index_dir.join("filename_index.yml")
99
+ Fontist.formula_index_dir.join("filename_index.yml")
82
100
  end
83
101
 
84
- def self.formula_filename_index_path=(path)
85
- @formula_filename_index_path = path
102
+ def self.formula_index_dir
103
+ Fontist.fontist_version_path
86
104
  end
87
105
 
88
- def self.formula_index_dir
89
- Fontist.fontist_path
106
+ def self.preferred_family?
107
+ !!@preferred_family
108
+ end
109
+
110
+ def self.preferred_family=(bool)
111
+ @preferred_family = bool
112
+ end
113
+
114
+ def self.debug?
115
+ @debug || false
116
+ end
117
+
118
+ def self.debug=(bool)
119
+ @debug = bool
90
120
  end
91
121
  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.9.3
4
+ version: 1.11.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: 2021-08-06 00:00:00.000000000 Z
11
+ date: 2021-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -25,69 +25,69 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: thor
28
+ name: extract_ttc
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.1
33
+ version: '0.1'
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: 1.0.1
40
+ version: '0.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: git
42
+ name: thor
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.0'
47
+ version: 1.0.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.0'
54
+ version: 1.0.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: ttfunk
56
+ name: git
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.6'
61
+ version: '1.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.6'
68
+ version: '1.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: excavate
70
+ name: ttfunk
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.1'
75
+ version: '1.6'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0.1'
82
+ version: '1.6'
83
83
  - !ruby/object:Gem::Dependency
84
- name: extract_ttc
84
+ name: excavate
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.1'
90
- type: :development
90
+ type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
@@ -221,19 +221,19 @@ dependencies:
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  - !ruby/object:Gem::Dependency
224
- name: ruby-protocol-buffers
224
+ name: socksify
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
- - - "~>"
227
+ - - ">="
228
228
  - !ruby/object:Gem::Version
229
- version: '1.0'
230
- type: :development
229
+ version: '0'
230
+ type: :runtime
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
- - - "~>"
234
+ - - ">="
235
235
  - !ruby/object:Gem::Version
236
- version: '1.0'
236
+ version: '0'
237
237
  description: Install openly-licensed fonts on Windows, Linux and Mac!
238
238
  email:
239
239
  - open.source@ribose.com
@@ -242,7 +242,6 @@ executables:
242
242
  extensions: []
243
243
  extra_rdoc_files: []
244
244
  files:
245
- - ".github/workflows/check_google.yml"
246
245
  - ".github/workflows/metanorma.yml"
247
246
  - ".github/workflows/release.yml"
248
247
  - ".github/workflows/rspec.yml"
@@ -252,7 +251,7 @@ files:
252
251
  - ".rubocop.yml"
253
252
  - Gemfile
254
253
  - LICENSE.txt
255
- - README.md
254
+ - README.adoc
256
255
  - Rakefile
257
256
  - exe/fontist
258
257
  - fontist.gemspec
@@ -262,9 +261,8 @@ files:
262
261
  - lib/fontist/font.rb
263
262
  - lib/fontist/font_installer.rb
264
263
  - lib/fontist/font_path.rb
265
- - lib/fontist/fontist_font.rb
266
264
  - lib/fontist/formula.rb
267
- - lib/fontist/formula_paths.rb
265
+ - lib/fontist/google_cli.rb
268
266
  - lib/fontist/helpers.rb
269
267
  - lib/fontist/import.rb
270
268
  - lib/fontist/import/convert_formulas.rb
@@ -275,9 +273,6 @@ files:
275
273
  - lib/fontist/import/formula_builder.rb
276
274
  - lib/fontist/import/formula_serializer.rb
277
275
  - lib/fontist/import/google.rb
278
- - lib/fontist/import/google/fonts_public.md
279
- - lib/fontist/import/google/fonts_public.pb.rb
280
- - lib/fontist/import/google/fonts_public.proto
281
276
  - lib/fontist/import/google/new_fonts_fetcher.rb
282
277
  - lib/fontist/import/google/skiplist.yml
283
278
  - lib/fontist/import/google_check.rb
@@ -296,9 +291,11 @@ files:
296
291
  - lib/fontist/import/text_helper.rb
297
292
  - lib/fontist/index.rb
298
293
  - lib/fontist/indexes/base_index.rb
294
+ - lib/fontist/indexes/default_family_font_index.rb
299
295
  - lib/fontist/indexes/filename_index.rb
300
296
  - lib/fontist/indexes/font_index.rb
301
297
  - lib/fontist/indexes/index_formula.rb
298
+ - lib/fontist/indexes/preferred_family_font_index.rb
302
299
  - lib/fontist/manifest.rb
303
300
  - lib/fontist/manifest/install.rb
304
301
  - lib/fontist/manifest/locations.rb