fontisan 0.4.33 → 0.4.35

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b16e0b97aeb7431384ce5f50ff3e4dfd8977b863ec76655ef09e6d53fefddc3c
4
- data.tar.gz: b60547f43a45309f700f4a11bb67d36788cfde286de179b697a7fbfc3d43a897
3
+ metadata.gz: c534e6da296ea563119e164f40835bf5e794d0c7d37d4fdcd2c0e31008925410
4
+ data.tar.gz: be05402a2e893896e744432950d1f1e8951a59004f76ca9aacd2a9353f8d54cd
5
5
  SHA512:
6
- metadata.gz: c5b05277f8c003e64537cfeb57eb933b8e34f26449acc86de639b1ed90e8b344e502f0a8181417c92de1b8d4c51ffbd98ed9ccacf04ae38b4ff5e0deeb6e80b4
7
- data.tar.gz: ee1631c92ebf6a5fd7ba66c4f40bef089a8725560f08d013fd16dfafed46e6c8c3890d35128ded48d03c996f6a547bac1f2d8c17939a12bf5a429bd6ac9a1f58
6
+ metadata.gz: 2e77ac651176f1d4b42d24ac60d41d3b371ac548438bc373b9d5f1ce44b36f187050ce9e5e5b5385cfc83732e2e40d946cfb9d3ae2ac83ad9c82a20a8cc7fc5b
7
+ data.tar.gz: 903c46cd5ab5631f3ae6723bdee6f6df007c0351291e1a60856da0328ddcadbedc9a21ba68717d5db5d77031bd3b5bf69a003d08e33a8654302ae72eb122c7a4
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-07-09 14:55:09 UTC using RuboCop version 1.86.1.
3
+ # on 2026-07-11 07:11:58 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -12,183 +12,33 @@ Gemspec/RequiredRubyVersion:
12
12
  - 'docs/node_modules/speakingurl/speakingurl-rails.gemspec'
13
13
  - 'fontisan.gemspec'
14
14
 
15
- # Offense count: 276
16
- # This cop supports safe autocorrection (--autocorrect).
17
- # Configuration parameters: EnforcedStyle, IndentationWidth.
18
- # SupportedStyles: with_first_argument, with_fixed_indentation
19
- Layout/ArgumentAlignment:
20
- Enabled: false
21
-
22
- # Offense count: 22
23
- # This cop supports safe autocorrection (--autocorrect).
24
- # Configuration parameters: EnforcedStyle, IndentationWidth.
25
- # SupportedStyles: with_first_element, with_fixed_indentation
26
- Layout/ArrayAlignment:
27
- Exclude:
28
- - 'lib/fontisan/collection/writer.rb'
29
- - 'lib/fontisan/tables/cff2/index_builder.rb'
30
- - 'lib/fontisan/ufo/compile/cbdt_cblc.rb'
31
- - 'lib/fontisan/ufo/compile/cff.rb'
32
- - 'lib/fontisan/ufo/compile/cmap.rb'
33
- - 'lib/fontisan/ufo/compile/cpal.rb'
34
- - 'lib/fontisan/ufo/compile/gvar.rb'
35
- - 'lib/fontisan/ufo/compile/item_variation_store.rb'
36
- - 'lib/fontisan/ufo/compile/sbix.rb'
37
- - 'lib/fontisan/ufo/compile/stat.rb'
38
- - 'lib/fontisan/ufo/info.rb'
39
- - 'spec/fontisan/stitcher/glyph_signature_spec.rb'
40
- - 'spec/fontisan/svg_to_glyf/contour_builder_spec.rb'
41
- - 'spec/fontisan/ufo/compile/feature_writers/mkmk_spec.rb'
42
- - 'spec/fontisan/ufo/compile/filters/transformations_spec.rb'
43
-
44
- # Offense count: 1
45
- # This cop supports safe autocorrection (--autocorrect).
46
- # Configuration parameters: IndentationWidth.
47
- Layout/AssignmentIndentation:
48
- Exclude:
49
- - 'lib/fontisan/woff2/glyf_loca_reconstruct.rb'
50
-
51
- # Offense count: 58
52
- # This cop supports safe autocorrection (--autocorrect).
53
- # Configuration parameters: EnforcedStyleAlignWith.
54
- # SupportedStylesAlignWith: either, start_of_block, start_of_line
55
- Layout/BlockAlignment:
56
- Enabled: false
57
-
58
- # Offense count: 55
59
- # This cop supports safe autocorrection (--autocorrect).
60
- Layout/BlockEndNewline:
61
- Enabled: false
62
-
63
- # Offense count: 29
64
- # This cop supports safe autocorrection (--autocorrect).
65
- Layout/ClosingParenthesisIndentation:
66
- Exclude:
67
- - 'benchmark/compile_benchmark.rb'
68
- - 'lib/fontisan/ufo/compile/fvar.rb'
69
- - 'lib/fontisan/ufo/writer.rb'
70
- - 'spec/fontisan/stitcher/deduplicator_spec.rb'
71
- - 'spec/fontisan/stitcher/include_codepoints_map_spec.rb'
72
- - 'spec/fontisan/svg_to_glyf/affine_transform_spec.rb'
73
- - 'spec/fontisan/ufo/compile/filters/propagate_anchors_spec.rb'
74
- - 'spec/fontisan/ufo/compile_gvar_spec.rb'
75
- - 'spec/fontisan/ufo/compile_item_variation_store_spec.rb'
76
- - 'spec/fontisan/ufo/filters_spec.rb'
77
-
78
- # Offense count: 2
79
- # This cop supports safe autocorrection (--autocorrect).
80
- # Configuration parameters: AllowForAlignment.
81
- Layout/CommentIndentation:
82
- Exclude:
83
- - 'lib/fontisan/ufo/compile/cff.rb'
84
-
85
15
  # Offense count: 4
