mml 2.2.1 → 2.3.1

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 (410) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +9 -0
  3. data/.rubocop.yml +4 -0
  4. data/.rubocop_todo.yml +36 -17
  5. data/CLAUDE.md +79 -0
  6. data/Gemfile +0 -2
  7. data/README.adoc +334 -82
  8. data/Rakefile +16 -1
  9. data/lib/mml/base/content/annotation.rb +30 -0
  10. data/lib/mml/base/content/annotation_xml.rb +31 -0
  11. data/lib/mml/base/content/apply.rb +27 -0
  12. data/lib/mml/base/content/arith.rb +243 -0
  13. data/lib/mml/base/content/bind.rb +27 -0
  14. data/lib/mml/base/content/bvar.rb +20 -0
  15. data/lib/mml/base/content/calculus.rb +103 -0
  16. data/lib/mml/base/content/cbytes.rb +24 -0
  17. data/lib/mml/base/content/cerror.rb +24 -0
  18. data/lib/mml/base/content/ci.rb +77 -0
  19. data/lib/mml/base/content/cn.rb +33 -0
  20. data/lib/mml/base/content/condition.rb +20 -0
  21. data/lib/mml/base/content/constants.rb +173 -0
  22. data/lib/mml/base/content/cs.rb +22 -0
  23. data/lib/mml/base/content/csymbol.rb +79 -0
  24. data/lib/mml/base/content/declare.rb +34 -0
  25. data/lib/mml/base/content/degree.rb +20 -0
  26. data/lib/mml/base/content/elementary_functions.rb +309 -0
  27. data/lib/mml/base/content/fn.rb +25 -0
  28. data/lib/mml/base/content/functions.rb +85 -0
  29. data/lib/mml/base/content/interval.rb +24 -0
  30. data/lib/mml/base/content/inverse.rb +25 -0
  31. data/lib/mml/base/content/lambda.rb +20 -0
  32. data/lib/mml/base/content/linear_algebra.rb +122 -0
  33. data/lib/mml/base/content/logic.rb +93 -0
  34. data/lib/mml/base/content/otherwise.rb +20 -0
  35. data/lib/mml/base/content/piece.rb +20 -0
  36. data/lib/mml/base/content/piecewise.rb +20 -0
  37. data/lib/mml/base/content/relations.rb +113 -0
  38. data/lib/mml/base/content/reln.rb +19 -0
  39. data/lib/mml/base/content/semantics.rb +27 -0
  40. data/lib/mml/base/content/sep.rb +19 -0
  41. data/lib/mml/base/content/sets.rb +163 -0
  42. data/lib/mml/base/content/share.rb +24 -0
  43. data/lib/mml/base/content/statistics.rb +95 -0
  44. data/lib/mml/base/content/vector_calculus.rb +63 -0
  45. data/lib/mml/base/content_loader.rb +195 -0
  46. data/lib/mml/base/deprecated_font_attributes.rb +31 -0
  47. data/lib/mml/base/maction.rb +29 -0
  48. data/lib/mml/base/maligngroup.rb +26 -0
  49. data/lib/mml/base/malignmark.rb +26 -0
  50. data/lib/mml/base/math.rb +64 -0
  51. data/lib/mml/base/menclose.rb +27 -0
  52. data/lib/mml/base/merror.rb +25 -0
  53. data/lib/mml/base/mfenced.rb +34 -0
  54. data/lib/mml/base/mfrac.rb +35 -0
  55. data/lib/mml/base/mfraction.rb +33 -0
  56. data/lib/mml/base/mglyph.rb +44 -0
  57. data/lib/mml/base/mi.rb +37 -0
  58. data/lib/mml/base/mlabeledtr.rb +33 -0
  59. data/lib/mml/base/mlongdiv.rb +31 -0
  60. data/lib/mml/base/mmultiscripts.rb +31 -0
  61. data/lib/mml/base/mn.rb +35 -0
  62. data/lib/mml/base/mo.rb +74 -0
  63. data/lib/mml/base/mover.rb +29 -0
  64. data/lib/mml/base/mpadded.rb +35 -0
  65. data/lib/mml/base/mphantom.rb +25 -0
  66. data/lib/mml/base/mprescripts.rb +24 -0
  67. data/lib/mml/base/mroot.rb +25 -0
  68. data/lib/mml/base/mrow.rb +27 -0
  69. data/lib/mml/base/ms.rb +35 -0
  70. data/lib/mml/base/mscarries.rb +33 -0
  71. data/lib/mml/base/mscarry.rb +29 -0
  72. data/lib/mml/base/msgroup.rb +31 -0
  73. data/lib/mml/base/msline.rb +34 -0
  74. data/lib/mml/base/mspace.rb +52 -0
  75. data/lib/mml/base/msqrt.rb +25 -0
  76. data/lib/mml/base/msrow.rb +27 -0
  77. data/lib/mml/base/mstack.rb +33 -0
  78. data/lib/mml/base/mstyle.rb +185 -0
  79. data/lib/mml/base/msub.rb +27 -0
  80. data/lib/mml/base/msubsup.rb +29 -0
  81. data/lib/mml/base/msup.rb +27 -0
  82. data/lib/mml/base/mtable.rb +65 -0
  83. data/lib/mml/base/mtd.rb +35 -0
  84. data/lib/mml/base/mtext.rb +30 -0
  85. data/lib/mml/base/mtr.rb +35 -0
  86. data/lib/mml/base/munder.rb +31 -0
  87. data/lib/mml/base/munderover.rb +31 -0
  88. data/lib/mml/base/none.rb +24 -0
  89. data/lib/mml/base/semantics.rb +25 -0
  90. data/lib/mml/base/universal_presentation_attributes.rb +42 -0
  91. data/lib/mml/base/v3_common.rb +16 -0
  92. data/lib/mml/base/v3_only/operator_attrs.rb +24 -0
  93. data/lib/mml/base/v3_only/style_attrs.rb +31 -0
  94. data/lib/mml/base/v3_only/table_attrs.rb +28 -0
  95. data/lib/mml/base/v3_only.rb +11 -0
  96. data/lib/mml/base/v3_presentation_attributes.rb +15 -0
  97. data/lib/mml/base/v4_attributes.rb +16 -0
  98. data/lib/mml/base.rb +61 -0
  99. data/lib/mml/common_elements.rb +419 -0
  100. data/lib/mml/context_configuration.rb +147 -0
  101. data/lib/mml/context_options.rb +64 -0
  102. data/lib/mml/namespace.rb +10 -0
  103. data/lib/mml/v2/annotation.rb +9 -0
  104. data/lib/mml/v2/annotation_xml.rb +9 -0
  105. data/lib/mml/v2/apply.rb +9 -0
  106. data/lib/mml/v2/arith.rb +93 -0
  107. data/lib/mml/v2/bind.rb +9 -0
  108. data/lib/mml/v2/bvar.rb +9 -0
  109. data/lib/mml/v2/calculus.rb +33 -0
  110. data/lib/mml/v2/ci.rb +9 -0
  111. data/lib/mml/v2/cn.rb +9 -0
  112. data/lib/mml/v2/common_elements.rb +34 -0
  113. data/lib/mml/v2/condition.rb +9 -0
  114. data/lib/mml/v2/configuration.rb +13 -0
  115. data/lib/mml/v2/constants.rb +65 -0
  116. data/lib/mml/v2/csymbol.rb +9 -0
  117. data/lib/mml/v2/degree.rb +9 -0
  118. data/lib/mml/v2/elementary_functions.rb +121 -0
  119. data/lib/mml/v2/fn.rb +9 -0
  120. data/lib/mml/v2/functions.rb +29 -0
  121. data/lib/mml/v2/interval.rb +9 -0
  122. data/lib/mml/v2/inverse.rb +9 -0
  123. data/lib/mml/v2/lambda.rb +9 -0
  124. data/lib/mml/v2/linear_algebra.rb +41 -0
  125. data/lib/mml/v2/logic.rb +33 -0
  126. data/lib/mml/v2/maction.rb +9 -0
  127. data/lib/mml/v2/maligngroup.rb +9 -0
  128. data/lib/mml/v2/malignmark.rb +9 -0
  129. data/lib/mml/v2/math.rb +11 -0
  130. data/lib/mml/v2/menclose.rb +9 -0
  131. data/lib/mml/v2/merror.rb +9 -0
  132. data/lib/mml/v2/mfenced.rb +9 -0
  133. data/lib/mml/v2/mfrac.rb +9 -0
  134. data/lib/mml/v2/mfraction.rb +9 -0
  135. data/lib/mml/v2/mglyph.rb +9 -0
  136. data/lib/mml/v2/mi.rb +9 -0
  137. data/lib/mml/v2/mlabeledtr.rb +9 -0
  138. data/lib/mml/v2/mlongdiv.rb +9 -0
  139. data/lib/mml/v2/mmultiscripts.rb +9 -0
  140. data/lib/mml/v2/mn.rb +9 -0
  141. data/lib/mml/v2/mo.rb +10 -0
  142. data/lib/mml/v2/mover.rb +9 -0
  143. data/lib/mml/v2/mpadded.rb +9 -0
  144. data/lib/mml/v2/mphantom.rb +9 -0
  145. data/lib/mml/v2/mprescripts.rb +9 -0
  146. data/lib/mml/v2/mroot.rb +9 -0
  147. data/lib/mml/v2/mrow.rb +9 -0
  148. data/lib/mml/v2/ms.rb +9 -0
  149. data/lib/mml/v2/mscarries.rb +9 -0
  150. data/lib/mml/v2/mscarry.rb +9 -0
  151. data/lib/mml/v2/msgroup.rb +9 -0
  152. data/lib/mml/v2/msline.rb +9 -0
  153. data/lib/mml/v2/mspace.rb +9 -0
  154. data/lib/mml/v2/msqrt.rb +9 -0
  155. data/lib/mml/v2/msrow.rb +9 -0
  156. data/lib/mml/v2/mstack.rb +9 -0
  157. data/lib/mml/v2/mstyle.rb +10 -0
  158. data/lib/mml/v2/msub.rb +9 -0
  159. data/lib/mml/v2/msubsup.rb +9 -0
  160. data/lib/mml/v2/msup.rb +9 -0
  161. data/lib/mml/v2/mtable.rb +9 -0
  162. data/lib/mml/v2/mtd.rb +9 -0
  163. data/lib/mml/v2/mtext.rb +9 -0
  164. data/lib/mml/v2/mtr.rb +9 -0
  165. data/lib/mml/v2/munder.rb +9 -0
  166. data/lib/mml/v2/munderover.rb +9 -0
  167. data/lib/mml/v2/namespace.rb +7 -0
  168. data/lib/mml/v2/none.rb +9 -0
  169. data/lib/mml/v2/otherwise.rb +9 -0
  170. data/lib/mml/v2/piece.rb +9 -0
  171. data/lib/mml/v2/piecewise.rb +9 -0
  172. data/lib/mml/v2/relations.rb +41 -0
  173. data/lib/mml/v2/reln.rb +13 -0
  174. data/lib/mml/v2/semantics.rb +9 -0
  175. data/lib/mml/v2/sep.rb +9 -0
  176. data/lib/mml/v2/sets.rb +57 -0
  177. data/lib/mml/v2/statistics.rb +33 -0
  178. data/lib/mml/v2/vector_calculus.rb +21 -0
  179. data/lib/mml/v2.rb +311 -0
  180. data/lib/mml/v3/annotation.rb +10 -0
  181. data/lib/mml/v3/annotation_xml.rb +10 -0
  182. data/lib/mml/v3/apply.rb +10 -0
  183. data/lib/mml/v3/arith.rb +115 -0
  184. data/lib/mml/v3/bind.rb +10 -0
  185. data/lib/mml/v3/calculus.rb +40 -0
  186. data/lib/mml/v3/cbytes.rb +10 -0
  187. data/lib/mml/v3/cerror.rb +10 -0
  188. data/lib/mml/v3/ci.rb +10 -0
  189. data/lib/mml/v3/cn.rb +10 -0
  190. data/lib/mml/v3/common_elements.rb +42 -0
  191. data/lib/mml/v3/configuration.rb +4 -96
  192. data/lib/mml/v3/constants.rb +80 -0
  193. data/lib/mml/v3/constructs.rb +55 -0
  194. data/lib/mml/v3/cs.rb +10 -0
  195. data/lib/mml/v3/csymbol.rb +10 -0
  196. data/lib/mml/v3/deprecated_content.rb +29 -0
  197. data/lib/mml/v3/elementary_functions.rb +145 -0
  198. data/lib/mml/v3/functions.rb +35 -0
  199. data/lib/mml/v3/linear_algebra.rb +50 -0
  200. data/lib/mml/v3/logic.rb +40 -0
  201. data/lib/mml/v3/maction.rb +3 -15
  202. data/lib/mml/v3/maligngroup.rb +2 -12
  203. data/lib/mml/v3/malignmark.rb +2 -12
  204. data/lib/mml/v3/math.rb +7 -8
  205. data/lib/mml/v3/menclose.rb +3 -14
  206. data/lib/mml/v3/merror.rb +3 -12
  207. data/lib/mml/v3/mfenced.rb +3 -21
  208. data/lib/mml/v3/mfrac.rb +3 -20
  209. data/lib/mml/v3/mfraction.rb +3 -20
  210. data/lib/mml/v3/mglyph.rb +3 -38
  211. data/lib/mml/v3/mi.rb +4 -30
  212. data/lib/mml/v3/mlabeledtr.rb +2 -23
  213. data/lib/mml/v3/mlongdiv.rb +3 -18
  214. data/lib/mml/v3/mmultiscripts.rb +3 -20
  215. data/lib/mml/v3/mn.rb +4 -30
  216. data/lib/mml/v3/mo.rb +5 -78
  217. data/lib/mml/v3/mover.rb +3 -16
  218. data/lib/mml/v3/mpadded.rb +3 -22
  219. data/lib/mml/v3/mphantom.rb +3 -12
  220. data/lib/mml/v3/mprescripts.rb +2 -10
  221. data/lib/mml/v3/mroot.rb +3 -12
  222. data/lib/mml/v3/mrow.rb +4 -18
  223. data/lib/mml/v3/ms.rb +5 -36
  224. data/lib/mml/v3/mscarries.rb +3 -20
  225. data/lib/mml/v3/mscarry.rb +3 -16
  226. data/lib/mml/v3/msgroup.rb +3 -18
  227. data/lib/mml/v3/msline.rb +2 -20
  228. data/lib/mml/v3/mspace.rb +3 -50
  229. data/lib/mml/v3/msqrt.rb +3 -12
  230. data/lib/mml/v3/msrow.rb +3 -14
  231. data/lib/mml/v3/mstack.rb +3 -20
  232. data/lib/mml/v3/mstyle.rb +6 -204
  233. data/lib/mml/v3/msub.rb +3 -14
  234. data/lib/mml/v3/msubsup.rb +3 -16
  235. data/lib/mml/v3/msup.rb +3 -14
  236. data/lib/mml/v3/mtable.rb +3 -53
  237. data/lib/mml/v3/mtd.rb +3 -16
  238. data/lib/mml/v3/mtext.rb +4 -30
  239. data/lib/mml/v3/mtr.rb +2 -21
  240. data/lib/mml/v3/munder.rb +3 -18
  241. data/lib/mml/v3/munderover.rb +3 -18
  242. data/lib/mml/v3/namespace.rb +1 -4
  243. data/lib/mml/v3/none.rb +2 -10
  244. data/lib/mml/v3/relations.rb +50 -0
  245. data/lib/mml/v3/semantics.rb +3 -12
  246. data/lib/mml/v3/sets.rb +70 -0
  247. data/lib/mml/v3/statistics.rb +40 -0
  248. data/lib/mml/v3/vector_calculus.rb +25 -0
  249. data/lib/mml/v3.rb +74 -75
  250. data/lib/mml/v4/a.rb +3 -13
  251. data/lib/mml/v4/annotation.rb +10 -0
  252. data/lib/mml/v4/annotation_xml.rb +14 -0
  253. data/lib/mml/v4/apply.rb +9 -0
  254. data/lib/mml/v4/arith.rb +93 -0
  255. data/lib/mml/v4/calculus.rb +25 -0
  256. data/lib/mml/v4/cbytes.rb +9 -0
  257. data/lib/mml/v4/cerror.rb +9 -0
  258. data/lib/mml/v4/ci.rb +9 -0
  259. data/lib/mml/v4/cn.rb +9 -0
  260. data/lib/mml/v4/common_elements.rb +46 -0
  261. data/lib/mml/v4/configuration.rb +4 -97
  262. data/lib/mml/v4/constants.rb +65 -0
  263. data/lib/mml/v4/constructs.rb +49 -0
  264. data/lib/mml/v4/cs.rb +9 -0
  265. data/lib/mml/v4/csymbol.rb +9 -0
  266. data/lib/mml/v4/deprecated_content.rb +25 -0
  267. data/lib/mml/v4/elementary_functions.rb +118 -0
  268. data/lib/mml/v4/factorof.rb +9 -0
  269. data/lib/mml/v4/functions.rb +30 -0
  270. data/lib/mml/v4/limit.rb +9 -0
  271. data/lib/mml/v4/linear_algebra.rb +41 -0
  272. data/lib/mml/v4/logic.rb +33 -0
  273. data/lib/mml/v4/maction.rb +3 -19
  274. data/lib/mml/v4/maligngroup.rb +3 -17
  275. data/lib/mml/v4/malignmark.rb +3 -17
  276. data/lib/mml/v4/math.rb +4 -14
  277. data/lib/mml/v4/menclose.rb +3 -18
  278. data/lib/mml/v4/merror.rb +3 -16
  279. data/lib/mml/v4/mfenced.rb +3 -25
  280. data/lib/mml/v4/mfrac.rb +3 -24
  281. data/lib/mml/v4/mfraction.rb +3 -20
  282. data/lib/mml/v4/mglyph.rb +3 -35
  283. data/lib/mml/v4/mi.rb +4 -30
  284. data/lib/mml/v4/mlabeledtr.rb +5 -23
  285. data/lib/mml/v4/mlongdiv.rb +3 -18
  286. data/lib/mml/v4/mmultiscripts.rb +3 -24
  287. data/lib/mml/v4/mn.rb +4 -29
  288. data/lib/mml/v4/mo.rb +4 -75
  289. data/lib/mml/v4/mover.rb +3 -20
  290. data/lib/mml/v4/mpadded.rb +3 -26
  291. data/lib/mml/v4/mphantom.rb +3 -16
  292. data/lib/mml/v4/mprescripts.rb +3 -11
  293. data/lib/mml/v4/mroot.rb +3 -16
  294. data/lib/mml/v4/mrow.rb +4 -20
  295. data/lib/mml/v4/ms.rb +4 -34
  296. data/lib/mml/v4/mscarries.rb +3 -20
  297. data/lib/mml/v4/mscarry.rb +3 -16
  298. data/lib/mml/v4/msgroup.rb +3 -18
  299. data/lib/mml/v4/msline.rb +3 -21
  300. data/lib/mml/v4/mspace.rb +3 -49
  301. data/lib/mml/v4/msqrt.rb +3 -16
  302. data/lib/mml/v4/msrow.rb +3 -18
  303. data/lib/mml/v4/mstack.rb +3 -24
  304. data/lib/mml/v4/mstyle.rb +4 -186
  305. data/lib/mml/v4/msub.rb +3 -18
  306. data/lib/mml/v4/msubsup.rb +3 -20
  307. data/lib/mml/v4/msup.rb +3 -18
  308. data/lib/mml/v4/mtable.rb +3 -55
  309. data/lib/mml/v4/mtd.rb +3 -20
  310. data/lib/mml/v4/mtext.rb +4 -29
  311. data/lib/mml/v4/mtr.rb +3 -25
  312. data/lib/mml/v4/munder.rb +3 -22
  313. data/lib/mml/v4/munderover.rb +3 -22
  314. data/lib/mml/v4/namespace.rb +1 -4
  315. data/lib/mml/v4/none.rb +5 -11
  316. data/lib/mml/v4/relations.rb +37 -0
  317. data/lib/mml/v4/semantics.rb +3 -12
  318. data/lib/mml/v4/sets.rb +57 -0
  319. data/lib/mml/v4/statistics.rb +33 -0
  320. data/lib/mml/v4/tendsto.rb +9 -0
  321. data/lib/mml/v4/vector_calculus.rb +21 -0
  322. data/lib/mml/v4.rb +426 -71
  323. data/lib/mml/version.rb +1 -1
  324. data/lib/mml/versioned_parser.rb +46 -0
  325. data/lib/mml.rb +36 -6
  326. data/reference-docs/mathml-source/pubtext/mathmlspec.dtd +150 -0
  327. data/reference-docs/mathml-source/pubtext/xmlspec.dtd +2649 -0
  328. data/reference-docs/mathml-source/readme.txt +40 -0
  329. data/reference-docs/mathml-source/run +296 -0
  330. data/reference-docs/mathml-source/style/html/html2xhtml.xsl +216 -0
  331. data/reference-docs/mathml-source/style/html/images.xsl +98 -0
  332. data/reference-docs/mathml-source/style/html/mml6.xsl +1156 -0
  333. data/reference-docs/mathml-source/style/html/mmldiff.xsl +566 -0
  334. data/reference-docs/mathml-source/style/html/mmlspec.xsl +2531 -0
  335. data/reference-docs/mathml-source/style/html/slices-common.xsl +312 -0
  336. data/reference-docs/mathml-source/style/html/slices.xsl +48 -0
  337. data/reference-docs/mathml-source/style/html/xmlspec.xsl +2542 -0
  338. data/reference-docs/mathml-source/style/pdf/mathmlspec.xsl +2510 -0
  339. data/reference-docs/mathml-source/xml/changes.xml +773 -0
  340. data/reference-docs/mathml-source/xml/character-set.xml +1011 -0
  341. data/reference-docs/mathml-source/xml/content-element-def.xml +6143 -0
  342. data/reference-docs/mathml-source/xml/content-markup.xml +8178 -0
  343. data/reference-docs/mathml-source/xml/contributors.xml +425 -0
  344. data/reference-docs/mathml-source/xml/dom-bindings.xml +20 -0
  345. data/reference-docs/mathml-source/xml/dom-intro.xml +114 -0
  346. data/reference-docs/mathml-source/xml/fundamentals.xml +1646 -0
  347. data/reference-docs/mathml-source/xml/glossary.xml +519 -0
  348. data/reference-docs/mathml-source/xml/interface.xml +1096 -0
  349. data/reference-docs/mathml-source/xml/introduction.xml +724 -0
  350. data/reference-docs/mathml-source/xml/mathml-css-sample.xml +304 -0
  351. data/reference-docs/mathml-source/xml/mathml-dom.xml +3813 -0
  352. data/reference-docs/mathml-source/xml/mathml-spec.xml +356 -0
  353. data/reference-docs/mathml-source/xml/mixing.xml +982 -0
  354. data/reference-docs/mathml-source/xml/operator-dict.xml +551 -0
  355. data/reference-docs/mathml-source/xml/parsing.xml +2565 -0
  356. data/reference-docs/mathml-source/xml/presentation-markup.xml +6834 -0
  357. data/reference-docs/mathml-source/xml/references.xml +323 -0
  358. data/reference-docs/mathml-source/xml/validation-grammar.xml +877 -0
  359. data/schemas/README.adoc +15 -0
  360. data/schemas/mathml2/CVS/Entries +4 -0
  361. data/schemas/mathml2/CVS/Repository +1 -0
  362. data/schemas/mathml2/CVS/Root +1 -0
  363. data/schemas/mathml2/common/CVS/Entries +4 -0
  364. data/schemas/mathml2/common/CVS/Repository +1 -0
  365. data/schemas/mathml2/common/CVS/Root +1 -0
  366. data/schemas/mathml2/common/common-attribs.xsd +41 -0
  367. data/schemas/mathml2/common/math.xsd +126 -0
  368. data/schemas/mathml2/common/xlink-href.xsd +20 -0
  369. data/schemas/mathml2/content/CVS/Entries +16 -0
  370. data/schemas/mathml2/content/CVS/Repository +1 -0
  371. data/schemas/mathml2/content/CVS/Root +1 -0
  372. data/schemas/mathml2/content/arith.xsd +90 -0
  373. data/schemas/mathml2/content/calculus.xsd +146 -0
  374. data/schemas/mathml2/content/common-attrib.xsd +30 -0
  375. data/schemas/mathml2/content/constants.xsd +83 -0
  376. data/schemas/mathml2/content/constructs.xsd +260 -0
  377. data/schemas/mathml2/content/elementary-functions.xsd +117 -0
  378. data/schemas/mathml2/content/functions.xsd +73 -0
  379. data/schemas/mathml2/content/linear-algebra.xsd +173 -0
  380. data/schemas/mathml2/content/logic.xsd +53 -0
  381. data/schemas/mathml2/content/relations.xsd +55 -0
  382. data/schemas/mathml2/content/semantics.xsd +85 -0
  383. data/schemas/mathml2/content/sets.xsd +236 -0
  384. data/schemas/mathml2/content/statistics.xsd +136 -0
  385. data/schemas/mathml2/content/tokens.xsd +120 -0
  386. data/schemas/mathml2/content/tokens.xsd.~1.3.~ +119 -0
  387. data/schemas/mathml2/content/vector-calculus.xsd +88 -0
  388. data/schemas/mathml2/mathml2.xsd +59 -0
  389. data/schemas/mathml2/presentation/CVS/Entries +12 -0
  390. data/schemas/mathml2/presentation/CVS/Repository +1 -0
  391. data/schemas/mathml2/presentation/CVS/Root +1 -0
  392. data/schemas/mathml2/presentation/action.xsd +44 -0
  393. data/schemas/mathml2/presentation/characters.xsd +37 -0
  394. data/schemas/mathml2/presentation/common-attribs.xsd +113 -0
  395. data/schemas/mathml2/presentation/common-types.xsd +103 -0
  396. data/schemas/mathml2/presentation/error.xsd +40 -0
  397. data/schemas/mathml2/presentation/layout.xsd +195 -0
  398. data/schemas/mathml2/presentation/scripts.xsd +186 -0
  399. data/schemas/mathml2/presentation/space.xsd +52 -0
  400. data/schemas/mathml2/presentation/style.xsd +69 -0
  401. data/schemas/mathml2/presentation/table.xsd +216 -0
  402. data/schemas/mathml2/presentation/tokens.xsd +124 -0
  403. data/schemas/mathml3/mathml3-common.xsd +99 -0
  404. data/schemas/mathml3/mathml3-content.xsd +684 -0
  405. data/schemas/mathml3/mathml3-presentation.xsd +2151 -0
  406. data/schemas/mathml3/mathml3-strict-content.xsd +186 -0
  407. data/schemas/mathml3/mathml3.xsd +9 -0
  408. metadata +308 -4
  409. data/lib/mml/v3/common_attributes.rb +0 -22
  410. data/lib/mml/v4/common_attributes.rb +0 -26
