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