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
@@ -0,0 +1,547 @@
1
+ = SVG Profiles
2
+ :toc: left
3
+ :toclevels: 3
4
+ :sectlinks:
5
+ :sectanchors:
6
+ :source-highlighter: rouge
7
+
8
+ == Overview
9
+
10
+ A **Profile** is a collection of requirements and remediations that define a specific SVG conformance standard. Profiles target specific use cases such as IETF RFC documents, web publishing, or custom organizational standards.
11
+
12
+ Each profile consists of:
13
+
14
+ * **Requirements**: Validation checks that determine if an SVG document conforms to the profile
15
+ * **Remediations**: Automatic fixes that can be applied when requirements fail
16
+ * **Configuration**: Profile-specific settings and parameters
17
+
18
+ == Available profiles
19
+
20
+ SvgConform includes 5 built-in profiles, each designed for different use cases and compliance standards.
21
+
22
+ [[svg-1-2-rfc-profile]]
23
+ === SVG 1.2 RFC profile (`:svg_1_2_rfc`)
24
+
25
+ **Purpose**: Ensures SVG documents comply with RFC 7996 for IETF technical publications.
26
+
27
+ **Target use case**: Technical diagrams, network diagrams, protocol illustrations for IETF RFCs and Internet-Drafts.
28
+
29
+ **Key Characteristics**:
30
+ * **Black and white only**: Colors restricted to grayscale per RFC 6949
31
+ * **Limited element set**: Only essential SVG elements allowed (16 total)
32
+ * **Generic fonts only**: serif, sans-serif, monospace families
33
+ * **Self-contained**: No external references permitted
34
+ * **Structured markup**: Proper namespaces and viewBox required
35
+
36
+ **Requirements**:
37
+ [source,yaml]
38
+ ----
39
+ requirements:
40
+ - allowed_elements # 16 SVG elements + specific attributes
41
+ - color_restrictions # Black, white, #000000, #ffffff only
42
+ - font_family # serif, sans-serif, monospace only
43
+ - namespace_validation # SVG namespace required
44
+ - namespace_attributes # Only SVG/XLink/XML namespaces
45
+ - viewbox_required # viewBox attribute mandatory
46
+ - style # CSS style validation
47
+ - style_promotion # Detect promotable styles
48
+ - forbidden_content # No scripts, multimedia, animation
49
+ - id_references # Valid ID references required
50
+ - link_validation # ASCII-only links
51
+ ----
52
+
53
+ See link:requirements.adoc#allowed-elements-requirement[AllowedElementsRequirement], link:requirements.adoc#color-restrictions-requirement[ColorRestrictionsRequirement], link:requirements.adoc#font-family-requirement[FontFamilyRequirement], link:requirements.adoc#namespace-requirement[NamespaceRequirement], link:requirements.adoc#namespace-attributes-requirement[NamespaceAttributesRequirement], link:requirements.adoc#viewbox-required-requirement[ViewboxRequiredRequirement], link:requirements.adoc#style-requirement[StyleRequirement], link:requirements.adoc#style-promotion-requirement[StylePromotionRequirement], link:requirements.adoc#forbidden-content-requirement[ForbiddenContentRequirement], link:requirements.adoc#id-reference-requirement[IdReferenceRequirement], and link:requirements.adoc#link-validation-requirement[LinkValidationRequirement] for detailed requirement information.
54
+
55
+ **Remediations**:
56
+ [source,yaml]
57
+ ----
58
+ remediations:
59
+ - color_conversion # Convert colors → black/white
60
+ - font_family_conversion # Map fonts → generic families
61
+ - style_promotion # Promote styles → attributes
62
+ - viewbox_generation # Add missing viewBox
63
+ ----
64
+
65
+ See link:remediation.adoc#color-remediation[ColorRemediation], link:remediation.adoc#font-remediation[FontRemediation], link:remediation.adoc#style-promotion-remediation[StylePromotionRemediation], and link:remediation.adoc#viewbox-remediation[ViewboxRemediation] for detailed remediation information.
66
+
67
+ **RFC Compliance**: RFC 7996 (SVG 1.2 specification for RFCs), RFC 6949 (monochromatic requirement)
68
+
69
+ **SVGCheck Compatibility**: 100% - Perfect error report matching with Python svgcheck tool
70
+
71
+ **RDF Metadata Handling**: Strict - RDF namespace errors are generated for user awareness but filtered for svgcheck compatibility. For permissive RDF handling, use link:#svg-1-2-rfc-with-rdf-profile[`svg_1_2_rfc_with_rdf`].
72
+
73
+ **Configuration Features**:
74
+ - `skip_foreign_namespaces: true` - Generic namespace skipping
75
+ - `allow_rdf_metadata: false` - Strict RDF validation
76
+ - Recursive structural invalidity tracking
77
+
78
+ [[svg-1-2-rfc-with-rdf-profile]]
79
+ === SVG 1.2 RFC with RDF profile (`:svg_1_2_rfc_with_rdf`)
80
+
81
+ **Purpose**: Ensures SVG documents comply with RFC 7996 while permissively allowing RDF/Dublin Core metadata.
82
+
83
+ **Target use case**: Technical diagrams exported from design tools (Inkscape, Illustrator) that embed RDF metadata, while maintaining RFC 7996 conformance for SVG content.
84
+
85
+ **Key Characteristics**:
86
+ * **Black and white only**: Colors restricted to grayscale per RFC 6949
87
+ * **Limited element set**: Only essential SVG elements allowed (16 total)
88
+ * **Generic fonts only**: serif, sans-serif, monospace families
89
+ * **Self-contained**: No external references permitted
90
+ * **RDF metadata allowed**: Silently accepts RDF/Dublin Core metadata elements
91
+ * **Structured markup**: Proper namespaces and viewBox required
92
+
93
+ **Requirements**:
94
+ [source,yaml]
95
+ ----
96
+ requirements:
97
+ - allowed_elements # With allow_rdf_metadata: true
98
+ - color_restrictions # Black, white, #000000, #ffffff only
99
+ - font_family # serif, sans-serif, monospace only
100
+ - namespace_validation # SVG namespace + RDF namespaces allowed
101
+ - namespace_attributes # SVG/XLink/XML namespaces
102
+ - viewbox_required # viewBox attribute mandatory
103
+ - forbidden_content # No scripts, multimedia, animation
104
+ - id_references # Valid ID references required
105
+ - link_validation # ASCII-only links
106
+ ----
107
+
108
+ **RDF Namespaces Supported**:
109
+ - `http://www.w3.org/1999/02/22-rdf-syntax-ns#` (RDF)
110
+ - `http://creativecommons.org/ns#` (Creative Commons)
111
+ - `http://purl.org/dc/elements/1.1/` (Dublin Core)
112
+ - `http://purl.org/dc/dcmitype/` (DC MIME types)
113
+ - `http://www.w3.org/2000/01/rdf-schema#` (RDF Schema)
114
+
115
+ **Remediations**: Same as `svg_1_2_rfc` profile
116
+
117
+ **RFC Compliance**: RFC 7996/6949 for SVG content, permissive for metadata
118
+
119
+ **When to Use**:
120
+ * Processing SVG files exported from Inkscape, Adobe Illustrator
121
+ * Accepting design tool metadata while enforcing RFC 7996
122
+ * Workflows where RDF metadata provides useful document information
123
+ * Converting design files to RFC-compliant SVGs without metadata removal
124
+
125
+ **Comparison with svg_1_2_rfc**:
126
+
127
+ [cols="2,3,3", options="header"]
128
+ |===
129
+ |Aspect |svg_1_2_rfc (Strict) |svg_1_2_rfc_with_rdf (Permissive)
130
+
131
+ |RDF Elements
132
+ |Errors generated
133
+ |Silently allowed
134
+
135
+ |Validation Focus
136
+ |Pure RFC 7996 compliance
137
+ |RFC 7996 + design tool compatibility
138
+
139
+ |Use Case
140
+ |RFC publication
141
+ |Design tool exports
142
+
143
+ |Metadata
144
+ |Rejected
145
+ |Accepted (RDF/Dublin Core)
146
+
147
+ |SVG Content
148
+ |Identical validation
149
+ |Identical validation
150
+ |===
151
+
152
+ For detailed RDF metadata configuration, see link:rdf_metadata_support.adoc[RDF Metadata Support Documentation].
153
+
154
+ [[base-profile]]
155
+ === Base profile (`:base`)
156
+
157
+ **Purpose**: Provides foundational SVG validation rules common across profiles.
158
+
159
+ **Target use case**: Starting point for custom profiles, basic SVG structure validation.
160
+
161
+ **Key Characteristics**:
162
+ * **Namespace validation**: Proper SVG namespace structure
163
+ * **Basic structural checks**: ViewBox, document hierarchy
164
+ * **Foundation for extension**: Other profiles inherit from base
165
+
166
+ **Requirements**:
167
+ [source,yaml]
168
+ ----
169
+ requirements:
170
+ - namespace_validation # SVG namespace required
171
+ - viewbox_required # viewBox recommended
172
+ - id_references # Valid references
173
+ ----
174
+
175
+ See link:requirements.adoc#namespace-requirement[NamespaceRequirement], link:requirements.adoc#viewbox-required-requirement[ViewboxRequiredRequirement], and link:requirements.adoc#id-reference-requirement[IdReferenceRequirement] for detailed requirement information.
176
+
177
+ **Remediations**:
178
+ [source,yaml]
179
+ ----
180
+ remediations:
181
+ - viewbox_generation # Add viewBox if missing
182
+ - namespace_fixes # Fix namespace issues
183
+ ----
184
+
185
+ See link:remediation.adoc#viewbox-remediation[ViewboxRemediation] and link:remediation.adoc#namespace-remediation[NamespaceRemediation] for detailed remediation information.
186
+
187
+ [[no-external-css-profile]]
188
+ === No external CSS profile (`:no_external_css`)
189
+
190
+ **Purpose**: Ensures SVG documents are completely self-contained with no external dependencies.
191
+
192
+ **Target use case**: Embedded SVG content, email attachments, security-conscious applications.
193
+
194
+ **Key Characteristics**:
195
+ * **No external references**: Blocks all external CSS, fonts, images
196
+ * **Self-contained documents**: Everything embedded within the SVG
197
+ * **Security focused**: Prevents external resource loading
198
+
199
+ **Requirements**:
200
+ [source,yaml]
201
+ ----
202
+ requirements:
203
+ - no_external_css # Block @import, external stylesheets
204
+ - link_validation # Validate all link references
205
+ ----
206
+
207
+ See link:requirements.adoc#no-external-css-requirement[NoExternalCssRequirement] and link:requirements.adoc#link-validation-requirement[LinkValidationRequirement] for detailed requirement information.
208
+
209
+ **Remediations**:
210
+ [source,yaml]
211
+ ----
212
+ remediations:
213
+ - remove_external_css # Strip external CSS references
214
+ ----
215
+
216
+ See link:remediation.adoc#no-external-css-remediation[NoExternalCssRemediation] for detailed remediation information.
217
+
218
+ **Use Cases**:
219
+ * Email newsletters with embedded SVG
220
+ * Secure document processing
221
+ * Offline applications
222
+ * Content distribution networks
223
+
224
+ [[lucid-fix-profile]]
225
+ === Lucid fix profile (`:lucid_fix`)
226
+
227
+ **Purpose**: Removes Lucid drawing application-specific metadata and attributes.
228
+
229
+ **Target use case**: Cleaning up SVG exports from Lucid (formerly LucidChart) drawing applications.
230
+
231
+ **Key Characteristics**:
232
+ * **Namespace cleanup**: Removes `lucid:` namespace attributes
233
+ * **Metadata removal**: Strips Lucid-specific drawing metadata
234
+ * **Standard SVG output**: Produces clean, standard-compliant SVG
235
+
236
+ **Requirements**:
237
+ [source,yaml]
238
+ ----
239
+ requirements:
240
+ - namespace_attributes # Detect lucid: namespace usage
241
+ ----
242
+
243
+ See link:requirements.adoc#namespace-attributes-requirement[NamespaceAttributesRequirement] for detailed requirement information.
244
+
245
+ **Remediations**:
246
+ [source,yaml]
247
+ ----
248
+ remediations:
249
+ - namespace_attribute_removal # Remove lucid:* attributes
250
+ ----
251
+
252
+ See link:remediation.adoc#namespace-attribute-remediation[NamespaceAttributeRemediation] for detailed remediation information.
253
+
254
+ **Specific Fixes**:
255
+ * Removes `xmlns:lucid` declarations
256
+ * Strips `lucid:*` attributes from elements
257
+ * Preserves document structure and appearance
258
+ * Maintains valid SVG markup
259
+
260
+ [[metanorma-profile]]
261
+ === Metanorma profile (`:metanorma`)
262
+
263
+ **Purpose**: Ensures SVG documents comply with Metanorma requirements for technical documents with embedded resources.
264
+
265
+ **Target use case**: Technical diagrams, flowcharts, and illustrations for Metanorma-generated standards documents (ISO, IEC, IETF, etc.).
266
+
267
+ **Key Characteristics**:
268
+ * **Flexible colors**: Any colors allowed (unlike RFC 7996 black/white restriction)
269
+ * **Flexible fonts**: Any font families allowed (unlike RFC 7996 generic-only restriction)
270
+ * **Flexible styles**: Any CSS styles allowed
271
+ * **Self-contained resources**: All CSS and fonts must be embedded
272
+ * **Structural compliance**: Proper namespaces and viewBox required
273
+ * **No external dependencies**: External CSS and fonts strictly prohibited
274
+
275
+ **Requirements**:
276
+ [source,yaml]
277
+ ----
278
+ requirements:
279
+ - allowed_elements # 16 SVG elements + specific attributes
280
+ - namespace_validation # SVG namespace required
281
+ - namespace_attributes # Only SVG/XLink/XML namespaces
282
+ - viewbox_required # viewBox attribute mandatory
283
+ - forbidden_content # No scripts, multimedia, animation
284
+ - id_references # Valid ID references required
285
+ - link_validation # ASCII-only links
286
+ - no_external_css # External CSS prohibited
287
+ - no_external_fonts # External fonts prohibited
288
+ ----
289
+
290
+ See link:requirements.adoc#allowed-elements-requirement[AllowedElementsRequirement], link:requirements.adoc#namespace-requirement[NamespaceRequirement], link:requirements.adoc#namespace-attributes-requirement[NamespaceAttributesRequirement], link:requirements.adoc#viewbox-required-requirement[ViewboxRequiredRequirement], link:requirements.adoc#forbidden-content-requirement[ForbiddenContentRequirement], link:requirements.adoc#id-reference-requirement[IdReferenceRequirement], link:requirements.adoc#link-validation-requirement[LinkValidationRequirement], link:requirements.adoc#no-external-css-requirement[NoExternalCssRequirement], and link:requirements.adoc#no-external-fonts-requirement[NoExternalFontsRequirement] for detailed requirement information.
291
+
292
+ **Remediations**:
293
+ [source,yaml]
294
+ ----
295
+ remediations:
296
+ - viewbox_generation # Add missing viewBox
297
+ - namespace_attribute_cleanup # Remove disallowed namespace attributes
298
+ - font_embedding # Detect external fonts (placeholder)
299
+ ----
300
+
301
+ See link:remediation.adoc#viewbox-remediation[ViewboxRemediation], link:remediation.adoc#namespace-attribute-remediation[NamespaceAttributeRemediation], and link:remediation.adoc#font-embedding-remediation[FontEmbeddingRemediation] for detailed remediation information.
302
+
303
+ **Differences from RFC 7996 Profile**:
304
+
305
+ [cols="2,3,3", options="header"]
306
+ |===
307
+ |Aspect |svg_1_2_rfc (RFC 7996) |metanorma (Metanorma)
308
+
309
+ |Colors
310
+ |Black/white only (#000, #fff)
311
+ |Any colors allowed
312
+
313
+ |Fonts
314
+ |Generic only (serif, sans-serif, monospace)
315
+ |Any fonts allowed
316
+
317
+ |CSS Styles
318
+ |Restricted property set
319
+ |Any styles allowed
320
+
321
+ |External CSS
322
+ |Implicitly prohibited
323
+ |Explicitly prohibited with requirement
324
+
325
+ |External Fonts
326
+ |Not specifically checked
327
+ |Explicitly prohibited with detection
328
+
329
+ |Use Case
330
+ |RFC publication diagrams
331
+ |Metanorma standards documents
332
+
333
+ |Target Audience
334
+ |IETF RFC authors
335
+ |ISO, IEC, NIST, ITU standards authors
336
+ |===
337
+
338
+ **External Resource Policy**:
339
+ * ❌ **External CSS**: Rejected without remediation (cannot be automatically embedded)
340
+ * ⚠️ **External Fonts**: Detected with placeholder remediation (requires manual embedding or future implementation)
341
+ * ✅ **Embedded Fonts**: Supported via data: URIs
342
+ * ✅ **Inline Styles**: Fully supported
343
+
344
+ **When to Use**:
345
+ * Processing SVG files for Metanorma documents
346
+ * Need color/styled diagrams (unlike RFC 7996)
347
+ * Require self-contained SVG (no external dependencies)
348
+ * Converting design tool exports (Lucid, Draw.io, Inkscape)
349
+ * Publishing standards documents (ISO, IEC, IETF, NIST, ITU, etc.)
350
+
351
+ **Font Embedding Status**: Detection implemented, full embedding requires additional development. External fonts are flagged as errors, manual conversion to data: URIs is currently required.
352
+
353
+ == Profile Inheritance and Customization
354
+
355
+ Profiles support inheritance through the `import` directive:
356
+
357
+ [source,yaml]
358
+ ----
359
+ # config/profiles/my_custom_profile.yml
360
+ name: "Custom Organization Profile"
361
+ description: "Extends base profile with organization rules"
362
+ import: "base" # Inherit all base profile requirements
363
+
364
+ # Add additional requirements
365
+ requirements:
366
+ - id: "custom_colors"
367
+ type: "ColorRestrictionsRequirement"
368
+ description: "Allow organization brand colors"
369
+ allowed_colors: ["black", "white", "#0066cc", "#ff6600"]
370
+
371
+ # Add specific remediations
372
+ remediations:
373
+ - id: "brand_color_conversion"
374
+ type: "ColorRemediation"
375
+ description: "Convert to brand colors"
376
+ targets: ["custom_colors"]
377
+ ----
378
+
379
+ === Configuration Structure
380
+
381
+ Profiles use a structured YAML configuration format:
382
+
383
+ [source,yaml]
384
+ ----
385
+ profile:
386
+ name: "Profile Display Name"
387
+ description: "Brief description of profile purpose"
388
+ import: "parent_profile" # Optional inheritance
389
+
390
+ requirements:
391
+ - id: "unique_requirement_id"
392
+ type: "RequirementClassName"
393
+ description: "Human-readable description"
394
+ config: # Optional configuration
395
+ parameter: "value"
396
+ another_param: true
397
+
398
+ remediations:
399
+ - id: "unique_remediation_id"
400
+ type: "RemediationClassName"
401
+ description: "Human-readable description"
402
+ targets: ["requirement_id1", "requirement_id2"] # Which requirements this remediation addresses
403
+ config: # Optional configuration
404
+ strategy: "remove"
405
+ default_value: "fallback"
406
+ ----
407
+
408
+ === Profile Selection Guide
409
+
410
+ **Choose `svg_1_2_rfc` when**:
411
+ * Creating technical diagrams for IETF documents
412
+ * Need RFC 7996/6949 compliance
413
+ * Require black and white output
414
+ * Need maximum compatibility
415
+
416
+ **Choose `no_external_css` when**:
417
+ * Embedding SVG in emails or secure contexts
418
+ * Require fully self-contained documents
419
+ * Security is a primary concern
420
+ * Offline usage is required
421
+
422
+ **Choose `lucid_fix` when**:
423
+ * Processing SVG exports from Lucid applications
424
+ * Need to remove application-specific metadata
425
+ * Want clean, standard SVG output
426
+
427
+ **Choose `base` when**:
428
+ * Building custom profiles
429
+ * Need minimal validation rules
430
+ * Want foundational structure checking
431
+ * Creating organization-specific profiles
432
+
433
+ == Custom Profiles
434
+
435
+ You can create custom profiles by defining YAML configuration files:
436
+
437
+ [source,yaml]
438
+ ----
439
+ # config/profiles/my_profile.yml
440
+ profile:
441
+ name: "My Custom Profile"
442
+ description: "Custom SVG profile for my organization"
443
+ import: "base" # Optional: inherit from another profile
444
+
445
+ requirements:
446
+ - type: "NamespaceRequirement"
447
+ id: "svg_namespace"
448
+ description: "Ensure proper SVG namespace"
449
+ config:
450
+ required_namespace: "http://www.w3.org/2000/svg"
451
+
452
+ - type: "ViewboxRequiredRequirement"
453
+ id: "viewbox_required"
454
+ description: "Require viewBox attribute"
455
+
456
+ - type: "NoExternalCssRequirement"
457
+ id: "no_external_css"
458
+ description: "Prevent external CSS references"
459
+
460
+ remediations:
461
+ - type: "NamespaceRemediationAction"
462
+ id: "fix_namespace"
463
+ description: "Add missing SVG namespace"
464
+ targets: ["svg_namespace"]
465
+
466
+ - type: "ViewboxRemediationAction"
467
+ id: "fix_viewbox"
468
+ description: "Add missing viewBox attribute"
469
+ targets: ["viewbox_required"]
470
+ ----
471
+
472
+ === Profile Loading
473
+
474
+ Profiles can be loaded in several ways:
475
+
476
+ **From built-in profiles**:
477
+ [source,ruby]
478
+ ----
479
+ # Load built-in profile by symbol
480
+ profile = SvgConform::Profile.load(:svg_1_2_rfc)
481
+
482
+ # Load built-in profile by string
483
+ profile = SvgConform::Profile.load("base")
484
+ ----
485
+
486
+ **From file**:
487
+ [source,ruby]
488
+ ----
489
+ # Load custom profile from YAML file
490
+ profile = SvgConform::Profile.load_from_file('config/profiles/my_profile.yml')
491
+ ----
492
+
493
+ **Programmatically**:
494
+ [source,ruby]
495
+ ----
496
+ # Create profile programmatically
497
+ profile = SvgConform::Profile.new(
498
+ name: "Custom Profile",
499
+ description: "Created programmatically",
500
+ requirements: [
501
+ SvgConform::Requirements::NamespaceRequirement.new(id: "namespace", description: "SVG namespace")
502
+ ],
503
+ remediations: [
504
+ SvgConform::Remediations::NamespaceRemediation.new(id: "fix_namespace", targets: ["namespace"])
505
+ ]
506
+ )
507
+ ----
508
+
509
+ === Profile Validation
510
+
511
+ Profiles are validated when loaded to ensure:
512
+
513
+ * All referenced requirement classes exist
514
+ * All referenced remediation classes exist
515
+ * Remediation targets reference valid requirement IDs
516
+ * Configuration parameters are valid for each component
517
+ * No circular dependencies in profile inheritance
518
+
519
+ == Best Practices
520
+
521
+ === Profile Design
522
+
523
+ * **Be specific**: Target a particular use case or standard
524
+ * **Use inheritance**: Build on existing profiles when possible
525
+ * **Document thoroughly**: Provide clear descriptions for all components
526
+ * **Test extensively**: Validate with representative SVG files
527
+
528
+ === Requirement Selection
529
+
530
+ * **Choose focused requirements**: Each requirement should validate one concern
531
+ * **Avoid redundancy**: Don't include overlapping requirements
532
+ * **Consider performance**: More requirements mean longer validation time
533
+ * **Think about users**: Include requirements that provide actionable feedback
534
+
535
+ === Remediation Configuration
536
+
537
+ * **Map appropriately**: Ensure remediations target the right requirements
538
+ * **Test remediation results**: Verify fixes don't break document structure
539
+ * **Provide fallbacks**: Consider what happens when remediation fails
540
+ * **Document side effects**: Note any visual or structural changes
541
+
542
+ === Profile Maintenance
543
+
544
+ * **Version your profiles**: Track changes over time
545
+ * **Test with real content**: Use actual SVG files from target use cases
546
+ * **Monitor performance**: Profile complexity affects validation speed
547
+ * **Document updates**: Maintain clear change logs for profile modifications