data/README.adoc CHANGED
@@ -47,73 +47,74 @@ math4 = Mml.parse(input, version: 4)
47
47
  math.to_xml
48
48
 
49
49
  # Or use versioned modules directly
50
- Mml::V3::Math.from_xml(input)
51
- Mml::V4::Math.from_xml(input)
50
+ Mml::V3.parse(input)
51
+ Mml::V4.parse(input)
52
52
  ----
53
53
 
54
54
  == MathML version architecture
55
55
 
56
- Mml maintains two parallel class hierarchies under `Mml::V3` and `Mml::V4`.
57
- Both versions share the same namespace URI (`http://www.w3.org/1998/Math/MathML`)
58
- for backward compatibility.
56
+ Mml maintains three parallel class hierarchies under `Mml::V2`, `Mml::V3`, and `Mml::V4`.
57
+ All versions share the same namespace URI (`http://www.w3.org/1998/Math/MathML`).
59
58
 
60
59
  [source]
61
60
  ----
62
- ┌───────────────────────────────────────────┐
63
- Mml
64
- parse() delegates to V3 or V4
65
- └────────────────────┬──────────────────────┘
66
-
67
- ┌───────────────────┴────────────────────┐
68
-
69
- ┌────┴────┐ ┌────┴────┐
70
- │ Mml::V3 │ │ Mml::V4 │
71
- └────┬────┘ └────┬────┘
72
-
73
- ┌───────────────┼─────────────────────┐ ┌───────────────┼───────────────┐
74
- ┌────────────┴───────────────┐ ┌────────────┴────────────┐
75
- Element classes │ │ Element classes
76
- │ (Mi, Mn, Mo, Mrow, ...) │ │ │ (Mi, Mn, Mo, Mrow, ...) │ │
77
- │ │ │ │ │ + intent, arg,
78
- Inherits from │ │ │ displaystyle, │ │
79
- │ │ Lutaml::Model::Serializable│ │ │ │ scriptlevel │ │
80
- │ └────────────┬───────────────┘ │ │ │ + <a> element │ │
81
- │ │ │ │ └────────────┬────────────┘ │
82
- ┌────────────┴────────────┐ │ ┌────────────┴────────────┐ │
83
- CommonAttributes │ │ │ CommonAttributes │ │
84
- │ │ (child element mixin) │ │ │ │ (v4 version) │ │
85
- │ └─────────────────────────┘ │ | └─────────────────────────┘ |
86
- └─────────────────────────────────────┘ └───────────────────────────────┘
87
-
88
- ┌──────────────────┴──────────────────────┐
89
- │ Lutaml::Model::Serializable │
90
- (XML mapping framework) │
91
- └─────────────────────────────────────────┘
92
- ----
61
+ ┌───────────────────────────────────────────┐
62
+ Mml
63
+ parse() delegates to V2 / V3 / V4
64
+ └────────────────────┬──────────────────────┘
65
+
66
+ ┌─────────────────────────┼─────────────────────────┐
67
+
68
+ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
69
+ │ Mml::V2 │ │ Mml::V3 │ │ Mml::V4 │
70
+ └────┬────┘ └────┬────┘ └────┬────┘
71
+
72
+ ┌──────────┴──────────┐ ┌──────────┴──────────┐ ┌──────────┴──────────┐
73
+ V2-only classes │ │ Shared V4-only classes
74
+ (declare, reln, …) │ Base::modules + intent, arg,
75
+ └─────────────────────┘ └─────────────────────┘ displaystyle, │
76
+ scriptlevel,
77
+ + <a> element
78
+ └─────────────────────┘
79
+
80
+ ┌───────────────────────────────┐
81
+ lib/mml/base/
82
+ (shared attributes)
83
+ └───────────────────────────────┘
84
+ ----
85
+
86
+ **V2** (`lib/mml/v2/`): Standalone class hierarchy with full Content MathML support.
87
+ Includes deprecated elements like `declare` and `reln` not present in V3/V4.
88
+
89
+ **V3** (`lib/mml/v3/`): Uses shared `lib/mml/base/` modules for presentation elements.
90
+ Adds `overflow` attribute and V3-specific features.
91
+
92
+ **V4** (`lib/mml/v4/`): Uses shared `lib/mml/base/` modules with V4-only attributes
93
+ (`intent`, `arg`, `displaystyle`, `scriptlevel`) and the `<a>` hyperlink element.
93
94
 