86
16
  # This cop supports safe autocorrection (--autocorrect).
87
- Layout/ElseAlignment:
88
- Exclude:
89
- - 'lib/fontisan/commands/validate_collection_command.rb'
90
- - 'lib/fontisan/converters/collection_converter.rb'
91
- - 'spec/fontisan/woff2/sfnt_checksum_spec.rb'
92
-
93
- # Offense count: 4
94
- # This cop supports safe autocorrection (--autocorrect).
95
- # Configuration parameters: EnforcedStyleAlignWith.
96
- # SupportedStylesAlignWith: keyword, variable, start_of_line
97
- Layout/EndAlignment:
98
- Exclude:
99
- - 'lib/fontisan/commands/validate_collection_command.rb'
100
- - 'lib/fontisan/converters/collection_converter.rb'
101
- - 'spec/fontisan/woff2/sfnt_checksum_spec.rb'
102
-
103
- # Offense count: 29
104
- # This cop supports safe autocorrection (--autocorrect).
105
- # Configuration parameters: EnforcedStyle, IndentationWidth.
106
- # SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
107
- Layout/FirstArgumentIndentation:
108
- Exclude:
109
- - 'benchmark/compile_benchmark.rb'
110
- - 'lib/fontisan/ufo/compile/fvar.rb'
111
- - 'lib/fontisan/ufo/writer.rb'
112
- - 'spec/fontisan/stitcher/deduplicator_spec.rb'
113
- - 'spec/fontisan/stitcher/include_codepoints_map_spec.rb'
114
- - 'spec/fontisan/svg_to_glyf/affine_transform_spec.rb'
115
- - 'spec/fontisan/ufo/compile/filters/propagate_anchors_spec.rb'
116
- - 'spec/fontisan/ufo/compile_gvar_spec.rb'
117
- - 'spec/fontisan/ufo/compile_item_variation_store_spec.rb'
118
- - 'spec/fontisan/ufo/filters_spec.rb'
119
-
120
- # Offense count: 14
121
- # This cop supports safe autocorrection (--autocorrect).
122
- # Configuration parameters: EnforcedStyle, IndentationWidth.
123
- # SupportedStyles: special_inside_parentheses, consistent, align_brackets
124
- Layout/FirstArrayElementIndentation:
125
- Exclude:
126
- - 'spec/fontisan/stitcher/glyph_signature_spec.rb'
127
- - 'spec/fontisan/ufo/compile/feature_writers/mark_spec.rb'
128
-
129
- # Offense count: 194
130
- # This cop supports safe autocorrection (--autocorrect).
131
17
  # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
132
18
  # SupportedHashRocketStyles: key, separator, table
133
19
  # SupportedColonStyles: key, separator, table
134
20
  # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
