fontisan 0.4.34 → 0.4.36

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.
data/lib/fontisan/cli.rb CHANGED
@@ -38,10 +38,14 @@ module Fontisan
38
38
  desc: "Omit the codepoint list from the report"
39
39
  option :font_index, type: :numeric, default: nil,
40
40
  desc: "Audit only the given face of a collection"
41
+ option :validate, type: :string, default: nil,
42
+ desc: "Run validation checks. Use 'true' for all, or a " \
43
+ "profile name: default, structural, ots, layout"
41
44
  # Produce a structured font audit report (YAML or JSON).
42
45
  def audit(font_file)
43
46
  cmd_options = options.dup
44
47
  cmd_options[:include_codepoints] = !options[:no_codepoints]
48
+ cmd_options[:validate] = parse_validate_option(options[:validate])
45
49
  command = Commands::AuditCommand.new(font_file, cmd_options)
46
50
  result = command.run
47
51
  write_audit_result(result, options[:output])
@@ -797,6 +801,15 @@ module Fontisan
797
801
  format("%<idx>02d-%<name>s.%<suffix>s", idx: idx, name: safe_name, suffix: suffix)
798
802
  end
799
803
 
804
+ # The --validate option is either nil (no validation), "true" (run all
805
+ # checks), or a profile name (e.g. "ots", "structural").
806
+ def parse_validate_option(raw)
807
+ return nil if raw.nil? || raw.empty?
808
+ return true if raw == "true"
809
+
810
+ raw.to_sym
811
+ end
812
+
800
813
  def serialize_report(report, format)
801
814
  format == :json ? report.to_json : report.to_yaml
802
815
  end
@@ -75,6 +75,7 @@ module Fontisan
75
75
  populate_style(r, face)
76
76
  populate_coverage(r, face)
77
77
  populate_layout(r, face)
78
+ populate_validation(r, face) if validate?
78
79
  end
79
80
  end
80
81
 
@@ -246,11 +247,44 @@ module Fontisan
246
247
  end
247
248
 
248
249
  def features_for_script(layout_table, script)
249
-
250
250
  layout_table.features(script_tag: script)
251
251
  rescue StandardError
252
252
  []
253
-
253
+ end
254
+
255
+ # ------------------------------------------------------------------
256
+ # Validation (audit checks)
257
+ # ------------------------------------------------------------------
258
+
259
+ def populate_validation(report, face)
260
+ report.validation_issues = run_validation_checks(face)
261
+ end
262
+
263
+ def run_validation_checks(face)
264
+ checks = Audit::CheckRegistry.for(validation_profile)
265
+ checks.flat_map { |check| safe_run_check(check, face) }
266
+ end
267
+
268
+ def safe_run_check(check, face)
269
+ check.call(face)
270
+ rescue StandardError => e
271
+ [Models::ValidationReport::Issue.new(
272
+ severity: "fatal",
273
+ category: check.code.to_s,
274
+ message: "Check #{check.code} failed to execute: #{e.class}: #{e.message}",
275
+ location: nil,
276
+ )]
277
+ end
278
+
279
+ def validate?
280
+ @options.fetch(:validate, false)
281
+ end
282
+
283
+ def validation_profile
284
+ profile = @options[:validate]
285
+ return :default if profile == true
286
+
287
+ profile&.to_sym || :default
254
288
  end
255
289
  end
256
290
  end
@@ -73,6 +73,9 @@ module Fontisan
73
73
  attribute :opentype_scripts, :string, collection: true
74
74
  attribute :features, :string, collection: true
75
75
 
76
+ # Validation (populated only with --validate)
77
+ attribute :validation_issues, Models::ValidationReport::Issue, collection: true
78
+
76
79
  json do
77
80
  map "generated_at", to: :generated_at
78
81
  map "fontisan_version", to: :fontisan_version
@@ -104,6 +107,7 @@ module Fontisan
104
107
 
105
108
  map "opentype_scripts", to: :opentype_scripts
106
109
  map "features", to: :features
110
+ map "validation_issues", to: :validation_issues
107
111
  end
108
112
 
109
113
  yaml do
@@ -137,6 +141,7 @@ module Fontisan
137
141
 
138
142
  map "opentype_scripts", to: :opentype_scripts
139
143
  map "features", to: :features
144
+ map "validation_issues", to: :validation_issues
140
145
  end
141
146
  end
142
147
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fontisan
4
- VERSION = "0.4.34"
4
+ VERSION = "0.4.36"
5
5
  end
data/lib/fontisan.rb CHANGED
@@ -77,6 +77,7 @@ module Fontisan
77
77
 
78
78
  # Namespace hubs (each hub declares its own child autoloads)
79
79
  autoload :Binary, "fontisan/binary"
80
+ autoload :Audit, "fontisan/audit"
80
81
  autoload :Collection, "fontisan/collection"
81
82
  autoload :Commands, "fontisan/commands"
82
83
  autoload :Converters, "fontisan/converters"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontisan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.34
4
+ version: 0.4.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -293,6 +293,20 @@ files:
293
293
  - exe/fontisan
294
294
  - fontisan.gemspec
295
295
  - lib/fontisan.rb
296
+ - lib/fontisan/audit.rb
297
+ - lib/fontisan/audit/check.rb
298
+ - lib/fontisan/audit/check_registry.rb
299
+ - lib/fontisan/audit/checks.rb
300
+ - lib/fontisan/audit/checks/cmap_check.rb
301
+ - lib/fontisan/audit/checks/collection_integrity_check.rb
302
+ - lib/fontisan/audit/checks/format_round_trip_check.rb
303
+ - lib/fontisan/audit/checks/glyph_name_check.rb
304
+ - lib/fontisan/audit/checks/hinting_check.rb
305
+ - lib/fontisan/audit/checks/opentype_conformance_check.rb
306
+ - lib/fontisan/audit/checks/ots_compatibility_check.rb
307
+ - lib/fontisan/audit/checks/table_directory_check.rb
308
+ - lib/fontisan/audit/checks/variable_font_check.rb
309
+ - lib/fontisan/audit/checks/woff2_validation_check.rb
296
310
  - lib/fontisan/base_collection.rb
297
311
  - lib/fontisan/binary.rb
298
312
  - lib/fontisan/binary/base_record.rb