123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
- /* vim: set ts=2 et sw=2 tw=80: */
- /*************************************************************
- *
- * MathJax/extensions/mml2jax.js
- *
- * Implements the MathML to Jax preprocessor that locates <math> nodes
- * within the text of a document and replaces them with SCRIPT tags
- * for processing by MathJax.
- *
- * ---------------------------------------------------------------------
- *
- * Copyright (c) 2010-2017 The MathJax Consortium
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- MathJax.Extension.mml2jax = {
- version: "2.7.2",
- config: {
- preview: "mathml" // Use the <math> element as the
- // preview. Set to "none" for no preview,
- // set to "alttext" to use the alttext attribute
- // of the <math> element, set to "altimg" to use
- // an image described by the altimg* attributes
- // or set to an array specifying an HTML snippet
- // to use a fixed preview for all math
- },
- MMLnamespace: "http://www.w3.org/1998/Math/MathML",
-
- PreProcess: function (element) {
- if (!this.configured) {
- this.config = MathJax.Hub.CombineConfig("mml2jax",this.config);
- if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)}
- this.InitBrowser();
- this.configured = true;
- }
- if (typeof(element) === "string") {element = document.getElementById(element)}
- if (!element) {element = document.body}
- var mathArray = [];
- //
- // Handle all math tags with no namespaces
- //
- this.PushMathElements(mathArray,element,"math");
- //
- // Handle math with namespaces in XHTML
- //
- this.PushMathElements(mathArray,element,"math",this.MMLnamespace);
- //
- // Handle math with namespaces in HTML
- //
- var i, m;
- if (typeof(document.namespaces) !== "undefined") {
- //
- // IE namespaces are listed in document.namespaces
- //
- try {
- for (i = 0, m = document.namespaces.length; i < m; i++) {
- var ns = document.namespaces[i];
- if (ns.urn === this.MMLnamespace)
- {this.PushMathElements(mathArray,element,ns.name+":math")}
- }
- } catch (err) {}
- } else {
- //
- // Everybody else
- //
- var html = document.getElementsByTagName("html")[0];
- if (html) {
- for (i = 0, m = html.attributes.length; i < m; i++) {
- var attr = html.attributes[i];
- if (attr.nodeName.substr(0,6) === "xmlns:" && attr.nodeValue === this.MMLnamespace)
- {this.PushMathElements(mathArray,element,attr.nodeName.substr(6)+":math")}
- }
- }
- }
- this.ProcessMathArray(mathArray);
- },
-
- PushMathElements: function (array,element,name,namespace) {
- var math, preview = MathJax.Hub.config.preRemoveClass;
- if (namespace) {
- if (!element.getElementsByTagNameNS) return;
- math = element.getElementsByTagNameNS(namespace,name);
- } else {
- math = element.getElementsByTagName(name);
- }
- for (var i = 0, m = math.length; i < m; i++) {
- var parent = math[i].parentNode;
- if (parent && parent.className !== preview &&
- !parent.isMathJax && !math[i].prefix === !namespace) array.push(math[i]);
- }
- },
-
- ProcessMathArray: function (math) {
- var i, m = math.length;
- if (m) {
- if (this.MathTagBug) {
- for (i = 0; i < m; i++) {
- if (math[i].nodeName === "MATH") {this.ProcessMathFlattened(math[i])}
- else {this.ProcessMath(math[i])}
- }
- } else {
- for (i = 0; i < m; i++) {this.ProcessMath(math[i])}
- }
- }
- },
-
- ProcessMath: function (math) {
- var parent = math.parentNode;
- if (!parent || parent.className === MathJax.Hub.config.preRemoveClass) return;
- var script = document.createElement("script");
- script.type = "math/mml";
- parent.insertBefore(script,math);
- if (this.AttributeBug) {
- var html = this.OuterHTML(math);
- if (this.CleanupHTML) {
- html = html.replace(/<\?import .*?>/i,"").replace(/<\?xml:namespace .*?\/>/i,"");
- html = html.replace(/ /g," ");
- }
- MathJax.HTML.setScript(script,html); parent.removeChild(math);
- } else {
- var span = MathJax.HTML.Element("span"); span.appendChild(math);
- MathJax.HTML.setScript(script,span.innerHTML);
- }
- if (this.config.preview !== "none") {this.createPreview(math,script)}
- },
-
- ProcessMathFlattened: function (math) {
- var parent = math.parentNode;
- if (!parent || parent.className === MathJax.Hub.config.preRemoveClass) return;
- var script = document.createElement("script");
- script.type = "math/mml";
- parent.insertBefore(script,math);
- var mml = "", node, MATH = math;
- while (math && math.nodeName !== "/MATH") {
- node = math; math = math.nextSibling;
- mml += this.NodeHTML(node);
- node.parentNode.removeChild(node);
- }
- if (math && math.nodeName === "/MATH") {math.parentNode.removeChild(math)}
- script.text = mml + "</math>";
- if (this.config.preview !== "none") {this.createPreview(MATH,script)}
- },
-
- NodeHTML: function (node) {
- var html, i, m;
- if (node.nodeName === "#text") {
- html = this.quoteHTML(node.nodeValue);
- } else if (node.nodeName === "#comment") {
- html = "<!--" + node.nodeValue + "-->"
- } else {
- // In IE, outerHTML doesn't properly quote attributes, so quote them by hand
- // In Opera, HTML special characters aren't quoted in attributes, so quote them
- html = "<"+node.nodeName.toLowerCase();
- for (i = 0, m = node.attributes.length; i < m; i++) {
- var attribute = node.attributes[i];
- if (attribute.specified && attribute.nodeName.substr(0,10) !== "_moz-math-") {
- // Opera 11.5 beta turns xmlns into xmlns:xmlns, so put it back (*** check after 11.5 is out ***)
- html += " "+attribute.nodeName.toLowerCase().replace(/xmlns:xmlns/,"xmlns")+"=";
- var value = attribute.nodeValue; // IE < 8 doesn't properly set style by setAttributes
- if (value == null && attribute.nodeName === "style" && node.style) {value = node.style.cssText}
- html += '"'+this.quoteHTML(value)+'"';
- }
- }
- html += ">";
- // Handle internal HTML (possibly due to <semantics> annotation or missing </math>)
- if (node.outerHTML != null && node.outerHTML.match(/(.<\/[A-Z]+>|\/>)$/)) {
- for (i = 0, m = node.childNodes.length; i < m; i++)
- {html += this.OuterHTML(node.childNodes[i])}
- html += "</"+node.nodeName.toLowerCase()+">";
- }
- }
- return html;
- },
- OuterHTML: function (node) {
- if (node.nodeName.charAt(0) === "#") {return this.NodeHTML(node)}
- if (!this.AttributeBug) {return node.outerHTML}
- var html = this.NodeHTML(node);
- for (var i = 0, m = node.childNodes.length; i < m; i++)
- {html += this.OuterHTML(node.childNodes[i]);}
- html += "</"+node.nodeName.toLowerCase()+">";
- return html;
- },
- quoteHTML: function (string) {
- if (string == null) {string = ""}
- return string.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/\"/g,""");
- },
-
- createPreview: function (math,script) {
- var preview = this.config.preview;
- if (preview === "none") return;
- var isNodePreview = false;
- var previewClass = MathJax.Hub.config.preRemoveClass;
- if ((script.previousSibling||{}).className === previewClass) return;
- if (preview === "mathml") {
- isNodePreview = true;
- // mathml preview does not work with IE < 9, so fallback to alttext.
- if (this.MathTagBug) {preview = "alttext"} else {preview = math.cloneNode(true)}
- }
- if (preview === "alttext" || preview === "altimg") {
- isNodePreview = true;
- var alttext = this.filterPreview(math.getAttribute("alttext"));
- if (preview === "alttext") {
- if (alttext != null) {preview = MathJax.HTML.TextNode(alttext)} else {preview = null}
- } else {
- var src = math.getAttribute("altimg");
- if (src != null) {
- // FIXME: use altimg-valign when display="inline"?
- var style = {width: math.getAttribute("altimg-width"), height: math.getAttribute("altimg-height")};
- preview = MathJax.HTML.Element("img",{src:src,alt:alttext,style:style});
- } else {preview = null}
- }
- }
- if (preview) {
- var span;
- if (isNodePreview) {
- span = MathJax.HTML.Element("span",{className:previewClass});
- span.appendChild(preview);
- } else {
- span = MathJax.HTML.Element("span",{className:previewClass},preview);
- }
- script.parentNode.insertBefore(span,script);
- }
- },
-
- filterPreview: function (text) {return text},
-
- InitBrowser: function () {
- var test = MathJax.HTML.Element("span",{id:"<", className: "mathjax", innerHTML: "<math><mi>x</mi><mspace /></math>"});
- var html = test.outerHTML || "";
- this.AttributeBug = html !== "" && !(
- html.match(/id="<"/) && // "<" should convert to "<"
- html.match(/class="mathjax"/) && // IE leaves out quotes
- html.match(/<\/math>/) // Opera 9 drops tags after self-closing tags
- );
- this.MathTagBug = test.childNodes.length > 1; // IE < 9 flattens unknown tags
- this.CleanupHTML = MathJax.Hub.Browser.isMSIE; // remove namespace and other added tags
- }
- };
- //
- // We register the preprocessors with the following priorities:
- // - mml2jax.js: 5
- // - jsMath2jax.js: 8
- // - asciimath2jax.js, tex2jax.js: 10 (default)
- // See issues 18 and 484 and the other *2jax.js files.
- //
- MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.mml2jax],5);
- MathJax.Ajax.loadComplete("[MathJax]/extensions/mml2jax.js");
|