94
95
  === Version selection
95
96
 
96
97
  [source,ruby]
97
98
  ----
98
99
  Mml.parse(input) # Default: MathML 3 (Mml::V3)
100
+ Mml.parse(input, version: 2) # Explicit MathML 2
99
101
  Mml.parse(input, version: 3) # Explicit MathML 3
100
- Mml.parse(input, version: 4) # MathML 4 with intent/arg attributes
102
+ Mml.parse(input, version: 4) # Explicit MathML 4
103
+ Mml::V2.parse(input) # Direct v2 parsing
101
104
  Mml::V3.parse(input) # Direct v3 parsing
102
105
  Mml::V4.parse(input) # Direct v4 parsing
103
106
  ----
104
107
 
105
- === Key differences between MathML 3 and MathML 4
108
+ === Key differences between MathML 2, 3 and 4
106
109
 
107
- [cols="1,2",options="header"]
110
+ [cols="1,2,2",options="header"]
108
111
  |===
109
- |Feature |MathML 4 additions
110
- |Universal attributes |`intent`, `arg`, `displaystyle`, `scriptlevel` available on all presentation elements
111
- |New element |`<a>` hyperlink element with `href`, `hreflang`
112
- |Deprecated (not serialized) a|
113
- * `fontfamily`, `fontweight`, `fontstyle`, `fontsize`, `color`, `background` on `mstyle`, `mglyph`, `mspace`
114
- * `groupalign` on `mtable`, `mtr`, `mlabeledtr`
115
- * `fence`, `separator` on `mo`
116
- |Deprecated (recognized but hidden) |`<mlabeledtr>`, `<none>` removed from `CommonAttributes` but classes still exist
112
+ |Feature |MathML 3 additions |MathML 4 additions
113
+ |V3-only attributes |`overflow`, `linebreakmultchar` |-
114
+ |V4-universal attributes |- |`intent`, `arg`, `displaystyle`, `scriptlevel`
115
+ |V4 hyperlink element |- |`<a>` with `href`, `hreflang`
116
+ |V2 deprecated elements |`declare`, `reln`, `fn` |`declare`, `reln`, `fn`
117
+ |Deprecated font attrs |`fontfamily`, `fontweight`, etc. |removed from strict V4
117
118
  |===
