fontist 1.9.3 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
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