svg_conform 0.1.0 → 0.1.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -1
  3. data/.github/workflows/release.yml +6 -2
  4. data/.rubocop_todo.yml +273 -10
  5. data/Gemfile +1 -0
  6. data/README.adoc +54 -37
  7. data/config/profiles/metanorma.yml +4 -4
  8. data/docs/remediation.adoc +541 -542
  9. data/docs/requirements.adoc +800 -357
  10. data/examples/readme_usage.rb +67 -0
  11. data/examples/requirements_demo.rb +4 -4
  12. data/lib/svg_conform/document.rb +7 -1
  13. data/lib/svg_conform/element_proxy.rb +101 -0
  14. data/lib/svg_conform/fast_document_analyzer.rb +82 -0
  15. data/lib/svg_conform/node_index_builder.rb +47 -0
  16. data/lib/svg_conform/remediations/no_external_css_remediation.rb +4 -4
  17. data/lib/svg_conform/requirements/allowed_elements_requirement.rb +202 -0
  18. data/lib/svg_conform/requirements/base_requirement.rb +27 -0
  19. data/lib/svg_conform/requirements/color_restrictions_requirement.rb +53 -0
  20. data/lib/svg_conform/requirements/font_family_requirement.rb +18 -0
  21. data/lib/svg_conform/requirements/forbidden_content_requirement.rb +26 -0
  22. data/lib/svg_conform/requirements/id_reference_requirement.rb +96 -0
  23. data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +91 -0
  24. data/lib/svg_conform/requirements/link_validation_requirement.rb +30 -0
  25. data/lib/svg_conform/requirements/namespace_attributes_requirement.rb +59 -0
  26. data/lib/svg_conform/requirements/namespace_requirement.rb +74 -0
  27. data/lib/svg_conform/requirements/no_external_css_requirement.rb +74 -0
  28. data/lib/svg_conform/requirements/no_external_fonts_requirement.rb +58 -0
  29. data/lib/svg_conform/requirements/no_external_images_requirement.rb +40 -0
  30. data/lib/svg_conform/requirements/style_requirement.rb +12 -0
  31. data/lib/svg_conform/requirements/viewbox_required_requirement.rb +72 -0
  32. data/lib/svg_conform/sax_document.rb +46 -0
  33. data/lib/svg_conform/sax_validation_handler.rb +158 -0
  34. data/lib/svg_conform/validation_context.rb +84 -2
  35. data/lib/svg_conform/validator.rb +74 -6
  36. data/lib/svg_conform/version.rb +1 -1
  37. data/lib/svg_conform.rb +1 -0
  38. data/spec/fixtures/namespace/repair/basic_violations.svg +3 -3
  39. data/spec/fixtures/namespace_attributes/repair/basic_violations.svg +2 -2
  40. data/spec/fixtures/no_external_css/repair/basic_violations.svg +2 -2
  41. data/spec/fixtures/style_promotion/repair/basic_test.svg +2 -2
  42. data/svg_conform.gemspec +1 -1
  43. metadata +12 -6
@@ -1,44 +1,49 @@
1
- = SVG Requirements
1
+ = SvgConform requirements
2
2
  :toc: left
3
3
  :toclevels: 3
4
4
  :sectlinks:
5
5
  :sectanchors:
6
6
  :source-highlighter: rouge
7
7
 
8
- == Overview
8
+ == Purpose
9
9
 
10
- **Requirements** are the core validation logic that check SVG documents for conformance issues. There are two types of requirements:
10
+ Requirements are the core validation logic that check SVG documents for
11
+ conformance issues.
11
12
 
12
- === Structural Requirements
13
+ Requirements are configured in YAML format, allowing flexible and reusable
14
+ validation rules.
13
15
 
14
- Structural requirements validate the basic structure and syntax of SVG documents.
16
+ == Available requirements
15
17
 
16
- === Logical Requirements
18
+ [[namespace-requirement]]
19
+ === Namespace requirement
17
20
 
18
- Logical requirements validate the content and semantics of SVG documents.
21
+ ==== General
19
22
 
20
- Requirements can be configured with specific parameters to customize their behavior for different use cases. Each requirement type provides configuration options that affect how validation is performed.
23
+ Ensures proper SVG namespace declarations on elements, and prevents disallowed
24
+ namespaces from appearing in the document.
21
25
 
22
- == Available requirements
26
+ Implemented as `NamespaceRequirement`.
23
27
 
24
- SvgConform provides 15 different requirement types that can be configured in profiles to validate specific aspects of SVG documents.
28
+ ==== Configuration options
25
29
 
26
- === Structural requirements
30
+ `allowed_namespaces`:: List of permitted namespace URIs. Default includes SVG
31
+ and XLink namespaces.
27
32
 
28
- These validate the fundamental structure and syntax of SVG documents:
33
+ `required_namespace`:: The namespace URI that must be present on the root
34
+ element. Default: `"http://www.w3.org/2000/svg"`.
29
35
 
30
- [[namespace-requirement]]
31
- ==== NamespaceRequirement
36
+ `allow_rdf_metadata`:: Boolean flag to permit RDF/Dublin Core metadata
37
+ namespaces.
32
38
 
33
- Ensures proper SVG namespace declarations on elements.
39
+ `true`::: RDF namespaces are silently allowed.
40
+ `false`::: (default) RDF namespace errors are generated.
34
41
 
35
- **Configuration Options**:
42
+ ==== Configuration
36
43
 
37
- `allowed_namespaces`:: List of permitted namespace URIs. Default includes SVG and XLink namespaces.
38
- `required_namespace`:: The namespace URI that must be present on the root element. Default: `"http://www.w3.org/2000/svg"`.
39
- `allow_rdf_metadata`:: Boolean flag to permit RDF/Dublin Core metadata namespaces. When `true`, RDF namespaces are silently allowed. When `false` (default), RDF namespace errors are generated. Default: `false`.
40
-
41
- Configuration:
44
+ .Example configuration of NamespaceRequirement
45
+ [example]
46
+ ====
42
47
  [source,yaml]
43
48
  ----
44
49
  - id: "svg_namespace"
@@ -48,76 +53,132 @@ Configuration:
48
53
  - "http://www.w3.org/2000/svg"
49
54
  - ""
50
55
  required_namespace: "http://www.w3.org/2000/svg"
51
- allow_rdf_metadata: false # or true for permissive RDF handling
56
+ allow_rdf_metadata: false
52
57
  ----
58
+ ====
59
+
60
+ ==== Example from svg_1_2_rfc profile
53
61
 
54
- .Strict RDF validation (default)
55
62
  [example]
63
+ ====
56
64
  [source,yaml]
57
65
  ----
58
66
  - id: "namespace_validation"
59
67
  type: "NamespaceRequirement"
60
- allow_rdf_metadata: false # Strict: RDF errors generated
68
+ description: "Only allows SVG namespace elements per RFC 7996 Section 2.1"
69
+ allow_rdf_metadata: false
61
70
  allowed_namespaces:
62
71
  - "http://www.w3.org/2000/svg"
63
72
  - ""
64
73
  ----
74
+ ====
65
75
 
66
- RDF namespace elements will trigger validation errors that can be filtered for svgcheck compatibility or reported to users.
76
+ ==== RDF metadata support
77
+
78
+ The `allow_rdf_metadata` parameter controls how RDF/Dublin Core metadata
79
+ namespaces are handled.
80
+
81
+ ===== Strict RDF validation
67
82
 
68
- .Permissive RDF handling
69
83
  [example]
84
+ ====
70
85
  [source,yaml]
71
86
  ----
72
87
  - id: "namespace_validation"
73
88
  type: "NamespaceRequirement"
