svg_conform 0.1.4 → 0.1.6

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +18 -40
  3. data/README.adoc +111 -1171
  4. data/config/profiles/metanorma.yml +5 -0
  5. data/docs/api_reference.adoc +1355 -0
  6. data/docs/cli_guide.adoc +846 -0
  7. data/docs/reference_manifest.adoc +371 -0
  8. data/docs/requirements.adoc +68 -1
  9. data/examples/document_input_demo.rb +102 -0
  10. data/lib/svg_conform/document.rb +40 -1
  11. data/lib/svg_conform/profile.rb +15 -9
  12. data/lib/svg_conform/references/base_reference.rb +130 -0
  13. data/lib/svg_conform/references/id_definition.rb +38 -0
  14. data/lib/svg_conform/references/reference_classifier.rb +45 -0
  15. data/lib/svg_conform/references/reference_manifest.rb +129 -0
  16. data/lib/svg_conform/references.rb +11 -0
  17. data/lib/svg_conform/remediations/namespace_attribute_remediation.rb +34 -43
  18. data/lib/svg_conform/requirements/id_collection_requirement.rb +38 -0
  19. data/lib/svg_conform/requirements/id_reference_requirement.rb +11 -0
  20. data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +3 -0
  21. data/lib/svg_conform/requirements/link_validation_requirement.rb +114 -31
  22. data/lib/svg_conform/requirements/no_external_css_requirement.rb +5 -2
  23. data/lib/svg_conform/requirements.rb +11 -9
  24. data/lib/svg_conform/sax_validation_handler.rb +16 -1
  25. data/lib/svg_conform/validation_context.rb +67 -1
  26. data/lib/svg_conform/validation_result.rb +43 -2
  27. data/lib/svg_conform/validator.rb +56 -16
  28. data/lib/svg_conform/version.rb +1 -1
  29. data/lib/svg_conform.rb +11 -2
  30. data/spec/svg_conform/commands/svgcheck_compare_command_spec.rb +1 -0
  31. data/spec/svg_conform/commands/svgcheck_compatibility_command_spec.rb +1 -0
  32. data/spec/svg_conform/commands/svgcheck_generate_command_spec.rb +1 -0
  33. data/spec/svg_conform/references/integration_spec.rb +206 -0
  34. data/spec/svg_conform/references/reference_classifier_spec.rb +142 -0
  35. data/spec/svg_conform/references/reference_manifest_spec.rb +307 -0
  36. data/spec/svg_conform/requirements/id_reference_state_spec.rb +93 -0
  37. data/spec/svg_conform/validator_input_types_spec.rb +172 -0
  38. data/svg_conform.gemspec +1 -1
  39. metadata +25 -4
data/README.adoc CHANGED
@@ -25,6 +25,7 @@ SvgConform is distributed as a Ruby gem.
25
25
 
26
26
  * **Profile-based validation**: Validate SVG files against predefined or custom profiles
27
27
  * **Remediation**: Automatically fix common SVG conformance issues
28
+ * **Reference manifest**: Complete tracking of IDs and references for consumer-level validation
28
29
  * **Extensible architecture**: Easy to add new rules and profiles
29
30
  * **Command-line interface**: Validate and fix files from the command line
30
31
  * **Ruby API**: Integrate validation into Ruby applications
@@ -123,6 +124,31 @@ Each remediation action can be linked to a particular requirement to indicate
123
124
  their relationship, defined in the profile.
124
125
 
125
126
 
127
+ === Two-mode architecture
128
+
129
+ SvgConform uses two distinct operating modes for optimal performance and functionality:
130
+
131
+ **SAX Validation Mode** (always used for validation):
132
+
133
+ * Memory-safe streaming XML parser
134
+ * Constant memory usage regardless of file size
135
+ * Handles files of any size (tested with 100MB+ files)
136
+ * Read-only - cannot modify documents
137
+
138
+ **DOM Remediation Mode** (only when applying fixes):
139
+
140
+ * Full document tree loaded in memory
141
+ * XPath queries and tree modification
142
+ * Memory scales with file size
143
+ * Only used when `fix: true` option is specified
144
+
145
+ This architecture ensures validation is always safe for large files, while modifications
146
+ are only performed when explicitly requested and necessary.
147
+
148
+ See link:docs/sax_validation_mode.adoc[SAX Validation Mode Guide] for details on
149
+ writing SAX-compatible requirements.
150
+
151
+
126
152
  === Reporting
127
153
 
128
154
  SvgConform provides detailed reporting on SVG conformance issues.
@@ -141,7 +167,6 @@ profile conformance tools.
141
167
  See <<external_compliance>> for details.
142
168
 
143
169
 
144
-
145
170
  == Usage
146
171
 
147
172
  === Installation
@@ -171,7 +196,9 @@ $ gem install svg_conform
171
196
  === Command line usage
172
197
 
173
198
  Details and examples of command line usage can be found in
174
- <<command_line_interface>>.
199
+ link:docs/cli_guide.adoc[CLI Guide].
200
+
201
+ ==== Quick start
175
202
 
176
203
  List available profiles:
177
204
 
@@ -201,11 +228,16 @@ Batch process a directory of SVG files:
201
228
  $ svg_conform check --directory=images/ --profile=metanorma -f --output-dir=fixed/
202
229
  ----
203
230
 
231
+ For comprehensive CLI documentation including all options, workflows, and troubleshooting,
232
+ see link:docs/cli_guide.adoc[CLI Guide].
233
+
204
234
 
205
235
  === Ruby API usage
206
236
 
207
237
  Details and examples of Ruby API usage can be found in
208
- <<ruby_api_reference>>.
238
+ link:docs/api_reference.adoc[API Reference].
239
+
240
+ ==== Quick start
209
241
 
210
242
  [source,ruby]
211
243
  ----
@@ -230,1227 +262,135 @@ if !result.valid? && profile.remediation_count > 0
230
262
  end
231
263
  ----
232
264
 
265
+ ==== Accepting multiple input types
233
266
 
267
+ The validator accepts multiple input types and always uses SAX validation for memory-safe processing:
234
268
 