135
21
  Layout/HashAlignment:
136
- Enabled: false
137
-
138
- # Offense count: 1
139
- # This cop supports safe autocorrection (--autocorrect).
140
- # Configuration parameters: EnforcedStyle.
141
- # SupportedStyles: normal, indented_internal_methods
142
- Layout/IndentationConsistency:
143
22
  Exclude:
144
- - 'lib/fontisan/ufo/compile/cff.rb'
23
+ - 'lib/fontisan/ufo/compile/variable_otf.rb'
24
+ - 'spec/fontisan/ufo/compile/cff2_spec.rb'
145
25
 
146
- # Offense count: 121
26
+ # Offense count: 9
147
27
  # This cop supports safe autocorrection (--autocorrect).
148
28
  # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
149
29
  # SupportedStylesAlignWith: start_of_line, relative_to_receiver
150
30
  Layout/IndentationWidth:
151
- Enabled: false
31
+ Exclude:
32
+ - 'lib/fontisan/commands/audit_command.rb'
33
+ - 'lib/fontisan/ufo/compile/glyf_loca.rb'
152
34
 
153
- # Offense count: 2235
35
+ # Offense count: 2030
154
36
  # This cop supports safe autocorrection (--autocorrect).
155
37
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
156
38
  # URISchemes: http, https
157
39
  Layout/LineLength:
158
40
  Enabled: false
159
41
 
160
- # Offense count: 7
161
- # This cop supports safe autocorrection (--autocorrect).
162
- # Configuration parameters: EnforcedStyle.
163
- # SupportedStyles: symmetrical, new_line, same_line
164
- Layout/MultilineArrayBraceLayout:
165
- Exclude:
166
- - 'spec/fontisan/stitcher/glyph_signature_spec.rb'
167
- - 'spec/fontisan/ufo/compile/feature_writers/mark_spec.rb'
168
-
169
- # Offense count: 29
170
- # This cop supports safe autocorrection (--autocorrect).
171
- # Configuration parameters: EnforcedStyle.
172
- # SupportedStyles: symmetrical, new_line, same_line
173
- Layout/MultilineMethodCallBraceLayout:
174
- Exclude:
175
- - 'benchmark/compile_benchmark.rb'
176
- - 'lib/fontisan/ufo/compile/fvar.rb'
177
- - 'lib/fontisan/ufo/writer.rb'
178
- - 'spec/fontisan/stitcher/deduplicator_spec.rb'
179
- - 'spec/fontisan/stitcher/include_codepoints_map_spec.rb'
180
- - 'spec/fontisan/svg_to_glyf/affine_transform_spec.rb'
181
- - 'spec/fontisan/ufo/compile/filters/propagate_anchors_spec.rb'
182
- - 'spec/fontisan/ufo/compile_gvar_spec.rb'
183
- - 'spec/fontisan/ufo/compile_item_variation_store_spec.rb'
184
- - 'spec/fontisan/ufo/filters_spec.rb'
185
-
186
- # Offense count: 225
187
- # This cop supports safe autocorrection (--autocorrect).
188
- # Configuration parameters: AllowInHeredoc.
189
- Layout/TrailingWhitespace:
190
- Enabled: false
191
-
192
42
  # Offense count: 2
193
43
  Lint/CopDirectiveSyntax:
194
44
  Exclude:
@@ -248,7 +98,7 @@ Lint/StructNewOverride:
248
98
  Exclude:
249
99
  - 'lib/fontisan/optimizers/pattern_analyzer.rb'
250
100
 
251
- # Offense count: 24
101
+ # Offense count: 33
252
102
  # This cop supports safe autocorrection (--autocorrect).
253
103
  # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
254
104
  # NotImplementedExceptions: NotImplementedError
@@ -261,12 +111,12 @@ Lint/UselessConstantScoping:
261
111
  - 'lib/fontisan/conversion_options.rb'
262
112
  - 'lib/fontisan/type1/charstrings.rb'
263
113
 
264
- # Offense count: 715
114
+ # Offense count: 762
265
115
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
266
116
  Metrics/AbcSize:
267
117
  Enabled: false
268
118
 
269
- # Offense count: 34
119
+ # Offense count: 37
270
120
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
271
121
  # AllowedMethods: refine
272
122
  Metrics/BlockLength:
@@ -284,28 +134,28 @@ Metrics/CollectionLiteralLength:
284
134
  - 'lib/fontisan/type1/agl.rb'
285
135
  - 'lib/fontisan/type1/encodings.rb'
286
136
 
287
- # Offense count: 367
137
+ # Offense count: 379
288
138
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
289
139
  Metrics/CyclomaticComplexity:
290
140
  Enabled: false
291
141
 
292
- # Offense count: 990
142
+ # Offense count: 1034
293
143
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
294
144
  Metrics/MethodLength:
295
145
  Max: 135
296
146
 
297
- # Offense count: 30
147
+ # Offense count: 31
298
148
  # Configuration parameters: CountKeywordArgs.
299
149
  Metrics/ParameterLists:
300
150
  Max: 39
301
151
  MaxOptionalParameters: 4
302
152
 
303
- # Offense count: 279
153
+ # Offense count: 291
304
154
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
305
155
  Metrics/PerceivedComplexity:
306
156
  Enabled: false
307
157
 
308
- # Offense count: 202
158
+ # Offense count: 209
309
159
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
310
160
  # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
311
161
  Naming/MethodParameterName:
@@ -371,7 +221,7 @@ RSpec/AnyInstance:
371
221
  RSpec/ContextWording:
372
222
  Enabled: false
373
223
 
374
- # Offense count: 39
224
+ # Offense count: 41
375
225
  # Configuration parameters: IgnoredMetadata.
376
226
  RSpec/DescribeClass:
377
227
  Enabled: false
@@ -387,7 +237,7 @@ RSpec/DescribeMethod:
387
237
  - 'spec/fontisan/type1/seac_expander_spec.rb'
388
238
  - 'spec/fontisan/type1_real_fonts_spec.rb'
389
239
 
390
- # Offense count: 1710
240
+ # Offense count: 1727
391
241
  # Configuration parameters: CountAsOne.
392
242
  RSpec/ExampleLength:
393
243
  Max: 66
@@ -465,7 +315,7 @@ RSpec/MultipleDescribes:
465
315
  - 'spec/fontisan/utils/thread_pool_spec.rb'
466
316
  - 'spec/fontisan/variation/cache_spec.rb'
467
317
 
468
- # Offense count: 2126
318
+ # Offense count: 2151
469
319
  RSpec/MultipleExpectations:
470
320
  Max: 19
471
321
 
@@ -529,16 +379,6 @@ Rake/MethodDefinitionInTask:
529
379
  Exclude:
530
380
  - 'Rakefile'
531
381
 
532
- # Offense count: 68
533
- # This cop supports safe autocorrection (--autocorrect).
534
- # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
535
- # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
536
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
537
- # FunctionalMethods: let, let!, subject, watch
538
- # AllowedMethods: lambda, proc, it
539
- Style/BlockDelimiters:
540
- Enabled: false
541
-
542
382
  # Offense count: 6
543
383
  # This cop supports safe autocorrection (--autocorrect).
544
384
  Style/ComparableClamp:
@@ -573,47 +413,9 @@ Style/HashLikeCase:
573
413
  - 'lib/fontisan/commands/unpack_command.rb'
574
414
  - 'lib/fontisan/models/validation_report.rb'
575
415
 
576
- # Offense count: 16
577
- # This cop supports safe autocorrection (--autocorrect).
578
- Style/MultilineIfModifier:
579
- Exclude:
580
- - 'lib/fontisan/svg/standalone_glyph.rb'
581
- - 'lib/fontisan/svg_to_glyf/geometry/transform_parser.rb'
582
- - 'lib/fontisan/ufo/cli.rb'
583
- - 'lib/fontisan/ufo/convert.rb'
584
- - 'lib/fontisan/ufo/convert/from_bin_data.rb'
585
- - 'lib/fontisan/ufo/convert/to_dfont.rb'
586
- - 'lib/fontisan/ufo/convert/to_otc.rb'
587
- - 'lib/fontisan/ufo/convert/to_postscript.rb'
588
- - 'lib/fontisan/ufo/convert/to_woff.rb'
589
- - 'lib/fontisan/ufo/convert/to_woff2.rb'
590
- - 'lib/fontisan/ufo/plist.rb'
591
- - 'lib/fontisan/woff2/collection_decoder.rb'
592
- - 'lib/fontisan/woff2/collection_encoder.rb'
593
- - 'spec/support/fixture_downloader.rb'
594
-
595
- # Offense count: 4
596
- # This cop supports safe autocorrection (--autocorrect).
597
- Style/MultilineTernaryOperator:
598
- Exclude:
599
- - 'lib/fontisan/commands/validate_collection_command.rb'
600
- - 'lib/fontisan/converters/collection_converter.rb'
601
- - 'spec/fontisan/woff2/sfnt_checksum_spec.rb'
602
-
603
416
  # Offense count: 1