74
- allow_rdf_metadata: true # Permissive: RDF silently allowed
89
+ allow_rdf_metadata: false
75
90
  allowed_namespaces:
76
91
  - "http://www.w3.org/2000/svg"
77
92
  - ""
78
93
  ----
79
94
 
80
- RDF/Dublin Core metadata elements are silently accepted without generating errors.
95
+ RDF namespace elements will trigger validation errors that can be filtered for
96
+ svgcheck compatibility or reported to users.
97
+ ====
98
+
99
+ ===== Permissive RDF handling
100
+
101
+ [example]
102
+ ====
103
+ [source,yaml]
104
+ ----
105
+ - id: "namespace_validation"
106
+ type: "NamespaceRequirement"
107
+ allow_rdf_metadata: true
108
+ allowed_namespaces:
109
+ - "http://www.w3.org/2000/svg"
110
+ - ""
111
+ ----
112
+
113
+ RDF/Dublin Core metadata elements are silently accepted without generating
114
+ errors.
115
+ ====
116
+
117
+ Supported RDF namespaces (when `allow_rdf_metadata: true`) are:
118
+
119
+ * `http://www.w3.org/1999/02/22-rdf-syntax-ns#`
120
+ * `http://creativecommons.org/ns#`
121
+ * `http://purl.org/dc/elements/1.1/`
122
+ * `http://purl.org/dc/dcmitype/`
123
+ * `http://www.w3.org/2000/01/rdf-schema#`
124
+
125
+ For complete RDF metadata configuration details, see
126
+ link:rdf_metadata_support.adoc[RDF Metadata Support Documentation].
127
+
128
+ ==== Features
81
129
 
82
- Features:
83
130
  * Validates root SVG element has correct namespace
84
131
  * Removes elements with disallowed namespaces
85
132
  * Supports whitelist and blacklist modes
86
- * **Configurable RDF metadata support**: Control whether RDF namespaces are allowed
87
- * **Generic namespace detection**: No hardcoded element names
133
+ * Configurable RDF metadata support: Control whether RDF namespaces are allowed
134
+ * Generic namespace detection: No hardcoded element names
88
135
 
89
- **Supported RDF Namespaces** (when `allow_rdf_metadata: true`):
90
- - `http://www.w3.org/1999/02/22-rdf-syntax-ns#`
91
- - `http://creativecommons.org/ns#`
92
- - `http://purl.org/dc/elements/1.1/`
93
- - `http://purl.org/dc/dcmitype/`
94
- - `http://www.w3.org/2000/01/rdf-schema#`
136
+ ==== Related remediation
95
137
 
96
- For complete RDF metadata configuration details, see link:rdf_metadata_support.adoc[RDF Metadata Support Documentation].
138
+ * link:remediation.adoc#namespace-remediation[NamespaceRemediation]
97
139
 
98
- **Target Remediations**: link:remediation.adoc#namespace-remediation[NamespaceRemediation]
99
140
 
100
141
  [[allowed-elements-requirement]]
101
- ==== AllowedElementsRequirement
142
+ === Allowed elements requirement
143
+
144
+ ==== General
102
145
 
103
- Restricts which SVG elements and attributes are permitted.
146
+ Restricts which SVG elements and attributes are permitted in the document.
104
147
 
105
- **Configuration Options**:
148
+ Implemented as `AllowedElementsRequirement`.
106
149
 
107
- `element_configs`:: List of element configuration objects defining allowed elements and their attributes.
108
- `check_attributes`:: Boolean flag to enable attribute validation. Default: `false`.
109
- `check_parent_child`:: Boolean flag to enable parent-child relationship validation. Default: `false`.
110
- `skip_foreign_namespaces`:: Boolean flag to skip validation of foreign namespace elements. When `true`, elements in non-SVG namespaces are skipped and handled by NamespaceRequirement instead. Default: `false`.
111
- `allowed_namespaces`:: List of namespace URIs that are considered valid (not foreign). Used with `skip_foreign_namespaces`. Default: `[]`.
112
- `allow_rdf_metadata`:: Boolean flag to permit RDF/Dublin Core metadata namespaces. When `true`, RDF namespace elements are considered valid and skipped. Default: `false`.
150
+ ==== Configuration options
113
151
 
114
- Each element configuration object supports:
115
- - `tag`: Element name (required)
116
- - `attributes`: List of allowed attribute names
117
- - `required_attributes`: List of mandatory attribute names
118
- - `allowed_children`: List of allowed child element names
152
+ `element_configs`:: List of element configuration objects defining allowed
153
+ elements and their attributes. Each configuration object includes:
119
154
 
120
- Configuration:
155
+ `tag`::: Element name (required)
156
+ `attributes`::: List of allowed attribute names
157
+ `required_attributes`::: List of mandatory attribute names
158
+ `allowed_children`::: List of allowed child element names
159
+
160
+ `check_attributes`:: Boolean flag to enable attribute validation. Default:
161
+ `false`.
162
+
163
+ `check_parent_child`:: Boolean flag to enable parent-child relationship
164
+ validation. Default: `false`.
165
+
166
+ `skip_foreign_namespaces`:: Boolean flag to skip validation of foreign
167
+ namespace elements. When `true`, elements in non-SVG namespaces are skipped
168
+ and handled by NamespaceRequirement instead. Default: `false`.
169
+
170
+ `allowed_namespaces`:: List of namespace URIs that are considered valid (not
171
+ foreign). Used with `skip_foreign_namespaces`. Default: `[]`.
172
+
173
+ `allow_rdf_metadata`:: Boolean flag to permit RDF/Dublin Core metadata
174
+ namespaces. When `true`, RDF namespace elements are considered valid and
175
+ skipped. Default: `false`.
176
+
177
+ ==== Configuration
178
+
179
+ .Example configuration of AllowedElementsRequirement
180
+ [example]
181
+ ====
121
182
  [source,yaml]
122
183
  ----
123
184
  - id: "svg_elements"
@@ -135,575 +196,957 @@ Configuration:
135
196
  allowed_children: ["g", "rect", "circle", "path", "text"]
136
197
  - tag: "rect"
137
198
  attributes: ["x", "y", "width", "height", "fill", "stroke"]
138
- - tag: "circle"
139
- attributes: ["cx", "cy", "r", "fill", "stroke"]
140
199
  check_attributes: true
141
200
  check_parent_child: true
142
201
  ----
202
+ ====
203
+
204
+ ==== Example from svg_1_2_rfc profile
143
205
 
144
- .Generic namespace skipping
145
206
  [example]
207
+ ====
146
208
  [source,yaml]
147
209
  ----
148
210
  - id: "allowed_elements"
149
211
  type: "AllowedElementsRequirement"
212
+ description: "Validates allowed SVG elements and attributes per RFC 7996"
150
213
  skip_foreign_namespaces: true
214
+ allow_rdf_metadata: false
151
215
  allowed_namespaces:
152
216
  - "http://www.w3.org/2000/svg"
153
217
  - ""
154
218
  element_configs:
155
- # ... element definitions
219
+ - tag: "svg"
220
+ attributes: ["version", "baseProfile", "width", "viewBox"]
221
+ required_attributes: ["version", "baseProfile"]
222
+ allowed_children: ["title", "path", "rect", "circle", "g", "defs"]
223
+ - tag: "rect"
224
+ attributes: ["x", "y", "width", "height", "fill", "style"]
225
+ allowed_children: ["title", "desc"]
226
+ check_attributes: true
227
+ check_parent_child: true
156
228
  ----
229
+ ====
230
+
231
+ ==== Structural invalidity behavior
157
232
 