118
119
 
119
120
  === Migration from previous versions
@@ -128,19 +129,29 @@ namespace:
128
129
  # Before (no longer supported)
129
130
  require "mml/configuration"
130
131
  Mml::Configuration.adapter = :nokogiri
131
- Mml::Configuration.custom_models = { Mi => MyCustomMi }
132
+ Mml::Configuration.create_context(id: :custom_v3)
132
133
  Mml::Math.new(...)
133
134
 
134
135
  # After — explicit version
135
136
  require "mml"
136
137
  Mml::V3::Configuration.adapter = :nokogiri
137
- Mml::V3::Configuration.custom_models = { Mi => MyCustomMi }
138
- Mml::V3::Math.new(...)
138
+ Mml::V3::Configuration.create_context(
139
+ id: :custom_v3,
140
+ substitutions: [
141
+ { from_type: Mml::V3::Mi, to_type: MyCustomMi }
142
+ ]
143
+ )
144
+ Mml::V3.parse(input, context: :custom_v3)
139
145
 
140
146
  # Or for MathML 4
141
147
  Mml::V4::Configuration.adapter = :nokogiri
142
- Mml::V4::Configuration.custom_models = { Mi => MyCustomMi }
143
- Mml::V4::Math.new(...)
148
+ Mml::V4::Configuration.create_context(
149
+ id: :custom_v4,
150
+ substitutions: [
151
+ { from_type: Mml::V4::Mi, to_type: MyCustomMi }
152
+ ]
153
+ )
154
+ Mml::V4.parse(input, context: :custom_v4)
144
155
  ----
