mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-11-04 03:27:00 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			206 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*************************************************************
 | 
						|
 *
 | 
						|
 *  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-2012 Design Science, Inc.
 | 
						|
 * 
 | 
						|
 *  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.0",
 | 
						|
  config: {
 | 
						|
    preview: "alttext"      // Use the <math> element's alttext as the 
 | 
						|
                            //   preview.  Set to "none" for no preview,
 | 
						|
                            //   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}
 | 
						|
    //
 | 
						|
    //  Handle all math tags with no namespaces
 | 
						|
    //
 | 
						|
    this.ProcessMathArray(element.getElementsByTagName("math"));
 | 
						|
    //
 | 
						|
    //  Handle math with namespaces in XHTML
 | 
						|
    //
 | 
						|
    if (element.getElementsByTagNameNS)
 | 
						|
      {this.ProcessMathArray(element.getElementsByTagNameNS(this.MMLnamespace,"math"))}
 | 
						|
    //
 | 
						|
    //  Handle math with namespaces in HTML
 | 
						|
    //
 | 
						|
    var i, m;
 | 
						|
    if (document.namespaces) {
 | 
						|
      //
 | 
						|
      // IE namespaces are listed in document.namespaces
 | 
						|
      //
 | 
						|
      for (i = 0, m = document.namespaces.length; i < m; i++) {
 | 
						|
        var ns = document.namespaces[i];
 | 
						|
        if (ns.urn === this.MMLnamespace)
 | 
						|
          {this.ProcessMathArray(element.getElementsByTagName(ns.name+":math"))}
 | 
						|
      }
 | 
						|
    } 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.ProcessMathArray(element.getElementsByTagName(attr.nodeName.substr(6)+":math"))}
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  },
 | 
						|
  
 | 
						|
  ProcessMathArray: function (math) {
 | 
						|
    var i;
 | 
						|
    if (math.length) {
 | 
						|
      if (this.MathTagBug) {
 | 
						|
        for (i = math.length-1; i >= 0; i--) {
 | 
						|
          if (math[i].nodeName === "MATH") {this.ProcessMathFlattened(math[i])}
 | 
						|
                                      else {this.ProcessMath(math[i])}
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        for (i = math.length-1; i >= 0; i--) {this.ProcessMath(math[i])}
 | 
						|
      }
 | 
						|
    }
 | 
						|
  },
 | 
						|
  
 | 
						|
  ProcessMath: function (math) {
 | 
						|
    var parent = math.parentNode;
 | 
						|
    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;
 | 
						|
    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) {
 | 
						|
          // 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;
 | 
						|
    if (this.config.preview === "alttext") {
 | 
						|
      var text = math.getAttribute("alttext");
 | 
						|
      if (text != null) {preview = [this.filterPreview(text)]}
 | 
						|
    } else if (this.config.preview instanceof Array) {preview = this.config.preview}
 | 
						|
    if (preview) {
 | 
						|
      preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview);
 | 
						|
      script.parentNode.insertBefore(preview,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
 | 
						|
  }
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.mml2jax]);
 | 
						|
MathJax.Ajax.loadComplete("[MathJax]/extensions/mml2jax.js");
 |