158
- With `skip_foreign_namespaces: true`, elements in foreign namespaces (not in `allowed_namespaces`) are skipped during validation. This allows NamespaceRequirement to handle foreign namespace validation, preventing duplicate errors.
233
+ When an element is marked as structurally invalid (not allowed, or invalid
234
+ parent-child relationship):
235
+
236
+ . The element is marked as structurally invalid
237
+ . All descendants are recursively marked invalid
238
+ . All requirements skip invalid nodes and their descendants
239
+ . Matches svgcheck behavior: removes element WITH all children
240
+
241
+ This prevents cascade errors where children of invalid elements are separately
242
+ reported.
243
+
244
+ ==== Features
159
245
 
160
- Features:
161
246
  * Configurable whitelist of allowed elements and attributes
162
247
  * Parent-child relationship validation
163
248
  * Required attribute enforcement
164
- * **Generic namespace skipping**: Skip foreign namespace elements without hardcoding
165
- * **RDF metadata support**: Configurable via `allow_rdf_metadata` flag
166
- * **Structural invalidity tracking**: Invalid elements marked to skip descendant validation
167
- * **Zero hardcoding**: All element and namespace handling configuration-driven
249
+ * Generic namespace skipping: Skip foreign namespace elements without
250
+ hardcoding
251
+ * RDF metadata support: Configurable via `allow_rdf_metadata` flag
252
+ * Structural invalidity tracking: Invalid elements marked to skip descendant
253
+ validation
254
+ * Zero hardcoding: All element and namespace handling configuration-driven
168
255
 
169
- **Structural Invalidity Behavior**:
256
+ ==== Related remediation
170
257
 
171
- When an element is marked as structurally invalid (not allowed, or invalid parent-child relationship):
172
- 1. The element is marked as structurally invalid
173
- 2. All descendants are recursively marked invalid
174
- 3. All requirements skip invalid nodes and their descendants
175
- 4. Matches svgcheck behavior: removes element WITH all children
258
+ * Content removal remediations (elements removed by validation logic)
176
259
 
177
- This prevents cascade errors where children of invalid elements are separately reported.
178
-
179
- **Target Remediations**: Content removal remediations (elements removed by validation logic)
180
260
 
181
261
  [[viewbox-required-requirement]]
182
- ==== ViewboxRequiredRequirement
262
+ === ViewBox required requirement
263
+
264
+ ==== General
183
265
 
184
266
  Requires viewBox attribute on root SVG element.
185
267
 
186
- **Configuration Options**:
268
+ Implemented as `ViewboxRequiredRequirement`.
269
+
270
+ ==== Configuration options
187
271
 
188
- `auto_generate`:: Boolean flag to enable automatic viewBox generation from width/height. Default: `false`.
189
- `preserve_aspect_ratio`:: Boolean flag to maintain aspect ratio during generation. Default: `true`.
272
+ `auto_generate`:: Boolean flag to enable automatic viewBox generation from
273
+ width/height. Default: `false`.
190
274
 
191
- Configuration:
275
+ `preserve_aspect_ratio`:: Boolean flag to maintain aspect ratio during
276
+ generation. Default: `true`.
277
+
278
+ ==== Configuration
279
+
280
+ .Example configuration of ViewboxRequiredRequirement
281
+ [example]
282
+ ====
192
283
  [source,yaml]
193
284
  ----
194
285
  - id: "viewbox_required"
195
286
  type: "ViewboxRequiredRequirement"
196
287
  description: "Require viewBox on root element"
197
- config:
198
- auto_generate: true
199
- preserve_aspect_ratio: true
288
+ auto_generate: true
289
+ preserve_aspect_ratio: true
200
290
  ----
291
+ ====
292
+
293
+ ==== Example from svg_1_2_rfc profile
294
+
295
+ [example]
296
+ ====
297
+ [source,yaml]
298
+ ----
299
+ - id: "viewbox_required"
300
+ type: "ViewboxRequiredRequirement"
301
+ description: "Requires viewBox attribute on root SVG element per RFC 7996"
302
+ ----
303
+ ====
304
+
305
+ ==== Features
201
306
 
202
- Features:
203
307
  * Validates presence of viewBox attribute
204
308
  * Validates viewBox format (four space-separated numbers)
205
309
  * Critical for scalable SVG rendering
206
310
  * Optional auto-generation from width/height attributes
207
311
 
208
- **Target Remediations**: link:remediation.adoc#viewbox-remediation[ViewboxRemediation]
312
+ ==== Related remediation
313
+
314
+ * link:remediation.adoc#viewbox-remediation[ViewboxRemediation]
315
+
209
316
 
210
317
  [[namespace-attributes-requirement]]
211
- ==== NamespaceAttributesRequirement
318
+ === Namespace attributes requirement
319
+
320
+ ==== General
212
321
 
213
322
  Validates attributes don't use disallowed namespaces.
214
323
 
215
- **Configuration Options**:
324
+ Implemented as `NamespaceAttributesRequirement`.
325
+
326
+ ==== Configuration options
327
+
328
+ `allowed_namespaces`:: List of namespace URIs that are explicitly allowed
329
+ (whitelist mode).
330
+
331
+ `disallowed_namespaces`:: List of namespace URIs that are not permitted on
332
+ attributes.
216
333
 
217
- `disallowed_namespaces`:: List of namespace URIs that are not permitted on attributes.
218
- `allowed_namespaces`:: List of namespace URIs that are explicitly allowed (whitelist mode).
219
334
  `mode`:: Validation mode: `"blacklist"` (default) or `"whitelist"`.
220
335
 
221
- Configuration:
336
+ `exempt_elements`:: List of element names that are exempt from namespace
337
+ attribute validation (e.g., RDF metadata elements).
338
+
339
+ ==== Configuration
340
+
341
+ .Example configuration of NamespaceAttributesRequirement
342
+ [example]
343
+ ====
222
344
  [source,yaml]
223
345
  ----
224
346
  - id: "namespace_attrs"
225
347
  type: "NamespaceAttributesRequirement"
226
348
  description: "Control namespace attribute usage"
227
- config:
228
- mode: "blacklist"
229
- disallowed_namespaces:
230
- - "http://custom.namespace.com"
231
- - "http://www.inkscape.org/namespaces/inkscape"
232
- - "http://www.lucidchart.com/chart"
349
+ allowed_namespaces:
350
+ - "http://www.w3.org/2000/svg"
351
+ - "http://www.w3.org/1999/xlink"
352
+ - ""
233
353
  ----
354
+ ====
355
+
356
+ ==== Example from svg_1_2_rfc profile
357
+
358
+ [example]
359
+ ====
360
+ [source,yaml]
361
+ ----
362
+ - id: "namespace_attributes"
363
+ type: "NamespaceAttributesRequirement"
364
+ description: "Only allows attributes from SVG, XLink, and XML namespaces"
365
+ allowed_namespaces:
366
+ - "http://www.w3.org/2000/svg"
367
+ - "http://www.w3.org/1999/xlink"
368
+ - "http://www.w3.org/XML/1998/namespace"
369
+ - ""
370
+ exempt_elements:
371
+ - "RDF"
372
+ - "Work"
373
+ - "format"
374
+ ----
375
+ ====
376
+
377
+ ==== Features
234
378
 
235
- Features:
236
379
  * Removes attributes from disallowed namespaces
237
380
  * Supports both whitelist and blacklist modes
238
381
  * Preserves valid namespace attributes (xlink, xml)
239
382
  * Configurable namespace filtering
383
+ * Exempt element list for special cases (e.g., RDF metadata)
240
384
 
241
- **Target Remediations**: link:remediation.adoc#namespace-attribute-remediation[NamespaceAttributeRemediation]
385
+ ==== Related remediation
242
386
 
243
- === Content requirements
387
+ * link:remediation.adoc#namespace-attribute-remediation[NamespaceAttributeRemediation]
244
388
 