604
417
  # Configuration parameters: AllowedMethods.
605
418
  # AllowedMethods: respond_to_missing?
606
419
  Style/OptionalBooleanParameter:
607
420
  Exclude:
608
421
  - 'lib/fontisan/conversion_options.rb'
609
-
610
- # Offense count: 22
611
- # This cop supports safe autocorrection (--autocorrect).
612
- # Configuration parameters: EnforcedStyleForMultiline.
613
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
614
- Style/TrailingCommaInArguments:
615
- Exclude:
616
- - 'benchmark/compile_benchmark.rb'
617
- - 'spec/fontisan/ufo/compile/filters/propagate_anchors_spec.rb'
618
- - 'spec/fontisan/ufo/compile_gvar_spec.rb'
619
- - 'spec/fontisan/ufo/filters_spec.rb'
@@ -11,7 +11,7 @@ Each file is `NN-short-name.md` where `NN` is the priority order.
11
11
  - [x] ~~[15 — CFF/CFF2 subsetter strategy](15-cff-cff2-subsetter-strategy.md)~~ ✓ Done — CFF via UFO round-trip, CFF2 via standalone INDEX filter with VStore preservation
12
12
 
13
13
  ### P1 — High-value features
14
- - [03 — `fontisan audit` command (identity+style+features lens)](03-fontisan-audit-command.md)
14
+ - [x] ~~[03 — `fontisan audit` command (identity+style+features lens)](03-fontisan-audit-command.md)~~ ✓ Done (Phase 1: identity, style, coverage, layout, provenance; Phase 2 axes: table directory validation, glyph name validation, cmap validation, OTS compatibility predictor, collection integrity; CLI `fontisan audit --validate` with profiles: default, structural, ots, layout)
15
15
  - [x] ~~[04 — UFO composite glyph encoding](04-ufo-composite-glyph-encoding.md)~~ ✓ Done
