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
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
= SVG Remediations
|
|
2
|
+
:toc: left
|
|
3
|
+
:toclevels: 3
|
|
4
|
+
:sectlinks:
|
|
5
|
+
:sectanchors:
|
|
6
|
+
:source-highlighter: rouge
|
|
7
|
+
|
|
8
|
+
== Overview
|
|
9
|
+
|
|
10
|
+
**Remediations** are automatic fixing actions that can resolve requirement failures. Each remediation targets one or more specific requirements through a mapping system.
|
|
11
|
+
|
|
12
|
+
Remediations are configured with specific parameters to customize their behavior and can be mapped to requirements using the `targets` configuration in profile YAML files.
|
|
13
|
+
|
|
14
|
+
== Remediation System
|
|
15
|
+
|
|
16
|
+
=== Targeting System
|
|
17
|
+
|
|
18
|
+
Remediations are mapped to requirements using the `targets` configuration:
|
|
19
|
+
|
|
20
|
+
[source,yaml]
|
|
21
|
+
----
|
|
22
|
+
remediations:
|
|
23
|
+
- id: "fix_invalid_colors"
|
|
24
|
+
type: "ColorRemediation"
|
|
25
|
+
description: "Convert invalid colors to black or white"
|
|
26
|
+
targets: ["color_restrictions"] # Maps to ColorRestrictionsRequirement
|
|
27
|
+
----
|
|
28
|
+
|
|
29
|
+
This mapping system allows:
|
|
30
|
+
* **Targeted fixes**: Remediations only run when their target requirements fail
|
|
31
|
+
* **Flexible configuration**: Multiple remediations can target the same requirement
|
|
32
|
+
* **Conditional application**: Remediations can be enabled/disabled per profile
|
|
33
|
+
|
|
34
|
+
=== Remediation Types
|
|
35
|
+
|
|
36
|
+
Remediations are categorized by the type of fix they apply:
|
|
37
|
+
|
|
38
|
+
**Convert**: Transform invalid content to valid alternatives
|
|
39
|
+
**Remove**: Delete non-compliant elements or attributes
|
|
40
|
+
**Add**: Insert missing required content
|
|
41
|
+
**Promote**: Change content structure while preserving meaning
|
|
42
|
+
|
|
43
|
+
== Available remediations
|
|
44
|
+
|
|
45
|
+
SvgConform provides 9 different remediation types that automatically fix validation violations.
|
|
46
|
+
|
|
47
|
+
=== Content conversion remediations
|
|
48
|
+
|
|
49
|
+
[[color-remediation]]
|
|
50
|
+
==== ColorRemediation
|
|
51
|
+
|
|
52
|
+
Converts invalid colors to allowed alternatives using the enhanced CssColor system with threshold-based conversion.
|
|
53
|
+
|
|
54
|
+
**Configuration Options**:
|
|
55
|
+
|
|
56
|
+
`conversion_strategy`:: Strategy for color conversion: `"threshold"`, `"nearest"`, or `"strict"`. Default: `"threshold"`.
|
|
57
|
+
`fallback_color`:: Default color when conversion is not possible. Default: `"black"`.
|
|
58
|
+
`preserve_transparency`:: Boolean flag to preserve alpha channel information. Default: `false`.
|
|
59
|
+
|
|
60
|
+
Configuration:
|
|
61
|
+
[source,yaml]
|
|
62
|
+
----
|
|
63
|
+
- id: "fix_colors"
|
|
64
|
+
type: "ColorRemediation"
|
|
65
|
+
description: "Convert colors to allowed equivalents"
|
|
66
|
+
targets: ["color_restrictions"]
|
|
67
|
+
config:
|
|
68
|
+
conversion_strategy: "threshold"
|
|
69
|
+
fallback_color: "black"
|
|
70
|
+
preserve_transparency: false
|
|
71
|
+
----
|
|
72
|
+
|
|
73
|
+
Where,
|
|
74
|
+
|
|
75
|
+
`targets`:: List of requirement IDs that this remediation addresses.
|
|
76
|
+
|
|
77
|
+
.Using ColorRemediation with threshold-based conversion
|
|
78
|
+
[example]
|
|
79
|
+
====
|
|
80
|
+
[source,yaml]
|
|
81
|
+
----
|
|
82
|
+
remediations:
|
|
83
|
+
- id: "color_conversion"
|
|
84
|
+
type: "ColorRemediation"
|
|
85
|
+
description: "Convert colors to black and white using RGB threshold"
|
|
86
|
+
targets: ["color_restrictions"]
|
|
87
|
+
config:
|
|
88
|
+
conversion_strategy: "threshold"
|
|
89
|
+
fallback_color: "black"
|
|
90
|
+
----
|
|
91
|
+
====
|
|
92
|
+
|
|
93
|
+
When the target ColorRestrictionsRequirement has a `black_and_white_threshold` configured, the remediation applies threshold-based conversion:
|
|
94
|
+
- RGB sum ≤ threshold → converted to `black`
|
|
95
|
+
- RGB sum > threshold → converted to `white`
|
|
96
|
+
|
|
97
|
+
**Targets**: link:requirements.adoc#color-restrictions-requirement[ColorRestrictionsRequirement] violations
|
|
98
|
+
**Remediation Type**: Convert
|
|
99
|
+
**Confidence**: Automatic
|
|
100
|
+
|
|
101
|
+
Features:
|
|
102
|
+
* **Smart color conversion** using CssColor equivalence and threshold logic
|
|
103
|
+
* **Threshold-based conversion**: When `black_and_white_threshold` is configured, applies RGB sum logic
|
|
104
|
+
* **Preserves color intent** when possible (dark → black, light → white)
|
|
105
|
+
* **Handles all color formats**: named, hex, RGB, percentage RGB, short hex, mixed formats
|
|
106
|
+
* **Case-insensitive processing**: Handles uppercase color names and hex values
|
|
107
|
+
* Updates both attributes and style properties
|
|
108
|
+
|
|
109
|
+
[[font-remediation]]
|
|
110
|
+
==== FontRemediation
|
|
111
|
+
|
|
112
|
+
Maps font families to generic alternatives.
|
|
113
|
+
|
|
114
|
+
**Configuration Options**:
|
|
115
|
+
|
|
116
|
+
`font_mapping`:: Hash mapping specific font names to generic alternatives.
|
|
117
|
+
`default_family`:: Default font family for unmapped fonts. Default: `"sans-serif"`.
|
|
118
|
+
`preserve_fallbacks`:: Boolean flag to preserve existing font fallback lists. Default: `true`.
|
|
119
|
+
`case_sensitive`:: Boolean flag for case-sensitive font name matching. Default: `false`.
|
|
120
|
+
|
|
121
|
+
Configuration:
|
|
122
|
+
[source,yaml]
|
|
123
|
+
----
|
|
124
|
+
- id: "fix_fonts"
|
|
125
|
+
type: "FontRemediation"
|
|
126
|
+
description: "Convert to generic font families"
|
|
127
|
+
targets: ["font_family"]
|
|
128
|
+
config:
|
|
129
|
+
default_family: "sans-serif"
|
|
130
|
+
preserve_fallbacks: true
|
|
131
|
+
case_sensitive: false
|
|
132
|
+
font_mapping:
|
|
133
|
+
"Arial": "sans-serif"
|
|
134
|
+
"Helvetica": "sans-serif"
|
|
135
|
+
"Times": "serif"
|
|
136
|
+
"Times New Roman": "serif"
|
|
137
|
+
"Courier": "monospace"
|
|
138
|
+
"Courier New": "monospace"
|
|
139
|
+
----
|
|
140
|
+
|
|
141
|
+
**Targets**: link:requirements.adoc#font-family-requirement[FontFamilyRequirement] violations
|
|
142
|
+
**Remediation Type**: Convert
|
|
143
|
+
**Confidence**: Automatic
|
|
144
|
+
|
|
145
|
+
Features:
|
|
146
|
+
* Configurable font family mappings
|
|
147
|
+
* Handles comma-separated font lists
|
|
148
|
+
* Updates both font-family attributes and style properties
|
|
149
|
+
* Preserves font fallback chains when configured
|
|
150
|
+
* Case-insensitive font matching
|
|
151
|
+
|
|
152
|
+
=== Element and attribute removal remediations
|
|
153
|
+
|
|
154
|
+
[[namespace-remediation]]
|
|
155
|
+
==== NamespaceRemediation
|
|
156
|
+
|
|
157
|
+
Removes invalid namespace elements and attributes.
|
|
158
|
+
|
|
159
|
+
**Configuration Options**:
|
|
160
|
+
|
|
161
|
+
`default_namespace`:: Default namespace to apply to elements. Default: `"http://www.w3.org/2000/svg"`.
|
|
162
|
+
`preserve_content`:: Boolean flag to preserve element content when removing namespace elements. Default: `false`.
|
|
163
|
+
`cleanup_declarations`:: Boolean flag to remove unused namespace declarations. Default: `true`.
|
|
164
|
+
|
|
165
|
+
Configuration:
|
|
166
|
+
[source,yaml]
|
|
167
|
+
----
|
|
168
|
+
- id: "fix_namespaces"
|
|
169
|
+
type: "NamespaceRemediation"
|
|
170
|
+
description: "Remove invalid namespace content"
|
|
171
|
+
targets: ["namespace_validation"]
|
|
172
|
+
config:
|
|
173
|
+
default_namespace: "http://www.w3.org/2000/svg"
|
|
174
|
+
preserve_content: false
|
|
175
|
+
cleanup_declarations: true
|
|
176
|
+
----
|
|
177
|
+
|
|
178
|
+
**Targets**: link:requirements.adoc#namespace-requirement[NamespaceRequirement] violations
|
|
179
|
+
**Remediation Type**: Remove
|
|
180
|
+
**Confidence**: Safe Removal
|
|
181
|
+
|
|
182
|
+
Features:
|
|
183
|
+
* **Removes invalid namespace elements** (e.g., `<custom:element>`)
|
|
184
|
+
* **Removes invalid namespace attributes** (e.g., `custom:attr`)
|
|
185
|
+
* **Preserves valid namespaces** (SVG, XLink, XML)
|
|
186
|
+
* **Cleans up namespace declarations**
|
|
187
|
+
* Optional content preservation during element removal
|
|
188
|
+
|
|
189
|
+
[[namespace-attribute-remediation]]
|
|
190
|
+
==== NamespaceAttributeRemediation
|
|
191
|
+
|
|
192
|
+
Removes attributes from disallowed namespaces.
|
|
193
|
+
|
|
194
|
+
**Configuration Options**:
|
|
195
|
+
|
|
196
|
+
`removal_strategy`:: Strategy for attribute removal: `"remove_all"` or `"selective"`. Default: `"selective"`.
|
|
197
|
+
`preserve_data`:: Boolean flag to preserve data contained in removed attributes. Default: `false`.
|
|
198
|
+
|
|
199
|
+
Configuration:
|
|
200
|
+
[source,yaml]
|
|
201
|
+
----
|
|
202
|
+
- id: "fix_namespace_attrs"
|
|
203
|
+
type: "NamespaceAttributeRemediation"
|
|
204
|
+
description: "Remove disallowed namespace attributes"
|
|
205
|
+
targets: ["namespace_attributes"]
|
|
206
|
+
config:
|
|
207
|
+
removal_strategy: "selective"
|
|
208
|
+
preserve_data: false
|
|
209
|
+
----
|
|
210
|
+
|
|
211
|
+
**Targets**: link:requirements.adoc#namespace-attributes-requirement[NamespaceAttributesRequirement] violations
|
|
212
|
+
**Remediation Type**: Remove
|
|
213
|
+
**Confidence**: Safe Removal
|
|
214
|
+
|
|
215
|
+
Features:
|
|
216
|
+
* Removes attributes from disallowed namespaces
|
|
217
|
+
* Selective removal based on namespace blacklist/whitelist
|
|
218
|
+
* Optional data preservation for removed attributes
|
|
219
|
+
* Maintains document structure integrity
|
|
220
|
+
|
|
221
|
+
[[no-external-css-remediation]]
|
|
222
|
+
==== NoExternalCssRemediation
|
|
223
|
+
|
|
224
|
+
Removes external CSS references.
|
|
225
|
+
|
|
226
|
+
**Configuration Options**:
|
|
227
|
+
|
|
228
|
+
`strategy`:: Removal strategy: `"remove_external_references"`, `"inline_external"`, or `"convert_to_internal"`. Default: `"remove_external_references"`.
|
|
229
|
+
`preserve_internal_styles`:: Boolean flag to preserve internal `<style>` elements. Default: `true`.
|
|
230
|
+
|
|
231
|
+
Configuration:
|
|
232
|
+
[source,yaml]
|
|
233
|
+
----
|
|
234
|
+
- id: "remove_external_css"
|
|
235
|
+
type: "NoExternalCssRemediation"
|
|
236
|
+
description: "Remove external CSS references"
|
|
237
|
+
targets: ["no_external_css"]
|
|
238
|
+
config:
|
|
239
|
+
strategy: "remove_external_references"
|
|
240
|
+
preserve_internal_styles: true
|
|
241
|
+
----
|
|
242
|
+
|
|
243
|
+
**Targets**: link:requirements.adoc#no-external-css-requirement[NoExternalCssRequirement] violations
|
|
244
|
+
**Remediation Type**: Remove
|
|
245
|
+
**Confidence**: Safe Removal
|
|
246
|
+
|
|
247
|
+
Features:
|
|
248
|
+
* Removes external `<link>` elements
|
|
249
|
+
* Strips `@import` statements from `<style>` elements
|
|
250
|
+
* Removes external URLs from style attributes
|
|
251
|
+
* Optional preservation of internal styles
|
|
252
|
+
* Configurable removal strategies
|
|
253
|
+
|
|
254
|
+
=== Addition remediations
|
|
255
|
+
|
|
256
|
+
[[viewbox-remediation]]
|
|
257
|
+
==== ViewboxRemediation
|
|
258
|
+
|
|
259
|
+
Adds missing viewBox attributes to root SVG elements.
|
|
260
|
+
|
|
261
|
+
**Configuration Options**:
|
|
262
|
+
|
|
263
|
+
`generation_strategy`:: Strategy for viewBox generation: `"from_dimensions"`, `"from_content"`, or `"default"`. Default: `"from_dimensions"`.
|
|
264
|
+
`default_viewbox`:: Default viewBox value when automatic generation fails. Default: `"0 0 100 100"`.
|
|
265
|
+
`preserve_existing`:: Boolean flag to preserve existing viewBox attributes. Default: `true`.
|
|
266
|
+
`auto_calculate_bounds`:: Boolean flag to calculate bounds from SVG content. Default: `false`.
|
|
267
|
+
|
|
268
|
+
Configuration:
|
|
269
|
+
[source,yaml]
|
|
270
|
+
----
|
|
271
|
+
- id: "add_viewbox"
|
|
272
|
+
type: "ViewboxRemediation"
|
|
273
|
+
description: "Add missing viewBox attributes"
|
|
274
|
+
targets: ["viewbox_required"]
|
|
275
|
+
config:
|
|
276
|
+
generation_strategy: "from_dimensions"
|
|
277
|
+
default_viewbox: "0 0 100 100"
|
|
278
|
+
preserve_existing: true
|
|
279
|
+
auto_calculate_bounds: false
|
|
280
|
+
----
|
|
281
|
+
|
|
282
|
+
**Targets**: link:requirements.adoc#viewbox-required-requirement[ViewboxRequiredRequirement] violations
|
|
283
|
+
**Remediation Type**: Add
|
|
284
|
+
**Confidence**: Safe Structural
|
|
285
|
+
|
|
286
|
+
Features:
|
|
287
|
+
* Auto-generates viewBox from width/height attributes
|
|
288
|
+
* Handles malformed viewBox values
|
|
289
|
+
* Preserves existing valid viewBox attributes
|
|
290
|
+
* Optional content-based bounds calculation
|
|
291
|
+
* Configurable fallback values
|
|
292
|
+
|
|
293
|
+
=== Style processing remediations
|
|
294
|
+
|
|
295
|
+
[[style-promotion-remediation]]
|
|
296
|
+
==== StylePromotionRemediation
|
|
297
|
+
|
|
298
|
+
Promotes CSS style properties to SVG attributes.
|
|
299
|
+
|
|
300
|
+
**Configuration Options**:
|
|
301
|
+
|
|
302
|
+
`promotable_properties`:: List of CSS properties that can be promoted to SVG attributes.
|
|
303
|
+
`preserve_style_attribute`:: Boolean flag to preserve original style attribute after promotion. Default: `false`.
|
|
304
|
+
`selective_promotion`:: Boolean flag to promote only when beneficial. Default: `true`.
|
|
305
|
+
|
|
306
|
+
Configuration:
|
|
307
|
+
[source,yaml]
|
|
308
|
+
----
|
|
309
|
+
- id: "promote_styles"
|
|
310
|
+
type: "StylePromotionRemediation"
|
|
311
|
+
description: "Promote style properties to attributes"
|
|
312
|
+
targets: ["style_promotion"]
|
|
313
|
+
config:
|
|
314
|
+
preserve_style_attribute: false
|
|
315
|
+
selective_promotion: true
|
|
316
|
+
promotable_properties:
|
|
317
|
+
- "fill"
|
|
318
|
+
- "stroke"
|
|
319
|
+
- "font-family"
|
|
320
|
+
- "font-size"
|
|
321
|
+
- "opacity"
|
|
322
|
+
----
|
|
323
|
+
|
|
324
|
+
**Targets**: link:requirements.adoc#style-promotion-requirement[StylePromotionRequirement] violations
|
|
325
|
+
**Remediation Type**: Promote
|
|
326
|
+
**Confidence**: Automatic
|
|
327
|
+
|
|
328
|
+
Features:
|
|
329
|
+
* Converts style properties to equivalent SVG attributes
|
|
330
|
+
* Improves SVG compatibility and optimization
|
|
331
|
+
* Preserves visual appearance while changing structure
|
|
332
|
+
* Configurable property selection
|
|
333
|
+
* Optional selective promotion based on benefit analysis
|
|
334
|
+
|
|
335
|
+
=== Reference fixing remediations
|
|
336
|
+
|
|
337
|
+
[[invalid-id-references-remediation]]
|
|
338
|
+
==== InvalidIdReferencesRemediation
|
|
339
|
+
|
|
340
|
+
Fixes or removes broken ID references.
|
|
341
|
+
|
|
342
|
+
**Configuration Options**:
|
|
343
|
+
|
|
344
|
+
`strategy`:: Fixing strategy: `"remove_broken_elements"`, `"remove_references"`, or `"create_placeholders"`. Default: `"remove_broken_elements"`.
|
|
345
|
+
`preserve_structure`:: Boolean flag to maintain document structure when removing elements. Default: `true`.
|
|
346
|
+
`placeholder_content`:: Content to use for placeholder elements when using `"create_placeholders"` strategy.
|
|
347
|
+
|
|
348
|
+
Configuration:
|
|
349
|
+
[source,yaml]
|
|
350
|
+
----
|
|
351
|
+
- id: "fix_broken_refs"
|
|
352
|
+
type: "InvalidIdReferencesRemediation"
|
|
353
|
+
description: "Fix broken ID references"
|
|
354
|
+
targets: ["id_references", "invalid_id_references"]
|
|
355
|
+
config:
|
|
356
|
+
strategy: "remove_broken_elements"
|
|
357
|
+
preserve_structure: true
|
|
358
|
+
placeholder_content: "<!-- Missing reference -->"
|
|
359
|
+
----
|
|
360
|
+
|
|
361
|
+
**Targets**: link:requirements.adoc#id-reference-requirement[IdReferenceRequirement], InvalidIdReferencesRequirement violations
|
|
362
|
+
**Remediation Type**: Remove
|
|
363
|
+
**Confidence**: Safe Removal
|
|
364
|
+
|
|
365
|
+
Features:
|
|
366
|
+
* Removes `<use>` elements with broken href references
|
|
367
|
+
* Removes or fixes other broken ID references
|
|
368
|
+
* Can replace with placeholder content or remove entirely
|
|
369
|
+
* Configurable fixing strategies
|
|
370
|
+
* Maintains document structural integrity
|
|
371
|
+
|
|
372
|
+
== Structural Invalidity and Descendant Skipping
|
|
373
|
+
|
|
374
|
+
SvgConform implements **structural invalidity tracking** to match svgcheck's behavior of removing invalid elements with all their children.
|
|
375
|
+
|
|
376
|
+
=== How It Works
|
|
377
|
+
|
|
378
|
+
When an element is determined to be structurally invalid (e.g., not an allowed element, or has an invalid parent-child relationship):
|
|
379
|
+
|
|
380
|
+
1. **Element marked invalid**: The element is marked as structurally invalid in the validation context
|
|
381
|
+
2. **Descendants recursively marked**: All child elements are recursively marked as invalid
|
|
382
|
+
3. **Validation skipping**: All requirements skip validation of structurally invalid nodes
|
|
383
|
+
4. **Single error reported**: Only the parent element error is reported, not separate errors for each child
|
|
384
|
+
|
|
385
|
+
=== Benefits
|
|
386
|
+
|
|
387
|
+
**Prevents Cascade Errors**:
|
|
388
|
+
- Invalid `<font>` element → 48 `<glyph>` children automatically skipped
|
|
389
|
+
- Invalid `<clipPath>` parent → all children skipped
|
|
390
|
+
- Matches svgcheck: removes element WITH all children
|
|
391
|
+
|
|
392
|
+
**Example**:
|
|
393
|
+
|
|
394
|
+
Without structural invalidity tracking:
|
|
395
|
+
```
|
|
396
|
+
ERROR: Element 'font' is not allowed as a child of 'defs'
|
|
397
|
+
ERROR: Element 'font-face' is not allowed in this profile
|
|
398
|
+
ERROR: Element 'missing-glyph' is not allowed in this profile
|
|
399
|
+
ERROR: Element 'glyph' is not allowed in this profile (x48 times)
|
|
400
|
+
Total: 51 errors
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
With structural invalidity tracking:
|
|
404
|
+
```
|
|
405
|
+
ERROR: Element 'font' is not allowed as a child of 'defs'
|
|
406
|
+
Total: 1 error
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
=== Implementation
|
|
410
|
+
|
|
411
|
+
**Marking Invalid Nodes** (in AllowedElementsRequirement):
|
|
412
|
+
```ruby
|
|
413
|
+
unless allowed_elements.include?(element_name)
|
|
414
|
+
context.add_error(...)
|
|
415
|
+
context.mark_node_structurally_invalid(node) # Marks node and all descendants
|
|
416
|
+
return
|
|
417
|
+
end
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Skipping Invalid Nodes** (in BaseRequirement):
|
|
421
|
+
```ruby
|
|
422
|
+
def should_check_node?(node, context = nil)
|
|
423
|
+
return false unless node.respond_to?(:name) && node.respond_to?(:attributes)
|
|
424
|
+
return false if context && context.node_structurally_invalid?(node)
|
|
425
|
+
true
|
|
426
|
+
end
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Recursive Descendant Marking** (in ValidationContext):
|
|
430
|
+
```ruby
|
|
431
|
+
def mark_node_structurally_invalid(node)
|
|
432
|
+
@structurally_invalid_node_ids.add(generate_node_id(node))
|
|
433
|
+
mark_descendants_invalid(node) # Recursively mark all descendants
|
|
434
|
+
end
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
=== Impact on Remediations
|
|
438
|
+
|
|
439
|
+
Remediations automatically benefit from structural invalidity tracking:
|
|
440
|
+
|
|
441
|
+
* **Fewer errors to process**: Only parent errors, not descendant errors
|
|
442
|
+
* **Cleaner error reports**: More focused, actionable error messages
|
|
443
|
+
* **Better performance**: Less validation work on invalid subtrees
|
|
444
|
+
* **Matches svgcheck**: 100% compatibility with svgcheck behavior
|
|
445
|
+
|
|
446
|
+
== Violation Types and Remediability
|
|
447
|
+
|
|
448
|
+
SvgConform categorizes violations into two main types:
|
|
449
|
+
|
|
450
|
+
=== Remediable Violations
|
|
451
|
+
|
|
452
|
+
These can be automatically fixed through remediation processing:
|
|
453
|
+
|
|
454
|
+
**ColorViolation** (`color_restrictions`):
|
|
455
|
+
* **Remediation**: Convert using CssColor equivalence system
|
|
456
|
+
* **Examples**: `red` → `black`, `#f00` → `#000000`
|
|
457
|
+
* **Confidence**: Automatic
|
|
458
|
+
|
|
459
|
+
**FontViolation** (`font_family`):
|
|
460
|
+
* **Remediation**: Map to generic font families
|
|
461
|
+
* **Examples**: `Arial` → `sans-serif`, `Times New Roman` → `serif`
|
|
462
|
+
* **Confidence**: Automatic
|
|
463
|
+
|
|
464
|
+
**ContentViolation** (`forbidden_content`):
|
|
465
|
+
* **Remediation**: Remove forbidden elements/attributes
|
|
466
|
+
* **Examples**: Remove `<script>`, `onclick` attributes
|
|
467
|
+
* **Confidence**: Safe removal
|
|
468
|
+
|
|
469
|
+
**ReferenceViolation** (`id_reference`, `link_validation`):
|
|
470
|
+
* **Remediation**: Remove broken references or elements
|
|
471
|
+
* **Examples**: Remove `<use>` with invalid href, broken links
|
|
472
|
+
* **Confidence**: Safe removal
|
|
473
|
+
|
|
474
|
+
**NamespaceViolation** (`namespace`, `namespace_attributes`):
|
|
475
|
+
* **Remediation**: Remove invalid namespace elements/attributes
|
|
476
|
+
* **Examples**: Remove `<inkscape:layer>`, `custom:attr`
|
|
477
|
+
* **Confidence**: Safe removal
|
|
478
|
+
|
|
479
|
+
**ViewboxViolation** (`viewbox_required`):
|
|
480
|
+
* **Remediation**: Add missing viewBox attributes
|
|
481
|
+
* **Examples**: Generate from width/height dimensions
|
|
482
|
+
* **Confidence**: Safe structural
|
|
483
|
+
|
|
484
|
+
**StyleViolation** (`style`, `style_promotion`):
|
|
485
|
+
* **Remediation**: Promote or convert style properties
|
|
486
|
+
* **Examples**: Move `style="fill:black"` to `fill="black"`
|
|
487
|
+
* **Confidence**: Automatic
|
|
488
|
+
|
|
489
|
+
=== Non-Remediable Violations
|
|
490
|
+
|
|
491
|
+
These require manual intervention:
|
|
492
|
+
|
|
493
|
+
**StructuralViolation**:
|
|
494
|
+
* **Examples**: Malformed XML, root element not `<svg>`, invalid document hierarchy
|
|
495
|
+
* **Reason**: Automatic fixing could break document integrity or change meaning
|
|
496
|
+
* **Solution**: Manual document restructuring required
|
|
497
|
+
|
|
498
|
+
== Configuration Best Practices
|
|
499
|
+
|
|
500
|
+
=== Remediation Configuration
|
|
501
|
+
|
|
502
|
+
**Target Mapping**:
|
|
503
|
+
[source,yaml]
|
|
504
|
+
----
|
|
505
|
+
remediations:
|
|
506
|
+
- id: "comprehensive_color_fix"
|
|
507
|
+
type: "ColorRemediation"
|
|
508
|
+
description: "Handle all color violations"
|
|
509
|
+
targets: ["color_restrictions", "style_colors"] # Multiple targets
|
|
510
|
+
----
|
|
511
|
+
|
|
512
|
+
**Strategy Selection**:
|
|
513
|
+
[source,yaml]
|
|
514
|
+
----
|
|
515
|
+
- id: "safe_id_fix"
|
|
516
|
+
type: "InvalidIdReferencesRemediation"
|
|
517
|
+
targets: ["id_references"]
|
|
518
|
+
config:
|
|
519
|
+
strategy: "remove_references" # Conservative approach
|
|
520
|
+
preserve_structure: true
|
|
521
|
+
|
|
522
|
+
- id: "aggressive_id_fix"
|
|
523
|
+
type: "InvalidIdReferencesRemediation"
|
|
524
|
+
targets: ["id_references"]
|
|
525
|
+
config:
|
|
526
|
+
strategy: "remove_broken_elements" # More thorough cleanup
|
|
527
|
+
preserve_structure: false
|
|
528
|
+
----
|
|
529
|
+
|
|
530
|
+
=== Performance Optimization
|
|
531
|
+
|
|
532
|
+
**Efficient Remediation Order**:
|
|
533
|
+
1. **Namespace cleanups** (removes invalid content early)
|
|
534
|
+
2. **Content removal** (reduces document size for subsequent processing)
|
|
535
|
+
3. **Content conversion** (processes remaining valid content)
|
|
536
|
+
4. **Structure additions** (adds missing required elements)
|
|
537
|
+
5. **Style promotion** (final optimization step)
|
|
538
|
+
|
|
539
|
+
**Remediation Grouping**:
|
|
540
|
+
[source,yaml]
|
|
541
|
+
----
|
|
542
|
+
# Group related remediations for efficiency
|
|
543
|
+
remediations:
|
|
544
|
+
- id: "namespace_cleanup"
|
|
545
|
+
type: "NamespaceRemediation"
|
|
546
|
+
targets: ["namespace_validation"]
|
|
547
|
+
- id: "namespace_attrs_cleanup"
|
|
548
|
+
type: "NamespaceAttributeRemediation"
|
|
549
|
+
targets: ["namespace_attributes"]
|
|
550
|
+
- id: "color_conversion"
|
|
551
|
+
type: "ColorRemediation"
|
|
552
|
+
targets: ["color_restrictions"]
|
|
553
|
+
----
|
|
554
|
+
|
|
555
|
+
=== Safety Configuration
|
|
556
|
+
|
|
557
|
+
**Conservative Settings**:
|
|
558
|
+
[source,yaml]
|
|
559
|
+
----
|
|
560
|
+
- id: "safe_remediation"
|
|
561
|
+
type: "NamespaceRemediation"
|
|
562
|
+
config:
|
|
563
|
+
preserve_content: true # Don't lose content
|
|
564
|
+
cleanup_declarations: false # Minimal cleanup
|
|
565
|
+
----
|
|
566
|
+
|
|
567
|
+
**Aggressive Settings**:
|
|
568
|
+
[source,yaml]
|
|
569
|
+
----
|
|
570
|
+
- id: "thorough_cleanup"
|
|
571
|
+
type: "NamespaceRemediation"
|
|
572
|
+
config:
|
|
573
|
+
preserve_content: false # Remove invalid content
|
|
574
|
+
cleanup_declarations: true # Full cleanup
|
|
575
|
+
----
|
|
576
|
+
|
|
577
|
+
== Advanced Configuration
|
|
578
|
+
|
|
579
|
+
=== Conditional Remediations
|
|
580
|
+
|
|
581
|
+
Remediations can be configured to apply conditionally based on document characteristics:
|
|
582
|
+
|
|
583
|
+
[source,yaml]
|
|
584
|
+
----
|
|
585
|
+
- id: "conditional_color_fix"
|
|
586
|
+
type: "ColorRemediation"
|
|
587
|
+
description: "Apply color conversion only to specific elements"
|
|
588
|
+
targets: ["color_restrictions"]
|
|
589
|
+
config:
|
|
590
|
+
apply_to_elements: ["rect", "circle"] # Only fix colors on these elements
|
|
591
|
+
conversion_strategy: "threshold"
|
|
592
|
+
----
|
|
593
|
+
|
|
594
|
+
=== Custom Remediation Strategies
|
|
595
|
+
|
|
596
|
+
Define custom strategies for complex remediation scenarios:
|
|
597
|
+
|
|
598
|
+
[source,yaml]
|
|
599
|
+
----
|
|
600
|
+
- id: "smart_font_mapping"
|
|
601
|
+
type: "FontRemediation"
|
|
602
|
+
targets: ["font_family"]
|
|
603
|
+
config:
|
|
604
|
+
font_mapping:
|
|
605
|
+
# Map common fonts to generic equivalents
|
|
606
|
+
"Arial": "sans-serif"
|
|
607
|
+
"Helvetica": "sans-serif"
|
|
608
|
+
"Georgia": "serif"
|
|
609
|
+
"Verdana": "sans-serif"
|
|
610
|
+
fallback_strategy: "closest_generic" # Find closest generic match
|
|
611
|
+
preserve_fallbacks: true
|
|
612
|
+
----
|
|
613
|
+
|
|
614
|
+
=== Remediation Chaining
|
|
615
|
+
|
|
616
|
+
Configure remediations to work together in sequence:
|
|
617
|
+
|
|
618
|
+
[source,yaml]
|
|
619
|
+
----
|
|
620
|
+
remediations:
|
|
621
|
+
# Step 1: Clean up namespaces
|
|
622
|
+
- id: "namespace_cleanup"
|
|
623
|
+
type: "NamespaceRemediation"
|
|
624
|
+
targets: ["namespace_validation"]
|
|
625
|
+
|
|
626
|
+
# Step 2: Remove invalid attributes (depends on step 1)
|
|
627
|
+
- id: "attribute_cleanup"
|
|
628
|
+
type: "NamespaceAttributeRemediation"
|
|
629
|
+
targets: ["namespace_attributes"]
|
|
630
|
+
depends_on: ["namespace_cleanup"]
|
|
631
|
+
|
|
632
|
+
# Step 3: Fix remaining content (depends on steps 1-2)
|
|
633
|
+
- id: "content_fixes"
|
|
634
|
+
type: "ColorRemediation"
|
|
635
|
+
targets: ["color_restrictions"]
|
|
636
|
+
depends_on: ["namespace_cleanup", "attribute_cleanup"]
|
|
637
|
+
----
|
|
638
|
+
|
|
639
|
+
== Enhanced Color System
|
|
640
|
+
|
|
641
|
+
SvgConform uses the `CssColor` class for advanced color equivalence recognition:
|
|
642
|
+
|
|
643
|
+
=== Color Equivalence Examples
|
|
644
|
+
|
|
645
|
+
[source]
|
|
646
|
+
----
|
|
647
|
+
# These are all equivalent and recognized as "white":
|
|
648
|
+
white
|
|
649
|
+
#ffffff
|
|
650
|
+
#FFFFFF
|
|
651
|
+
#fff
|
|
652
|
+
#FFF
|
|
653
|
+
rgb(255,255,255)
|
|
654
|
+
rgba(255,255,255,1.0)
|
|
655
|
+
|
|
656
|
+
# These are all equivalent and recognized as "black":
|
|
657
|
+
black
|
|
658
|
+
#000000
|
|
659
|
+
#000
|
|
660
|
+
rgb(0,0,0)
|
|
661
|
+
----
|
|
662
|
+
|
|
663
|
+
=== Color Conversion Features
|
|
664
|
+
|
|
665
|
+
* **Normalization**: All color formats converted to canonical hex
|
|
666
|
+
* **Named Color Support**: Full CSS named color palette
|
|
667
|
+
* **Case Insensitive**: Hex colors match regardless of case
|
|
668
|
+
* **Short Hex Expansion**: `#fff` automatically expands to `#ffffff`
|
|
669
|
+
* **RGB Function Parsing**: `rgb(255,0,0)` converts to `#ff0000`
|
|
670
|
+
* **Equivalence Checking**: Smart matching across all formats
|
|
671
|
+
|
|
672
|
+
Usage in color remediation:
|
|
673
|
+
[source,ruby]
|
|
674
|
+
----
|
|
675
|
+
# These will all be recognized as equivalent to "white":
|
|
676
|
+
CssColor.equivalent?("#fff", "white") # => true
|
|
677
|
+
CssColor.equivalent?("#FFFFFF", "#fff") # => true
|
|
678
|
+
CssColor.normalize("rgb(255,255,255)") # => "#ffffff"
|
|
679
|
+
CssColor.to_canonical("#fff") # => "white"
|
|
680
|
+
----
|
|
681
|
+
|
|
682
|
+
== Troubleshooting
|
|
683
|
+
|
|
684
|
+
=== Common Remediation Issues
|
|
685
|
+
|
|
686
|
+
**Target Mismatch**:
|
|
687
|
+
- Ensure remediation `targets` match requirement IDs exactly
|
|
688
|
+
- Check that target requirements are included in the same profile
|
|
689
|
+
- Verify requirement IDs are spelled correctly
|
|
690
|
+
|
|
691
|
+
**Configuration Errors**:
|
|
692
|
+
- Validate YAML syntax for remediation configuration
|
|
693
|
+
- Ensure all referenced configuration parameters exist
|
|
694
|
+
- Check parameter types match expected values
|
|
695
|
+
|
|
696
|
+
**Remediation Conflicts**:
|
|
697
|
+
- Avoid multiple remediations targeting the same content
|
|
698
|
+
- Order remediations to prevent conflicts
|
|
699
|
+
- Use conditional application when needed
|
|
700
|
+
|
|
701
|
+
=== Debugging Remediations
|
|
702
|
+
|
|
703
|
+
**Enable detailed logging**:
|
|
704
|
+
[source,yaml]
|
|
705
|
+
----
|
|
706
|
+
- id: "debug_remediation"
|
|
707
|
+
type: "ColorRemediation"
|
|
708
|
+
targets: ["color_restrictions"]
|
|
709
|
+
config:
|
|
710
|
+
debug_logging: true # Enable detailed remediation logs
|
|
711
|
+
trace_changes: true # Track all changes made
|
|
712
|
+
----
|
|
713
|
+
|
|
714
|
+
**Test remediation results**:
|
|
715
|
+
- Always validate remediated documents
|
|
716
|
+
- Check that visual appearance is preserved
|
|
717
|
+
- Verify no new validation errors are introduced
|
|
718
|
+
- Test with representative SVG files
|
|
719
|
+
|
|
720
|
+
=== Performance Troubleshooting
|
|
721
|
+
|
|
722
|
+
**Slow remediations**:
|
|
723
|
+
- Profile remediation performance with timing
|
|
724
|
+
- Check for expensive operations in configuration
|
|
725
|
+
- Consider breaking complex remediations into simpler ones
|
|
726
|
+
- Optimize target requirement selection
|
|
727
|
+
|
|
728
|
+
**Memory usage**:
|
|
729
|
+
- Monitor memory consumption during large document processing
|
|
730
|
+
- Use streaming processing for very large SVG files
|
|
731
|
+
- Consider processing documents in batches
|
|
732
|
+
- Optimize configuration data structures
|