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.
Files changed (335) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/rake.yml +15 -0
  3. data/.github/workflows/release.yml +23 -0
  4. data/.github/workflows/svgcheck-compatibility.yml +135 -0
  5. data/.gitignore +12 -0
  6. data/.rspec +3 -0
  7. data/.rubocop.yml +13 -0
  8. data/.rubocop_todo.yml +183 -0
  9. data/CODE_OF_CONDUCT.md +132 -0
  10. data/Gemfile +14 -0
  11. data/README.adoc +1384 -0
  12. data/Rakefile +15 -0
  13. data/config/profiles/base.yml +34 -0
  14. data/config/profiles/lucid_fix.yml +37 -0
  15. data/config/profiles/metanorma.yml +212 -0
  16. data/config/profiles/no_external_css.yml +20 -0
  17. data/config/profiles/svg_1_2_rfc.yml +284 -0
  18. data/config/profiles/svg_1_2_rfc_with_rdf.yml +145 -0
  19. data/config/svgcheck_mapping.yml +180 -0
  20. data/docs/profiles.adoc +547 -0
  21. data/docs/rdf_metadata_support.adoc +212 -0
  22. data/docs/remediation.adoc +732 -0
  23. data/docs/requirements.adoc +709 -0
  24. data/examples/demo.rb +116 -0
  25. data/examples/requirements_demo.rb +240 -0
  26. data/exe/svg_conform +7 -0
  27. data/lib/svg_conform/batch_report.rb +70 -0
  28. data/lib/svg_conform/cli.rb +107 -0
  29. data/lib/svg_conform/commands/check.rb +390 -0
  30. data/lib/svg_conform/commands/profiles.rb +118 -0
  31. data/lib/svg_conform/commands/svgcheck.rb +90 -0
  32. data/lib/svg_conform/commands/svgcheck_compare.rb +92 -0
  33. data/lib/svg_conform/commands/svgcheck_compatibility.rb +43 -0
  34. data/lib/svg_conform/commands/svgcheck_generate.rb +262 -0
  35. data/lib/svg_conform/compatibility/analysis_context.rb +68 -0
  36. data/lib/svg_conform/compatibility/comparison_result.rb +147 -0
  37. data/lib/svg_conform/compatibility/compatibility_analyzer.rb +85 -0
  38. data/lib/svg_conform/compatibility/file_processor.rb +109 -0
  39. data/lib/svg_conform/compatibility/pattern_discovery.rb +319 -0
  40. data/lib/svg_conform/compatibility/report_formatter.rb +359 -0
  41. data/lib/svg_conform/compatibility/svg_analysis_engine.rb +316 -0
  42. data/lib/svg_conform/compatibility/validity_analysis.rb +252 -0
  43. data/lib/svg_conform/compatibility/xml_analysis_engine.rb +198 -0
  44. data/lib/svg_conform/compatibility_analyzer.rb +285 -0
  45. data/lib/svg_conform/conformance_report.rb +267 -0
  46. data/lib/svg_conform/constants.rb +199 -0
  47. data/lib/svg_conform/css_color.rb +262 -0
  48. data/lib/svg_conform/document.rb +203 -0
  49. data/lib/svg_conform/external_checkers/svgcheck/compatibility_engine.rb +166 -0
  50. data/lib/svg_conform/external_checkers/svgcheck/output_generator.rb +101 -0
  51. data/lib/svg_conform/external_checkers/svgcheck/parser.rb +200 -0
  52. data/lib/svg_conform/external_checkers/svgcheck/report_comparator.rb +175 -0
  53. data/lib/svg_conform/external_checkers/svgcheck/report_generator.rb +82 -0
  54. data/lib/svg_conform/external_checkers/svgcheck/validation_pipeline.rb +249 -0
  55. data/lib/svg_conform/external_checkers/svgcheck.rb +56 -0
  56. data/lib/svg_conform/external_checkers.rb +34 -0
  57. data/lib/svg_conform/fixer.rb +56 -0
  58. data/lib/svg_conform/profile.rb +164 -0
  59. data/lib/svg_conform/profiles.rb +60 -0
  60. data/lib/svg_conform/remediation_engine.rb +92 -0
  61. data/lib/svg_conform/remediation_result.rb +36 -0
  62. data/lib/svg_conform/remediation_runner.rb +225 -0
  63. data/lib/svg_conform/remediations/base_remediation.rb +165 -0
  64. data/lib/svg_conform/remediations/color_remediation.rb +226 -0
  65. data/lib/svg_conform/remediations/font_embedding_remediation.rb +145 -0
  66. data/lib/svg_conform/remediations/font_remediation.rb +122 -0
  67. data/lib/svg_conform/remediations/image_embedding_remediation.rb +154 -0
  68. data/lib/svg_conform/remediations/invalid_id_references_remediation.rb +129 -0
  69. data/lib/svg_conform/remediations/namespace_attribute_remediation.rb +244 -0
  70. data/lib/svg_conform/remediations/namespace_remediation.rb +151 -0
  71. data/lib/svg_conform/remediations/no_external_css_remediation.rb +192 -0
  72. data/lib/svg_conform/remediations/style_promotion_remediation.rb +93 -0
  73. data/lib/svg_conform/remediations/viewbox_remediation.rb +127 -0
  74. data/lib/svg_conform/remediations.rb +40 -0
  75. data/lib/svg_conform/report_comparator.rb +772 -0
  76. data/lib/svg_conform/requirements/allowed_elements_requirement.rb +367 -0
  77. data/lib/svg_conform/requirements/base_requirement.rb +98 -0
  78. data/lib/svg_conform/requirements/color_restrictions_requirement.rb +126 -0
  79. data/lib/svg_conform/requirements/element_requirement_config.rb +75 -0
  80. data/lib/svg_conform/requirements/font_family_requirement.rb +133 -0
  81. data/lib/svg_conform/requirements/forbidden_content_requirement.rb +60 -0
  82. data/lib/svg_conform/requirements/id_reference_requirement.rb +133 -0
  83. data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +132 -0
  84. data/lib/svg_conform/requirements/link_validation_requirement.rb +55 -0
  85. data/lib/svg_conform/requirements/namespace_attributes_requirement.rb +211 -0
  86. data/lib/svg_conform/requirements/namespace_requirement.rb +294 -0
  87. data/lib/svg_conform/requirements/no_external_css_requirement.rb +132 -0
  88. data/lib/svg_conform/requirements/no_external_fonts_requirement.rb +121 -0
  89. data/lib/svg_conform/requirements/no_external_images_requirement.rb +91 -0
  90. data/lib/svg_conform/requirements/style_promotion_requirement.rb +72 -0
  91. data/lib/svg_conform/requirements/style_requirement.rb +226 -0
  92. data/lib/svg_conform/requirements/viewbox_required_requirement.rb +96 -0
  93. data/lib/svg_conform/requirements.rb +49 -0
  94. data/lib/svg_conform/semantic_comparator.rb +829 -0
  95. data/lib/svg_conform/validation_context.rb +408 -0
  96. data/lib/svg_conform/validation_result.rb +146 -0
  97. data/lib/svg_conform/validator.rb +91 -0
  98. data/lib/svg_conform/version.rb +5 -0
  99. data/lib/svg_conform.rb +68 -0
  100. data/lib/tasks/fixtures.rake +321 -0
  101. data/lib/tasks/svgcheck.rake +111 -0
  102. data/reference-docs/SVG-1.2-RFC.rnc.txt +1676 -0
  103. data/reference-docs/Scalable Vector Graphics (SVG) 1.1 (Second Edition).html +40764 -0
  104. data/reference-docs/Scalable Vector Graphics (SVG) Tiny 1.2 Specification.html +44591 -0
  105. data/reference-docs/rfc7996.txt +2971 -0
  106. data/sig/svg_conform.rbs +4 -0
  107. data/spec/fixtures/allowed_elements/inputs/basic_violations.svg +21 -0
  108. data/spec/fixtures/allowed_elements/repair/basic_violations.svg +18 -0
  109. data/spec/fixtures/color_restrictions/inputs/basic_violations.svg +23 -0
  110. data/spec/fixtures/color_restrictions/repair/basic_violations.svg +23 -0
  111. data/spec/fixtures/comprehensive/inputs/multiple_violations.svg +21 -0
  112. data/spec/fixtures/comprehensive/repair/multiple_violations.svg +16 -0
  113. data/spec/fixtures/font_family/inputs/basic_violations.svg +17 -0
  114. data/spec/fixtures/font_family/repair/basic_violations.svg +17 -0
  115. data/spec/fixtures/forbidden_content/inputs/basic_violations.svg +27 -0
  116. data/spec/fixtures/forbidden_content/repair/basic_violations.svg +19 -0
  117. data/spec/fixtures/id_reference/inputs/basic_violations.svg +17 -0
  118. data/spec/fixtures/id_reference/repair/basic_violations.svg +15 -0
  119. data/spec/fixtures/link_validation/inputs/basic_violations.svg +20 -0
  120. data/spec/fixtures/link_validation/repair/basic_violations.svg +16 -0
  121. data/spec/fixtures/lucid/inputs/simple.svg +67 -0
  122. data/spec/fixtures/lucid/repair/simple.svg +63 -0
  123. data/spec/fixtures/namespace/inputs/basic_violations.svg +20 -0
  124. data/spec/fixtures/namespace/repair/basic_violations.svg +17 -0
  125. data/spec/fixtures/namespace_attributes/inputs/basic_violations.svg +16 -0
  126. data/spec/fixtures/namespace_attributes/repair/basic_violations.svg +15 -0
  127. data/spec/fixtures/no_external_css/inputs/basic_violations.svg +20 -0
  128. data/spec/fixtures/no_external_css/repair/basic_violations.svg +18 -0
  129. data/spec/fixtures/style/inputs/basic_violations.svg +22 -0
  130. data/spec/fixtures/style/repair/basic_violations.svg +22 -0
  131. data/spec/fixtures/style_promotion/inputs/basic_test.svg +15 -0
  132. data/spec/fixtures/style_promotion/repair/basic_test.svg +15 -0
  133. data/spec/fixtures/svg_1_2_rfc/inputs/allowed_elements_violations.svg +18 -0
  134. data/spec/fixtures/svg_1_2_rfc/inputs/color_restrictions_violations.svg +23 -0
  135. data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.code +1 -0
  136. data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.err +0 -0
  137. data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.out +23 -0
  138. data/spec/fixtures/svgcheck/check/IETF-test.svg.code +1 -0
  139. data/spec/fixtures/svgcheck/check/IETF-test.svg.err +0 -0
  140. data/spec/fixtures/svgcheck/check/IETF-test.svg.out +20 -0
  141. data/spec/fixtures/svgcheck/check/circle.svg.code +1 -0
  142. data/spec/fixtures/svgcheck/check/circle.svg.err +0 -0
  143. data/spec/fixtures/svgcheck/check/circle.svg.out +2 -0
  144. data/spec/fixtures/svgcheck/check/colors.svg.code +1 -0
  145. data/spec/fixtures/svgcheck/check/colors.svg.err +0 -0
  146. data/spec/fixtures/svgcheck/check/colors.svg.out +13 -0
  147. data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.code +1 -0
  148. data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.err +0 -0
  149. data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.out +76 -0
  150. data/spec/fixtures/svgcheck/check/example-dot.svg.code +1 -0
  151. data/spec/fixtures/svgcheck/check/example-dot.svg.err +0 -0
  152. data/spec/fixtures/svgcheck/check/example-dot.svg.out +11 -0
  153. data/spec/fixtures/svgcheck/check/full-tiny.svg.code +1 -0
  154. data/spec/fixtures/svgcheck/check/full-tiny.svg.err +0 -0
  155. data/spec/fixtures/svgcheck/check/full-tiny.svg.out +5835 -0
  156. data/spec/fixtures/svgcheck/check/good.svg.code +1 -0
  157. data/spec/fixtures/svgcheck/check/good.svg.err +0 -0
  158. data/spec/fixtures/svgcheck/check/good.svg.out +1 -0
  159. data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.code +1 -0
  160. data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.err +0 -0
  161. data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.out +5 -0
  162. data/spec/fixtures/svgcheck/check/malformed.svg.code +1 -0
  163. data/spec/fixtures/svgcheck/check/malformed.svg.err +0 -0
  164. data/spec/fixtures/svgcheck/check/malformed.svg.out +8 -0
  165. data/spec/fixtures/svgcheck/check/rfc-svg.svg.code +1 -0
  166. data/spec/fixtures/svgcheck/check/rfc-svg.svg.err +0 -0
  167. data/spec/fixtures/svgcheck/check/rfc-svg.svg.out +1 -0
  168. data/spec/fixtures/svgcheck/check/rfc.xml.code +1 -0
  169. data/spec/fixtures/svgcheck/check/rfc.xml.err +0 -0
  170. data/spec/fixtures/svgcheck/check/rfc.xml.out +2 -0
  171. data/spec/fixtures/svgcheck/check/rgb.svg.code +1 -0
  172. data/spec/fixtures/svgcheck/check/rgb.svg.err +0 -0
  173. data/spec/fixtures/svgcheck/check/rgb.svg.out +9 -0
  174. data/spec/fixtures/svgcheck/check/svg-wordle.svg.code +1 -0
  175. data/spec/fixtures/svgcheck/check/svg-wordle.svg.err +0 -0
  176. data/spec/fixtures/svgcheck/check/svg-wordle.svg.out +508 -0
  177. data/spec/fixtures/svgcheck/check/threshold.svg.code +1 -0
  178. data/spec/fixtures/svgcheck/check/threshold.svg.err +0 -0
  179. data/spec/fixtures/svgcheck/check/threshold.svg.out +20 -0
  180. data/spec/fixtures/svgcheck/check/utf8.svg.code +1 -0
  181. data/spec/fixtures/svgcheck/check/utf8.svg.err +0 -0
  182. data/spec/fixtures/svgcheck/check/utf8.svg.out +162 -0
  183. data/spec/fixtures/svgcheck/check/viewBox-both.svg.code +1 -0
  184. data/spec/fixtures/svgcheck/check/viewBox-both.svg.err +0 -0
  185. data/spec/fixtures/svgcheck/check/viewBox-both.svg.out +4 -0
  186. data/spec/fixtures/svgcheck/check/viewBox-height.svg.code +1 -0
  187. data/spec/fixtures/svgcheck/check/viewBox-height.svg.err +0 -0
  188. data/spec/fixtures/svgcheck/check/viewBox-height.svg.out +3 -0
  189. data/spec/fixtures/svgcheck/check/viewBox-none.svg.code +1 -0
  190. data/spec/fixtures/svgcheck/check/viewBox-none.svg.err +0 -0
  191. data/spec/fixtures/svgcheck/check/viewBox-none.svg.out +3 -0
  192. data/spec/fixtures/svgcheck/check/viewBox-width.svg.code +1 -0
  193. data/spec/fixtures/svgcheck/check/viewBox-width.svg.err +0 -0
  194. data/spec/fixtures/svgcheck/check/viewBox-width.svg.out +3 -0
  195. data/spec/fixtures/svgcheck/inputs/DrawBerry-sample-2.svg +28 -0
  196. data/spec/fixtures/svgcheck/inputs/IETF-test.svg +28 -0
  197. data/spec/fixtures/svgcheck/inputs/circle.svg +3 -0
  198. data/spec/fixtures/svgcheck/inputs/colors.svg +18 -0
  199. data/spec/fixtures/svgcheck/inputs/dia-sample-svg.svg +47 -0
  200. data/spec/fixtures/svgcheck/inputs/example-dot.svg +75 -0
  201. data/spec/fixtures/svgcheck/inputs/full-tiny.svg +16194 -0
  202. data/spec/fixtures/svgcheck/inputs/good.svg +19 -0
  203. data/spec/fixtures/svgcheck/inputs/httpbis-proxy20-fig6.svg +2 -0
  204. data/spec/fixtures/svgcheck/inputs/malformed.svg +11 -0
  205. data/spec/fixtures/svgcheck/inputs/rfc-svg.svg +1028 -0
  206. data/spec/fixtures/svgcheck/inputs/rfc.xml +37 -0
  207. data/spec/fixtures/svgcheck/inputs/rgb.svg +9 -0
  208. data/spec/fixtures/svgcheck/inputs/svg-wordle.svg +330 -0
  209. data/spec/fixtures/svgcheck/inputs/threshold.svg +26 -0
  210. data/spec/fixtures/svgcheck/inputs/utf8.svg +448 -0
  211. data/spec/fixtures/svgcheck/inputs/viewBox-both.svg +3 -0
  212. data/spec/fixtures/svgcheck/inputs/viewBox-height.svg +3 -0
  213. data/spec/fixtures/svgcheck/inputs/viewBox-none.svg +3 -0
  214. data/spec/fixtures/svgcheck/inputs/viewBox-width.svg +3 -0
  215. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.code +1 -0
  216. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.err +0 -0
  217. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.file +0 -0
  218. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.out +23 -0
  219. data/spec/fixtures/svgcheck/repair/IETF-test.svg.code +1 -0
  220. data/spec/fixtures/svgcheck/repair/IETF-test.svg.err +0 -0
  221. data/spec/fixtures/svgcheck/repair/IETF-test.svg.file +29 -0
  222. data/spec/fixtures/svgcheck/repair/IETF-test.svg.out +20 -0
  223. data/spec/fixtures/svgcheck/repair/circle.svg.code +1 -0
  224. data/spec/fixtures/svgcheck/repair/circle.svg.err +0 -0
  225. data/spec/fixtures/svgcheck/repair/circle.svg.file +4 -0
  226. data/spec/fixtures/svgcheck/repair/circle.svg.out +2 -0
  227. data/spec/fixtures/svgcheck/repair/colors.svg.code +1 -0
  228. data/spec/fixtures/svgcheck/repair/colors.svg.err +0 -0
  229. data/spec/fixtures/svgcheck/repair/colors.svg.file +19 -0
  230. data/spec/fixtures/svgcheck/repair/colors.svg.out +13 -0
  231. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.code +1 -0
  232. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.err +0 -0
  233. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.file +47 -0
  234. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.out +76 -0
  235. data/spec/fixtures/svgcheck/repair/example-dot.svg.code +1 -0
  236. data/spec/fixtures/svgcheck/repair/example-dot.svg.err +0 -0
  237. data/spec/fixtures/svgcheck/repair/example-dot.svg.file +69 -0
  238. data/spec/fixtures/svgcheck/repair/example-dot.svg.out +11 -0
  239. data/spec/fixtures/svgcheck/repair/good.svg.code +1 -0
  240. data/spec/fixtures/svgcheck/repair/good.svg.err +0 -0
  241. data/spec/fixtures/svgcheck/repair/good.svg.file +0 -0
  242. data/spec/fixtures/svgcheck/repair/good.svg.out +1 -0
  243. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.code +1 -0
  244. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.err +0 -0
  245. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.file +73 -0
  246. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.out +5 -0
  247. data/spec/fixtures/svgcheck/repair/malformed.svg.code +1 -0
  248. data/spec/fixtures/svgcheck/repair/malformed.svg.err +0 -0
  249. data/spec/fixtures/svgcheck/repair/malformed.svg.file +9 -0
  250. data/spec/fixtures/svgcheck/repair/malformed.svg.out +8 -0
  251. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.code +1 -0
  252. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.err +0 -0
  253. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.file +0 -0
  254. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.out +1 -0
  255. data/spec/fixtures/svgcheck/repair/rfc.xml.code +1 -0
  256. data/spec/fixtures/svgcheck/repair/rfc.xml.err +0 -0
  257. data/spec/fixtures/svgcheck/repair/rfc.xml.file +37 -0
  258. data/spec/fixtures/svgcheck/repair/rfc.xml.out +2 -0
  259. data/spec/fixtures/svgcheck/repair/rgb.svg.code +1 -0
  260. data/spec/fixtures/svgcheck/repair/rgb.svg.err +0 -0
  261. data/spec/fixtures/svgcheck/repair/rgb.svg.file +10 -0
  262. data/spec/fixtures/svgcheck/repair/rgb.svg.out +9 -0
  263. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.code +1 -0
  264. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.err +0 -0
  265. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.file +112 -0
  266. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.out +508 -0
  267. data/spec/fixtures/svgcheck/repair/threshold.svg.code +1 -0
  268. data/spec/fixtures/svgcheck/repair/threshold.svg.err +0 -0
  269. data/spec/fixtures/svgcheck/repair/threshold.svg.file +27 -0
  270. data/spec/fixtures/svgcheck/repair/threshold.svg.out +20 -0
  271. data/spec/fixtures/svgcheck/repair/utf8.svg.code +1 -0
  272. data/spec/fixtures/svgcheck/repair/utf8.svg.err +0 -0
  273. data/spec/fixtures/svgcheck/repair/utf8.svg.file +381 -0
  274. data/spec/fixtures/svgcheck/repair/utf8.svg.out +162 -0
  275. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.code +1 -0
  276. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.err +0 -0
  277. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.file +4 -0
  278. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.out +4 -0
  279. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.code +1 -0
  280. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.err +0 -0
  281. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.file +4 -0
  282. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.out +3 -0
  283. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.code +1 -0
  284. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.err +0 -0
  285. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.file +4 -0
  286. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.out +3 -0
  287. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.code +1 -0
  288. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.err +0 -0
  289. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.file +4 -0
  290. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.out +3 -0
  291. data/spec/fixtures/viewbox_required/inputs/missing_viewbox.svg +10 -0
  292. data/spec/fixtures/viewbox_required/repair/missing_viewbox.svg +10 -0
  293. data/spec/spec_helper.rb +16 -0
  294. data/spec/svg_conform/batch_report_spec.rb +99 -0
  295. data/spec/svg_conform/commands/check_command_spec.rb +90 -0
  296. data/spec/svg_conform/commands/profiles_command_spec.rb +20 -0
  297. data/spec/svg_conform/commands/svgcheck_compare_command_spec.rb +13 -0
  298. data/spec/svg_conform/commands/svgcheck_compatibility_command_spec.rb +13 -0
  299. data/spec/svg_conform/commands/svgcheck_generate_command_spec.rb +14 -0
  300. data/spec/svg_conform/profiles/base_profile_spec.rb +42 -0
  301. data/spec/svg_conform/profiles/lucid_fix_profile_spec.rb +46 -0
  302. data/spec/svg_conform/profiles/lucid_profile_spec.rb +84 -0
  303. data/spec/svg_conform/profiles/metanorma_profile_spec.rb +62 -0
  304. data/spec/svg_conform/profiles/no_external_css_profile_spec.rb +66 -0
  305. data/spec/svg_conform/profiles/svg_1_2_rfc_profile_spec.rb +200 -0
  306. data/spec/svg_conform/profiles/svg_1_2_rfc_with_rdf_profile_spec.rb +81 -0
  307. data/spec/svg_conform/remediations/color_remediation_spec.rb +95 -0
  308. data/spec/svg_conform/remediations/font_embedding_remediation_spec.rb +20 -0
  309. data/spec/svg_conform/remediations/font_remediation_spec.rb +95 -0
  310. data/spec/svg_conform/remediations/image_embedding_remediation_spec.rb +20 -0
  311. data/spec/svg_conform/remediations/invalid_id_references_remediation_spec.rb +97 -0
  312. data/spec/svg_conform/remediations/namespace_attribute_remediation_spec.rb +97 -0
  313. data/spec/svg_conform/remediations/namespace_remediation_spec.rb +95 -0
  314. data/spec/svg_conform/remediations/no_external_css_remediation_spec.rb +97 -0
  315. data/spec/svg_conform/remediations/style_promotion_remediation_spec.rb +97 -0
  316. data/spec/svg_conform/remediations/viewbox_remediation_spec.rb +95 -0
  317. data/spec/svg_conform/requirements/allowed_elements_requirement_spec.rb +118 -0
  318. data/spec/svg_conform/requirements/color_restrictions_requirement_spec.rb +168 -0
  319. data/spec/svg_conform/requirements/font_family_requirement_spec.rb +188 -0
  320. data/spec/svg_conform/requirements/forbidden_content_requirement_spec.rb +195 -0
  321. data/spec/svg_conform/requirements/id_reference_requirement_spec.rb +78 -0
  322. data/spec/svg_conform/requirements/invalid_id_references_requirement_spec.rb +78 -0
  323. data/spec/svg_conform/requirements/link_validation_requirement_spec.rb +78 -0
  324. data/spec/svg_conform/requirements/namespace_attributes_requirement_spec.rb +86 -0
  325. data/spec/svg_conform/requirements/namespace_requirement_spec.rb +184 -0
  326. data/spec/svg_conform/requirements/no_external_css_requirement_spec.rb +78 -0
  327. data/spec/svg_conform/requirements/no_external_fonts_requirement_spec.rb +20 -0
  328. data/spec/svg_conform/requirements/no_external_images_requirement_spec.rb +20 -0
  329. data/spec/svg_conform/requirements/style_promotion_requirement_spec.rb +78 -0
  330. data/spec/svg_conform/requirements/style_requirement_spec.rb +76 -0
  331. data/spec/svg_conform/requirements/viewbox_required_requirement_spec.rb +165 -0
  332. data/spec/svg_conform_spec.rb +32 -0
  333. data/spec/svgcheck_compatibility_spec.rb +355 -0
  334. data/svg_conform.gemspec +35 -0
  335. 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.