145
156
 
146
157
  ==== Element class references
@@ -233,7 +244,7 @@ math.to_xml
233
244
 
234
245
  *v4 only*: `a` (hyperlink)
235
246
 
236
- *Deprecated*: `mlabeledtr`, `none` (classes exist but hidden from CommonAttributes in v4)
247
+ *Deprecated*: `mlabeledtr`, `none` (classes exist but hidden from CommonElements in v4)
237
248
 
238
249
  === Token elements (leaf nodes)
239
250
 
@@ -257,6 +268,7 @@ Container elements hold child elements via `#{tag}_value` collection attributes:
257
268
  [source,ruby]
258
269
  ----
259
270
  Mml::V3::Mrow.new(
271
+ lutaml_register: Mml::V3::Configuration.context_id,
260
272
  mi_value: [Mml::V3::Mi.new(value: "x")],
261
273
  mo_value: [Mml::V3::Mo.new(value: "+")],
262
274
  mn_value: [Mml::V3::Mn.new(value: "1")],
@@ -271,8 +283,10 @@ Build an expression tree by nesting elements:
271
283
  [source,ruby]
272
284
  ----
273
285
  Mml::V3::Math.new(
286
+ lutaml_register: Mml::V3::Configuration.context_id,
274
287
  mfrac_value: [
275
288
  Mml::V3::Mfrac.new(
289
+ lutaml_register: Mml::V3::Configuration.context_id,
276
290
  mi_value: [Mml::V3::Mi.new(value: "a"), Mml::V3::Mi.new(value: "b")],
277
291
  ),
278
292
  ],
@@ -285,11 +299,19 @@ Mml::V3::Math.new(
285
299
  [source,ruby]
286
300
  ----
287
301
  Mml::V3::Mtable.new(
302
+ lutaml_register: Mml::V3::Configuration.context_id,
288
303
  mtr_value: [
289
304
  Mml::V3::Mtr.new(
305
+ lutaml_register: Mml::V3::Configuration.context_id,
290
306
  mtd_value: [
291
- Mml::V3::Mtd.new(mi_value: [Mml::V3::Mi.new(value: "a")]),
292
- Mml::V3::Mtd.new(mi_value: [Mml::V3::Mi.new(value: "b")]),
307
+ Mml::V3::Mtd.new(
308
+ lutaml_register: Mml::V3::Configuration.context_id,
309
+ mi_value: [Mml::V3::Mi.new(value: "a")]
310
+ ),
311
+ Mml::V3::Mtd.new(
312
+ lutaml_register: Mml::V3::Configuration.context_id,
313
+ mi_value: [Mml::V3::Mi.new(value: "b")]
314
+ ),
293
315
  ],
294
316
  ),
295
317
  ],
@@ -301,6 +323,7 @@ Mml::V3::Mtable.new(
301
323
  [source,ruby]
302
324
  ----
303
325
  Mml::V4::A.new(
326
+ lutaml_register: Mml::V4::Configuration.context_id,
304
327
  href: "https://example.com",
305
328
  hreflang: "en",
306
329
  mi_value: [Mml::V4::Mi.new(value: "click")]
@@ -308,41 +331,141 @@ Mml::V4::A.new(
308
331
  # => <a href="https://example.com" hreflang="en"><mi>click</mi></a>
309
332
  ----
310
333
 
334
+ == MathML V2 Support
335
+
336
+ V2 is a standalone implementation with its own class hierarchy in `lib/mml/v2/`.
337
+ It includes full Content MathML support with elements not present in V3/V4:
338
+
339
+ [source,ruby]
340
+ ----
341
+ # Parse MathML 2
342
+ Mml::V2.parse('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math>')
343
+
344
+ # Content elements available in V2 (deprecated in V3/V4)
345
+ Mml::V2::Declare.new(...)
346
+ Mml::V2::Reln.new(...)
347
+ Mml::V2::Fn.new(...)
348
+ ----
349
+
350
+ V2 uses `Mml::V2::Configuration` for context management:
351
+
352
+ [source,ruby]
353
+ ----
354
+ Mml::V2::Configuration.context_id # => :mml_v2
355
+ Mml::V2::Configuration.context
356
+ Mml::V2::Configuration.populate_context!
357
+ ----
358
+
359
+ == MathML V4 Compliance
360
+
361
+ This implementation has been audited against the
362
+ https://www.w3.org/TR/MathML4/[MathML 4 W3C Recommendation].
363
+
364
+ === Universal V4 Attributes
365
+
366
+ All MathML 4 presentation elements include `intent`, `arg`, `displaystyle`,
367
+ `scriptlevel`, `mathcolor`, and `mathbackground` via the shared
368
+ `Base::V4Attributes` module.
369
+
370
+ === Legacy Schema Support
371
+
372
+ For backwards compatibility with existing MathML content, this gem supports
373
+ both the strict V4 schema and the legacy schema:
374
+
375
+ [cols="1,2",options="header"]
376
+ |===
377
+ |Feature |Status
378
+ |Universal V4 attributes (`intent`, `arg`, `displaystyle`, `scriptlevel`) |Full support
379
+ |`mathcolor`, `mathbackground` on all presentation elements |Full support
380
+ |`<a>` hyperlink element |Full support
381
+ |Deprecated font attributes (`fontfamily`, `fontweight`, etc.) |Legacy support (V3 + V4 legacy schema)
382
+ |`fence`, `separator` on `<mo>` |Legacy support (removed from default V4 schema)
383
+ |`none` element |Deprecated in V4 (empty `<mrow>` recommended)
384
+ |`mlabeledtr` element |Legacy support (removed from default V4 schema)
385
+ |===
386
+
387
+
311
388
  == Internal architecture
312
389
 
313
390
  === Element class patterns
314
391
 
315
- All element classes inherit from `Lutaml::Model::Serializable`:
392
+ Shared attributes and mappings live in `Base::` modules (`lib/mml/base/`).
393
+ V3 and V4 classes include these modules independently — no cross-version inheritance.
394
+
395
+ * *Leaf elements*: inherit `Lutaml::Model::Serializable`, include `Base::ElementName`
396
+ * *Container elements*: inherit `CommonElements`, include `Base::ElementName`
316
397
 
317
- * *Leaf elements*: use `map_content to: :value` for text content
318
- * *Container elements*: use `mixed_content` for child elements
398
+ Each element self-registers in its version's built-in `GlobalContext` context.
319
399
 
320
400
  [source,ruby]
321
401
  ----
322
- # Leaf text content
323
- class Mi < Lutaml::Model::Serializable
324
- attribute :value, :string
325
- xml do
326
- element "mi"
327
- map_content to: :value
402
+ # Shared attributes (lib/mml/base/mi.rb)
403
+ module Base::Mi
404
+ def self.included(klass)
405
+ klass.class_eval do
406
+ attribute :value, :string
407
+ xml do
408
+ element "mi"
409
+ map_content to: :value
410
+ end
411
+ end
328
412
  end
329
413
  end
330
414
 
331
- # Container — child elements
332
- class Mrow < Lutaml::Model::Serializable
333
- xml do
334
- element "mrow"
335
- mixed_content
336
- end
415
+ # V3 leaf
416
+ class V3::Mi < Lutaml::Model::Serializable
417
+ include Base::Mi
418
+ end
419
+
420
+ # V4 leaf — adds V4-only attributes
421
+ class V4::Mi < Lutaml::Model::Serializable
422
+ include Base::Mi
423
+ attribute :intent, :string
424
+ end
425
+
426
+ # V3 container
427
+ class V3::Mrow < CommonElements
428
+ include Base::Mrow
337
429
  end
338
430
  ----
339
431
 
340
- === CommonAttributes
432
+ === CommonElements
433
+
434
+ Container elements inherit `CommonElements`, which defines `#{tag}_value` collection
435
+ attributes for all supported child elements. Attribute types use symbols (e.g., `:mi`,
436
+ `:mfrac`) resolved through `Lutaml::Model::GlobalContext`.
437
+
438
+ V4's `CommonElements` extends the base with the `<a>` hyperlink element.
439
+
440
+ === Context and type resolution
441
+
442
+ When calling `from_xml` directly (outside of `Mml.parse` or `Mml::V3.parse`), pass
443
+ the version-specific context id for correct type resolution.
341
444
 
342
- Container elements that accept arbitrary MathML children import `CommonAttributes`,
343
- which defines `#{tag}_value` collection attributes for all supported child elements.
344
- The list of classes that receive this mixin is in
345
- `Configuration::COMMON_ATTRIBUTES_CLASSES`.
445
+ NOTE: `lutaml-model` still uses the keyword name `register:` in low-level APIs.
446
+ In MML, the value passed to that keyword should be a context id.
447
+
448
+ [source,ruby]
449
+ ----
450
+ Mml::V3::Math.from_xml(input, register: Mml::V3::Configuration.context_id)
451
+ Mml::V4::Math.from_xml(input, register: Mml::V4::Configuration.context_id)
452
+ ----
453
+
454
+ The `parse` methods handle this automatically.
455
+
456
+ When constructing container elements directly, also pass the context id on the
457
+ instance via `lutaml_register:` so symbolic child types resolve in the right
458
+ versioned context:
459
+
460
+ [source,ruby]
461
+ ----
462
+ math = Mml::V3::Math.new(
463
+ lutaml_register: Mml::V3::Configuration.context_id,
464
+ mi_value: [Mml::V3::Mi.new(value: "x")]
465
+ )
466
+
467
+ math.to_xml
468
+ ----
346
469
 
347
470
  === Namespace
348
471
 
@@ -355,19 +478,148 @@ Three input forms are supported:
355
478
 
356
479
  == Configuration
357
480
 
358
- Configuration is version-specific. Use the namespace matching your target version:
359
-
360
481
  [source,ruby]
361
482
  ----
362
- # Switch XML adapter (default: :ox, also supports :nokogiri)
483
+ # Switch XML adapter (default: :ox, :oga on Opal)
363
484
  Mml::V3::Configuration.adapter = :nokogiri
364
- Mml::V4::Configuration.adapter = :nokogiri
365
485
 
366
- # Register custom model replacements
367
- Mml::V3::Configuration.custom_models = { Mi => MyCustomMi }
368
- Mml::V4::Configuration.custom_models = { Mi => MyCustomMi }
486
+ # Access the built-in version-specific contexts
487
+ Mml::V3::Configuration.context_id # => :mml_v3
488
+ Mml::V4::Configuration.context_id # => :mml_v4
489
+ Mml::V3::Configuration.context
490
+ Mml::V4::Configuration.context
491
+
492
+ # Rebuild a built-in context after an explicit GlobalContext.reset!
493
+ Mml::V3::Configuration.populate_context!
494
+ Mml::V4::Configuration.populate_context!
495
+
496
+ # Create a derived context with substitutions
497
+ Mml::V3::Configuration.create_context(
498
+ id: :custom_v3,
499
+ substitutions: [
500
+ { from_type: Mml::V3::Mi, to_type: MyCustomMi }
501
+ ]
502
+ )
503
+
504
+ # Parse using the custom context
505
+ Mml::V3.parse(input, context: :custom_v3)
506
+
507
+ # Low-level APIs still use the upstream keyword name `register:`
508
+ Mml::V3::Math.from_xml(input, register: :custom_v3)
369
509
  ----
370
510
 
511
+ The `context:` keyword is the preferred MML API. The legacy `register:` keyword is
512
+ still accepted temporarily in MML parse methods, but it emits a deprecation warning
513
+ and is normalized to a context id internally.
514
+
515
+ If you reset global contexts and need the built-in MML contexts restored
516
+ explicitly, call `populate_context!` for the version(s) you want to restore.
517
+
518
+ == Unsupported Features
519
+
520
+ The following MathML test suite files are intentionally skipped (not failures) because
521
+ they use features that are not part of the MathML namespace:
522
+
523
+ [cols="1,3,1",options="header"]
524
+ |===
525
+ |Feature |Reason |Approx. Tests Skipped
526
+ |HTML attributes (`style`, `class`, `id`, `dir`, `mode`, `tabindex`, `data-*`, event handlers) |These are HTML/XML attributes, not MathML attributes |Varies by test suite
527
+ |HTML `<span>` elements |HTML elements are not part of MathML namespace |Varies by test suite
528
+ |XML comments |XML comments inside MathML elements are not supported |Varies by test suite
529
+ |Foreign content in `annotation-xml` |SVG, XHTML content inside annotation-xml is not supported |Varies by test suite
530
+ |Entity references |Named entity references other than standard XML entities |Varies by test suite
531
+ |===
532
+
533
+ These tests are filtered out via `UNSUPPORTED_PATTERNS` in the test configuration
534
+ and do not represent bugs. They are marked as "pending" in test output because
535
+ RSpec's `skip` directive still records them as pending tests.
536
+
537
+ == Version-Specific Attributes
538
+
539
+ Some MathML attributes are version-specific and only available on the appropriate version:
540
+
541
+ [cols="1,1,2",options="header"]
542
+ |===
543
+ |Attribute |Element |Notes
544
+ |`overflow` |`math` |MathML 3 only (line overflow behavior)
545
+ |`linebreakmultchar` |`math` |MathML 3 only (line break character)
546
+ |`scriptsizemultiplier` |`mscarries` |Float type for fractional scaling
547
+ |===
548
+
549
+ == Content Elements
550
+
551
+ The following Content MathML elements are supported for cross-content markup:
552
+
553
+ * `cn` - numeric content
554
+ * `ci` - identifier content
555
+ * `csymbol` - symbolic content (with presentation element support: `msub`, `msup`, `mrow`, etc.)
556
+ * `cs` - string content
557
+ * `cbytes` - bytes content with encoding attribute
558
+ * `apply`, `bind`, `bvar` - function application and binding
559
+ * `semantics`, `annotation`, `annotation-xml` - semantic annotations
560
+
561
+ == Test Suite and Fixtures
562
+
563
+ The gem uses multiple MathML test suites to validate parsing and serialization:
564
+
565
+ [cols="1,1,3",options="header"]
566
+ |===
567
+ |Test Suite |Version |Description
568
+ |`spec/fixtures/mml2-testsuite/` |V2 |W3C MathML 2 test suite with Content and Presentation elements
569
+ |`spec/fixtures/mml3-testsuite/` |V3 |W3C MathML 3 test suite
570
+ |`spec/fixtures/mmlcore-testsuite/` |V4 |WPT MathML Core tests (modern browser implementation)
571
+ |`spec/fixtures/v2/`, `spec/fixtures/v4/` |V2/V4 |Hand-crafted fixtures for version-specific features
572
+ |===
573
+
574
+ === Running Tests
575
+
576
+ [source,bash]
577
+ ----
578
+ bundle exec rake # Run all specs + rubocop
579
+ bundle exec rspec # Run all tests
580
+ bundle exec rspec spec/mml/v3_spec.rb # Run specific test file
581
+ bundle exec rspec --only-failures # Run only previously failing tests
582
+ ----
583
+
584
+ === Test Fixture Processing
585
+
586
+ Some test suites require preprocessing to extract clean MathML from HTML wrappers:
587
+
588
+ [source,bash]
589
+ ----
590
+ # Preprocess test fixtures (strips HTML wrappers, extracts MathML)
591
+ rake spec:preprocess_fixtures
592
+
593
+ # Validate preprocessed fixtures against XSD schemas
594
+ rake spec:validate_cleaned_fixtures
595
+
596
+ # Both in sequence
597
+ rake spec:prepare
598
+ ----
599
+
600
+ The preprocessed fixtures are stored in `tmp/cleaned_fixtures/` and are excluded from git.
601
+
602
+ === Unsupported Test Patterns
603
+
604
+ Tests are filtered via `UNSUPPORTED_PATTERNS` when they contain:
605
+
606
+ * HTML elements/attributes (`<span>`, `style=`, `class=`, etc.)
607
+ * XML comments inside elements
608
+ * Foreign content (SVG in `annotation-xml`)
609
+ * Entity references not handled by the parser
610
+ * Content elements not supported in presentation context (V3/V4)
611
+
612
+ These are marked as pending, not failures, because they represent features outside the MathML namespace.
613
+
614
+ === Known Pending Issues
615
+
616
+ [cols="1,3",options="header"]
617
+ |===
618
+ |Issue |Affected Tests
619
+ |lutaml-model Unicode NCR comparison |V2 tests with `&#x02009;` spacing characters
620
+ |Parser schema validation |V3 ErrorHandling tests (parser accepts invalid MathML)
621
+ |===
622
+
371
623
  == Development
372
624
 
373
625
  [source,bash]
data/Rakefile CHANGED
@@ -6,7 +6,22 @@ require "rspec/core/rake_task"
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  require "rubocop/rake_task"
9
-
10
9
  RuboCop::RakeTask.new
11
10
 
11
+ # Spec preparation tasks
12
+ namespace :spec do
13
+ desc "Preprocess MathML fixture files to clean them"
14
+ task :preprocess_fixtures do
15
+ load "spec/tasks/preprocess_fixtures.rb"
16
+ end
17
+
18
+ desc "Validate cleaned fixtures against XSD schemas"
19
+ task :validate_cleaned_fixtures do
20
+ load "spec/tasks/validate_cleaned_fixtures.rb"
21
+ end
22
+
23
+ desc "Prepare spec fixtures (preprocess + validate)"
24
+ task prepare: %i[preprocess_fixtures validate_cleaned_fixtures]
25
+ end
26
+
12
27
  task default: %i[spec rubocop]
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mml
4
+ module Base
5
+ module Content
6
+ # annotation is a non-XML annotation for semantic markup.
7
+ # Used within semantics element.
8
+ module Annotation
9
+ def self.included(klass)
10
+ klass.class_eval do
11
+ attribute :definition_url, :string
12
+ attribute :encoding_value, :string
13
+ attribute :href, :string
14
+ attribute :value, :string
15
+
16
+ xml do
17
+ namespace Mml::Namespace
18
+ element "annotation"
19
+
20
+ map_content to: :value
21
+ map_attribute "href", to: :href
22
+ map_attribute "definitionURL", to: :definition_url
23
+ map_attribute "encoding", to: :encoding_value
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mml
4
+ module Base
5
+ module Content
6
+ # annotation-xml is an XML-encoded annotation for semantic markup.
7
+ # Used within semantics element to embed presentation or other markup.
8
+ module AnnotationXml
9
+ def self.included(klass)
10
+ klass.class_eval do
11
+ attribute :definitionURL, :string
12
+ attribute :annotation_xml_encoding, :string
13
+ attribute :cd, :string
14
+ attribute :name, :string
15
+
16
+ xml do
17
+ namespace Mml::Namespace
18
+ element "annotation-xml"
19
+ mixed_content
20
+
21
+ map_attribute "definitionURL", to: :definitionURL
22
+ map_attribute "encoding", to: :annotation_xml_encoding
23
+ map_attribute "cd", to: :cd
24
+ map_attribute "name", to: :name
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mml
4
+ module Base
5
+ module Content
6
+ # The apply element applies a function to its arguments.
7
+ # First child is the operator, remaining children are operands.
8
+ module Apply
9
+ def self.included(klass)
10
+ klass.class_eval do
11
+ attribute :definition_url, :string
12
+ attribute :encoding_value, :string
13
+
14
+ xml do
15
+ namespace Mml::Namespace
16
+ element "apply"
17
+ mixed_content
18
+
19
+ map_attribute "definitionURL", to: :definition_url
20
+ map_attribute "encoding", to: :encoding_value
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end