svg_conform 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/rake.yml +15 -0
- data/.github/workflows/release.yml +23 -0
- data/.github/workflows/svgcheck-compatibility.yml +135 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +183 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/Gemfile +14 -0
- data/README.adoc +1384 -0
- data/Rakefile +15 -0
- data/config/profiles/base.yml +34 -0
- data/config/profiles/lucid_fix.yml +37 -0
- data/config/profiles/metanorma.yml +212 -0
- data/config/profiles/no_external_css.yml +20 -0
- data/config/profiles/svg_1_2_rfc.yml +284 -0
- data/config/profiles/svg_1_2_rfc_with_rdf.yml +145 -0
- data/config/svgcheck_mapping.yml +180 -0
- data/docs/profiles.adoc +547 -0
- data/docs/rdf_metadata_support.adoc +212 -0
- data/docs/remediation.adoc +732 -0
- data/docs/requirements.adoc +709 -0
- data/examples/demo.rb +116 -0
- data/examples/requirements_demo.rb +240 -0
- data/exe/svg_conform +7 -0
- data/lib/svg_conform/batch_report.rb +70 -0
- data/lib/svg_conform/cli.rb +107 -0
- data/lib/svg_conform/commands/check.rb +390 -0
- data/lib/svg_conform/commands/profiles.rb +118 -0
- data/lib/svg_conform/commands/svgcheck.rb +90 -0
- data/lib/svg_conform/commands/svgcheck_compare.rb +92 -0
- data/lib/svg_conform/commands/svgcheck_compatibility.rb +43 -0
- data/lib/svg_conform/commands/svgcheck_generate.rb +262 -0
- data/lib/svg_conform/compatibility/analysis_context.rb +68 -0
- data/lib/svg_conform/compatibility/comparison_result.rb +147 -0
- data/lib/svg_conform/compatibility/compatibility_analyzer.rb +85 -0
- data/lib/svg_conform/compatibility/file_processor.rb +109 -0
- data/lib/svg_conform/compatibility/pattern_discovery.rb +319 -0
- data/lib/svg_conform/compatibility/report_formatter.rb +359 -0
- data/lib/svg_conform/compatibility/svg_analysis_engine.rb +316 -0
- data/lib/svg_conform/compatibility/validity_analysis.rb +252 -0
- data/lib/svg_conform/compatibility/xml_analysis_engine.rb +198 -0
- data/lib/svg_conform/compatibility_analyzer.rb +285 -0
- data/lib/svg_conform/conformance_report.rb +267 -0
- data/lib/svg_conform/constants.rb +199 -0
- data/lib/svg_conform/css_color.rb +262 -0
- data/lib/svg_conform/document.rb +203 -0
- data/lib/svg_conform/external_checkers/svgcheck/compatibility_engine.rb +166 -0
- data/lib/svg_conform/external_checkers/svgcheck/output_generator.rb +101 -0
- data/lib/svg_conform/external_checkers/svgcheck/parser.rb +200 -0
- data/lib/svg_conform/external_checkers/svgcheck/report_comparator.rb +175 -0
- data/lib/svg_conform/external_checkers/svgcheck/report_generator.rb +82 -0
- data/lib/svg_conform/external_checkers/svgcheck/validation_pipeline.rb +249 -0
- data/lib/svg_conform/external_checkers/svgcheck.rb +56 -0
- data/lib/svg_conform/external_checkers.rb +34 -0
- data/lib/svg_conform/fixer.rb +56 -0
- data/lib/svg_conform/profile.rb +164 -0
- data/lib/svg_conform/profiles.rb +60 -0
- data/lib/svg_conform/remediation_engine.rb +92 -0
- data/lib/svg_conform/remediation_result.rb +36 -0
- data/lib/svg_conform/remediation_runner.rb +225 -0
- data/lib/svg_conform/remediations/base_remediation.rb +165 -0
- data/lib/svg_conform/remediations/color_remediation.rb +226 -0
- data/lib/svg_conform/remediations/font_embedding_remediation.rb +145 -0
- data/lib/svg_conform/remediations/font_remediation.rb +122 -0
- data/lib/svg_conform/remediations/image_embedding_remediation.rb +154 -0
- data/lib/svg_conform/remediations/invalid_id_references_remediation.rb +129 -0
- data/lib/svg_conform/remediations/namespace_attribute_remediation.rb +244 -0
- data/lib/svg_conform/remediations/namespace_remediation.rb +151 -0
- data/lib/svg_conform/remediations/no_external_css_remediation.rb +192 -0
- data/lib/svg_conform/remediations/style_promotion_remediation.rb +93 -0
- data/lib/svg_conform/remediations/viewbox_remediation.rb +127 -0
- data/lib/svg_conform/remediations.rb +40 -0
- data/lib/svg_conform/report_comparator.rb +772 -0
- data/lib/svg_conform/requirements/allowed_elements_requirement.rb +367 -0
- data/lib/svg_conform/requirements/base_requirement.rb +98 -0
- data/lib/svg_conform/requirements/color_restrictions_requirement.rb +126 -0
- data/lib/svg_conform/requirements/element_requirement_config.rb +75 -0
- data/lib/svg_conform/requirements/font_family_requirement.rb +133 -0
- data/lib/svg_conform/requirements/forbidden_content_requirement.rb +60 -0
- data/lib/svg_conform/requirements/id_reference_requirement.rb +133 -0
- data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +132 -0
- data/lib/svg_conform/requirements/link_validation_requirement.rb +55 -0
- data/lib/svg_conform/requirements/namespace_attributes_requirement.rb +211 -0
- data/lib/svg_conform/requirements/namespace_requirement.rb +294 -0
- data/lib/svg_conform/requirements/no_external_css_requirement.rb +132 -0
- data/lib/svg_conform/requirements/no_external_fonts_requirement.rb +121 -0
- data/lib/svg_conform/requirements/no_external_images_requirement.rb +91 -0
- data/lib/svg_conform/requirements/style_promotion_requirement.rb +72 -0
- data/lib/svg_conform/requirements/style_requirement.rb +226 -0
- data/lib/svg_conform/requirements/viewbox_required_requirement.rb +96 -0
- data/lib/svg_conform/requirements.rb +49 -0
- data/lib/svg_conform/semantic_comparator.rb +829 -0
- data/lib/svg_conform/validation_context.rb +408 -0
- data/lib/svg_conform/validation_result.rb +146 -0
- data/lib/svg_conform/validator.rb +91 -0
- data/lib/svg_conform/version.rb +5 -0
- data/lib/svg_conform.rb +68 -0
- data/lib/tasks/fixtures.rake +321 -0
- data/lib/tasks/svgcheck.rake +111 -0
- data/reference-docs/SVG-1.2-RFC.rnc.txt +1676 -0
- data/reference-docs/Scalable Vector Graphics (SVG) 1.1 (Second Edition).html +40764 -0
- data/reference-docs/Scalable Vector Graphics (SVG) Tiny 1.2 Specification.html +44591 -0
- data/reference-docs/rfc7996.txt +2971 -0
- data/sig/svg_conform.rbs +4 -0
- data/spec/fixtures/allowed_elements/inputs/basic_violations.svg +21 -0
- data/spec/fixtures/allowed_elements/repair/basic_violations.svg +18 -0
- data/spec/fixtures/color_restrictions/inputs/basic_violations.svg +23 -0
- data/spec/fixtures/color_restrictions/repair/basic_violations.svg +23 -0
- data/spec/fixtures/comprehensive/inputs/multiple_violations.svg +21 -0
- data/spec/fixtures/comprehensive/repair/multiple_violations.svg +16 -0
- data/spec/fixtures/font_family/inputs/basic_violations.svg +17 -0
- data/spec/fixtures/font_family/repair/basic_violations.svg +17 -0
- data/spec/fixtures/forbidden_content/inputs/basic_violations.svg +27 -0
- data/spec/fixtures/forbidden_content/repair/basic_violations.svg +19 -0
- data/spec/fixtures/id_reference/inputs/basic_violations.svg +17 -0
- data/spec/fixtures/id_reference/repair/basic_violations.svg +15 -0
- data/spec/fixtures/link_validation/inputs/basic_violations.svg +20 -0
- data/spec/fixtures/link_validation/repair/basic_violations.svg +16 -0
- data/spec/fixtures/lucid/inputs/simple.svg +67 -0
- data/spec/fixtures/lucid/repair/simple.svg +63 -0
- data/spec/fixtures/namespace/inputs/basic_violations.svg +20 -0
- data/spec/fixtures/namespace/repair/basic_violations.svg +17 -0
- data/spec/fixtures/namespace_attributes/inputs/basic_violations.svg +16 -0
- data/spec/fixtures/namespace_attributes/repair/basic_violations.svg +15 -0
- data/spec/fixtures/no_external_css/inputs/basic_violations.svg +20 -0
- data/spec/fixtures/no_external_css/repair/basic_violations.svg +18 -0
- data/spec/fixtures/style/inputs/basic_violations.svg +22 -0
- data/spec/fixtures/style/repair/basic_violations.svg +22 -0
- data/spec/fixtures/style_promotion/inputs/basic_test.svg +15 -0
- data/spec/fixtures/style_promotion/repair/basic_test.svg +15 -0
- data/spec/fixtures/svg_1_2_rfc/inputs/allowed_elements_violations.svg +18 -0
- data/spec/fixtures/svg_1_2_rfc/inputs/color_restrictions_violations.svg +23 -0
- data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.out +23 -0
- data/spec/fixtures/svgcheck/check/IETF-test.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/IETF-test.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/IETF-test.svg.out +20 -0
- data/spec/fixtures/svgcheck/check/circle.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/circle.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/circle.svg.out +2 -0
- data/spec/fixtures/svgcheck/check/colors.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/colors.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/colors.svg.out +13 -0
- data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.out +76 -0
- data/spec/fixtures/svgcheck/check/example-dot.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/example-dot.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/example-dot.svg.out +11 -0
- data/spec/fixtures/svgcheck/check/full-tiny.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/full-tiny.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/full-tiny.svg.out +5835 -0
- data/spec/fixtures/svgcheck/check/good.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/good.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/good.svg.out +1 -0
- data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.out +5 -0
- data/spec/fixtures/svgcheck/check/malformed.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/malformed.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/malformed.svg.out +8 -0
- data/spec/fixtures/svgcheck/check/rfc-svg.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/rfc-svg.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/rfc-svg.svg.out +1 -0
- data/spec/fixtures/svgcheck/check/rfc.xml.code +1 -0
- data/spec/fixtures/svgcheck/check/rfc.xml.err +0 -0
- data/spec/fixtures/svgcheck/check/rfc.xml.out +2 -0
- data/spec/fixtures/svgcheck/check/rgb.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/rgb.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/rgb.svg.out +9 -0
- data/spec/fixtures/svgcheck/check/svg-wordle.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/svg-wordle.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/svg-wordle.svg.out +508 -0
- data/spec/fixtures/svgcheck/check/threshold.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/threshold.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/threshold.svg.out +20 -0
- data/spec/fixtures/svgcheck/check/utf8.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/utf8.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/utf8.svg.out +162 -0
- data/spec/fixtures/svgcheck/check/viewBox-both.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/viewBox-both.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/viewBox-both.svg.out +4 -0
- data/spec/fixtures/svgcheck/check/viewBox-height.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/viewBox-height.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/viewBox-height.svg.out +3 -0
- data/spec/fixtures/svgcheck/check/viewBox-none.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/viewBox-none.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/viewBox-none.svg.out +3 -0
- data/spec/fixtures/svgcheck/check/viewBox-width.svg.code +1 -0
- data/spec/fixtures/svgcheck/check/viewBox-width.svg.err +0 -0
- data/spec/fixtures/svgcheck/check/viewBox-width.svg.out +3 -0
- data/spec/fixtures/svgcheck/inputs/DrawBerry-sample-2.svg +28 -0
- data/spec/fixtures/svgcheck/inputs/IETF-test.svg +28 -0
- data/spec/fixtures/svgcheck/inputs/circle.svg +3 -0
- data/spec/fixtures/svgcheck/inputs/colors.svg +18 -0
- data/spec/fixtures/svgcheck/inputs/dia-sample-svg.svg +47 -0
- data/spec/fixtures/svgcheck/inputs/example-dot.svg +75 -0
- data/spec/fixtures/svgcheck/inputs/full-tiny.svg +16194 -0
- data/spec/fixtures/svgcheck/inputs/good.svg +19 -0
- data/spec/fixtures/svgcheck/inputs/httpbis-proxy20-fig6.svg +2 -0
- data/spec/fixtures/svgcheck/inputs/malformed.svg +11 -0
- data/spec/fixtures/svgcheck/inputs/rfc-svg.svg +1028 -0
- data/spec/fixtures/svgcheck/inputs/rfc.xml +37 -0
- data/spec/fixtures/svgcheck/inputs/rgb.svg +9 -0
- data/spec/fixtures/svgcheck/inputs/svg-wordle.svg +330 -0
- data/spec/fixtures/svgcheck/inputs/threshold.svg +26 -0
- data/spec/fixtures/svgcheck/inputs/utf8.svg +448 -0
- data/spec/fixtures/svgcheck/inputs/viewBox-both.svg +3 -0
- data/spec/fixtures/svgcheck/inputs/viewBox-height.svg +3 -0
- data/spec/fixtures/svgcheck/inputs/viewBox-none.svg +3 -0
- data/spec/fixtures/svgcheck/inputs/viewBox-width.svg +3 -0
- data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.file +0 -0
- data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.out +23 -0
- data/spec/fixtures/svgcheck/repair/IETF-test.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/IETF-test.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/IETF-test.svg.file +29 -0
- data/spec/fixtures/svgcheck/repair/IETF-test.svg.out +20 -0
- data/spec/fixtures/svgcheck/repair/circle.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/circle.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/circle.svg.file +4 -0
- data/spec/fixtures/svgcheck/repair/circle.svg.out +2 -0
- data/spec/fixtures/svgcheck/repair/colors.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/colors.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/colors.svg.file +19 -0
- data/spec/fixtures/svgcheck/repair/colors.svg.out +13 -0
- data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.file +47 -0
- data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.out +76 -0
- data/spec/fixtures/svgcheck/repair/example-dot.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/example-dot.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/example-dot.svg.file +69 -0
- data/spec/fixtures/svgcheck/repair/example-dot.svg.out +11 -0
- data/spec/fixtures/svgcheck/repair/good.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/good.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/good.svg.file +0 -0
- data/spec/fixtures/svgcheck/repair/good.svg.out +1 -0
- data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.file +73 -0
- data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.out +5 -0
- data/spec/fixtures/svgcheck/repair/malformed.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/malformed.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/malformed.svg.file +9 -0
- data/spec/fixtures/svgcheck/repair/malformed.svg.out +8 -0
- data/spec/fixtures/svgcheck/repair/rfc-svg.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/rfc-svg.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/rfc-svg.svg.file +0 -0
- data/spec/fixtures/svgcheck/repair/rfc-svg.svg.out +1 -0
- data/spec/fixtures/svgcheck/repair/rfc.xml.code +1 -0
- data/spec/fixtures/svgcheck/repair/rfc.xml.err +0 -0
- data/spec/fixtures/svgcheck/repair/rfc.xml.file +37 -0
- data/spec/fixtures/svgcheck/repair/rfc.xml.out +2 -0
- data/spec/fixtures/svgcheck/repair/rgb.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/rgb.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/rgb.svg.file +10 -0
- data/spec/fixtures/svgcheck/repair/rgb.svg.out +9 -0
- data/spec/fixtures/svgcheck/repair/svg-wordle.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/svg-wordle.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/svg-wordle.svg.file +112 -0
- data/spec/fixtures/svgcheck/repair/svg-wordle.svg.out +508 -0
- data/spec/fixtures/svgcheck/repair/threshold.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/threshold.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/threshold.svg.file +27 -0
- data/spec/fixtures/svgcheck/repair/threshold.svg.out +20 -0
- data/spec/fixtures/svgcheck/repair/utf8.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/utf8.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/utf8.svg.file +381 -0
- data/spec/fixtures/svgcheck/repair/utf8.svg.out +162 -0
- data/spec/fixtures/svgcheck/repair/viewBox-both.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/viewBox-both.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/viewBox-both.svg.file +4 -0
- data/spec/fixtures/svgcheck/repair/viewBox-both.svg.out +4 -0
- data/spec/fixtures/svgcheck/repair/viewBox-height.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/viewBox-height.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/viewBox-height.svg.file +4 -0
- data/spec/fixtures/svgcheck/repair/viewBox-height.svg.out +3 -0
- data/spec/fixtures/svgcheck/repair/viewBox-none.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/viewBox-none.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/viewBox-none.svg.file +4 -0
- data/spec/fixtures/svgcheck/repair/viewBox-none.svg.out +3 -0
- data/spec/fixtures/svgcheck/repair/viewBox-width.svg.code +1 -0
- data/spec/fixtures/svgcheck/repair/viewBox-width.svg.err +0 -0
- data/spec/fixtures/svgcheck/repair/viewBox-width.svg.file +4 -0
- data/spec/fixtures/svgcheck/repair/viewBox-width.svg.out +3 -0
- data/spec/fixtures/viewbox_required/inputs/missing_viewbox.svg +10 -0
- data/spec/fixtures/viewbox_required/repair/missing_viewbox.svg +10 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/svg_conform/batch_report_spec.rb +99 -0
- data/spec/svg_conform/commands/check_command_spec.rb +90 -0
- data/spec/svg_conform/commands/profiles_command_spec.rb +20 -0
- data/spec/svg_conform/commands/svgcheck_compare_command_spec.rb +13 -0
- data/spec/svg_conform/commands/svgcheck_compatibility_command_spec.rb +13 -0
- data/spec/svg_conform/commands/svgcheck_generate_command_spec.rb +14 -0
- data/spec/svg_conform/profiles/base_profile_spec.rb +42 -0
- data/spec/svg_conform/profiles/lucid_fix_profile_spec.rb +46 -0
- data/spec/svg_conform/profiles/lucid_profile_spec.rb +84 -0
- data/spec/svg_conform/profiles/metanorma_profile_spec.rb +62 -0
- data/spec/svg_conform/profiles/no_external_css_profile_spec.rb +66 -0
- data/spec/svg_conform/profiles/svg_1_2_rfc_profile_spec.rb +200 -0
- data/spec/svg_conform/profiles/svg_1_2_rfc_with_rdf_profile_spec.rb +81 -0
- data/spec/svg_conform/remediations/color_remediation_spec.rb +95 -0
- data/spec/svg_conform/remediations/font_embedding_remediation_spec.rb +20 -0
- data/spec/svg_conform/remediations/font_remediation_spec.rb +95 -0
- data/spec/svg_conform/remediations/image_embedding_remediation_spec.rb +20 -0
- data/spec/svg_conform/remediations/invalid_id_references_remediation_spec.rb +97 -0
- data/spec/svg_conform/remediations/namespace_attribute_remediation_spec.rb +97 -0
- data/spec/svg_conform/remediations/namespace_remediation_spec.rb +95 -0
- data/spec/svg_conform/remediations/no_external_css_remediation_spec.rb +97 -0
- data/spec/svg_conform/remediations/style_promotion_remediation_spec.rb +97 -0
- data/spec/svg_conform/remediations/viewbox_remediation_spec.rb +95 -0
- data/spec/svg_conform/requirements/allowed_elements_requirement_spec.rb +118 -0
- data/spec/svg_conform/requirements/color_restrictions_requirement_spec.rb +168 -0
- data/spec/svg_conform/requirements/font_family_requirement_spec.rb +188 -0
- data/spec/svg_conform/requirements/forbidden_content_requirement_spec.rb +195 -0
- data/spec/svg_conform/requirements/id_reference_requirement_spec.rb +78 -0
- data/spec/svg_conform/requirements/invalid_id_references_requirement_spec.rb +78 -0
- data/spec/svg_conform/requirements/link_validation_requirement_spec.rb +78 -0
- data/spec/svg_conform/requirements/namespace_attributes_requirement_spec.rb +86 -0
- data/spec/svg_conform/requirements/namespace_requirement_spec.rb +184 -0
- data/spec/svg_conform/requirements/no_external_css_requirement_spec.rb +78 -0
- data/spec/svg_conform/requirements/no_external_fonts_requirement_spec.rb +20 -0
- data/spec/svg_conform/requirements/no_external_images_requirement_spec.rb +20 -0
- data/spec/svg_conform/requirements/style_promotion_requirement_spec.rb +78 -0
- data/spec/svg_conform/requirements/style_requirement_spec.rb +76 -0
- data/spec/svg_conform/requirements/viewbox_required_requirement_spec.rb +165 -0
- data/spec/svg_conform_spec.rb +32 -0
- data/spec/svgcheck_compatibility_spec.rb +355 -0
- data/svg_conform.gemspec +35 -0
- metadata +436 -0
data/README.adoc
ADDED
|
@@ -0,0 +1,1384 @@
|
|
|
1
|
+
= SvgConform: Ruby library for validating and fixing SVG files
|
|
2
|
+
:toc: left
|
|
3
|
+
:toclevels: 3
|
|
4
|
+
:sectlinks:
|
|
5
|
+
:sectanchors:
|
|
6
|
+
:source-highlighter: rouge
|
|
7
|
+
|
|
8
|
+
== Purpose
|
|
9
|
+
|
|
10
|
+
SvgConform is an SVG conformance processor that validates SVG documents against
|
|
11
|
+
defined SVG profiles, and supports automatic remediation of profile requirement
|
|
12
|
+
violations when possible.
|
|
13
|
+
|
|
14
|
+
SvgConform is designed to ensure SVG files meet specific requirements for
|
|
15
|
+
different use cases, such as those required in:
|
|
16
|
+
|
|
17
|
+
* Metanorma documents
|
|
18
|
+
* PDF and PDF/A compliance
|
|
19
|
+
* IETF XMLRFC documents (RFC 7996)
|
|
20
|
+
|
|
21
|
+
SvgConform is distributed as a Ruby gem.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
== Features
|
|
25
|
+
|
|
26
|
+
* **Profile-based validation**: Validate SVG files against predefined or custom profiles
|
|
27
|
+
* **Remediation**: Automatically fix common SVG conformance issues
|
|
28
|
+
* **Extensible architecture**: Easy to add new rules and profiles
|
|
29
|
+
* **Command-line interface**: Validate and fix files from the command line
|
|
30
|
+
* **Ruby API**: Integrate validation into Ruby applications
|
|
31
|
+
* **Multiple report output formats**: Text and JSON output formats
|
|
32
|
+
* **100% SVGCheck compatibility**: Perfect error report matching with Python svgcheck tool
|
|
33
|
+
* **Configurable RDF metadata support**: Choose strict or permissive RDF/Dublin Core handling
|
|
34
|
+
* **Generic namespace handling**: Configuration-driven foreign namespace validation
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
== Concepts
|
|
38
|
+
|
|
39
|
+
=== General
|
|
40
|
+
|
|
41
|
+
SvgConform is built upon a set of core concepts that define its architecture and
|
|
42
|
+
functionality.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
=== SVG document
|
|
46
|
+
|
|
47
|
+
An SVG document is a file that contains Scalable Vector Graphics (SVG) content.
|
|
48
|
+
|
|
49
|
+
In SvgConform, an SVG document is represented by the `SvgConform::Document` class,
|
|
50
|
+
which wraps the Moxml XML document and provides SVG-specific functionality.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
=== SVG profile
|
|
54
|
+
|
|
55
|
+
An SVG profile is a defined set of requirements that an SVG document must meet.
|
|
56
|
+
|
|
57
|
+
These requirements represent concerns that go beyond the SVG standards, such as
|
|
58
|
+
accessibility or stylistic concerns.
|
|
59
|
+
|
|
60
|
+
In SvgConform, a `Profile` object is a collection of requirements and
|
|
61
|
+
remediations that define a specific SVG conformance standard.
|
|
62
|
+
|
|
63
|
+
Each `Profile` object consists of:
|
|
64
|
+
|
|
65
|
+
* `Requirement` objects: Validation checks that determine if an SVG document
|
|
66
|
+
conforms to the profile
|
|
67
|
+
|
|
68
|
+
* `Remediation` objects: Automatic fixes that can be applied when requirements
|
|
69
|
+
fail
|
|
70
|
+
|
|
71
|
+
* `Configuration` objects: Profile-specific settings and parameters
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
Conformance to an SVG profile is a measure of the degree to which an SVG
|
|
75
|
+
document meets the requirements of a specific profile.
|
|
76
|
+
|
|
77
|
+
In SvgConform, SVG conformance is determined by whether an SVG document passes
|
|
78
|
+
all the requirements defined in the profile.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
=== SVG requirement
|
|
82
|
+
|
|
83
|
+
An SVG requirement is a specific condition or set of conditions that an SVG
|
|
84
|
+
document must meet.
|
|
85
|
+
|
|
86
|
+
In SvgConform, a `Requirement` object encapsulates the logic to check for a
|
|
87
|
+
specific requirement.
|
|
88
|
+
|
|
89
|
+
Each `Requirement` object is designed to be modular and focuses on a single
|
|
90
|
+
concern, such as color usage, font family restrictions, or structural validity.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
=== SVG remediation action
|
|
94
|
+
|
|
95
|
+
An SVG remediation action is an automatic fix or adjustment applied to an SVG
|
|
96
|
+
document to resolve one or more SVG requirement failures.
|
|
97
|
+
|
|
98
|
+
A remediation action may imply a lossless or lossy change.
|
|
99
|
+
|
|
100
|
+
In SvgConform, a `Remediation` object encapsulates the logic to perform a
|
|
101
|
+
specific remediation action.
|
|
102
|
+
|
|
103
|
+
Each `Remediation` object targets one or more specific requirements through a
|
|
104
|
+
mapping system.
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
=== Defining profiles with configuration
|
|
108
|
+
|
|
109
|
+
Requirements and remediations can be configured with specific parameters to
|
|
110
|
+
customize their behavior.
|
|
111
|
+
|
|
112
|
+
In SvgConform, `Requirement` and `Remediation` objects are customizable
|
|
113
|
+
executable components that can be tailored to specific use cases.
|
|
114
|
+
|
|
115
|
+
These parameters can be set in the profile YAML configuration to influence how
|
|
116
|
+
requirements and remediations operate.
|
|
117
|
+
|
|
118
|
+
In combination, it allows for flexible definition and authoring of new
|
|
119
|
+
deterministic SVG profiles, with the ability to enforce specific requirements
|
|
120
|
+
and remediation strategies.
|
|
121
|
+
|
|
122
|
+
Each remediation action can be linked to a particular requirement to indicate
|
|
123
|
+
their relationship, defined in the profile.
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
=== Reporting
|
|
127
|
+
|
|
128
|
+
SvgConform provides detailed reporting on SVG conformance issues.
|
|
129
|
+
|
|
130
|
+
* Validation results: Summary of passed and failed checks
|
|
131
|
+
* Report formats: The resulting validation report can be exported
|
|
132
|
+
in machine-readable formats, including JSON and YAML
|
|
133
|
+
* Error messages: Descriptions of specific conformance issues
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
=== Compatibility with other tools
|
|
137
|
+
|
|
138
|
+
SvgConform aims to deliver accurate results for compatibility with existing SVG
|
|
139
|
+
profile conformance tools.
|
|
140
|
+
|
|
141
|
+
See <<external_compliance>> for details.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
== Usage
|
|
146
|
+
|
|
147
|
+
=== Installation
|
|
148
|
+
|
|
149
|
+
Add this line to your application's Gemfile:
|
|
150
|
+
|
|
151
|
+
[source,ruby]
|
|
152
|
+
----
|
|
153
|
+
gem 'svg_conform'
|
|
154
|
+
----
|
|
155
|
+
|
|
156
|
+
And then execute:
|
|
157
|
+
|
|
158
|
+
[source,bash]
|
|
159
|
+
----
|
|
160
|
+
$ bundle install
|
|
161
|
+
----
|
|
162
|
+
|
|
163
|
+
Or install it yourself as:
|
|
164
|
+
|
|
165
|
+
[source,bash]
|
|
166
|
+
----
|
|
167
|
+
$ gem install svg_conform
|
|
168
|
+
----
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
=== Command line usage
|
|
172
|
+
|
|
173
|
+
Details and examples of command line usage can be found in
|
|
174
|
+
<<command_line_interface>>.
|
|
175
|
+
|
|
176
|
+
List available profiles:
|
|
177
|
+
|
|
178
|
+
[source,bash]
|
|
179
|
+
----
|
|
180
|
+
$ svg_conform profiles
|
|
181
|
+
----
|
|
182
|
+
|
|
183
|
+
Check/validate an SVG file against a profile:
|
|
184
|
+
|
|
185
|
+
[source,bash]
|
|
186
|
+
----
|
|
187
|
+
$ svg_conform check file.svg --profile=metanorma
|
|
188
|
+
----
|
|
189
|
+
|
|
190
|
+
Check and fix an SVG file to conform to a profile:
|
|
191
|
+
|
|
192
|
+
[source,bash]
|
|
193
|
+
----
|
|
194
|
+
$ svg_conform check file.svg --profile=metanorma -f --fix-output=fixed.svg
|
|
195
|
+
----
|
|
196
|
+
|
|
197
|
+
Batch process a directory of SVG files:
|
|
198
|
+
|
|
199
|
+
[source,bash]
|
|
200
|
+
----
|
|
201
|
+
$ svg_conform check --directory=images/ --profile=metanorma -f --output-dir=fixed/
|
|
202
|
+
----
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
=== Ruby API usage
|
|
206
|
+
|
|
207
|
+
Details and examples of Ruby API usage can be found in
|
|
208
|
+
<<ruby_api_reference>>.
|
|
209
|
+
|
|
210
|
+
[source,ruby]
|
|
211
|
+
----
|
|
212
|
+
require 'svg_conform'
|
|
213
|
+
|
|
214
|
+
# Load a profile and validate
|
|
215
|
+
profile = SvgConform::Profile.load_from_file("config/profiles/svg_1_2_rfc.yml")
|
|
216
|
+
document = SvgConform::Document.new(svg_content)
|
|
217
|
+
result = profile.validate(document)
|
|
218
|
+
|
|
219
|
+
puts "Valid: #{result.valid?}"
|
|
220
|
+
puts "Errors: #{result.errors.count}"
|
|
221
|
+
puts "Warnings: #{result.warnings.count}"
|
|
222
|
+
|
|
223
|
+
# Apply remediations to fix issues
|
|
224
|
+
if !result.valid? && profile.has_remediations?
|
|
225
|
+
engine = SvgConform::RemediationEngine.new(profile)
|
|
226
|
+
remediation_results = engine.apply_remediations(document, result)
|
|
227
|
+
|
|
228
|
+
puts "Applied #{remediation_results.length} remediations"
|
|
229
|
+
puts "Fixed SVG:"
|
|
230
|
+
puts document.to_xml
|
|
231
|
+
end
|
|
232
|
+
----
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
== Core components
|
|
237
|
+
|
|
238
|
+
=== Architecture
|
|
239
|
+
|
|
240
|
+
The SvgConform architecture is built around a modular design that separates
|
|
241
|
+
concerns and allows for easy extension.
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
[source]
|
|
245
|
+
----
|
|
246
|
+
╭────────────────────────────────────────────────────────────────╮
|
|
247
|
+
│ SvgConform │
|
|
248
|
+
├────────────────────────────────────────────────────────────────┤
|
|
249
|
+
│ │
|
|
250
|
+
│ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │
|
|
251
|
+
│ │ CLI │ │ Ruby API │ │ Profiles │ │
|
|
252
|
+
│ │ │ │ │ │ Registry │ │
|
|
253
|
+
│ ╰─────┬───────╯ ╰──────┬──────╯ ╰─────┬───────╯ │
|
|
254
|
+
│ │ │ │ │
|
|
255
|
+
│ └───────────────────┼─────────────────┘ │
|
|
256
|
+
│ │ │
|
|
257
|
+
│ ╭─────────────────────────▼─────────────────────────╮ │
|
|
258
|
+
│ │ Validator │ │
|
|
259
|
+
│ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
|
|
260
|
+
│ │ │ Document │ │ Validation │ │ Remediation │ │ │
|
|
261
|
+
│ │ │ Parser │ │ Engine │ │ Engine │ │ │
|
|
262
|
+
│ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
|
|
263
|
+
│ ╰─────────────────────────┬─────────────────────────╯ │
|
|
264
|
+
│ │ │
|
|
265
|
+
│ ╭─────────────────────────▼─────────────────────────╮ │
|
|
266
|
+
│ │ Profile System │ │
|
|
267
|
+
│ │ │ │
|
|
268
|
+
│ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
|
|
269
|
+
│ │ │ SVG 1.2 RFC │ │ Metanorma │ │ Future │ │ │
|
|
270
|
+
│ │ │ Profile │ │ SVG Profile │ │ Profiles │ │ │
|
|
271
|
+
│ │ │ │ │ │ │ │ │ │
|
|
272
|
+
│ │ │ • svgcheck │ │ • ID links │ │ • Custom │ │ │
|
|
273
|
+
│ │ │ compatible │ │ • No ext. │ │ rules │ │ │
|
|
274
|
+
│ │ │ • Grayscale │ │ fonts │ │ • Org │ │ │
|
|
275
|
+
│ │ │ • RFC 7996 │ │ • Font def. │ │ standards │ │ │
|
|
276
|
+
│ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
|
|
277
|
+
│ ╰─────────────────────────┬─────────────────────────╯ │
|
|
278
|
+
│ │ │
|
|
279
|
+
│ ╭─────────────────────────▼─────────────────────────╮ │
|
|
280
|
+
│ │ Requirements & Remediations Engine │ │
|
|
281
|
+
│ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
|
|
282
|
+
│ │ │Requirements │ │Remediations │ │ Validation │ │ │
|
|
283
|
+
│ │ │ System │ │ System │ │ Results │ │ │
|
|
284
|
+
│ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
|
|
285
|
+
│ ╰─────────────────────────┬─────────────────────────╯ │
|
|
286
|
+
│ │ │
|
|
287
|
+
│ ╭─────────────────────────▼─────────────────────────╮ │
|
|
288
|
+
│ │ svgcheck Compatibility │ │
|
|
289
|
+
│ │ ╭─────────────╮ ╭─────────────╮ ╭─────────────╮ │ │
|
|
290
|
+
│ │ │ svgcheck │ │ YAML │ │ Report │ │ │
|
|
291
|
+
│ │ │ Parser │ │ Mapping │ │ Comparator │ │ │
|
|
292
|
+
│ │ ╰─────────────╯ ╰─────────────╯ ╰─────────────╯ │ │
|
|
293
|
+
│ ╰─────────────────────────┬─────────────────────────╯ │
|
|
294
|
+
│ │ │
|
|
295
|
+
│ ╭─────────────────────────▼─────────────────────────╮ │
|
|
296
|
+
│ │ Moxml │ │
|
|
297
|
+
│ │ (XML Processing) │ │
|
|
298
|
+
│ ╰───────────────────────────────────────────────────╯ │
|
|
299
|
+
│ │
|
|
300
|
+
╰────────────────────────────────────────────────────────────────╯
|
|
301
|
+
----
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
=== Profiles
|
|
305
|
+
|
|
306
|
+
SvgConform includes predefined profiles that can be used out-of-the-box.
|
|
307
|
+
Each profile is designed for different use cases and compliance standards.
|
|
308
|
+
|
|
309
|
+
.Predefined SVG profiles included in SvgConform
|
|
310
|
+
[cols="2,3,3,2", options="header"]
|
|
311
|
+
|===
|
|
312
|
+
|Profile |Use Case |Key Features |Documentation
|
|
313
|
+
|
|
314
|
+
|`base`
|
|
315
|
+
|Foundation profile
|
|
316
|
+
|Basic validation, namespace checks, starting point for custom profiles.
|
|
317
|
+
|link:docs/profiles.adoc#base-profile[Details]
|
|
318
|
+
|
|
319
|
+
|`metanorma`
|
|
320
|
+
|Metanorma SVG profile
|
|
321
|
+
|Standard SVG for Metanorma documents. Valid HREFs and ID linking. No external
|
|
322
|
+
fonts, images and CSS. No non-SVG elements or attributes.
|
|
323
|
+
|link:docs/profiles.adoc#no-external-css-profile[Details]
|
|
324
|
+
|
|
325
|
+
|`svg_1_2_rfc`
|
|
326
|
+
|IETF RFC SVG 1.2 profile
|
|
327
|
+
|RFC 7996/6949 compliant. Black/white color only, limited elements, generic
|
|
328
|
+
fonts. Fully compatible with `svgcheck` outcomes.
|
|
329
|
+
|link:docs/profiles.adoc#svg-1-2-rfc-profile[Details]
|
|
330
|
+
|
|
331
|
+
|`svg_1_2_rfc_with_rdf`
|
|
332
|
+
|IETF RFC SVG 1.2 profile with RDF metadata
|
|
333
|
+
|Same as `svg_1_2_rfc`, but allows RDF/Dublin Core metadata from design tools.
|
|
334
|
+
Supported by `svgcheck`.
|
|
335
|
+
|link:docs/profiles.adoc#svg-1-2-rfc-with-rdf-profile[Details]
|
|
336
|
+
|
|
337
|
+
|`no_external_css`
|
|
338
|
+
|Self-contained SVG
|
|
339
|
+
|No external references, security-focused, offline usage.
|
|
340
|
+
|link:docs/profiles.adoc#no-external-css-profile[Details]
|
|
341
|
+
|
|
342
|
+
|`lucid_fix`
|
|
343
|
+
|Lucid cleanup
|
|
344
|
+
|Remove Lucid-specific metadata, clean standard SVG output
|
|
345
|
+
|link:docs/profiles.adoc#lucid-fix-profile[Details]
|
|
346
|
+
|===
|
|
347
|
+
|
|
348
|
+
For complete profile documentation, including inheritance, customization, RDF
|
|
349
|
+
metadata support, and selection guides, see
|
|
350
|
+
link:docs/profiles.adoc[SVG Profiles Documentation].
|
|
351
|
+
|
|
352
|
+
For detailed information about configuring RDF metadata support in profiles, see
|
|
353
|
+
link:docs/rdf_metadata_support.adoc[RDF Metadata Support Documentation].
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
=== Requirements
|
|
358
|
+
|
|
359
|
+
SvgConform includes different requirement checkers that validate various aspects
|
|
360
|
+
of SVG documents.
|
|
361
|
+
|
|
362
|
+
There are two main categories of requirements:
|
|
363
|
+
|
|
364
|
+
* structural requirements: requirements set towards the XML structure and syntax of SVG documents
|
|
365
|
+
* logical requirements: requirements set towards content and stylistic aspects of SVG documents
|
|
366
|
+
|
|
367
|
+
.SvgConform supported requirement classes
|
|
368
|
+
[cols="2,2,3", options="header"]
|
|
369
|
+
|===
|
|
370
|
+
|Type |Requirement |Description
|
|
371
|
+
|
|
372
|
+
|Structural
|
|
373
|
+
|`NamespaceRequirement`
|
|
374
|
+
|Ensures proper SVG namespace declarations
|
|
375
|
+
|
|
376
|
+
|Structural
|
|
377
|
+
|`NamespaceAttributesRequirement`
|
|
378
|
+
|Validates namespace attributes are from allowed namespaces
|
|
379
|
+
|
|
380
|
+
|Structural
|
|
381
|
+
|`AllowedElementsRequirement`
|
|
382
|
+
|Restricts which SVG elements are permitted
|
|
383
|
+
|
|
384
|
+
|Structural
|
|
385
|
+
|`ViewboxRequiredRequirement`
|
|
386
|
+
|Requires viewBox attributes on root elements
|
|
387
|
+
|
|
388
|
+
|Logical
|
|
389
|
+
|`ColorRestrictionsRequirement`
|
|
390
|
+
|Enforces color usage restrictions (e.g., grayscale only)
|
|
391
|
+
|
|
392
|
+
|Logical
|
|
393
|
+
|`FontFamilyRequirement`
|
|
394
|
+
|Controls font family usage and validates font specifications
|
|
395
|
+
|
|
396
|
+
|Logical
|
|
397
|
+
|`NoExternalCssRequirement`
|
|
398
|
+
|Prevents external CSS references to ensure self-contained documents
|
|
399
|
+
|
|
400
|
+
|Logical
|
|
401
|
+
|`ForbiddenContentRequirement`
|
|
402
|
+
|Prevents inclusion of forbidden elements and attributes
|
|
403
|
+
|
|
404
|
+
|Logical
|
|
405
|
+
|`IdReferenceRequirement`
|
|
406
|
+
|Validates that ID references point to existing elements
|
|
407
|
+
|
|
408
|
+
|Logical
|
|
409
|
+
|`InvalidIdReferencesRequirement`
|
|
410
|
+
|Detects and validates broken ID references in SVG documents
|
|
411
|
+
|
|
412
|
+
|Logical
|
|
413
|
+
|`LinkValidationRequirement`
|
|
414
|
+
|Validates that links use only ASCII characters (IETF requirement)
|
|
415
|
+
|
|
416
|
+
|Logical
|
|
417
|
+
|`StyleRequirement`
|
|
418
|
+
|Comprehensive CSS style validation including syntax and properties
|
|
419
|
+
|
|
420
|
+
|Logical
|
|
421
|
+
|`StylePromotionRequirement`
|
|
422
|
+
|Detects style properties that should be promoted to SVG attributes
|
|
423
|
+
|===
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
=== Remediations
|
|
428
|
+
|
|
429
|
+
Remediations are automatic fixing actions that can resolve requirement failures.
|
|
430
|
+
Each remediation targets one or more specific requirements.
|
|
431
|
+
|
|
432
|
+
SvgConform includes different remediation actions that can automatically fix
|
|
433
|
+
SVG documents to resolve requirement violations.
|
|
434
|
+
|
|
435
|
+
.SvgConform supported remediation classes
|
|
436
|
+
[cols="2,2,3,2", options="header"]
|
|
437
|
+
|===
|
|
438
|
+
|Type |Remediation |Description |Targets
|
|
439
|
+
|
|
440
|
+
|Content Conversion
|
|
441
|
+
|`ColorRemediation`
|
|
442
|
+
|Converts invalid colors to allowed alternatives using threshold-based conversion
|
|
443
|
+
|<<color-restrictions-requirement,`ColorRestrictionsRequirement`>>
|
|
444
|
+
|
|
445
|
+
|Content Conversion
|
|
446
|
+
|`FontRemediation`
|
|
447
|
+
|Maps font families to generic alternatives (serif, sans-serif, monospace)
|
|
448
|
+
|<<font-family-requirement,`FontFamilyRequirement`>>
|
|
449
|
+
|
|
450
|
+
|Element/Attribute Removal
|
|
451
|
+
|`NamespaceRemediation`
|
|
452
|
+
|Removes invalid namespace elements and cleans up namespace declarations
|
|
453
|
+
|<<namespace-requirement,`NamespaceRequirement`>>
|
|
454
|
+
|
|
455
|
+
|Element/Attribute Removal
|
|
456
|
+
|`NamespaceAttributeRemediation`
|
|
457
|
+
|Removes attributes from disallowed namespaces
|
|
458
|
+
|<<namespace-attributes-requirement,`NamespaceAttributesRequirement`>>
|
|
459
|
+
|
|
460
|
+
|Element/Attribute Removal
|
|
461
|
+
|`NoExternalCssRemediation`
|
|
462
|
+
|Removes external CSS references including @import and external stylesheets
|
|
463
|
+
|<<no-external-css-requirement,`NoExternalCssRequirement`>>
|
|
464
|
+
|
|
465
|
+
|Addition
|
|
466
|
+
|`ViewboxRemediation`
|
|
467
|
+
|Adds missing viewBox attributes to root SVG elements
|
|
468
|
+
|<<viewbox-required-requirement,`ViewboxRequiredRequirement`>>
|
|
469
|
+
|
|
470
|
+
|Style Processing
|
|
471
|
+
|`StylePromotionRemediation`
|
|
472
|
+
|Promotes CSS style properties to equivalent SVG attributes
|
|
473
|
+
|<<style-promotion-requirement,`StylePromotionRequirement`>>
|
|
474
|
+
|
|
475
|
+
|Reference Fixing
|
|
476
|
+
|`InvalidIdReferencesRemediation`
|
|
477
|
+
|Fixes or removes broken ID references and invalid href attributes
|
|
478
|
+
|<<id-reference-requirement,`IdReferenceRequirement`>>, <<invalid-id-references-requirement,`InvalidIdReferencesRequirement`>>
|
|
479
|
+
|===
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
=== Requirement and remediation mapping
|
|
483
|
+
|
|
484
|
+
Remediations are mapped to requirements using the `targets` configuration in
|
|
485
|
+
profile YAML files.
|
|
486
|
+
|
|
487
|
+
[source,yaml]
|
|
488
|
+
----
|
|
489
|
+
remediations:
|
|
490
|
+
- id: "fix_invalid_colors"
|
|
491
|
+
type: "ColorRemediationAction"
|
|
492
|
+
description: "Convert invalid colors to black or white"
|
|
493
|
+
targets: ["color_restrictions"] # Maps to ColorRestrictionsRequirement
|
|
494
|
+
----
|
|
495
|
+
|
|
496
|
+
This mapping system allows:
|
|
497
|
+
|
|
498
|
+
* **Targeted fixes**: Remediations only run when their target requirements fail
|
|
499
|
+
* **Flexible configuration**: Multiple remediations can target the same requirement
|
|
500
|
+
* **Conditional application**: Remediations can be enabled/disabled per profile
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
=== Validation and remediation flow
|
|
505
|
+
|
|
506
|
+
The following steps illustrates the data flow through the core components of
|
|
507
|
+
SvgConform.
|
|
508
|
+
|
|
509
|
+
. An SVG file is read and parsed into a Document object.
|
|
510
|
+
. The Document is validated against a Profile using the Validator.
|
|
511
|
+
. The Validator applies Requirements and collects results in a ConformanceReport object.
|
|
512
|
+
. If fixing is enabled, the Validator uses the RemediationEngine to apply Remediations.
|
|
513
|
+
. The fixed Document is returned along with the validation results in the ConformanceReport.
|
|
514
|
+
|
|
515
|
+
[source]
|
|
516
|
+
----
|
|
517
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
518
|
+
│ SVG File │───▶│ Document │───▶│ Validator │
|
|
519
|
+
│ │ │ Parser │ │ │
|
|
520
|
+
└─────────────┘ └─────────────┘ └─────┬───────┘
|
|
521
|
+
│
|
|
522
|
+
┌─────────────┐ │
|
|
523
|
+
│ Profile │◀─────────┘
|
|
524
|
+
└─────┬───────┘
|
|
525
|
+
│
|
|
526
|
+
┌─────▼───────┐
|
|
527
|
+
│ Rules │
|
|
528
|
+
└─────┬───────┘
|
|
529
|
+
│
|
|
530
|
+
┌─────▼───────┐ ┌─────────────┐
|
|
531
|
+
│Requirements │───▶│ Validation │
|
|
532
|
+
│ │ │ Result │
|
|
533
|
+
└─────────────┘ └─────┬───────┘
|
|
534
|
+
│
|
|
535
|
+
┌─────────────┐ │
|
|
536
|
+
│Remediations │◀─────────┘
|
|
537
|
+
└─────┬───────┘
|
|
538
|
+
│
|
|
539
|
+
┌───────▼────────┐
|
|
540
|
+
│ Fixed Document │
|
|
541
|
+
└────────────────┘
|
|
542
|
+
----
|
|
543
|
+
|
|
544
|
+
=== Classes
|
|
545
|
+
|
|
546
|
+
==== Document (`SvgConform::Document`)
|
|
547
|
+
|
|
548
|
+
Represents an SVG document. The SVG document in XML is parsed using the `Moxml`
|
|
549
|
+
library, and provides SVG-specific functionality through the Document class.
|
|
550
|
+
|
|
551
|
+
==== Validator (`SvgConform::Validator`)
|
|
552
|
+
|
|
553
|
+
The validator is the main entry point for SVG validation. It orchestrates the
|
|
554
|
+
validation process with loading profiles, applying rules, and collecting results.
|
|
555
|
+
|
|
556
|
+
==== Profile (`SvgConform::Profile`)
|
|
557
|
+
|
|
558
|
+
A profile is a collection of requirements and remediations that define a specific
|
|
559
|
+
SVG conformance standard. Profiles are defined in YAML configuration files and are
|
|
560
|
+
loaded dynamically at runtime.
|
|
561
|
+
|
|
562
|
+
Notice that there are requirement violations that cannot be automatically
|
|
563
|
+
remediated. For example, if an SVG uses a forbidden element, the remediation may
|
|
564
|
+
simply remove it, which could lead to loss of important content.
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
==== Requirements
|
|
568
|
+
|
|
569
|
+
An SvgConform requirement is a specific validation check that determines if an SVG
|
|
570
|
+
document meets certain criteria. Requirements are implemented as classes that inherit
|
|
571
|
+
from `SvgConform::Requirements::BaseRequirement`.
|
|
572
|
+
|
|
573
|
+
Each requirement class focuses on a single concern implemented using
|
|
574
|
+
XML tree traversal and validation logic.
|
|
575
|
+
|
|
576
|
+
Every requirement check can be configured with specific parameters to fine-tune
|
|
577
|
+
its behavior.
|
|
578
|
+
|
|
579
|
+
Profiles can include multiple requirements to cover various aspects of SVG
|
|
580
|
+
conformance.
|
|
581
|
+
|
|
582
|
+
==== Remediations
|
|
583
|
+
|
|
584
|
+
An SvgConform remediation is an automatic fixing action that can be applied to
|
|
585
|
+
an SVG document to resolve one or more requirement failures. Remediations are
|
|
586
|
+
implemented as classes that inherit from `SvgConform::Remediations::BaseRemediation`.
|
|
587
|
+
|
|
588
|
+
Each remediation class focuses on a specific fixing action implemented using
|
|
589
|
+
XML tree manipulation and editing.
|
|
590
|
+
|
|
591
|
+
Every remediation can be configured with specific parameters to customize its
|
|
592
|
+
behavior. A remediation can target one or more specific requirements through
|
|
593
|
+
configuration options.
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
[[command_line_interface]]
|
|
598
|
+
== Command line interface
|
|
599
|
+
|
|
600
|
+
=== General
|
|
601
|
+
|
|
602
|
+
The `svg_conform` command provides a comprehensive CLI for validation and fixing.
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
=== `svg_conform profiles`
|
|
606
|
+
|
|
607
|
+
The `profiles` command lists all available SVG profiles included in SvgConform.
|
|
608
|
+
|
|
609
|
+
Syntax:
|
|
610
|
+
|
|
611
|
+
[source,bash]
|
|
612
|
+
----
|
|
613
|
+
svg_conform profiles [OPTIONS]
|
|
614
|
+
|
|
615
|
+
Options:
|
|
616
|
+
-v, --verbose Show detailed profile information
|
|
617
|
+
----
|
|
618
|
+
|
|
619
|
+
[example]
|
|
620
|
+
====
|
|
621
|
+
[source,bash]
|
|
622
|
+
----
|
|
623
|
+
# List all profiles
|
|
624
|
+
$ svg_conform profiles
|
|
625
|
+
|
|
626
|
+
Available SVG Profiles
|
|
627
|
+
========================================
|
|
628
|
+
|
|
629
|
+
╭──────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
|
630
|
+
│ Profile │ Description │
|
|
631
|
+
├──────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
632
|
+
│ base │ Base SVG validation profile with common requirements │
|
|
633
|
+
│ lucid_fix │ Lucid SVG Fix Profile - Removes invalid use element references and namespace attributes from Lucid-generated SVGs │
|
|
634
|
+
│ metanorma │ Metanorma SVG Profile - SVG requirements for Metanorma technical documents with embedded resources │
|
|
635
|
+
│ no_external_css │ Security-focused profile that disallows external CSS references │
|
|
636
|
+
│ svg_1_2_rfc │ SVG 1.2 RFC Profile (RFC 7996) - Black and white diagrams for technical documents │
|
|
637
|
+
│ svg_1_2_rfc_with_rdf │ SVG 1.2 RFC Profile with RDF metadata support - Allows RDF/Dublin Core metadata in SVG files │
|
|
638
|
+
╰──────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
639
|
+
----
|
|
640
|
+
====
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
=== `svg_conform check`
|
|
645
|
+
|
|
646
|
+
The `check` command validates SVG files against a specified profile and optionally
|
|
647
|
+
applies automatic remediations. It supports single files, multiple files via shell
|
|
648
|
+
glob expansion, and directory scanning.
|
|
649
|
+
|
|
650
|
+
Syntax:
|
|
651
|
+
|
|
652
|
+
[source,bash]
|
|
653
|
+
----
|
|
654
|
+
svg_conform check [*FILES] [OPTIONS]
|
|
655
|
+
svg_conform check --directory PATH [OPTIONS]
|
|
656
|
+
|
|
657
|
+
Required Options:
|
|
658
|
+
-p, --profile PROFILE Profile to validate against
|
|
659
|
+
|
|
660
|
+
Input Options:
|
|
661
|
+
-d, --directory PATH Directory to scan recursively for SVG files
|
|
662
|
+
|
|
663
|
+
Remediation Options:
|
|
664
|
+
-f, --fix Enable automatic remediation
|
|
665
|
+
--output-dir DIR Output directory for remediated files (required for multi-file)
|
|
666
|
+
--in-place Replace original files (requires --force)
|
|
667
|
+
--force Confirm destructive operations
|
|
668
|
+
--fix-output FILE Output file for single file mode (default: FILE.fixed.svg)
|
|
669
|
+
|
|
670
|
+
Reporting Options:
|
|
671
|
+
--format FORMAT Output format for single file: table, yaml, json (default: table)
|
|
672
|
+
-o, --output FILE Output file for single file mode
|
|
673
|
+
--report-format FORMAT Batch report format: json, yaml
|
|
674
|
+
--report-output FILE Save detailed batch report to file
|
|
675
|
+
--manifest FILE Manifest file path (default: manifest.json with --fix)
|
|
676
|
+
-q, --quiet Suppress per-file output, show summary only
|
|
677
|
+
-v, --verbose Show detailed progress
|
|
678
|
+
----
|
|
679
|
+
|
|
680
|
+
The check command supports three operational modes:
|
|
681
|
+
|
|
682
|
+
**Single File Mode:**
|
|
683
|
+
|
|
684
|
+
Validates a single SVG file and outputs a detailed validation report.
|
|
685
|
+
|
|
686
|
+
[source,bash]
|
|
687
|
+
----
|
|
688
|
+
# Basic validation
|
|
689
|
+
svg_conform check file.svg -p metanorma
|
|
690
|
+
|
|
691
|
+
# With remediation
|
|
692
|
+
svg_conform check file.svg -p metanorma -f --fix-output fixed.svg
|
|
693
|
+
|
|
694
|
+
# Output YAML report
|
|
695
|
+
svg_conform check file.svg -p metanorma --format yaml -o report.yaml
|
|
696
|
+
----
|
|
697
|
+
|
|
698
|
+
**Multiple Files Mode (Shell Glob):**
|
|
699
|
+
|
|
700
|
+
Validates multiple files specified via shell glob patterns. The shell expands
|
|
701
|
+
patterns like `*.svg` before passing to the command.
|
|
702
|
+
|
|
703
|
+
[source,bash]
|
|
704
|
+
----
|
|
705
|
+
# Validate all SVG files in current directory
|
|
706
|
+
svg_conform check *.svg -p metanorma
|
|
707
|
+
|
|
708
|
+
# Validate with pattern matching
|
|
709
|
+
svg_conform check images/*/*.svg -p metanorma
|
|
710
|
+
|
|
711
|
+
# Fix multiple files
|
|
712
|
+
svg_conform check *.svg -p metanorma -f --output-dir fixed/
|
|
713
|
+
|
|
714
|
+
# With JSON batch report
|
|
715
|
+
svg_conform check *.svg -p metanorma --report-format json --report-output report.json
|
|
716
|
+
----
|
|
717
|
+
|
|
718
|
+
**Directory Mode:**
|
|
719
|
+
|
|
720
|
+
Recursively scans a directory for all SVG files using the `--directory` or `-d` flag.
|
|
721
|
+
|
|
722
|
+
[source,bash]
|
|
723
|
+
----
|
|
724
|
+
# Scan directory and validate
|
|
725
|
+
svg_conform check -d images/ -p metanorma
|
|
726
|
+
|
|
727
|
+
# Scan and remediate to new directory
|
|
728
|
+
svg_conform check -d images/ -p metanorma -f --output-dir fixed/
|
|
729
|
+
|
|
730
|
+
# Replace files in place (requires confirmation)
|
|
731
|
+
svg_conform check -d images/ -p metanorma -f --in-place --force
|
|
732
|
+
|
|
733
|
+
# Quiet mode with detailed JSON report
|
|
734
|
+
svg_conform check -d images/ -p metanorma -f --output-dir fixed/ --quiet \
|
|
735
|
+
--report-format json --report-output report.json
|
|
736
|
+
|
|
737
|
+
# With custom manifest file
|
|
738
|
+
svg_conform check -d images/ -p metanorma -f --output-dir fixed/ --manifest mappings.json
|
|
739
|
+
----
|
|
740
|
+
|
|
741
|
+
**Batch Report Format:**
|
|
742
|
+
|
|
743
|
+
When processing multiple files or directories, a batch summary is displayed:
|
|
744
|
+
|
|
745
|
+
[source]
|
|
746
|
+
----
|
|
747
|
+
BATCH VALIDATION SUMMARY
|
|
748
|
+
Directory: /path/to/images
|
|
749
|
+
Profile: metanorma
|
|
750
|
+
Files processed: 56
|
|
751
|
+
Valid before: 0
|
|
752
|
+
Remediated: 56
|
|
753
|
+
Valid after: 56
|
|
754
|
+
Failed: 0
|
|
755
|
+
Success rate: 100.0%
|
|
756
|
+
Manifest written to manifest.json
|
|
757
|
+
----
|
|
758
|
+
|
|
759
|
+
If `--report-format` is specified, a detailed report is generated in JSON or
|
|
760
|
+
YAML format using lutaml-model serialization:
|
|
761
|
+
|
|
762
|
+
[source,json]
|
|
763
|
+
----
|
|
764
|
+
{
|
|
765
|
+
"directory": "/path/to/images",
|
|
766
|
+
"profile": "metanorma",
|
|
767
|
+
"timestamp": "2025-10-12T15:36:25+08:00",
|
|
768
|
+
"total_files": 56,
|
|
769
|
+
"valid_before": 0,
|
|
770
|
+
"valid_after": 56,
|
|
771
|
+
"remediated": 56,
|
|
772
|
+
"failed": 0,
|
|
773
|
+
"success_rate": 100.0,
|
|
774
|
+
"files": [
|
|
775
|
+
{
|
|
776
|
+
"filename": "diagram.svg",
|
|
777
|
+
"original_path": "/path/to/images/diagram.svg",
|
|
778
|
+
"valid_before": false,
|
|
779
|
+
"valid_after": true,
|
|
780
|
+
"errors_before": 3,
|
|
781
|
+
"errors_after": 0,
|
|
782
|
+
"remediated_path": "/path/to/fixed/diagram.svg",
|
|
783
|
+
"status": "remediated"
|
|
784
|
+
}
|
|
785
|
+
],
|
|
786
|
+
"manifest": {
|
|
787
|
+
"/path/to/images/diagram.svg": "/path/to/fixed/diagram.svg"
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
----
|
|
791
|
+
|
|
792
|
+
**Manifest File:**
|
|
793
|
+
|
|
794
|
+
When using `--fix`, a manifest file is automatically created (or can be
|
|
795
|
+
explicitly specified with `--manifest`). The manifest maps original file paths
|
|
796
|
+
to their remediated counterparts:
|
|
797
|
+
|
|
798
|
+
[source,json]
|
|
799
|
+
----
|
|
800
|
+
{
|
|
801
|
+
"timestamp": "2025-10-12T15:00:00+08:00",
|
|
802
|
+
"profile": "metanorma",
|
|
803
|
+
"mappings": {
|
|
804
|
+
"/original/path/file1.svg": "/fixed/path/file1.svg",
|
|
805
|
+
"/original/path/file2.svg": "/fixed/path/file2.svg"
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
----
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
=== `svg_conform version`
|
|
812
|
+
|
|
813
|
+
The `version` command displays the current version of SvgConform.
|
|
814
|
+
|
|
815
|
+
Syntax:
|
|
816
|
+
|
|
817
|
+
[source,bash]
|
|
818
|
+
----
|
|
819
|
+
svg_conform version
|
|
820
|
+
----
|
|
821
|
+
|
|
822
|
+
[example]
|
|
823
|
+
[source,bash]
|
|
824
|
+
----
|
|
825
|
+
$ svg_conform version
|
|
826
|
+
SvgConform 0.1.0
|
|
827
|
+
----
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
[[ruby_api_reference]]
|
|
832
|
+
== Ruby API
|
|
833
|
+
|
|
834
|
+
=== Basic usage
|
|
835
|
+
|
|
836
|
+
[source,ruby]
|
|
837
|
+
----
|
|
838
|
+
require 'svg_conform'
|
|
839
|
+
|
|
840
|
+
# Validate a file
|
|
841
|
+
result = SvgConform.validate_file('diagram.svg', profile: :svg_1_2_rfc)
|
|
842
|
+
|
|
843
|
+
# Check validation status
|
|
844
|
+
puts "Valid: #{result.valid?}"
|
|
845
|
+
puts "Errors: #{result.errors.count}"
|
|
846
|
+
puts "Warnings: #{result.warnings.count}"
|
|
847
|
+
|
|
848
|
+
# Get detailed error information
|
|
849
|
+
result.errors.each do |error|
|
|
850
|
+
puts "#{error.rule.id}: #{error.message}"
|
|
851
|
+
puts " Element: #{error.element}" if error.element
|
|
852
|
+
puts " Location: #{error.location}" if error.location
|
|
853
|
+
end
|
|
854
|
+
----
|
|
855
|
+
|
|
856
|
+
=== Advanced usage
|
|
857
|
+
|
|
858
|
+
[source,ruby]
|
|
859
|
+
----
|
|
860
|
+
# Create validator instance
|
|
861
|
+
validator = SvgConform::Validator.new
|
|
862
|
+
|
|
863
|
+
# Validate with custom options
|
|
864
|
+
result = validator.validate_file('diagram.svg',
|
|
865
|
+
profile: :svg_1_2_rfc,
|
|
866
|
+
fix: true,
|
|
867
|
+
strict: false
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
# Access fixed document
|
|
871
|
+
if result.fixed?
|
|
872
|
+
fixed_svg = result.fixed_document.to_xml
|
|
873
|
+
File.write('diagram_fixed.svg', fixed_svg)
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
# Get profile information
|
|
877
|
+
profile_info = validator.profile_info(:svg_1_2_rfc)
|
|
878
|
+
puts "Profile: #{profile_info[:name]}"
|
|
879
|
+
puts "Description: #{profile_info[:description]}"
|
|
880
|
+
puts "Rules: #{profile_info[:rules].map { |r| r[:id] }.join(', ')}"
|
|
881
|
+
----
|
|
882
|
+
|
|
883
|
+
=== Working with loaded SVG content
|
|
884
|
+
|
|
885
|
+
[source,ruby]
|
|
886
|
+
----
|
|
887
|
+
# Parse SVG content
|
|
888
|
+
document = SvgConform::Document.from_content(svg_string)
|
|
889
|
+
|
|
890
|
+
# Access document elements
|
|
891
|
+
root = document.root
|
|
892
|
+
puts "Root element: #{root.name}"
|
|
893
|
+
puts "Namespace: #{root.namespace}"
|
|
894
|
+
|
|
895
|
+
# Find elements
|
|
896
|
+
circles = document.find_elements('circle')
|
|
897
|
+
texts = document.find_elements('text')
|
|
898
|
+
|
|
899
|
+
# Modify document
|
|
900
|
+
fixer = SvgConform::Fixer.new(document)
|
|
901
|
+
fixer.remove_element(some_element)
|
|
902
|
+
fixer.set_attribute(element, 'fill', 'black')
|
|
903
|
+
|
|
904
|
+
# Get modified XML
|
|
905
|
+
modified_svg = fixer.to_xml
|
|
906
|
+
----
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
== Configuration
|
|
910
|
+
|
|
911
|
+
=== Profile configuration
|
|
912
|
+
|
|
913
|
+
Profiles can be configured using YAML files in the `config/profiles/` directory:
|
|
914
|
+
|
|
915
|
+
[source,yaml]
|
|
916
|
+
----
|
|
917
|
+
# config/profiles/custom.yml
|
|
918
|
+
name: "Custom Profile"
|
|
919
|
+
description: "Custom SVG profile for specific requirements"
|
|
920
|
+
extends: "base" # Optional: inherit from another profile
|
|
921
|
+
|
|
922
|
+
rules:
|
|
923
|
+
- id: "namespace"
|
|
924
|
+
type: "namespace_rule"
|
|
925
|
+
config:
|
|
926
|
+
required_namespace: "http://www.w3.org/2000/svg"
|
|
927
|
+
|
|
928
|
+
- id: "allowed_elements"
|
|
929
|
+
type: "allowed_elements_rule"
|
|
930
|
+
config:
|
|
931
|
+
allowed_elements:
|
|
932
|
+
- "svg"
|
|
933
|
+
- "g"
|
|
934
|
+
- "rect"
|
|
935
|
+
- "circle"
|
|
936
|
+
- "path"
|
|
937
|
+
- "text"
|
|
938
|
+
|
|
939
|
+
- id: "color_restrictions"
|
|
940
|
+
type: "color_restrictions_rule"
|
|
941
|
+
config:
|
|
942
|
+
grayscale_only: true
|
|
943
|
+
allowed_colors:
|
|
944
|
+
- "black"
|
|
945
|
+
- "white"
|
|
946
|
+
- "gray"
|
|
947
|
+
----
|
|
948
|
+
|
|
949
|
+
=== Requirement configuration
|
|
950
|
+
|
|
951
|
+
TODO.
|
|
952
|
+
|
|
953
|
+
=== Remediation configuration
|
|
954
|
+
|
|
955
|
+
TODO.
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
== Extending SvgConform
|
|
959
|
+
|
|
960
|
+
=== Custom profiles
|
|
961
|
+
|
|
962
|
+
Create a new profile by defining a YAML configuration:
|
|
963
|
+
|
|
964
|
+
[source,yaml]
|
|
965
|
+
----
|
|
966
|
+
# config/profiles/my_organization.yml
|
|
967
|
+
profile:
|
|
968
|
+
name: "My Organization SVG Profile"
|
|
969
|
+
description: "SVG profile for internal use"
|
|
970
|
+
import: "base" # Optional: inherit from another profile
|
|
971
|
+
|
|
972
|
+
requirements:
|
|
973
|
+
- id: "namespace"
|
|
974
|
+
type: "NamespaceRequirement"
|
|
975
|
+
description: "Ensure proper SVG namespace"
|
|
976
|
+
|
|
977
|
+
- id: "custom_requirement"
|
|
978
|
+
type: "CustomRequirement"
|
|
979
|
+
description: "Validate custom elements"
|
|
980
|
+
config:
|
|
981
|
+
custom_option: "organization_value"
|
|
982
|
+
|
|
983
|
+
- id: "security_restrictions"
|
|
984
|
+
type: "NoExternalCssRequirement"
|
|
985
|
+
description: "Prevent external CSS references"
|
|
986
|
+
|
|
987
|
+
remediations:
|
|
988
|
+
- id: "fix_namespace"
|
|
989
|
+
type: "NamespaceRemediationAction"
|
|
990
|
+
description: "Add missing SVG namespace"
|
|
991
|
+
targets: ["namespace"]
|
|
992
|
+
|
|
993
|
+
- id: "fix_custom_elements"
|
|
994
|
+
type: "CustomRemediationAction"
|
|
995
|
+
description: "Fix custom element issues"
|
|
996
|
+
targets: ["custom_requirement"]
|
|
997
|
+
config:
|
|
998
|
+
default_value: "organization_default"
|
|
999
|
+
----
|
|
1000
|
+
|
|
1001
|
+
Then load the profile:
|
|
1002
|
+
|
|
1003
|
+
[source,ruby]
|
|
1004
|
+
----
|
|
1005
|
+
# Load and use the custom profile
|
|
1006
|
+
profile = SvgConform::Profile.load_from_file('config/profiles/my_organization.yml')
|
|
1007
|
+
document = SvgConform::Document.new(svg_content)
|
|
1008
|
+
result = profile.validate(document)
|
|
1009
|
+
|
|
1010
|
+
# Apply remediations if needed
|
|
1011
|
+
if !result.valid? && profile.has_remediations?
|
|
1012
|
+
engine = SvgConform::RemediationEngine.new(profile)
|
|
1013
|
+
remediation_results = engine.apply_remediations(document, result)
|
|
1014
|
+
end
|
|
1015
|
+
----
|
|
1016
|
+
|
|
1017
|
+
[[external_compliance]]
|
|
1018
|
+
== External compliance
|
|
1019
|
+
|
|
1020
|
+
=== General
|
|
1021
|
+
|
|
1022
|
+
SvgConform supports external compliance validation through compatibility testing
|
|
1023
|
+
and comparison with external SVG validation tools.
|
|
1024
|
+
|
|
1025
|
+
SvgConform provides validation report comparison capabilities that enable
|
|
1026
|
+
assessment of compatibility with external SVG validation tools. This supports
|
|
1027
|
+
migration workflows and quality assurance processes.
|
|
1028
|
+
|
|
1029
|
+
=== svgcheck
|
|
1030
|
+
|
|
1031
|
+
IETF provides the `svgcheck` tool, a Python-based SVG validator and fixer
|
|
1032
|
+
that checks SVG files against the SVG 1.2 RFC profile defined in RFC 7996.
|
|
1033
|
+
|
|
1034
|
+
SvgConform supports validation compatibility testing against the IETF Python
|
|
1035
|
+
svgcheck tool for SVG 1.2 RFC validation.
|
|
1036
|
+
|
|
1037
|
+
SvgConform includes a compatibility analysis feature that compares its
|
|
1038
|
+
validation results with those of `svgcheck`, helping users identify any
|
|
1039
|
+
discrepancies or issues.
|
|
1040
|
+
|
|
1041
|
+
IMPORTANT: As of version 2025-10-12, SvgConform's SVG 1.2 RFC profile provides a
|
|
1042
|
+
100% match in check and repair modes of svgcheck for all test files, except for
|
|
1043
|
+
the `full-tiny.svg` file, which svgcheck marks as invalid and fails to repair.
|
|
1044
|
+
|
|
1045
|
+
|
|
1046
|
+
=== svgcheck testing workflow
|
|
1047
|
+
|
|
1048
|
+
The external compliance testing workflow involves generating reference outputs
|
|
1049
|
+
from external tools and comparing validation results:
|
|
1050
|
+
|
|
1051
|
+
[source,bash]
|
|
1052
|
+
----
|
|
1053
|
+
# 1. Generate external tool outputs for reference
|
|
1054
|
+
svg_conform svgcheck generate SVGCHECK_REPO_LOCAL_PATH --mode both
|
|
1055
|
+
|
|
1056
|
+
# 2. Generate comparison reports
|
|
1057
|
+
svg_conform svgcheck compatibility --output comparison_report.json
|
|
1058
|
+
----
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
=== svgcheck compatibility architecture
|
|
1062
|
+
|
|
1063
|
+
SvgConform provides compatibility with the IETF Python svgcheck tool through a
|
|
1064
|
+
sophisticated mapping and comparison system that enables validation against the
|
|
1065
|
+
SVG 1.2 RFC profile.
|
|
1066
|
+
|
|
1067
|
+
.Architecture of svgcheck compatibility checks
|
|
1068
|
+
[source]
|
|
1069
|
+
----
|
|
1070
|
+
╭────────────────────────────────────────────────────────────────╮
|
|
1071
|
+
│ svgcheck Compatibility System │
|
|
1072
|
+
│ (SvgConform ↔ svgcheck Python tool) │
|
|
1073
|
+
├────────────────────────────────────────────────────────────────┤
|
|
1074
|
+
│ │
|
|
1075
|
+
│ ╭─────────────╮ ╭─────────────────────────────────────╮ │
|
|
1076
|
+
│ │ svgcheck │ │ YAML Mapping │ │
|
|
1077
|
+
│ │ Raw Errors │───▶│ config/svgcheck_mapping.yml │ │
|
|
1078
|
+
│ │ (Python) │ │ │ │
|
|
1079
|
+
│ ╰─────────────╯ │ • Pattern matching with regex │ │
|
|
1080
|
+
│ │ • Requirement categorization │ │
|
|
1081
|
+
│ │ • Semantic meaning extraction │ │
|
|
1082
|
+
│ │ • Unmapped error detection │ │
|
|
1083
|
+
│ ╰─────────────┬───────────────────────╯ │
|
|
1084
|
+
│ │ │
|
|
1085
|
+
│ ╭────────────────────────────────▼────────────────────────╮ │
|
|
1086
|
+
│ │ SvgcheckParser │ │
|
|
1087
|
+
│ │ │ │
|
|
1088
|
+
│ │ • Applies YAML mapping during parsing │ │
|
|
1089
|
+
│ │ • Categorizes errors by requirement │ │
|
|
1090
|
+
│ │ • Marks unmapped errors for RED display │ │
|
|
1091
|
+
│ │ • Creates properly structured ConformanceReport │ │
|
|
1092
|
+
│ ╰─────────────────────────┬───────────────────────────────╯ │
|
|
1093
|
+
│ │ │
|
|
1094
|
+
│ ▼ │
|
|
1095
|
+
│ ╭─────────────────────────────────────────────────────────╮ │
|
|
1096
|
+
│ │ Parallel Processing │ │
|
|
1097
|
+
│ │ │ │
|
|
1098
|
+
│ │ ╭─────────────────────╮ ╭─────────────────────────╮ │ │
|
|
1099
|
+
│ │ │ SvgConform │ │ svgcheck │ │ │
|
|
1100
|
+
│ │ │ Validation │ │ ConformanceReport │ │ │
|
|
1101
|
+
│ │ │ │ │ (mapped) │ │ │
|
|
1102
|
+
│ │ │ • Native Ruby │ │ • Parsed from YAML │ │ │
|
|
1103
|
+
│ │ │ • Direct profile │ │ • Requirement-mapped │ │ │
|
|
1104
|
+
│ │ │ • ConformanceReport │ │ • Compatible structure │ │ │
|
|
1105
|
+
│ │ ╰─────────────────────╯ ╰─────────────────────────╯ │ │
|
|
1106
|
+
│ ╰─────────────┬───────────────────────┬───────────────────╯ │
|
|
1107
|
+
│ │ │ │
|
|
1108
|
+
│ └───────────┬───────────┘ │
|
|
1109
|
+
│ │ │
|
|
1110
|
+
│ ╭─────────────────────────▼─────────────────────────╮ │
|
|
1111
|
+
│ │ ReportComparator │ │
|
|
1112
|
+
│ │ │ │
|
|
1113
|
+
│ │ • Direct ConformanceReport comparison │ │
|
|
1114
|
+
│ │ • Unified requirement-based display │ │
|
|
1115
|
+
│ │ • Side-by-side error mapping │ │
|
|
1116
|
+
│ │ • 🚨 RED highlighting for unmapped errors │ │
|
|
1117
|
+
│ │ • Compatibility metrics and analysis │ │
|
|
1118
|
+
│ ╰───────────────────────────────────────────────────╯ │
|
|
1119
|
+
│ │
|
|
1120
|
+
╰────────────────────────────────────────────────────────────────╯
|
|
1121
|
+
----
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
=== svgcheck compatibility commands
|
|
1125
|
+
|
|
1126
|
+
==== General
|
|
1127
|
+
|
|
1128
|
+
In order to run the compatibility commands, you need to have the `svgcheck` tool
|
|
1129
|
+
installed and accessible in your PATH.
|
|
1130
|
+
|
|
1131
|
+
NOTE: The `svgcheck` tool can be installed via `pip install svgcheck`.
|
|
1132
|
+
|
|
1133
|
+
The commands in this section provide functionality to generate svgcheck outputs
|
|
1134
|
+
for test files and perform compatibility analysis between SvgConform and svgcheck
|
|
1135
|
+
results.
|
|
1136
|
+
|
|
1137
|
+
The test files from svgcheck are included in the SvgConform repository under
|
|
1138
|
+
`spec/fixtures/svgcheck` to ensure consistent testing.
|
|
1139
|
+
|
|
1140
|
+
The mapping configuration file `config/svgcheck_mapping.yml` defines how
|
|
1141
|
+
svgcheck error messages are interpreted and mapped to SvgConform requirements.
|
|
1142
|
+
|
|
1143
|
+
The data flow steps for compatibility analysis is as follows:
|
|
1144
|
+
|
|
1145
|
+
. svgcheck outputs are generated for test files using the `svgcheck generate` command.
|
|
1146
|
+
|
|
1147
|
+
. For each test file, svgcheck outputs are generated in both check-only and
|
|
1148
|
+
repair modes through the `svgcheck generate` command, and are then parsed by the
|
|
1149
|
+
`Svgcheck::Parser` class into the `ReportGenerator` class.
|
|
1150
|
+
|
|
1151
|
+
. SvgConform validates the same test files using the SVG 1.2 RFC profile, which provides
|
|
1152
|
+
a `ConformanceReport` object.
|
|
1153
|
+
|
|
1154
|
+
. The `ReportComparator` class compares the `ConformanceReport` from SvgConform
|
|
1155
|
+
with the svgcheck `ReportGenerator` results. The `ReportComparator` handles
|
|
1156
|
+
both check-only and repair mode outputs, and maps svgcheck messages to SvgConform
|
|
1157
|
+
requirements and remediations outcomes.
|
|
1158
|
+
|
|
1159
|
+
. A detailed comparison report is generated, highlighting matches and discrepancies.
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
==== `svg_conform svgcheck compatibility`
|
|
1164
|
+
|
|
1165
|
+
The `svgcheck compatibility` command performs a comprehensive compatibility analysis
|
|
1166
|
+
between SvgConform validation results and the IETF `svgcheck` tool output.
|
|
1167
|
+
|
|
1168
|
+
[source,bash]
|
|
1169
|
+
----
|
|
1170
|
+
svg_conform svgcheck compatibility [OPTIONS] [FILE]
|
|
1171
|
+
|
|
1172
|
+
Options:
|
|
1173
|
+
-p, --profile PROFILE Profile to use (default: svg_1_2_rfc)
|
|
1174
|
+
-f, --file FILE Analyze specific file instead of all test files
|
|
1175
|
+
-o, --output FILE Output clean report to file (no color codes)
|
|
1176
|
+
-v, --verbose Verbose output
|
|
1177
|
+
----
|
|
1178
|
+
|
|
1179
|
+
[example]
|
|
1180
|
+
====
|
|
1181
|
+
[source,bash]
|
|
1182
|
+
----
|
|
1183
|
+
# Run comprehensive compatibility analysis
|
|
1184
|
+
svg_conform svgcheck compatibility
|
|
1185
|
+
|
|
1186
|
+
# Analyze specific file
|
|
1187
|
+
svg_conform svgcheck compatibility --file example.svg
|
|
1188
|
+
|
|
1189
|
+
# Generate clean report for documentation
|
|
1190
|
+
svg_conform svgcheck compatibility --output compatibility-report.md
|
|
1191
|
+
|
|
1192
|
+
# Analyze specific file and save to file
|
|
1193
|
+
svg_conform svgcheck compatibility --file example.svg --output analysis.md
|
|
1194
|
+
----
|
|
1195
|
+
====
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
==== `svg_conform svgcheck generate`
|
|
1199
|
+
|
|
1200
|
+
The `svgcheck generate` command generates svgcheck outputs for test files to
|
|
1201
|
+
facilitate compatibility analysis.
|
|
1202
|
+
|
|
1203
|
+
These files are generated in a structured output directory, with separate subdirectories
|
|
1204
|
+
for check-only and repair modes.
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
[source,bash]
|
|
1208
|
+
----
|
|
1209
|
+
Usage:
|
|
1210
|
+
svg_conform svgcheck generate SVGCHECK_REPO_PATH
|
|
1211
|
+
|
|
1212
|
+
Options:
|
|
1213
|
+
-m, [--mode=MODE] # Generation mode: check, repair, or both
|
|
1214
|
+
# Default: both
|
|
1215
|
+
# Possible values: check, repair, both
|
|
1216
|
+
[--svgcheck-exec=SVGCHECK_EXEC] # Path to svgcheck executable
|
|
1217
|
+
[--fixtures-path=FIXTURES_PATH] # Output directory (default: spec/fixtures/svgcheck)
|
|
1218
|
+
-f, [--single-file=SINGLE_FILE] # Process single file only
|
|
1219
|
+
[--force] # Overwrite existing outputs
|
|
1220
|
+
# Default: false
|
|
1221
|
+
-v, [--verbose], [--no-verbose], [--skip-verbose] # Verbose output
|
|
1222
|
+
# Default: false
|
|
1223
|
+
|
|
1224
|
+
Description:
|
|
1225
|
+
Generate svgcheck outputs for test files by running svgcheck on them.
|
|
1226
|
+
|
|
1227
|
+
SVGCHECK_REPO_PATH: Path to the svgcheck repository (e.g., svgcheck-reference)
|
|
1228
|
+
|
|
1229
|
+
By default, processes all test files in SVGCHECK_REPO_PATH/svgcheck/Tests/ and generates BOTH check and repair
|
|
1230
|
+
outputs in separate subdirectories.
|
|
1231
|
+
|
|
1232
|
+
Examples: svg_conform svgcheck generate svgcheck-reference svg_conform svgcheck generate svgcheck-reference --mode
|
|
1233
|
+
check svg_conform svgcheck generate svgcheck-reference --single-file example.svg
|
|
1234
|
+
----
|
|
1235
|
+
|
|
1236
|
+
This command provides a bridge between SvgConform and the Python svgcheck tool,
|
|
1237
|
+
enabling comprehensive compatibility testing and analysis. By default, it
|
|
1238
|
+
generates both check and repair outputs in separate subdirectories.
|
|
1239
|
+
|
|
1240
|
+
The command creates a structured output directory with separate subdirectories
|
|
1241
|
+
for different svgcheck modes:
|
|
1242
|
+
|
|
1243
|
+
[source]
|
|
1244
|
+
----
|
|
1245
|
+
spec/fixtures/svgcheck/
|
|
1246
|
+
├── check/ # Check-only outputs (validation without remediation)
|
|
1247
|
+
│ ├── file1.svg.out # Validation messages from svgcheck
|
|
1248
|
+
│ ├── file1.svg.err # Error messages from svgcheck
|
|
1249
|
+
│ └── file1.svg.code # Exit status from svgcheck
|
|
1250
|
+
└── repair/ # Repair outputs (validation + remediation)
|
|
1251
|
+
├── file1.svg.out # Validation messages from svgcheck
|
|
1252
|
+
├── file1.svg.err # Error messages from svgcheck
|
|
1253
|
+
├── file1.svg.code # Exit status from svgcheck
|
|
1254
|
+
└── file1.svg.file # Remediated SVG content
|
|
1255
|
+
----
|
|
1256
|
+
|
|
1257
|
+
Some svgcheck test files are renamed to indicate their actual type of content,
|
|
1258
|
+
which is defined in `svgcheck_generate.rb`:
|
|
1259
|
+
|
|
1260
|
+
* svgcheck `full-tiny.xml` is renamed to `full-tiny.svg`
|
|
1261
|
+
* svgcheck `rfc-svg.xml` is renamed to `rfc-svg.svg`
|
|
1262
|
+
|
|
1263
|
+
The generated outputs are used by the `compatibility` command to perform
|
|
1264
|
+
detailed comparisons between SvgConform and svgcheck validation results. The
|
|
1265
|
+
structured directory layout enables:
|
|
1266
|
+
|
|
1267
|
+
- **Targeted analysis**: Compare check-only vs repair mode behaviors
|
|
1268
|
+
- **Comprehensive testing**: Validate against both validation and remediation workflows
|
|
1269
|
+
- **Regression testing**: Track changes in svgcheck behavior over time
|
|
1270
|
+
- **Profile development**: Use svgcheck outputs as reference for profile refinement
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
There are three modes of operation for generating svgcheck outputs:
|
|
1274
|
+
|
|
1275
|
+
**Check Mode** (`--mode check`):
|
|
1276
|
+
|
|
1277
|
+
- Runs svgcheck without the `--repair` flag
|
|
1278
|
+
- Only validates SVG files and reports errors
|
|
1279
|
+
- Generates `.out`, `.err`, and `.code` files
|
|
1280
|
+
- No remediated content is produced
|
|
1281
|
+
|
|
1282
|
+
**Repair Mode** (`--mode repair`):
|
|
1283
|
+
|
|
1284
|
+
- Runs svgcheck with the `--repair` flag
|
|
1285
|
+
- Validates SVG files and generates remediated content
|
|
1286
|
+
- Generates `.out`, `.err`, `.code`, and `.file` files
|
|
1287
|
+
- The `.file` contains the remediated SVG content
|
|
1288
|
+
|
|
1289
|
+
**Both Mode** (`--mode both`, default):
|
|
1290
|
+
|
|
1291
|
+
- Runs both check and repair modes for each file
|
|
1292
|
+
- Generates complete output sets in both subdirectories
|
|
1293
|
+
- Provides comprehensive data for compatibility analysis
|
|
1294
|
+
|
|
1295
|
+
[source,bash]
|
|
1296
|
+
----
|
|
1297
|
+
# Generate both check and repair outputs for all test files
|
|
1298
|
+
svg_conform svgcheck generate /path/to/svgcheck-reference
|
|
1299
|
+
|
|
1300
|
+
# Generate only check outputs
|
|
1301
|
+
svg_conform svgcheck generate /path/to/svgcheck-reference --mode check
|
|
1302
|
+
|
|
1303
|
+
# Generate only repair outputs
|
|
1304
|
+
svg_conform svgcheck generate /path/to/svgcheck-reference --mode repair
|
|
1305
|
+
|
|
1306
|
+
# Process a single file with verbose output
|
|
1307
|
+
svg_conform svgcheck generate /path/to/svgcheck-reference --single-file example.svg --verbose
|
|
1308
|
+
|
|
1309
|
+
# Force regeneration of existing outputs
|
|
1310
|
+
svg_conform svgcheck generate /path/to/svgcheck-reference --force
|
|
1311
|
+
|
|
1312
|
+
# Use custom output directory
|
|
1313
|
+
svg_conform svgcheck generate /path/to/svgcheck-reference --fixtures-path /path/to/custom/output
|
|
1314
|
+
----
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
==== `svg_conform svgcheck compare`
|
|
1319
|
+
|
|
1320
|
+
The `svgcheck compare` command compares SvgConform validation results with existing
|
|
1321
|
+
svgcheck reports to assess compatibility.
|
|
1322
|
+
|
|
1323
|
+
This command is useful for verifying that SvgConform produces equivalent results
|
|
1324
|
+
to the IETF svgcheck tool.
|
|
1325
|
+
|
|
1326
|
+
Syntax:
|
|
1327
|
+
|
|
1328
|
+
[source,bash]
|
|
1329
|
+
----
|
|
1330
|
+
svg_conform svgcheck compare FILE [OPTIONS]
|
|
1331
|
+
|
|
1332
|
+
Options:
|
|
1333
|
+
-p, --profile PROFILE Profile to use (default: svg_1_2_rfc)
|
|
1334
|
+
--svgcheck-report FILE Path to svgcheck report (default: auto-detect)
|
|
1335
|
+
----
|
|
1336
|
+
|
|
1337
|
+
[example]
|
|
1338
|
+
====
|
|
1339
|
+
[source,bash]
|
|
1340
|
+
----
|
|
1341
|
+
# Compare with auto-detected svgcheck report
|
|
1342
|
+
$ svg_conform svgcheck compare diagram.svg -p svg_1_2_rfc
|
|
1343
|
+
|
|
1344
|
+
# Specify svgcheck report explicitly
|
|
1345
|
+
$ svg_conform svgcheck compare diagram.svg --svgcheck-report diagram.svg.svgcheck.yaml
|
|
1346
|
+
----
|
|
1347
|
+
====
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
== Testing
|
|
1351
|
+
|
|
1352
|
+
Run the test suite:
|
|
1353
|
+
|
|
1354
|
+
[source,bash]
|
|
1355
|
+
----
|
|
1356
|
+
bundle exec rspec
|
|
1357
|
+
----
|
|
1358
|
+
|
|
1359
|
+
Run specific test categories:
|
|
1360
|
+
|
|
1361
|
+
[source,bash]
|
|
1362
|
+
----
|
|
1363
|
+
# Unit tests
|
|
1364
|
+
bundle exec rspec spec/unit/
|
|
1365
|
+
|
|
1366
|
+
# Integration tests
|
|
1367
|
+
bundle exec rspec spec/integration/
|
|
1368
|
+
|
|
1369
|
+
# SVGCheck compatibility tests
|
|
1370
|
+
bundle exec rspec spec/svgcheck_compatibility_spec.rb
|
|
1371
|
+
----
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
== Changelog
|
|
1375
|
+
|
|
1376
|
+
See link:CHANGELOG.md[CHANGELOG.md] for version history and changes.
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
== Copyright and license
|
|
1380
|
+
|
|
1381
|
+
Copyright Ribose.
|
|
1382
|
+
|
|
1383
|
+
This gem is available as open source under the terms of the Ribose 2-clause BSD
|
|
1384
|
+
license.
|