235
- == Core components
236
-
237
- === Architecture
238
-
239
- The SvgConform architecture is built around a modular design that separates
240
- concerns and allows for easy extension.
241
-
242
-
243
- [source]
244
- ----
245
- ╭────────────────────────────────────────────────────────────────╮
246
- │ SvgConform │
247
- ├────────────────────────────────────────────────────────────────┤
248
- │ │
249
- │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │
250
- │ │ CLI │ │ Ruby API │ │ Profiles │ │
251
- │ │ │ │ │ │ Registry │ │
252
- │ ╰─────┬───────╯ ╰──────┬──────╯ ╰─────┬───────╯ │
253
- │ │ │ │ │
254
- │ └───────────────────┼─────────────────┘ │
255
- │ │ │
256
- │ ╭─────────────────────────▼─────────────────────────╮ │
257
- │ │ Validator │ │
258
- │ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
259
- │ │ │ Document │ │ Validation │ │ Remediation │ │ │
260
- │ │ │ Parser │ │ Engine │ │ Engine │ │ │
261
- │ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
262
- │ ╰─────────────────────────┬─────────────────────────╯ │
263
- │ │ │
264
- │ ╭─────────────────────────▼─────────────────────────╮ │
265
- │ │ Profile System │ │
266
- │ │ │ │
267
- │ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
268
- │ │ │ SVG 1.2 RFC │ │ Metanorma │ │ Future │ │ │
269
- │ │ │ Profile │ │ SVG Profile │ │ Profiles │ │ │
270
- │ │ │ │ │ │ │ │ │ │
271
- │ │ │ • svgcheck │ │ • ID links │ │ • Custom │ │ │
272
- │ │ │ compatible │ │ • No ext. │ │ rules │ │ │
273
- │ │ │ • Grayscale │ │ fonts │ │ • Org │ │ │
274
- │ │ │ • RFC 7996 │ │ • Font def. │ │ standards │ │ │
275
- │ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
276
- │ ╰─────────────────────────┬─────────────────────────╯ │
277
- │ │ │
278
- │ ╭─────────────────────────▼─────────────────────────╮ │
279
- │ │ Requirements & Remediations Engine │ │
280
- │ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
281
- │ │ │Requirements │ │Remediations │ │ Validation │ │ │
282
- │ │ │ System │ │ System │ │ Results │ │ │
283
- │ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
284
- │ ╰─────────────────────────┬─────────────────────────╯ │
285
- │ │ │
286
- │ ╭─────────────────────────▼─────────────────────────╮ │
287
- │ │ svgcheck Compatibility │ │
288
- │ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
289
- │ │ │ svgcheck │ │ YAML │ │ Report │ │ │
290
- │ │ │ Parser │ │ Mapping │ │ Comparator │ │ │
291
- │ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
292
- │ ╰─────────────────────────┬─────────────────────────╯ │
293
- │ │ │
294
- │ ╭─────────────────────────▼─────────────────────────╮ │
295
- │ │ Moxml │ │
296
- │ │ (XML Processing) │ │
297
- │ ╰───────────────────────────────────────────────────╯ │
298
- │ │
299
- ╰────────────────────────────────────────────────────────────────╯
300
- ----
301
-
302
-
303
- === Profiles
304
-
305
- SvgConform includes predefined profiles that can be used out-of-the-box.
306
- Each profile is designed for different use cases and compliance standards.
307
-
308
- .Predefined SVG profiles included in SvgConform
309
- [cols="2,3,3,2", options="header"]
310
- |===
311
- |Profile |Use Case |Key Features |Documentation
312
-
313
- |`base`
314
- |Foundation profile
315
- |Basic validation, namespace checks, starting point for custom profiles.
316
- |link:docs/profiles.adoc#base-profile[Details]
317
-
318
- |`metanorma`
319
- |Metanorma SVG profile
320
- |Standard SVG for Metanorma documents. Valid HREFs and ID linking. No external
321
- fonts, images and CSS. No non-SVG elements or attributes.
322
- |link:docs/profiles.adoc#no-external-css-profile[Details]
323
-
324
- |`svg_1_2_rfc`
325
- |IETF RFC SVG 1.2 profile
326
- |RFC 7996/6949 compliant. Black/white color only, limited elements, generic
327
- fonts. Fully compatible with `svgcheck` outcomes.
328
- |link:docs/profiles.adoc#svg-1-2-rfc-profile[Details]
329
-
330
- |`svg_1_2_rfc_with_rdf`
331
- |IETF RFC SVG 1.2 profile with RDF metadata
332
- |Same as `svg_1_2_rfc`, but allows RDF/Dublin Core metadata from design tools.
333
- Supported by `svgcheck`.
334
- |link:docs/profiles.adoc#svg-1-2-rfc-with-rdf-profile[Details]
335
-
336
- |`no_external_css`
337
- |Self-contained SVG
338
- |No external references, security-focused, offline usage.
339
- |link:docs/profiles.adoc#no-external-css-profile[Details]
340
-
341
- |`lucid_fix`
342
- |Lucid cleanup
343
- |Remove Lucid-specific metadata, clean standard SVG output
344
- |link:docs/profiles.adoc#lucid-fix-profile[Details]
345
- |===
346
-
347
- For complete profile documentation, including inheritance, customization, RDF
348
- metadata support, and selection guides, see
349
- link:docs/profiles.adoc[SVG Profiles Documentation].
350
-
351
- For detailed information about configuring RDF metadata support in profiles, see
352
- link:docs/rdf_metadata_support.adoc[RDF Metadata Support Documentation].
353
-
354
-
355
-
356
- === Requirements
357
-
358
- SvgConform includes different requirement checkers that validate various aspects
359
- of SVG documents.
360
-
361
- There are two main categories of requirements:
362
-
363
- * structural requirements: requirements set towards the XML structure and syntax of SVG documents
364
- * logical requirements: requirements set towards content and stylistic aspects of SVG documents
365
-
366
- .SvgConform supported requirement classes
367
- [cols="2,2,3", options="header"]
368
- |===
369
- |Type |Requirement |Description
370
-
371
- |Structural
372
- |link:docs/requirements.adoc#namespace-requirement[`NamespaceRequirement`]
373
- |Ensures proper SVG namespace declarations
374
-
375
- |Structural
376
- |link:docs/requirements.adoc#namespace-attributes-requirement[`NamespaceAttributesRequirement`]
377
- |Validates namespace attributes are from allowed namespaces
378
-
379
- |Structural
380
- |link:docs/requirements.adoc#allowed-elements-requirement[`AllowedElementsRequirement`]
381
- |Restricts which SVG elements are permitted
382
-
383
- |Structural
384
- |link:docs/requirements.adoc#viewbox-required-requirement[`ViewboxRequiredRequirement`]
385
- |Requires viewBox attributes on root elements
386
-
387
- |Logical
388
- |link:docs/requirements.adoc#color-restrictions-requirement[`ColorRestrictionsRequirement`]
389
- |Enforces color usage restrictions (e.g., grayscale only)
390
-
391
- |Logical
392
- |link:docs/requirements.adoc#font-family-requirement[`FontFamilyRequirement`]
393
- |Controls font family usage and validates font specifications
394
-
395
- |Logical
396
- |link:docs/requirements.adoc#no-external-css-requirement[`NoExternalCssRequirement`]
397
- |Prevents external CSS references to ensure self-contained documents
398
-
399
- |Logical
400
- |link:docs/requirements.adoc#no-external-fonts-requirement[`NoExternalFontsRequirement`]
401
- |Validates that no external font references are present
402
-
403
- |Logical
404
- |link:docs/requirements.adoc#no-external-images-requirement[`NoExternalImagesRequirement`]
405
- |Validates that no external image references are present
406
-
407
- |Logical
408
- |link:docs/requirements.adoc#forbidden-content-requirement[`ForbiddenContentRequirement`]
409
- |Prevents inclusion of forbidden elements and attributes
410
-
411
- |Logical
412
- |link:docs/requirements.adoc#id-reference-requirement[`IdReferenceRequirement`]
413
- |Validates that ID references point to existing elements
414
-
415
- |Logical
416
- |link:docs/requirements.adoc#invalid-id-references-requirement[`InvalidIdReferencesRequirement`]
417
- |Detects and validates broken ID references in SVG documents
418
-
419
- |Logical
420
- |link:docs/requirements.adoc#link-validation-requirement[`LinkValidationRequirement`]
421
- |Validates that links use only ASCII characters (IETF requirement)
422
-
423
- |Logical
424
- |link:docs/requirements.adoc#style-requirement[`StyleRequirement`]
425
- |Comprehensive CSS style validation including syntax and properties
426
-
427
- |Logical
428
- |link:docs/requirements.adoc#style-promotion-requirement[`StylePromotionRequirement`]
429
- |Detects style properties that should be promoted to SVG attributes
430
- |===
431
-
432
-
433
-
434
- === Remediations
435
-
436
- Remediations are automatic fixing actions that can resolve requirement failures.
437
- Each remediation targets one or more specific requirements.
438
-
439
- SvgConform includes different remediation actions that can automatically fix
440
- SVG documents to resolve requirement violations.
441
-
442
- .SvgConform supported remediation classes
443
- [cols="2,2,3,2", options="header"]
444
- |===
445
- |Type |Remediation |Description |Targets
446
-
447
- |Content Conversion
448
- |link:docs/remediation.adoc#color-remediation[`ColorRemediation`]
449
- |Converts invalid colors to allowed alternatives using threshold-based conversion
450
- |link:docs/requirements.adoc#color-restrictions-requirement[`ColorRestrictionsRequirement`]
451
-
452
- |Content Conversion
453
- |link:docs/remediation.adoc#font-remediation[`FontRemediation`]
454
- |Maps font families to generic alternatives (serif, sans-serif, monospace)
455
- |link:docs/requirements.adoc#font-family-requirement[`FontFamilyRequirement`]
456
-
457
- |Content Conversion
458
- |link:docs/remediation.adoc#font-embedding-remediation[`FontEmbeddingRemediation`]
459
- |Converts external font references to embedded data URIs
460
- |link:docs/requirements.adoc#no-external-fonts-requirement[`NoExternalFontsRequirement`]
461
-
462
- |Content Conversion
463
- |link:docs/remediation.adoc#image-embedding-remediation[`ImageEmbeddingRemediation`]
464
- |Converts external image references to embedded data URIs
465
- |link:docs/requirements.adoc#no-external-images-requirement[`NoExternalImagesRequirement`]
466
-
467
- |Element/Attribute Removal
468
- |link:docs/remediation.adoc#namespace-remediation[`NamespaceRemediation`]
469
- |Removes invalid namespace elements and cleans up namespace declarations
470
- |link:docs/requirements.adoc#namespace-requirement[`NamespaceRequirement`]
471
-
472
- |Element/Attribute Removal
473
- |link:docs/remediation.adoc#namespace-attribute-remediation[`NamespaceAttributeRemediation`]
474
- |Removes attributes from disallowed namespaces
475
- |link:docs/requirements.adoc#namespace-attributes-requirement[`NamespaceAttributesRequirement`]
476
-
477
- |Element/Attribute Removal
478
- |link:docs/remediation.adoc#no-external-css-remediation[`NoExternalCssRemediation`]
479
- |Removes external CSS references including @import and external stylesheets
480
- |link:docs/requirements.adoc#no-external-css-requirement[`NoExternalCssRequirement`]
481
-
482
- |Addition
483
- |link:docs/remediation.adoc#viewbox-remediation[`ViewboxRemediation`]
484
- |Adds missing viewBox attributes to root SVG elements
485
- |link:docs/requirements.adoc#viewbox-required-requirement[`ViewboxRequiredRequirement`]
486
-
487
- |Style Processing
488
- |link:docs/remediation.adoc#style-promotion-remediation[`StylePromotionRemediation`]
489
- |Promotes CSS style properties to equivalent SVG attributes
490
- |link:docs/requirements.adoc#style-promotion-requirement[`StylePromotionRequirement`]
491
-
492
- |Reference Fixing
493
- |link:docs/remediation.adoc#invalid-id-references-remediation[`InvalidIdReferencesRemediation`]
494
- |Fixes or removes broken ID references and invalid href attributes
495
- |link:docs/requirements.adoc#id-reference-requirement[`IdReferenceRequirement`], `InvalidIdReferencesRequirement`
496
- |===
497
-
498
-
499
- === Requirement and remediation mapping
500
-
501
- Remediations are mapped to requirements using the `targets` configuration in
502
- profile YAML files.
503
-
504
- [source,yaml]
505
- ----
506
- remediations:
507
- - id: "fix_invalid_colors"
508
- type: "ColorRemediationAction"
509
- description: "Convert invalid colors to black or white"
510
- targets: ["color_restrictions"] # Maps to ColorRestrictionsRequirement
511
- ----
512
-
513
- This mapping system allows:
514
-
515
- * **Targeted fixes**: Remediations only run when their target requirements fail
516
- * **Flexible configuration**: Multiple remediations can target the same requirement
517
- * **Conditional application**: Remediations can be enabled/disabled per profile
518
-
519
-
520
-
521
- === Validation and remediation flow
522
-
523
- The following steps illustrates the data flow through the core components of
524
- SvgConform.
525
-
526
- . An SVG file is read and parsed into a Document object.
527
- . The Document is validated against a Profile using the Validator.
528
- . The Validator applies Requirements and collects results in a ConformanceReport object.
529
- . If fixing is enabled, the Validator uses the RemediationEngine to apply Remediations.
530
- . The fixed Document is returned along with the validation results in the ConformanceReport.
531
-
532
- [source]
533
- ----
534
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
535
- │ SVG File │───▶│ Document │───▶│ Validator │
536
- │ │ │ Parser │ │ │
537
- └─────────────┘ └─────────────┘ └─────┬───────┘
538
-
539
- ┌─────────────┐ │
540
- │ Profile │◀─────────┘
541
- └─────┬───────┘
542
-
543
- ┌─────▼───────┐
544
- │ Rules │
545
- └─────┬───────┘
546
-
547
- ┌─────▼───────┐ ┌─────────────┐
548
- │Requirements │───▶│ Validation │
549
- │ │ │ Result │
550
- └─────────────┘ └─────┬───────┘
551
-
552
- ┌─────────────┐ │
553
- │Remediations │◀─────────┘
554
- └─────┬───────┘
555
-
556
- ┌───────▼────────┐
557
- │ Fixed Document │
558
- └────────────────┘
559
- ----
560
-
561
- === Classes
562
-
563
- ==== Document (`SvgConform::Document`)
564
-
565
- Represents an SVG document. The SVG document in XML is parsed using the `Moxml`
566
- library, and provides SVG-specific functionality through the Document class.
567
-
568
- ==== Validator (`SvgConform::Validator`)
569
-
570
- The validator is the main entry point for SVG validation. It orchestrates the
571
- validation process with loading profiles, applying rules, and collecting results.
572
-
573
- ==== Profile (`SvgConform::Profile`)
574
-
575
- A profile is a collection of requirements and remediations that define a specific
576
- SVG conformance standard. Profiles are defined in YAML configuration files and are
577
- loaded dynamically at runtime.
578
-
579
- Notice that there are requirement violations that cannot be automatically
580
- remediated. For example, if an SVG uses a forbidden element, the remediation may
581
- simply remove it, which could lead to loss of important content.
582
-
583
-
584
- ==== Requirements
585
-
586
- An SvgConform requirement is a specific validation check that determines if an SVG
587
- document meets certain criteria. Requirements are implemented as classes that inherit
588
- from `SvgConform::Requirements::BaseRequirement`.
589
-
590
- Each requirement class focuses on a single concern implemented using
591
- XML tree traversal and validation logic.
592
-
593
- Every requirement check can be configured with specific parameters to fine-tune
594
- its behavior.
595
-
596
- Profiles can include multiple requirements to cover various aspects of SVG
597
- conformance.
598
-
599
- ==== Remediations
600
-
601
- An SvgConform remediation is an automatic fixing action that can be applied to
602
- an SVG document to resolve one or more requirement failures. Remediations are
603
- implemented as classes that inherit from `SvgConform::Remediations::BaseRemediation`.
604
-
605
- Each remediation class focuses on a specific fixing action implemented using
606
- XML tree manipulation and editing.
607
-
608
- Every remediation can be configured with specific parameters to customize its
609
- behavior. A remediation can target one or more specific requirements through
610
- configuration options.
611
-
612
-
613
-
614
- [[command_line_interface]]
615
- == Command line interface
616
-
617
- === General
618
-
619
- The `svg_conform` command provides a comprehensive CLI for validation and fixing.
620
-
621
-
622
- === `svg_conform profiles`
623
-
624
- The `profiles` command lists all available SVG profiles included in SvgConform.
625
-
626
- Syntax:
627
-
628
- [source,bash]
629
- ----
630
- svg_conform profiles [OPTIONS]
631
-
632
- Options:
633
- -v, --verbose Show detailed profile information
634
- ----
635
-
636
- [example]
637
- ====
638
- [source,bash]
639
- ----
640
- # List all profiles
641
- $ svg_conform profiles
642
-
643
- Available SVG Profiles
644
- ========================================
645
-
646
- ╭──────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
647
- │ Profile │ Description │
648
- ├──────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
649
- │ base │ Base SVG validation profile with common requirements │
650
- │ lucid_fix │ Lucid SVG Fix Profile - Removes invalid use element references and namespace attributes from Lucid-generated SVGs │
651
- │ metanorma │ Metanorma SVG Profile - SVG requirements for Metanorma technical documents with embedded resources │
652
- │ no_external_css │ Security-focused profile that disallows external CSS references │
653
- │ svg_1_2_rfc │ SVG 1.2 RFC Profile (RFC 7996) - Black and white diagrams for technical documents │
654
- │ svg_1_2_rfc_with_rdf │ SVG 1.2 RFC Profile with RDF metadata support - Allows RDF/Dublin Core metadata in SVG files │
655
- ╰──────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
656
- ----
657
- ====
658
-
659
-
660
-
661
- === `svg_conform check`
662
-
663
- The `check` command validates SVG files against a specified profile and optionally
664
- applies automatic remediations. It supports single files, multiple files via shell
665
- glob expansion, and directory scanning.
666
-
667
- Syntax:
668
-
669
- [source,bash]
670
- ----
671
- svg_conform check [*FILES] [OPTIONS]
672
- svg_conform check --directory PATH [OPTIONS]
673
-
674
- Required Options:
675
- -p, --profile PROFILE Profile to validate against
676
-
677
- Input Options:
678
- -d, --directory PATH Directory to scan recursively for SVG files
679
-
680
- Remediation Options:
681
- -f, --fix Enable automatic remediation
682
- --output-dir DIR Output directory for remediated files (required for multi-file)
683
- --in-place Replace original files (requires --force)
684
- --force Confirm destructive operations
685
- --fix-output FILE Output file for single file mode (default: FILE.fixed.svg)
686
-
687
- Reporting Options:
688
- --format FORMAT Output format for single file: table, yaml, json (default: table)
689
- -o, --output FILE Output file for single file mode
690
- --report-format FORMAT Batch report format: json, yaml
691
- --report-output FILE Save detailed batch report to file
692
- --manifest FILE Manifest file path (default: manifest.json with --fix)
693
- -q, --quiet Suppress per-file output, show summary only
694
- -v, --verbose Show detailed progress
695
- ----
696
-
697
- The check command supports three operational modes:
698
-
699
- **Single File Mode:**
700
-
701
- Validates a single SVG file and outputs a detailed validation report.
702
-
703
- [source,bash]
704
- ----
705
- # Basic validation
706
- svg_conform check file.svg -p metanorma
707
-
708
- # With remediation
709
- svg_conform check file.svg -p metanorma -f --fix-output fixed.svg
710
-
711
- # Output YAML report
712
- svg_conform check file.svg -p metanorma --format yaml -o report.yaml
713
- ----
714
-
715
- **Multiple Files Mode (Shell Glob):**
716
-
717
- Validates multiple files specified via shell glob patterns. The shell expands
718
- patterns like `*.svg` before passing to the command.
719
-
720
- [source,bash]
721
- ----
722
- # Validate all SVG files in current directory
723
- svg_conform check *.svg -p metanorma
724
-
725
- # Validate with pattern matching
726
- svg_conform check images/*/*.svg -p metanorma
727
-
728
- # Fix multiple files
729
- svg_conform check *.svg -p metanorma -f --output-dir fixed/
730
-
731
- # With JSON batch report
732
- svg_conform check *.svg -p metanorma --report-format json --report-output report.json
733
- ----
734
-
735
- **Directory Mode:**
736
-
737
- Recursively scans a directory for all SVG files using the `--directory` or `-d` flag.
738
-
739
- [source,bash]
269
+ [source,ruby]
740
270
  ----
741
- # Scan directory and validate
742
- svg_conform check -d images/ -p metanorma
743
-
744
- # Scan and remediate to new directory
745
- svg_conform check -d images/ -p metanorma -f --output-dir fixed/
746
-
747
- # Replace files in place (requires confirmation)
748
- svg_conform check -d images/ -p metanorma -f --in-place --force
271
+ validator = SvgConform::Validator.new
749
272
 
750
- # Quiet mode with detailed JSON report
751
- svg_conform check -d images/ -p metanorma -f --output-dir fixed/ --quiet \
752
- --report-format json --report-output report.json
273
+ # String input: Direct SAX parsing
274
+ result = validator.validate(svg_string, profile: :metanorma)
753
275
 
754
- # With custom manifest file
755
- svg_conform check -d images/ -p metanorma -f --output-dir fixed/ --manifest mappings.json
756
- ----
276
+ # Moxml documents/elements: Serialize once, then SAX validate
277
+ moxml_doc = Moxml.new.parse(svg_string)
278
+ result = validator.validate(moxml_doc, profile: :metanorma)
757
279
 
758
- **Batch Report Format:**
280
+ moxml_element = moxml_doc.root
281
+ result = validator.validate(moxml_element, profile: :metanorma)
759
282
 
760
- When processing multiple files or directories, a batch summary is displayed:
283
+ # Nokogiri documents/elements: Serialize once, then SAX validate
284
+ nokogiri_doc = Nokogiri::XML(svg_string)
285
+ result = validator.validate(nokogiri_doc, profile: :metanorma)
761
286
 
762
- [source]
763
- ----
764
- BATCH VALIDATION SUMMARY
765
- Directory: /path/to/images
766
- Profile: metanorma
767
- Files processed: 56
768
- Valid before: 0
769
- Remediated: 56
770
- Valid after: 56
771
- Failed: 0
772
- Success rate: 100.0%
773
- Manifest written to manifest.json
287
+ nokogiri_element = nokogiri_doc.root # Common in metanorma integration
288
+ result = validator.validate(nokogiri_element, profile: :metanorma)
774
289
  ----
775
290
 
776
- If `--report-format` is specified, a detailed report is generated in JSON or
777
- YAML format using lutaml-model serialization:
291
+ **Why SAX validation for all inputs?**
778
292
 
779
- [source,json]
780
- ----
781
- {
782
- "directory": "/path/to/images",
783
- "profile": "metanorma",
784
- "timestamp": "2025-10-12T15:36:25+08:00",
785
- "total_files": 56,
786
- "valid_before": 0,
787
- "valid_after": 56,
788
- "remediated": 56,
789
- "failed": 0,
790
- "success_rate": 100.0,
791
- "files": [
792
- {
793
- "filename": "diagram.svg",
794
- "original_path": "/path/to/images/diagram.svg",
795
- "valid_before": false,
796
- "valid_after": true,
797
- "errors_before": 3,
798
- "errors_after": 0,
799
- "remediated_path": "/path/to/fixed/diagram.svg",
800
- "status": "remediated"
801
- }
802
- ],
803
- "manifest": {
804
- "/path/to/images/diagram.svg": "/path/to/fixed/diagram.svg"
805
- }
806
- }
807
- ----
293
+ SAX (Simple API for XML) parsing is memory-safe and can handle arbitrarily large SVG files without hanging. DOM-based validation loads the entire tree into memory, which can cause performance issues or crashes with large files.
808
294
 
809
- **Manifest File:**
295
+ **Benefits of accepting DOM objects**:
810
296
 
811
- When using `--fix`, a manifest file is automatically created (or can be
812
- explicitly specified with `--manifest`). The manifest maps original file paths
813
- to their remediated counterparts:
297
+ When integrating with tools like Metanorma where SVG elements are already parsed:
814
298
 
815
- [source,json]
816
- ----
817
- {
818
- "timestamp": "2025-10-12T15:00:00+08:00",
819
- "profile": "metanorma",
820
- "mappings": {
821
- "/original/path/file1.svg": "/fixed/path/file1.svg",
822
- "/original/path/file2.svg": "/fixed/path/file2.svg"
823
- }
824
- }
299
+ [source,ruby]
825
300
  ----
301
+ # ❌ Old way: User manually serializes
302
+ result = validator.validate(svg_element.to_xml, profile: :metanorma)
826
303
 
827
-
828
- === `svg_conform version`
829
-
830
- The `version` command displays the current version of SvgConform.
831
-
832
- Syntax:
833
-
834
- [source,bash]
835
- ----
836
- svg_conform version
304
+ # ✅ New way: Library handles serialization internally
305
+ result = validator.validate(svg_element, profile: :metanorma)
837
306
  ----
838
307
 
839
- [example]
840
- [source,bash]
841
- ----
842
- $ svg_conform version
843
- SvgConform 0.1.0
844
- ----
308
+ Benefits:
309
+ - **Cleaner API**: No need to call `.to_xml` explicitly
310
+ - **Type flexibility**: Works with Nokogiri, Moxml, or strings
311
+ - **Safe for large files**: Always uses memory-efficient SAX parsing
312
+ - **Backward compatible**: String input still works as before
845
313
 
314
+ For comprehensive API documentation including all classes, methods, advanced usage,
315
+ and integration patterns, see link:docs/api_reference.adoc[API Reference].
846
316
 
847
317
 
848
- [[ruby_api_reference]]
849
- == Ruby API
318
+ === Reference manifest
850
319
 
851
- === Basic usage
320
+ SvgConform provides comprehensive ID and reference tracking through its reference manifest system:
852
321
 
853
322
  [source,ruby]
854
323
  ----
855
- require 'svg_conform'
856
-
857
- # Validate a file
858
- result = SvgConform.validate_file('diagram.svg', profile: :svg_1_2_rfc)
324
+ result = validator.validate(svg_content, profile: :metanorma)
859
325
 
860
- # Check validation status
861
- puts "Valid: #{result.valid?}"
862
- puts "Errors: #{result.errors.count}"
863
- puts "Warnings: #{result.warnings.count}"
326
+ # Access the reference manifest
327
+ manifest = result.reference_manifest
864
328
 
865
- # Get detailed error information
866
- result.errors.each do |error|
867
- puts "#{error.rule.id}: #{error.message}"
868
- puts " Element: #{error.element}" if error.element
869
- puts " Location: #{error.location}" if error.location
329
+ # Get all defined IDs
330
+ manifest.available_ids.each do |id_def|
331
+ puts "ID: #{id_def.id_value} at line #{id_def.line_number}"
870
332
  end
871
- ----
872
-
873
- === Advanced usage
874
333
 
875
- [source,ruby]
876
- ----
877
- # Create validator instance
878
- validator = SvgConform::Validator.new
879
-
880
- # Validate with custom options
881
- result = validator.validate_file('diagram.svg',
882
- profile: :svg_1_2_rfc,
883
- fix: true,
884
- strict: false
885
- )
886
-
887
- # Access fixed document
888
- if result.fixed?
889
- fixed_svg = result.fixed_document.to_xml
890
- File.write('diagram_fixed.svg', fixed_svg)
334
+ # Check for unresolved internal references
335
+ if result.has_unresolved_references?
336
+ result.unresolved_internal_references.each do |ref|
337
+ puts "Unresolved reference: #{ref.value} at line #{ref.line_number}"
338
+ end
891
339
  end
892
340
 
893
- # Get profile information
894
- profile_info = validator.profile_info(:svg_1_2_rfc)
895
- puts "Profile: #{profile_info[:name]}"
896
- puts "Description: #{profile_info[:description]}"
897
- puts "Rules: #{profile_info[:rules].map { |r| r[:id] }.join(', ')}"
898
- ----
899
-
900
- === Working with loaded SVG content
901
-
902
- [source,ruby]
903
- ----
904
- # Parse SVG content
905
- document = SvgConform::Document.from_content(svg_string)
906
-
907
- # Access document elements
908
- root = document.root
909
- puts "Root element: #{root.name}"
910
- puts "Namespace: #{root.namespace}"
911
-
912
- # Find elements
913
- circles = document.find_elements('circle')
914
- texts = document.find_elements('text')
915
-
916
- # Modify document
917
- fixer = SvgConform::Fixer.new(document)
918
- fixer.remove_element(some_element)
919
- fixer.set_attribute(element, 'fill', 'black')
920
-
921
- # Get modified XML
922
- modified_svg = fixer.to_xml
923
- ----
924
-
925
-
926
- == Configuration
927
-
928
- === Profile configuration
929
-
930
- Profiles can be configured using YAML files in the `config/profiles/` directory:
931
-
932
- [source,yaml]
933
- ----
934
- # config/profiles/custom.yml
935
- name: "Custom Profile"
936
- description: "Custom SVG profile for specific requirements"
937
- extends: "base" # Optional: inherit from another profile
938
-
939
- rules:
940
- - id: "namespace"
941
- type: "namespace_rule"
942
- config:
943
- required_namespace: "http://www.w3.org/2000/svg"
944
-
945
- - id: "allowed_elements"
946
- type: "allowed_elements_rule"
947
- config:
948
- allowed_elements:
949
- - "svg"
950
- - "g"
951
- - "rect"
952
- - "circle"
953
- - "path"
954
- - "text"
955
-
956
- - id: "color_restrictions"
957
- type: "color_restrictions_rule"
958
- config:
959
- grayscale_only: true
960
- allowed_colors:
961
- - "black"
962
- - "white"
963
- - "gray"
964
- ----
965
-
966
- === Requirement configuration
967
-
968
- TODO.
969
-
970
- === Remediation configuration
971
-
972
- TODO.
973
-
974
-
975
- == Extending SvgConform
976
-
977
- === Custom profiles
978
-
979
- Create a new profile by defining a YAML configuration:
980
-
981
- [source,yaml]
982
- ----
983
- # config/profiles/my_organization.yml
984
- profile:
985
- name: "My Organization SVG Profile"
986
- description: "SVG profile for internal use"
987
- import: "base" # Optional: inherit from another profile
988
-
989
- requirements:
990
- - id: "namespace"
991
- type: "NamespaceRequirement"
992
- description: "Ensure proper SVG namespace"
993
-
994
- - id: "custom_requirement"
995
- type: "CustomRequirement"
996
- description: "Validate custom elements"
997
- config:
998
- custom_option: "organization_value"
999
-
1000
- - id: "security_restrictions"
1001
- type: "NoExternalCssRequirement"
1002
- description: "Prevent external CSS references"
1003
-
1004
- remediations:
1005
- - id: "fix_namespace"
1006
- type: "NamespaceRemediationAction"
1007
- description: "Add missing SVG namespace"
1008
- targets: ["namespace"]
1009
-
1010
- - id: "fix_custom_elements"
1011
- type: "CustomRemediationAction"
1012
- description: "Fix custom element issues"
1013
- targets: ["custom_requirement"]
1014
- config:
1015
- default_value: "organization_default"
341
+ # Check for external references
342
+ if result.has_external_references?
343
+ result.external_references.each do |ref|
344
+ puts "External reference: #{ref.value}"
345
+ end
346
+ end
1016
347
  ----
1017
348
 
1018
- Then load the profile:
349
+ See link:docs/reference_manifest.adoc[Reference Manifest Documentation] for complete details.
1019
350
 
1020
- [source,ruby]
1021
- ----
1022
- # Load and use the custom profile
1023
- profile = SvgConform::Profile.load_from_file('config/profiles/my_organization.yml')
1024
- document = SvgConform::Document.new(svg_content)
1025
- result = profile.validate(document)
1026
-
1027
- # Apply remediations if needed
1028
- if !result.valid? && profile.remediation_count > 0
1029
- changes = profile.apply_remediations(document)
1030
- puts "Applied #{changes.length} remediations"
1031
- end
1032
- ----
1033
351
 
1034
352
  [[external_compliance]]
1035
353
  == External compliance
1036
354
 
1037
- === General
1038
-
1039
- SvgConform supports external compliance validation through compatibility testing
1040
- and comparison with external SVG validation tools.
1041
-
1042
- SvgConform provides validation report comparison capabilities that enable
1043
- assessment of compatibility with external SVG validation tools. This supports
1044
- migration workflows and quality assurance processes.
1045
-
1046
- === svgcheck
1047
-
1048
- IETF provides the `svgcheck` tool, a Python-based SVG validator and fixer
1049
- that checks SVG files against the SVG 1.2 RFC profile defined in RFC 7996.
1050
-
1051
- SvgConform supports validation compatibility testing against the IETF Python
1052
- svgcheck tool for SVG 1.2 RFC validation.
1053
-
1054
- SvgConform includes a compatibility analysis feature that compares its
1055
- validation results with those of `svgcheck`, helping users identify any
1056
- discrepancies or issues.
1057
-
1058
- IMPORTANT: As of version 2025-10-12, SvgConform's SVG 1.2 RFC profile provides a
1059
- 100% match in check and repair modes of svgcheck for all test files, except for
1060
- the `full-tiny.svg` file, which svgcheck marks as invalid and fails to repair.
1061
-
1062
-
1063
- === svgcheck testing workflow
1064
-
1065
- The external compliance testing workflow involves generating reference outputs
1066
- from external tools and comparing validation results:
1067
-
1068
- [source,bash]
1069
- ----
1070
- # 1. Generate external tool outputs for reference
1071
- svg_conform svgcheck generate SVGCHECK_REPO_LOCAL_PATH --mode both
1072
-
1073
- # 2. Generate comparison reports
1074
- svg_conform svgcheck compatibility --output comparison_report.json
1075
- ----
1076
-
1077
-
1078
- === svgcheck compatibility architecture
1079
-
1080
- SvgConform provides compatibility with the IETF Python svgcheck tool through a
1081
- sophisticated mapping and comparison system that enables validation against the
1082
- SVG 1.2 RFC profile.
1083
-
1084
- .Architecture of svgcheck compatibility checks
1085
- [source]
1086
- ----
1087
- ╭────────────────────────────────────────────────────────────────╮
1088
- │ svgcheck Compatibility System │
1089
- │ (SvgConform ↔ svgcheck Python tool) │
1090
- ├────────────────────────────────────────────────────────────────┤
1091
- │ │
1092
- │ ╭─────────────╮ ╭─────────────────────────────────────╮ │
1093
- │ │ svgcheck │ │ YAML Mapping │ │
1094
- │ │ Raw Errors │───▶│ config/svgcheck_mapping.yml │ │
1095
- │ │ (Python) │ │ │ │
1096
- │ ╰─────────────╯ │ • Pattern matching with regex │ │
1097
- │ │ • Requirement categorization │ │
1098
- │ │ • Semantic meaning extraction │ │
1099
- │ │ • Unmapped error detection │ │
1100
- │ ╰─────────────┬───────────────────────╯ │
1101
- │ │ │
1102
- │ ╭────────────────────────────────▼────────────────────────╮ │
1103
- │ │ SvgcheckParser │ │
1104
- │ │ │ │
1105
- │ │ • Applies YAML mapping during parsing │ │
1106
- │ │ • Categorizes errors by requirement │ │
1107
- │ │ • Marks unmapped errors for RED display │ │
1108
- │ │ • Creates properly structured ConformanceReport │ │
1109
- │ ╰─────────────────────────┬───────────────────────────────╯ │
1110
- │ │ │
1111
- │ ▼ │
1112
- │ ╭─────────────────────────────────────────────────────────╮ │
1113
- │ │ Parallel Processing │ │
1114
- │ │ │ │
1115
- │ │ ╭─────────────────────╮ ╭─────────────────────────╮ │ │
1116
- │ │ │ SvgConform │ │ svgcheck │ │ │
1117
- │ │ │ Validation │ │ ConformanceReport │ │ │
1118
- │ │ │ │ │ (mapped) │ │ │
1119
- │ │ │ • Native Ruby │ │ • Parsed from YAML │ │ │
1120
- │ │ │ • Direct profile │ │ • Requirement-mapped │ │ │
1121
- │ │ │ • ConformanceReport │ │ • Compatible structure │ │ │
1122
- │ │ ╰─────────────────────╯ ╰─────────────────────────╯ │ │
1123
- │ ╰─────────────┬───────────────────────┬───────────────────╯ │
1124
- │ │ │ │
1125
- │ └───────────┬───────────┘ │
1126
- │ │ │
1127
- │ ╭─────────────────────────▼─────────────────────────╮ │
1128
- │ │ ReportComparator │ │
1129
- │ │ │ │
1130
- │ │ • Direct ConformanceReport comparison │ │
1131
- │ │ • Unified requirement-based display │ │
1132
- │ │ • Side-by-side error mapping │ │
1133
- │ │ • 🚨 RED highlighting for unmapped errors │ │
1134
- │ │ • Compatibility metrics and analysis │ │
1135
- │ ╰───────────────────────────────────────────────────╯ │
1136
- │ │
1137
- ╰────────────────────────────────────────────────────────────────╯
1138
- ----
1139
-
1140
-
1141
- === svgcheck compatibility commands
1142
-
1143
- ==== General
1144
-
1145
- In order to run the compatibility commands, you need to have the `svgcheck` tool
1146
- installed and accessible in your PATH.
1147
-
1148
- NOTE: The `svgcheck` tool can be installed via `pip install svgcheck`.
1149
-
1150
- The commands in this section provide functionality to generate svgcheck outputs
1151
- for test files and perform compatibility analysis between SvgConform and svgcheck
1152
- results.
1153
-
1154
- The test files from svgcheck are included in the SvgConform repository under
1155
- `spec/fixtures/svgcheck` to ensure consistent testing.
1156
-
1157
- The mapping configuration file `config/svgcheck_mapping.yml` defines how
1158
- svgcheck error messages are interpreted and mapped to SvgConform requirements.
1159
-
1160
- The data flow steps for compatibility analysis is as follows:
1161
-
1162
- . svgcheck outputs are generated for test files using the `svgcheck generate` command.
1163
-
1164
- . For each test file, svgcheck outputs are generated in both check-only and
1165
- repair modes through the `svgcheck generate` command, and are then parsed by the
1166
- `Svgcheck::Parser` class into the `ReportGenerator` class.
1167
-
1168
- . SvgConform validates the same test files using the SVG 1.2 RFC profile, which provides
1169
- a `ConformanceReport` object.
1170
-
1171
- . The `ReportComparator` class compares the `ConformanceReport` from SvgConform
1172
- with the svgcheck `ReportGenerator` results. The `ReportComparator` handles
1173
- both check-only and repair mode outputs, and maps svgcheck messages to SvgConform
1174
- requirements and remediations outcomes.
1175
-
1176
- . A detailed comparison report is generated, highlighting matches and discrepancies.
1177
-
1178
-
1179
-
1180
- ==== `svg_conform svgcheck compatibility`
1181
-
1182
- The `svgcheck compatibility` command performs a comprehensive compatibility analysis
1183
- between SvgConform validation results and the IETF `svgcheck` tool output.
1184
-
1185
- [source,bash]
1186
- ----
1187
- svg_conform svgcheck compatibility [OPTIONS] [FILE]
1188
-
1189
- Options:
1190
- -p, --profile PROFILE Profile to use (default: svg_1_2_rfc)
1191
- -f, --file FILE Analyze specific file instead of all test files
1192
- -o, --output FILE Output clean report to file (no color codes)
1193
- -v, --verbose Verbose output
1194
- ----
1195
-
1196
- [example]
1197
- ====
1198
- [source,bash]
1199
- ----
1200
- # Run comprehensive compatibility analysis
1201
- svg_conform svgcheck compatibility
1202
-
1203
- # Analyze specific file
1204
- svg_conform svgcheck compatibility --file example.svg
1205
-
1206
- # Generate clean report for documentation
1207
- svg_conform svgcheck compatibility --output compatibility-report.md
1208
-
1209
- # Analyze specific file and save to file
1210
- svg_conform svgcheck compatibility --file example.svg --output analysis.md
1211
- ----
1212
- ====
1213
-
1214
-
1215
- ==== `svg_conform svgcheck generate`
1216
-
1217
- The `svgcheck generate` command generates svgcheck outputs for test files to
1218
- facilitate compatibility analysis.
1219
-
1220
- These files are generated in a structured output directory, with separate subdirectories
1221
- for check-only and repair modes.
1222
-
1223
-
1224
- [source,bash]
1225
- ----
1226
- Usage:
1227
- svg_conform svgcheck generate SVGCHECK_REPO_PATH
1228
-
1229
- Options:
1230
- -m, [--mode=MODE] # Generation mode: check, repair, or both
1231
- # Default: both
1232
- # Possible values: check, repair, both
1233
- [--svgcheck-exec=SVGCHECK_EXEC] # Path to svgcheck executable
1234
- [--fixtures-path=FIXTURES_PATH] # Output directory (default: spec/fixtures/svgcheck)
1235
- -f, [--single-file=SINGLE_FILE] # Process single file only
1236
- [--force] # Overwrite existing outputs
1237
- # Default: false
1238
- -v, [--verbose], [--no-verbose], [--skip-verbose] # Verbose output
1239
- # Default: false
1240
-
1241
- Description:
1242
- Generate svgcheck outputs for test files by running svgcheck on them.
1243
-
1244
- SVGCHECK_REPO_PATH: Path to the svgcheck repository (e.g., svgcheck-reference)
1245
-
1246
- By default, processes all test files in SVGCHECK_REPO_PATH/svgcheck/Tests/ and generates BOTH check and repair
1247
- outputs in separate subdirectories.
1248
-
1249
- Examples: svg_conform svgcheck generate svgcheck-reference svg_conform svgcheck generate svgcheck-reference --mode
1250
- check svg_conform svgcheck generate svgcheck-reference --single-file example.svg
1251
- ----
1252
-
1253
- This command provides a bridge between SvgConform and the Python svgcheck tool,
1254
- enabling comprehensive compatibility testing and analysis. By default, it
1255
- generates both check and repair outputs in separate subdirectories.
1256
-
1257
- The command creates a structured output directory with separate subdirectories
1258
- for different svgcheck modes:
1259
-
1260
- [source]
1261
- ----
1262
- spec/fixtures/svgcheck/
1263
- ├── check/ # Check-only outputs (validation without remediation)
1264
- │ ├── file1.svg.out # Validation messages from svgcheck
1265
- │ ├── file1.svg.err # Error messages from svgcheck
1266
- │ └── file1.svg.code # Exit status from svgcheck
1267
- └── repair/ # Repair outputs (validation + remediation)
1268
- ├── file1.svg.out # Validation messages from svgcheck
1269
- ├── file1.svg.err # Error messages from svgcheck
1270
- ├── file1.svg.code # Exit status from svgcheck
1271
- └── file1.svg.file # Remediated SVG content
1272
- ----
1273
-
1274
- Some svgcheck test files are renamed to indicate their actual type of content,
1275
- which is defined in `svgcheck_generate.rb`:
1276
-
1277
- * svgcheck `full-tiny.xml` is renamed to `full-tiny.svg`
1278
- * svgcheck `rfc-svg.xml` is renamed to `rfc-svg.svg`
1279
-
1280
- The generated outputs are used by the `compatibility` command to perform
1281
- detailed comparisons between SvgConform and svgcheck validation results. The
1282
- structured directory layout enables:
1283
-
1284
- - **Targeted analysis**: Compare check-only vs repair mode behaviors
1285
- - **Comprehensive testing**: Validate against both validation and remediation workflows
1286
- - **Regression testing**: Track changes in svgcheck behavior over time
1287
- - **Profile development**: Use svgcheck outputs as reference for profile refinement
1288
-
1289
-
1290
- There are three modes of operation for generating svgcheck outputs:
1291
-
1292
- **Check Mode** (`--mode check`):
1293
-
1294
- - Runs svgcheck without the `--repair` flag
1295
- - Only validates SVG files and reports errors
1296
- - Generates `.out`, `.err`, and `.code` files
1297
- - No remediated content is produced
1298
-
1299
- **Repair Mode** (`--mode repair`):
1300
-
1301
- - Runs svgcheck with the `--repair` flag
1302
- - Validates SVG files and generates remediated content
1303
- - Generates `.out`, `.err`, `.code`, and `.file` files
1304
- - The `.file` contains the remediated SVG content
1305
-
1306
- **Both Mode** (`--mode both`, default):
1307
-
1308
- - Runs both check and repair modes for each file
1309
- - Generates complete output sets in both subdirectories
1310
- - Provides comprehensive data for compatibility analysis
1311
-
1312
- [source,bash]
1313
- ----
1314
- # Generate both check and repair outputs for all test files
1315
- svg_conform svgcheck generate /path/to/svgcheck-reference
1316
-
1317
- # Generate only check outputs
1318
- svg_conform svgcheck generate /path/to/svgcheck-reference --mode check
1319
-
1320
- # Generate only repair outputs
1321
- svg_conform svgcheck generate /path/to/svgcheck-reference --mode repair
1322
-
1323
- # Process a single file with verbose output
1324
- svg_conform svgcheck generate /path/to/svgcheck-reference --single-file example.svg --verbose
1325
-
1326
- # Force regeneration of existing outputs
1327
- svg_conform svgcheck generate /path/to/svgcheck-reference --force
355
+ SvgConform provides compatibility with existing SVG validation tools:
1328
356
 
1329
- # Use custom output directory
1330
- svg_conform svgcheck generate /path/to/svgcheck-reference --fixtures-path /path/to/custom/output
1331
- ----
1332
-
1333
-
1334
-
1335
- ==== `svg_conform svgcheck compare`
1336
-
1337
- The `svgcheck compare` command compares SvgConform validation results with existing
1338
- svgcheck reports to assess compatibility.
1339
-
1340
- This command is useful for verifying that SvgConform produces equivalent results
1341
- to the IETF svgcheck tool.
1342
-
1343
- Syntax:
1344
-
1345
- [source,bash]
1346
- ----
1347
- svg_conform svgcheck compare FILE [OPTIONS]
1348
-
1349
- Options:
1350
- -p, --profile PROFILE Profile to use (default: svg_1_2_rfc)
1351
- --svgcheck-report FILE Path to svgcheck report (default: auto-detect)
1352
- ----
1353
-
1354
- [example]
1355
- ====
1356
- [source,bash]
1357
- ----
1358
- # Compare with auto-detected svgcheck report
1359
- $ svg_conform svgcheck compare diagram.svg -p svg_1_2_rfc
1360
-
1361
- # Specify svgcheck report explicitly
1362
- $ svg_conform svgcheck compare diagram.svg --svgcheck-report diagram.svg.svgcheck.yaml
1363
- ----
1364
- ====
1365
-
1366
-
1367
-
1368
- == Performance
1369
-
1370
- === SAX streaming validation
1371
-
1372
- SvgConform implements SAX (Simple API for XML) streaming validation for
1373
- high-performance processing of large SVG files.
357
+ * **SVGCheck**: 100% error report matching with Python svgcheck tool
358
+ * Profile compatibility modes for different validation tools
1374
359
 
1375
- Performance characteristics:
360
+ See link:docs/compatibility.adoc[Compatibility Documentation] for details.
1376
361
 
1377
- * Small files (<1 MB): ~0.5s validation time
1378
- * Medium files (1-5 MB): ~1s validation time (vs 60-80s with DOM)
1379
- * Large files (>5 MB): ~2s validation time (vs minutes-hours with DOM)
1380
362
 
1381
- Real-world samples results:
363
+ == Documentation
1382
364
 
1383
- * 5.93 MB file: >` 60s → 1.89s (30x faster)
1384
- * 4.57 MB file: >60s → 1.37s (40x faster)
1385
- * 3.44 MB file: >60s → 0.29s (200x faster)
365
+ === User documentation
1386
366
 
1387
- How it works:
367
+ * link:docs/cli_guide.adoc[CLI Guide] - Comprehensive command-line usage
368
+ * link:docs/api_reference.adoc[API Reference] - Complete Ruby API documentation
369
+ * link:docs/profiles.adoc[Profile Documentation] - Profile system and built-in profiles
370
+ * link:docs/requirements.adoc[Requirements Reference] - All validation requirements
371
+ * link:docs/remediation.adoc[Remediation Reference] - All automatic remediations
372
+ * link:docs/reference_manifest.adoc[Reference Manifest] - ID and reference tracking
373
+ * link:docs/rdf_metadata_support.adoc[RDF Metadata Support] - RDF/Dublin Core configuration
1388
374
 
1389
- SAX streaming validation processes XML events without building a full DOM tree
1390
- in memory. This provides:
375
+ === Developer documentation
1391
376
 
1392
- * Forward-only processing: Single pass through XML stream
1393
- * Constant memory: No full DOM tree in memory
1394
- * Predictable performance: O(n) complexity guaranteed
1395
- * No object identity issues: Path-based node identification
377
+ * link:docs/sax_validation_mode.adoc[SAX Validation Mode] - Writing SAX-compatible requirements
378
+ * link:CONTINUATION_PLAN.md[Development Plan] - Project roadmap and tasks
379
+ * link:IMPLEMENTATION_STATUS.md[Implementation Status] - Component status tracking
1396
380
 
1397
- Mode selection:
1398
381
 
1399
- By default, SAX mode is used for all validation operations. DOM mode is
1400
- automatically used when remediation is requested (`fix: true`).
382
+ == Development
1401
383
 
1402
- [source,ruby]
1403
- ----
1404
- # Default: SAX mode (best performance)
1405
- validator = SvgConform::Validator.new
1406
- result = validator.validate_file('large.svg', profile: :metanorma)
1407
-
1408
- # Explicit mode selection
1409
- validator_sax = SvgConform::Validator.new(mode: :sax) # Force SAX
1410
- validator_dom = SvgConform::Validator.new(mode: :dom) # Force DOM
1411
- validator_auto = SvgConform::Validator.new(mode: :auto) # File size based (>1MB uses SAX)
1412
- ----
1413
-
1414
- Validation parity:
1415
-
1416
- SAX mode produces identical validation results to DOM mode on 18/19 test files
1417
- (94.7% parity). The one exception is `full-tiny.svg`, a comprehensive test file
1418
- with known architectural differences.
1419
-
1420
-
1421
-
1422
- == Testing
1423
-
1424
- Run the test suite:
1425
-
1426
- [source,bash]
1427
- ----
1428
- bundle exec rspec
1429
- ----
1430
-
1431
- Run specific test categories:
1432
-
1433
- [source,bash]
1434
- ----
1435
- # Unit tests
1436
- bundle exec rspec spec/unit/
1437
-
1438
- # Integration tests
1439
- bundle exec rspec spec/integration/
1440
-
1441
- # SVGCheck compatibility tests
1442
- bundle exec rspec spec/svgcheck_compatibility_spec.rb
1443
- ----
384
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
1444
385
 
386
+ To install this gem onto your local machine, run `bundle exec rake install`.
1445
387
 
1446
- == Changelog
1447
388
 
1448
- See link:CHANGELOG.md[CHANGELOG.md] for version history and changes.
389
+ == Contributing
1449
390
 
391
+ Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/svg_conform.
1450
392
 
1451
- == Copyright and license
1452
393
 
1453
- Copyright Ribose.
394
+ == License
1454
395
 
1455
- This gem is available as open source under the terms of the Ribose 2-clause BSD
1456
- license.
396
+ The gem is available as open source under the terms of the BSD 2-Clause License.