245
- These validate the content and semantics of SVG documents:
246
389
 
247
390
  [[color-restrictions-requirement]]
248
- ==== ColorRestrictionsRequirement
391
+ === Color restrictions requirement
392
+
393
+ ==== General
394
+
395
+ Enforces color usage restrictions with enhanced equivalence detection and
396
+ threshold-based validation.
249
397
 
250
- Enforces color usage restrictions with enhanced equivalence detection and threshold-based validation.
398
+ Implemented as `ColorRestrictionsRequirement`.
251
399
 
252
- **Configuration Options**:
400
+ ==== Configuration options
253
401
 
254
402
  `mode`:: Color restriction mode. Currently supports `"black_white_only"`.
403
+
255
404
  `allowed_colors`:: List of exact color strings that are permitted.
256
- `black_and_white_threshold`:: Optional RGB sum threshold for strict validation. When specified, only exact string matches from `allowed_colors` are permitted.
257
- `case_sensitive`:: Boolean flag for case-sensitive color matching. Default: `false`.
258
405
 
259
- Configuration:
406
+ `black_and_white_threshold`:: Optional RGB sum threshold for strict
407
+ validation. When specified, only exact string matches from `allowed_colors`
408
+ are permitted, and threshold logic is applied during remediation.
409
+
410
+ `case_sensitive`:: Boolean flag for case-sensitive color matching. Default:
411
+ `false`.
412
+
413
+ ==== Configuration
414
+
415
+ .Example configuration of ColorRestrictionsRequirement
416
+ [example]
417
+ ====
260
418
  [source,yaml]
261
419
  ----
262
420
  - id: "colors"
263
421
  type: "ColorRestrictionsRequirement"
264
422
  description: "Restrict colors to black and white"
265
- config:
266
- mode: "black_white_only"
267
- allowed_colors: ["black", "white", "#000000", "#ffffff", "none", "inherit", "currentColor"]
268
- black_and_white_threshold: 764 # Optional: RGB sum threshold for strict validation
269
- case_sensitive: false
423
+ mode: "black_white_only"
424
+ allowed_colors: ["black", "white", "#000000", "#ffffff", "none", "inherit"]
425
+ black_and_white_threshold: 764
426
+ case_sensitive: false
270
427
  ----
428
+ ====
271
429
 
272
- Where,
273
-
274
- `mode`:: The color restriction mode. Currently supports `black_white_only`.
275
- `allowed_colors`:: List of exact color strings that are permitted.
276
- `black_and_white_threshold`:: Optional RGB sum threshold for strict validation. When specified, only exact string matches from `allowed_colors` are permitted, and threshold logic is applied during remediation.
430
+ ==== Example from svg_1_2_rfc profile
277
431
 
278
- .Using strict black and white validation with RGB threshold
279
432
  [example]
280
433
  ====
281
434
  [source,yaml]
282
435
  ----
283
- - id: "strict_colors"
436
+ - id: "color_restrictions"
284
437
  type: "ColorRestrictionsRequirement"
285
- description: "Strict black and white validation for technical documents"
286
- config:
287
- mode: "black_white_only"
288
- black_and_white_threshold: 764
289
- allowed_colors: ["black", "white", "#000000", "#ffffff", "#FFFFFF", "none", "inherit", "currentColor"]
438
+ description: "Restricts colors to black and white only per RFC 7996"
439
+ mode: "black_white_only"
440
+ allowed_colors: ["black", "white", "#000000", "#ffffff", "#FFFFFF", "none",
441
+ "inherit", "currentColor"]
442
+ black_and_white_threshold: 764
290
443
  ----
444
+
445
+ The `black_and_white_threshold` of 764 matches svgcheck's color threshold
446
+ (RGB sum: 255+255+254 = 764). Colors with RGB sum ≤ 764 convert to black,
447
+ RGB sum > 764 converts to white.
291
448
  ====
292
449
 
293
- This configuration enables strict validation where only exact color strings are accepted during validation, while threshold-based conversion (RGB sum ≤ 764 → black, RGB sum > 764 → white) is applied during remediation.
450
+ ==== Color equivalence
451
+
452
+ The requirement uses enhanced color equivalence detection:
294
453
 
295
- Features:
296
- * **Enhanced color equivalence**: `#fff` ↔ `#ffffff` `white` (when threshold not specified)
297
- * **Strict format validation**: When `black_and_white_threshold` is specified, only exact strings from `allowed_colors` are permitted
298
- * **Percentage RGB support**: `rgb(100%,100%,100%)` and mixed formats handled
299
- * **Case-insensitive processing**: `BLACK` → `black` normalization
300
- * **RGB function support**: `rgb(255,255,255)` → `white` equivalence
301
- * **Short hex expansion**: `#000` → `#000000` normalization
454
+ * `#fff` ↔ `#ffffff` ↔ `white` (when threshold not specified)
455
+ * `rgb(100%,100%,100%)` and mixed formats handled
456
+ * `BLACK` `black` normalization (case-insensitive)
457
+ * `rgb(255,255,255)` `white` equivalence
458
+ * `#000` → `#000000` normalization (short hex expansion)
459
+
460
+ ==== Features
461
+
462
+ * Enhanced color equivalence across all formats
463
+ * Strict format validation when `black_and_white_threshold` is specified
464
+ * Percentage RGB support
465
+ * Case-insensitive processing
466
+ * RGB function support
467
+ * Short hex expansion
302
468
  * Validates fill, stroke, and style attributes
303
469
 
304
- **Target Remediations**: link:remediation.adoc#color-remediation[ColorRemediation]
470
+ ==== Related remediation
471
+
472
+ * link:remediation.adoc#color-remediation[ColorRemediation]
473
+
305
474
 
306
475
  [[font-family-requirement]]
307
- ==== FontFamilyRequirement
476
+ === Font family requirement
477
+
478
+ ==== General
308
479
 
309
480
  Controls font family usage and validates font specifications.
310
481
 
311
- **Configuration Options**:
482
+ Implemented as `FontFamilyRequirement`.
483
+
484
+ ==== Configuration options
312
485
 
313
486
  `allowed_families`:: List of permitted font family names (case-insensitive).
314
- `default_family`:: Default font family to suggest in error messages. Default: `"sans-serif"`.
315
- `strict_mode`:: Boolean flag to enable strict font validation. Default: `false`.
316
- `allow_generic`:: Boolean flag to allow CSS generic font families. Default: `true`.
317
487
 
318
- Configuration:
488
+ `default_family`:: Default font family to suggest in error messages. Default:
489
+ `"sans-serif"`.
490
+
491
+ `strict_mode`:: Boolean flag to enable strict font validation. Default:
492
+ `false`.
493
+
494
+ `allow_generic`:: Boolean flag to allow CSS generic font families. Default:
495
+ `true`.
496
+
497
+ ==== Configuration
498
+
499
+ .Example configuration of FontFamilyRequirement
500
+ [example]
501
+ ====
319
502
  [source,yaml]
320
503
  ----
321
504
  - id: "fonts"
322
505
  type: "FontFamilyRequirement"
323
506
  description: "Restrict to generic font families"
324
- config:
325
- allowed_families: ["serif", "sans-serif", "monospace"]
326
- default_family: "sans-serif"
327
- strict_mode: true
328
- allow_generic: true
507
+ allowed_families: ["serif", "sans-serif", "monospace"]
508
+ default_family: "sans-serif"
509
+ strict_mode: true
510
+ allow_generic: true
511
+ ----
512
+ ====
513
+
514
+ ==== Example from svg_1_2_rfc profile
515
+
516
+ [example]
517
+ ====
518
+ [source,yaml]
329
519
  ----
