mml3.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*************************************************************
  2. *
  3. * MathJax/extensions/MathML/mml3.js
  4. *
  5. * This file implements an XSLT transform to convert some MathML 3
  6. * constructs to constructs MathJax can render. The transform is
  7. * performed in a pre-filter for the MathML input jax, so that the
  8. * Show Math As menu will still show the Original MathML correctly,
  9. * but the transformed MathML can be obtained from the regular MathML menu.
  10. *
  11. * To load it, include
  12. *
  13. * MathML: {
  14. * extensions: ["mml3.js"]
  15. * }
  16. *
  17. * in your configuration.
  18. *
  19. * A portion of this file is taken from mml3mj.xsl which is
  20. * Copyright (c) David Carlisle 2008-2015
  21. * and is used by permission of David Carlisle, who has agreed to allow us
  22. * to release it under the Apache2 license (see below). That portion is
  23. * indicated via comments.
  24. *
  25. * The remainder falls under the copyright that follows.
  26. * ---------------------------------------------------------------------
  27. *
  28. * Copyright (c) 2013-2018 The MathJax Consortium
  29. *
  30. * Licensed under the Apache License, Version 2.0 (the "License");
  31. * you may not use this file except in compliance with the License.
  32. * You may obtain a copy of the License at
  33. *
  34. * http://www.apache.org/licenses/LICENSE-2.0
  35. *
  36. * Unless required by applicable law or agreed to in writing, software
  37. * distributed under the License is distributed on an "AS IS" BASIS,
  38. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  39. * See the License for the specific language governing permissions and
  40. * limitations under the License.
  41. */
  42. MathJax.Extension["MathML/mml3"] = {
  43. version: "2.7.5"
  44. };
  45. MathJax.Hub.Register.StartupHook("MathML Jax Ready",function () {
  46. var MATHML = MathJax.InputJax.MathML,
  47. PARSE = MATHML.Parse.prototype;
  48. MATHML.prefilterHooks.Add(function (data) {
  49. if (!MATHML.mml3XSLT) return;
  50. // Parse the <math> but use MATHML.Parse's preProcessMath to apply the normal preprocessing.
  51. if (!MATHML.ParseXML) {MATHML.ParseXML = MATHML.createParser()}
  52. var doc = MATHML.ParseXML(PARSE.preProcessMath(data.math));
  53. // Now transform the <math> using the mml3 stylesheet.
  54. var newdoc = MATHML.mml3XSLT.transformToDocument(doc);
  55. if ((typeof newdoc) === "string") {
  56. // Internet Explorer returns a string, so just use it.
  57. data.math = newdoc;
  58. } else if (window.XMLSerializer) {
  59. // Serialize the <math> again. We could directly provide the DOM content
  60. // but other prefilterHooks may assume data.math is still a string.
  61. var serializer = new XMLSerializer();
  62. data.math = serializer.serializeToString(newdoc.documentElement, doc);
  63. }
  64. });
  65. /*
  66. * The following is derived from mml3mj.xsl
  67. * (https://github.com/davidcarlisle/web-xslt/blob/master/ctop/mml3mj.xsl)
  68. * which is Copyright (c) David Carlisle 2008-2015.
  69. * It is used by permission of David Carlisle, who has agreed to allow it to
  70. * be released under the Apache License, Version 2.0.
  71. */
  72. var BROWSER = MathJax.Hub.Browser;
  73. var exslt = '';
  74. if (BROWSER.isEdge || BROWSER.isMSIE) {
  75. exslt = 'urn:schemas-microsoft-com:xslt'
  76. } else {
  77. exslt = 'http://exslt.org/common';
  78. }
  79. var mml3Stylesheet =
  80. '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
  81. ' xmlns:m="http://www.w3.org/1998/Math/MathML"' +
  82. ' xmlns:c="' + exslt + '"' +
  83. ' exclude-result-prefixes="m c">' +
  84. '<xsl:output indent="yes" omit-xml-declaration="yes"/>' +
  85. '<xsl:output indent="yes" omit-xml-declaration="yes"/><xsl:template match="*">' +
  86. ' <xsl:copy>' +
  87. ' <xsl:copy-of select="@*"/>' +
  88. ' <xsl:apply-templates/>' +
  89. ' </xsl:copy>' +
  90. '</xsl:template><xsl:template match="m:*[@dir=\'rtl\']" priority="10">' +
  91. ' <xsl:apply-templates mode="rtl" select="."/>' +
  92. '</xsl:template><xsl:template match="@*" mode="rtl">' +
  93. ' <xsl:copy-of select="."/>' +
  94. ' <xsl:attribute name="dir">ltr</xsl:attribute>' +
  95. '</xsl:template>' +
  96. '<xsl:template match="*" mode="rtl">' +
  97. ' <xsl:copy>' +
  98. ' <xsl:apply-templates select="@*" mode="rtl"/>' +
  99. ' <xsl:for-each select="node()">' +
  100. ' <xsl:sort data-type="number" order="descending" select="position()"/>' +
  101. ' <xsl:text> </xsl:text>' +
  102. ' <xsl:apply-templates mode="rtl" select="."/>' +
  103. ' </xsl:for-each>' +
  104. ' </xsl:copy>' +
  105. '</xsl:template><xsl:template match="@open" mode="rtl">' +
  106. ' <xsl:attribute name="close"><xsl:value-of select="."/></xsl:attribute>' +
  107. '</xsl:template><xsl:template match="@open[.=\'(\']" mode="rtl">' +
  108. ' <xsl:attribute name="close">)</xsl:attribute>' +
  109. '</xsl:template><xsl:template match="@open[.=\')\']" mode="rtl">' +
  110. ' <xsl:attribute name="close">(</xsl:attribute>' +
  111. '</xsl:template>' +
  112. '<xsl:template match="@open[.=\'[\']" mode="rtl">' +
  113. ' <xsl:attribute name="close">]</xsl:attribute>' +
  114. '</xsl:template>' +
  115. '<xsl:template match="@open[.=\']\']" mode="rtl">' +
  116. ' <xsl:attribute name="close">[</xsl:attribute>' +
  117. '</xsl:template>' +
  118. '<xsl:template match="@open[.=\'{\']" mode="rtl">' +
  119. ' <xsl:attribute name="close">}</xsl:attribute>' +
  120. '</xsl:template>' +
  121. '<xsl:template match="@open[.=\'}\']" mode="rtl">' +
  122. ' <xsl:attribute name="close">{</xsl:attribute>' +
  123. '</xsl:template>' +
  124. '<xsl:template match="@close" mode="rtl">' +
  125. ' <xsl:attribute name="open"><xsl:value-of select="."/></xsl:attribute>' +
  126. '</xsl:template><xsl:template match="@close[.=\'(\']" mode="rtl">' +
  127. ' <xsl:attribute name="open">)</xsl:attribute>' +
  128. '</xsl:template><xsl:template match="@close[.=\')\']" mode="rtl">' +
  129. ' <xsl:attribute name="open">(</xsl:attribute>' +
  130. '</xsl:template>' +
  131. '<xsl:template match="@close[.=\'[\']" mode="rtl">' +
  132. ' <xsl:attribute name="open">]</xsl:attribute>' +
  133. '</xsl:template>' +
  134. '<xsl:template match="@close[.=\']\']" mode="rtl">' +
  135. ' <xsl:attribute name="open">[</xsl:attribute>' +
  136. '</xsl:template>' +
  137. '<xsl:template match="@close[.=\'{\']" mode="rtl">' +
  138. ' <xsl:attribute name="open">}</xsl:attribute>' +
  139. '</xsl:template>' +
  140. '<xsl:template match="@close[.=\'}\']" mode="rtl">' +
  141. ' <xsl:attribute name="open">{</xsl:attribute>' +
  142. '</xsl:template><xsl:template match="m:mfrac[@bevelled=\'true\']" mode="rtl">' +
  143. ' <m:mrow>' +
  144. ' <m:msub><m:mi></m:mi><xsl:apply-templates select="*[2]" mode="rtl"/></m:msub>' +
  145. ' <m:mo>&#x5c;</m:mo>' +
  146. ' <m:msup><m:mi></m:mi><xsl:apply-templates select="*[1]" mode="rtl"/></m:msup>' +
  147. ' </m:mrow>' +
  148. '</xsl:template><xsl:template match="m:mfrac" mode="rtl">' +
  149. ' <xsl:copy>' +
  150. ' <xsl:apply-templates mode="rtl" select="@*|*"/>' +
  151. ' </xsl:copy>' +
  152. '</xsl:template><xsl:template match="m:mroot" mode="rtl">' +
  153. ' <m:msup>' +
  154. ' <m:menclose notation="top right">' +
  155. ' <xsl:apply-templates mode="rtl" select="@*|*[1]"/>' +
  156. ' </m:menclose>' +
  157. ' <xsl:apply-templates mode="rtl" select="*[2]"/>' +
  158. ' </m:msup>' +
  159. '</xsl:template>' +
  160. '<xsl:template match="m:msqrt" mode="rtl">' +
  161. ' <m:menclose notation="top right">' +
  162. ' <xsl:apply-templates mode="rtl" select="@*|*[1]"/>' +
  163. ' </m:menclose>' +
  164. '</xsl:template><xsl:template match="m:mtable|m:munder|m:mover|m:munderover" mode="rtl" priority="2">' +
  165. ' <xsl:copy>' +
  166. ' <xsl:apply-templates select="@*" mode="rtl"/>' +
  167. ' <xsl:apply-templates mode="rtl">' +
  168. ' </xsl:apply-templates>' +
  169. ' </xsl:copy>' +
  170. '</xsl:template>' +
  171. '<xsl:template match="m:msup" mode="rtl" priority="2">' +
  172. ' <m:mmultiscripts>' +
  173. ' <xsl:apply-templates select="*[1]" mode="rtl"/>' +
  174. ' <m:mprescripts/>' +
  175. ' <m:none/>' +
  176. ' <xsl:apply-templates select="*[2]" mode="rtl"/>' +
  177. ' </m:mmultiscripts>' +
  178. '</xsl:template>' +
  179. '<xsl:template match="m:msub" mode="rtl" priority="2">' +
  180. ' <m:mmultiscripts>' +
  181. ' <xsl:apply-templates select="*[1]" mode="rtl"/>' +
  182. ' <m:mprescripts/>' +
  183. ' <xsl:apply-templates select="*[2]" mode="rtl"/>' +
  184. ' <m:none/>' +
  185. ' </m:mmultiscripts>' +
  186. '</xsl:template>' +
  187. '<xsl:template match="m:msubsup" mode="rtl" priority="2">' +
  188. ' <m:mmultiscripts>' +
  189. ' <xsl:apply-templates select="*[1]" mode="rtl"/>' +
  190. ' <m:mprescripts/>' +
  191. ' <xsl:apply-templates select="*[2]" mode="rtl"/>' +
  192. ' <xsl:apply-templates select="*[3]" mode="rtl"/>' +
  193. ' </m:mmultiscripts>' +
  194. '</xsl:template>' +
  195. '<xsl:template match="m:mmultiscripts" mode="rtl" priority="2">' +
  196. ' <m:mmultiscripts>' +
  197. ' <xsl:apply-templates select="*[1]" mode="rtl"/>' +
  198. ' <xsl:for-each select="m:mprescripts/following-sibling::*[position() mod 2 = 1]">' +
  199. ' <xsl:sort data-type="number" order="descending" select="position()"/>' +
  200. ' <xsl:apply-templates select="." mode="rtl"/>' +
  201. ' <xsl:apply-templates select="following-sibling::*[1]" mode="rtl"/>' +
  202. ' </xsl:for-each>' +
  203. ' <m:mprescripts/>' +
  204. ' <xsl:for-each select="m:mprescripts/preceding-sibling::*[position()!=last()][position() mod 2 = 0]">' +
  205. ' <xsl:sort data-type="number" order="descending" select="position()"/>' +
  206. ' <xsl:apply-templates select="." mode="rtl"/>' +
  207. ' <xsl:apply-templates select="following-sibling::*[1]" mode="rtl"/>' +
  208. ' </xsl:for-each>' +
  209. ' </m:mmultiscripts>' +
  210. '</xsl:template>' +
  211. '<xsl:template match="m:mmultiscripts[not(m:mprescripts)]" mode="rtl" priority="3">' +
  212. ' <m:mmultiscripts>' +
  213. ' <xsl:apply-templates select="*[1]" mode="rtl"/>' +
  214. ' <m:mprescripts/>' +
  215. ' <xsl:for-each select="*[position() mod 2 = 0]">' +
  216. ' <xsl:sort data-type="number" order="descending" select="position()"/>' +
  217. ' <xsl:apply-templates select="." mode="rtl"/>' +
  218. ' <xsl:apply-templates select="following-sibling::*[1]" mode="rtl"/>' +
  219. ' </xsl:for-each>' +
  220. ' </m:mmultiscripts>' +
  221. '</xsl:template>' +
  222. '<xsl:template match="text()[.=\'(\']" mode="rtl">)</xsl:template>' +
  223. '<xsl:template match="text()[.=\')\']" mode="rtl">(</xsl:template>' +
  224. '<xsl:template match="text()[.=\'{\']" mode="rtl">}</xsl:template>' +
  225. '<xsl:template match="text()[.=\'}\']" mode="rtl">{</xsl:template>' +
  226. '<xsl:template match="text()[.=\'&lt;\']" mode="rtl">&gt;</xsl:template>' +
  227. '<xsl:template match="text()[.=\'&gt;\']" mode="rtl">&lt;</xsl:template>' +
  228. '<xsl:template match="text()[.=\'&#x2208;\']" mode="rtl">&#x220b;</xsl:template>' +
  229. '<xsl:template match="text()[.=\'&#x220b;\']" mode="rtl">&#x2208;</xsl:template>' +
  230. '<xsl:template match="@notation[.=\'radical\']" mode="rtl">' +
  231. ' <xsl:attribute name="notation">top right</xsl:attribute>' +
  232. '</xsl:template>' +
  233. '<xsl:template match="m:mlongdiv|m:mstack" mode="rtl">' +
  234. ' <m:mrow dir="ltr">' +
  235. ' <xsl:apply-templates select="."/>' +
  236. ' </m:mrow>' +
  237. '</xsl:template>' +
  238. '<xsl:template match="m:mstack" priority="11">' +
  239. ' <xsl:variable name="m">' +
  240. ' <m:mtable columnspacing="0em">' +
  241. ' <xsl:copy-of select="@align"/>' +
  242. ' <xsl:variable name="t">' +
  243. ' <xsl:apply-templates select="*" mode="mstack1">' +
  244. ' <xsl:with-param name="p" select="0"/>' +
  245. ' </xsl:apply-templates>' +
  246. ' </xsl:variable>' +
  247. ' <xsl:variable name="maxl">' +
  248. ' <xsl:for-each select="c:node-set($t)/*/@l">' +
  249. ' <xsl:sort data-type="number" order="descending"/>' +
  250. ' <xsl:if test="position()=1">' +
  251. ' <xsl:value-of select="."/>' +
  252. ' </xsl:if>' +
  253. ' </xsl:for-each>' +
  254. ' </xsl:variable>' +
  255. ' <xsl:for-each select="c:node-set($t)/*[not(@class=\'mscarries\') or following-sibling::*[1]/@class=\'mscarries\']">' +
  256. '<xsl:variable name="c" select="preceding-sibling::*[1][@class=\'mscarries\']"/>' +
  257. ' <xsl:text>&#10;</xsl:text>' +
  258. ' <m:mtr>' +
  259. ' <xsl:copy-of select="@class[.=\'msline\']"/>' +
  260. ' <xsl:variable name="offset" select="$maxl - @l"/>' +
  261. ' <xsl:choose>' +
  262. ' <xsl:when test="@class=\'msline\' and @l=\'*\'">' +
  263. ' <xsl:variable name="msl" select="*[1]"/>' +
  264. ' <xsl:for-each select="(//node())[position()&lt;=$maxl]">' +
  265. ' <xsl:copy-of select="$msl"/>' +
  266. ' </xsl:for-each>' +
  267. ' </xsl:when>' +
  268. ' <xsl:when test="$c">' +
  269. ' <xsl:variable name="ldiff" select="$c/@l - @l"/>' +
  270. ' <xsl:variable name="loffset" select="$maxl - $c/@l"/>' +
  271. ' <xsl:for-each select="(//*)[position()&lt;= $offset]">' +
  272. ' <xsl:variable name="pn" select="position()"/>' +
  273. ' <xsl:variable name="cy" select="$c/*[position()=$pn - $loffset]"/>' +
  274. ' <m:mtd>' +
  275. ' <xsl:if test="$cy/*">' +
  276. ' <m:mover><m:mphantom><m:mn>0</m:mn></m:mphantom><m:mpadded width="0em" lspace="-0.5width">' +
  277. ' <xsl:copy-of select="$cy/*"/></m:mpadded></m:mover>' +
  278. ' </xsl:if>' +
  279. ' </m:mtd>' +
  280. ' </xsl:for-each>' +
  281. ' <xsl:for-each select="*">' +
  282. ' <xsl:variable name="pn" select="position()"/>' +
  283. ' <xsl:variable name="cy" select="$c/*[position()=$pn + $ldiff]"/>' +
  284. ' <xsl:copy>' +
  285. ' <xsl:copy-of select="@*"/>' +
  286. ' <xsl:variable name="b">' +
  287. ' <xsl:choose>' +
  288. ' <xsl:when test="not(string($cy/@crossout) or $cy/@crossout=\'none\')"><xsl:copy-of select="*"/></xsl:when>' +
  289. ' <xsl:otherwise>' +
  290. ' <m:menclose notation="{$cy/@crossout}"><xsl:copy-of select="*"/></m:menclose>' +
  291. ' </xsl:otherwise>' +
  292. ' </xsl:choose>' +
  293. ' </xsl:variable>' +
  294. ' <xsl:choose>' +
  295. ' <xsl:when test="$cy/m:none or not($cy/*)"><xsl:copy-of select="$b"/></xsl:when>' +
  296. ' <xsl:when test="not(string($cy/@location)) or $cy/@location=\'n\'">' +
  297. ' <m:mover>' +
  298. ' <xsl:copy-of select="$b"/><m:mpadded width="0em" lspace="-0.5width">' +
  299. ' <xsl:copy-of select="$cy/*"/>' +
  300. ' </m:mpadded>' +
  301. ' </m:mover>' +
  302. ' </xsl:when>' +
  303. ' <xsl:when test="$cy/@location=\'nw\'">' +
  304. ' <m:mmultiscripts><xsl:copy-of select="$b"/><m:mprescripts/><m:none/><m:mpadded lspace="-1width" width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:mmultiscripts>' +
  305. ' </xsl:when>' +
  306. ' <xsl:when test="$cy/@location=\'s\'">' +
  307. ' <m:munder><xsl:copy-of select="$b"/><m:mpadded width="0em" lspace="-0.5width"><xsl:copy-of select="$cy/*"/></m:mpadded></m:munder>' +
  308. ' </xsl:when>' +
  309. ' <xsl:when test="$cy/@location=\'sw\'">' +
  310. ' <m:mmultiscripts><xsl:copy-of select="$b"/><m:mprescripts/><m:mpadded lspace="-1width" width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded><m:none/></m:mmultiscripts>' +
  311. ' </xsl:when>' +
  312. ' <xsl:when test="$cy/@location=\'ne\'">' +
  313. ' <m:msup><xsl:copy-of select="$b"/><m:mpadded width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msup>' +
  314. ' </xsl:when>' +
  315. ' <xsl:when test="$cy/@location=\'se\'">' +
  316. ' <m:msub><xsl:copy-of select="$b"/><m:mpadded width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msub>' +
  317. ' </xsl:when>' +
  318. ' <xsl:when test="$cy/@location=\'w\'">' +
  319. ' <m:msup><m:mrow/><m:mpadded lspace="-1width" width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msup>' +
  320. ' <xsl:copy-of select="$b"/>' +
  321. ' </xsl:when>' +
  322. ' <xsl:when test="$cy/@location=\'e\'">' +
  323. ' <xsl:copy-of select="$b"/>' +
  324. ' <m:msup><m:mrow/><m:mpadded width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msup>' +
  325. ' </xsl:when>' +
  326. ' <xsl:otherwise>' +
  327. ' <xsl:copy-of select="$b"/>' +
  328. ' </xsl:otherwise>' +
  329. ' </xsl:choose>' +
  330. ' </xsl:copy>' +
  331. ' </xsl:for-each>' +
  332. ' </xsl:when>' +
  333. ' <xsl:otherwise>' +
  334. ' <xsl:for-each select="(//*)[position()&lt;= $offset]"><m:mtd/></xsl:for-each>' +
  335. ' <xsl:copy-of select="*"/>' +
  336. ' </xsl:otherwise>' +
  337. ' </xsl:choose>' +
  338. ' </m:mtr>' +
  339. ' </xsl:for-each>' +
  340. ' </m:mtable>' +
  341. '</xsl:variable>' +
  342. '<xsl:apply-templates mode="ml" select="c:node-set($m)"/>' +
  343. '</xsl:template>' +
  344. '<xsl:template match="*" mode="ml">' +
  345. ' <xsl:copy>' +
  346. ' <xsl:copy-of select="@*"/>' +
  347. ' <xsl:apply-templates mode="ml"/>' +
  348. ' </xsl:copy>' +
  349. '</xsl:template>' +
  350. '<xsl:template mode="ml" match="m:mtr[following-sibling::*[1][@class=\'msline\']]">' +
  351. ' <m:mtr>' +
  352. ' <xsl:copy-of select="@*"/>' +
  353. ' <xsl:variable name="m" select="following-sibling::*[1]/m:mtd"/>' +
  354. ' <xsl:for-each select="m:mtd">' +
  355. ' <xsl:variable name="p" select="position()"/>' +
  356. ' <m:mtd>' +
  357. ' <xsl:copy-of select="@*"/>' +
  358. ' <xsl:choose>' +
  359. ' <xsl:when test="$m[$p]/m:mpadded">' +
  360. ' <m:menclose notation="bottom">' +
  361. ' <m:mpadded depth=".1em" height="1em" width=".4em">' +
  362. ' <xsl:copy-of select="*"/>' +
  363. ' </m:mpadded>' +
  364. ' </m:menclose>' +
  365. ' </xsl:when>' +
  366. ' <xsl:otherwise>' +
  367. ' <xsl:copy-of select="*"/>' +
  368. ' </xsl:otherwise>' +
  369. ' </xsl:choose>' +
  370. ' </m:mtd>' +
  371. ' </xsl:for-each>' +
  372. ' </m:mtr>' +
  373. '</xsl:template><xsl:template mode="ml" match="m:mtr[not(preceding-sibling::*)][@class=\'msline\']" priority="3">' +
  374. ' <m:mtr>' +
  375. ' <xsl:copy-of select="@*"/>' +
  376. ' <xsl:for-each select="m:mtd">' +
  377. ' <m:mtd>' +
  378. ' <xsl:copy-of select="@*"/>' +
  379. ' <xsl:if test="m:mpadded">' +
  380. ' <m:menclose notation="bottom">' +
  381. ' <m:mpadded depth=".1em" height="1em" width=".4em">' +
  382. ' <m:mspace width=".2em"/>' +
  383. ' </m:mpadded>' +
  384. ' </m:menclose>' +
  385. ' </xsl:if>' +
  386. ' </m:mtd>' +
  387. ' </xsl:for-each>' +
  388. ' </m:mtr>' +
  389. '</xsl:template><xsl:template mode="ml" match="m:mtr[@class=\'msline\']" priority="2"/>' +
  390. '<xsl:template mode="mstack1" match="*">' +
  391. ' <xsl:param name="p"/>' +
  392. ' <xsl:param name="maxl" select="0"/>' +
  393. ' <m:mtr l="{1 + $p}">' +
  394. ' <xsl:if test="ancestor::mstack[1]/@stackalign=\'left\'">' +
  395. ' <xsl:attribute name="l"><xsl:value-of select="$p"/></xsl:attribute>' +
  396. ' </xsl:if>' +
  397. ' <m:mtd><xsl:apply-templates select="."/></m:mtd>' +
  398. ' </m:mtr>' +
  399. '</xsl:template>' +
  400. '<xsl:template mode="mstack1" match="m:msrow">' +
  401. ' <xsl:param name="p"/>' +
  402. ' <xsl:param name="maxl" select="0"/>' +
  403. ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' +
  404. ' <xsl:variable name="align">' +
  405. ' <xsl:choose>' +
  406. ' <xsl:when test="string($align1)=\'\'">decimalpoint</xsl:when>' +
  407. ' <xsl:otherwise><xsl:value-of select="$align1"/></xsl:otherwise>' +
  408. ' </xsl:choose>' +
  409. ' </xsl:variable>' +
  410. ' <xsl:variable name="row">' +
  411. ' <xsl:apply-templates mode="mstack1" select="*">' +
  412. ' <xsl:with-param name="p" select="0"/>' +
  413. ' </xsl:apply-templates>' +
  414. ' </xsl:variable>' +
  415. ' <xsl:text>&#10;</xsl:text>' +
  416. ' <xsl:variable name="l1">' +
  417. ' <xsl:choose>' +
  418. ' <xsl:when test="$align=\'decimalpoint\' and m:mn">' +
  419. ' <xsl:for-each select="c:node-set($row)/m:mtr[m:mtd/m:mn][1]">' +
  420. ' <xsl:value-of select="number(sum(@l))+count(preceding-sibling::*/@l)"/>' +
  421. ' </xsl:for-each>' +
  422. ' </xsl:when>' +
  423. ' <xsl:when test="$align=\'right\' or $align=\'decimalpoint\'">' +
  424. ' <xsl:value-of select="count(c:node-set($row)/m:mtr/m:mtd)"/>' +
  425. ' </xsl:when>' +
  426. ' <xsl:otherwise>' +
  427. ' <xsl:value-of select="0"/>' +
  428. ' </xsl:otherwise>' +
  429. ' </xsl:choose>' +
  430. ' </xsl:variable>' +
  431. ' <m:mtr class="msrow" l="{number($l1) + number(sum(@position)) +$p}">' +
  432. ' <xsl:copy-of select="c:node-set($row)/m:mtr/*"/>' +
  433. ' </m:mtr>' +
  434. '</xsl:template><xsl:template mode="mstack1" match="m:mn">' +
  435. ' <xsl:param name="p"/>' +
  436. ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' +
  437. ' <xsl:variable name="dp1" select="ancestor::*[@decimalpoint][1]/@decimalpoint"/>' +
  438. ' <xsl:variable name="align">' +
  439. ' <xsl:choose>' +
  440. ' <xsl:when test="string($align1)=\'\'">decimalpoint</xsl:when>' +
  441. ' <xsl:otherwise><xsl:value-of select="$align1"/></xsl:otherwise>' +
  442. ' </xsl:choose>' +
  443. ' </xsl:variable>' +
  444. ' <xsl:variable name="dp">' +
  445. ' <xsl:choose>' +
  446. ' <xsl:when test="string($dp1)=\'\'">.</xsl:when>' +
  447. ' <xsl:otherwise><xsl:value-of select="$dp1"/></xsl:otherwise>' +
  448. ' </xsl:choose>' +
  449. ' </xsl:variable>' +
  450. ' <m:mtr l="$p">' +
  451. ' <xsl:variable name="mn" select="normalize-space(.)"/>' +
  452. ' <xsl:variable name="len" select="string-length($mn)"/>' +
  453. ' <xsl:choose>' +
  454. ' <xsl:when test="$align=\'right\' or ($align=\'decimalpoint\' and not(contains($mn,$dp)))">' +
  455. ' <xsl:attribute name="l"><xsl:value-of select="$p + $len"/></xsl:attribute>' +
  456. ' </xsl:when>' +
  457. ' <xsl:when test="$align=\'center\'">' +
  458. ' <xsl:attribute name="l"><xsl:value-of select="round(($p + $len) div 2)"/></xsl:attribute>' +
  459. ' </xsl:when>' +
  460. ' <xsl:when test="$align=\'decimalpoint\'">' +
  461. ' <xsl:attribute name="l"><xsl:value-of select="$p + string-length(substring-before($mn,$dp))"/></xsl:attribute>' +
  462. ' </xsl:when>' +
  463. ' </xsl:choose> <xsl:for-each select="(//node())[position() &lt;=$len]">' +
  464. ' <xsl:variable name="pos" select="position()"/>' +
  465. ' <m:mtd><m:mn><xsl:value-of select="substring($mn,$pos,1)"/></m:mn></m:mtd>' +
  466. ' </xsl:for-each>' +
  467. ' </m:mtr>' +
  468. '</xsl:template>' +
  469. '<xsl:template match="m:msgroup" mode="mstack1">' +
  470. ' <xsl:param name="p"/>' +
  471. ' <xsl:variable name="s" select="number(sum(@shift))"/>' +
  472. ' <xsl:variable name="thisp" select="number(sum(@position))"/>' +
  473. ' <xsl:for-each select="*">' +
  474. ' <xsl:apply-templates mode="mstack1" select=".">' +
  475. ' <xsl:with-param name="p" select="number($p)+$thisp+(position()-1)*$s"/>' +
  476. ' </xsl:apply-templates>' +
  477. ' </xsl:for-each>' +
  478. '</xsl:template>' +
  479. '<xsl:template match="m:msline" mode="mstack1">' +
  480. ' <xsl:param name="p"/>' +
  481. ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' +
  482. ' <xsl:variable name="align">' +
  483. ' <xsl:choose>' +
  484. ' <xsl:when test="string($align1)=\'\'">decimalpoint</xsl:when>' +
  485. ' <xsl:otherwise><xsl:value-of select="$align1"/></xsl:otherwise>' +
  486. ' </xsl:choose>' +
  487. ' </xsl:variable>' +
  488. ' <m:mtr class="msline">' +
  489. ' <xsl:attribute name="l">' +
  490. ' <xsl:choose>' +
  491. ' <xsl:when test="not(string(@length)) or @length=0">*</xsl:when>' +
  492. ' <xsl:when test="string($align)=\'right\' or string($align)=\'decimalpoint\' "><xsl:value-of select="$p+ @length"/></xsl:when>' +
  493. ' <xsl:otherwise><xsl:value-of select="$p"/></xsl:otherwise>' +
  494. ' </xsl:choose>' +
  495. ' </xsl:attribute>' +
  496. ' <xsl:variable name="w">' +
  497. ' <xsl:choose>' +
  498. ' <xsl:when test="@mslinethickness=\'thin\'">0.1em</xsl:when>' +
  499. ' <xsl:when test="@mslinethickness=\'medium\'">0.15em</xsl:when>' +
  500. ' <xsl:when test="@mslinethickness=\'thick\'">0.2em</xsl:when>' +
  501. ' <xsl:when test="@mslinethickness"><xsl:value-of select="@mslinethickness"/></xsl:when>' +
  502. ' <xsl:otherwise>0.15em</xsl:otherwise>' +
  503. ' </xsl:choose>' +
  504. ' </xsl:variable>' +
  505. ' <xsl:choose>' +
  506. ' <xsl:when test="not(string(@length)) or @length=0">' +
  507. ' <m:mtd class="mslinemax">' +
  508. ' <m:mpadded lspace="-0.2em" width="0em" height="0em">' +
  509. ' <m:mfrac linethickness="{$w}">' +
  510. ' <m:mspace width=".4em"/>' +
  511. ' <m:mrow/>' +
  512. ' </m:mfrac>' +
  513. ' </m:mpadded>' +
  514. ' </m:mtd>' +
  515. ' </xsl:when>' +
  516. ' <xsl:otherwise>' +
  517. ' <xsl:variable name="l" select="@length"/>' +
  518. ' <xsl:for-each select="(//node())[position()&lt;=$l]">' +
  519. ' <m:mtd class="msline">' +
  520. ' <m:mpadded lspace="-0.2em" width="0em" height="0em">' +
  521. ' <m:mfrac linethickness="{$w}">' +
  522. ' <m:mspace width=".4em"/>' +
  523. ' <m:mrow/>' +
  524. ' </m:mfrac>' +
  525. ' </m:mpadded>' +
  526. ' </m:mtd>' +
  527. ' </xsl:for-each>' +
  528. ' </xsl:otherwise>' +
  529. ' </xsl:choose>' +
  530. ' </m:mtr>' +
  531. '</xsl:template>' +
  532. '<xsl:template match="m:mscarries" mode="mstack1">' +
  533. ' <xsl:param name="p"/>' +
  534. ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' +
  535. ' <xsl:variable name="l1">' +
  536. ' <xsl:choose>' +
  537. ' <xsl:when test="string($align1)=\'left\'">0</xsl:when>' +
  538. ' <xsl:otherwise><xsl:value-of select="count(*)"/></xsl:otherwise>' +
  539. ' </xsl:choose>' +
  540. ' </xsl:variable>' +
  541. ' <m:mtr class="mscarries" l="{$p + $l1 + sum(@position)}">' +
  542. ' <xsl:apply-templates select="*" mode="msc"/>' +
  543. ' </m:mtr>' +
  544. '</xsl:template><xsl:template match="*" mode="msc">' +
  545. ' <m:mtd>' +
  546. ' <xsl:copy-of select="../@location|../@crossout"/>' +
  547. ' <xsl:choose>' +
  548. ' <xsl:when test="../@scriptsizemultiplier">' +
  549. ' <m:mstyle mathsize="{round(../@scriptsizemultiplier div .007)}%">' +
  550. ' <xsl:apply-templates select="."/>' +
  551. ' </m:mstyle>' +
  552. ' </xsl:when>' +
  553. ' <xsl:otherwise>' +
  554. ' <xsl:apply-templates select="."/>' +
  555. ' </xsl:otherwise>' +
  556. ' </xsl:choose>' +
  557. ' </m:mtd>' +
  558. '</xsl:template><xsl:template match="m:mscarry" mode="msc">' +
  559. ' <m:mtd>' +
  560. ' <xsl:copy-of select="@location|@crossout"/>' +
  561. ' <xsl:choose>' +
  562. ' <xsl:when test="../@scriptsizemultiplier">' +
  563. ' <m:mstyle mathsize="{round(../@scriptsizemultiplier div .007)}%">' +
  564. ' <xsl:apply-templates/>' +
  565. ' </m:mstyle>' +
  566. ' </xsl:when>' +
  567. ' <xsl:otherwise>' +
  568. ' <xsl:apply-templates/>' +
  569. ' </xsl:otherwise>' +
  570. ' </xsl:choose>' +
  571. ' </m:mtd>' +
  572. '</xsl:template>' +
  573. '<xsl:template match="m:mlongdiv" priority="11">' +
  574. ' <xsl:variable name="ms">' +
  575. ' <m:mstack>' +
  576. ' <xsl:copy-of select="(ancestor-or-self::*/@decimalpoint)[last()]"/>' +
  577. ' <xsl:choose>' +
  578. ' <xsl:when test="@longdivstyle=\'left)(right\'">' +
  579. ' <m:msrow>' +
  580. ' <m:mrow><xsl:copy-of select="*[1]"/></m:mrow>' +
  581. ' <m:mo>)</m:mo>' +
  582. ' <xsl:copy-of select="*[3]"/>' +
  583. ' <m:mo>(</m:mo>' +
  584. ' <xsl:copy-of select="*[2]"/>' +
  585. ' </m:msrow>' +
  586. ' </xsl:when>' +
  587. ' <xsl:when test="@longdivstyle=\'left/\right\'">' +
  588. ' <m:msrow>' +
  589. ' <m:mrow><xsl:copy-of select="*[1]"/></m:mrow>' +
  590. ' <m:mo>/</m:mo>' +
  591. ' <xsl:copy-of select="*[3]"/>' +
  592. ' <m:mo>\</m:mo>' +
  593. ' <xsl:copy-of select="*[2]"/>' +
  594. ' </m:msrow>' +
  595. ' </xsl:when>' +
  596. ' <xsl:when test="@longdivstyle=\':right=right\'">' +
  597. ' <m:msrow>' +
  598. ' <xsl:copy-of select="*[3]"/>' +
  599. ' <m:mo>:</m:mo>' +
  600. ' <xsl:copy-of select="*[1]"/>' +
  601. ' <m:mo>=</m:mo>' +
  602. ' <xsl:copy-of select="*[2]"/>' +
  603. ' </m:msrow>' +
  604. ' </xsl:when>' +
  605. ' <xsl:when test="@longdivstyle=\'stackedrightright\'' +
  606. ' or @longdivstyle=\'mediumstackedrightright\'' +
  607. ' or @longdivstyle=\'shortstackedrightright\'' +
  608. ' or @longdivstyle=\'stackedleftleft\'' +
  609. ' ">' +
  610. ' <xsl:attribute name="align">top</xsl:attribute>' +
  611. ' <xsl:copy-of select="*[3]"/>' +
  612. ' </xsl:when>' +
  613. ' <xsl:when test="@longdivstyle=\'stackedleftlinetop\'">' +
  614. ' <xsl:copy-of select="*[2]"/>' +
  615. ' <m:msline length="{string-length(*[3])-1}"/>' +
  616. ' <m:msrow>' +
  617. ' <m:mrow>' +
  618. ' <m:menclose notation="bottom right">' +
  619. ' <xsl:copy-of select="*[1]"/>' +
  620. ' </m:menclose>' +
  621. ' </m:mrow>' +
  622. ' <xsl:copy-of select="*[3]"/>' +
  623. ' </m:msrow>' +
  624. ' </xsl:when>' +
  625. ' <xsl:when test="@longdivstyle=\'righttop\'">' +
  626. ' <xsl:copy-of select="*[2]"/>' +
  627. ' <m:msline length="{string-length(*[3])}"/>' +
  628. ' <m:msrow>' +
  629. ' <xsl:copy-of select="*[3]"/>' +
  630. ' <m:menclose notation="top left bottom">' +
  631. ' <xsl:copy-of select="*[1]"/></m:menclose>' +
  632. ' </m:msrow>' +
  633. ' </xsl:when>' +
  634. ' <xsl:otherwise>' +
  635. ' <xsl:copy-of select="*[2]"/>' +
  636. ' <m:msline length="{string-length(*[3])}"/>' +
  637. ' <m:msrow>' +
  638. ' <m:mrow><xsl:copy-of select="*[1]"/></m:mrow>' +
  639. ' <m:mo>)</m:mo>' +
  640. ' <xsl:copy-of select="*[3]"/>' +
  641. ' </m:msrow>' +
  642. ' </xsl:otherwise>' +
  643. ' </xsl:choose>' +
  644. ' <xsl:copy-of select="*[position()&gt;3]"/>' +
  645. ' </m:mstack>' +
  646. ' </xsl:variable>' +
  647. ' <xsl:choose>' +
  648. ' <xsl:when test="@longdivstyle=\'stackedrightright\'">' +
  649. ' <m:menclose notation="right">' +
  650. ' <xsl:apply-templates select="c:node-set($ms)"/>' +
  651. ' </m:menclose>' +
  652. ' <m:mtable align="top">' +
  653. ' <m:mtr>' +
  654. ' <m:menclose notation="bottom">' +
  655. ' <xsl:copy-of select="*[1]"/>' +
  656. ' </m:menclose>' +
  657. ' </m:mtr>' +
  658. ' <m:mtr>' +
  659. ' <mtd><xsl:copy-of select="*[2]"/></mtd>' +
  660. ' </m:mtr>' +
  661. ' </m:mtable>' +
  662. ' </xsl:when>' +
  663. ' <xsl:when test="@longdivstyle=\'mediumstackedrightright\'">' +
  664. ' <xsl:apply-templates select="c:node-set($ms)"/>' +
  665. ' <m:menclose notation="left">' +
  666. ' <m:mtable align="top">' +
  667. ' <m:mtr>' +
  668. ' <m:menclose notation="bottom">' +
  669. ' <xsl:copy-of select="*[1]"/>' +
  670. ' </m:menclose>' +
  671. ' </m:mtr>' +
  672. ' <m:mtr>' +
  673. ' <mtd><xsl:copy-of select="*[2]"/></mtd>' +
  674. ' </m:mtr>' +
  675. ' </m:mtable>' +
  676. ' </m:menclose>' +
  677. ' </xsl:when>' +
  678. ' <xsl:when test="@longdivstyle=\'shortstackedrightright\'">' +
  679. ' <xsl:apply-templates select="c:node-set($ms)"/>' +
  680. ' <m:mtable align="top">' +
  681. ' <m:mtr>' +
  682. ' <m:menclose notation="left bottom">' +
  683. ' <xsl:copy-of select="*[1]"/>' +
  684. ' </m:menclose>' +
  685. ' </m:mtr>' +
  686. ' <m:mtr>' +
  687. ' <mtd><xsl:copy-of select="*[2]"/></mtd>' +
  688. ' </m:mtr>' +
  689. ' </m:mtable>' +
  690. ' </xsl:when>' +
  691. ' <xsl:when test="@longdivstyle=\'stackedleftleft\'">' +
  692. ' <m:mtable align="top">' +
  693. ' <m:mtr>' +
  694. ' <m:menclose notation="bottom">' +
  695. ' <xsl:copy-of select="*[1]"/>' +
  696. ' </m:menclose>' +
  697. ' </m:mtr>' +
  698. ' <m:mtr>' +
  699. ' <mtd><xsl:copy-of select="*[2]"/></mtd>' +
  700. ' </m:mtr>' +
  701. ' </m:mtable>' +
  702. ' <m:menclose notation="left">' +
  703. ' <xsl:apply-templates select="c:node-set($ms)"/>' +
  704. ' </m:menclose>' +
  705. ' </xsl:when>' +
  706. ' <xsl:otherwise>' +
  707. ' <xsl:apply-templates select="c:node-set($ms)"/>' +
  708. ' </xsl:otherwise>' +
  709. ' </xsl:choose>' +
  710. '</xsl:template>' +
  711. '<xsl:template match="m:menclose[@notation=\'madruwb\']" mode="rtl">' +
  712. ' <m:menclose notation="bottom right">' +
  713. ' <xsl:apply-templates mode="rtl"/>' +
  714. ' </m:menclose>' +
  715. '</xsl:template></xsl:stylesheet>';
  716. /*
  717. * End of mml3mj.xsl material.
  718. */
  719. var mml3;
  720. if (window.XSLTProcessor) {
  721. // standard method: just use an XSLTProcessor and parse the stylesheet
  722. if (!MATHML.ParseXML) {MATHML.ParseXML = MATHML.createParser()}
  723. MATHML.mml3XSLT = new XSLTProcessor();
  724. MATHML.mml3XSLT.importStylesheet(MATHML.ParseXML(mml3Stylesheet));
  725. } else if (MathJax.Hub.Browser.isMSIE) {
  726. // nonstandard methods for Internet Explorer
  727. if (MathJax.Hub.Browser.versionAtLeast("9.0") || (document.documentMode||0) >= 9) {
  728. // For Internet Explorer >= 9, use createProcessor
  729. mml3 = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
  730. mml3.loadXML(mml3Stylesheet);
  731. var xslt = new ActiveXObject("Msxml2.XSLTemplate");
  732. xslt.stylesheet = mml3;
  733. MATHML.mml3XSLT = {
  734. mml3: xslt.createProcessor(),
  735. transformToDocument: function(doc) {
  736. this.mml3.input = doc;
  737. this.mml3.transform();
  738. return this.mml3.output;
  739. }
  740. }
  741. } else {
  742. // For Internet Explorer <= 8, use transformNode
  743. mml3 = MATHML.createMSParser();
  744. mml3.async = false;
  745. mml3.loadXML(mml3Stylesheet);
  746. MATHML.mml3XSLT = {
  747. mml3: mml3,
  748. transformToDocument: function(doc) {
  749. return doc.documentElement.transformNode(this.mml3);
  750. }
  751. }
  752. }
  753. } else {
  754. // No XSLT support. Do not change the <math> content.
  755. MATHML.mml3XSLT = null;
  756. }
  757. // Tweak CSS to avoid some browsers rearranging HTML output
  758. MathJax.Ajax.Styles({
  759. ".MathJax .mi, .MathJax .mo, .MathJax .mn, .MathJax .mtext": {
  760. direction: "ltr",
  761. display: "inline-block"
  762. },
  763. ".MathJax .ms, .MathJax .mspace, .MathJax .mglyph": {
  764. direction: "ltr",
  765. display: "inline-block"
  766. }
  767. });
  768. MathJax.Hub.Startup.signal.Post("MathML mml3.js Ready");
  769. });
  770. MathJax.Ajax.loadComplete("[MathJax]/extensions/MathML/mml3.js");