16
16
  - [x] ~~[05 — OTF compiler real CFF charstrings](05-otf-compiler-real-cff.md)~~ ✓ Already working (discovered in PR #117 — Cff.build produces real Type 2 charstrings; stale TODO marker removed)
17
17
 
@@ -19,14 +19,14 @@ Each file is `NN-short-name.md` where `NN` is the priority order.
19
19
  - [x] ~~[07 — CPAL v1 header fields](07-cpal-v1-header-fields.md)~~ ✓ Done (v0.4.25)
20
20
  - [x] ~~[08 — CFF standard string table](08-cff-standard-string-table.md)~~ ✓ Done (full 391 SIDs per Adobe TN 5176)
21
21
  - [x] ~~[06 — CFF2 blend/vsindex operators](06-cff2-blend-vsindex-operators.md)~~ ✓ Done — `Cff2.build_variable` emits blend operators in charstrings; `VariableOtf` passes masters through; VStore embedded with regions
22
- - [09 — Type 1 seac expansion](09-type1-seac-expansion.md)
23
- - [10 — UFO image set + feature writers](10-ufo-image-set-feature-writers.md)
22
+ - [x] ~~[09 — Type 1 seac expansion](09-type1-seac-expansion.md)~~ ✓ Done — recursive seac expansion with cycle detection; `CharStrings.from_hash` factory added for clean test construction
23
+ - [x] ~~[10 — UFO image set + feature writers](10-ufo-image-set-feature-writers.md)~~ ✓ Done — `ImageSet` loads/writes UFO 3 images directory; `FeatureCompiler` parses liga/kern FEA constructs; `Compile::Gsub` builds LigatureSubst GSUB
24
24
  - [x] ~~[11 — kern groups.plist support](11-kern-groups-plist.md)~~ ✓ Done (Groups model in PR #116 + GPOS group resolution in this PR)
25
25
 
26
26
  ### P3 — Code-quality cleanup
27
27
  - [x] ~~[13 — Split `OctokitFetcher` out of `fixture_downloader.rb`](13-split-octokit-fetcher.md)~~ ✓ Done (v0.4.24)
28
28
  - [x] ~~[12 — `cbdt_fixture.rb` full BinData conversion](12-cbdt-fixture-bindata-conversion.md)~~ ✓ Done (critical tables converted; remaining os2/name/hmtx/cmap verified correct, BinData conversion is diminishing returns)
29
- - [14 — Rubocop baseline chip (per-namespace)](14-rubocop-baseline-chip.md)
29
+ - [x] ~~[14 — Rubocop baseline chip (per-namespace)](14-rubocop-baseline-chip.md)~~ ✓ Partially done — baseline reduced from 619 to 428 lines; all namespaces pass `rubocop` with 0 offenses; remaining baseline offenses are non-autocorrectable manual fixes (~7h total per TODO estimate)
30
30
 
31
31
  ## Convention
32
32
 
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Fontisan
6
+ module Audit
7
+ # Abstract base for all audit checks. A check is a stateless
8
+ # function that examines a loaded font and returns an Array of
9
+ # {Models::ValidationReport::Issue} records. An empty array means
10
+ # the font passed the check.
11
+ #
12
+ # Subclasses MUST override {.call} and {.code}.
13
+ #
14
+ # Checks are intentionally stateless + side-effect free so they
15
+ # can be composed, run in parallel, and tested in isolation.
16
+ class Check
17
+ # Run the check against +font+.
18
+ #
19
+ # @param font [SfntFont, BaseCollection]
20
+ # @return [Array<Models::ValidationReport::Issue>]
21
+ def self.call(font)
22
+ raise NotImplementedError,
23
+ "#{name} must override .call(font) -> Array<Issue>"
24
+ end
25
+
26
+ # Unique short identifier for this check (e.g. :table_checksum).
27
+ # Used as the issue +category+ for programmatic filtering.
28
+ #
29
+ # @return [Symbol]
30
+ def self.code
31
+ raise NotImplementedError,
32
+ "#{name} must override .code -> Symbol"
33
+ end
34
+
35
+ # Build an issue. Centralizes the category so callers don't repeat it.
36
+ # @return [Models::ValidationReport::Issue]
37
+ def self.issue(severity:, message:, location: nil)
38
+ Models::ValidationReport::Issue.new(
39
+ severity: severity.to_s,
40
+ category: code.to_s,
41
+ message: message,
42
+ location: location,
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontisan
4
+ module Audit
5
+ # Central registry of audit checks. A profile is a named subset of
6
+ # checks (e.g. +:ots+, +:structural+). The +:default+ profile runs
7
+ # every registered check.
8
+ #
9
+ # Profiles let callers opt into specific validation axes without
10
+ # running everything — e.g. +fontisan audit font.ttf --validate ots+
11
+ # runs only the OTS compatibility check.
12
+ #
13
+ # @example Run all checks
14
+ # CheckRegistry.for(:default) # => [TableDirectoryCheck, ...]
15
+ #
16
+ # @example Run a specific profile
17
+ # CheckRegistry.for(:ots) # => [OtsCompatibilityCheck]
18
+ class CheckRegistry
19
+ PROFILES = {
20
+ default: %i[table_directory glyph_names cmap ots_compatibility
21
+ collection_integrity],
22
+ structural: %i[table_directory collection_integrity],
23
+ ots: %i[ots_compatibility],
24
+ layout: %i[glyph_names cmap],
25
+ }.freeze
26
+
27
+ # @param profile [Symbol]
28
+ # @return [Array<Class>] check classes for the profile
29
+ def self.for(profile)
30
+ codes = PROFILES[profile] || PROFILES[:default]
31
+ codes.filter_map { |code| check_for(code) }
32
+ end
33
+
34
+ # @param code [Symbol]
35
+ # @return [Class, nil] the check class
36
+ def self.check_for(code)
37
+ case code
38
+ when :table_directory then Checks::TableDirectoryCheck
39
+ when :glyph_names then Checks::GlyphNameCheck
40
+ when :cmap then Checks::CmapCheck
41
+ when :ots_compatibility then Checks::OtsCompatibilityCheck
42
+ when :collection_integrity then Checks::CollectionIntegrityCheck
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end