520
+ - id: "font_family"
521
+ type: "FontFamilyRequirement"
522
+ description: "Restricts font families to generic families per RFC 7996"
523
+ allowed_families: ["serif", "sans-serif", "monospace", "inherit"]
524
+ ----
525
+
526
+ RFC 7996 Section 17 specifies that only generic font families (serif,
527
+ sans-serif, monospace) are allowed in SVG 1.2 RFC documents.
528
+ ====
529
+
530
+ ==== Features
330
531
 
331
- Features:
332
532
  * Restricts to specific font families
333
533
  * Validates both font-family attributes and style properties
334
534
  * Handles comma-separated font family lists
335
535
  * Support for CSS generic font families
336
536
  * Case-insensitive font name matching
337
537
 
338
- **Target Remediations**: link:remediation.adoc#font-remediation[FontRemediation]
538
+ ==== Related remediation
539
+
540
+ * link:remediation.adoc#font-remediation[FontRemediation]
541
+
339
542
 
340
543
  [[forbidden-content-requirement]]
341
- ==== ForbiddenContentRequirement
544
+ === Forbidden content requirement
545
+
546
+ ==== General
342
547
 
343
548
  Prevents inclusion of forbidden elements and attributes.
344
549
 
345
- **Configuration Options**:
550
+ Implemented as `ForbiddenContentRequirement`.
551
+
552
+ ==== Configuration options
346
553
 
347
554
  `forbidden_elements`:: List of element names that are not permitted.
555
+
348
556
  `forbidden_attributes`:: List of attribute names that are not permitted.
557
+
349
558
  `case_sensitive`:: Boolean flag for case-sensitive matching. Default: `false`.
350
- `remove_content`:: Boolean flag to remove forbidden content during validation. Default: `false`.
351
559
 
352
- Configuration:
560
+ `remove_content`:: Boolean flag to remove forbidden content during validation.
561
+ Default: `false`.
562
+
563
+ ==== Configuration
564
+
565
+ .Example configuration of ForbiddenContentRequirement
566
+ [example]
567
+ ====
353
568
  [source,yaml]
354
569
  ----
355
570
  - id: "no_scripts"
356
571
  type: "ForbiddenContentRequirement"
357
572
  description: "Prevent scripting and multimedia"
358
- config:
359
- forbidden_elements: ["script", "audio", "video", "object", "embed"]
360
- forbidden_attributes: ["onclick", "onload", "onmouseover", "onchange"]
361
- case_sensitive: false
362
- remove_content: true
573
+ forbidden_elements: ["script", "audio", "video", "object", "embed"]
574
+ forbidden_attributes: ["onclick", "onload", "onmouseover"]
575
+ case_sensitive: false
576
+ remove_content: true
577
+ ----
578
+ ====
579
+
580
+ ==== Example from svg_1_2_rfc profile
581
+
582
+ [example]
583
+ ====
584
+ [source,yaml]
585
+ ----
586
+ - id: "forbidden_content"
587
+ type: "ForbiddenContentRequirement"
588
+ description: "Prohibits multimedia, animation, scripting per RFC 7996"
589
+ forbidden_elements: ["script", "audio", "video", "animation",
590
+ "animateColor", "animateMotion", "animateTransform", "set"]
591
+ forbidden_attributes: ["onload", "onclick", "onmouseover", "onmouseout",
592
+ "onfocus", "onblur", "onkeydown", "onkeyup", "onkeypress"]
363
593
  ----
364
594
 
365
- Features:
595
+ RFC 7996 Section 2 prohibits multimedia, animation, and scripting elements
596
+ to ensure documents are suitable for static publication formats.
597
+ ====
598
+
599
+ ==== Features
600
+
366
601
  * Configurable lists of forbidden elements and attributes
367
602
  * Useful for security-focused profiles
368
603
  * Supports multimedia and scripting restrictions
369
604
  * Optional content removal during validation
370
605
 
371
- **Target Remediations**: Content removal occurs during validation when `remove_content` is enabled
606
+ ==== Related remediation
607
+
608
+ * Content removal occurs during validation when `remove_content` is enabled
609
+
372
610
 
373
611
  [[no-external-css-requirement]]
374
- ==== NoExternalCssRequirement
612
+ === No external CSS requirement
613
+
614
+ ==== General
375
615
 
376
616
  Prevents external CSS references to ensure self-contained documents.
377
617
 
378
- **Configuration Options**:
618
+ Implemented as `NoExternalCssRequirement`.
619
+
620
+ ==== Configuration options
621
+
622
+ `allowed_protocols`:: List of permitted URL protocols. Empty list blocks all
623
+ external references.
379
624
 
380
- `allowed_protocols`:: List of permitted URL protocols. Empty list blocks all external references.
381
625
  `allow_data_urls`:: Boolean flag to allow data: URLs. Default: `true`.
626
+
382
627
  `strict_mode`:: Boolean flag for strict URL validation. Default: `false`.
383
628
 
384
- Configuration:
629
+ `check_style_elements`:: Boolean flag to check `<style>` elements for
630
+ `@import`. Default: `true`.
631
+
632
+ `check_style_attributes`:: Boolean flag to check style attributes for external
633
+ URLs. Default: `true`.
634
+
635
+ `check_link_elements`:: Boolean flag to check `<link>` elements. Default:
636
+ `true`.
637
+
638
+ ==== Configuration
639
+
640
+ .Example configuration of NoExternalCssRequirement
641
+ [example]
642
+ ====
385
643
  [source,yaml]
386
644
  ----
387
645
  - id: "no_external_css"
388
646
  type: "NoExternalCssRequirement"
389
647
  description: "Block external CSS references"
390
- config:
391
- allowed_protocols: [] # No external protocols allowed
392
- allow_data_urls: true
393
- strict_mode: true
648
+ allowed_protocols: []
649
+ allow_data_urls: true
650
+ strict_mode: true
651
+ ----
652
+ ====
653
+
654
+ ==== Example from metanorma profile
655
+
656
+ [example]
657
+ ====
658
+ [source,yaml]
394
659
  ----
660
+ - id: "no_external_css"
661
+ type: "NoExternalCssRequirement"
662
+ description: "Prohibits external CSS references"
663
+ check_style_elements: true
664
+ check_style_attributes: true
665
+ check_link_elements: true
666
+ ----
667
+
668
+ The metanorma profile requires all CSS to be embedded within the SVG document
669
+ for portability and PDF/A compliance.
670
+ ====
671
+
672
+ ==== Features
395
673
 
396
- Features:
397
674
  * Blocks `@import` statements in `<style>` elements
398
675
  * Prevents external stylesheet `<link>` elements
399
676
  * Validates URL references in style attributes
400
677
  * Configurable protocol restrictions
401
678
 
402
- **Target Remediations**: link:remediation.adoc#no-external-css-remediation[NoExternalCssRemediation]
679
+ ==== Related remediation
403
680
 
