fontist 3.0.27 → 3.0.29
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.
- checksums.yaml +4 -4
- data/README.adoc +148 -0
- data/fontist.gemspec +1 -1
- data/lib/fontist/cli.rb +105 -5
- data/lib/fontist/css/google_family.rb +50 -0
- data/lib/fontist/css/local.rb +157 -0
- data/lib/fontist/css/styles.rb +79 -0
- data/lib/fontist/css.rb +110 -0
- data/lib/fontist/errors.rb +3 -0
- data/lib/fontist/font_file.rb +2 -1
- data/lib/fontist/font_finder.rb +15 -2
- data/lib/fontist/font_installer.rb +97 -94
- data/lib/fontist/font_operations/convert.rb +55 -0
- data/lib/fontist/font_operations/extract.rb +53 -0
- data/lib/fontist/font_operations/instance.rb +92 -0
- data/lib/fontist/font_operations/pack.rb +49 -0
- data/lib/fontist/font_operations/subset.rb +68 -0
- data/lib/fontist/font_operations.rb +25 -0
- data/lib/fontist/format_spec.rb +35 -0
- data/lib/fontist/formula.rb +17 -0
- data/lib/fontist/formula_picker.rb +27 -8
- data/lib/fontist/import/google/data_sources/github.rb +28 -0
- data/lib/fontist/import/google/formula_builders/formula_builder_v5.rb +30 -57
- data/lib/fontist/import/google/models/font_family.rb +3 -0
- data/lib/fontist/import/google/variable_font_source.rb +105 -0
- data/lib/fontist/import/google.rb +1 -0
- data/lib/fontist/import/sil_importer.rb +18 -5
- data/lib/fontist/import/windows.rb +13 -2
- data/lib/fontist/import_cli.rb +19 -0
- data/lib/fontist/indexes/index_mixin.rb +51 -3
- data/lib/fontist/manifest.rb +63 -0
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +2 -0
- metadata +15 -4
|
@@ -75,6 +75,7 @@ module Fontist
|
|
|
75
75
|
# Drop the memoized parsed instance along with the index file,
|
|
76
76
|
# to force a fresh parse on next access
|
|
77
77
|
Fontist::FromFileCache.clear
|
|
78
|
+
reset_sidecar_cache
|
|
78
79
|
|
|
79
80
|
# Delete the index file and its lookup sidecar to force a
|
|
80
81
|
# rebuild on next access. This is important for tests to
|
|
@@ -96,10 +97,12 @@ module Fontist
|
|
|
96
97
|
def sidecar_entries
|
|
97
98
|
sidecar_path = "#{path}.json"
|
|
98
99
|
return unless File.exist?(sidecar_path)
|
|
99
|
-
return if
|
|
100
|
-
File.mtime(sidecar_path) < File.mtime(path)
|
|
100
|
+
return if sidecar_stale?(sidecar_path)
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
entries = cached_sidecar_entries(sidecar_path)
|
|
103
|
+
return entries if entries
|
|
104
|
+
|
|
105
|
+
parse_sidecar_entries(sidecar_path)
|
|
103
106
|
rescue JSON::ParserError, TypeError
|
|
104
107
|
nil
|
|
105
108
|
end
|
|
@@ -109,6 +112,51 @@ module Fontist
|
|
|
109
112
|
File.write("#{path}.json", JSON.dump("entries" => entries_hash))
|
|
110
113
|
entries_hash
|
|
111
114
|
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
|
|
118
|
+
def sidecar_stale?(sidecar_path)
|
|
119
|
+
File.exist?(path) && File.mtime(sidecar_path) < File.mtime(path)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def cached_sidecar_entries(sidecar_path)
|
|
123
|
+
mtime = File.mtime(sidecar_path)
|
|
124
|
+
entry = nil
|
|
125
|
+
sidecar_cache_mutex.synchronize do
|
|
126
|
+
entry = sidecar_cache[sidecar_path]
|
|
127
|
+
end
|
|
128
|
+
entry[:entries] if entry&.fetch(:mtime, nil) == mtime
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Parsing the sidecar costs tens of milliseconds per call and
|
|
132
|
+
# lookups re-enter many times per operation (every printed font
|
|
133
|
+
# path consults the filename sidecar), so parsed entries are
|
|
134
|
+
# memoized per sidecar mtime and shared between callers; treat
|
|
135
|
+
# as read-only
|
|
136
|
+
def parse_sidecar_entries(sidecar_path)
|
|
137
|
+
mtime = File.mtime(sidecar_path)
|
|
138
|
+
entries = JSON.parse(File.read(sidecar_path))["entries"]
|
|
139
|
+
|
|
140
|
+
sidecar_cache_mutex.synchronize do
|
|
141
|
+
sidecar_cache[sidecar_path] = { mtime: mtime, entries: entries }
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
entries
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Class-level cache of parsed sidecar entries, invalidated by
|
|
148
|
+
# sidecar mtime so `fontist update` rewrites are picked up
|
|
149
|
+
def sidecar_cache
|
|
150
|
+
@sidecar_cache ||= {}
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def sidecar_cache_mutex
|
|
154
|
+
@sidecar_cache_mutex ||= Mutex.new
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def reset_sidecar_cache
|
|
158
|
+
sidecar_cache_mutex.synchronize { sidecar_cache.clear }
|
|
159
|
+
end
|
|
112
160
|
end
|
|
113
161
|
|
|
114
162
|
# Build index by loading all formulas from disk.
|
data/lib/fontist/manifest.rb
CHANGED
|
@@ -18,6 +18,12 @@ module Fontist
|
|
|
18
18
|
# Collection options
|
|
19
19
|
attribute :collection_index, :integer
|
|
20
20
|
|
|
21
|
+
# Font operations (subsetting, conversion failure handling)
|
|
22
|
+
attribute :subset_unicodes, :string
|
|
23
|
+
attribute :subset_text, :string
|
|
24
|
+
attribute :fallback_to_original, :boolean, default: false
|
|
25
|
+
attribute :instance, :string
|
|
26
|
+
|
|
21
27
|
# Build FormatSpec from attributes
|
|
22
28
|
def format_spec
|
|
23
29
|
FormatSpec.new(
|
|
@@ -27,6 +33,10 @@ module Fontist
|
|
|
27
33
|
transcode_path: transcode_path,
|
|
28
34
|
keep_original: keep_original,
|
|
29
35
|
collection_index: collection_index,
|
|
36
|
+
subset_unicodes: subset_unicodes,
|
|
37
|
+
subset_text: subset_text,
|
|
38
|
+
fallback_to_original: fallback_to_original,
|
|
39
|
+
instance: instance,
|
|
30
40
|
)
|
|
31
41
|
end
|
|
32
42
|
|
|
@@ -129,6 +139,57 @@ module Fontist
|
|
|
129
139
|
}
|
|
130
140
|
end
|
|
131
141
|
|
|
142
|
+
# Font options a manifest entry can carry next to its styles:
|
|
143
|
+
#
|
|
144
|
+
# Roboto:
|
|
145
|
+
# styles: [Regular, Bold]
|
|
146
|
+
# format: woff2
|
|
147
|
+
#
|
|
148
|
+
# The plain form `Roboto: [Regular, Bold]` stays valid.
|
|
149
|
+
FONT_OPTIONS = %w[format variable_axes prefer_variable transcode_path
|
|
150
|
+
keep_original collection_index subset_unicodes
|
|
151
|
+
subset_text fallback_to_original instance].freeze
|
|
152
|
+
|
|
153
|
+
def self.from_yaml(content, options = {})
|
|
154
|
+
data = YAML.safe_load(content)
|
|
155
|
+
return super unless data.is_a?(Hash) && data.values.any?(Hash)
|
|
156
|
+
|
|
157
|
+
plain, font_options = split_font_options(data)
|
|
158
|
+
super(plain.to_yaml, options).tap do |manifest|
|
|
159
|
+
manifest.apply_font_options(font_options)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def self.split_font_options(data)
|
|
164
|
+
font_options = {}
|
|
165
|
+
plain = data.to_h do |name, value|
|
|
166
|
+
next [name, value] unless value.is_a?(Hash)
|
|
167
|
+
|
|
168
|
+
font_options[name] = font_options_of(name, value)
|
|
169
|
+
[name, value["styles"] || value[:styles]]
|
|
170
|
+
end
|
|
171
|
+
[plain, font_options]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def self.font_options_of(name, value)
|
|
175
|
+
value = value.transform_keys(&:to_s)
|
|
176
|
+
unknown = value.keys - FONT_OPTIONS - ["styles"]
|
|
177
|
+
unless unknown.empty?
|
|
178
|
+
raise Fontist::Errors::ManifestCouldNotBeReadError,
|
|
179
|
+
"Unknown option(s) for '#{name}': #{unknown.join(', ')}"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
value.slice(*FONT_OPTIONS)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def apply_font_options(font_options)
|
|
186
|
+
Array(fonts).each do |font|
|
|
187
|
+
font_options.fetch(font.name, {}).each do |key, value|
|
|
188
|
+
font.public_send(:"#{key}=", value)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
132
193
|
def self.from_file(path, locations: false)
|
|
133
194
|
Fontist.ui.debug("Manifest: #{path}")
|
|
134
195
|
|
|
@@ -159,8 +220,10 @@ module Fontist
|
|
|
159
220
|
|
|
160
221
|
def self.from_hash(data, options = {})
|
|
161
222
|
locations = options.delete(:locations) || false
|
|
223
|
+
data, font_options = split_font_options(data) if data.is_a?(Hash)
|
|
162
224
|
|
|
163
225
|
model = super
|
|
226
|
+
model.apply_font_options(font_options) if font_options
|
|
164
227
|
|
|
165
228
|
# Use performance optimizations for faster manifest compilation
|
|
166
229
|
with_performance_optimizations do
|
data/lib/fontist/version.rb
CHANGED
data/lib/fontist.rb
CHANGED
|
@@ -17,6 +17,7 @@ require_relative "fontist/yaml_backend"
|
|
|
17
17
|
module Fontist
|
|
18
18
|
# Core classes
|
|
19
19
|
autoload :Config, "#{__dir__}/fontist/config"
|
|
20
|
+
autoload :Css, "#{__dir__}/fontist/css"
|
|
20
21
|
autoload :Font, "#{__dir__}/fontist/font"
|
|
21
22
|
autoload :FontCollection, "#{__dir__}/fontist/font_collection"
|
|
22
23
|
autoload :FontFile, "#{__dir__}/fontist/font_file"
|
|
@@ -25,6 +26,7 @@ module Fontist
|
|
|
25
26
|
autoload :FontPath, "#{__dir__}/fontist/font_path"
|
|
26
27
|
autoload :FontStyle, "#{__dir__}/fontist/font_style"
|
|
27
28
|
autoload :Fontconfig, "#{__dir__}/fontist/fontconfig"
|
|
29
|
+
autoload :FontOperations, "#{__dir__}/fontist/font_operations"
|
|
28
30
|
autoload :FormatSpec, "#{__dir__}/fontist/format_spec"
|
|
29
31
|
autoload :Formula, "#{__dir__}/fontist/formula"
|
|
30
32
|
autoload :FormulaCollection, "#{__dir__}/fontist/formula"
|
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: 3.0.
|
|
4
|
+
version: 3.0.29
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-11-
|
|
11
|
+
date: 2026-11-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: down
|
|
@@ -53,7 +53,7 @@ dependencies:
|
|
|
53
53
|
version: '0.4'
|
|
54
54
|
- - ">="
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: 0.4.
|
|
56
|
+
version: 0.4.47
|
|
57
57
|
type: :runtime
|
|
58
58
|
prerelease: false
|
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -63,7 +63,7 @@ dependencies:
|
|
|
63
63
|
version: '0.4'
|
|
64
64
|
- - ">="
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: 0.4.
|
|
66
|
+
version: 0.4.47
|
|
67
67
|
- !ruby/object:Gem::Dependency
|
|
68
68
|
name: fuzzy_match
|
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -357,6 +357,10 @@ files:
|
|
|
357
357
|
- lib/fontist/collection_file.rb
|
|
358
358
|
- lib/fontist/config.rb
|
|
359
359
|
- lib/fontist/config_cli.rb
|
|
360
|
+
- lib/fontist/css.rb
|
|
361
|
+
- lib/fontist/css/google_family.rb
|
|
362
|
+
- lib/fontist/css/local.rb
|
|
363
|
+
- lib/fontist/css/styles.rb
|
|
360
364
|
- lib/fontist/errors.rb
|
|
361
365
|
- lib/fontist/exclude.yml
|
|
362
366
|
- lib/fontist/extract.rb
|
|
@@ -366,6 +370,12 @@ files:
|
|
|
366
370
|
- lib/fontist/font_finder.rb
|
|
367
371
|
- lib/fontist/font_installer.rb
|
|
368
372
|
- lib/fontist/font_model.rb
|
|
373
|
+
- lib/fontist/font_operations.rb
|
|
374
|
+
- lib/fontist/font_operations/convert.rb
|
|
375
|
+
- lib/fontist/font_operations/extract.rb
|
|
376
|
+
- lib/fontist/font_operations/instance.rb
|
|
377
|
+
- lib/fontist/font_operations/pack.rb
|
|
378
|
+
- lib/fontist/font_operations/subset.rb
|
|
369
379
|
- lib/fontist/font_path.rb
|
|
370
380
|
- lib/fontist/font_style.rb
|
|
371
381
|
- lib/fontist/fontconfig.rb
|
|
@@ -414,6 +424,7 @@ files:
|
|
|
414
424
|
- lib/fontist/import/google/models/font_variant.rb
|
|
415
425
|
- lib/fontist/import/google/models/metadata.rb
|
|
416
426
|
- lib/fontist/import/google/models/source_metadata.rb
|
|
427
|
+
- lib/fontist/import/google/variable_font_source.rb
|
|
417
428
|
- lib/fontist/import/google_fonts_importer.rb
|
|
418
429
|
- lib/fontist/import/google_import.rb
|
|
419
430
|
- lib/fontist/import/helpers.rb
|