404
- === Reference requirements
681
+ * link:remediation.adoc#no-external-css-remediation[NoExternalCssRemediation]
682
+
683
+
684
+ [[no-external-fonts-requirement]]
685
+ === No external fonts requirement
686
+
687
+ ==== General
688
+
689
+ Validates that no external font references are present to ensure
690
+ self-contained documents.
691
+
692
+ Implemented as `NoExternalFontsRequirement`.
693
+
694
+ ==== Configuration options
695
+
696
+ `check_font_face`:: Boolean flag to enable validation of `<font-face>`
697
+ elements. Default: `true`.
698
+
699
+ `check_style_fonts`:: Boolean flag to enable validation of `@font-face` in
700
+ style elements and style attributes. Default: `true`.
701
+
702
+ ==== Configuration
703
+
704
+ .Example configuration of NoExternalFontsRequirement
705
+ [example]
706
+ ====
707
+ [source,yaml]
708
+ ----
709
+ - id: "no_external_fonts"
710
+ type: "NoExternalFontsRequirement"
711
+ description: "Prohibit external font references"
712
+ check_font_face: true
713
+ check_style_fonts: true
714
+ ----
715
+ ====
716
+
717
+ ==== Example from metanorma profile
718
+
719
+ [example]
720
+ ====
721
+ [source,yaml]
722
+ ----
723
+ - id: "no_external_fonts"
724
+ type: "NoExternalFontsRequirement"
725
+ description: "Prohibits external font references"
726
+ check_font_face: true
727
+ check_style_fonts: true
728
+ ----
729
+
730
+ The metanorma profile requires all fonts to be embedded to ensure documents
731
+ are self-contained and portable.
732
+ ====
733
+
734
+ ==== Features
735
+
736
+ * Validates `@font-face` rules in `<style>` elements for external `src` URLs
737
+ * Checks `<font-face-uri>` elements for external `href`/`xlink:href`
738
+ attributes
739
+ * Validates style attributes for external font URLs
740
+ * Allows data: URIs and fragment identifiers as embedded/internal references
741
+ * Critical for creating portable, self-contained SVG documents
742
+
743
+ ==== Related remediation
744
+
745
+ * link:remediation.adoc#font-embedding-remediation[FontEmbeddingRemediation]
746
+
747
+
748
+ [[no-external-images-requirement]]
749
+ === No external images requirement
750
+
751
+ ==== General
752
+
753
+ Validates that no external image references are present to ensure
754
+ self-contained documents.
755
+
756
+ Implemented as `NoExternalImagesRequirement`.
757
+
758
+ ==== Configuration options
759
+
760
+ `check_image_elements`:: Boolean flag to enable validation of `<image>`
761
+ elements. Default: `true`.
762
+
763
+ `check_style_images`:: Boolean flag to enable validation of image URLs in
764
+ style attributes. Default: `true`.
765
+
766
+ ==== Configuration
767
+
768
+ .Example configuration of NoExternalImagesRequirement
769
+ [example]
770
+ ====
771
+ [source,yaml]
772
+ ----
773
+ - id: "no_external_images"
774
+ type: "NoExternalImagesRequirement"
775
+ description: "Prohibit external image references"
776
+ check_image_elements: true
777
+ check_style_images: true
778
+ ----
779
+ ====
780
+
781
+ ==== Example from metanorma profile
782
+
783
+ [example]
784
+ ====
785
+ [source,yaml]
786
+ ----
787
+ - id: "no_external_images"
788
+ type: "NoExternalImagesRequirement"
789
+ description: "Prohibits external image references"
790
+ check_image_elements: true
791
+ check_style_images: true
792
+ ----
793
+
794
+ The metanorma profile requires all images to be embedded for PDF/A compliance
795
+ and offline document portability.
796
+ ====
797
+
798
+ ==== Features
799
+
800
+ * Validates `<image>` elements for external `href` and `xlink:href`
801
+ attributes
802
+ * Checks style attributes for external image URLs in `background`,
803
+ `background-image`, etc.
804
+ * Allows data: URIs and fragment identifiers as embedded/internal references
805
+ * Essential for PDF/A compliance and offline document portability
806
+ * Prevents broken image links in archived documents
807
+
808
+ ==== Related remediation
809
+
810
+ * link:remediation.adoc#image-embedding-remediation[ImageEmbeddingRemediation]
405
811
 
406
- These validate links and references within SVG documents:
407
812
 
408
813
  [[id-reference-requirement]]
409
- ==== IdReferenceRequirement
814
+ === ID reference requirement
815
+
816
+ ==== General
410
817
 
411
818
  Validates that ID references point to existing elements.
412
819
 
413
- **Configuration Options**:
820
+ Implemented as `IdReferenceRequirement`.
821
+
822
+ ==== Configuration options
823
+
824
+ `strict_validation`:: Boolean flag for strict ID reference checking. Default:
825
+ `true`.
826
+
827
+ `allow_external_refs`:: Boolean flag to allow references to external
828
+ documents. Default: `false`.
414
829
 
415
- `strict_validation`:: Boolean flag for strict ID reference checking. Default: `true`.
416
- `allow_external_refs`:: Boolean flag to allow references to external documents. Default: `false`.
417
- `case_sensitive`:: Boolean flag for case-sensitive ID matching. Default: `true`.
830
+ `case_sensitive`:: Boolean flag for case-sensitive ID matching. Default:
831
+ `true`.
418
832
 
419
- Configuration:
833
+ ==== Configuration
834
+
835
+ .Example configuration of IdReferenceRequirement
836
+ [example]
837
+ ====
420
838
  [source,yaml]
421
839
  ----
422
840
  - id: "valid_ids"
423
841
  type: "IdReferenceRequirement"
424
842
  description: "Ensure ID references are valid"
425
- config:
426
- strict_validation: true
427
- allow_external_refs: false
428
- case_sensitive: true
843
+ strict_validation: true
844
+ allow_external_refs: false
845
+ case_sensitive: true
846
+ ----
847
+ ====
848
+
849
+ ==== Example from svg_1_2_rfc profile
850
+
851
+ [example]
852
+ ====
853
+ [source,yaml]
854
+ ----
855
+ - id: "id_references"
856
+ type: "IdReferenceRequirement"
857
+ description: "Validates ID references point to existing elements per RFC 7996"
429
858
  ----
430
859
 
431
- Features:
860
+ Ensures all `<use>` elements and URL fragment references point to valid
861
+ elements within the document.
862
+ ====
863
+
864
+ ==== Features
865
+
432
866
  * Validates `<use>` element href references
433
867
  * Checks URL fragments in various attributes
434
868
  * Prevents broken internal links
435
869
  * Configurable strictness levels
436
870
 
437
- **Target Remediations**: link:remediation.adoc#invalid-id-references-remediation[InvalidIdReferencesRemediation]
871
+ ==== Related remediation
872
+
873
+ * link:remediation.adoc#invalid-id-references-remediation[InvalidIdReferencesRemediation]
874
+
438
875
 
439
876
  [[link-validation-requirement]]
440
- ==== LinkValidationRequirement
877
+ === Link validation requirement
878
+
879
+ ==== General
441
880
 
442
881
  Validates that links use only ASCII characters (IETF requirement).
443
882
 
444
- **Configuration Options**:
883
+ Implemented as `LinkValidationRequirement`.
445
884
 
446
- `ascii_only`:: Boolean flag to restrict links to ASCII characters. Default: `true`.
447
- `allow_unicode`:: Boolean flag to allow Unicode characters in links. Default: `false`.
448
- `encoding_check`:: Boolean flag to validate proper URL encoding. Default: `true`.
885
+ ==== Configuration options
449
886
 
450
- Configuration:
887
+ `ascii_only`:: Boolean flag to restrict links to ASCII characters. Default:
888
+ `true`.
889
+
890
+ `allow_unicode`:: Boolean flag to allow Unicode characters in links. Default:
891
+ `false`.
892
+
893
+ `encoding_check`:: Boolean flag to validate proper URL encoding. Default:
894
+ `true`.
895
+
896
+ `error_context`:: Custom error context message for validation failures.
897
+
898
+ ==== Configuration
899
+
900
+ .Example configuration of LinkValidationRequirement
901
+ [example]
902
+ ====
451
903
  [source,yaml]
452
904
  ----
453
905
  - id: "ascii_links"
454
906
  type: "LinkValidationRequirement"
455
907
  description: "Links must be ASCII-only"
456
- config:
457
- ascii_only: true
458
- allow_unicode: false
459
- encoding_check: true
908
+ ascii_only: true
909
+ allow_unicode: false
910
+ encoding_check: true
911
+ ----
912
+ ====
913
+
914
+ ==== Example from svg_1_2_rfc profile
915
+
916
+ [example]
917
+ ====
918
+ [source,yaml]
919
+ ----
920
+ - id: "link_validation"
921
+ type: "LinkValidationRequirement"
922
+ description: "Validates links are ASCII-only per RFC 7996 Section 14"
923
+ error_context: "RFC 7996 Section 14 requires ASCII-only IRIs"
460
924
  ----
461
925
 
462
- Features:
926
+ RFC 7996 Section 14 requires that all IRIs (Internationalized Resource
927
+ Identifiers) contain only ASCII characters for maximum compatibility.
928
+ ====
929
+
930
+ ==== Features
931
+
463
932
  * Validates href attributes contain only ASCII
464
933
  * Required for RFC 7996 compliance
465
934
  * Prevents internationalization issues
466
935
  * Configurable character set restrictions
936
+ * Custom error context messages
467
937
 
468
- **Target Remediations**: Manual link correction required (no automatic remediation available)
938
+ ==== Related remediation
469
939
 
470
- === Style requirements
940
+ * Manual link correction required (no automatic remediation available)
471
941
 
472
- These validate CSS styling within SVG documents:
473
942
 
474
943
  [[style-requirement]]
475
- ==== StyleRequirement
944
+ === Style requirement
945
+
946
+ ==== General
476
947
 
477
948
  Comprehensive CSS style validation including syntax, properties, and values.
478
949
 
479
- **Configuration Options**:
950
+ Implemented as `StyleRequirement`.
951
+
952
+ ==== Configuration options
480
953
 
481
954
  `allowed_properties`:: List of permitted CSS property names.
955
+
482
956
  `property_values`:: Hash mapping CSS properties to allowed values.
483
- `strict_syntax`:: Boolean flag for strict CSS syntax validation. Default: `false`.
957
+
958
+ `strict_syntax`:: Boolean flag for strict CSS syntax validation. Default:
959
+ `false`.
960
+
484
961
  `validate_values`:: Boolean flag to validate property values. Default: `true`.
485
962
 
486
- Configuration:
963
+ `basic_types`:: Hash defining basic type validators (e.g., `<color>`,
964
+ `<number>`).
965
+
966
+ `property_types`:: Hash mapping CSS properties to their value types.
967
+
968
+ ==== Configuration
969
+
970
+ .Example configuration of StyleRequirement
971
+ [example]
972
+ ====
487
973
  [source,yaml]
488
974
  ----
489
975
  - id: "valid_styles"
490
976
  type: "StyleRequirement"
491
977
  description: "Validate CSS style syntax and properties"
492
- config:
493
- strict_syntax: true
494
- validate_values: true
495
- allowed_properties: ["fill", "stroke", "font-family", "font-size"]
496
- property_values:
497
- "fill": ["black", "white", "none"]
498
- "stroke": ["black", "white", "none"]
499
- "font-family": ["serif", "sans-serif", "monospace"]
978
+ strict_syntax: true
979
+ validate_values: true
980
+ allowed_properties: ["fill", "stroke", "font-family", "font-size"]
981
+ property_values:
982
+ "fill": ["black", "white", "none"]
983
+ "stroke": ["black", "white", "none"]
500
984
  ----
985
+ ====
986
+
987
+ ==== Example from svg_1_2_rfc profile
988
+
989
+ [example]
990
+ ====
991
+ [source,yaml]
992
+ ----
993
+ - id: "style"
994
+ type: "StyleRequirement"
995
+ description: "Validates style attributes per RFC 7996"
996
+ allowed_properties: ["font-family", "font-weight", "fill", "stroke",
997
+ "stroke-width", "fill-opacity"]
998
+ property_values:
999
+ "font-family": ["serif", "sans-serif", "monospace", "inherit"]
1000
+ "fill": ["none", "inherit", "<color>"]
1001
+ basic_types:
1002
+ "<color>": ["black", "#ffffff", "#FFFFFF", "white", "#000000"]
1003
+ property_types:
1004
+ "fill": "<color>"
1005
+ "stroke": "<paint>"
1006
+ ----
1007
+
1008
+ Uses basic type definitions matching svgcheck's validation system for
1009
+ extensible property value validation.
1010
+ ====
1011
+
1012
+ ==== Features
501
1013
 
502
- Features:
503
1014
  * CSS syntax validation
504
1015
  * Property whitelist enforcement
505
1016
  * Property value validation with type checking
506
1017
  * Supports complex property configurations
507
1018
  * Flexible validation rules
1019
+ * Basic type system for reusable validations
508
1020
 
509
- **Target Remediations**: Manual style correction required (validation-focused requirement)
1021
+ ==== Related remediation
510
1022
 
511
- [[style-promotion-requirement]]
512
- ==== StylePromotionRequirement
1023
+ * Manual style correction required (validation-focused requirement)
513
1024
 
514
- Detects style properties that should be promoted to SVG attributes.
515
1025
 
516
- **Configuration Options**:
1026
+ [[style-promotion-requirement]]
1027
+ === Style promotion requirement
517
1028
 
518
- `promotable_properties`:: List of CSS properties that can become SVG attributes.
519
- `auto_promote`:: Boolean flag to automatically promote during validation. Default: `false`.
520
- `preserve_style`:: Boolean flag to preserve original style attribute. Default: `false`.
1029
+ ==== General
521
1030
 
522
- Configuration:
523
- [source,yaml]
524
- ----
525
- - id: "promote_styles"
526
- type: "StylePromotionRequirement"
527
- description: "Detect styles that should be attributes"
528
- config:
529
- auto_promote: false
530
- preserve_style: false
531
- promotable_properties: ["fill", "stroke", "font-family", "font-size", "opacity"]
532
- ----
1031
+ Detects style properties that should be promoted to SVG attributes.
533
1032
 
534
- Features:
535
- * Identifies style properties that can be SVG attributes
536
- * Helps with SVG optimization and compatibility
537
- * Configurable property promotion rules
538
- * Optional automatic promotion during validation
1033
+ Implemented as `StylePromotionRequirement`.
539
1034
 
540
- **Target Remediations**: link:remediation.adoc#style-promotion-remediation[StylePromotionRemediation]
1035
+ ==== Configuration options
541
1036
 
542
- == Configuration Best Practices
1037
+ `promotable_properties`:: List of CSS properties that can become SVG
1038
+ attributes.
543
1039
 
544
- === Parameter Types
1040
+ `auto_promote`:: Boolean flag to automatically promote during validation.
1041
+ Default: `false`.
545
1042
 
546
- Requirements support several parameter types:
1043
+ `preserve_style`:: Boolean flag to preserve original style attribute. Default:
1044
+ `false`.
547
1045
 
548
- **String parameters**:
549
- [source,yaml]
550
- ----
551
- config:
552
- required_namespace: "http://www.w3.org/2000/svg"
553
- default_family: "sans-serif"
554
- ----
1046
+ ==== Configuration
555
1047
 
556
- **Boolean parameters**:
1048
+ .Example configuration of StylePromotionRequirement
1049
+ [example]
1050
+ ====
557
1051
  [source,yaml]
558
1052
  ----
559
- config:
560
- strict_mode: true
561
- case_sensitive: false
562
- auto_generate: true
1053
+ - id: "promote_styles"
1054
+ type: "StylePromotionRequirement"
1055
+ description: "Detect styles that should be attributes"
1056
+ auto_promote: false
1057
+ preserve_style: false
1058
+ promotable_properties: ["fill", "stroke", "font-family", "font-size"]
563
1059
  ----
1060
+ ====
564
1061
 
565
- **Array parameters**:
566
- [source,yaml]
567
- ----
568
- config:
569
- allowed_colors: ["black", "white", "#000000"]
570
- forbidden_elements: ["script", "audio", "video"]
571
- ----
1062
+ ==== Example from svg_1_2_rfc profile
572
1063
 
573
- **Hash parameters**:
1064
+ [example]
1065
+ ====
574
1066
  [source,yaml]
575
1067
  ----
576
- config:
577
- property_values:
578
- "fill": ["black", "white", "none"]
579
- "font-family": ["serif", "sans-serif"]
1068
+ - id: "style_promotion"
1069
+ type: "StylePromotionRequirement"
1070
+ description: "Detects CSS style properties that should be promoted per RFC"
580
1071
  ----
581
1072
 
582
- **Nested object parameters**:
583
- [source,yaml]
584
- ----
585
- config:
586
- element_configs:
587
- - tag: "rect"
588
- attributes: ["x", "y", "width", "height"]
589
- required_attributes: ["width", "height"]
590
- ----
1073
+ Identifies opportunities to convert style properties to attributes for better
1074
+ SVG compatibility.
1075
+ ====
591
1076
 
592
- === Validation Modes
1077
+ ==== Features
593
1078
 
594
- Many requirements support different validation modes:
1079
+ * Identifies style properties that can be SVG attributes
1080
+ * Helps with SVG optimization and compatibility
1081
+ * Configurable property promotion rules
1082
+ * Optional automatic promotion during validation
595
1083
 
596
- **Strict vs Permissive**:
597
- - `strict_mode: true` - Fails validation for any non-compliant content
598
- - `strict_mode: false` - Issues warnings but allows content
1084
+ ==== Related remediation
599
1085
 
600
- **Whitelist vs Blacklist**:
601
- - `mode: "whitelist"` - Only explicitly allowed items pass validation
602
- - `mode: "blacklist"` - Only explicitly forbidden items fail validation
1086
+ * link:remediation.adoc#style-promotion-remediation[StylePromotionRemediation]
603
1087
 
604
- **Case Sensitivity**:
605
- - `case_sensitive: true` - Exact case matching required
606
- - `case_sensitive: false` - Case-insensitive matching
607
1088
 
608
- === Performance Considerations
1089
+ [[invalid-id-references-requirement]]
1090
+ === Invalid ID references requirement
609
1091
 
610
- **Efficient Configuration**:
611
- - Use specific allowed lists rather than broad restrictions
612
- - Avoid overly complex regular expressions in validation
613
- - Consider validation frequency vs. thoroughness tradeoffs
1092
+ ==== General
614
1093
 
615
- **Memory Usage**:
616
- - Large allowed/forbidden lists consume more memory
617
- - Complex nested configurations increase processing time
618
- - Balance configuration detail with performance needs
1094
+ Detects and validates broken ID references in SVG documents.
619
1095
 
620
- == Advanced Configuration
1096
+ Implemented as `InvalidIdReferencesRequirement`.
621
1097
 
622
- === Conditional Requirements
1098
+ ==== Configuration options
623
1099
 
624
- Requirements can be configured to apply conditionally:
1100
+ `check_use_elements`:: Boolean flag to check `<use>` elements for broken
1101
+ references. Default: `true`.
625
1102
 
626
- [source,yaml]
627
- ----
628
- - id: "conditional_colors"
629
- type: "ColorRestrictionsRequirement"
630
- description: "Apply color restrictions only to specific elements"
631
- config:
632
- mode: "black_white_only"
633
- allowed_colors: ["black", "white"]
634
- apply_to_elements: ["rect", "circle", "path"] # Only validate these elements
635
- ----
1103
+ `check_other_references`:: Boolean flag to check other ID references. Default:
1104
+ `true`.
636
1105
 
637
- === Custom Validation Rules
1106
+ `strict_mode`:: Boolean flag for strict validation. Default: `false`.
638
1107
 
639
- Requirements support custom validation logic through configuration:
1108
+ ==== Configuration
640
1109
 
1110
+ .Example configuration of InvalidIdReferencesRequirement
1111
+ [example]
1112
+ ====
641
1113
  [source,yaml]
642
1114
  ----
643
- - id: "custom_element_validation"
644
- type: "AllowedElementsRequirement"
645
- description: "Custom element validation with business logic"
646
- config:
647
- element_configs:
648
- - tag: "text"
649
- attributes: ["x", "y", "font-family"]
650
- custom_rules:
651
- - rule: "max_length"
652
- value: 100
653
- - rule: "required_parent"
654
- value: ["g", "svg"]
1115
+ - id: "invalid_id_refs"
1116
+ type: "InvalidIdReferencesRequirement"
1117
+ description: "Detect broken ID references"
1118
+ check_use_elements: true
1119
+ check_other_references: true
1120
+ strict_mode: false
655
1121
  ----
1122
+ ====
656
1123
 
657
- === Profile-Specific Configuration
658
-
659
- Requirements can have different configurations per profile:
1124
+ ==== Example from lucid_fix profile
660
1125
 
1126
+ [example]
1127
+ ====
661
1128
  [source,yaml]
662
1129
  ----
663
- # In profile A - strict colors
664
- - id: "colors"
665
- type: "ColorRestrictionsRequirement"
666
- config:
667
- mode: "black_white_only"
668
- black_and_white_threshold: 764
669
-
670
- # In profile B - relaxed colors
671
- - id: "colors"
672
- type: "ColorRestrictionsRequirement"
673
- config:
674
- mode: "black_white_only"
675
- allowed_colors: ["black", "white", "gray", "#808080"]
1130
+ - id: "invalid_id_references"
1131
+ type: "InvalidIdReferencesRequirement"
1132
+ description: "Validates that ID references point to existing elements"
1133
+ check_use_elements: true
1134
+ check_other_references: true
1135
+ strict_mode: true
676
1136
  ----
677
1137
 
678
- == Troubleshooting
679
-
680
- === Common Configuration Issues
681
-
682
- **Invalid parameter names**:
683
- - Check requirement class documentation for correct parameter names
684
- - Use `config` hash for all requirement-specific parameters
685
-
686
- **Type mismatches**:
687
- - Ensure arrays are provided as YAML lists `[item1, item2]`
688
- - Ensure booleans are `true`/`false`, not `"true"`/`"false"`
1138
+ Lucid-generated SVGs often contain broken `<use>` element references that need
1139
+ to be detected and removed for valid SVG output.
1140
+ ====
689
1141
 
690
- **Missing required parameters**:
691
- - Some requirements have mandatory configuration parameters
692
- - Check requirement documentation for required vs. optional parameters
1142
+ ==== Features
693
1143
 
694
- === Validation Debugging
1144
+ * Validates `<use>` element href and xlink:href references
1145
+ * Checks other ID references in various attributes
1146
+ * Detects references to non-existent IDs
1147
+ * Configurable validation strictness
1148
+ * Essential for cleaning up tool-generated SVGs
695
1149
 
696
- **Enable verbose logging**:
697
- [source,yaml]
698
- ----
699
- - id: "debug_requirement"
700
- type: "ColorRestrictionsRequirement"
701
- config:
702
- verbose_logging: true # Enable detailed validation messages
703
- debug_mode: true # Include debug information in results
704
- ----
1150
+ ==== Related remediation
705
1151
 
706
- **Test with minimal configuration**:
707
- - Start with simple configurations and add complexity gradually
708
- - Use built-in profiles as configuration examples
709
- - Validate configuration syntax before deployment
1152
+ * link:remediation.adoc#invalid-id-references-remediation[InvalidIdReferencesRemediation]