diff --git a/resources/viewer/mathjax/MathJax.js b/resources/viewer/mathjax/MathJax.js index 1763eb6098..689ef5a177 100644 --- a/resources/viewer/mathjax/MathJax.js +++ b/resources/viewer/mathjax/MathJax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax.js @@ -9,7 +12,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -24,13 +27,28 @@ * limitations under the License. */ -if (document.getElementById && document.childNodes && document.createElement) { -if (!window.MathJax) {window.MathJax= {}} -if (!MathJax.Hub) { // skip if already loaded +// +// Check if browser can support MathJax (no one fails this nowadays) +// +if (document.getElementById && document.childNodes && document.createElement) { +// +// Skip if MathJax is already loaded +// +if (!(window.MathJax && MathJax.Hub)) { -MathJax.version = "2.0"; -MathJax.fileversion = "2.0"; +// +// Get author configuration from MathJax variable, if any +// +if (window.MathJax) {window.MathJax = {AuthorConfig: window.MathJax}} + else {window.MathJax = {}} + +// MathJax.isPacked = true; // This line is uncommented by the packer. + +MathJax.version = "2.6.0"; +MathJax.fileversion = "2.6.0"; +MathJax.cdnVersion = "2.6.0"; // specifies a revision to break caching +MathJax.cdnFileVersions = {}; // can be used to specify revisions for individual files /**********************************************************/ @@ -40,22 +58,12 @@ MathJax.fileversion = "2.0"; var PROTO = []; // a static object used to indicate when a prototype is being created var OBJECT = function (def) { - var obj = def.constructor; if (!obj) {obj = new Function("")} + var obj = def.constructor; if (!obj) {obj = function () {}} for (var id in def) {if (id !== 'constructor' && def.hasOwnProperty(id)) {obj[id] = def[id]}} return obj; }; var CONSTRUCTOR = function () { - return new Function ("return arguments.callee.Init.call(this,arguments)"); - }; - // - // Test for Safari 2.x bug (can't replace prototype for result of new Function()). - // (We don't use this version for everyone since it is a closure and we don't need that). - // - var BUGTEST = CONSTRUCTOR(); BUGTEST.prototype = {bug_test: 1}; - if (!BUGTEST.prototype.bug_test) { - CONSTRUCTOR = function () { - return function () {return arguments.callee.Init.call(this,arguments)}; - }; + return function () {return arguments.callee.Init.call(this,arguments)}; }; BASE.Object = OBJECT({ @@ -133,26 +141,17 @@ MathJax.fileversion = "2.0"; }, wrap: function (id,f) { - if (typeof(f) === 'function' && f.toString().match(/\.\s*SUPER\s*\(/)) { - var fn = new Function(this.wrapper); - fn.label = id; fn.original = f; f = fn; - fn.toString = this.stringify; - } - return f; - }, - - wrapper: function () { - var fn = arguments.callee; - this.SUPER = fn.SUPER[fn.label]; - try {var result = fn.original.apply(this,arguments)} - catch (err) {delete this.SUPER; throw err} - delete this.SUPER; - return result; - }.toString().replace(/^\s*function\s*\(\)\s*\{\s*/i,"").replace(/\s*\}\s*$/i,""), - - toString: function () { - return this.original.toString.apply(this.original,arguments); + if (typeof(f) !== 'function' || !f.toString().match(/\.\s*SUPER\s*\(/)) {return f} + var fn = function () { + this.SUPER = fn.SUPER[id]; + try {var result = f.apply(this,arguments)} catch (err) {delete this.SUPER; throw err} + delete this.SUPER; + return result; + } + fn.toString = function () {return f.toString.apply(f,arguments)} + return fn; } + }) }); @@ -216,7 +215,7 @@ MathJax.fileversion = "2.0"; // Create a callback from an associative array // var CALLBACK = function (data) { - var cb = new Function("return arguments.callee.execute.apply(arguments.callee,arguments)"); + var cb = function () {return arguments.callee.execute.apply(arguments.callee,arguments)}; for (var id in CALLBACK.prototype) { if (CALLBACK.prototype.hasOwnProperty(id)) { if (typeof(data[id]) !== 'undefined') {cb[id] = data[id]} @@ -243,40 +242,45 @@ MathJax.fileversion = "2.0"; var ISCALLBACK = function (f) { return (typeof(f) === "function" && f.isCallback); } + // // Evaluate a string in global context // var EVAL = function (code) {return eval.call(window,code)} - EVAL("var __TeSt_VaR__ = 1"); // check if it works in global context - if (window.__TeSt_VaR__) { - try { delete window.__TeSt_VaR__; } // NOTE IE9 throws when in IE7 mode - catch (error) { window.__TeSt_VaR__ = null; } - } else { - if (window.execScript) { - // IE - EVAL = function (code) { - BASE.__code = code; - code = "try {"+BASENAME+".__result = eval("+BASENAME+".__code)} catch(err) {"+BASENAME+".__result = err}"; - window.execScript(code); - var result = BASE.__result; delete BASE.__result; delete BASE.__code; - if (result instanceof Error) {throw result} - return result; - } + var TESTEVAL = function () { + EVAL("var __TeSt_VaR__ = 1"); // check if it works in global context + if (window.__TeSt_VaR__) { + try { delete window.__TeSt_VaR__; } // NOTE IE9 throws when in IE7 mode + catch (error) { window.__TeSt_VaR__ = null; } } else { - // Safari2 - EVAL = function (code) { - BASE.__code = code; - code = "try {"+BASENAME+".__result = eval("+BASENAME+".__code)} catch(err) {"+BASENAME+".__result = err}"; - var head = (document.getElementsByTagName("head"))[0]; if (!head) {head = document.body} - var script = document.createElement("script"); - script.appendChild(document.createTextNode(code)); - head.appendChild(script); head.removeChild(script); - var result = BASE.__result; delete BASE.__result; delete BASE.__code; - if (result instanceof Error) {throw result} - return result; + if (window.execScript) { + // IE + EVAL = function (code) { + BASE.__code = code; + code = "try {"+BASENAME+".__result = eval("+BASENAME+".__code)} catch(err) {"+BASENAME+".__result = err}"; + window.execScript(code); + var result = BASE.__result; delete BASE.__result; delete BASE.__code; + if (result instanceof Error) {throw result} + return result; + } + } else { + // Safari2 + EVAL = function (code) { + BASE.__code = code; + code = "try {"+BASENAME+".__result = eval("+BASENAME+".__code)} catch(err) {"+BASENAME+".__result = err}"; + var head = (document.getElementsByTagName("head"))[0]; if (!head) {head = document.body} + var script = document.createElement("script"); + script.appendChild(document.createTextNode(code)); + head.appendChild(script); head.removeChild(script); + var result = BASE.__result; delete BASE.__result; delete BASE.__code; + if (result instanceof Error) {throw result} + return result; + } } } + TESTEVAL = null; } + // // Create a callback from various types of data // @@ -301,6 +305,7 @@ MathJax.fileversion = "2.0"; return CALLBACK({hook: args[1], object: args[0], data: args.slice(2)}); } } else if (typeof(args) === 'string') { + if (TESTEVAL) TESTEVAL(); return CALLBACK({hook: EVAL, data: [args]}); } else if (args instanceof Object) { return CALLBACK(args); @@ -375,7 +380,9 @@ MathJax.fileversion = "2.0"; // Init: function (reset) { this.hooks = []; + this.remove = []; // used when hooks are removed during execution of list this.reset = reset; + this.running = false; }, // // Add a callback to the list, in priority order (default priority is 10) @@ -391,25 +398,42 @@ MathJax.fileversion = "2.0"; }, Remove: function (hook) { for (var i = 0, m = this.hooks.length; i < m; i++) { - if (this.hooks[i] === hook) {this.hooks.splice(i,1); return} + if (this.hooks[i] === hook) { + if (this.running) {this.remove.push(i)} + else {this.hooks.splice(i,1)} + return; + } } }, // // Execute the list of callbacks, resetting them if requested. // If any return callbacks, return a callback that will be // executed when they all have completed. + // Remove any hooks that requested being removed during processing. // Execute: function () { var callbacks = [{}]; + this.running = true; for (var i = 0, m = this.hooks.length; i < m; i++) { if (this.reset) {this.hooks[i].reset()} var result = this.hooks[i].apply(window,arguments); if (ISCALLBACK(result) && !result.called) {callbacks.push(result)} } + this.running = false; + if (this.remove.length) {this.RemovePending()} if (callbacks.length === 1) {return null} if (callbacks.length === 2) {return callbacks[1]} return AFTER.apply({},callbacks); + }, + // + // Remove hooks that asked to be removed during execution of list + // + RemovePending: function () { + this.remove = this.remove.sort(); + for (var i = this.remove.length-1; i >= 0; i--) {this.hooks.splice(i,1)} + this.remove = []; } + }); // @@ -434,7 +458,7 @@ MathJax.fileversion = "2.0"; // Create the queue and push any commands that are specified // Init: function () { - this.pending = 0; this.running = 0; + this.pending = this.running = 0; this.queue = []; this.Push.apply(this,arguments); }, @@ -489,6 +513,8 @@ MathJax.fileversion = "2.0"; this.name = name; this.posted = []; // the messages posted so far this.listeners = HOOKS(true); // those with interest in this signal + this.posting = false; + this.callback = null; }, // // Post a message to the signal listeners, with callback for when complete @@ -503,7 +529,7 @@ MathJax.fileversion = "2.0"; this.Suspend(); this.posting = true; var result = this.listeners.Execute(message); if (ISCALLBACK(result) && !result.called) {WAITFOR(result,this)} - this.Resume(); delete this.posting; + this.Resume(); this.posting = false; if (!this.pending) {this.call()} } return callback; @@ -527,7 +553,7 @@ MathJax.fileversion = "2.0"; call: function () {this.callback(this); this.Process()}, // - // A listener calls this to register intrest in the signal (so it will be called + // A listener calls this to register interest in the signal (so it will be called // when posts occur). If ignorePast is true, it will not be sent the post history. // Interest: function (callback,ignorePast,priority) { @@ -559,15 +585,22 @@ MathJax.fileversion = "2.0"; this.hooks[msg].Add(callback,priority); for (var i = 0, m = this.posted.length; i < m; i++) {if (this.posted[i] == msg) {callback.reset(); callback(this.posted[i])}} + callback.msg = msg; // keep track so we can remove it return callback; }, // // Execute the message hooks for the given message // - ExecuteHooks: function (msg,more) { + ExecuteHooks: function (msg) { var type = ((msg instanceof Array) ? msg[0] : msg); if (!this.hooks[type]) {return null} return this.hooks[type].Execute(msg); + }, + // + // Remove a hook safely + // + RemoveHook: function (hook) { + this.hooks[hook.msg].Remove(hook); } },{ @@ -608,7 +641,7 @@ MathJax.fileversion = "2.0"; if (document.styleSheets && document.styleSheets.length > sheets) {sheets = document.styleSheets.length} if (!head) { - head = (document.getElementsByTagName("head"))[0]; + head = document.head || ((document.getElementsByTagName("head"))[0]); if (!head) {head = document.body} } return head; @@ -624,25 +657,57 @@ MathJax.fileversion = "2.0"; SCRIPTS = []; }; + var PATH = {}; + PATH[BASENAME] = ""; // empty path gets the root URL + BASE.Ajax = { loaded: {}, // files already loaded loading: {}, // files currently in process of loading loadHooks: {}, // hooks to call when files are loaded timeout: 15*1000, // timeout for loading of files (15 seconds) styleDelay: 1, // delay to use before styles are available - config: {root: ""}, // URL of root directory to load from + config: { + root: "", // URL of root directory to load from + path: PATH // paths to named URL's (e.g., [MathJax]/...) + }, STATUS: { OK: 1, // file is loading or did load OK ERROR: -1 // file timed out during load }, - - rootPattern: new RegExp("^\\["+BASENAME+"\\]"), - + // - // Return a complete URL to a file (replacing the root pattern) + // Return a complete URL to a file (replacing any root names) // - fileURL: function (file) {return file.replace(this.rootPattern,this.config.root)}, + fileURL: function (file) { + var match = file.match(/^\[([-._a-z0-9]+)\]/i); + if (match && match[1] in PATH) + {file = (PATH[match[1]]||this.config.root) + file.substr(match[1].length+2)} + return file; + }, + // + // Replace root names if URL includes one + // + fileName: function (url) { + var root = this.config.root; + if (url.substr(0,root.length) === root) {url = "["+BASENAME+"]"+url.substr(root.length)} + else { + for (var id in PATH) {if (PATH.hasOwnProperty(id) && PATH[id]) { + if (url.substr(0,PATH[id].length) === PATH[id]) + {url = "["+id+"]"+url.substr(PATH[id].length); break} + }} + } + return url; + }, + // + // Cache-breaking revision number for file + // + fileRev: function (file) { + var rev = BASE.cdnFileVersions[name] || BASE.cdnVersion; + if (rev) {rev = "?rev="+rev} + return rev; + }, + urlRev: function (file) {return this.fileURL(file)+this.fileRev(file)}, // // Load a file if it hasn't been already. @@ -650,8 +715,10 @@ MathJax.fileversion = "2.0"; // Require: function (file,callback) { callback = BASE.Callback(callback); var type; - if (file instanceof Object) {for (var i in file) {}; type = i.toUpperCase(); file = file[i]} - else {type = file.split(/\./).pop().toUpperCase()} + if (file instanceof Object) { + for (var i in file) + {if (file.hasOwnProperty(i)) {type = i.toUpperCase(); file = file[i]}} + } else {type = file.split(/\./).pop().toUpperCase()} file = this.fileURL(file); // FIXME: check that URL is OK if (this.loaded[file]) { @@ -669,15 +736,17 @@ MathJax.fileversion = "2.0"; // Load: function (file,callback) { callback = BASE.Callback(callback); var type; - if (file instanceof Object) {for (var i in file) {}; type = i.toUpperCase(); file = file[i]} - else {type = file.split(/\./).pop().toUpperCase()} + if (file instanceof Object) { + for (var i in file) + {if (file.hasOwnProperty(i)) {type = i.toUpperCase(); file = file[i]}} + } else {type = file.split(/\./).pop().toUpperCase()} file = this.fileURL(file); if (this.loading[file]) { this.addHook(file,callback); } else { this.head = HEAD(this.head); if (this.loader[type]) {this.loader[type].call(this,file,callback)} - else {throw Error("Can't load files of type "+type)} + else {throw Error("Can't load files of type "+type)} } return callback; }, @@ -688,7 +757,8 @@ MathJax.fileversion = "2.0"; // LoadHook: function (file,callback,priority) { callback = BASE.Callback(callback); - if (file instanceof Object) {for (var i in file) {file = file[i]}} + if (file instanceof Object) + {for (var i in file) {if (file.hasOwnProperty(i)) {file = file[i]}}} file = this.fileURL(file); if (this.loaded[file]) {callback(this.loaded[file])} else {this.addHook(file,callback,priority)} @@ -697,6 +767,13 @@ MathJax.fileversion = "2.0"; addHook: function (file,callback,priority) { if (!this.loadHooks[file]) {this.loadHooks[file] = MathJax.Callback.Hooks()} this.loadHooks[file].Add(callback,priority); + callback.file = file; + }, + removeHook: function (hook) { + if (this.loadHooks[hook.file]) { + this.loadHooks[hook.file].Remove(hook); + if (!this.loadHooks[hook.file].hooks.length) {delete this.loadHooks[hook.file]} + } }, // @@ -718,29 +795,36 @@ MathJax.fileversion = "2.0"; // Create a SCRIPT tag to load the file // JS: function (file,callback) { + var name = this.fileName(file); var script = document.createElement("script"); var timeout = BASE.Callback(["loadTimeout",this,file]); this.loading[file] = { callback: callback, - message: BASE.Message.File(file), timeout: setTimeout(timeout,this.timeout), status: this.STATUS.OK, script: script }; + // + // Add this to the structure above after it is created to prevent recursion + // when loading the initial localization file (before loading messsage is available) + // + this.loading[file].message = BASE.Message.File(name); script.onerror = timeout; // doesn't work in IE and no apparent substitute script.type = "text/javascript"; - script.src = file; + script.src = file+this.fileRev(name); this.head.appendChild(script); }, // // Create a LINK tag to load the style sheet // CSS: function (file,callback) { + var name = this.fileName(file); var link = document.createElement("link"); - link.rel = "stylesheet"; link.type = "text/css"; link.href = file; + link.rel = "stylesheet"; link.type = "text/css"; + link.href = file+this.fileRev(name); this.loading[file] = { callback: callback, - message: BASE.Message.File(file), + message: BASE.Message.File(name), status: this.STATUS.OK }; this.head.appendChild(link); @@ -762,9 +846,9 @@ MathJax.fileversion = "2.0"; if (node.nodeName === "STYLE" && node.styleSheet && typeof(node.styleSheet.cssText) !== 'undefined') { callback(this.STATUS.OK); // MSIE processes style immediately, but doesn't set its styleSheet! - } else if (window.chrome && typeof(window.sessionStorage) !== "undefined" && - node.nodeName === "STYLE") { - callback(this.STATUS.OK); // Same for Chrome 5 (beta), Grrr. + } else if (window.chrome && node.nodeName === "LINK") { + callback(this.STATUS.OK); // Chrome doesn't give access to cssRules for stylesheet in + // a link node, so we can't detect when it is loaded. } else if (isSafari2) { this.timer.start(this,[this.timer.checkSafari2,sheets++,callback],this.styleDelay); } else { @@ -779,7 +863,7 @@ MathJax.fileversion = "2.0"; check = BASE.Callback(check); check.execute = this.execute; check.time = this.time; check.STATUS = AJAX.STATUS; check.timeout = timeout || AJAX.timeout; - check.delay = check.total = 0; + check.delay = check.total = delay || 0; if (delay) {setTimeout(check,delay)} else {check()} }, // @@ -880,7 +964,7 @@ MathJax.fileversion = "2.0"; // The default error hook for file load failures // loadError: function (file) { - BASE.Message.Set("File failed to load: "+file,null,2000); + BASE.Message.Set(["LoadFailed","File failed to load: %1",file],null,2000); BASE.Hub.signal.Post(["file load error",file]); }, @@ -936,7 +1020,7 @@ MathJax.fileversion = "2.0"; return string; } }; - + })("MathJax"); /**********************************************************/ @@ -956,19 +1040,25 @@ MathJax.HTML = { // " for more details.)"]); // Element: function (type,def,contents) { - var obj = document.createElement(type); + var obj = document.createElement(type), id; if (def) { - if (def.style) { + if (def.hasOwnProperty("style")) { var style = def.style; def.style = {}; - for (var id in style) {if (style.hasOwnProperty(id)) + for (id in style) {if (style.hasOwnProperty(id)) {def.style[id.replace(/-([a-z])/g,this.ucMatch)] = style[id]}} } MathJax.Hub.Insert(obj,def); + for (id in def) { + if (id === "role" || id.substr(0,5) === "aria-") obj.setAttribute(id,def[id]); + } } if (contents) { - for (var i = 0; i < contents.length; i++) { + if (!(contents instanceof Array)) {contents = [contents]} + for (var i = 0, m = contents.length; i < m; i++) { if (contents[i] instanceof Array) { obj.appendChild(this.Element(contents[i][0],contents[i][1],contents[i][2])); + } else if (type === "script") { // IE throws an error if script is added as a text node + this.setScript(obj, contents[i]); } else { obj.appendChild(document.createTextNode(contents[i])); } @@ -1017,7 +1107,7 @@ MathJax.HTML = { var time = new Date(); time.setDate(time.getDate() + this.expires); cookie += '; expires='+time.toGMTString(); } - document.cookie = cookie+"; path=/"; + try {document.cookie = cookie+"; path=/"} catch (err) {} // ignore errors saving cookies }, // @@ -1027,7 +1117,8 @@ MathJax.HTML = { Get: function (name,obj) { if (!obj) {obj = {}} var pattern = new RegExp("(?:^|;\\s*)"+this.prefix+"\\."+name+"=([^;]*)(?:;|$)"); - var match = pattern.exec(document.cookie); + var match; + try {match = pattern.exec(document.cookie)} catch (err) {}; // ignore errors reading cookies if (match && match[1] !== "") { var keys = unescape(match[1]).split('&;'); for (var i = 0, m = keys.length; i < m; i++) { @@ -1045,6 +1136,474 @@ MathJax.HTML = { }; +/**********************************************************/ + +MathJax.Localization = { + + locale: "en", + directory: "[MathJax]/localization", + strings: { + // Currently, this list is not modified by the MathJax-i18n script. You can + // run the following command in MathJax/unpacked/localization to update it: + // + // find . -name "*.js" | xargs grep menuTitle\: | grep -v qqq | sed 's/^\.\/\(.*\)\/.*\.js\: / "\1"\: \{/' | sed 's/,$/\},/' | sed 's/"English"/"English", isLoaded: true/' > tmp ; sort tmp > tmp2 ; sed '$ s/,$//' tmp2 ; rm tmp* + // + // This only takes languages with localization data so you must also add + // the languages that use a remap but are not translated at all. + // + "ast": {menuTitle: "asturianu"}, + "bg": {menuTitle: "\u0431\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438"}, + "bcc": {menuTitle: "\u0628\u0644\u0648\u0686\u06CC"}, + "br": {menuTitle: "brezhoneg"}, + "ca": {menuTitle: "catal\u00E0"}, + "cdo": {menuTitle: "M\u00ECng-d\u0115\u0324ng-ng\u1E73\u0304"}, + "cs": {menuTitle: "\u010De\u0161tina"}, + "da": {menuTitle: "dansk"}, + "de": {menuTitle: "Deutsch"}, + "en": {menuTitle: "English", isLoaded: true}, + "eo": {menuTitle: "Esperanto"}, + "es": {menuTitle: "espa\u00F1ol"}, + "fa": {menuTitle: "\u0641\u0627\u0631\u0633\u06CC"}, + "fi": {menuTitle: "suomi"}, + "fr": {menuTitle: "fran\u00E7ais"}, + "gl": {menuTitle: "galego"}, + "he": {menuTitle: "\u05E2\u05D1\u05E8\u05D9\u05EA"}, + "ia": {menuTitle: "interlingua"}, + "it": {menuTitle: "italiano"}, + "ja": {menuTitle: "\u65E5\u672C\u8A9E"}, + "kn": {menuTitle: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1"}, + "ko": {menuTitle: "\uD55C\uAD6D\uC5B4"}, + "lb": {menuTitle: "L\u00EBtzebuergesch"}, + "lt": {menuTitle: "lietuvi\u0173"}, + "mk": {menuTitle: "\u043C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438"}, + "nl": {menuTitle: "Nederlands"}, + "oc": {menuTitle: "occitan"}, + "pl": {menuTitle: "polski"}, + "pt": {menuTitle: "portugus\u00EA"}, + "pt-br": {menuTitle: "portugu\u00EAs do Brasil"}, + "ru": {menuTitle: "\u0440\u0443\u0441\u0441\u043A\u0438\u0439"}, + "sco": {menuTitle: "Scots"}, + "scn": {menuTitle: "sicilianu"}, + "sl": {menuTitle: "sloven\u0161\u010Dina"}, + "sv": {menuTitle: "svenska"}, + "tr": {menuTitle: "T\u00FCrk\u00E7e"}, + "uk": {menuTitle: "\u0443\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"}, + "vi": {menuTitle: "Ti\u1EBFng Vi\u1EC7t"}, + "zh-hans": {menuTitle: "\u4E2D\u6587\uFF08\u7B80\u4F53\uFF09"} + }, + + // + // The pattern for substitution escapes: + // %n or %{n} or %{plural:%n|option1|option1|...} or %c + // + pattern: /%(\d+|\{\d+\}|\{[a-z]+:\%\d+(?:\|(?:%\{\d+\}|%.|[^\}])*)+\}|.)/g, + + SPLIT: ("axb".split(/(x)/).length === 3 ? + function (string,regex) {return string.split(regex)} : + // + // IE8 and below don't do split() correctly when the pattern includes + // parentheses (the split should include the matched exrepssions). + // So implement it by hand here. + // + function (string,regex) { + var result = [], match, last = 0; + regex.lastIndex = 0; + while ((match = regex.exec(string))) { + result.push(string.substr(last,match.index-last)); + result.push.apply(result,match.slice(1)); + last = match.index + match[0].length; + } + result.push(string.substr(last)); + return result; + }), + + _: function (id,phrase) { + if (phrase instanceof Array) {return this.processSnippet(id,phrase)} + return this.processString(this.lookupPhrase(id,phrase),[].slice.call(arguments,2)); + }, + + processString: function (string,args,domain) { + // + // Process arguments for substitution + // If the argument is a snippet (and we are processing snippets) do so, + // Otherwise, if it is a number, convert it for the lacale + // + var i, m; + for (i = 0, m = args.length; i < m; i++) { + if (domain && args[i] instanceof Array) {args[i] = this.processSnippet(domain,args[i])} + } + // + // Split string at escapes and process them individually + // + var parts = this.SPLIT(string,this.pattern); + for (i = 1, m = parts.length; i < m; i += 2) { + var c = parts[i].charAt(0); // first char will be { or \d or a char to be kept literally + if (c >= "0" && c <= "9") { // %n + parts[i] = args[parts[i]-1]; + if (typeof parts[i] === "number") parts[i] = this.number(parts[i]); + } else if (c === "{") { // %{n} or %{plural:%n|...} + c = parts[i].substr(1); + if (c >= "0" && c <= "9") { // %{n} + parts[i] = args[parts[i].substr(1,parts[i].length-2)-1]; + if (typeof parts[i] === "number") parts[i] = this.number(parts[i]); + } else { // %{plural:%n|...} + var match = parts[i].match(/^\{([a-z]+):%(\d+)\|(.*)\}$/); + if (match) { + if (match[1] === "plural") { + var n = args[match[2]-1]; + if (typeof n === "undefined") { + parts[i] = "???"; // argument doesn't exist + } else { + n = this.plural(n) - 1; // index of the form to use + var plurals = match[3].replace(/(^|[^%])(%%)*%\|/g,"$1$2%\uEFEF").split(/\|/); // the parts (replacing %| with a special character) + if (n >= 0 && n < plurals.length) { + parts[i] = this.processString(plurals[n].replace(/\uEFEF/g,"|"),args,domain); + } else { + parts[i] = "???"; // no string for this index + } + } + } else {parts[i] = "%"+parts[i]} // not "plural", put back the % and leave unchanged + } + } + } + if (parts[i] == null) {parts[i] = "???"} + } + // + // If we are not forming a snippet, return the completed string + // + if (!domain) {return parts.join("")} + // + // We need to return an HTML snippet, so buld it from the + // broken up string with inserted parts (that could be snippets) + // + var snippet = [], part = ""; + for (i = 0; i < m; i++) { + part += parts[i]; i++; // add the string and move on to substitution result + if (i < m) { + if (parts[i] instanceof Array) { // substitution was a snippet + snippet.push(part); // add the accumulated string + snippet = snippet.concat(parts[i]); // concatenate the substution snippet + part = ""; // start accumulating a new string + } else { // substitution was a string + part += parts[i]; // add to accumulating string + } + } + } + if (part !== "") {snippet.push(part)} // add final string + return snippet; + }, + + processSnippet: function (domain,snippet) { + var result = []; // the new snippet + // + // Look through the original snippet for + // strings or snippets to translate + // + for (var i = 0, m = snippet.length; i < m; i++) { + if (snippet[i] instanceof Array) { + // + // This could be a sub-snippet: + // ["tag"] or ["tag",{properties}] or ["tag",{properties},snippet] + // Or it could be something to translate: + // [id,string,args] or [domain,snippet] + var data = snippet[i]; + if (typeof data[1] === "string") { // [id,string,args] + var id = data[0]; if (!(id instanceof Array)) {id = [domain,id]} + var phrase = this.lookupPhrase(id,data[1]); + result = result.concat(this.processMarkdown(phrase,data.slice(2),domain)); + } else if (data[1] instanceof Array) { // [domain,snippet] + result = result.concat(this.processSnippet.apply(this,data)); + } else if (data.length >= 3) { // ["tag",{properties},snippet] + result.push([data[0],data[1],this.processSnippet(domain,data[2])]); + } else { // ["tag"] or ["tag",{properties}] + result.push(snippet[i]); + } + } else { // a string + result.push(snippet[i]); + } + } + return result; + }, + + markdownPattern: /(%.)|(\*{1,3})((?:%.|.)+?)\2|(`+)((?:%.|.)+?)\4|\[((?:%.|.)+?)\]\(([^\s\)]+)\)/, + // %c or *bold*, **italics**, ***bold-italics***, or `code`, or [link](url) + + processMarkdown: function (phrase,args,domain) { + var result = [], data; + // + // Split the string by the Markdown pattern + // (the text blocks are separated by + // c,stars,star-text,backtics,code-text,link-text,URL). + // Start with teh first text string from the split. + // + var parts = phrase.split(this.markdownPattern); + var string = parts[0]; + // + // Loop through the matches and process them + // + for (var i = 1, m = parts.length; i < m; i += 8) { + if (parts[i+1]) { // stars (for bold/italic) + // + // Select the tag to use by number of stars (three stars requires two tags) + // + data = this.processString(parts[i+2],args,domain); + if (!(data instanceof Array)) {data = [data]} + data = [["b","i","i"][parts[i+1].length-1],{},data]; // number of stars determines type + if (parts[i+1].length === 3) {data = ["b",{},data]} // bold-italic + } else if (parts[i+3]) { // backtics (for code) + // + // Remove one leading or trailing space, and process substitutions + // Make a tag + // + data = this.processString(parts[i+4].replace(/^\s/,"").replace(/\s$/,""),args,domain); + if (!(data instanceof Array)) {data = [data]} + data = ["code",{},data]; + } else if (parts[i+5]) { // hyperlink + // + // Process the link text, and make an tag with the URL + // + data = this.processString(parts[i+5],args,domain); + if (!(data instanceof Array)) {data = [data]} + data = ["a",{href:this.processString(parts[i+6],args),target:"_blank"},data]; + } else { + // + // Escaped character (%c) gets added into the string. + // + string += parts[i]; data = null; + } + // + // If there is a tag to insert, + // Add any pending string, then push the tag + // + if (data) { + result = this.concatString(result,string,args,domain); + result.push(data); string = ""; + } + // + // Process the string that follows matches pattern + // + if (parts[i+7] !== "") {string += parts[i+7]} + }; + // + // Add any pending string and return the resulting snippet + // + result = this.concatString(result,string,args,domain); + return result; + }, + concatString: function (result,string,args,domain) { + if (string != "") { + // + // Process the substutions. + // If the result is not a snippet, turn it into one. + // Then concatenate the snippet to the current one + // + string = this.processString(string,args,domain); + if (!(string instanceof Array)) {string = [string]} + result = result.concat(string); + } + return result; + }, + + lookupPhrase: function (id,phrase,domain) { + // + // Get the domain and messageID + // + if (!domain) {domain = "_"} + if (id instanceof Array) {domain = (id[0] || "_"); id = (id[1] || "")} + // + // Check if the data is available and if not, + // load it and throw a restart error so the calling + // code can wait for the load and try again. + // + var load = this.loadDomain(domain); + if (load) {MathJax.Hub.RestartAfter(load)} + // + // Look up the message in the localization data + // (if not found, the original English is used) + // + var localeData = this.strings[this.locale]; + if (localeData) { + if (localeData.domains && domain in localeData.domains) { + var domainData = localeData.domains[domain]; + if (domainData.strings && id in domainData.strings) + {phrase = domainData.strings[id]} + } + } + // + // return the translated phrase + // + return phrase; + }, + + // + // Load a langauge data file from the proper + // directory and file. + // + loadFile: function (file,data,callback) { + callback = MathJax.Callback(callback); + file = (data.file || file); // the data's file name or the default name + if (!file.match(/\.js$/)) {file += ".js"} // add .js if needed + // + // Add the directory if the file doesn't + // contain a full URL already. + // + if (!file.match(/^([a-z]+:|\[MathJax\])/)) { + var dir = (this.strings[this.locale].directory || + this.directory + "/" + this.locale || + "[MathJax]/localization/" + this.locale); + file = dir + "/" + file; + } + // + // Load the file and mark the data as loaded (even if it + // failed to load, so we don't continue to try to load it + // over and over). + // + var load = MathJax.Ajax.Require(file,function () {data.isLoaded = true; return callback()}); + // + // Return the callback if needed, otherwise null. + // + return (load.called ? null : load); + }, + + // + // Check to see if the localization data are loaded + // for the given domain; if not, load the data file, + // and return a callback for the loading operation. + // Otherwise return null (data are loaded). + // + loadDomain: function (domain,callback) { + var load, localeData = this.strings[this.locale]; + if (localeData) { + if (!localeData.isLoaded) { + load = this.loadFile(this.locale,localeData); + if (load) { + return MathJax.Callback.Queue( + load,["loadDomain",this,domain] // call again to load domain + ).Push(callback||{}); + } + } + if (localeData.domains && domain in localeData.domains) { + var domainData = localeData.domains[domain]; + if (!domainData.isLoaded) { + load = this.loadFile(domain,domainData); + if (load) {return MathJax.Callback.Queue(load).Push(callback)} + } + } + } + // localization data are loaded, so just do the callback + return MathJax.Callback(callback)(); + }, + + // + // Perform a function, properly handling + // restarts due to localization file loads. + // + // Note that this may return before the function + // has been called successfully, so you should + // consider fn as running asynchronously. (Callbacks + // can be used to synchronize it with other actions.) + // + Try: function (fn) { + fn = MathJax.Callback(fn); fn.autoReset = true; + try {fn()} catch (err) { + if (!err.restart) {throw err} + MathJax.Callback.After(["Try",this,fn],err.restart); + } + }, + + // + // Reset the current language + // + resetLocale: function(locale) { + // Selection algorithm: + // 1) Downcase locale name (e.g. "en-US" => "en-us") + // 2) Try a parent language (e.g. "en-us" => "en") + // 3) Try the fallback specified in the data (e.g. "pt" => "pt-br") + // 4) Otherwise don't change the locale. + if (!locale) return; + locale = locale.toLowerCase(); + while (!this.strings[locale]) { + var dashPos = locale.lastIndexOf("-"); + if (dashPos === -1) return; + locale = locale.substring(0, dashPos); + } + var remap = this.strings[locale].remap; + this.locale = remap ? remap : locale; + }, + + // + // Set the current language + // + setLocale: function(locale) { + this.resetLocale(locale); + if (MathJax.Menu) {this.loadDomain("MathMenu")} + }, + + // + // Add or update a language or domain + // + addTranslation: function (locale,domain,definition) { + var data = this.strings[locale], isNew = false; + if (!data) {data = this.strings[locale] = {}; isNew = true} + if (!data.domains) {data.domains = {}} + if (domain) { + if (!data.domains[domain]) {data.domains[domain] = {}} + data = data.domains[domain]; + } + MathJax.Hub.Insert(data,definition); + if (isNew && MathJax.Menu.menu) {MathJax.Menu.CreateLocaleMenu()} + }, + + // + // Set CSS for an element based on font requirements + // + setCSS: function (div) { + var locale = this.strings[this.locale]; + if (locale) { + if (locale.fontFamily) {div.style.fontFamily = locale.fontFamily} + if (locale.fontDirection) { + div.style.direction = locale.fontDirection; + if (locale.fontDirection === "rtl") {div.style.textAlign = "right"} + } + } + return div; + }, + + // + // Get the language's font family or direction + // + fontFamily: function () { + var locale = this.strings[this.locale]; + return (locale ? locale.fontFamily : null); + }, + fontDirection: function () { + var locale = this.strings[this.locale]; + return (locale ? locale.fontDirection : null); + }, + + // + // Get the language's plural index for a number + // + plural: function (n) { + var locale = this.strings[this.locale]; + if (locale && locale.plural) {return locale.plural(n)} + // default + if (n == 1) {return 1} // one + return 2; // other + }, + + // + // Convert a number to language-specific form + // + number: function(n) { + var locale = this.strings[this.locale]; + if (locale && locale.number) {return locale.number(n)} + // default + return n; + } +}; + + /**********************************************************/ MathJax.Message = { @@ -1072,7 +1631,9 @@ MathJax.Message = { browsers: { MSIE: function (browser) { - MathJax.Hub.config.styles["#MathJax_Message"].position = "absolute"; + MathJax.Message.msieFixedPositionBug = ((document.documentMode||0) < 7); + if (MathJax.Message.msieFixedPositionBug) + {MathJax.Hub.config.styles["#MathJax_Message"].position = "absolute"} MathJax.Message.quirks = (document.compatMode === "BackCompat"); }, Chrome: function (browser) { @@ -1095,8 +1656,8 @@ MathJax.Message = { } if (!this.div) { var frame = document.body; - if (MathJax.Hub.Browser.isMSIE) { - frame = this.frame = this.addDiv(document.body); frame.removeAttribute("id"); + if (this.msieFixedPositionBug && window.attachEvent) { + frame = this.frame = this.addDiv(document.body); frame.removeAttribute("id"); frame.style.position = "absolute"; frame.style.border = frame.style.margin = frame.style.padding = "0px"; frame.style.zIndex = "101"; frame.style.height = "0px"; @@ -1129,17 +1690,21 @@ MathJax.Message = { frame = frame.firstChild; frame.style.height = body.clientHeight + 'px'; }, + + localize: function (message) { + return MathJax.Localization._(message,message); + }, - filterText: function (text,n) { + filterText: function (text,n,id) { if (MathJax.Hub.config.messageStyle === "simple") { - if (text.match(/^Loading /)) { - if (!this.loading) {this.loading = "Loading "} + if (id === "LoadFile") { + if (!this.loading) {this.loading = this.localize("Loading") + " "} text = this.loading; this.loading += "."; - } else if (text.match(/^Processing /)) { - if (!this.processing) {this.processing = "Processing "} + } else if (id === "ProcessMath") { + if (!this.processing) {this.processing = this.localize("Processing") + " "} text = this.processing; this.processing += "."; - } else if (text.match(/^Typesetting /)) { - if (!this.typesetting) {this.typesetting = "Typesetting "} + } else if (id === "TypesetMath") { + if (!this.typesetting) {this.typesetting = this.localize("Typesetting") + " "} text = this.typesetting; this.typesetting += "."; } } @@ -1147,14 +1712,53 @@ MathJax.Message = { }, Set: function (text,n,clearDelay) { - if (this.timer) {clearTimeout(this.timer); delete this.timeout} if (n == null) {n = this.log.length; this.log[n] = {}} - this.log[n].text = text; this.log[n].filteredText = text = this.filterText(text,n); + // + // Translate message if it is [id,message,arguments] + // + var id = ""; + if (text instanceof Array) { + id = text[0]; if (id instanceof Array) {id = id[1]} + // + // Localization._() will throw a restart error if a localization file + // needs to be loaded, so trap that and redo the Set() call + // after it is loaded. + // + try { + text = MathJax.Localization._.apply(MathJax.Localization,text); + } catch (err) { + if (!err.restart) {throw err} + if (!err.restart.called) { + // + // Mark it so we can tell if the Clear() comes before the message is displayed + // + if (this.log[n].restarted == null) {this.log[n].restarted = 0} + this.log[n].restarted++; delete this.log[n].cleared; + MathJax.Callback.After(["Set",this,text,n,clearDelay],err.restart); + return n; + } + } + } + // + // Clear the timout timer. + // + if (this.timer) {clearTimeout(this.timer); delete this.timer} + // + // Save the message and filtered message. + // + this.log[n].text = text; this.log[n].filteredText = text = this.filterText(text,n,id); + // + // Hook the message into the message list so we can tell + // what message to put up when this one is removed. + // if (typeof(this.log[n].next) === "undefined") { this.log[n].next = this.current; if (this.current != null) {this.log[this.current].prev = n} this.current = n; } + // + // Show the message if it is the currently active one. + // if (this.current === n && MathJax.Hub.config.messageStyle !== "none") { if (this.Init()) { if (this.textNodeBug) {this.div.innerHTML = text} else {this.text.nodeValue = text} @@ -1165,24 +1769,50 @@ MathJax.Message = { this.status = true; } } + // + // Check if the message was resetarted to load a localization file + // and if it has been cleared in the meanwhile. + // + if (this.log[n].restarted) { + if (this.log[n].cleared) {clearDelay = 0} + if (--this.log[n].restarted === 0) {delete this.log[n].cleared} + } + // + // Check if we need to clear the message automatically. + // if (clearDelay) {setTimeout(MathJax.Callback(["Clear",this,n]),clearDelay)} - else if (clearDelay == 0) {this.Clear(n,0)} + else if (clearDelay == 0) {this.Clear(n,0)} + // + // Return the message number. + // return n; }, Clear: function (n,delay) { + // + // Detatch the message from the active list. + // if (this.log[n].prev != null) {this.log[this.log[n].prev].next = this.log[n].next} if (this.log[n].next != null) {this.log[this.log[n].next].prev = this.log[n].prev} + // + // If it is the current message, get the next one to show. + // if (this.current === n) { this.current = this.log[n].next; if (this.text) { if (this.div.parentNode == null) {this.Init()} // see ASCIIMathML comments above if (this.current == null) { - if (this.timer) {clearTimeout(this.timer); delete this.timer} + // + // If there are no more messages, remove the message box. + // + if (this.timer) {clearTimeout(this.timer); delete this.timer} if (delay == null) {delay = 600} if (delay === 0) {this.Remove()} else {this.timer = setTimeout(MathJax.Callback(["Remove",this]),delay)} } else if (MathJax.Hub.config.messageStyle !== "none") { + // + // If there is an old message, put it in place + // if (this.textNodeBug) {this.div.innerHTML = this.log[this.current].filteredText} else {this.text.nodeValue = this.log[this.current].filteredText} } @@ -1191,8 +1821,16 @@ MathJax.Message = { window.status = (this.current == null ? "" : this.log[this.current].text); } } + // + // Clean up the log data no longer needed + // delete this.log[n].next; delete this.log[n].prev; delete this.log[n].filteredText; + // + // If this is a restarted localization message, mark that it has been cleared + // while waiting for the file to load. + // + if (this.log[n].restarted) {this.log[n].cleared = true} }, Remove: function () { @@ -1202,9 +1840,7 @@ MathJax.Message = { }, File: function (file) { - var root = MathJax.Ajax.config.root; - if (file.substr(0,root.length) === root) {file = "[MathJax]"+file.substr(root.length)} - return this.Set("Loading "+file); + return this.Set(["LoadFile","Loading %1",file],null,null); }, Log: function () { @@ -1238,9 +1874,8 @@ MathJax.Hub = { // set to "configured" to delay startup until MathJax.Hub.Configured() is called // set to a Callback to wait for before continuing with the startup skipStartupTypeset: false, // set to true to skip PreProcess and Process during startup - "v1.0-compatible": true, // set to false to prevent message about configuration change elements: [], // array of elements to process when none is given explicitly - positionToHash: true, // after initial typeset pass, position to #hash location? + positionToHash: true, // after initial typeset pass, position to #hash location? showMathMenu: true, // attach math context menu to typeset math? showMathMenuMSIE: true, // separtely determine if MSIE should have math menu @@ -1257,21 +1892,31 @@ MathJax.Hub = { renderer: "", // set when Jax are loaded font: "Auto", // what font HTML-CSS should use context: "MathJax", // or "Browser" for pass-through to browser menu + locale: "en", // the language to use for messages mpContext: false, // true means pass menu events to MathPlayer in IE mpMouse: false, // true means pass mouse events to MathPlayer in IE - texHints: true // include class names for TeXAtom elements + texHints: true, // include class names for TeXAtom elements + semantics: false // add semantics tag with original form in MathML output }, errorSettings: { - message: ["[Math Processing Error]"], // HTML snippet structure for message to use + // localized HTML snippet structure for message to use + message: ["[",["MathProcessingError","Math Processing Error"],"]"], style: {color: "#CC0000", "font-style":"italic"} // style for message - } + }, + + ignoreMMLattributes: {} // attributes not to copy to HTML-CSS or SVG output + // from MathML input (in addition to the ones in MML.nocopyAttributes). + // An id set to true will be ignored, one set to false will + // be allowed (even if other criteria normally would prevent + // it from being copied); use false carefully! }, preProcessors: MathJax.Callback.Hooks(true), // list of callbacks for preprocessing (initialized by extensions) inputJax: {}, // mime-type mapped to input jax (by registration) outputJax: {order:{}}, // mime-type mapped to output jax list (by registration) + processSectionDelay: 50, // pause between input and output phases of processing processUpdateTime: 250, // time between screen updates when processing math (milliseconds) processUpdateDelay: 10, // pause between screen updates to allow other processing (milliseconds) @@ -1292,11 +1937,17 @@ MathJax.Hub = { }, Register: { - PreProcessor: function () {MathJax.Hub.preProcessors.Add.apply(MathJax.Hub.preProcessors,arguments)}, + PreProcessor: function () {return MathJax.Hub.preProcessors.Add.apply(MathJax.Hub.preProcessors,arguments)}, MessageHook: function () {return MathJax.Hub.signal.MessageHook.apply(MathJax.Hub.signal,arguments)}, StartupHook: function () {return MathJax.Hub.Startup.signal.MessageHook.apply(MathJax.Hub.Startup.signal,arguments)}, LoadHook: function () {return MathJax.Ajax.LoadHook.apply(MathJax.Ajax,arguments)} }, + UnRegister: { + PreProcessor: function (hook) {MathJax.Hub.preProcessors.Remove(hook)}, + MessageHook: function (hook) {MathJax.Hub.signal.RemoveHook(hook)}, + StartupHook: function (hook) {MathJax.Hub.Startup.signal.RemoveHook(hook)}, + LoadHook: function (hook) {MathJax.Ajax.removeHook(hook)} + }, getAllJax: function (element) { var jax = [], scripts = this.elementScripts(element); @@ -1330,7 +1981,8 @@ MathJax.Hub = { getJaxFor: function (element) { if (typeof(element) === 'string') {element = document.getElementById(element)} if (element && element.MathJax) {return element.MathJax.elementJax} - if (element && element.isMathJax) { + if (this.isMathJaxNode(element)) { + if (!element.isMathJax) {element = element.firstChild} // for NativeMML output while (element && !element.jaxID) {element = element.parentNode} if (element) {return MathJax.OutputJax[element.jaxID].getJaxFromMath(element)} } @@ -1339,14 +1991,17 @@ MathJax.Hub = { isJax: function (element) { if (typeof(element) === 'string') {element = document.getElementById(element)} - if (element && element.isMathJax) {return 1} - if (element && element.tagName != null && element.tagName.toLowerCase() === 'script') { + if (this.isMathJaxNode(element)) {return 1} + if (element && (element.tagName||"").toLowerCase() === 'script') { if (element.MathJax) {return (element.MathJax.state === MathJax.ElementJax.STATE.PROCESSED ? 1 : -1)} if (element.type && this.inputJax[element.type.replace(/ *;(.|\s)*/,"")]) {return -1} } return 0; }, + isMathJaxNode: function (element) { + return !!element && (element.isMathJax || (element.className||"") === "MathJax_MathML"); + }, setRenderer: function (renderer,type) { if (!renderer) return; @@ -1375,14 +2030,11 @@ MathJax.Hub = { Typeset: function (element,callback) { if (!MathJax.isReady) return null; var ec = this.elementCallback(element,callback); - var queue = MathJax.Callback.Queue(); - for (var i = 0, m = ec.elements.length; i < m; i++) { - if (ec.elements[i]) { - queue.Push( - ["PreProcess",this,ec.elements[i]], - ["Process",this,ec.elements[i]] - ); - } + if (ec.count) { + var queue = MathJax.Callback.Queue( + ["PreProcess",this,ec.elements], + ["Process",this,ec.elements] + ); } return queue.Push(ec.callback); }, @@ -1390,14 +2042,13 @@ MathJax.Hub = { PreProcess: function (element,callback) { var ec = this.elementCallback(element,callback); var queue = MathJax.Callback.Queue(); - for (var i = 0, m = ec.elements.length; i < m; i++) { - if (ec.elements[i]) { - queue.Push( - ["Post",this.signal,["Begin PreProcess",ec.elements[i]]], - (arguments.callee.disabled? {} : ["Execute",this.preProcessors,ec.elements[i]]), - ["Post",this.signal,["End PreProcess",ec.elements[i]]] - ); + if (ec.count) { + var elements = (ec.count === 1 ? [ec.elements] : ec.elements); + queue.Push(["Post",this.signal,["Begin PreProcess",ec.elements]]); + for (var i = 0, m = elements.length; i < m; i++) { + if (elements[i]) {queue.Push(["Execute",this.preProcessors,elements[i]])} } + queue.Push(["Post",this.signal,["End PreProcess",ec.elements]]); } return queue.Push(ec.callback); }, @@ -1409,32 +2060,37 @@ MathJax.Hub = { takeAction: function (action,element,callback) { var ec = this.elementCallback(element,callback); + var elements = ec.elements; var queue = MathJax.Callback.Queue(["Clear",this.signal]); - for (var i = 0, m = ec.elements.length; i < m; i++) { - if (ec.elements[i]) { - var state = { - scripts: [], // filled in by prepareScripts - start: new Date().getTime(), // timer for processing messages - i: 0, j: 0, // current script, current jax - jax: {}, // scripts grouped by output jax - jaxIDs: [] // id's of jax used - }; - queue.Push( - ["Post",this.signal,["Begin "+action,ec.elements[i]]], - ["Post",this.signal,["Begin Math",ec.elements[i],action]], - ["prepareScripts",this,action,ec.elements[i],state], - ["Post",this.signal,["Begin Math Input",ec.elements[i],action]], - ["processInput",this,state], - ["Post",this.signal,["End Math Input",ec.elements[i],action]], - ["prepareOutput",this,state,"preProcess"], - ["Post",this.signal,["Begin Math Output",ec.elements[i],action]], - ["processOutput",this,state], - ["Post",this.signal,["End Math Output",ec.elements[i],action]], - ["prepareOutput",this,state,"postProcess"], - ["Post",this.signal,["End Math",ec.elements[i],action]], - ["Post",this.signal,["End "+action,ec.elements[i]]] - ); - } + var state = { + scripts: [], // filled in by prepareScripts + start: new Date().getTime(), // timer for processing messages + i: 0, j: 0, // current script, current jax + jax: {}, // scripts grouped by output jax + jaxIDs: [] // id's of jax used + }; + if (ec.count) { + var delay = ["Delay",MathJax.Callback,this.processSectionDelay]; + if (!delay[2]) {delay = {}} + queue.Push( + ["Post",this.signal,["Begin "+action,elements]], + ["Post",this.signal,["Begin Math",elements,action]], + ["prepareScripts",this,action,elements,state], + ["Post",this.signal,["Begin Math Input",elements,action]], + ["processInput",this,state], + ["Post",this.signal,["End Math Input",elements,action]], + delay, + ["prepareOutput",this,state,"preProcess"], + delay, + ["Post",this.signal,["Begin Math Output",elements,action]], + ["processOutput",this,state], + ["Post",this.signal,["End Math Output",elements,action]], + delay, + ["prepareOutput",this,state,"postProcess"], + delay, + ["Post",this.signal,["End Math",elements,action]], + ["Post",this.signal,["End "+action,elements]] + ); } return queue.Push(ec.callback); }, @@ -1526,13 +2182,15 @@ MathJax.Hub = { if (!script.MathJax.elementJax || script.MathJax.state === STATE.UPDATE) { this.checkScriptSiblings(script); // remove preJax/postJax etc. var type = script.type.replace(/ *;(.|\s)*/,""); // the input jax type - jax = this.inputJax[type].Process(script,state); // run the input jax + var input = this.inputJax[type]; // the input jax itself + jax = input.Process(script,state); // run the input jax if (typeof jax === 'function') { // if a callback was returned if (jax.called) continue; // go back and call Process() again this.RestartAfter(jax); // wait for the callback } - jax.Attach(script,this.inputJax[type].id); // register the jax on the script + jax = jax.Attach(script,input.id); // register the jax on the script this.saveScript(jax,state,script,STATE); // add script to state + this.postInputHooks.Execute(jax,input.id,script); // run global jax filters } else if (script.MathJax.state === STATE.OUTPUT) { this.saveScript(script.MathJax.elementJax,state,script,STATE); // add script to state } @@ -1548,10 +2206,11 @@ MathJax.Hub = { // Put up final message, reset the state and return // if (state.scripts.length && this.config.showProcessingMessages) - {MathJax.Message.Set("Processing math: 100%",0)} + {MathJax.Message.Set(["ProcessMath","Processing math: %1%%",100],0)} state.start = new Date().getTime(); state.i = state.j = 0; return null; }, + postInputHooks: MathJax.Callback.Hooks(true), // hooks to run after element jax is created saveScript: function (jax,state,script,STATE) { // // Check that output jax exists @@ -1600,7 +2259,7 @@ MathJax.Hub = { } } catch (err) { if (!err.restart) { - MathJax.Message.Set("Error preparing "+id+" output ("+method+")",null,600); + MathJax.Message.Set(["PrepError","Error preparing %1 output (%2)",id,method],null,600); MathJax.Hub.lastPrepError = err; state.j++; } @@ -1622,19 +2281,28 @@ MathJax.Hub = { // // Check that there is an element jax // - script = state.scripts[state.i]; if (!script || !script.MathJax) {state.i++; continue} + script = state.scripts[state.i]; + if (!script || !script.MathJax || script.MathJax.error) {state.i++; continue} var jax = script.MathJax.elementJax; if (!jax) {state.i++; continue} // // Call the output Jax's Process method (which will be its Translate() - // method once loaded). Mark it as complete and remove the preview. + // method once loaded). Mark it as complete and remove the preview unless + // the Process() call returns an explicit false value (in which case, it will + // handle this later during the postProcess phase, as HTML-CSS does). // result = MathJax.OutputJax[jax.outputJax].Process(script,state); - script.MathJax.state = STATE.PROCESSED; state.i++; - if (script.MathJax.preview) {script.MathJax.preview.innerHTML = ""} + if (result !== false) { + script.MathJax.state = STATE.PROCESSED; + if (script.MathJax.preview) {script.MathJax.preview.innerHTML = ""} + // + // Signal that new math is available + // + this.signal.Post(["New Math",jax.inputID]); // FIXME: wait for this? (i.e., restart if returns uncalled callback) + } // - // Signal that new math is available + // Go on to next math expression // - this.signal.Post(["New Math",jax.inputID]); // FIXME: wait for this? (i.e., restart if returns uncalled callback) + state.i++; // // Update the processing message, if needed // @@ -1647,7 +2315,7 @@ MathJax.Hub = { // Put up the typesetting-complete message // if (state.scripts.length && this.config.showProcessingMessages) { - MathJax.Message.Set("Typesetting math: 100%",0); + MathJax.Message.Set(["TypesetMath","Typesetting math: %1%%",100],0); MathJax.Message.Clear(0); } state.i = state.j = 0; @@ -1656,8 +2324,9 @@ MathJax.Hub = { processMessage: function (state,type) { var m = Math.floor(state.i/(state.scripts.length)*100); - var message = (type === "Output" ? "Typesetting" : "Processing"); - if (this.config.showProcessingMessages) {MathJax.Message.Set(message+" math: "+m+"%",0)} + var message = (type === "Output" ? ["TypesetMath","Typesetting math: %1%%"] : + ["ProcessMath","Processing math: %1%%"]); + if (this.config.showProcessingMessages) {MathJax.Message.Set(message.concat(m),0)} }, processError: function (err,state,type) { @@ -1670,20 +2339,55 @@ MathJax.Hub = { }, formatError: function (script,err) { - var error = MathJax.HTML.Element("span",{className:"MathJax_Error"},this.config.errorSettings.message); - error.jaxID = "Error"; + var LOCALIZE = function (id,text,arg1,arg2) {return MathJax.Localization._(id,text,arg1,arg2)}; + // + // Get the error message, URL, and line, and save it for + // reporting in the Show Math As Error menu + // + var message = LOCALIZE("ErrorMessage","Error: %1",err.message)+"\n"; + if (err.sourceURL||err.fileName) message += "\n"+LOCALIZE("ErrorFile","file: %1",err.sourceURL||err.fileName); + if (err.line||err.lineNumber) message += "\n"+LOCALIZE("ErrorLine","line: %1",err.line||err.lineNumber); + message += "\n\n"+LOCALIZE("ErrorTips","Debugging tips: use %1, inspect %2 in the browser console","'unpacked/MathJax.js'","'MathJax.Hub.lastError'"); + script.MathJax.error = MathJax.OutputJax.Error.Jax(message,script); + + // + // Create the [Math Processing Error] span + // + var errorSettings = this.config.errorSettings; + var errorText = LOCALIZE(errorSettings.messageId,errorSettings.message); + var error = MathJax.HTML.Element("span", { + className:"MathJax_Error", jaxID:"Error", isMathJax:true, + id: script.MathJax.error.inputID+"-Frame" + },errorText); + // + // Attach the menu events + // if (MathJax.Extension.MathEvents) { - error.oncontextmenu = MathJax.Extension.MathEvents.Event.Menu; - error.onmousedown = MathJax.Extension.MathEvents.Event.Mousedown; + var EVENT = MathJax.Extension.MathEvents.Event; + error.oncontextmenu = EVENT.Menu; + error.onmousedown = EVENT.Mousedown; + error.onkeydown = EVENT.Keydown; + error.tabIndex = 0; } else { MathJax.Ajax.Require("[MathJax]/extensions/MathEvents.js",function () { - error.oncontextmenu = MathJax.Extension.MathEvents.Event.Menu; - error.onmousedown = MathJax.Extension.MathEvents.Event.Mousedown; + var EVENT = MathJax.Extension.MathEvents.Event; + error.oncontextmenu = EVENT.Menu; + error.onmousedown = EVENT.Mousedown; + error.keydown = EVENT.Keydown; + error.tabIndex = 0; }); } + // + // Insert the error into the page and remove any preview + // script.parentNode.insertBefore(error,script); if (script.MathJax.preview) {script.MathJax.preview.innerHTML = ""} + // + // Save the error for debugging purposes + // Report the error as a signal + // this.lastError = err; + this.signal.Post(["Math Processing Error",script,err]); }, RestartAfter: function (callback) { @@ -1694,20 +2398,55 @@ MathJax.Hub = { if (callback == null && (element instanceof Array || typeof element === 'function')) {try {MathJax.Callback(element); callback = element; element = null} catch(e) {}} if (element == null) {element = this.config.elements || []} + if (this.isHTMLCollection(element)) {element = this.HTMLCollection2Array(element)} if (!(element instanceof Array)) {element = [element]} element = [].concat(element); // make a copy so the original isn't changed for (var i = 0, m = element.length; i < m; i++) {if (typeof(element[i]) === 'string') {element[i] = document.getElementById(element[i])}} + if (!document.body) {document.body = document.getElementsByTagName("body")[0]} if (element.length == 0) {element.push(document.body)} if (!callback) {callback = {}} - return {elements: element, callback: callback}; + return { + count: element.length, + elements: (element.length === 1 ? element[0] : element), + callback: callback + }; }, elementScripts: function (element) { + var scripts = []; + if (element instanceof Array || this.isHTMLCollection(element)) { + for (var i = 0, m = element.length; i < m; i++) { + var alreadyDone = 0; + for (var j = 0; j < i && !alreadyDone; j++) + {alreadyDone = element[j].contains(element[i])} + if (!alreadyDone) scripts.push.apply(scripts,this.elementScripts(element[i])); + } + return scripts; + } if (typeof(element) === 'string') {element = document.getElementById(element)} + if (!document.body) {document.body = document.getElementsByTagName("body")[0]} if (element == null) {element = document.body} if (element.tagName != null && element.tagName.toLowerCase() === "script") {return [element]} - return element.getElementsByTagName("script"); + scripts = element.getElementsByTagName("script"); + if (this.msieHTMLCollectionBug) {scripts = this.HTMLCollection2Array(scripts)} + return scripts; + }, + + // + // IE8 fails to check "obj instanceof HTMLCollection" for some values of obj. + // + isHTMLCollection: function (obj) { + return ("HTMLCollection" in window && typeof(obj) === "object" && obj instanceof HTMLCollection); + }, + // + // IE8 doesn't deal with HTMLCollection as an array, so convert to array + // + HTMLCollection2Array: function (nodes) { + if (!this.msieHTMLCollectionBug) {return [].slice.call(nodes)} + var NODES = []; + for (var i = 0, m = nodes.length; i < m; i++) {NODES[i] = nodes[i]} + return NODES; }, Insert: function (dst,src) { @@ -1721,7 +2460,13 @@ MathJax.Hub = { } }} return dst; - } + }, + + // Old browsers (e.g. Internet Explorer <= 8) do not support trim(). + SplitList: ("trim" in String.prototype ? + function (list) {return list.trim().split(/\s+/)} : + function (list) {return list.replace(/^\s+/,''). + replace(/\s+$/,'').split(/\s+/)}) }; MathJax.Hub.Insert(MathJax.Hub.config.styles,MathJax.Message.styles); MathJax.Hub.Insert(MathJax.Hub.config.styles,{".MathJax_Error":MathJax.Hub.config.errorSettings.style}); @@ -1747,18 +2492,12 @@ MathJax.Hub.Startup = { Config: function () { this.queue.Push(["Post",this.signal,"Begin Config"]); // - // Check for user cookie configuration + // If a locale is given as a parameter, + // set the locale and the default menu value for the locale // - var user = MathJax.HTML.Cookie.Get("user"); - if (user.URL || user.Config) { - if (confirm( - "MathJax has found a user-configuration cookie that includes code to be run. " + - "Do you want to run it?\n\n"+ - "(You should press Cancel unless you set up the cookie yourself.)" - )) { - if (user.URL) {this.queue.Push(["Require",MathJax.Ajax,user.URL])} - if (user.Config) {this.queue.Push(new Function(user.Config))} - } else {MathJax.HTML.Cookie.Set("user",{})} + if (this.params.locale) { + MathJax.Localization.resetLocale(this.params.locale); + MathJax.Hub.config.menuSettings.locale = this.params.locale; } // // Run the config files, if any are given in the parameter list @@ -1771,17 +2510,19 @@ MathJax.Hub.Startup = { } } // + // Perform author configuration from in-line MathJax = {...} + // + this.queue.Push(["Config",MathJax.Hub,MathJax.AuthorConfig]); + // // Run the deprecated configuration script, if any (ignoring return value) // Wait for the startup delay signal // Run the mathjax-config blocks - // Handle the default configuration (v1.0 compatible) // Load the files in the configuration's config array // if (this.script.match(/\S/)) {this.queue.Push(this.script+";\n1;")} this.queue.Push( ["ConfigDelay",this], ["ConfigBlocks",this], - ["ConfigDefault",this], [function (THIS) {return THIS.loadArray(MathJax.Hub.config.config,"config",null,true)},this], ["Post",this.signal,"End Config"] ); @@ -1796,7 +2537,7 @@ MathJax.Hub.Startup = { return delay; }, // - // Run the scipts of type=text/x-mathajx-config + // Run the scripts of type=text/x-mathjax-config // ConfigBlocks: function () { var scripts = document.getElementsByTagName("script"); @@ -1810,18 +2551,10 @@ MathJax.Hub.Startup = { } return last; }, - // - // Check for v1.0 no-configuration and put up a warning message. - // - ConfigDefault: function () { - var CONFIG = MathJax.Hub.config; - if (CONFIG["v1.0-compatible"] && (CONFIG.jax||[]).length === 0 && - !this.params.config && (CONFIG.config||[]).length === 0) - {return MathJax.Ajax.Require(this.URL("extensions","v1.0-warning.js"))} - }, // // Read cookie and set up menu defaults + // (set the locale according to the cookie) // (adjust the jax to accommodate renderer preferences) // Cookie: function () { @@ -1829,6 +2562,8 @@ MathJax.Hub.Startup = { ["Post",this.signal,"Begin Cookie"], ["Get",MathJax.HTML.Cookie,"menu",MathJax.Hub.config.menuSettings], [function (config) { + var SETTINGS = config.menuSettings; + if (SETTINGS.locale) MathJax.Localization.resetLocale(SETTINGS.locale); var renderer = config.menuSettings.renderer, jax = config.jax; if (renderer) { var name = "output/"+renderer; jax.sort(); @@ -1840,6 +2575,14 @@ MathJax.Hub.Startup = { } jax.unshift(name); } + if (SETTINGS.CHTMLpreview != null) { + if (SETTINGS.FastPreview == null) SETTINGS.FastPreview = SETTINGS.CHTMLpreview; + delete SETTINGS.CHTMLpreview; + } + if (SETTINGS.FastPreview && !MathJax.Extension["fast-preview"]) + MathJax.Hub.config.extensions.push("fast-preview.js"); + if (config.menuSettings.assistiveMML && !MathJax.Extension.AssistiveMML) + MathJax.Hub.config.extensions.push("AssistiveMML.js"); },MathJax.Hub.config], ["Post",this.signal,"End Cookie"] ); @@ -1862,8 +2605,9 @@ MathJax.Hub.Startup = { var config = MathJax.Hub.config, jax = MathJax.Hub.outputJax; // Save the order of the output jax since they are loading asynchronously for (var i = 0, m = config.jax.length, k = 0; i < m; i++) { - if (config.jax[i].substr(0,7) === "output/") - {jax.order[config.jax[i].substr(7)] = k; k++} + var name = config.jax[i].substr(7); + if (config.jax[i].substr(0,7) === "output/" && jax.order[name] == null) + {jax.order[name] = k; k++} } var queue = MathJax.Callback.Queue(); return queue.Push( @@ -1911,8 +2655,28 @@ MathJax.Hub.Startup = { // Set the location to the designated hash position // Hash: function () { - if (MathJax.Hub.config.positionToHash && document.location.hash) - {setTimeout("document.location = document.location.hash",1)} + if (MathJax.Hub.config.positionToHash && document.location.hash && + document.body && document.body.scrollIntoView) { + var name = document.location.hash.substr(1); + var target = document.getElementById(name); + if (!target) { + var a = document.getElementsByTagName("a"); + for (var i = 0, m = a.length; i < m; i++) + {if (a[i].name === name) {target = a[i]; break}} + } + if (target) { + while (!target.scrollIntoView) {target = target.parentNode} + target = this.HashCheck(target); + if (target && target.scrollIntoView) + {setTimeout(function () {target.scrollIntoView(true)},1)} + } + } + }, + HashCheck: function (target) { + var jax = MathJax.Hub.getJaxFor(target); + if (jax && MathJax.OutputJax[jax.outputJax].hashCheck) + {target = MathJax.OutputJax[jax.outputJax].hashCheck(target)} + return target; }, // @@ -1922,27 +2686,44 @@ MathJax.Hub.Startup = { // if needed later on. // MenuZoom: function () { - if (!MathJax.Extension.MathMenu) { - setTimeout( - MathJax.Callback(["Require",MathJax.Ajax,"[MathJax]/extensions/MathMenu.js",{}]), - 1000 - ); - } - if (!MathJax.Extension.MathZoom) { - setTimeout( - MathJax.Callback(["Require",MathJax.Ajax,"[MathJax]/extensions/MathZoom.js",{}]), - 2000 - ); + if (MathJax.Hub.config.showMathMenu) { + if (!MathJax.Extension.MathMenu) { + setTimeout( + function () { + MathJax.Callback.Queue( + ["Require",MathJax.Ajax,"[MathJax]/extensions/MathMenu.js",{}], + ["loadDomain",MathJax.Localization,"MathMenu"] + ) + },1000 + ); + } else { + setTimeout( + MathJax.Callback(["loadDomain",MathJax.Localization,"MathMenu"]), + 1000 + ); + } + if (!MathJax.Extension.MathZoom) { + setTimeout( + MathJax.Callback(["Require",MathJax.Ajax,"[MathJax]/extensions/MathZoom.js",{}]), + 2000 + ); + } } }, // // Setup the onload callback // - onLoad: function (when) { + onLoad: function () { var onload = this.onload = MathJax.Callback(function () {MathJax.Hub.Startup.signal.Post("onLoad")}); - if (document.body && document.readyState && document.readyState !== "loading") {return [onload]} + if (document.body && document.readyState) + if (MathJax.Hub.Browser.isMSIE) { + // IE can change from loading to interactive before + // full page is ready, so go with complete (even though + // that means we may have to wait longer). + if (document.readyState === "complete") {return [onload]} + } else if (document.readyState !== "loading") {return [onload]} if (window.addEventListener) { window.addEventListener("load",onload,false); if (!this.params.noDOMContentEvent) @@ -2075,7 +2856,7 @@ MathJax.Hub.Startup = { } },{ id: "Jax", - version: "2.0", + version: "2.6.0", directory: ROOT+"/jax", extensionDir: ROOT+"/extensions" }); @@ -2084,6 +2865,7 @@ MathJax.Hub.Startup = { BASE.InputJax = JAX.Subclass({ elementJax: "mml", // the element jax to load for this input jax + sourceMenuTitle: /*_(MathMenu)*/ ["Original","Original Form"], copyTranslate: true, Process: function (script,state) { var queue = CALLBACK.Queue(), file; @@ -2120,7 +2902,7 @@ MathJax.Hub.Startup = { } },{ id: "InputJax", - version: "2.0", + version: "2.6.0", directory: JAX.directory+"/input", extensionDir: JAX.extensionDir }); @@ -2153,7 +2935,7 @@ MathJax.Hub.Startup = { Remove: function (jax) {} },{ id: "OutputJax", - version: "2.0", + version: "2.6.0", directory: JAX.directory+"/output", extensionDir: JAX.extensionDir, fontDir: ROOT+(BASE.isPacked?"":"/..")+"/fonts", @@ -2171,6 +2953,7 @@ MathJax.Hub.Startup = { inputID: null, originalText: "", mimeType: "", + sourceMenuTitle: /*_(MathMenu)*/ ["MathMLcode","MathML Code"], Text: function (text,callback) { var script = this.SourceElement(); @@ -2236,7 +3019,7 @@ MathJax.Hub.Startup = { } },{ id: "ElementJax", - version: "2.0", + version: "2.6.0", directory: JAX.directory+"/element", extensionDir: JAX.extensionDir, ID: 0, // jax counter (for IDs) @@ -2260,14 +3043,27 @@ MathJax.Hub.Startup = { // Some "Fake" jax used to allow menu access for "Math Processing Error" messages // BASE.OutputJax.Error = { - id: "Error", version: "2.0", config: {}, + id: "Error", version: "2.6.0", config: {}, errors: 0, ContextMenu: function () {return BASE.Extension.MathEvents.Event.ContextMenu.apply(BASE.Extension.MathEvents.Event,arguments)}, Mousedown: function () {return BASE.Extension.MathEvents.Event.AltContextMenu.apply(BASE.Extension.MathEvents.Event,arguments)}, - getJaxFromMath: function () {return {inputJax:"Error", outputJax:"Error", originalText:"Math Processing Error"}} + getJaxFromMath: function (math) {return (math.nextSibling.MathJax||{}).error}, + Jax: function (text,script) { + var jax = MathJax.Hub.inputJax[script.type.replace(/ *;(.|\s)*/,"")]; + this.errors++; + return { + inputJax: (jax||{id:"Error"}).id, // Use Error InputJax as fallback + outputJax: "Error", + inputID: "MathJax-Error-"+this.errors, + sourceMenuTitle: /*_(MathMenu)*/ ["ErrorMessage","Error Message"], + sourceMenuFormat: "Error", + originalText: MathJax.HTML.getScript(script), + errorText: text + } + } }; BASE.InputJax.Error = { - id: "Error", version: "2.0", config: {}, - sourceMenuTitle: "Error Message" + id: "Error", version: "2.6.0", config: {}, + sourceMenuTitle: /*_(MathMenu)*/ ["Original","Original Form"] }; })("MathJax"); @@ -2279,12 +3075,14 @@ MathJax.Hub.Startup = { if (!BASE) {BASE = window[BASENAME] = {}} var HUB = BASE.Hub; var STARTUP = HUB.Startup; var CONFIG = HUB.config; - var HEAD = document.getElementsByTagName("head")[0]; + var HEAD = document.head || (document.getElementsByTagName("head")[0]); if (!HEAD) {HEAD = document.childNodes[0]}; var scripts = (document.documentElement || document).getElementsByTagName("script"); + if (scripts.length === 0 && HEAD.namespaceURI) + scripts = document.getElementsByTagNameNS(HEAD.namespaceURI,"script"); var namePattern = new RegExp("(^|/)"+BASENAME+"\\.js(\\?.*)?$"); for (var i = scripts.length-1; i >= 0; i--) { - if (scripts[i].src.match(namePattern)) { + if ((scripts[i].src||"").match(namePattern)) { STARTUP.script = scripts[i].innerHTML; if (RegExp.$2) { var params = RegExp.$2.substr(1).split(/\&/); @@ -2293,22 +3091,27 @@ MathJax.Hub.Startup = { if (KV) {STARTUP.params[unescape(KV[1])] = unescape(KV[2])} } } - CONFIG.root = scripts[i].src.replace(/(^|\/)[^\/]*(\?.*)?$/,''); + CONFIG.root = scripts[i].src.replace(/(^|\/)[^\/]*(\?.*)?$/,'') + // convert mathjax/latest to mathjax/x.y-latest so that all files are the same version + .replace(/^(https?:\/\/cdn.mathjax.org\/mathjax\/)(latest)/,"$1"+BASE.version.split(/\./).slice(0,2).join(".")+"-$2"); + BASE.Ajax.config.root = CONFIG.root; break; } } - BASE.Ajax.config = CONFIG; + var AGENT = navigator.userAgent; var BROWSERS = { isMac: (navigator.platform.substr(0,3) === "Mac"), isPC: (navigator.platform.substr(0,3) === "Win"), - isMSIE: (window.ActiveXObject != null && window.clipboardData != null), - isFirefox: (window.netscape != null && document.ATTRIBUTE_NODE != null && !window.opera), - isSafari: (navigator.userAgent.match(/ (Apple)?WebKit\//) != null && - (!window.chrome || window.chrome.loadTimes == null)), - isChrome: (window.chrome != null && window.chrome.loadTimes != null), - isOpera: (window.opera != null && window.opera.version != null), - isKonqueror: (window.hasOwnProperty && window.hasOwnProperty("konqueror") && navigator.vendor == "KDE"), + isMSIE: ("ActiveXObject" in window && "clipboardData" in window), + isEdge: ("MSGestureEvent" in window && "chrome" in window && + window.chrome.loadTimes == null), + isFirefox: (!!AGENT.match(/Gecko\//) && !AGENT.match(/like Gecko/)), + isSafari: (!!AGENT.match(/ (Apple)?WebKit\//) && !AGENT.match(/ like iPhone /) && + (!window.chrome || window.chrome.app == null)), + isChrome: ("chrome" in window && window.chrome.loadTimes != null), + isOpera: ("opera" in window && window.opera.version != null), + isKonqueror: ("konqueror" in window && navigator.vendor == "KDE"), versionAtLeast: function (v) { var bv = (this.version).split('.'); v = (new String(v)).split('.'); for (var i = 0, m = v.length; i < m; i++) @@ -2322,7 +3125,7 @@ MathJax.Hub.Startup = { } }; - var AGENT = navigator.userAgent + var xAGENT = AGENT .replace(/^Mozilla\/(\d+\.)+\d+ /,"") // remove initial Mozilla, which is never right .replace(/[a-z][-a-z0-9._: ]+\/\d+[^ ]*-[^ ]*\.([a-z][a-z])?\d+ /i,"") // remove linux version .replace(/Gentoo |Ubuntu\/(\d+\.)*\d+ (\([^)]*\) )?/,""); // special case for these @@ -2334,37 +3137,42 @@ MathJax.Hub.Startup = { if (browser === "Mac" || browser === "PC") continue; HUB.Browser = HUB.Insert(new String(browser),BROWSERS); var VERSION = new RegExp( - ".*(Version)/((?:\\d+\\.)+\\d+)|" + // for Safari and Opera10 - ".*("+browser+")"+(browser == "MSIE" ? " " : "/")+"((?:\\d+\\.)*\\d+)|"+ // for one of the main browser + ".*(Version/| Trident/.*; rv:)((?:\\d+\\.)+\\d+)|" + // for Safari, Opera10, and IE11+ + ".*("+browser+")"+(browser == "MSIE" ? " " : "/")+"((?:\\d+\\.)*\\d+)|"+ // for one of the main browsers "(?:^|\\(| )([a-z][-a-z0-9._: ]+|(?:Apple)?WebKit)/((?:\\d+\\.)+\\d+)"); // for unrecognized browser - var MATCH = VERSION.exec(AGENT) || ["","","","unknown","0.0"]; - HUB.Browser.name = (MATCH[1] == "Version" ? browser : (MATCH[3] || MATCH[5])); + var MATCH = VERSION.exec(xAGENT) || ["","","","unknown","0.0"]; + HUB.Browser.name = (MATCH[1] != "" ? browser : (MATCH[3] || MATCH[5])); HUB.Browser.version = MATCH[2] || MATCH[4] || MATCH[6]; break; } }}; // - // Initial browser-specific info (e.g., touch up version or name) + // Initial browser-specific info (e.g., touch up version or name, check for MathPlayer, etc.) + // Wrap in try/catch just in case of error (see issue #1155). // - HUB.Browser.Select({ + try {HUB.Browser.Select({ Safari: function (browser) { var v = parseInt((String(browser.version).split("."))[0]); if (v > 85) {browser.webkit = browser.version} - if (v >= 534) {browser.version = "5.1"} + if (v >= 538) {browser.version = "8.0"} + else if (v >= 537) {browser.version = "7.0"} + else if (v >= 536) {browser.version = "6.0"} + else if (v >= 534) {browser.version = "5.1"} else if (v >= 533) {browser.version = "5.0"} else if (v >= 526) {browser.version = "4.0"} else if (v >= 525) {browser.version = "3.1"} else if (v > 500) {browser.version = "3.0"} else if (v > 400) {browser.version = "2.0"} else if (v > 85) {browser.version = "1.0"} + browser.webkit = (navigator.appVersion.match(/WebKit\/(\d+)\./))[1]; browser.isMobile = (navigator.appVersion.match(/Mobile/i) != null); browser.noContextMenu = browser.isMobile; }, Firefox: function (browser) { - if ((browser.version === "0.0" || navigator.userAgent.match(/Firefox/) == null) && + if ((browser.version === "0.0" || AGENT.match(/Firefox/) == null) && navigator.product === "Gecko") { - var rv = navigator.userAgent.match(/[\/ ]rv:(\d+\.\d.*?)[\) ]/); + var rv = AGENT.match(/[\/ ]rv:(\d+\.\d.*?)[\) ]/); if (rv) {browser.version = rv[1]} else { var date = (navigator.buildID||navigator.productSub||"0").substr(0,8); @@ -2381,30 +3189,57 @@ MathJax.Hub.Startup = { } } browser.isMobile = (navigator.appVersion.match(/Android/i) != null || - navigator.userAgent.match(/ Fennec\//) != null); + AGENT.match(/ Fennec\//) != null || + AGENT.match(/Mobile/) != null); + }, + Chrome: function (browser) { + browser.noContextMenu = browser.isMobile = !!navigator.userAgent.match(/ Mobile[ \/]/); }, Opera: function (browser) {browser.version = opera.version()}, + Edge: function (browser) { + browser.isMobile = !!navigator.userAgent.match(/ Phone/); + }, MSIE: function (browser) { + browser.isMobile = !!navigator.userAgent.match(/ Phone/); browser.isIE9 = !!(document.documentMode && (window.performance || window.msPerformance)); MathJax.HTML.setScriptBug = !browser.isIE9 || document.documentMode < 9; - var MathPlayer = false; - try {new ActiveXObject("MathPlayer.Factory.1"); MathPlayer = true} catch(err) {} - if (MathPlayer && !STARTUP.params.NoMathPlayer) { - var mathplayer = document.createElement("object"); - mathplayer.id = "mathplayer"; mathplayer.classid = "clsid:32F66A20-7614-11D4-BD11-00104BD3F987"; - document.getElementsByTagName("head")[0].appendChild(mathplayer); - document.namespaces.add("m","http://www.w3.org/1998/Math/MathML"); - browser.hasMathPlayer = true; - if (document.readyState && (document.readyState === "loading" || - document.readyState === "interactive")) { - document.write(''); - browser.mpImported = true; - } + MathJax.Hub.msieHTMLCollectionBug = (document.documentMode < 9); + // + // MathPlayer doesn't function properly in IE10, and not at all in IE11, + // so don't even try to load it. + // + if (document.documentMode < 10 && !STARTUP.params.NoMathPlayer) { + try { + new ActiveXObject("MathPlayer.Factory.1"); + browser.hasMathPlayer = true; + } catch (err) {} + try { + if (browser.hasMathPlayer) { + var mathplayer = document.createElement("object"); + mathplayer.id = "mathplayer"; mathplayer.classid = "clsid:32F66A20-7614-11D4-BD11-00104BD3F987"; + HEAD.appendChild(mathplayer); + document.namespaces.add("m","http://www.w3.org/1998/Math/MathML"); + browser.mpNamespace = true; + if (document.readyState && (document.readyState === "loading" || + document.readyState === "interactive")) { + document.write(''); + browser.mpImported = true; + } + } else { + // Adding any namespace avoids a crash in IE9 in IE9-standards mode + // (any reference to document.namespaces before document.readyState is + // "complete" causes an "unspecified error" to be thrown) + document.namespaces.add("mjx_IE_fix","http://www.w3.org/1999/xlink"); + } + } catch (err) {} } } - }); + });} catch (err) { + console.error(err.message); + } HUB.Browser.Select(MathJax.Message.browsers); + if (BASE.AuthorConfig && typeof BASE.AuthorConfig.AuthorInit === "function") {BASE.AuthorConfig.AuthorInit()} HUB.queue = BASE.Callback.Queue(); HUB.queue.Push( ["Post",STARTUP.signal,"Begin"], @@ -2432,5 +3267,3 @@ MathJax.Hub.Startup = { })("MathJax"); }} - -/**********************************************************/ diff --git a/resources/viewer/mathjax/extensions/AssistiveMML.js b/resources/viewer/mathjax/extensions/AssistiveMML.js new file mode 100644 index 0000000000..e9f1975171 --- /dev/null +++ b/resources/viewer/mathjax/extensions/AssistiveMML.js @@ -0,0 +1,151 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/AssistiveMML.js + * + * Implements an extension that inserts hidden MathML into the + * page for screen readers or other asistive technology. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2015 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. + */ + +(function (AJAX,CALLBACK,HUB,HTML) { + var SETTINGS = HUB.config.menuSettings; + + var AssistiveMML = MathJax.Extension["AssistiveMML"] = { + version: "2.6.0", + + config: { + disabled: false, + styles: { + ".MJX_Assistive_MathML": { + position:"absolute!important", + top: 0, left: 0, + clip: (HUB.Browser.isMSIE && (document.documentMode||0) < 8 ? + "rect(1px 1px 1px 1px)" : "rect(1px, 1px, 1px, 1px)"), + padding: "1px 0 0 0!important", + border: "0!important", + height: "1px!important", + width: "1px!important", + overflow: "hidden!important", + display:"block!important" + }, + ".MJX_Assistive_MathML.MJX_Assistive_MathML_Block": { + width: "100%!important" + } + } + }, + + Config: function () { + if (!this.config.disabled && SETTINGS.assistiveMML == null) + HUB.Config({menuSettings:{assistiveMML:true}}); + AJAX.Styles(this.config.styles); + HUB.Register.MessageHook("End Math",function (msg) { + if (SETTINGS.assistiveMML) return AssistiveMML.AddAssistiveMathML(msg[1]) + }); + }, + + // + // This sets up a state object that lists the jax and index into the jax, + // and a dummy callback that is used to synchronizing with MathJax. + // It will be called when the jax are all processed, and that will + // let the MathJax queue continue (it will block until then). + // + AddAssistiveMathML: function (node) { + var state = { + jax: HUB.getAllJax(node), i: 0, + callback: MathJax.Callback({}) + }; + this.HandleMML(state); + return state.callback; + }, + + // + // This removes the data-mathml attribute and the assistive MathML from + // all the jax. + // + RemoveAssistiveMathML: function (node) { + var jax = HUB.getAllJax(node), frame; + for (var i = 0, m = jax.length; i < m; i++) { + frame = document.getElementById(jax[i].inputID+"-Frame"); + if (frame && frame.getAttribute("data-mathml")) { + frame.removeAttribute("data-mathml"); + if (frame.lastChild && frame.lastChild.className.match(/MJX_Assistive_MathML/)) + frame.removeChild(frame.lastChild); + } + } + }, + + // + // For each jax in the state, look up the frame. + // If the jax doesn't use NativeMML and hasn't already been handled: + // Get the MathML for the jax, taking resets into account. + // Add a data-mathml attribute to the frame, and + // Create a span that is not visible on screen and put the MathML in it, + // and add it to the frame. + // When all the jax are processed, call the callback. + // + HandleMML: function (state) { + var m = state.jax.length, jax, mml, frame, span; + while (state.i < m) { + jax = state.jax[state.i]; + frame = document.getElementById(jax.inputID+"-Frame"); + if (jax.outputJax !== "NativeMML" && frame && !frame.getAttribute("data-mathml")) { + try { + mml = jax.root.toMathML("").replace(/\n */g,"").replace(//g,""); + } catch (err) { + if (!err.restart) throw err; // an actual error + return MathJax.Callback.After(["HandleMML",this,state],err.restart); + } + frame.setAttribute("data-mathml",mml); + span = HTML.addElement(frame,"span",{ + isMathJax: true, + className: "MJX_Assistive_MathML" + + (jax.root.Get("display") === "block" ? " MJX_Assistive_MathML_Block" : "") + }); + span.innerHTML = mml; + frame.style.position = "relative"; + frame.setAttribute("role","presentation"); + frame.firstChild.setAttribute("aria-hidden","true"); + span.setAttribute("role","presentation"); + } + state.i++; + } + state.callback(); + } + + }; + + HUB.Startup.signal.Post("AssistiveMML Ready"); + +})(MathJax.Ajax,MathJax.Callback,MathJax.Hub,MathJax.HTML); + +// +// Make sure the toMathML extension is loaded before we signal +// the load complete for this extension. Then wait for the end +// of the user configuration before configuring this extension. +// +MathJax.Callback.Queue( + ["Require",MathJax.Ajax,"[MathJax]/extensions/toMathML.js"], + ["loadComplete",MathJax.Ajax,"[MathJax]/extensions/AssistiveMML.js"], + function () { + MathJax.Hub.Register.StartupHook("End Config",["Config",MathJax.Extension.AssistiveMML]); + } +); + diff --git a/resources/viewer/mathjax/extensions/CHTML-preview.js b/resources/viewer/mathjax/extensions/CHTML-preview.js new file mode 100644 index 0000000000..4562fd3236 --- /dev/null +++ b/resources/viewer/mathjax/extensions/CHTML-preview.js @@ -0,0 +1,30 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/CHTML-preview.js + * + * Backward compatibility with old CHTML-preview extension. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2014-2015 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.Callback.Queue( + ["Require",MathJax.Ajax,"[MathJax]/extensions/fast-preview.js"], + ["loadComplete",MathJax.Ajax,"[MathJax]/extensions/CHTML-preview.js"] +); diff --git a/resources/viewer/mathjax/extensions/FontWarnings.js b/resources/viewer/mathjax/extensions/FontWarnings.js index 02e1a5814b..f97a974545 100644 --- a/resources/viewer/mathjax/extensions/FontWarnings.js +++ b/resources/viewer/mathjax/extensions/FontWarnings.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/FontWarnings.js @@ -67,7 +70,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -83,7 +86,10 @@ */ (function (HUB,HTML) { - var VERSION = "2.0"; + var VERSION = "2.6.0"; + + var STIXURL = "http://www.stixfonts.org/"; + var MATHJAXURL = "https://github.com/mathjax/MathJax/tree/master/fonts/HTML-CSS/TeX/otf"; var CONFIG = HUB.CombineConfig("FontWarnings",{ // @@ -110,33 +116,37 @@ // The messages for the various situations // Message: { + webFont: [ ["closeBox"], - "MathJax is using web-based fonts to display the mathematics ", - "on this page. These take time to download, so the page would ", - "render faster if you installed math fonts directly in your ", - "system's font folder.", + ["webFont", + "MathJax is using web-based fonts to display the mathematics "+ + "on this page. These take time to download, so the page would "+ + "render faster if you installed math fonts directly in your "+ + "system's font folder."], ["fonts"] ], imageFonts: [ ["closeBox"], - "MathJax is using its image fonts rather than local or web-based fonts. ", - "This will render slower than usual, and the mathematics may not print ", - "at the full resolution of your printer.", + ["imageFonts", + "MathJax is using its image fonts rather than local or web-based fonts. "+ + "This will render slower than usual, and the mathematics may not print "+ + "at the full resolution of your printer."], ["fonts"], - ["webfonts"] + ["webFonts"] ], noFonts: [ ["closeBox"], - "MathJax is unable to locate a font to use to display ", - "its mathematics, and image fonts are not available, so it ", - "is falling back on generic unicode characters in hopes that ", - "your browser will be able to display them. Some characters ", - "may not show up properly, or possibly not at all.", + ["noFonts", + "MathJax is unable to locate a font to use to display "+ + "its mathematics, and image fonts are not available, so it "+ + "is falling back on generic unicode characters in hopes that "+ + "your browser will be able to display them. Some characters "+ + "may not show up properly, or possibly not at all."], ["fonts"], - ["webfonts"] + ["webFonts"] ] }, @@ -168,34 +178,40 @@ [["span",{style:{position:"relative", bottom:".2em"}},["x"]]] ]], - webfonts: [ + webFonts: [ ["p"], - "Most modern browsers allow for fonts to be downloaded over the web. ", - "Updating to a more recent version of your browser (or changing browsers) ", - "could improve the quality of the mathematics on this page." + ["webFonts", + "Most modern browsers allow for fonts to be downloaded over the web. "+ + "Updating to a more recent version of your browser (or changing "+ + "browsers) could improve the quality of the mathematics on this page." + ] ], - + fonts: [ ["p"], - "MathJax can use either the ", - ["a",{href:"http://www.stixfonts.org/",target:"_blank"},"STIX fonts"], - " or the ", - ["a",{href:"http://www.mathjax.org/help-v2/fonts/",target:"_blank"},["MathJax TeX fonts"]], - ". Download and install either one to improve your MathJax experience." + ["fonts", + "MathJax can use either the [STIX fonts](%1) or the [MathJax TeX fonts](%2). " + + "Download and install one of those fonts to improve your MathJax experience.", + STIXURL,MATHJAXURL + ] ], - - STIXfonts: [ - ["p"], - "This page is designed to use the ", - ["a",{href:"http://www.stixfonts.org/",target:"_blank"},"STIX fonts"], - ". Download and install those fonts to improve your MathJax experience." - ], - + + STIXfonts: [ + ["p"], + ["STIXPage", + "This page is designed to use the [STIX fonts](%1). " + + "Download and install those fonts to improve your MathJax experience.", + STIXURL + ] + ], + TeXfonts: [ ["p"], - "This page is designed to use the ", - ["a",{href:"http://www.mathjax.org/help-v2/fonts/",target:"_blank"},["MathJax TeX fonts"]], - ". Download and install those fonts to improve your MathJax experience." + ["TeXPage", + "This page is designed to use the [MathJax TeX fonts](%1). " + + "Download and install those fonts to improve your MathJax experience.", + MATHJAXURL + ] ] }, @@ -225,16 +241,26 @@ if (HUB.Browser.isMSIE) { if (CONFIG.messageStyle.position === "fixed") { MathJax.Message.Init(); // make sure MathJax_MSIE_frame exists - frame = document.getElementById("MathJax_MSIE_Frame"); - CONFIG.messageStyle.position = "absolute"; + frame = document.getElementById("MathJax_MSIE_Frame") || frame; + if (frame !== document.body) {CONFIG.messageStyle.position = "absolute"} } } else {delete CONFIG.messageStyle.filter} CONFIG.messageStyle.maxWidth = (document.body.clientWidth-75) + "px"; var i = 0; while (i < data.length) { - if (data[i] instanceof Array && CONFIG.HTML[data[i][0]]) - {data.splice.apply(data,[i,1].concat(CONFIG.HTML[data[i][0]]))} else {i++} + if (data[i] instanceof Array) { + if (data[i].length === 1 && CONFIG.HTML[data[i][0]]) { + data.splice.apply(data,[i,1].concat(CONFIG.HTML[data[i][0]])); + } else if (typeof data[i][1] === "string") { + var message = MathJax.Localization.lookupPhrase(["FontWarnings",data[i][0]],data[i][1]); + message = MathJax.Localization.processMarkdown(message,data[i].slice(2),"FontWarnings"); + data.splice.apply(data,[i,1].concat(message)); + i += message.length; + } else {i++} + } else {i++} } - DATA.div = HTMLCSS.addElement(frame,"div",{id:"MathJax_FontWarning",style:CONFIG.messageStyle},data); + DATA.div = HTMLCSS.addElement(frame,"div", + {id:"MathJax_FontWarning",style:CONFIG.messageStyle},data); + MathJax.Localization.setCSS(DATA.div); if (CONFIG.removeAfter) { HUB.Register.StartupHook("End",function () {DATA.timer = setTimeout(FADEOUT,CONFIG.removeAfter)}); @@ -276,7 +302,8 @@ if (message.match(/- Web-Font/)) {if (localFonts) {MSG = "webFont"}} else if (message.match(/- using image fonts/)) {MSG = "imageFonts"} else if (message.match(/- no valid font/)) {MSG = "noFonts"} - if (MSG && CONFIG.Message[MSG]) {CREATEMESSAGE(CONFIG.Message[MSG])} + if (MSG && CONFIG.Message[MSG]) + {MathJax.Localization.loadDomain("FontWarnings",[CREATEMESSAGE,CONFIG.Message[MSG]])} } }); } diff --git a/resources/viewer/mathjax/extensions/HTML-CSS/handle-floats.js b/resources/viewer/mathjax/extensions/HTML-CSS/handle-floats.js new file mode 100644 index 0000000000..b919a05405 --- /dev/null +++ b/resources/viewer/mathjax/extensions/HTML-CSS/handle-floats.js @@ -0,0 +1,82 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/HTML-CSS/handle-floats.js + * + * This extension allows HTML-CSS output to deal with floating elements + * better. In particular, when there are tags or equation numbers, these + * would overlap floating elements, but with this extension, the width of + * the line should properly correspond to the amount of space remaining. + * + * To load it, include + * + * "HTML-CSS": { + * extensions: ["handle-floats.js"] + * } + * + * in your configuration. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2012-2015 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["HTML-CSS/handle-floats"] = { + version: "2.6.0" +}; + +// +// Make the display DIV be a table-cell +// Use padding to get the separation, since table cells don't do margin +// Make the width large (it will shrink to fit the remaining room) +// +MathJax.Hub.Config({ + "HTML-CSS": { + styles: { + ".MathJax_Display": { + display: "table-cell", + padding: "1em 0 ! important", + width: (MathJax.Hub.Browser.isMSIE && (document.documentMode||0) < 8 ? "100%" : "1000em") + } + } + } +}); + +// +// Two consecutive equations would end up side-by-side, so force a separator +// (Needed by IE8, IE9, and Firefox, at least). +// +MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { + var HTMLCSS = MathJax.OutputJax["HTML-CSS"], + TRANSLATE = HTMLCSS.Translate; + HTMLCSS.Augment({ + Translate: function (script,state) { + TRANSLATE.apply(this,arguments); + if (script.MathJax.elementJax.HTMLCSS.display) { + var next = script.nextSibling; + if (!next || next.className !== "MathJax_MSIE_Separator") { + var span = HTMLCSS.Element("span",{className:"MathJax_MSIE_Separator"}); + script.parentNode.insertBefore(span,next); + } + } + } + }); + MathJax.Hub.Startup.signal.Post("HTML-CSS handle-floats Ready"); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/HTML-CSS/handle-floats.js"); diff --git a/resources/viewer/mathjax/extensions/HelpDialog.js b/resources/viewer/mathjax/extensions/HelpDialog.js new file mode 100644 index 0000000000..48fdb39af0 --- /dev/null +++ b/resources/viewer/mathjax/extensions/HelpDialog.js @@ -0,0 +1,203 @@ +/************************************************************* + * + * MathJax/extensions/HelpDialog.js + * + * Implements the MathJax Help dialog box. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2015 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. + */ + +(function (HUB,HTML,AJAX,OUTPUT,LOCALE) { + + var HELP = MathJax.Extension.Help = { + version: "2.6.0" + }; + + var STIXURL = "http://www.stixfonts.org/"; + var MENU = MathJax.Menu; + var FALSE, KEY; + HUB.Register.StartupHook("MathEvents Ready",function () { + FALSE = MathJax.Extension.MathEvents.Event.False; + KEY = MathJax.Extension.MathEvents.Event.KEY; + }); + + + var CONFIG = HUB.CombineConfig("HelpDialog",{ + + styles: { + "#MathJax_Help": { + position:"fixed", left:"50%", width:"auto", "max-width": "90%", "text-align":"center", + border:"3px outset", padding:"1em 2em", "background-color":"#DDDDDD", color:"black", + cursor: "default", "font-family":"message-box", "font-size":"120%", + "font-style":"normal", "text-indent":0, "text-transform":"none", + "line-height":"normal", "letter-spacing":"normal", "word-spacing":"normal", + "word-wrap":"normal", "white-space":"wrap", "float":"none", "z-index":201, + + "border-radius": "15px", // Opera 10.5 and IE9 + "-webkit-border-radius": "15px", // Safari and Chrome + "-moz-border-radius": "15px", // Firefox + "-khtml-border-radius": "15px", // Konqueror + + "box-shadow":"0px 10px 20px #808080", // Opera 10.5 and IE9 + "-webkit-box-shadow":"0px 10px 20px #808080", // Safari 3 and Chrome + "-moz-box-shadow":"0px 10px 20px #808080", // Forefox 3.5 + "-khtml-box-shadow":"0px 10px 20px #808080", // Konqueror + filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')" // IE + }, + "#MathJax_Help.MathJax_MousePost": { + outline:"none" + }, + + "#MathJax_HelpContent": { + overflow:"auto", "text-align":"left", "font-size":"80%", + padding:".4em .6em", border:"1px inset", margin:"1em 0px", + "max-height":"20em", "max-width":"30em", "background-color":"#EEEEEE" + }, + + "#MathJax_HelpClose": { + position:"absolute", top:".2em", right:".2em", + cursor:"pointer", + display:"inline-block", + border:"2px solid #AAA", + "border-radius":"18px", + "-webkit-border-radius": "18px", // Safari and Chrome + "-moz-border-radius": "18px", // Firefox + "-khtml-border-radius": "18px", // Konqueror + "font-family":"'Courier New',Courier", + "font-size":"24px", + color:"#F0F0F0" + }, + "#MathJax_HelpClose span": { + display:"block", "background-color":"#AAA", border:"1.5px solid", + "border-radius":"18px", + "-webkit-border-radius": "18px", // Safari and Chrome + "-moz-border-radius": "18px", // Firefox + "-khtml-border-radius": "18px", // Konqueror + "line-height":0, + padding:"8px 0 6px" // may need to be browser-specific + }, + "#MathJax_HelpClose:hover": { + color:"white!important", + border:"2px solid #CCC!important" + }, + "#MathJax_HelpClose:hover span": { + "background-color":"#CCC!important" + }, + "#MathJax_HelpClose:hover:focus": { + outline:"none" + } + } + }); + + /* + * Handle the Help Dialog box + */ + HELP.Dialog = function (event) { + LOCALE.loadDomain("HelpDialog",["Post",HELP,event]); + }; + + HELP.Post = function (event) { + this.div = MENU.Background(this); + var help = HTML.addElement(this.div,"div",{ + id: "MathJax_Help", tabIndex: 0, onkeydown: HELP.Keydown + },LOCALE._("HelpDialog",[ + ["b",{style:{fontSize:"120%"}},[["Help","MathJax Help"]]], + ["div",{id: "MathJax_HelpContent", tabIndex: 0},[ + ["p",{},[["MathJax", + "*MathJax* is a JavaScript library that allows page authors to include " + + "mathematics within their web pages. As a reader, you don't need to do " + + "anything to make that happen."]] + ], + ["p",{},[["Browsers", + "*Browsers*: MathJax works with all modern browsers including IE6+, Firefox 3+, " + + "Chrome 0.2+, Safari 2+, Opera 9.6+ and most mobile browsers."]] + ], + ["p",{},[["Menu", + "*Math Menu*: MathJax adds a contextual menu to equations. Right-click or " + + "CTRL-click on any mathematics to access the menu."]] + ], + ["div",{style:{"margin-left":"1em"}},[ + ["p",{},[["ShowMath", + "*Show Math As* allows you to view the formula's source markup " + + "for copy & paste (as MathML or in its original format)."]] + ], + ["p",{},[["Settings", + "*Settings* gives you control over features of MathJax, such as the " + + "size of the mathematics, and the mechanism used to display equations."]] + ], + ["p",{},[["Language", + "*Language* lets you select the language used by MathJax for its menus " + + "and warning messages."]] + ], + ]], + ["p",{},[["Zoom", + "*Math Zoom*: If you are having difficulty reading an equation, MathJax can " + + "enlarge it to help you see it better."]] + ], + ["p",{},[["Accessibilty", + "*Accessibility*: MathJax will automatically work with screen readers to make " + + "mathematics accessible to the visually impaired."]] + ], + ["p",{},[["Fonts", + "*Fonts*: MathJax will use certain math fonts if they are installed on your " + + "computer; otherwise, it will use web-based fonts. Although not required, " + + "locally installed fonts will speed up typesetting. We suggest installing " + + "the [STIX fonts](%1).",STIXURL]] + ] + ]], + ["a",{href:"http://www.mathjax.org/"},["www.mathjax.org"]], + ["span",{id: "MathJax_HelpClose", onclick: HELP.Remove, + onkeydown: HELP.Keydown, tabIndex: 0, role: "button", + "aria-label": LOCALE._(["HelpDialog","CloseDialog"],"Close help dialog")}, + [["span",{},["\u00D7"]]] + ] + ])); + if (event.type === "mouseup") help.className += " MathJax_MousePost"; + help.focus(); + LOCALE.setCSS(help); + var doc = (document.documentElement||{}); + var H = window.innerHeight || doc.clientHeight || doc.scrollHeight || 0; + if (MENU.prototype.msieAboutBug) { + help.style.width = "20em"; help.style.position = "absolute"; + help.style.left = Math.floor((document.documentElement.scrollWidth - help.offsetWidth)/2)+"px"; + help.style.top = (Math.floor((H-help.offsetHeight)/3)+document.body.scrollTop)+"px"; + } else { + help.style.marginLeft = Math.floor(-help.offsetWidth/2)+"px"; + help.style.top = Math.floor((H-help.offsetHeight)/3)+"px"; + } + }; + HELP.Remove = function (event) { + if (HELP.div) {document.body.removeChild(HELP.div); delete HELP.div} + }; + HELP.Keydown = function(event) { + if (event.keyCode === KEY.ESCAPE || + (this.id === "MathJax_HelpClose" && + (event.keyCode === KEY.SPACE || event.keyCode === KEY.RETURN))) { + HELP.Remove(event); + MENU.CurrentNode().focus(); + FALSE(event); + } + }, + + MathJax.Callback.Queue( + HUB.Register.StartupHook("End Config",{}), // wait until config is complete + ["Styles",AJAX,CONFIG.styles], + ["Post",HUB.Startup.signal,"HelpDialig Ready"], + ["loadComplete",AJAX,"[MathJax]/extensions/HelpDialog.js"] + ); + +})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.OutputJax,MathJax.Localization); diff --git a/resources/viewer/mathjax/extensions/MatchWebFonts.js b/resources/viewer/mathjax/extensions/MatchWebFonts.js new file mode 100644 index 0000000000..c3dd3f7edf --- /dev/null +++ b/resources/viewer/mathjax/extensions/MatchWebFonts.js @@ -0,0 +1,309 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/MatchWebFonts.js + * + * Adds code to the output jax so that if web fonts are used on the page, + * MathJax will be able to detect their arrival and update the math to + * accommodate the change in font. For the NativeMML output, this works + * both for web fonts in main text, and for web fonts in the math as well. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2015 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. + */ + +(function (HUB,AJAX) { + var VERSION = "2.6.0"; + + var CONFIG = MathJax.Hub.CombineConfig("MatchWebFonts",{ + matchFor: { + "HTML-CSS": true, + NativeMML: true, + SVG: true + }, + fontCheckDelay: 500, // initial delay for the first check for web fonts + fontCheckTimeout: 15 * 1000, // how long to keep looking for fonts (15 seconds) + }); + + MathJax.Extension.MatchWebFonts = { + version: VERSION, + config: CONFIG + }; + + HUB.Register.StartupHook("HTML-CSS Jax Ready",function () { + var HTMLCSS = MathJax.OutputJax["HTML-CSS"]; + var POSTTRANSLATE = HTMLCSS.postTranslate; + + HTMLCSS.Augment({ + postTranslate: function (state,partial) { + if (!partial && CONFIG.matchFor["HTML-CSS"] && this.config.matchFontHeight) { + // + // Check for changes in the web fonts that might affect the font + // size for math elements. This is a periodic check that goes on + // until a timeout is reached. + // + AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]], + CONFIG.fontCheckDelay,CONFIG.fontCheckTimeout); + } + return POSTTRANSLATE.apply(this,arguments); // do the original function + }, + + checkFonts: function (check,scripts) { + if (check.time(function () {})) return; + var size = [], i, m, retry = false; + // + // Add the elements used for testing ex and em sizes + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script); + } + } + // + // Check to see if anything has changed + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; if (!script.parentNode) continue; retry = true; + var jax = script.MathJax.elementJax; if (!jax) continue; + // + // Check if ex or mex has changed + // + var test = script.previousSibling; + var ex = test.firstChild.offsetHeight/60; + var em = test.lastChild.lastChild.offsetHeight/60; + if (ex === 0 || ex === "NaN") {ex = this.defaultEx; em = this.defaultEm} + if (ex !== jax.HTMLCSS.ex || em !== jax.HTMLCSS.em) { + var scale = ex/this.TeX.x_height/em; + scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)*this.config.scale); + if (scale/100 !== jax.scale) {size.push(script); scripts[i] = {}} + } + } + // + // Remove markers + // + scripts = scripts.concat(size); // some scripts have been moved to the size array + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; + if (script && script.parentNode && script.MathJax.elementJax) { + script.parentNode.removeChild(script.previousSibling); + } + } + // + // Rerender the changed items + // + if (size.length) {HUB.Queue(["Rerender",HUB,[size],{}])} + // + // Try again later + // + if (retry) {setTimeout(check,check.delay)} + } + }); + }); + + HUB.Register.StartupHook("SVG Jax Ready",function () { + var SVG = MathJax.OutputJax.SVG; + var POSTTRANSLATE = SVG.postTranslate; + + SVG.Augment({ + postTranslate: function (state,partial) { + if (!partial && CONFIG.matchFor.SVG) { + // + // Check for changes in the web fonts that might affect the font + // size for math elements. This is a periodic check that goes on + // until a timeout is reached. + // + AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]], + CONFIG.fontCheckDelay,CONFIG.fontCheckTimeout); + } + return POSTTRANSLATE.apply(this,arguments); // do the original function + }, + + checkFonts: function (check,scripts) { + if (check.time(function () {})) return; + var size = [], i, m, retry = false; + // + // Add the elements used for testing ex and em sizes + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.insertBefore(this.ExSpan.cloneNode(true),script); + } + } + // + // Check to see if anything has changed + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; if (!script.parentNode) continue; retry = true; + var jax = script.MathJax.elementJax; if (!jax) continue; + // + // Check if ex or mex has changed + // + var test = script.previousSibling; + var ex = test.firstChild.offsetHeight/60; + if (ex === 0 || ex === "NaN") {ex = this.defaultEx} + if (ex !== jax.SVG.ex) {size.push(script); scripts[i] = {}} + } + // + // Remove markers + // + scripts = scripts.concat(size); // some scripts have been moved to the size array + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.removeChild(script.previousSibling); + } + } + // + // Rerender the changed items + // + if (size.length) {HUB.Queue(["Rerender",HUB,[size],{}])} + // + // Try again later (if not all the scripts are null) + // + + if (retry) setTimeout(check,check.delay); + } + }); + }); + + HUB.Register.StartupHook("NativeMML Jax Ready",function () { + var nMML = MathJax.OutputJax.NativeMML; + var POSTTRANSLATE = nMML.postTranslate; + + nMML.Augment({ + postTranslate: function (state) { + if (!HUB.Browser.isMSIE && CONFIG.matchFor.NativeMML) { + // + // Check for changes in the web fonts that might affect the sizes + // of math elements. This is a periodic check that goes on until + // a timeout is reached. + // + AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]], + CONFIG.fontCheckDelay,CONFIG.fontCheckTimeout); + } + POSTTRANSLATE.apply(this,arguments); // do the original routine + }, + + // + // Check to see if web fonts have been loaded that change the ex size + // of the surrounding font, the ex size within the math, or the widths + // of math elements. We do this by rechecking the ex and mex sizes + // (to see if the font scaling needs adjusting) and by checking the + // size of the inner mrow of math elements and mtd elements. The + // sizes of these have been stored in the NativeMML object of the + // element jax so that we can check for them here. + // + checkFonts: function (check,scripts) { + if (check.time(function () {})) return; + var adjust = [], mtd = [], size = [], i, m, script; + // + // Add the elements used for testing ex and em sizes + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script); + } + } + // + // Check to see if anything has changed + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; if (!script.parentNode) continue; + var jax = script.MathJax.elementJax; if (!jax) continue; + var span = document.getElementById(jax.inputID+"-Frame"); + var math = span.getElementsByTagName("math")[0]; if (!math) continue; + jax = jax.NativeMML; + // + // Check if ex or mex has changed + // + var test = script.previousSibling; + var ex = test.firstChild.offsetWidth/60; + var mex = test.lastChild.offsetWidth/60; + if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx} + var newEx = (ex !== jax.ex); + if (newEx || mex != jax.mex) { + var scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1); + scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale); + if (scale/100 !== jax.scale) {size.push([span.style,scale])} + jax.scale = scale/100; jax.fontScale = scale+"%"; jax.ex = ex; jax.mex = mex; + } + + // + // Check width of math elements + // + if ("scrollWidth" in jax && (newEx || jax.scrollWidth !== math.firstChild.scrollWidth)) { + jax.scrollWidth = math.firstChild.scrollWidth; + adjust.push([math.parentNode.style,jax.scrollWidth/jax.ex/jax.scale]); + } + // + // Check widths of mtd elements + // + if (math.MathJaxMtds) { + for (var j = 0, n = math.MathJaxMtds.length; j < n; j++) { + if (!math.MathJaxMtds[j].parentNode) continue; + if (newEx || math.MathJaxMtds[j].firstChild.scrollWidth !== jax.mtds[j]) { + jax.mtds[j] = math.MathJaxMtds[j].firstChild.scrollWidth; + mtd.push([math.MathJaxMtds[j],jax.mtds[j]/jax.ex]); + } + } + } + } + // + // Remove markers + // + for (i = 0, m = scripts.length; i < m; i++) { + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.removeChild(script.previousSibling); + } + } + // + // Adjust scaling factor + // + for (i = 0, m = size.length; i < m; i++) { + size[i][0].fontSize = size[i][1] + "%"; + } + // + // Adjust width of spans containing math elements that have changed + // + for (i = 0, m = adjust.length; i < m; i++) { + adjust[i][0].width = adjust[i][1].toFixed(3)+"ex"; + } + // + // Adjust widths of mtd elements that have changed + // + for (i = 0, m = mtd.length; i < m; i++) { + var style = mtd[i][0].getAttribute("style"); + style = style.replace(/(($|;)\s*min-width:).*?ex/,"$1 "+mtd[i][1].toFixed(3)+"ex"); + mtd[i][0].setAttribute("style",style); + } + // + // Try again later + // + setTimeout(check,check.delay); + } + }); + }); + + HUB.Startup.signal.Post("MatchWebFonts Extension Ready"); + AJAX.loadComplete("[MathJax]/extensions/MatchWebFonts.js"); + +})(MathJax.Hub,MathJax.Ajax); diff --git a/resources/viewer/mathjax/extensions/MathEvents.js b/resources/viewer/mathjax/extensions/MathEvents.js index fd17e4c070..0c106d6b1a 100644 --- a/resources/viewer/mathjax/extensions/MathEvents.js +++ b/resources/viewer/mathjax/extensions/MathEvents.js @@ -1,20 +1,23 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/MathEvents.js - * + * * Implements the event handlers needed by the output jax to perform * menu, hover, and other events. * * --------------------------------------------------------------------- - * - * Copyright (c) 2011-2012 Design Science, Inc. - * + * + * Copyright (c) 2011-2015 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. @@ -22,14 +25,14 @@ * limitations under the License. */ -(function (HUB,HTML,AJAX,CALLBACK,OUTPUT,INPUT) { - var VERSION = "2.0"; - +(function (HUB,HTML,AJAX,CALLBACK,LOCALE,OUTPUT,INPUT) { + var VERSION = "2.6.0"; + var EXTENSION = MathJax.Extension; var ME = EXTENSION.MathEvents = {version: VERSION}; - + var SETTINGS = HUB.config.menuSettings; - + var CONFIG = { hover: 500, // time required to be considered a hover frame: { @@ -38,11 +41,10 @@ bcolor: "#A6D", // frame border color hwidth: "15px", // haze width hcolor: "#83A" // haze color - }, + }, button: { - x: -4, y: -3, // menu button offsets - wx: -2, // button offset for full-width equations - src: AJAX.fileURL(OUTPUT.imageDir+"/MenuArrow-15.png") // button image + x: -6, y: -3, // menu button offsets + wx: -2 // button offset for full-width equations }, fadeinInc: .2, // increment for fade-in fadeoutInc: .05, // increment for fade-out @@ -66,24 +68,61 @@ display: "inline-block", position:"absolute" }, - ".MathJax_Hover_Arrow": { + ".MathJax_Menu_Button .MathJax_Hover_Arrow": { position:"absolute", - width:"15px", height:"11px", - cursor:"pointer" + cursor:"pointer", + display:"inline-block", + border:"2px solid #AAA", + "border-radius":"4px", + "-webkit-border-radius": "4px", // Safari and Chrome + "-moz-border-radius": "4px", // Firefox + "-khtml-border-radius": "4px", // Konqueror + "font-family":"'Courier New',Courier", + "font-size":"9px", + color:"#F0F0F0" + }, + ".MathJax_Menu_Button .MathJax_Hover_Arrow span": { + display:"block", + "background-color":"#AAA", + border:"1px solid", + "border-radius":"3px", + "line-height":0, + padding:"4px" + }, + ".MathJax_Hover_Arrow:hover": { + color:"white!important", + border:"2px solid #CCC!important" + }, + ".MathJax_Hover_Arrow:hover span": { + "background-color":"#CCC!important" } } }; - + // // Common event-handling code // var EVENT = ME.Event = { - + LEFTBUTTON: 0, // the event.button value for left button RIGHTBUTTON: 2, // the event.button value for right button MENUKEY: "altKey", // the event value for alternate context menu + /*************************************************************/ + /* + * Enum element for key codes. + */ + KEY: { + RETURN: 13, + ESCAPE: 27, + SPACE: 32, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40 + }, + Mousedown: function (event) {return EVENT.Handler(event,"Mousedown",this)}, Mouseup: function (event) {return EVENT.Handler(event,"Mouseup",this)}, Mousemove: function (event) {return EVENT.Handler(event,"Mousemove",this)}, @@ -92,7 +131,7 @@ Click: function (event) {return EVENT.Handler(event,"Click",this)}, DblClick: function (event) {return EVENT.Handler(event,"DblClick",this)}, Menu: function (event) {return EVENT.Handler(event,"ContextMenu",this)}, - + // // Call the output jax's event handler or the zoom handler // @@ -104,21 +143,30 @@ if (jax[type]) {return jax[type](event,math)} if (EXTENSION.MathZoom) {return EXTENSION.MathZoom.HandleEvent(event,type,math)} }, - + // // Try to cancel the event in every way we can // False: function (event) { if (!event) {event = window.event} if (event) { - if (event.preventDefault) {event.preventDefault()} + if (event.preventDefault) {event.preventDefault()} else {event.returnValue = false} if (event.stopPropagation) {event.stopPropagation()} event.cancelBubble = true; - event.returnValue = false; } return false; }, + // + // Keydown event handler. Should only fire on Space key. + // + Keydown: function (event, math) { + if (!event) event = window.event; + if (event.keyCode === EVENT.KEY.SPACE) { + EVENT.ContextMenu(event, this); + }; + }, + // // Load the contextual menu code, if needed, and post the menu // @@ -141,35 +189,68 @@ } // - // If the menu code is loaded, post the menu - // Otherwse lad the menu code and try again + // If the menu code is loaded, + // Check if localization needs loading; + // If not, post the menu, and return. + // Otherwise wait for the localization to load + // Otherwse load the menu code. + // Try again after the file is loaded. // - var MENU = MathJax.Menu; + var MENU = MathJax.Menu; var load, fn; if (MENU) { - MENU.jax = jax; - var source = MENU.menu.Find("Show Math As").menu; - source.items[1].name = (INPUT[jax.inputJax].sourceMenuTitle||"Original Form"); - source.items[0].hidden = (jax.inputJax === "Error"); // hide MathML choice for error messages - var MathPlayer = MENU.menu.Find("Math Settings","MathPlayer"); - MathPlayer.hidden = !(jax.outputJax === "NativeMML" && HUB.Browser.hasMathPlayer); - return MENU.menu.Post(event); - } else { - if (!AJAX.loadingMathMenu) { - AJAX.loadingMathMenu = true; - var ev = { - pageX:event.pageX, pageY:event.pageY, - clientX:event.clientX, clientY:event.clientY - }; - CALLBACK.Queue( - AJAX.Require("[MathJax]/extensions/MathMenu.js"), - function () {delete AJAX.loadingMathMenu; if (!MathJax.Menu) {MathJax.Menu = {}}}, - ["ContextMenu",this,ev,math,force] // call this function again - ); + if (MENU.loadingDomain) {return EVENT.False(event)} + load = LOCALE.loadDomain("MathMenu"); + if (!load) { + MENU.jax = jax; + var source = MENU.menu.Find("Show Math As").submenu; + source.items[0].name = jax.sourceMenuTitle; + source.items[0].format = (jax.sourceMenuFormat||"MathML"); + source.items[1].name = INPUT[jax.inputJax].sourceMenuTitle; + source.items[5].disabled = !INPUT[jax.inputJax].annotationEncoding; + + // + // Try and find each known annotation format and enable the menu + // items accordingly. + // + var annotations = source.items[2]; annotations.disabled = true; + var annotationItems = annotations.submenu.items; + annotationList = MathJax.Hub.Config.semanticsAnnotations; + for (var i = 0, m = annotationItems.length; i < m; i++) { + var name = annotationItems[i].name[1] + if (jax.root && jax.root.getAnnotation(name) !== null) { + annotations.disabled = false; + annotationItems[i].hidden = false; + } else { + annotationItems[i].hidden = true; + } + } + + var MathPlayer = MENU.menu.Find("Math Settings","MathPlayer"); + MathPlayer.hidden = !(jax.outputJax === "NativeMML" && HUB.Browser.hasMathPlayer); + return MENU.menu.Post(event); + } + MENU.loadingDomain = true; + fn = function () {delete MENU.loadingDomain}; + } else { + if (AJAX.loadingMathMenu) {return EVENT.False(event)} + AJAX.loadingMathMenu = true; + load = AJAX.Require("[MathJax]/extensions/MathMenu.js"); + fn = function () { + delete AJAX.loadingMathMenu; + if (!MathJax.Menu) {MathJax.Menu = {}} } - return EVENT.False(event); } + var ev = { + pageX:event.pageX, pageY:event.pageY, + clientX:event.clientX, clientY:event.clientY + }; + CALLBACK.Queue( + load, fn, // load the file and delete the marker when done + ["ContextMenu",EVENT,ev,math,force] // call this function again + ); + return EVENT.False(event); }, - + // // Mousedown handler for alternate means of accessing menu // @@ -186,26 +267,26 @@ return JAX.ContextMenu(event,math,true); } }, - + ClearSelection: function () { if (ME.safariContextMenuBug) {setTimeout("window.getSelection().empty()",0)} if (document.selection) {setTimeout("document.selection.empty()",0)} }, - + getBBox: function (span) { span.appendChild(ME.topImg); var h = ME.topImg.offsetTop, d = span.offsetHeight-h, w = span.offsetWidth; span.removeChild(ME.topImg); return {w:w, h:h, d:d}; } - + }; - + // // Handle hover "discoverability" // var HOVER = ME.Hover = { - + // // Check if we are moving from a non-MathJax element to a MathJax one // and either start fading in again (if it is fading out) or start the @@ -215,7 +296,7 @@ if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") { var from = event.fromElement || event.relatedTarget, to = event.toElement || event.target; - if (from && to && (from.isMathJax != to.isMathJax || + if (from && to && (HUB.isMathJaxNode(from) !== HUB.isMathJaxNode(to) || HUB.getJaxFor(from) !== HUB.getJaxFor(to))) { var jax = this.getJaxFromMath(math); if (jax.hover) {HOVER.ReHover(jax)} else {HOVER.HoverTimer(jax,math)} @@ -232,7 +313,7 @@ if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") { var from = event.fromElement || event.relatedTarget, to = event.toElement || event.target; - if (from && to && (from.isMathJax != to.isMathJax || + if (from && to && (HUB.isMathJaxNode(from) !== HUB.isMathJaxNode(to) || HUB.getJaxFor(from) !== HUB.getJaxFor(to))) { var jax = this.getJaxFromMath(math); if (jax.hover) {HOVER.UnHover(jax)} else {HOVER.ClearHoverTimer()} @@ -252,7 +333,7 @@ return EVENT.False(event); } }, - + // // Clear the old timer and start a new one // @@ -263,7 +344,7 @@ ClearHoverTimer: function () { if (this.hoverTimer) {clearTimeout(this.hoverTimer); delete this.hoverTimer} }, - + // // Handle putting up the hover frame // @@ -299,17 +380,17 @@ ]] ); var button = HTML.Element("span",{ - isMathJax: true, id:jax.hover.id+"Menu", + isMathJax: true, id:jax.hover.id+"Menu", className:"MathJax_Menu_Button", style:{display:"inline-block", "z-index": 1, width:0, height:0, position:"relative"} - },[["img",{ + },[["span",{ className: "MathJax_Hover_Arrow", isMathJax: true, math: math, - src: CONFIG.button.src, onclick: this.HoverMenu, jax:JAX.id, + onclick: this.HoverMenu, jax:JAX.id, style: { left:this.Px(bbox.w+dx+dd+(bbox.x||0)+CONFIG.button.x), top:this.Px(-bbox.h-dy-dd-(bbox.y||0)-CONFIG.button.y), opacity:0, filter:"alpha(opacity=0)" } - }]] + },[["span",{isMathJax:true},"\u25BC"]]]] ); if (bbox.width) { frame.style.width = button.style.width = bbox.width; @@ -374,7 +455,7 @@ jax.hover.timer = setTimeout(CALLBACK(["HoverFade",this,jax]),(delay||CONFIG.fadeDelay)); } }, - + // // Handle a click on the menu button // @@ -382,7 +463,7 @@ if (!event) {event = window.event} return OUTPUT[this.jax].ContextMenu(event,this.math,true); }, - + // // Clear all hover timers // @@ -392,7 +473,7 @@ HOVER.ClearHoverTimer(); delete jax.hover; }, - + // // Make a measurement in pixels // @@ -405,14 +486,16 @@ // Preload images so they show up with the menu // getImages: function () { - var menu = new Image(); - menu.src = CONFIG.button.src; + if (SETTINGS.discoverable) { + var menu = new Image(); + menu.src = CONFIG.button.src; + } } }; - + // - // Handle touch events. + // Handle touch events. // // Use double-tap-and-hold as a replacement for context menu event. // Use double-tap as a replacement for double click. @@ -421,57 +504,61 @@ last: 0, // time of last tap event delay: 500, // delay time for double-click - + // // Check if this is a double-tap, and if so, start the timer // for the double-tap and hold (to trigger the contextual menu) // start: function (event) { var now = new Date().getTime(); - var dblTap = (now - TOUCH.last < TOUCH.delay); - TOUCH.last = now; + var dblTap = (now - TOUCH.last < TOUCH.delay && TOUCH.up); + TOUCH.last = now; TOUCH.up = false; if (dblTap) { TOUCH.timeout = setTimeout(TOUCH.menu,TOUCH.delay,event,this); event.preventDefault(); } }, - + // - // Check if there is a timeout pending, i.e., we have a + // Check if there is a timeout pending, i.e., we have a // double-tap and were waiting to see if it is held long // enough for the menu. Since we got the end before the // timeout, it is a double-click, not a double-tap-and-hold. // Prevent the default action and issue a double click. // end: function (event) { + var now = new Date().getTime(); + TOUCH.up = (now - TOUCH.last < TOUCH.delay); if (TOUCH.timeout) { clearTimeout(TOUCH.timeout); - delete TOUCH.timeout; TOUCH.last = 0; + delete TOUCH.timeout; TOUCH.last = 0; TOUCH.up = false; event.preventDefault(); return EVENT.Handler((event.touches[0]||event.touch),"DblClick",this); } }, - + // // If the timeout passes without an end event, we issue // the contextual menu event. // menu: function (event,math) { - delete TOUCH.timeout; TOUCH.last = 0; + delete TOUCH.timeout; TOUCH.last = 0; TOUCH.up = false; return EVENT.Handler((event.touches[0]||event.touch),"ContextMenu",math); } - + }; - - // - // Mobile screens are small, so use larger version of arrow - // - if (HUB.Browser.isMobile) { - var arrow = CONFIG.styles[".MathJax_Hover_Arrow"]; - arrow.width = "25px"; arrow.height = "18px"; - CONFIG.button.x = -6; - } - + + /* + * // + * // Mobile screens are small, so use larger version of arrow + * // + * if (HUB.Browser.isMobile) { + * var arrow = CONFIG.styles[".MathJax_Hover_Arrow"]; + * arrow.width = "25px"; arrow.height = "18px"; + * CONFIG.button.x = -6; + * } + */ + // // Set up browser-specific values // @@ -494,7 +581,7 @@ ME.noContextMenuBug = true; // doesn't produce contextmenu event } }); - + // // Used in measuring zoom and hover positions // @@ -515,7 +602,7 @@ haze["-moz-box-shadow"] = haze["-khtml-box-shadow"] = "0px 0px "+CONFIG.frame.hwidth+" "+CONFIG.frame.hcolor; }; - + // // Queue the events needed for startup // @@ -527,5 +614,6 @@ ["Post",HUB.Startup.signal,"MathEvents Ready"], ["loadComplete",AJAX,"[MathJax]/extensions/MathEvents.js"] ); - -})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback,MathJax.OutputJax,MathJax.InputJax); + +})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback, + MathJax.Localization,MathJax.OutputJax,MathJax.InputJax); diff --git a/resources/viewer/mathjax/extensions/MathML/content-mathml.js b/resources/viewer/mathjax/extensions/MathML/content-mathml.js new file mode 100644 index 0000000000..b1846603f3 --- /dev/null +++ b/resources/viewer/mathjax/extensions/MathML/content-mathml.js @@ -0,0 +1,1730 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/MathML/content-mathml.js + * + * This file provides methods to convert Content-MathML to + * Presentation MathML for processing by MathJax. The transform is + * performed in a DOM filter for the MathML input jax, so that the + * Show Math As menu will still show the Original MathML as Content MathML, + * but the Presentation MathML can be obtained from the main MathML menu. + * + * To load it, include + * + * MathML: { + * extensions: ["content-mathml.js"] + * } + * + * in your configuration. + * + * A portion of this file is taken from ctop.js which is + * Copyright (c) David Carlisle 2001, 2002, 2008, 2009, 2013, + * and is used by permission of David Carlisle, who has agreed to allow us + * to release it under the Apache2 license (see below). That portion is + * indicated via comments. + * + * The remainder falls under the copyright that follows. + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2015 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["MathML/content-mathml"] = (function(HUB) { + /* + * Content MathML to Presentation MathML conversion + * + * based on David Carlisle's ctop.js - https://web-xslt.googlecode.com/svn/trunk/ctop/ctop.js + * + */ + + + var isMSIE = HUB.Browser.isMSIE; + + if (isMSIE) { + try {document.namespaces.add("m","http://www.w3.org/1998/Math/MathML")} catch (err) {} + } + + var CONFIG = HUB.CombineConfig("MathML.content-mathml",{ + // render `a+(-b)` as `a-b`? + collapsePlusMinus: true, + + /* mathvariant to use with corresponding type attribute */ + cistyles: { + vector: 'bold-italic', + matrix: 'bold-upright' + }, + + /* Symbol names to translate to characters + */ + symbols: { + gamma: '\u03B3' + } + + }); + + var CToP = { + version: "2.6.0", + settings: CONFIG, + + /* Transform the given elements from Content MathML to Presentation MathML and replace the original elements + */ + transformElements: function(elements) { + for (var i = 0, l = elements.length; i= 0) element = CToP.cloneNode(element,true); // removes namespaces + var mathNode = CToP.cloneNode(element); + for (var j = 0, l = element.childNodes.length; j1) { + CToP.applyTransform(mrow,args[0],tokenPrecedence); + } + CToP.appendToken(mrow,'mo',name); + if (args.length>0) { + var z = args[(args.length === 1)?0:1]; + CToP.applyTransform(mrow,z,tokenPrecedence); + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + } + }, + + /* Transform an infix operator + * + * (function factory) + */ + infix: function(name,tokenPrecedence) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>tokenPrecedence; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j0) { + CToP.appendToken(mrow,'mo',name); + } + CToP.applyTransform(mrow,args[j],tokenPrecedence); + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + } + }, + + /* Transform an iterated operation, e.g. summation + * + * (function factory + */ + iteration: function(name,limitSymbol) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var mo = CToP.createElement('mo'); + CToP.setTextContent(mo,name); + var munderover = CToP.createElement('munderover'); + munderover.appendChild(mo); + var mrow1 = CToP.createElement('mrow'); + var i, j, num_qualifiers, num_bvars, children, bvar, num_children, num_args; + for (i = 0, num_qualifiers = qualifiers.length; i',1), + lt: CToP.transforms.infix('<',1), + geq: CToP.transforms.infix('\u2265',1), + leq: CToP.transforms.infix('\u2264',1), + equivalent: CToP.transforms.infix('\u2261',1), + approx: CToP.transforms.infix('\u2248',1), + subset: CToP.transforms.infix('\u2286',2), + prsubset: CToP.transforms.infix('\u2282',2), + cartesianproduct: CToP.transforms.infix('\u00D7',2), + "cartesian_product": CToP.transforms.infix('\u00D7',2), + vectorproduct: CToP.transforms.infix('\u00D7',2), + scalarproduct: CToP.transforms.infix('.',2), + outerproduct: CToP.transforms.infix('\u2297',2), + sum: CToP.transforms.iteration('\u2211','='), + product: CToP.transforms.iteration('\u220F','='), + forall: CToP.transforms.bind('\u2200','.',','), + exists: CToP.transforms.bind('\u2203','.',','), + lambda: CToP.transforms.bind('\u03BB','.',','), + limit: CToP.transforms.iteration('lim','\u2192'), + sdev: CToP.transforms.fn('\u03c3'), + determinant: CToP.transforms.fn('det'), + max: CToP.transforms.minmax('max'), + min: CToP.transforms.minmax('min'), + real: CToP.transforms.fn('\u211b'), + imaginary: CToP.transforms.fn('\u2111'), + set: CToP.transforms.set('{','}'), + list: CToP.transforms.set('(',')'), + + exp: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + CToP.appendToken(msup,'mi','e'); + CToP.applyTransform(msup,args[0],0); + parentNode.appendChild(msup); + }, + + union: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length) { + CToP.transforms.iteration('\u22C3','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } else { + CToP.transforms.infix('\u222A',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + intersect: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length) { + CToP.transforms.iteration('\u22C2','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } else { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>2; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j0) { + CToP.appendToken(mrow,'mo','\u2229'); + if (args[j].nodeName === 'apply') { + var child = CToP.getChildren(args[j])[0]; + argBrackets = child.nodeName === 'union'; + } + } + if (argBrackets) { + CToP.appendToken(mrow,'mo','('); + } + CToP.applyTransform(mrow,args[j],2); + if (argBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + } + }, + + floor: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u230a'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','\u230b'); + parentNode.appendChild(mrow); + }, + + conjugate: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mover = CToP.createElement('mover'); + CToP.applyTransform(mover,args[0],0); + CToP.appendToken(mover,'mo','\u00af'); + parentNode.appendChild(mover); + }, + + abs: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','|'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','|'); + parentNode.appendChild(mrow); + }, + + and: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length || qualifiers.length) { + CToP.transforms.iteration('\u22c0','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4); + } else { + CToP.transforms.infix('\u2227',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + or: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length || qualifiers.length) { + CToP.transforms.iteration('\u22c1','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4); + } else { + CToP.transforms.infix('\u2228',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + xor: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length || qualifiers.length) { + CToP.transforms.iteration('xor','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4); + } else { + CToP.transforms.infix('xor',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + card: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','|'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','|'); + parentNode.appendChild(mrow); + }, + + mean: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (args.length === 1) { + var mover = CToP.createElement('mover'); + CToP.applyTransform(mover,args[0],0); + CToP.appendToken(mover,'mo','\u00af'); + parentNode.appendChild(mover); + } else { + parentNode.appendChild(CToP.createmfenced(args,'\u27e8','\u27e9')); + } + }, + + moment: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var degree, momentabout, children, i, j, l; + + for (i = 0, l = qualifiers.length; i1) { + argrow.appendChild(CToP.createmfenced(args,'(',')')); + } else { + CToP.applyTransform(argrow,args[0],0); + } + if (degree) { + var msup = CToP.createElement('msup'); + msup.appendChild(argrow); + children = CToP.getChildren(degree); + for (j = 0, l = children.length; j3; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j0) { + CToP.appendToken(mrow,'mo',(args[j].nodeName === 'cn') ? "\u00D7" :"\u2062"); + } + CToP.applyTransform(mrow,args[j],3); + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + }, + + plus: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>2; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j0) { + var n; + if (CToP.settings.collapsePlusMinus) { + if (arg.nodeName === 'cn' && !(children.length) && (n = Number(CToP.getTextContent(arg))) <0) { + CToP.appendToken(mrow,'mo','\u2212'); + CToP.appendToken(mrow,'mn', -n); + } else if (arg.nodeName === 'apply' && children.length === 2 && children[0].nodeName === 'minus') { + CToP.appendToken(mrow,'mo','\u2212'); + CToP.applyTransform(mrow,children[1],2); + } else if (arg.nodeName === 'apply' && children.length>2 && children[0].nodeName === 'times' && children[1].nodeName === 'cn' && ( n = Number(CToP.getTextContent(children[1])) < 0)) { + CToP.appendToken(mrow,'mo','\u2212'); + CToP.getTextContent(children[1]) = -n;// fix me: modifying document + CToP.applyTransform(mrow,arg,2); + } else{ + CToP.appendToken(mrow,'mo','+'); + CToP.applyTransform(mrow,arg,2); + } + } else { + CToP.appendToken(mrow,'mo','+'); + CToP.applyTransform(mrow,arg,2); + } + } else { + CToP.applyTransform(mrow,arg,2); + } + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + }, + + transpose: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + CToP.applyTransform(msup,args[0],precedence); + CToP.appendToken(msup,'mi','T'); + parentNode.appendChild(msup); + }, + + power: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + CToP.applyTransform(msup,args[0],3); + CToP.applyTransform(msup,args[1],precedence); + parentNode.appendChild(msup); + }, + + selector: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msub = CToP.createElement('msub'); + var mrow = args ? args[0]: CToP.createElement('mrow'); + CToP.applyTransform(msub,mrow,0); + var mrow2 = CToP.createElement('mrow'); + for (var i = 1, l = args.length; i1) { + CToP.applyTransform(mrow,args[1],0); + } + } + CToP.appendToken(mrow,'mo','\u230B'); + parentNode.appendChild(mrow); + }, + + factorial: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.applyTransform(mrow,args[0],4); + CToP.appendToken(mrow,'mo','!'); + parentNode.appendChild(mrow); + }, + + root: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mr; + if (firstArg.nodeName === 'root' && (qualifiers.length === 0 || (qualifiers[0].nodeName === 'degree' && CToP.getTextContent(qualifiers[0]) === '2'))) { + mr = CToP.createElement('msqrt'); + for (var i = 0, l = args.length; i1) { + var msup = CToP.createElement('msup'); + CToP.applyTransform(msup,bvar,0); + CToP.appendToken(msup,'mn',degree); + bottomrow.appendChild(msup); + } else { + CToP.applyTransform(bottomrow,bvar,0); + } + } + for (i = 0, l = lambdaSequence.length; i0) { + if (hadFirst) { + CToP.appendToken(degreeRow,'mo','+'); + } + CToP.appendToken(degreeRow,'mn',degree); + } + } + + if (args.length) { + differendNode = args[0]; + } + + for (i = 0, l = bvars.length; i but use MATHML.Parse's preProcessMath to apply the normal preprocessing. + if (!MATHML.ParseXML) {MATHML.ParseXML = MATHML.createParser()} + var doc = MATHML.ParseXML(PARSE.preProcessMath(data.math)); + + // Now transform the using the mml3 stylesheet. + var newdoc = MATHML.mml3XSLT.transformToDocument(doc); + + if ((typeof newdoc) === "string") { + // Internet Explorer returns a string, so just use it. + data.math = newdoc; + } else if (window.XMLSerializer) { + // Serialize the again. We could directly provide the DOM content + // but other prefilterHooks may assume data.math is still a string. + var serializer = new XMLSerializer(); + data.math = serializer.serializeToString(newdoc.documentElement, doc); + } + }); + + /* + * The following is derived from mml3mj.xsl + * (https://github.com/davidcarlisle/web-xslt/blob/master/ctop/mml3mj.xsl) + * which is Copyright (c) David Carlisle 2008-2015. + * It is used by permission of David Carlisle, who has agreed to allow it to + * be released under the Apache License, Version 2.0. + */ + var BROWSER = MathJax.Hub.Browser; + var exslt = ''; + if (BROWSER.isEdge || BROWSER.isMSIE) { + exslt = 'urn:schemas-microsoft-com:xslt' + } else { + exslt = 'http://exslt.org/common'; + } + var mml3Stylesheet = + '' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + '' + + ' ' + + ' ltr' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + '' + + ' )' + + '' + + ' (' + + '' + + '' + + ' ]' + + '' + + '' + + ' [' + + '' + + '' + + ' }' + + '' + + '' + + ' {' + + '' + + '' + + ' ' + + '' + + ' )' + + '' + + ' (' + + '' + + '' + + ' ]' + + '' + + '' + + ' [' + + '' + + '' + + ' }' + + '' + + '' + + ' {' + + '' + + ' ' + + ' ' + + ' \' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ')' + + '(' + + '}' + + '{' + + '>' + + '<' + + '' + + '' + + '' + + ' top right' + + '' + + '' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 0' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' decimalpoint' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' decimalpoint' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' .' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' decimalpoint' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' *' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 0.1em' + + ' 0.15em' + + ' 0.2em' + + ' ' + + ' 0.15em' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 0' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' )' + + ' ' + + ' (' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' /' + + ' ' + + ' \' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' :' + + ' ' + + ' =' + + ' ' + + ' ' + + ' ' + + ' ' + + ' top' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' )' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ''; + + /* + * End of mml3mj.xsl material. + */ + + var mml3; + if (window.XSLTProcessor) { + // standard method: just use an XSLTProcessor and parse the stylesheet + if (!MATHML.ParseXML) {MATHML.ParseXML = MATHML.createParser()} + MATHML.mml3XSLT = new XSLTProcessor(); + MATHML.mml3XSLT.importStylesheet(MATHML.ParseXML(mml3Stylesheet)); + } else if (MathJax.Hub.Browser.isMSIE) { + // nonstandard methods for Internet Explorer + if (MathJax.Hub.Browser.versionAtLeast("9.0") || (document.documentMode||0) >= 9) { + // For Internet Explorer >= 9, use createProcessor + mml3 = new ActiveXObject("Msxml2.FreeThreadedDOMDocument"); + mml3.loadXML(mml3Stylesheet); + var xslt = new ActiveXObject("Msxml2.XSLTemplate"); + xslt.stylesheet = mml3; + MATHML.mml3XSLT = { + mml3: xslt.createProcessor(), + transformToDocument: function(doc) { + this.mml3.input = doc; + this.mml3.transform(); + return this.mml3.output; + } + } + } else { + // For Internet Explorer <= 8, use transformNode + mml3 = MATHML.createMSParser(); + mml3.async = false; + mml3.loadXML(mml3Stylesheet); + MATHML.mml3XSLT = { + mml3: mml3, + transformToDocument: function(doc) { + return doc.documentElement.transformNode(this.mml3); + } + } + } + } else { + // No XSLT support. Do not change the content. + MATHML.mml3XSLT = null; + } + + // Tweak CSS to avoid some browsers rearranging HTML output + MathJax.Ajax.Styles({ + ".MathJax .mi, .MathJax .mo, .MathJax .mn, .MathJax .mtext": { + direction: "ltr", + display: "inline-block" + }, + ".MathJax .ms, .MathJax .mspace, .MathJax .mglyph": { + direction: "ltr", + display: "inline-block" + } + }); + + MathJax.Hub.Startup.signal.Post("MathML mml3.js Ready"); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/MathML/mml3.js"); diff --git a/resources/viewer/mathjax/extensions/MathMenu.js b/resources/viewer/mathjax/extensions/MathMenu.js index d0273543b0..caa69de335 100644 --- a/resources/viewer/mathjax/extensions/MathMenu.js +++ b/resources/viewer/mathjax/extensions/MathMenu.js @@ -1,21 +1,24 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/MathMenu.js - * + * * Implements a right-mouse (or CTRL-click) menu over mathematics * elements that gives the user the ability to copy the source, * change the math size, and zoom settings. * * --------------------------------------------------------------------- - * - * Copyright (c) 2010-2012 Design Science, Inc. - * + * + * Copyright (c) 2010-2015 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. @@ -24,35 +27,52 @@ */ (function (HUB,HTML,AJAX,CALLBACK,OUTPUT) { - var VERSION = "2.0"; + var VERSION = "2.6.0"; + + var SIGNAL = MathJax.Callback.Signal("menu"); // signal for menu events - var SIGNAL = MathJax.Callback.Signal("menu") // signal for menu events - MathJax.Extension.MathMenu = { version: VERSION, signal: SIGNAL }; + var _ = function (id) { + return MathJax.Localization._.apply( + MathJax.Localization, + [["MathMenu",id]].concat([].slice.call(arguments,1)) + ); + }; + var isPC = HUB.Browser.isPC, isMSIE = HUB.Browser.isMSIE, isIE9 = ((document.documentMode||0) > 8); var ROUND = (isPC ? null : "5px"); - + var CONFIG = HUB.CombineConfig("MathMenu",{ delay: 150, // the delay for submenus - helpURL: "http://www.mathjax.org/help-v2/user/", // the URL for the "MathJax Help" menu - closeImg: AJAX.fileURL(OUTPUT.imageDir+"/CloseX-31.png"), // image for close "X" for mobiles showRenderer: true, // show the "Math Renderer" menu? showMathPlayer: true, // show the "MathPlayer" menu? showFontMenu: false, // show the "Font Preference" menu? showContext: false, // show the "Context Menu" menu? showDiscoverable: false, // show the "Discoverable" menu? + showLocale: true, // show the "Locale" menu? + showLocaleURL: false, // show the "Load from URL" menu? + + semanticsAnnotations: { + "TeX": ["TeX", "LaTeX", "application/x-tex"], + "StarMath": ["StarMath 5.0"], + "Maple": ["Maple"], + "ContentMathML": ["MathML-Content", "application/mathml-content+xml"], + "OpenMath": ["OpenMath"] + }, windowSettings: { // for source window status: "no", toolbar: "no", locationbar: "no", menubar: "no", directories: "no", personalbar: "no", resizable: "yes", scrollbars: "yes", - width: 100, height: 50 + width: 400, height: 300, + left: Math.round((screen.width - 400)/2), + top: Math.round((screen.height - 300)/3) }, - + styles: { "#MathJax_About": { position:"fixed", left:"50%", width:"auto", "text-align":"center", @@ -73,6 +93,9 @@ "-khtml-box-shadow":"0px 10px 20px #808080", // Konqueror filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')" // IE }, + "#MathJax_About.MathJax_MousePost": { + outline:"none" + }, ".MathJax_Menu": { position:"absolute", "background-color":"white", color:"black", @@ -99,110 +122,210 @@ background:"transparent" }, - ".MathJax_MenuTitle": { - "background-color":"#CCCCCC", - margin: (isPC ? "-1px -1px 1px -1px" : "-5px 0 0 0"), - "text-align":"center", "font-style":"italic", "font-size":"80%", color:"#444444", - padding:"2px 0", overflow:"hidden" - }, - ".MathJax_MenuArrow": { - position:"absolute", right:".5em", color:"#666666", - "font-family": (isMSIE ? "'Arial unicode MS'" : null) + position:"absolute", right:".5em", "padding-top":".25em", color:"#666666", + "font-family": (isMSIE ? "'Arial unicode MS'" : null), "font-size": ".75em" }, ".MathJax_MenuActive .MathJax_MenuArrow": {color:"white"}, + ".MathJax_MenuArrow.RTL": {left:".5em", right:"auto"}, ".MathJax_MenuCheck": { position:"absolute", left:".7em", "font-family": (isMSIE ? "'Arial unicode MS'" : null) }, + ".MathJax_MenuCheck.RTL": {right:".7em", left:"auto"}, ".MathJax_MenuRadioCheck": { position:"absolute", left: (isPC ? "1em" : ".7em") }, + ".MathJax_MenuRadioCheck.RTL": { + right: (isPC ? "1em" : ".7em"), left:"auto" + }, ".MathJax_MenuLabel": { padding: (isPC ? "2px 2em 4px 1.33em" : "1px 2em 3px 1.33em"), "font-style":"italic" }, - + ".MathJax_MenuRule": { "border-top": (isPC ? "1px solid #CCCCCC" : "1px solid #DDDDDD"), margin: (isPC ? "4px 1px 0px" : "4px 3px") }, - + ".MathJax_MenuDisabled": { color:"GrayText" }, - ".MathJax_MenuActive": { "background-color": (isPC ? "Highlight" : "#606872"), color: (isPC ? "HighlightText" : "white") }, - - ".MathJax_Menu_Close": { - position:"absolute", - width: "31px", height: "31px", - top:"-15px", left:"-15px" + + ".MathJax_MenuDisabled:focus, .MathJax_MenuLabel:focus": { + "background-color": "#E8E8E8" + }, + ".MathJax_ContextMenu:focus": { + outline:"none" + }, + ".MathJax_ContextMenu .MathJax_MenuItem:focus": { + outline:"none" + }, + + "#MathJax_AboutClose": { + top:".2em", right:".2em" + }, + ".MathJax_Menu .MathJax_MenuClose": { + top:"-10px", left:"-10px" + }, + + ".MathJax_MenuClose": { + position:"absolute", + cursor:"pointer", + display:"inline-block", + border:"2px solid #AAA", + "border-radius":"18px", + "-webkit-border-radius": "18px", // Safari and Chrome + "-moz-border-radius": "18px", // Firefox + "-khtml-border-radius": "18px", // Konqueror + "font-family":"'Courier New',Courier", + "font-size":"24px", + color:"#F0F0F0" + }, + ".MathJax_MenuClose span": { + display:"block", "background-color":"#AAA", border:"1.5px solid", + "border-radius":"18px", + "-webkit-border-radius": "18px", // Safari and Chrome + "-moz-border-radius": "18px", // Firefox + "-khtml-border-radius": "18px", // Konqueror + "line-height":0, + padding:"8px 0 6px" // may need to be browser-specific + }, + ".MathJax_MenuClose:hover": { + color:"white!important", + border:"2px solid #CCC!important" + }, + ".MathJax_MenuClose:hover span": { + "background-color":"#CCC!important" + }, + ".MathJax_MenuClose:hover:focus": { + outline:"none" } } }); - - var FALSE, HOVER; + + var FALSE, HOVER, KEY; HUB.Register.StartupHook("MathEvents Ready",function () { FALSE = MathJax.Extension.MathEvents.Event.False; HOVER = MathJax.Extension.MathEvents.Hover; + KEY = MathJax.Extension.MathEvents.Event.KEY; }); - + + + /*************************************************************/ + /* + * Abstract class of all keyboard navigatable objects. + */ + var NAV = MathJax.Object.Subclass({ + /* + * Moving in the list of items. + */ + Keydown: function(event, menu) { + switch (event.keyCode) { + case KEY.ESCAPE: + this.Remove(event, menu); + break; + case KEY.RIGHT: + this.Right(event, menu); + break; + case KEY.LEFT: + this.Left(event, menu); + break; + case KEY.UP: + this.Up(event, menu); + break; + case KEY.DOWN: + this.Down(event, menu); + break; + case KEY.RETURN: + case KEY.SPACE: + this.Space(event, menu); + break; + default: + return; + break; + } + return FALSE(event); + }, + Escape: function(event, menu) { }, + Right: function(event, menu) { }, + Left: function(event, menu) { }, + Up: function(event, menu) { }, + Down: function(event, menu) { }, + Space: function(event, menu) { } + }, {}); + + /*************************************************************/ /* * The main menu class */ - var MENU = MathJax.Menu = MathJax.Object.Subclass({ + var MENU = MathJax.Menu = NAV.Subclass({ version: VERSION, items: [], posted: false, title: null, margin: 5, - + Init: function (def) {this.items = [].slice.call(arguments,0)}, With: function (def) {if (def) {HUB.Insert(this,def)}; return this}, /* * Display the menu */ - Post: function (event,parent) { - if (!event) {event = window.event}; - var title = (!this.title ? null : [["div",{className: "MathJax_MenuTitle"},[this.title]]]); + Post: function (event,parent,forceLTR) { + if (!event) {event = window.event||{}} var div = document.getElementById("MathJax_MenuFrame"); if (!div) { div = MENU.Background(this); delete ITEM.lastItem; delete ITEM.lastMenu; delete MENU.skipUp; SIGNAL.Post(["post",MENU.jax]); + MENU.isRTL = (MathJax.Localization.fontDirection() === "rtl"); } - var menu = HTML.addElement(div,"div",{ + var menu = HTML.Element("div",{ onmouseup: MENU.Mouseup, ondblclick: FALSE, ondragstart: FALSE, onselectstart: FALSE, oncontextmenu: FALSE, - menuItem: this, className: "MathJax_Menu" - },title); + menuItem: this, className: "MathJax_Menu", onkeydown: MENU.Keydown, + role: "menu" + }); + if (event.type === "contextmenu" || event.type === "mouseover") + menu.className += " MathJax_ContextMenu"; + if (!forceLTR) {MathJax.Localization.setCSS(menu)} for (var i = 0, m = this.items.length; i < m; i++) {this.items[i].Create(menu)} if (MENU.isMobile) { HTML.addElement(menu,"span",{ - className: "MathJax_Menu_Close", menu: parent, + className: "MathJax_MenuClose", menu: parent, ontouchstart: MENU.Close, ontouchend: FALSE, onmousedown: MENU.Close, onmouseup: FALSE - },[["img",{src: CONFIG.closeImg, style:{width:"100%",height:"100%"}}]]); + },[["span",{},"\u00D7"]]); } + + div.appendChild(menu); this.posted = true; - - menu.style.width = (menu.offsetWidth+2) + "px"; + if (menu.offsetWidth) menu.style.width = (menu.offsetWidth+2) + "px"; var x = event.pageX, y = event.pageY; - if (!x && !y) { + if (!x && !y && "clientX" in event) { x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; } if (!parent) { + var node = MENU.CurrentNode() || event.target; + if ((event.type === "keydown" || (!x && !y)) && node) { + var offsetX = window.pageXOffset || document.documentElement.scrollLeft; + var offsetY = window.pageYOffset || document.documentElement.scrollTop; + var rect = node.getBoundingClientRect(); + x = (rect.right + rect.left) / 2 + offsetX; + y = (rect.bottom + rect.top) / 2 + offsetY; + } if (x + menu.offsetWidth > document.body.offsetWidth - this.margin) {x = document.body.offsetWidth - menu.offsetWidth - this.margin} if (MENU.isMobile) {x = Math.max(5,x-Math.floor(menu.offsetWidth/2)); y -= 20} @@ -214,8 +337,11 @@ x += parent.offsetLeft; y += parent.offsetTop; parent = parent.parentNode; } - if (x + menu.offsetWidth > document.body.offsetWidth - this.margin && !MENU.isMobile) - {side = "right"; x = Math.max(this.margin,x - mw - menu.offsetWidth + 6)} + if (!MENU.isMobile) { + if ((MENU.isRTL && x - mw - menu.offsetWidth > this.margin) || + (!MENU.isRTL && x + menu.offsetWidth > document.body.offsetWidth - this.margin)) + {side = "right"; x = Math.max(this.margin,x - mw - menu.offsetWidth + 6)} + } if (!isPC) { // in case these ever get implemented menu.style["borderRadiusTop"+side] = 0; // Opera 10.5 @@ -224,10 +350,19 @@ menu.style["KhtmlBorderRadiusTop"+side] = 0; // Konqueror } } - + menu.style.left = x+"px"; menu.style.top = y+"px"; - if (document.selection && document.selection.empty) {document.selection.empty()} + + // Focusing while keeping the scroll position. + var oldX = window.pageXOffset || document.documentElement.scrollLeft; + var oldY = window.pageYOffset || document.documentElement.scrollTop; + MENU.Focus(menu); + if (event.type === "keydown") { + MENU.skipMouseoverFromKey = true; + setTimeout(function() {delete MENU.skipMouseoverFromKey;}, CONFIG.delay); + } + window.scrollTo(oldX, oldY); return FALSE(event); }, @@ -245,53 +380,82 @@ delete MENU.jax.hover.nofade; HOVER.UnHover(MENU.jax); } + MENU.Unfocus(menu); + if (event.type === "mousedown") MENU.CurrentNode().blur(); return FALSE(event); }, /* - * Find a named item in a menu (or submenu). - * A list of names means descend into submenus. + * Find an item in a menu (or submenu) by name (Find) or ID (FindID). + * A list of names or IDs means descend into submenus. */ - Find: function (name) { - var names = [].slice.call(arguments,1); + Find: function (name) {return this.FindN(1,name,[].slice.call(arguments,1))}, + FindId: function (name) {return this.FindN(0,name,[].slice.call(arguments,1))}, + FindN: function (n,name,names) { for (var i = 0, m = this.items.length; i < m; i++) { - if (this.items[i].name === name) { + if (this.items[i].name[n] === name) { if (names.length) { - if (!this.items[i].menu) {return null} - return this.items[i].menu.Find.apply(this.items[i].menu,names); + if (!this.items[i].submenu) {return null} + return this.items[i].submenu.FindN(n,names[0],names.slice(1)); } return this.items[i]; } } return null; }, - + /* * Find the index of a menu item (so we can insert before or after it) */ - IndexOf: function (name) { + IndexOf: function (name) {return this.IndexOfN(1,name)}, + IndexOfId: function (name) {return this.IndexOfN(0,name)}, + IndexOfN: function (n,name) { for (var i = 0, m = this.items.length; i < m; i++) - {if (this.items[i].name === name) {return i}} + {if (this.items[i].name[n] === name) {return i}} return null; + }, + + Right: function(event, menu) { + MENU.Right(event, menu); + }, + Left: function(event, menu) { + MENU.Left(event, menu); + }, + Up: function(event, menu) { + var node = menu.lastChild; + node.menuItem.Activate(event, node); + }, + Down: function(event, menu) { + var node = menu.firstChild; + node.menuItem.Activate(event, node); + }, + Space: function(event, menu) { + this.Remove(event, menu); } - },{ - + config: CONFIG, - div: null, // the DOM elements for the menu and submenus - - Close: function (event) - {return MENU.Event(event,this.menu||this.parentNode,(this.menu?"Touchend":"Remove"))}, Remove: function (event) {return MENU.Event(event,this,"Remove")}, Mouseover: function (event) {return MENU.Event(event,this,"Mouseover")}, Mouseout: function (event) {return MENU.Event(event,this,"Mouseout")}, Mousedown: function (event) {return MENU.Event(event,this,"Mousedown")}, Mouseup: function (event) {return MENU.Event(event,this,"Mouseup")}, + Keydown: function (event) {return MENU.Event(event,this,"Keydown")}, + /* + * Events for mobile devices. + */ Touchstart: function (event) {return MENU.Event(event,this,"Touchstart")}, Touchend: function (event) {return MENU.Event(event,this,"Touchend")}, + Close: function (event) { + return MENU.Event(event,this.menu||this.parentNode,(this.menu?"Touchend":"Remove")); + }, Event: function (event,menu,type,force) { if (MENU.skipMouseover && type === "Mouseover" && !force) {return FALSE(event)} + if (MENU.skipMouseoverFromKey && type === "Mouseover") { + delete MENU.skipMouseoverFromKey; + return FALSE(event); + } if (MENU.skipUp) { if (type.match(/Mouseup|Touchend/)) {delete MENU.skipUp; return FALSE(event)} if (type === "Touchstart" || @@ -302,7 +466,6 @@ if (item && item[type]) {return item[type](event,menu)} return null; }, - /* * Style for the background DIV */ @@ -312,15 +475,16 @@ }, Background: function (menu) { - var div = HTML.addElement(document.body,"div",{style:this.BGSTYLE, id:"MathJax_MenuFrame"}, + var div = HTML.addElement(document.body,"div", + {style:this.BGSTYLE, id:"MathJax_MenuFrame"}, [["div",{style: this.BGSTYLE, menuItem: menu, onmousedown: this.Remove}]]); var bg = div.firstChild; - if (menu.msieBackgroundBug) { + if (MENU.msieBackgroundBug) { // MSIE doesn't allow transparent background to be hit boxes, so // fake it using opacity with solid background color bg.style.backgroundColor = "white"; bg.style.filter = "alpha(opacity=0)"; } - if (menu.msieFixedPositionBug) { + if (MENU.msieFixedPositionBug) { // MSIE can't do fixed position, so use a full-sized background // and an onresize handler to update it (stupid, but necessary) div.width = div.height = 0; this.Resize(); @@ -341,64 +505,164 @@ bg.style.height = document.body.scrollHeight + "px"; } }, - + + /*************************************************************/ + /* + * Keyboard navigation of menu. + */ + posted: false, // Is a menu open? + active: null, // The focused in HTML node in the menu. + + GetNode: function(jax) { + var node = document.getElementById(jax.inputID + "-Frame"); + return node.isMathJax ? node : node.firstChild; + }, + CurrentNode: function() { + return MENU.GetNode(MENU.jax); + }, + AllNodes: function() { + var jaxs = MathJax.Hub.getAllJax(); + var nodes = []; + for (var i = 0, jax; jax = jaxs[i]; i++) { + nodes.push(MENU.GetNode(jax)); + } + return nodes; + }, + ActiveNode: function() { + return MENU.active; + }, + FocusNode: function(node) { + MENU.active = node; + node.focus(); + }, + // + // Focus is a global affair, since we only ever want a single focused item. + // + Focus: function(menu) { + !MENU.posted ? MENU.Activate(menu) : MENU.ActiveNode().tabIndex = -1; + menu.tabIndex = 0; + MENU.FocusNode(menu); + }, + Activate: function(event, menu) { + var jaxs = MENU.AllNodes(); + for (var j = 0, jax; jax = jaxs[j]; j++) { + jax.tabIndex = -1; + } + MENU.posted = true; + }, + Unfocus: function() { + MENU.ActiveNode().tabIndex = -1; + var jaxs = MENU.AllNodes(); + for (var j = 0, jax; jax = jaxs[j]; j++) { + jax.tabIndex = 0; + } + MENU.FocusNode(MENU.CurrentNode()); + MENU.posted = false; + }, + MoveHorizontal: function(event, menu, move) { + if (!event.shiftKey) return; + var jaxs = MENU.AllNodes(); + var len = jaxs.length; + if (len === 0) return; + var next = jaxs[MENU.Mod(move(MENU.IndexOf(jaxs, MENU.CurrentNode())), len)]; + if (next === MENU.CurrentNode()) return; + MENU.menu.Remove(event, menu); + MENU.jax = MathJax.Hub.getJaxFor(next); + MENU.FocusNode(next); + MENU.menu.Post(null); + }, + Right: function(event, menu) { + MENU.MoveHorizontal(event, menu, function(x) {return x + 1;}); + }, + Left: function(event, menu) { + MENU.MoveHorizontal(event, menu, function(x) {return x - 1;}); + }, + + //TODO: Move to utility class. + // Computes a mod n. + Mod: function(a, n) { + return ((a % n) + n) % n; + }, + IndexOf: (Array.prototype.indexOf ? + function (A, item, start) {return A.indexOf(item, start);} : + function (A, item, start) { + for (var i = (start || 0), j = A.length; i < j; i++) { + if (item === A[i]) return i; + } + return -1; + }), + saveCookie: function () {HTML.Cookie.Set("menu",this.cookie)}, - getCookie: function () {this.cookie = HTML.Cookie.Get("menu")}, - - // - // Preload images so they show up with the menu - // - getImages: function () { - if (MENU.isMobile) {var close = new Image(); close.src = CONFIG.closeImg} - } + getCookie: function () {this.cookie = HTML.Cookie.Get("menu")} }); + MathJax.Menu.NAV = NAV; + /*************************************************************/ /* - * The menu item root subclass + * Abstract class of menu items. */ - var ITEM = MENU.ITEM = MathJax.Object.Subclass({ - name: "", // the menu item's label + var ITEM = MENU.ITEM = NAV.Subclass({ + + name: "", // The menu item's label as [id,label] pair. + node: null, // The HTML node of the item. + menu: null, // The parent menu containing that item. HTML node. + + Attributes: function(def) { + return HUB.Insert( + {onmouseup: MENU.Mouseup, + ondragstart: FALSE, onselectstart: FALSE, onselectend: FALSE, + ontouchstart: MENU.Touchstart, ontouchend: MENU.Touchend, + className: "MathJax_MenuItem", role: this.role, + menuItem: this}, + def); + }, Create: function (menu) { if (!this.hidden) { - var def = { - onmouseover: MENU.Mouseover, onmouseout: MENU.Mouseout, - onmouseup: MENU.Mouseup, onmousedown: MENU.Mousedown, - ondragstart: FALSE, onselectstart: FALSE, onselectend: FALSE, - ontouchstart: MENU.Touchstart, ontouchend: MENU.Touchend, - className: "MathJax_MenuItem", menuItem: this - }; - if (this.disabled) {def.className += " MathJax_MenuDisabled"} - HTML.addElement(menu,"div",def,this.Label(def,menu)); + var def = this.Attributes(); + var label = this.Label(def,menu); + HTML.addElement(menu, "div", def, label); + } + }, + Name: function () {return _(this.name[0],this.name[1])}, + + Mouseover: function (event,menu) { + if (menu.parentNode === MENU.ActiveNode().parentNode) { + this.Deactivate(MENU.ActiveNode()); + } + this.Activate(event, menu); + }, + Mouseout: function (event,menu) { + this.Deactivate(menu); + }, + Mouseup: function (event,menu) {return this.Remove(event,menu)}, + + + DeactivateSubmenus: function(menu) { + var menus = document.getElementById("MathJax_MenuFrame").childNodes, + items = ITEM.GetMenuNode(menu).childNodes; + for (var i = 0, m = items.length; i < m; i++) { + var item = items[i].menuItem; + // Deactivates submenu items. + if (item && item.submenu && item.submenu.posted && + item !== menu.menuItem) { + item.Deactivate(items[i]); + } + } + this.RemoveSubmenus(menu, menus); + }, + RemoveSubmenus: function(menu, menus) { + menus = menus || document.getElementById("MathJax_MenuFrame").childNodes; + var m = menus.length-1; + while (m >= 0 && ITEM.GetMenuNode(menu).menuItem !== menus[m].menuItem) { + menus[m].menuItem.posted = false; + menus[m].parentNode.removeChild(menus[m]); + m--; } }, - Mouseover: function (event,menu) { - if (!this.disabled) {this.Activate(menu)} - if (!this.menu || !this.menu.posted) { - var menus = document.getElementById("MathJax_MenuFrame").childNodes, - items = menu.parentNode.childNodes; - for (var i = 0, m = items.length; i < m; i++) { - var item = items[i].menuItem; - if (item && item.menu && item.menu.posted) {item.Deactivate(items[i])} - } - m = menus.length-1; - while (m >= 0 && menu.parentNode.menuItem !== menus[m].menuItem) { - menus[m].menuItem.posted = false; - menus[m].parentNode.removeChild(menus[m]); - m--; - } - if (this.Timer && !MENU.isMobile) {this.Timer(event,menu)} - } - }, - Mouseout: function (event,menu) { - if (!this.menu || !this.menu.posted) {this.Deactivate(menu)} - if (this.timer) {clearTimeout(this.timer); delete this.timer} - }, - Mouseup: function (event,menu) {return this.Remove(event,menu)}, - Touchstart: function (event,menu) {return this.TouchEvent(event,menu,"Mousedown")}, Touchend: function (event,menu) {return this.TouchEvent(event,menu,"Mouseup")}, TouchEvent: function (event,menu,type) { @@ -411,31 +675,126 @@ MENU.Event(event,menu,type); return false; }, - + Remove: function (event,menu) { menu = menu.parentNode.menuItem; return menu.Remove(event,menu); }, - Activate: function (menu) {this.Deactivate(menu); menu.className += " MathJax_MenuActive"}, - Deactivate: function (menu) {menu.className = menu.className.replace(/ MathJax_MenuActive/,"")}, + With: function (def) {if (def) {HUB.Insert(this,def)}; return this}, + + isRTL: function () {return MENU.isRTL}, + rtlClass: function () {return (this.isRTL() ? " RTL" : "")} + }, { + GetMenuNode: function(item) { + return item.parentNode; + } + }); + + /*************************************************************/ + /* + * Abstract class of menu items that are focusable and perform some action + */ + MENU.ENTRY = MENU.ITEM.Subclass({ + role: "menuitem", // Aria role. + + Attributes: function(def) { + def = HUB.Insert( + {onmouseover: MENU.Mouseover, onmouseout: MENU.Mouseout, + onmousedown: MENU.Mousedown, onkeydown: MENU.Keydown, + "aria-disabled": !!this.disabled}, + def); + def = this.SUPER(arguments).Attributes.call(this, def); + if (this.disabled) { + def.className += " MathJax_MenuDisabled"; + } + return def; + }, + MoveVertical: function(event, item, move) { + var menuNode = ITEM.GetMenuNode(item); + var items = []; + for (var i = 0, allItems = menuNode.menuItem.items, it; + it = allItems[i]; i++) { + if (!it.hidden) { + items.push(it); + } + } + var index = MENU.IndexOf(items, this); + if (index === -1) return; + var len = items.length; + var children = menuNode.childNodes; + do { + index = MENU.Mod(move(index), len); + } while (items[index].hidden || !children[index].role || + children[index].role === "separator"); + this.Deactivate(item); + items[index].Activate(event, children[index]); + }, + Up: function(event, item) { + this.MoveVertical(event, item, function(x) { return x - 1; }); + }, + Down: function(event, item) { + this.MoveVertical(event, item, function(x) { return x + 1; }); + }, + Right: function(event, item) { + this.MoveHorizontal(event, item, MENU.Right, !this.isRTL()); + }, + Left: function(event, item) { + this.MoveHorizontal(event, item, MENU.Left, this.isRTL()); + }, + MoveHorizontal: function(event, item, move, rtl) { + var menuNode = ITEM.GetMenuNode(item); + if (menuNode.menuItem === MENU.menu && event.shiftKey) { + move(event, item); + } + if (rtl) return; + if (menuNode.menuItem !== MENU.menu) { + this.Deactivate(item); + } + var parentNodes = menuNode.previousSibling.childNodes; + var length = parentNodes.length; + while (length--) { + var parent = parentNodes[length]; + if (parent.menuItem.submenu && + parent.menuItem.submenu === menuNode.menuItem) { + MENU.Focus(parent); + break; + } + } + this.RemoveSubmenus(item); + }, + Space: function (event, menu) { + this.Mouseup(event, menu); + }, + + Activate: function (event, menu) { + this.Deactivate(menu); + if (!this.disabled) { + menu.className += " MathJax_MenuActive"; + } + this.DeactivateSubmenus(menu); + MENU.Focus(menu); + }, + Deactivate: function (menu) { + menu.className = menu.className.replace(/ MathJax_MenuActive/,""); + } - With: function (def) {if (def) {HUB.Insert(this,def)}; return this} }); /*************************************************************/ /* * A menu item that performs a command when selected */ - MENU.ITEM.COMMAND = MENU.ITEM.Subclass({ + MENU.ITEM.COMMAND = MENU.ENTRY.Subclass({ action: function () {}, Init: function (name,action,def) { + if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair this.name = name; this.action = action; this.With(def); }, - - Label: function (def,menu) {return [this.name]}, + + Label: function (def,menu) {return [this.Name()]}, Mouseup: function (event,menu) { if (!this.disabled) { this.Remove(event,menu); @@ -450,48 +809,97 @@ /* * A menu item that posts a submenu */ - MENU.ITEM.SUBMENU = MENU.ITEM.Subclass({ - menu: null, // the submenu - marker: (isPC && !HUB.Browser.isSafari ? "\u25B6" : "\u25B8"), // the menu arrow + MENU.ITEM.SUBMENU = MENU.ENTRY.Subclass({ + submenu: null, // the submenu + marker: "\u25BA", // the submenu arrow + markerRTL: "\u25C4", // the submenu arrow for RTL + Attributes: function(def) { + def = HUB.Insert({"aria-haspopup": "true"}, def); + def = this.SUPER(arguments).Attributes.call(this, def); + return def; + }, Init: function (name,def) { + if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair this.name = name; var i = 1; if (!(def instanceof MENU.ITEM)) {this.With(def), i++} - this.menu = MENU.apply(MENU,[].slice.call(arguments,i)); + this.submenu = MENU.apply(MENU,[].slice.call(arguments,i)); }, Label: function (def,menu) { - this.menu.posted = false; - return [this.name+" ",["span",{className:"MathJax_MenuArrow"},[this.marker]]]; + this.submenu.posted = false; + return [this.Name()+" ",["span",{ + className:"MathJax_MenuArrow" + this.rtlClass() + },[this.isRTL() ? this.markerRTL : this.marker]]]; }, Timer: function (event,menu) { - if (this.timer) {clearTimeout(this.timer)} - event = {clientX: event.clientX, clientY: event.clientY}; // MSIE can't pass the event below + this.ClearTimer(); + event = {type: event.type, + clientX: event.clientX, clientY: event.clientY}; // MSIE can't pass the event below this.timer = setTimeout(CALLBACK(["Mouseup",this,event,menu]),CONFIG.delay); }, + ClearTimer: function() { + if (this.timer) { + clearTimeout(this.timer); + } + }, Touchend: function (event,menu) { - var forceout = this.menu.posted; + var forceout = this.submenu.posted; var result = this.SUPER(arguments).Touchend.apply(this,arguments); if (forceout) {this.Deactivate(menu); delete ITEM.lastItem; delete ITEM.lastMenu} return result; }, + Mouseout: function(event, menu) { + if (!this.submenu.posted) { + this.Deactivate(menu); + } + this.ClearTimer(); + }, + Mouseover: function(event, menu) { + this.Activate(event, menu); + }, Mouseup: function (event,menu) { if (!this.disabled) { - if (!this.menu.posted) { - if (this.timer) {clearTimeout(this.timer); delete this.timer} - this.menu.Post(event,menu); + if (!this.submenu.posted) { + this.ClearTimer(); + this.submenu.Post(event, menu, this.ltr); + MENU.Focus(menu); } else { - var menus = document.getElementById("MathJax_MenuFrame").childNodes, - m = menus.length-1; - while (m >= 0) { - var child = menus[m]; - child.menuItem.posted = false; - child.parentNode.removeChild(child); - if (child.menuItem === this.menu) {break}; - m--; - } + this.DeactivateSubmenus(menu); } } return FALSE(event); + }, + Activate: function (event, menu) { + if (!this.disabled) { + this.Deactivate(menu); + menu.className += " MathJax_MenuActive"; + } + if (!this.submenu.posted) { + this.DeactivateSubmenus(menu); + if (!MENU.isMobile) { + this.Timer(event,menu); + } + } + MENU.Focus(menu); + }, + MoveVertical: function(event, item, move) { + this.ClearTimer(); + this.SUPER(arguments).MoveVertical.apply(this, arguments); + }, + MoveHorizontal: function(event, menu, move, rtl) { + if (!rtl) { + this.SUPER(arguments).MoveHorizontal.apply(this, arguments); + return; + } + if (this.disabled) return; + if (!this.submenu.posted) { + this.Activate(event, menu); + return; + } + var submenuNodes = ITEM.GetMenuNode(menu).nextSibling.childNodes; + if (submenuNodes.length > 0) { + this.submenu.items[0].Activate(event, submenuNodes[0]); + } } }); @@ -499,28 +907,39 @@ /* * A menu item that is one of several radio buttons */ - MENU.ITEM.RADIO = MENU.ITEM.Subclass({ + MENU.ITEM.RADIO = MENU.ENTRY.Subclass({ variable: null, // the variable name marker: (isPC ? "\u25CF" : "\u2713"), // the checkmark + role: "menuitemradio", + Attributes: function(def) { + var checked = CONFIG.settings[this.variable] === this.value ? "true" : "false"; + def = HUB.Insert({"aria-checked": checked}, def); + def = this.SUPER(arguments).Attributes.call(this, def); + return def; + }, Init: function (name,variable,def) { + if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair this.name = name; this.variable = variable; this.With(def); - if (this.value == null) {this.value = this.name} + if (this.value == null) {this.value = this.name[0]} }, Label: function (def,menu) { - var span = {className:"MathJax_MenuRadioCheck"}; - if (CONFIG.settings[this.variable] !== this.value) {span = {style:{display:"none"}}} - return [["span",span,[this.marker]]," "+this.name]; + var span = {className:"MathJax_MenuRadioCheck" + this.rtlClass()}; + if (CONFIG.settings[this.variable] !== this.value) { + span = {style:{display:"none"}}; + } + return [["span",span,[this.marker]]," "+this.Name()]; }, Mouseup: function (event,menu) { if (!this.disabled) { var child = menu.parentNode.childNodes; for (var i = 0, m = child.length; i < m; i++) { var item = child[i].menuItem; - if (item && item.variable === this.variable) - {child[i].firstChild.style.display = "none"} + if (item && item.variable === this.variable) { + child[i].firstChild.style.display = "none"; + } } - menu.firstChild.display = ""; + menu.firstChild.display = ""; CONFIG.settings[this.variable] = this.value; MENU.cookie[this.variable] = CONFIG.settings[this.variable]; MENU.saveCookie(); SIGNAL.Post(["radio button",this]); @@ -535,17 +954,25 @@ /* * A menu item that is checkable */ - MENU.ITEM.CHECKBOX = MENU.ITEM.Subclass({ + MENU.ITEM.CHECKBOX = MENU.ENTRY.Subclass({ variable: null, // the variable name marker: "\u2713", // the checkmark + role: "menuitemcheckbox", + Attributes: function(def) { + var checked = CONFIG.settings[this.variable] ? "true" : "false"; + def = HUB.Insert({"aria-checked": checked}, def); + def = this.SUPER(arguments).Attributes.call(this, def); + return def; + }, Init: function (name,variable,def) { + if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair this.name = name; this.variable = variable; this.With(def); }, Label: function (def,menu) { - var span = {className:"MathJax_MenuCheck"}; + var span = {className:"MathJax_MenuCheck" + this.rtlClass()}; if (!CONFIG.settings[this.variable]) {span = {style:{display:"none"}}} - return [["span",span,[this.marker]]," "+this.name]; + return [["span",span,[this.marker]]," "+this.Name()]; }, Mouseup: function (event,menu) { if (!this.disabled) { @@ -564,13 +991,22 @@ /* * A menu item that is a label */ - MENU.ITEM.LABEL = MENU.ITEM.Subclass({ - Init: function (name,def) {this.name = name; this.With(def)}, + MENU.ITEM.LABEL = MENU.ENTRY.Subclass({ + role: "menuitem", // Aria role. + + Init: function (name,def) { + if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair + this.name = name; this.With(def); + }, Label: function (def,menu) { - delete def.onmouseover, delete def.onmouseout; delete def.onmousedown; def.className += " MathJax_MenuLabel"; - return [this.name]; - } + return [this.Name()]; + }, + Activate: function(event, menu) { + this.Deactivate(menu); + MENU.Focus(menu); + }, + Mouseup: function (event,menu) { } }); /*************************************************************/ @@ -578,48 +1014,60 @@ * A rule in a menu */ MENU.ITEM.RULE = MENU.ITEM.Subclass({ + role: "separator", + + Attributes: function(def) { + def = HUB.Insert({"aria-orientation": "vertical"}, def); + def = this.SUPER(arguments).Attributes.call(this, def); + return def; + }, Label: function (def,menu) { - delete def.onmouseover, delete def.onmouseout; delete def.onmousedown; def.className += " MathJax_MenuRule"; return null; } }); - + /*************************************************************/ /*************************************************************/ /* * Handle the ABOUT box */ - MENU.About = function () { - var HTMLCSS = OUTPUT["HTML-CSS"] || {fontInUse: ""}; - var local = (HTMLCSS.webFonts ? "" : "local "), web = (HTMLCSS.webFonts ? " web" : ""); - var font = (HTMLCSS.imgFonts ? "Image" : local+HTMLCSS.fontInUse+web) + " fonts"; - if (font === "local fonts" && OUTPUT.SVG) {font = "web SVG fonts"} + MENU.About = function (event) { + var font = MENU.About.GetFont(); + var format = MENU.About.GetFormat(); var jax = ["MathJax.js v"+MathJax.fileversion,["br"]]; jax.push(["div",{style:{"border-top":"groove 2px",margin:".25em 0"}}]); - MENU.About.GetJax(jax,MathJax.InputJax,"Input Jax"); - MENU.About.GetJax(jax,MathJax.OutputJax,"Output Jax"); - MENU.About.GetJax(jax,MathJax.ElementJax,"Element Jax"); + MENU.About.GetJax(jax,MathJax.InputJax,["InputJax","%1 Input Jax v%2"]); + MENU.About.GetJax(jax,MathJax.OutputJax,["OutputJax","%1 Output Jax v%2"]); + MENU.About.GetJax(jax,MathJax.ElementJax,["ElementJax","%1 Element Jax v%2"]); jax.push(["div",{style:{"border-top":"groove 2px",margin:".25em 0"}}]); - MENU.About.GetJax(jax,MathJax.Extension,"Extension",true); + MENU.About.GetJax(jax,MathJax.Extension,["Extension","%1 Extension v%2"],true); jax.push(["div",{style:{"border-top":"groove 2px",margin:".25em 0"}}],["center",{},[ - HUB.Browser + " v"+HUB.Browser.version + - (HTMLCSS.webFonts && !HTMLCSS.imgFonts ? " \u2014 "+HTMLCSS.allowWebFonts+" fonts" : "") + HUB.Browser + " v"+HUB.Browser.version + (format ? + " \u2014 " + _(format.replace(/ /g,""),format) : "") ]]); MENU.About.div = MENU.Background(MENU.About); var about = HTML.addElement(MENU.About.div,"div",{ - id: "MathJax_About", onclick: MENU.About.Remove + id: "MathJax_About", tabIndex: 0, onkeydown: MENU.About.Keydown },[ ["b",{style:{fontSize:"120%"}},["MathJax"]]," v"+MathJax.version,["br"], - "using "+font,["br"],["br"], + _(font.replace(/ /g,""),"using "+font),["br"],["br"], ["span",{style:{ display:"inline-block", "text-align":"left", "font-size":"80%", - "max-height":"20em", overflow:"auto", + "max-height":"20em", overflow:"auto", "background-color":"#E4E4E4", padding:".4em .6em", border:"1px inset" - }},jax],["br"],["br"], - ["a",{href:"http://www.mathjax.org/"},["www.mathjax.org"]] + }, tabIndex: 0},jax],["br"],["br"], + ["a",{href:"http://www.mathjax.org/"},["www.mathjax.org"]], + ["span",{className:"MathJax_MenuClose",id:"MathJax_AboutClose", + onclick:MENU.About.Remove, + onkeydown: MENU.About.Keydown, tabIndex: 0, role: "button", + "aria-label": _("CloseAboutDialog","Close about MathJax dialog")}, + [["span",{},"\u00D7"]]] ]); + if (event.type === "mouseup") about.className += " MathJax_MousePost"; + about.focus(); + MathJax.Localization.setCSS(about); var doc = (document.documentElement||{}); var H = window.innerHeight || doc.clientHeight || doc.scrollHeight || 0; if (MENU.prototype.msieAboutBug) { @@ -634,25 +1082,49 @@ MENU.About.Remove = function (event) { if (MENU.About.div) {document.body.removeChild(MENU.About.div); delete MENU.About.div} }; + MENU.About.Keydown = function(event) { + if (event.keyCode === KEY.ESCAPE || + (this.id === "MathJax_AboutClose" && + (event.keyCode === KEY.SPACE || event.keyCode === KEY.RETURN))) { + MENU.About.Remove(event); + MENU.CurrentNode().focus(); + FALSE(event); + } + }, MENU.About.GetJax = function (jax,JAX,type,noTypeCheck) { var info = []; for (var id in JAX) {if (JAX.hasOwnProperty(id) && JAX[id]) { if ((noTypeCheck && JAX[id].version) || (JAX[id].isa && JAX[id].isa(JAX))) - {info.push((JAX[id].id||id)+" "+type+" v"+JAX[id].version)} + {info.push(_(type[0],type[1],(JAX[id].id||id),JAX[id].version))} }} info.sort(); for (var i = 0, m = info.length; i < m; i++) {jax.push(info[i],["br"])} return jax; }; + MENU.About.GetFont = function () { + var jax = MathJax.Hub.outputJax["jax/mml"][0] || {}; + var font = { + SVG: "web SVG", + CommonHTML: "web TeX", + "HTML-CSS": (jax.imgFonts ? "image" : (jax.webFonts ? "web" : "local")+" "+jax.fontInUse) + }[jax.id] || "generic"; + return font + " fonts"; + }; + MENU.About.GetFormat = function () { + var jax = MathJax.Hub.outputJax["jax/mml"][0] || {}; + if (jax.id !== "HTML-CSS"|| !jax.webFonts || jax.imgFonts) return; + return jax.allowWebFonts.replace(/otf/,"woff or otf") + " fonts"; + }; + - /* * Handle the MathJax HELP menu */ - MENU.Help = function () { - window.open(CONFIG.helpURL,"MathJaxHelp"); + MENU.Help = function (event) { + AJAX.Require("[MathJax]/extensions/HelpDialog.js", + function () {MathJax.Extension.Help.Dialog({type:event.type})}); }; - + /* * Handle showing of element's source */ @@ -664,9 +1136,9 @@ var MML = MathJax.ElementJax.mml; if (MML && typeof(MML.mbase.prototype.toMathML) !== "undefined") { // toMathML() can call MathJax.Hub.RestartAfter, so trap errors and check - try {MENU.ShowSource.Text(MENU.jax.root.toMathML(),event)} catch (err) { + try {MENU.ShowSource.Text(MENU.jax.root.toMathML("",MENU.jax),event)} catch (err) { if (!err.restart) {throw err} - CALLBACK.After([this,MENU.ShowSource,EVENT]); + CALLBACK.After([this,MENU.ShowSource,EVENT],err.restart); } } else if (!AJAX.loadingToMathML) { AJAX.loadingToMathML = true; @@ -681,8 +1153,16 @@ ); return; } + } else if (this.format === "Error") { + MENU.ShowSource.Text(MENU.jax.errorText,event); + } else if (CONFIG.semanticsAnnotations[this.format]) { + var annotation = MENU.jax.root.getAnnotation(this.format); + if (annotation.data[0]) MENU.ShowSource.Text(annotation.data[0].toString()); } else { - if (MENU.jax.originalText == null) {alert("No original form available"); return} + if (MENU.jax.originalText == null) { + alert(_("NoOriginalForm","No original form available")); + return; + } MENU.ShowSource.Text(MENU.jax.originalText,event); } }; @@ -695,65 +1175,77 @@ return MENU.ShowSource.w; }; MENU.ShowSource.Text = function (text,event) { - var w = MENU.ShowSource.Window(event); + var w = MENU.ShowSource.Window(event); delete MENU.ShowSource.w; text = text.replace(/^\s*/,"").replace(/\s*$/,""); text = text.replace(/&/g,"&").replace(//g,">"); + var title = _("EqSource","MathJax Equation Source"); if (MENU.isMobile) { w.document.open(); - w.document.write("MathJax Equation Source"); + w.document.write(""+title+""); w.document.write("
"+text+"
"); - w.document.write("
"); + w.document.write("
"); w.document.write(""); w.document.close(); } else { w.document.open(); - w.document.write("MathJax Equation Source"); + w.document.write(""+title+""); w.document.write("
"+text+"
"); w.document.write(""); w.document.close(); var table = w.document.body.firstChild; - var H = (w.outerHeight-w.innerHeight)||30, W = (w.outerWidth-w.innerWidth)||30; - W = Math.min(Math.floor(.5*screen.width),table.offsetWidth+W+25); - H = Math.min(Math.floor(.5*screen.height),table.offsetHeight+H+25); - w.resizeTo(W,H); - if (event && event.screenX != null) { - var x = Math.max(0,Math.min(event.screenX-Math.floor(W/2), screen.width-W-20)), - y = Math.max(0,Math.min(event.screenY-Math.floor(H/2), screen.height-H-20)); - w.moveTo(x,y); - } + setTimeout(function () { + var H = (w.outerHeight-w.innerHeight)||30, W = (w.outerWidth-w.innerWidth)||30, x, y; + W = Math.max(140,Math.min(Math.floor(.5*screen.width),table.offsetWidth+W+25)); + H = Math.max(40,Math.min(Math.floor(.5*screen.height),table.offsetHeight+H+25)); + if (MENU.prototype.msieHeightBug) {H += 35}; // for title bar in XP + w.resizeTo(W,H); + var X; try {X = event.screenX} catch (e) {}; // IE8 throws an error accessing screenX + if (event && X != null) { + x = Math.max(0,Math.min(event.screenX-Math.floor(W/2), screen.width-W-20)); + y = Math.max(0,Math.min(event.screenY-Math.floor(H/2), screen.height-H-20)); + w.moveTo(x,y); + } + },50); } - delete MENU.ShowSource.w; }; - + /* * Handle rescaling all the math */ MENU.Scale = function () { - var HTMLCSS = OUTPUT["HTML-CSS"], nMML = OUTPUT.NativeMML; - var SCALE = (HTMLCSS ? HTMLCSS.config.scale : nMML.config.scale); - var scale = prompt("Scale all mathematics (compared to surrounding text) by",SCALE+"%"); + var JAX = ["CommonHTML","HTML-CSS","SVG","NativeMML","PreviewHTML"], m = JAX.length, + SCALE = 100, i, jax; + for (i = 0; i < m; i++) { + jax = OUTPUT[JAX[i]]; + if (jax) {SCALE = jax.config.scale; break} + } + var scale = prompt(_("ScaleMath","Scale all mathematics (compared to surrounding text) by"),SCALE+"%"); if (scale) { - if (scale.match(/^\s*\d+\s*%?\s*$/)) { - scale = parseInt(scale); + if (scale.match(/^\s*\d+(\.\d*)?\s*%?\s*$/)) { + scale = parseFloat(scale); if (scale) { if (scale !== SCALE) { - if (HTMLCSS) {HTMLCSS.config.scale = scale} - if (nMML) {nMML.config.scale = scale} - MENU.cookie.scale = scale; - MENU.saveCookie(); HUB.Reprocess(); + for (i = 0; i < m; i++) { + jax = OUTPUT[JAX[i]]; + if (jax) jax.config.scale = scale; + } + MENU.cookie.scale = HUB.config.scale = scale; + MENU.saveCookie(); + HUB.Queue(["Rerender",HUB]); } - } else {alert("The scale should not be zero")} - } else {alert("The scale should be a perentage (e.g., 120%)")} + } else {alert(_("NonZeroScale","The scale should not be zero"))} + } else {alert(_("PercentScale", + "The scale should be a percentage (e.g., 120%%)"))} } }; - + /* * Handle loading the zoom code */ MENU.Zoom = function () { if (!MathJax.Extension.MathZoom) {AJAX.Require("[MathJax]/extensions/MathZoom.js")} }; - + /* * Handle changing the renderer */ @@ -767,8 +1259,10 @@ switch (CONFIG.settings.renderer) { case "NativeMML": if (!CONFIG.settings.warnedMML) { - if (BROWSER.isChrome || (BROWSER.isSafari && !BROWSER.versionAtLeast("5.0"))) {message = MESSAGE.MML.WebKit} + if (BROWSER.isChrome && BROWSER.version.substr(0,3) !== "24.") {message = MESSAGE.MML.WebKit} + else if (BROWSER.isSafari && !BROWSER.versionAtLeast("5.0")) {message = MESSAGE.MML.WebKit} else if (BROWSER.isMSIE) {if (!BROWSER.hasMathPlayer) {message = MESSAGE.MML.MSIE}} + else if (BROWSER.isEdge) {message = MESSAGE.MML.WebKit} else {message = MESSAGE.MML[BROWSER]} warned = "warnedMML"; } @@ -778,13 +1272,21 @@ if (!CONFIG.settings.warnedSVG) { if (BROWSER.isMSIE && !isIE9) {message = MESSAGE.SVG.MSIE} } - break; + break; } if (message) { - message += "\n\nSwitch the renderer anyway?\n\n" + - "(Press OK to switch, CANCEL to continue with the current renderer)"; - MENU.cookie.renderer = jax[0].id; MENU.saveCookie(); if (!confirm(message)) {return} - if (warned) {MENU.cookie[warned] = CONFIG.settings[warned] = true} + message = _(message[0],message[1]); + message += "\n\n"; + message += _("SwitchAnyway", + "Switch the renderer anyway?\n\n" + + "(Press OK to switch, CANCEL to continue with the current renderer)"); + MENU.cookie.renderer = jax[0].id; MENU.saveCookie(); + if (!confirm(message)) { + MENU.cookie.renderer = CONFIG.settings.renderer = HTML.Cookie.Get("menu").renderer; + MENU.saveCookie(); + return; + } + if (warned) {MENU.cookie.warned = CONFIG.settings.warned = true} MENU.cookie.renderer = CONFIG.settings.renderer; MENU.saveCookie(); } HUB.Queue( @@ -795,28 +1297,48 @@ }; MENU.Renderer.Messages = { MML: { - WebKit: "Your browser doesn't seem to support MathML natively, " + - "so switching to MathML output may cause the mathematics " + - "on the page to become unreadable.", + WebKit: ["WebkitNativeMMLWarning", + "Your browser doesn't seem to support MathML natively, " + + "so switching to MathML output may cause the mathematics " + + "on the page to become unreadable."], - MSIE: "Internet Explorer requires the MathPlayer plugin " + - "in order to process MathML output.", - - Opera: "Opera's support for MathML is limited, so switching to " + - "MathML output may cause some expressions to render poorly.", + MSIE: ["MSIENativeMMLWarning", + "Internet Explorer requires the MathPlayer plugin " + + "in order to process MathML output."], - Firefox: "Your browser's native MathML does not implement all the features " + - "used by MathJax, so some expressions my render improperly." + Opera: ["OperaNativeMMLWarning", + "Opera's support for MathML is limited, so switching to " + + "MathML output may cause some expressions to render poorly."], + + Safari: ["SafariNativeMMLWarning", + "Your browser's native MathML does not implement all the features " + + "used by MathJax, so some expressions may not render properly."], + + Firefox: ["FirefoxNativeMMLWarning", + "Your browser's native MathML does not implement all the features " + + "used by MathJax, so some expressions may not render properly."] }, - + SVG: { - MSIE: "SVG is not implemented in Internet Explorer prior to " + - "IE9, or when the browser is emulating IE8 or below. " + - "Switching to SVG output will cause the mathemtics to " + - "not display properly." + MSIE: ["MSIESVGWarning", + "SVG is not implemented in Internet Explorer prior to " + + "IE9 or when it is emulating IE8 or below. " + + "Switching to SVG output will cause the mathematics to " + + "not display properly."] } }; + MENU.AssistiveMML = function (item,restart) { + var AMML = MathJax.Extension.AssistiveMML; + if (!AMML) { + // Try to load the extension, but only try once. + if (!restart) + AJAX.Require("[MathJax]/extensions/AssistiveMML.js",["AssistiveMML",MENU,item,true]); + return; + } + MathJax.Hub.Queue([(CONFIG.settings.assistiveMML ? "Add" : "Remove")+"AssistiveMathML",AMML]); + }; + /* * Handle setting the HTMLCSS fonts */ @@ -824,7 +1346,29 @@ var HTMLCSS = OUTPUT["HTML-CSS"]; if (!HTMLCSS) return; document.location.reload(); }; - + + /* + * Handle selection of locale and rerender the page + */ + MENU.Locale = function () { + MathJax.Localization.setLocale(CONFIG.settings.locale); + MathJax.Hub.Queue(["Reprocess",MathJax.Hub]); // FIXME: Just reprocess error messages? + }; + MENU.LoadLocale = function () { + var url = prompt(_("LoadURL","Load translation data from this URL:")); + if (url) { + if (!url.match(/\.js$/)) { + alert(_("BadURL", + "The URL should be for a javascript file that defines MathJax translation data. " + + "Javascript file names should end with '.js'" + )); + } + AJAX.Require(url,function (status) { + if (status != AJAX.STATUS.OK) {alert(_("BadData","Failed to load translation data from %1",url))} + }); + } + }; + /* * Handle setting MathPlayer events */ @@ -832,7 +1376,7 @@ var discoverable = CONFIG.settings.discoverable, MESSAGE = MENU.MPEvents.Messages; if (!isIE9) { - if (CONFIG.settings.mpMouse && !confirm(MESSAGE.IE8warning)) { + if (CONFIG.settings.mpMouse && !confirm(_.apply(_,MESSAGE.IE8warning))) { delete MENU.cookie.mpContext; delete CONFIG.settings.mpContext; delete MENU.cookie.mpMouse; delete CONFIG.settings.mpMouse; MENU.saveCookie(); @@ -842,19 +1386,20 @@ MENU.cookie.mpContext = MENU.cookie.mpMouse = CONFIG.settings.mpMouse; MENU.saveCookie(); MathJax.Hub.Queue(["Rerender",MathJax.Hub]) - } else if (!discoverable && item.name === "Menu Events" && CONFIG.settings.mpContext) { - alert(MESSAGE.IE9warning); + } else if (!discoverable && item.name[1] === "Menu Events" && CONFIG.settings.mpContext) { + alert(_.apply(_,MESSAGE.IE9warning)); } }; + MENU.MPEvents.Messages = { - IE8warning: + IE8warning: ["IE8warning", "This will disable the MathJax menu and zoom features, " + "but you can Alt-Click on an expression to obtain the MathJax " + - "menu instead.\n\nReally change the MathPlayer settings?", + "menu instead.\n\nReally change the MathPlayer settings?"], - IE9warning: + IE9warning: ["IE9warning", "The MathJax contextual menu will be disabled, but you can " + - "Alt-Click on an expression to obtain the MathJax menu instead." + "Alt-Click on an expression to obtain the MathJax menu instead."] }; /*************************************************************/ @@ -866,9 +1411,11 @@ var isIE8 = browser.versionAtLeast("8.0") && document.documentMode > 7; MENU.Augment({ margin: 20, - msieBackgroundBug: true, + msieBackgroundBug: ((document.documentMode||0) < 9), msieFixedPositionBug: (quirks || !isIE8), - msieAboutBug: quirks + msieAboutBug: quirks, + msieHeightBug: ((document.documentMode||0) < 9) + // height of window doesn't include title bar in XP }); if (isIE9) { delete CONFIG.styles["#MathJax_About"].filter; @@ -885,6 +1432,48 @@ /*************************************************************/ + // + // Creates the locale menu from the list of locales in MathJax.Localization.strings + // + MENU.CreateLocaleMenu = function () { + if (!MENU.menu) return; + var menu = MENU.menu.Find("Language").submenu, items = menu.items; + // + // Get the names of the languages and sort them + // + var locales = [], LOCALE = MathJax.Localization.strings; + for (var id in LOCALE) {if (LOCALE.hasOwnProperty(id)) {locales.push(id)}} + locales = locales.sort(); menu.items = []; + // + // Add a menu item for each + // + for (var i = 0, m = locales.length; i < m; i++) { + var title = LOCALE[locales[i]].menuTitle; + if (title) {title += " ("+locales[i]+")"} else {title = locales[i]} + menu.items.push(ITEM.RADIO([locales[i],title],"locale",{action:MENU.Locale})); + } + // + // Add the rule and "Load from URL" items + // + menu.items.push(items[items.length-2],items[items.length-1]); + }; + + // + // Create the annotation menu from MathJax.Hub.config.semanticsAnnotations + // + MENU.CreateAnnotationMenu = function () { + if (!MENU.menu) return; + var menu = MENU.menu.Find("Show Math As","Annotation").submenu; + var annotations = CONFIG.semanticsAnnotations; + for (var a in annotations) { + if (annotations.hasOwnProperty(a)) { + menu.items.push(ITEM.COMMAND([a,a], MENU.ShowSource, {hidden: true, nativeTouch: true, format: a})); + } + } + }; + + /*************************************************************/ + HUB.Register.StartupHook("End Config",function () { /* @@ -901,28 +1490,31 @@ /* * The main menu */ + // Localization: items used as key, should be refactored. MENU.menu = MENU( - ITEM.SUBMENU("Show Math As", - ITEM.COMMAND("MathML Code", MENU.ShowSource, {nativeTouch: true, format: "MathML"}), - ITEM.COMMAND("Original Form", MENU.ShowSource, {nativeTouch: true}), + ITEM.SUBMENU(["Show","Show Math As"], + ITEM.COMMAND(["MathMLcode","MathML Code"], MENU.ShowSource, {nativeTouch: true, format: "MathML"}), + ITEM.COMMAND(["Original","Original Form"], MENU.ShowSource, {nativeTouch: true}), + ITEM.SUBMENU(["Annotation","Annotation"], {disabled:true}), ITEM.RULE(), - ITEM.CHECKBOX("Show TeX hints in MathML", "texHints") + ITEM.CHECKBOX(["texHints","Show TeX hints in MathML"], "texHints"), + ITEM.CHECKBOX(["semantics","Add original form as annotation"], "semantics") ), ITEM.RULE(), - ITEM.SUBMENU("Math Settings", - ITEM.SUBMENU("Zoom Trigger", - ITEM.RADIO("Hover", "zoom", {action: MENU.Zoom}), - ITEM.RADIO("Click", "zoom", {action: MENU.Zoom}), - ITEM.RADIO("Double-Click", "zoom", {action: MENU.Zoom}), - ITEM.RADIO("No Zoom", "zoom", {value: "None"}), + ITEM.SUBMENU(["Settings","Math Settings"], + ITEM.SUBMENU(["ZoomTrigger","Zoom Trigger"], + ITEM.RADIO(["Hover","Hover"], "zoom", {action: MENU.Zoom}), + ITEM.RADIO(["Click","Click"], "zoom", {action: MENU.Zoom}), + ITEM.RADIO(["DoubleClick","Double-Click"], "zoom", {action: MENU.Zoom}), + ITEM.RADIO(["NoZoom","No Zoom"], "zoom", {value: "None"}), ITEM.RULE(), - ITEM.LABEL("Trigger Requires:"), - ITEM.CHECKBOX((HUB.Browser.isMac ? "Option" : "Alt"), "ALT"), - ITEM.CHECKBOX("Command", "CMD", {hidden: !HUB.Browser.isMac}), - ITEM.CHECKBOX("Control", "CTRL", {hidden: HUB.Browser.isMac}), - ITEM.CHECKBOX("Shift", "Shift") + ITEM.LABEL(["TriggerRequires","Trigger Requires:"]), + ITEM.CHECKBOX((HUB.Browser.isMac ? ["Option","Option"] : ["Alt","Alt"]), "ALT"), + ITEM.CHECKBOX(["Command","Command"], "CMD", {hidden: !HUB.Browser.isMac}), + ITEM.CHECKBOX(["Control","Control"], "CTRL", {hidden: HUB.Browser.isMac}), + ITEM.CHECKBOX(["Shift","Shift"], "Shift") ), - ITEM.SUBMENU("Zoom Factor", + ITEM.SUBMENU(["ZoomFactor","Zoom Factor"], ITEM.RADIO("125%", "zscale"), ITEM.RADIO("133%", "zscale"), ITEM.RADIO("150%", "zscale"), @@ -933,56 +1525,75 @@ ITEM.RADIO("400%", "zscale") ), ITEM.RULE(), - ITEM.SUBMENU("Math Renderer", {hidden:!CONFIG.showRenderer}, - ITEM.RADIO("HTML-CSS", "renderer", {action: MENU.Renderer}), - ITEM.RADIO("MathML", "renderer", {action: MENU.Renderer, value:"NativeMML"}), - ITEM.RADIO("SVG", "renderer", {action: MENU.Renderer}) - ), - ITEM.SUBMENU("MathPlayer", {hidden:!HUB.Browser.isMSIE || - !CONFIG.showMathPlayer, - disabled:!HUB.Browser.hasMathPlayer}, - ITEM.LABEL("Let MathPlayer Handle:"), - ITEM.CHECKBOX("Menu Events", "mpContext", {action: MENU.MPEvents, hidden:!isIE9}), - ITEM.CHECKBOX("Mouse Events", "mpMouse", {action: MENU.MPEvents, hidden:!isIE9}), - ITEM.CHECKBOX("Mouse and Menu Events", "mpMouse", {action: MENU.MPEvents, hidden:isIE9}) - ), - ITEM.SUBMENU("Font Preference", {hidden:!CONFIG.showFontMenu}, - ITEM.LABEL("For HTML-CSS:"), - ITEM.RADIO("Auto", "font", {action: MENU.Font}), + ITEM.SUBMENU(["Renderer","Math Renderer"], {hidden:!CONFIG.showRenderer}, + ITEM.RADIO("HTML-CSS", "renderer", {action: MENU.Renderer}), + ITEM.RADIO("Common HTML","renderer", {action: MENU.Renderer, value:"CommonHTML"}), + ITEM.RADIO("Fast HTML", "renderer", {action: MENU.Renderer, value:"PreviewHTML"}), + ITEM.RADIO("MathML", "renderer", {action: MENU.Renderer, value:"NativeMML"}), + ITEM.RADIO("SVG", "renderer", {action: MENU.Renderer}), + ITEM.RADIO("PlainSource","renderer", {action: MENU.Renderer, value:"PlainSource"}), ITEM.RULE(), - ITEM.RADIO("TeX (local)", "font", {action: MENU.Font}), - ITEM.RADIO("TeX (web)", "font", {action: MENU.Font}), - ITEM.RADIO("TeX (image)", "font", {action: MENU.Font}), - ITEM.RULE(), - ITEM.RADIO("STIX (local)", "font", {action: MENU.Font}) + ITEM.CHECKBOX("Fast Preview", "FastPreview"), + ITEM.CHECKBOX("Assistive MathML", "assistiveMML", {action:MENU.AssistiveMML}) ), - ITEM.SUBMENU("Contextual Menu", {hidden:!CONFIG.showContext}, + ITEM.SUBMENU("MathPlayer", {hidden:!HUB.Browser.isMSIE || !CONFIG.showMathPlayer, + disabled:!HUB.Browser.hasMathPlayer}, + ITEM.LABEL(["MPHandles","Let MathPlayer Handle:"]), + ITEM.CHECKBOX(["MenuEvents","Menu Events"], "mpContext", {action: MENU.MPEvents, hidden:!isIE9}), + ITEM.CHECKBOX(["MouseEvents","Mouse Events"], "mpMouse", {action: MENU.MPEvents, hidden:!isIE9}), + ITEM.CHECKBOX(["MenuAndMouse","Mouse and Menu Events"], "mpMouse", {action: MENU.MPEvents, hidden:isIE9}) + ), + ITEM.SUBMENU(["FontPrefs","Font Preference"], {hidden:!CONFIG.showFontMenu}, + ITEM.LABEL(["ForHTMLCSS","For HTML-CSS:"]), + ITEM.RADIO(["Auto","Auto"], "font", {action: MENU.Font}), + ITEM.RULE(), + ITEM.RADIO(["TeXLocal","TeX (local)"], "font", {action: MENU.Font}), + ITEM.RADIO(["TeXWeb","TeX (web)"], "font", {action: MENU.Font}), + ITEM.RADIO(["TeXImage","TeX (image)"], "font", {action: MENU.Font}), + ITEM.RULE(), + ITEM.RADIO(["STIXLocal","STIX (local)"], "font", {action: MENU.Font}), + ITEM.RADIO(["STIXWeb","STIX (web)"], "font", {action: MENU.Font}), + ITEM.RULE(), + ITEM.RADIO(["AsanaMathWeb","Asana Math (web)"], "font", {action: MENU.Font}), + ITEM.RADIO(["GyrePagellaWeb","Gyre Pagella (web)"], "font", {action: MENU.Font}), + ITEM.RADIO(["GyreTermesWeb","Gyre Termes (web)"], "font", {action: MENU.Font}), + ITEM.RADIO(["LatinModernWeb","Latin Modern (web)"], "font", {action: MENU.Font}), + ITEM.RADIO(["NeoEulerWeb","Neo Euler (web)"], "font", {action: MENU.Font}) + ), + ITEM.SUBMENU(["ContextMenu","Contextual Menu"], {hidden:!CONFIG.showContext}, ITEM.RADIO("MathJax", "context"), - ITEM.RADIO("Browser", "context") + ITEM.RADIO(["Browser","Browser"], "context") ), - ITEM.COMMAND("Scale All Math ...",MENU.Scale), - ITEM.RULE().With({hidden:!CONFIG.showDiscoverable, name:"discover_rule"}), - ITEM.CHECKBOX("Highlight on Hover", "discoverable", {hidden:!CONFIG.showDiscoverable}) + ITEM.COMMAND(["Scale","Scale All Math ..."],MENU.Scale), + ITEM.RULE().With({hidden:!CONFIG.showDiscoverable, name:["","discover_rule"]}), + ITEM.CHECKBOX(["Discoverable","Highlight on Hover"], "discoverable", {hidden:!CONFIG.showDiscoverable}) + ), + ITEM.SUBMENU(["Locale","Language"], {hidden:!CONFIG.showLocale, ltr:true}, + ITEM.RADIO("en", "locale", {action: MENU.Locale}), + ITEM.RULE().With({hidden:!CONFIG.showLocaleURL, name:["","localURL_rule"]}), + ITEM.COMMAND(["LoadLocale","Load from URL ..."], MENU.LoadLocale, {hidden:!CONFIG.showLocaleURL}) ), ITEM.RULE(), - ITEM.COMMAND("About MathJax",MENU.About), - ITEM.COMMAND("MathJax Help",MENU.Help) + ITEM.COMMAND(["About","About MathJax"],MENU.About), + ITEM.COMMAND(["Help","MathJax Help"],MENU.Help) ); if (MENU.isMobile) { (function () { var settings = CONFIG.settings; - var trigger = MENU.menu.Find("Math Settings","Zoom Trigger").menu; + var trigger = MENU.menu.Find("Math Settings","Zoom Trigger").submenu; trigger.items[0].disabled = trigger.items[1].disabled = true; if (settings.zoom === "Hover" || settings.zoom == "Click") {settings.zoom = "None"} trigger.items = trigger.items.slice(0,4); - + if (navigator.appVersion.match(/[ (]Android[) ]/)) { MENU.ITEM.SUBMENU.Augment({marker: "\u00BB"}); } })(); } + MENU.CreateLocaleMenu(); + MENU.CreateAnnotationMenu(); }); MENU.showRenderer = function (show) { @@ -1002,21 +1613,24 @@ MENU.menu.Find("Math Settings","Contextual Menu").hidden = !show; }; MENU.showDiscoverable = function (show) { - MENU.cookie.showContext = CONFIG.showContext = show; MENU.saveCookie(); + MENU.cookie.showDiscoverable = CONFIG.showDiscoverable = show; MENU.saveCookie(); MENU.menu.Find("Math Settings","Highlight on Hover").hidden = !show; MENU.menu.Find("Math Settings","discover_rule").hidden = !show; }; - + MENU.showLocale = function (show) { + MENU.cookie.showLocale = CONFIG.showLocale = show; MENU.saveCookie(); + MENU.menu.Find("Language").hidden = !show; + }; + MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { if (!MathJax.OutputJax["HTML-CSS"].config.imageFont) {MENU.menu.Find("Math Settings","Font Preference","TeX (image)").disabled = true} }); - + /*************************************************************/ CALLBACK.Queue( HUB.Register.StartupHook("End Config",{}), // wait until config is complete - ["getImages",MENU], ["Styles",AJAX,CONFIG.styles], ["Post",HUB.Startup.signal,"MathMenu Ready"], ["loadComplete",AJAX,"[MathJax]/extensions/MathMenu.js"] diff --git a/resources/viewer/mathjax/extensions/MathZoom.js b/resources/viewer/mathjax/extensions/MathZoom.js index 251b76c03c..6f087f8e08 100644 --- a/resources/viewer/mathjax/extensions/MathZoom.js +++ b/resources/viewer/mathjax/extensions/MathZoom.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/MathZoom.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -23,7 +26,7 @@ */ (function (HUB,HTML,AJAX,HTMLCSS,nMML) { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var CONFIG = HUB.CombineConfig("MathZoom",{ styles: { @@ -37,6 +40,9 @@ "text-align":"left", "text-indent":0, "text-transform":"none", "line-height":"normal", "letter-spacing":"normal", "word-spacing":"normal", "word-wrap":"normal", "white-space":"nowrap", "float":"none", + "-webkit-box-sizing":"content-box", // Android ≤ 2.3, iOS ≤ 4 + "-moz-box-sizing":"content-box", // Firefox ≤ 28 + "box-sizing":"content-box", // Chrome, Firefox 29+, IE 8+, Opera, Safari 5.1 "box-shadow":"5px 5px 15px #AAAAAA", // Opera 10.5 and IE9 "-webkit-box-shadow":"5px 5px 15px #AAAAAA", // Safari 3 and Chrome "-moz-box-shadow":"5px 5px 15px #AAAAAA", // Forefox 3.5 @@ -53,6 +59,11 @@ "background-color":"white", opacity:0, filter:"alpha(opacity=0)" }, + "#MathJax_ZoomFrame": { + position:"relative", display:"inline-block", + height:0, width:0 + }, + "#MathJax_ZoomEventTrap": { position:"absolute", left:0, top:0, "z-index":302, display:"inline-block", border:0, padding:0, margin:0, @@ -98,7 +109,7 @@ // Zoom on double click // DblClick: function (event,math) { - if (this.settings.zoom === "Double-Click") {return this.Zoom(event,math)} + if (this.settings.zoom === "Double-Click" || this.settings.zoom === "DoubleClick") {return this.Zoom(event,math)} }, // @@ -129,27 +140,26 @@ // // Create the DOM elements for the zoom box // - var Mw = Math.floor(.85*document.body.clientWidth), - Mh = Math.floor(.85*Math.max(document.body.clientHeight,document.documentElement.clientHeight)); + var container = this.findContainer(math); + var Mw = Math.floor(.85*container.clientWidth), + Mh = Math.max(document.body.clientHeight,document.documentElement.clientHeight); + if (this.getOverflow(container) !== "visible") {Mh = Math.min(container.clientHeight,Mh)} + Mh = Math.floor(.85*Mh); var div = HTML.Element( - "span",{ - style: {position:"relative", display:"inline-block", height:0, width:0}, - id:"MathJax_ZoomFrame" - },[ + "span",{id:"MathJax_ZoomFrame"},[ ["span",{id:"MathJax_ZoomOverlay", onmousedown:this.Remove}], ["span",{ id:"MathJax_Zoom", onclick:this.Remove, - style:{ - visibility:"hidden", fontSize:this.settings.zscale, - "max-width":Mw+"px", "max-height":Mh+"px" - } + style:{visibility:"hidden", fontSize:this.settings.zscale} },[["span",{style:{display:"inline-block", "white-space":"nowrap"}}]] ]] ); var zoom = div.lastChild, span = zoom.firstChild, overlay = div.firstChild; - math.parentNode.insertBefore(div,math); + math.parentNode.insertBefore(div,math); math.parentNode.insertBefore(math,div); // put div after math if (span.addEventListener) {span.addEventListener("mousedown",this.Remove,true)} - + var eW = zoom.offsetWidth || zoom.clientWidth; Mw -= eW; Mh -= eW; + zoom.style.maxWidth = Mw+"px"; zoom.style.maxHeight = Mh+"px"; + if (this.msieTrapEventBug) { var trap = HTML.Element("span",{id:"MathJax_ZoomEventTrap", onmousedown:this.Remove}); div.insertBefore(trap,zoom); @@ -182,7 +192,8 @@ if (zoom.offsetWidth > Mw) {zoom.style.width = Mw+"px"; zoom.style.height = (bbox.zH+this.scrollSize)+"px"} } if (this.operaPositionBug) {zoom.style.width = Math.min(Mw,bbox.zW)+"px"} // Opera gets width as 0? - if (zoom.offsetWidth < Mw && zoom.offsetHeight < Mh) {zoom.style.overflow = "visible"} + if (zoom.offsetWidth > eW && zoom.offsetWidth-eW < Mw && zoom.offsetHeight-eW < Mh) + {zoom.style.overflow = "visible"} // don't show scroll bars if we don't need to this.Position(zoom,bbox); if (this.msieTrapEventBug) { trap.style.height = zoom.clientHeight+"px"; trap.style.width = zoom.clientWidth+"px"; @@ -214,8 +225,10 @@ // Set the position of the zoom box and overlay // Position: function (zoom,bbox) { + zoom.style.display = "none"; // avoids getting excessive width in Resize() var XY = this.Resize(), x = XY.x, y = XY.y, W = bbox.mW; - var dx = -Math.floor((zoom.offsetWidth-W)/2), dy = bbox.Y; + zoom.style.display = ""; + var dx = -W-Math.floor((zoom.offsetWidth-W)/2), dy = bbox.Y; zoom.style.left = Math.max(dx,10-x)+"px"; zoom.style.top = Math.max(dy,10-y)+"px"; if (!ZOOM.msiePositionBug) {ZOOM.SetWH()} // refigure overlay width/height }, @@ -225,24 +238,61 @@ // Resize: function (event) { if (ZOOM.onresize) {ZOOM.onresize(event)} - var x = 0, y = 0, obj, - div = document.getElementById("MathJax_ZoomFrame"), + var div = document.getElementById("MathJax_ZoomFrame"), overlay = document.getElementById("MathJax_ZoomOverlay"); + var xy = ZOOM.getXY(div), obj = ZOOM.findContainer(div); + if (ZOOM.getOverflow(obj) !== "visible") { + overlay.scroll_parent = obj; // Save this for future reference. + var XY = ZOOM.getXY(obj); // Remove container position + xy.x -= XY.x; xy.y -= XY.y; + XY = ZOOM.getBorder(obj); // Remove container border + xy.x -= XY.x; xy.y -= XY.y; + } + overlay.style.left = (-xy.x)+"px"; overlay.style.top = (-xy.y)+"px"; + if (ZOOM.msiePositionBug) {setTimeout(ZOOM.SetWH,0)} else {ZOOM.SetWH()} + return xy; + }, + SetWH: function () { + var overlay = document.getElementById("MathJax_ZoomOverlay"); + if (!overlay) return; + overlay.style.display = "none"; // so scrollWidth/Height will be right below + var doc = overlay.scroll_parent || document.documentElement || document.body; + overlay.style.width = doc.scrollWidth + "px"; + overlay.style.height = Math.max(doc.clientHeight,doc.scrollHeight) + "px"; + overlay.style.display = ""; + }, + findContainer: function (obj) { + obj = obj.parentNode; + while (obj.parentNode && obj !== document.body && ZOOM.getOverflow(obj) === "visible") + {obj = obj.parentNode} + return obj; + }, + // + // Look up CSS properties (use getComputeStyle if available, or currentStyle if not) + // + getOverflow: (window.getComputedStyle ? + function (obj) {return getComputedStyle(obj).overflow} : + function (obj) {return (obj.currentStyle||{overflow:"visible"}).overflow}), + getBorder: function (obj) { + var size = {thin: 1, medium: 2, thick: 3}; + var style = (window.getComputedStyle ? getComputedStyle(obj) : + (obj.currentStyle || {borderLeftWidth:0,borderTopWidth:0})); + var x = style.borderLeftWidth, y = style.borderTopWidth; + if (size[x]) {x = size[x]} else {x = parseInt(x)} + if (size[y]) {y = size[y]} else {y = parseInt(y)} + return {x:x, y:y}; + }, + // + // Get the position of an element on the page + // + getXY: function (div) { + var x = 0, y = 0, obj; obj = div; while (obj.offsetParent) {x += obj.offsetLeft; obj = obj.offsetParent} if (ZOOM.operaPositionBug) {div.style.border = "1px solid"} // to get vertical position right obj = div; while (obj.offsetParent) {y += obj.offsetTop; obj = obj.offsetParent} if (ZOOM.operaPositionBug) {div.style.border = ""} - overlay.style.left = (-x)+"px"; overlay.style.top = (-y)+"px"; - if (ZOOM.msiePositionBug) {setTimeout(ZOOM.SetWH,0)} else {ZOOM.SetWH()} return {x:x, y:y}; }, - SetWH: function () { - var overlay = document.getElementById("MathJax_ZoomOverlay"); - overlay.style.width = overlay.style.height = "1px"; // so scrollWidth/Height will be right below - var doc = document.documentElement || document.body; - overlay.style.width = doc.scrollWidth + "px"; - overlay.style.height = Math.max(doc.clientHeight,doc.scrollHeight) + "px"; - }, // // Remove zoom display and event handlers @@ -250,8 +300,8 @@ Remove: function (event) { var div = document.getElementById("MathJax_ZoomFrame"); if (div) { - var JAX = MathJax.OutputJax[div.nextSibling.jaxID]; - var jax = JAX.getJaxFromMath(div.nextSibling); + var JAX = MathJax.OutputJax[div.previousSibling.jaxID]; + var jax = JAX.getJaxFromMath(div.previousSibling); HUB.signal.Post(["math unzoomed",jax]); div.parentNode.removeChild(div); div = document.getElementById("MathJax_ZoomTracker"); diff --git a/resources/viewer/mathjax/extensions/Safe.js b/resources/viewer/mathjax/extensions/Safe.js new file mode 100644 index 0000000000..df659bafe4 --- /dev/null +++ b/resources/viewer/mathjax/extensions/Safe.js @@ -0,0 +1,348 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/Safe.js + * + * Implements a "Safe" mode that disables features that could be + * misused in a shared environment (such as href's to javascript URL's). + * See the CONFIG variable below for configuration options. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2015 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. + */ + +(function (HUB,AJAX) { + var VERSION = "2.6.0"; + + var CONFIG = MathJax.Hub.CombineConfig("Safe",{ + allow: { + // + // Values can be "all", "safe", or "none" + // + URLs: "safe", // safe are in safeProtocols below + classes: "safe", // safe start with MJX- + cssIDs: "safe", // safe start with MJX- + styles: "safe", // safe are in safeStyles below + fontsize: "all", // safe are between sizeMin and sizeMax em's + require: "safe" // safe are in safeRequire below + }, + sizeMin: .7, // \scriptsize + sizeMax: 1.44, // \large + safeProtocols: { + http: true, + https: true, + file: true, + javascript: false + }, + safeStyles: { + color: true, + backgroundColor: true, + border: true, + cursor: true, + margin: true, + padding: true, + textShadow: true, + fontFamily: true, + fontSize: true, + fontStyle: true, + fontWeight: true, + opacity: true, + outline: true + }, + safeRequire: { + action: true, + amscd: true, + amsmath: true, + amssymbols: true, + autobold: false, + "autoload-all": false, + bbox: true, + begingroup: true, + boldsymbol: true, + cancel: true, + color: true, + enclose: true, + extpfeil: true, + HTML: true, + mathchoice: true, + mhchem: true, + newcommand: true, + noErrors: false, + noUndefined: false, + unicode: true, + verb: true + } + }); + + var ALLOW = CONFIG.allow; + if (ALLOW.fontsize !== "all") {CONFIG.safeStyles.fontSize = false} + + var SAFE = MathJax.Extension.Safe = { + version: VERSION, + config: CONFIG, + div1: document.createElement("div"), // for CSS processing + div2: document.createElement("div"), + + // + // Methods called for MathML attribute processing + // + filter: { + href: "filterURL", + src: "filterURL", + altimg: "filterURL", + "class": "filterClass", + style: "filterStyles", + id: "filterID", + fontsize: "filterFontSize", + mathsize: "filterFontSize", + scriptminsize: "filterFontSize", + scriptsizemultiplier: "filterSizeMultiplier", + scriptlevel: "filterScriptLevel" + }, + + // + // Filter HREF URL's + // + filterURL: function (url) { + var protocol = (url.match(/^\s*([a-z]+):/i)||[null,""])[1].toLowerCase(); + if (ALLOW.URLs === "none" || + (ALLOW.URLs !== "all" && !CONFIG.safeProtocols[protocol])) {url = null} + return url; + }, + + // + // Filter class names and css ID's + // + filterClass: function (CLASS) { + if (ALLOW.classes === "none" || + (ALLOW.classes !== "all" && !CLASS.match(/^MJX-[-a-zA-Z0-9_.]+$/))) {CLASS = null} + return CLASS; + }, + filterID: function (id) { + if (ALLOW.cssIDs === "none" || + (ALLOW.cssIDs !== "all" && !id.match(/^MJX-[-a-zA-Z0-9_.]+$/))) {id = null} + return id; + }, + + // + // Filter style strings + // + filterStyles: function (styles) { + if (ALLOW.styles === "all") {return styles} + if (ALLOW.styles === "none") {return null} + try { + // + // Set the div1 styles to the given styles, and clear div2 + // + var STYLE1 = this.div1.style, STYLE2 = this.div2.style; + STYLE1.cssText = styles; STYLE2.cssText = ""; + // + // Check each allowed style and transfer OK ones to div2 + // + for (var name in CONFIG.safeStyles) {if (CONFIG.safeStyles.hasOwnProperty(name)) { + var value = this.filterStyle(name,STYLE1[name]); + if (value != null) {STYLE2[name] = value} + }} + // + // Return the div2 style string + // + styles = STYLE2.cssText; + } catch (e) {styles = null} + return styles; + }, + // + // Filter an individual name:value style pair + // + filterStyle: function (name,value) { + if (typeof value !== "string") {return null} + if (value.match(/^\s*expression/)) {return null} + if (value.match(/javascript:/)) {return null} + return (CONFIG.safeStyles[name] ? value : null); + }, + + // + // Filter TeX font size values (in em's) + // + filterSize: function (size) { + if (ALLOW.fontsize === "none") {return null} + if (ALLOW.fontsize !== "all") + {size = Math.min(Math.max(size,CONFIG.sizeMin),CONFIG.sizeMax)} + return size; + }, + filterFontSize: function (size) { + return (ALLOW.fontsize === "all" ? size: null); + }, + + // + // Filter scriptsizemultiplier + // + filterSizeMultiplier: function (size) { + if (ALLOW.fontsize === "none") {size = null} + else if (ALLOW.fontsize !== "all") {size = Math.min(1,Math.max(.6,size)).toString()} + return size; + }, + // + // Filter scriptLevel + // + filterScriptLevel: function (level) { + if (ALLOW.fontsize === "none") {level = null} + else if (ALLOW.fontsize !== "all") {level = Math.max(0,level).toString()} + return level; + }, + + // + // Filter TeX extension names + // + filterRequire: function (name) { + if (ALLOW.require === "none" || + (ALLOW.require !== "all" && !CONFIG.safeRequire[name.toLowerCase()])) + {name = null} + return name; + } + + }; + + HUB.Register.StartupHook("TeX HTML Ready",function () { + var TEX = MathJax.InputJax.TeX; + + TEX.Parse.Augment({ + + // + // Implements \href{url}{math} with URL filter + // + HREF_attribute: function (name) { + var url = SAFE.filterURL(this.GetArgument(name)), + arg = this.GetArgumentMML(name); + if (url) {arg.With({href:url})} + this.Push(arg); + }, + + // + // Implements \class{name}{math} with class-name filter + // + CLASS_attribute: function (name) { + var CLASS = SAFE.filterClass(this.GetArgument(name)), + arg = this.GetArgumentMML(name); + if (CLASS) { + if (arg["class"] != null) {CLASS = arg["class"] + " " + CLASS} + arg.With({"class":CLASS}); + } + this.Push(arg); + }, + + // + // Implements \style{style-string}{math} with style filter + // + STYLE_attribute: function (name) { + var style = SAFE.filterStyles(this.GetArgument(name)), + arg = this.GetArgumentMML(name); + if (style) { + if (arg.style != null) { + if (style.charAt(style.length-1) !== ";") {style += ";"} + style = arg.style + " " + style; + } + arg.With({style: style}); + } + this.Push(arg); + }, + + // + // Implements \cssId{id}{math} with ID filter + // + ID_attribute: function (name) { + var ID = SAFE.filterID(this.GetArgument(name)), + arg = this.GetArgumentMML(name); + if (ID) {arg.With({id:ID})} + this.Push(arg); + } + + }); + + }); + + HUB.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX, + PARSE = TEX.Parse, METHOD = SAFE.filter; + + PARSE.Augment({ + + // + // Implements \require{name} with filtering + // + Require: function (name) { + var file = this.GetArgument(name).replace(/.*\//,"").replace(/[^a-z0-9_.-]/ig,""); + file = SAFE.filterRequire(file); + if (file) {this.Extension(null,file)} + }, + + // + // Controls \mmlToken attributes + // + MmlFilterAttribute: function (name,value) { + if (METHOD[name]) {value = SAFE[METHOD[name]](value)} + return value; + }, + + // + // Handles font size macros with filtering + // + SetSize: function (name,size) { + size = SAFE.filterSize(size); + if (size) { + this.stack.env.size = size; + this.Push(TEX.Stack.Item.style().With({styles: {mathsize: size+"em"}})); + } + } + + }); + }); + + HUB.Register.StartupHook("TeX bbox Ready",function () { + var TEX = MathJax.InputJax.TeX; + + // + // Filter the styles for \bbox + // + TEX.Parse.Augment({ + BBoxStyle: function (styles) {return SAFE.filterStyles(styles)} + }); + + }); + + HUB.Register.StartupHook("MathML Jax Ready",function () { + var PARSE = MathJax.InputJax.MathML.Parse, + METHOD = SAFE.filter; + + // + // Filter MathML attributes + // + PARSE.Augment({ + filterAttribute: function (name,value) { + if (METHOD[name]) {value = SAFE[METHOD[name]](value)} + return value; + } + }); + + }); + + // MathML input (href, style, fontsize, class, id) + + HUB.Startup.signal.Post("Safe Extension Ready"); + AJAX.loadComplete("[MathJax]/extensions/Safe.js"); + +})(MathJax.Hub,MathJax.Ajax); diff --git a/resources/viewer/mathjax/extensions/TeX/AMScd.js b/resources/viewer/mathjax/extensions/TeX/AMScd.js new file mode 100644 index 0000000000..7e5742f2ad --- /dev/null +++ b/resources/viewer/mathjax/extensions/TeX/AMScd.js @@ -0,0 +1,158 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/AMScd.js + * + * Implements the CD environment for commutative diagrams. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2015 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["TeX/AMScd"] = { + version: "2.6.0", + config: MathJax.Hub.CombineConfig("TeX.CD",{ + colspace: "5pt", + rowspace: "5pt", + harrowsize: "2.75em", + varrowsize: "1.75em", + hideHorizontalLabels: false + }) +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var MML = MathJax.ElementJax.mml, + TEX = MathJax.InputJax.TeX, + STACKITEM = TEX.Stack.Item, + TEXDEF = TEX.Definitions, + CONFIG = MathJax.Extension["TeX/AMScd"].config; + + TEXDEF.environment.CD = "CD_env"; + TEXDEF.special["@"] = "CD_arrow"; + TEXDEF.macros.minCDarrowwidth = "CD_minwidth"; + TEXDEF.macros.minCDarrowheight = "CD_minheight"; + + TEX.Parse.Augment({ + // + // Implements \begin{CD}...\end{CD} + // + CD_env: function (begin) { + this.Push(begin); + return STACKITEM.array().With({ + arraydef: { + columnalign: "center", + columnspacing: CONFIG.colspace, + rowspacing: CONFIG.rowspace, + displaystyle: true + }, + minw: this.stack.env.CD_minw || CONFIG.harrowsize, + minh: this.stack.env.CD_minh || CONFIG.varrowsize + }); + }, + + CD_arrow: function (name) { + var c = this.string.charAt(this.i); + if (!c.match(/[>>> @<<< @VVV and @AAA, get the arrow and labels + // + var arrow = {">":"\u2192", "<":"\u2190", V:"\u2193", A:"\u2191"}[c]; + var a = this.GetUpTo(name+c,c), + b = this.GetUpTo(name+c,c); + + if (c === ">" || c === "<") { + // + // Lay out horizontal arrows with munderover if it has labels + // + mml = MML.mo(arrow).With(hdef); + if (!a) {a = "\\kern "+top.minw} // minsize needs work + if (a || b) { + var pad = {width:"+11mu", lspace:"6mu"}; + mml = MML.munderover(this.mmlToken(mml)); + if (a) { + a = TEX.Parse(a,this.stack.env).mml(); + mml.SetData(mml.over,MML.mpadded(a).With(pad).With({voffset:".1em"})); + } + if (b) { + b = TEX.Parse(b,this.stack.env).mml(); + mml.SetData(mml.under,MML.mpadded(b).With(pad)); + } + if (CONFIG.hideHorizontalLabels) + {mml = MML.mpadded(mml).With({depth:0, height:".67em"})} + } + } else { + // + // Lay out vertical arrows with mrow if there are labels + // + mml = arrow = this.mmlToken(MML.mo(arrow).With(vdef)); + if (a || b) { + mml = MML.mrow(); + if (a) {mml.Append(TEX.Parse("\\scriptstyle\\llap{"+a+"}",this.stack.env).mml())} + mml.Append(arrow.With({texClass: MML.TEXCLASS.ORD})); + if (b) {mml.Append(TEX.Parse("\\scriptstyle\\rlap{"+b+"}",this.stack.env).mml())} + } + } + } + if (mml) {this.Push(mml)}; + this.CD_cell(name); + }, + CD_cell: function (name) { + var top = this.stack.Top(); + if ((top.table||[]).length % 2 === 0 && (top.row||[]).length === 0) { + // + // Add a strut to the first cell in even rows to get + // better spacing of arrow rows. + // + this.Push(MML.mpadded().With({height:"8.5pt",depth:"2pt"})); + } + this.Push(STACKITEM.cell().With({isEntry:true, name:name})); + }, + + CD_minwidth: function (name) { + this.stack.env.CD_minw = this.GetDimen(name); + }, + CD_minheight: function (name) { + this.stack.env.CD_minh = this.GetDimen(name); + } + + }); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMScd.js"); diff --git a/resources/viewer/mathjax/extensions/TeX/AMSmath.js b/resources/viewer/mathjax/extensions/TeX/AMSmath.js index 9698448187..55b9860fd5 100644 --- a/resources/viewer/mathjax/extensions/TeX/AMSmath.js +++ b/resources/viewer/mathjax/extensions/TeX/AMSmath.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/AMSmath.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -22,10 +25,12 @@ */ MathJax.Extension["TeX/AMSmath"] = { - version: "2.0", + version: "2.6.0", number: 0, // current equation number startNumber: 0, // current starting equation number (for when equation is restarted) + IDs: {}, // IDs used in previous equations + eqIDs: {}, // IDs used in this equation labels: {}, // the set of labels eqlabels: {}, // labels in the current equation refs: [] // array of jax with unresolved references @@ -41,11 +46,20 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { STACKITEM = TEX.Stack.Item, CONFIG = TEX.config.equationNumbers; - var COLS = function (W) {return W.join("em ") + "em"}; + var COLS = function (W) { + var WW = []; + for (var i = 0, m = W.length; i < m; i++) + {WW[i] = TEX.Parse.prototype.Em(W[i])} + return WW.join(" "); + }; /******************************************************************************/ TEXDEF.Add({ + mathchar0mo: { + iiiint: ['2A0C',{texClass: MML.TEXCLASS.OP}] + }, + macros: { mathring: ['Accent','2DA'], // or 0x30A @@ -53,14 +67,16 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { negmedspace: ['Spacer',MML.LENGTH.NEGATIVEMEDIUMMATHSPACE], negthickspace: ['Spacer',MML.LENGTH.NEGATIVETHICKMATHSPACE], - intI: ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'], +// intI: ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'], // iint: ['MultiIntegral','\\int\\intI'], // now in core TeX input jax // iiint: ['MultiIntegral','\\int\\intI\\intI'], // now in core TeX input jax - iiiint: ['MultiIntegral','\\int\\intI\\intI\\intI'], +// iiiint: ['MultiIntegral','\\int\\intI\\intI\\intI'], // now in mathchar0mo above idotsint: ['MultiIntegral','\\int\\cdots\\int'], - dddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}}',1], - ddddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}\\mathord{.}}',1], +// dddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}}',1], +// ddddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}\\mathord{.}}',1], + dddot: ['Accent','20DB'], + ddddot: ['Accent','20DC'], sideset: ['Macro','\\mathop{\\mathop{\\rlap{\\phantom{#3}}}\\nolimits#1\\!\\mathop{#3}\\nolimits#2}',3], @@ -74,23 +90,24 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { substack: ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1], - injlim: ['Macro','\\mathop{\\rm inj\\,lim}'], - projlim: ['Macro','\\mathop{\\rm proj\\,lim}'], - varliminf: ['Macro','\\mathop{\\underline{\\rm lim}}'], - varlimsup: ['Macro','\\mathop{\\overline{\\rm lim}}'], - varinjlim: ['Macro','\\mathop{\\underrightarrow{\\rm lim\\Rule{-1pt}{0pt}{1pt}}\\Rule{0pt}{0pt}{.45em}}'], - varprojlim: ['Macro','\\mathop{\\underleftarrow{\\rm lim\\Rule{-1pt}{0pt}{1pt}}\\Rule{0pt}{0pt}{.45em}}'], + injlim: ['NamedOp','inj lim'], + projlim: ['NamedOp','proj lim'], + varliminf: ['Macro','\\mathop{\\underline{\\mmlToken{mi}{lim}}}'], + varlimsup: ['Macro','\\mathop{\\overline{\\mmlToken{mi}{lim}}}'], + varinjlim: ['Macro','\\mathop{\\underrightarrow{\\mmlToken{mi}{lim}\\Rule{-1pt}{0pt}{1pt}}\\Rule{0pt}{0pt}{.45em}}'], + varprojlim: ['Macro','\\mathop{\\underleftarrow{\\mmlToken{mi}{lim}\\Rule{-1pt}{0pt}{1pt}}\\Rule{0pt}{0pt}{.45em}}'], DeclareMathOperator: 'HandleDeclareOp', operatorname: 'HandleOperatorName', + SkipLimits: 'SkipLimits', genfrac: 'Genfrac', frac: ['Genfrac',"","","",""], tfrac: ['Genfrac',"","","",1], dfrac: ['Genfrac',"","","",0], - binom: ['Genfrac',"(",")","0em",""], - tbinom: ['Genfrac',"(",")","0em",1], - dbinom: ['Genfrac',"(",")","0em",0], + binom: ['Genfrac',"(",")","0",""], + tbinom: ['Genfrac',"(",")","0",1], + dbinom: ['Genfrac',"(",")","0",0], cfrac: 'CFrac', @@ -102,11 +119,11 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }, environment: { - align: ['AMSarray',null,true,true, 'rlrlrlrlrlrl',COLS([5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18])], - 'align*': ['AMSarray',null,false,true, 'rlrlrlrlrlrl',COLS([5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18])], + align: ['AMSarray',null,true,true, 'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0])], + 'align*': ['AMSarray',null,false,true, 'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0])], multline: ['Multline',null,true], 'multline*': ['Multline',null,false], - split: ['AMSarray',null,false,false,'rl',COLS([5/18])], + split: ['AMSarray',null,false,false,'rl',COLS([0])], gather: ['AMSarray',null,true,true, 'c'], 'gather*': ['AMSarray',null,false,true, 'c'], @@ -114,14 +131,17 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { 'alignat*': ['AlignAt',null,false,true], alignedat: ['AlignAt',null,false,false], - aligned: ['AlignedArray',null,null,null,'rlrlrlrlrlrl',COLS([5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18]),".5em",'D'], - gathered: ['AlignedArray',null,null,null,'c',null,".5em",'D'], + aligned: ['AlignedAMSArray',null,null,null,'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0]),".5em",'D'], + gathered: ['AlignedAMSArray',null,null,null,'c',null,".5em",'D'], - subarray: ['Array',null,null,null,null,COLS([0,0,0,0]),"0.1em",'S',1], + subarray: ['Array',null,null,null,null,COLS([0]),"0.1em",'S',1], smallmatrix: ['Array',null,null,null,'c',COLS([1/3]),".2em",'S',1], 'equation': ['EquationBegin','Equation',true], - 'equation*': ['EquationBegin','EquationStar',false] + 'equation*': ['EquationBegin','EquationStar',false], + + eqnarray: ['AMSarray',null,true,true, 'rcl',"0 "+MML.LENGTH.THICKMATHSPACE,".5em"], + 'eqnarray*': ['AMSarray',null,false,true,'rcl',"0 "+MML.LENGTH.THICKMATHSPACE,".5em"] }, delimiter: { @@ -145,8 +165,13 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var arg = this.trimSpaces(this.GetArgument(name)), tag = arg; if (!star) {arg = CONFIG.formatTag(arg)} var global = this.stack.global; global.tagID = tag; - if (global.notags) {TEX.Error(name+" not allowed in "+global.notags+" environment")} - if (global.tag) {TEX.Error("Multiple "+name)} + if (global.notags) { + TEX.Error(["CommandNotAllowedInEnv", + "%1 not allowed in %2 environment", + name,global.notags] + ); + } + if (global.tag) {TEX.Error(["MultipleCommand","Multiple %1",name])} global.tag = MML.mtd.apply(MML,this.InternalMath(arg)).With({id:CONFIG.formatID(tag)}); }, HandleNoTag: function (name) { @@ -159,11 +184,13 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { */ HandleLabel: function (name) { var global = this.stack.global, label = this.GetArgument(name); + if (label === "") return; if (!AMS.refUpdate) { - if (global.label) {TEX.Error("Multiple "+name+"'s")} + if (global.label) {TEX.Error(["MultipleCommand","Multiple %1",name])} global.label = label; - if (AMS.labels[label] || AMS.eqlabels[label]) {TEX.Error("Label '"+label+"' mutiply defined")} - AMS.eqlabels[label] = "???"; // will be replaced by tag value later + if (AMS.labels[label] || AMS.eqlabels[label]) + {TEX.Error(["MultipleLabel","Label '%1' multiply defined",label])} + AMS.eqlabels[label] = {tag:"???", id:""}; // will be replaced by tag value later } }, @@ -173,11 +200,10 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { HandleRef: function (name,eqref) { var label = this.GetArgument(name); var ref = AMS.labels[label] || AMS.eqlabels[label]; - if (!ref) {ref = "??"; AMS.badref = !AMS.refUpdate} - var tag = ref; if (eqref) {tag = CONFIG.formatTag(tag)} - if (CONFIG.useLabelIds) {ref = label} + if (!ref) {ref = {tag:"???",id:""}; AMS.badref = !AMS.refUpdate} + var tag = ref.tag; if (eqref) {tag = CONFIG.formatTag(tag)} this.Push(MML.mrow.apply(MML,this.InternalMath(tag)).With({ - href:CONFIG.formatURL(CONFIG.formatID(ref)), "class":"MathJax_ref" + href:CONFIG.formatURL(ref.id), "class":"MathJax_ref" })); }, @@ -185,7 +211,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { * Handle \DeclareMathOperator */ HandleDeclareOp: function (name) { - var limits = (this.GetStar() ? "\\limits" : ""); + var limits = (this.GetStar() ? "" : "\\nolimits\\SkipLimits"); var cs = this.trimSpaces(this.GetArgument(name)); if (cs.charAt(0) == "\\") {cs = cs.substr(1)} var op = this.GetArgument(name); @@ -194,19 +220,27 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }, HandleOperatorName: function (name) { - var limits = (this.GetStar() ? "\\limits" : "\\nolimits"); + var limits = (this.GetStar() ? "" : "\\nolimits\\SkipLimits"); var op = this.trimSpaces(this.GetArgument(name)); op = op.replace(/\*/g,'\\text{*}').replace(/-/g,'\\text{-}'); this.string = '\\mathop{\\rm '+op+'}'+limits+" "+this.string.slice(this.i); this.i = 0; }, + SkipLimits: function (name) { + var c = this.GetNext(), i = this.i; + if (c === "\\" && ++this.i && this.GetCS() !== "limits") this.i = i; + }, + /* * Record presence of \shoveleft and \shoveright */ HandleShove: function (name,shove) { var top = this.stack.Top(); - if (top.type !== "multline" || top.data.length) {TEX.Error(name+" must come at the beginning of the line")} + if (top.type !== "multline" || top.data.length) { + TEX.Error(["CommandAtTheBeginingOfLine", + "%1 must come at the beginning of the line",name]); + } top.data.shove = shove; }, @@ -220,7 +254,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var frac = MML.mfrac(TEX.Parse('\\strut\\textstyle{'+num+'}',this.stack.env).mml(), TEX.Parse('\\strut\\textstyle{'+den+'}',this.stack.env).mml()); lr = ({l:MML.ALIGN.LEFT, r:MML.ALIGN.RIGHT,"":""})[lr]; - if (lr == null) {TEX.Error("Illegal alignment specified in "+name)} + if (lr == null) + {TEX.Error(["IllegalAlign","Illegal alignment specified in %1",name])} if (lr) {frac.numalign = frac.denomalign = lr} this.Push(frac); }, @@ -229,18 +264,19 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { * Implement AMS generalized fraction */ Genfrac: function (name,left,right,thick,style) { - if (left == null) {left = this.GetDelimiterArg(name)} else {left = this.convertDelimiter(left)} - if (right == null) {right = this.GetDelimiterArg(name)} else {right = this.convertDelimiter(right)} + if (left == null) {left = this.GetDelimiterArg(name)} + if (right == null) {right = this.GetDelimiterArg(name)} if (thick == null) {thick = this.GetArgument(name)} if (style == null) {style = this.trimSpaces(this.GetArgument(name))} var num = this.ParseArg(name); var den = this.ParseArg(name); var frac = MML.mfrac(num,den); if (thick !== "") {frac.linethickness = thick} - if (left || right) {frac = MML.mfenced(frac).With({open: left, close: right})} + if (left || right) {frac = TEX.fixedFence(left,frac.With({texWithDelims:true}),right)} if (style !== "") { var STYLE = (["D","T","S","SS"])[style]; - if (STYLE == null) {TEX.Error("Bad math style for "+name)} + if (STYLE == null) + {TEX.Error(["BadMathStyleFor","Bad math style for %1",name])} frac = MML.mstyle(frac); if (STYLE === "D") {frac.displaystyle = true; frac.scriptlevel = 0} else {frac.displaystyle = false; frac.scriptlevel = style - 1} @@ -284,6 +320,11 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }); }, + AlignedAMSArray: function (begin) { + var align = this.GetBrackets("\\begin{"+begin.name+"}"); + return this.setArrayAlign(this.AMSarray.apply(this,arguments),align); + }, + /* * Handle alignat environments */ @@ -291,11 +332,14 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var n, valign, align = "", spacing = []; if (!taggable) {valign = this.GetBrackets("\\begin{"+begin.name+"}")} n = this.GetArgument("\\begin{"+begin.name+"}"); - if (n.match(/[^0-9]/)) {TEX.Error("Argument to \\begin{"+begin.name+"} must me a positive integer")} + if (n.match(/[^0-9]/)) { + TEX.Error(["PositiveIntegerArg","Argument to %1 must me a positive integer", + "\\begin{"+begin.name+"}"]); + } while (n > 0) {align += "rl"; spacing.push("0em 0em"); n--} spacing = spacing.join(" "); if (taggable) {return this.AMSarray(begin,numbered,taggable,align,spacing)} - var array = this.Array.call(this,begin,null,null,align,spacing,".5em",'D'); + var array = this.AMSarray(begin,numbered,taggable,align,spacing); return this.setArrayAlign(array,valign); }, @@ -316,7 +360,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { * Check for bad nesting of equation environments */ checkEqnEnv: function () { - if (this.stack.global.eqnenv) {TEX.Error("Erroneous nesting of equation structures")} + if (this.stack.global.eqnenv) + {TEX.Error(["ErroneousNestingEq","Erroneous nesting of equation structures"])} this.stack.global.eqnenv = true; }, @@ -352,7 +397,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { bot = TEX.Parse(bot,this.stack.env).mml() mml.SetData(mml.under,MML.mpadded(bot).With(def).With({voffset:"-.24em"})); } - this.Push(mml); + this.Push(mml.With({subsupOK:true})); }, /* @@ -360,9 +405,9 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { */ GetDelimiterArg: function (name) { var c = this.trimSpaces(this.GetArgument(name)); - if (c == "") {return null} - if (TEXDEF.delimiter[c] == null) {TEX.Error("Missing or unrecognized delimiter for "+name)} - return this.convertDelimiter(c); + if (c == "") return null; + if (c in TEXDEF.delimiter) return c; + TEX.Error(["MissingOrUnrecognizedDelim","Missing or unrecognized delimiter for %1",name]); }, /* @@ -387,7 +432,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { if (!global.notag) { AMS.number++; global.tagID = CONFIG.formatNumber(AMS.number.toString()); var mml = TEX.Parse("\\text{"+CONFIG.formatTag(global.tagID)+"}",{}).mml(); - global.tag = MML.mtd(mml.With({id:CONFIG.formatID(global.tagID)})); + global.tag = MML.mtd(mml).With({id:CONFIG.formatID(global.tagID)}); } }, @@ -397,11 +442,42 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { getTag: function () { var global = this.global, tag = global.tag; global.tagged = true; if (global.label) { - AMS.eqlabels[global.label] = global.tagID; if (CONFIG.useLabelIds) {tag.id = CONFIG.formatID(global.label)} + AMS.eqlabels[global.label] = {tag:global.tagID, id:tag.id}; } - delete global.tag; delete global.tagID; delete global.label; + // + // Check for repeated ID's (either in the document or as + // a previous tag) and find a unique related one. (#240) + // + if (document.getElementById(tag.id) || AMS.IDs[tag.id] || AMS.eqIDs[tag.id]) { + var i = 0, ID; + do {i++; ID = tag.id+"_"+i} + while (document.getElementById(ID) || AMS.IDs[ID] || AMS.eqIDs[ID]); + tag.id = ID; if (global.label) {AMS.eqlabels[global.label].id = ID} + } + AMS.eqIDs[tag.id] = 1; + this.clearTag(); return tag; + }, + clearTag: function () { + var global = this.global; + delete global.tag; delete global.tagID; delete global.label; + }, + + /* + * If the initial child, skipping any initial space or + * empty braces (TeXAtom with child being an empty inferred row), + * is an , preceed it by an empty to force the to + * be infix. + */ + fixInitialMO: function (data) { + for (var i = 0, m = data.length; i < m; i++) { + if (data[i] && (data[i].type !== "mspace" && + (data[i].type !== "texatom" || (data[i].data[0] && data[i].data[0].data.length)))) { + if (data[i].isEmbellished()) data.unshift(MML.mi()); + break; + } + } } }); @@ -417,13 +493,18 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { stack.global.tagged = !numbered && !stack.global.forcetag; // prevent automatic tagging in starred environments }, EndEntry: function () { + if (this.table.length) {this.fixInitialMO(this.data)} var mtd = MML.mtd.apply(MML,this.data); if (this.data.shove) {mtd.columnalign = this.data.shove} this.row.push(mtd); this.data = []; }, EndRow: function () { - if (this.row.length != 1) {TEX.Error("multline rows must have exactly one column")} + if (this.row.length != 1) { + TEX.Error(["MultlineRowsOneCol", + "The rows within the %1 environment must have exactly one column", + "multline"]); + } this.table.push(this.row); this.row = []; }, EndTable: function () { @@ -459,13 +540,18 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { stack.global.notags = (taggable ? null : name); stack.global.tagged = !numbered && !stack.global.forcetag; // prevent automatic tagging in starred environments }, + EndEntry: function () { + if (this.row.length) {this.fixInitialMO(this.data)} + this.row.push(MML.mtd.apply(MML,this.data)); + this.data = []; + }, EndRow: function () { var mtr = MML.mtr; if (!this.global.tag && this.numbered) {this.autoTag()} - if (this.global.tag &&! this.global.notags) { + if (this.global.tag && !this.global.notags) { this.row = [this.getTag()].concat(this.row); mtr = MML.mlabeledtr; - } + } else {this.clearTag()} if (this.numbered) {delete this.global.notag} this.table.push(mtr.apply(MML,this.row)); this.row = []; }, @@ -491,21 +577,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var def = { side: TEX.config.TagSide, minlabelspacing: TEX.config.TagIndent, - columnalign: mml.displayAlign + displaystyle: "inherit" // replaced by TeX input jax Translate() function with actual value }; - if (mml.displayAlign === MML.INDENTALIGN.LEFT) { - def.width = "100%"; - if (mml.displayIndent && !String(mml.displayIndent).match(/^0+(\.0*)?($|[a-z%])/)) { - def.columnwidth = mml.displayIndent + " fit"; def.columnspacing = "0" - row = [row[0],MML.mtd(),row[1]]; - } - } else if (mml.displayAlign === MML.INDENTALIGN.RIGHT) { - def.width = "100%"; - if (mml.displayIndent && !String(mml.displayIndent).match(/^0+(\.0*)?($|[a-z%])/)) { - def.columnwidth = "fit "+mml.displayIndent; def.columnspacing = "0" - row[2] = MML.mtd(); - } - } mml = MML.mtable(MML.mlabeledtr.apply(MML,row)).With(def); } return STACKITEM.mml(mml); @@ -522,15 +595,16 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { TEX.prefilterHooks.Add(function (data) { AMS.display = data.display; AMS.number = AMS.startNumber; // reset equation numbers (in case the equation restarted) - AMS.eqlabels = {}; AMS.badref = false; + AMS.eqlabels = AMS.eqIDs = {}; AMS.badref = false; if (AMS.refUpdate) {AMS.number = data.script.MathJax.startNumber} }); TEX.postfilterHooks.Add(function (data) { data.script.MathJax.startNumber = AMS.startNumber; AMS.startNumber = AMS.number; // equation numbers for next equation + MathJax.Hub.Insert(AMS.IDs,AMS.eqIDs); // save IDs from this equation MathJax.Hub.Insert(AMS.labels,AMS.eqlabels); // save labels from this equation if (AMS.badref && !data.math.texError) {AMS.refs.push(data.script)} // reprocess later - }); + },100); MathJax.Hub.Register.MessageHook("Begin Math Input",function () { AMS.refs = []; // array of jax with bad references @@ -555,7 +629,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // TEX.resetEquationNumbers = function (n,keepLabels) { AMS.startNumber = (n || 0); - if (!keepLabels) {AMS.labels = {}} + if (!keepLabels) {AMS.labels = AMS.IDs = {}} } /******************************************************************************/ diff --git a/resources/viewer/mathjax/extensions/TeX/AMSsymbols.js b/resources/viewer/mathjax/extensions/TeX/AMSsymbols.js index af05401ee8..50e7d59c89 100644 --- a/resources/viewer/mathjax/extensions/TeX/AMSsymbols.js +++ b/resources/viewer/mathjax/extensions/TeX/AMSsymbols.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/AMSsymbols.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Extension["TeX/AMSsymbols"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -55,22 +58,22 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { daleth: '2138', // Miscellaneous symbols -// hbar: '0127', // in MathJax_Main +// hbar: '0127', // in TeX/jax.js backprime: ['2035',{variantForm: true}], - hslash: ['210F',{variantForm: true}], + hslash: '210F', varnothing: ['2205',{variantForm: true}], - blacktriangle: '25B2', - triangledown: '25BD', - blacktriangledown: '25BC', - square: '25A1', - Box: '25A1', - blacksquare: '25A0', + blacktriangle: '25B4', + triangledown: ['25BD',{variantForm: true}], + blacktriangledown: '25BE', + square: '25FB', + Box: '25FB', + blacksquare: '25FC', lozenge: '25CA', Diamond: '25CA', blacklozenge: '29EB', circledS: ['24C8',{mathvariant: MML.VARIANT.NORMAL}], bigstar: '2605', -// angle: '2220', // in MathJax_Main +// angle: '2220', // in TeX/jax.js sphericalangle: '2222', measuredangle: '2221', nexists: '2204', @@ -93,7 +96,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // Binary operators dotplus: '2214', ltimes: '22C9', - smallsetminus: ['2216',{variantForm: true}], + smallsetminus: '2216', rtimes: '22CA', Cap: '22D2', doublecap: '22D2', @@ -113,7 +116,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { boxdot: '22A1', circledcirc: '229A', boxplus: '229E', - centerdot: '22C5', + centerdot: ['22C5',{variantForm: true}], divideontimes: '22C7', intercal: '22BA', @@ -177,9 +180,9 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { vDash: '22A8', Vdash: '22A9', Vvdash: '22AA', - smallsmile: '2323', + smallsmile: ['2323',{variantForm: true}], shortmid: ['2223',{variantForm: true}], - smallfrown: '2322', + smallfrown: ['2322',{variantForm: true}], shortparallel: ['2225',{variantForm: true}], bumpeq: '224F', between: '226C', @@ -187,8 +190,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { pitchfork: '22D4', varpropto: '221D', backepsilon: '220D', - blacktriangleleft: '25C0', - blacktriangleright: '25B6', + blacktriangleleft: '25C2', + blacktriangleright: '25B8', therefore: '2234', because: '2235', eqsim: '2242', @@ -343,59 +346,4 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }); -MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { - var HTMLCSS = MathJax.OutputJax["HTML-CSS"]; - var VARIANT = HTMLCSS.FONTDATA.VARIANT; - if (HTMLCSS.fontInUse === "TeX") { - VARIANT["-TeX-variant"] = { - fonts: ["MathJax_AMS","MathJax_Main","MathJax_Size1"], - remap: {0x2268: 0xE00C, 0x2269: 0xE00D, 0x2270: 0xE011, 0x2271: 0xE00E, - 0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2224: 0xE006, 0x2226: 0xE007, - 0x2288: 0xE016, 0x2289: 0xE018, 0x228A: 0xE01A, 0x228B: 0xE01B, - 0x2ACB: 0xE017, 0x2ACC: 0xE019, 0x03DC: 0xE008, 0x03F0: 0xE009} - }; - if (HTMLCSS.msieIE6) { - MathJax.Hub.Insert(VARIANT["-TeX-variant"].remap,{ - 0x2190:[0xE2C1,"-WinIE6"], 0x2192:[0xE2C0,"-WinIE6"], - 0x2223:[0xE2C2,"-WinIE6"], 0x2225:[0xE2C3,"-WinIE6"], - 0x223C:[0xE2C4,"-WinIE6"], 0x25B3:[0xE2D3,"-WinIE6"] - }); - } - } - if (HTMLCSS.fontInUse === "STIX") { - MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { - var TEXDEF = MathJax.InputJax.TeX.Definitions; - TEXDEF.mathchar0mi.varnothing = '2205'; - TEXDEF.mathchar0mi.hslash = '210F'; - TEXDEF.mathchar0mi.blacktriangle = '25B4'; - TEXDEF.mathchar0mi.blacktriangledown = '25BE'; - TEXDEF.mathchar0mi.square = '25FB'; - TEXDEF.mathchar0mi.blacksquare = '25FC'; - TEXDEF.mathchar0mi.vartriangle = ['25B3',{mathsize:"71%"}]; - TEXDEF.mathchar0mi.triangledown = ['25BD',{mathsize:"71%"}]; - TEXDEF.mathchar0mo.blacktriangleleft = '25C2'; - TEXDEF.mathchar0mo.blacktriangleright = '25B8'; - TEXDEF.mathchar0mo.smallsetminus = '2216'; - MathJax.Hub.Insert(VARIANT["-STIX-variant"],{ - remap: {0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2270: 0xE011, 0x2271: 0xE00E, - 0x22E0: 0xE04B, 0x22E1: 0xE04F, 0x2288: 0xE016, 0x2289: 0xE018} - }); - }); - } - -}); - -MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var SVG = MathJax.OutputJax.SVG; - var VARIANT = SVG.FONTDATA.VARIANT; - - VARIANT["-TeX-variant"] = { - fonts: ["MathJax_AMS","MathJax_Main","MathJax_Size1"], - remap: {0x2268: 0xE00C, 0x2269: 0xE00D, 0x2270: 0xE011, 0x2271: 0xE00E, - 0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2224: 0xE006, 0x2226: 0xE007, - 0x2288: 0xE016, 0x2289: 0xE018, 0x228A: 0xE01A, 0x228B: 0xE01B, - 0x2ACB: 0xE017, 0x2ACC: 0xE019, 0x03DC: 0xE008, 0x03F0: 0xE009} - }; -}); - MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSsymbols.js"); diff --git a/resources/viewer/mathjax/extensions/TeX/HTML.js b/resources/viewer/mathjax/extensions/TeX/HTML.js index bcdb158b1b..b645add82b 100644 --- a/resources/viewer/mathjax/extensions/TeX/HTML.js +++ b/resources/viewer/mathjax/extensions/TeX/HTML.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/HTML.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Extension["TeX/HTML"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -37,7 +40,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { style: 'STYLE_attribute', cssId: 'ID_attribute' } - }); + },null,true); TEX.Parse.Augment({ diff --git a/resources/viewer/mathjax/extensions/TeX/action.js b/resources/viewer/mathjax/extensions/TeX/action.js index c7fd19fbfd..f24a798467 100644 --- a/resources/viewer/mathjax/extensions/TeX/action.js +++ b/resources/viewer/mathjax/extensions/TeX/action.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/action.js @@ -16,7 +19,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -32,7 +35,7 @@ */ MathJax.Extension["TeX/action"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -42,9 +45,13 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // // Set up control sequenecs // - TEX.Definitions.macros.toggle = 'Toggle'; - TEX.Definitions.macros.mathtip = 'Mathtip'; - TEX.Definitions.macros.texttip = ['Macro','\\mathtip{#1}{\\text{#2}}',2]; + TEX.Definitions.Add({ + macros: { + toggle: 'Toggle', + mathtip: 'Mathtip', + texttip: ['Macro','\\mathtip{#1}{\\text{#2}}',2] + } + },null,true); TEX.Parse.Augment({ diff --git a/resources/viewer/mathjax/extensions/TeX/autobold.js b/resources/viewer/mathjax/extensions/TeX/autobold.js index 2e26ddac01..376c891643 100644 --- a/resources/viewer/mathjax/extensions/TeX/autobold.js +++ b/resources/viewer/mathjax/extensions/TeX/autobold.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/autobold.js @@ -5,7 +8,9 @@ * Adds \boldsymbol around mathematics that appears in a section * of an HTML page that is in bold. * - * Copyright (c) 2009-2012 Design Science, Inc. + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2015 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. @@ -21,7 +26,7 @@ */ MathJax.Extension["TeX/autobold"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { diff --git a/resources/viewer/mathjax/extensions/TeX/autoload-all.js b/resources/viewer/mathjax/extensions/TeX/autoload-all.js index dc08642c8e..2ea7ec9036 100644 --- a/resources/viewer/mathjax/extensions/TeX/autoload-all.js +++ b/resources/viewer/mathjax/extensions/TeX/autoload-all.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/autoload-all.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2012 Design Science, Inc. + * Copyright (c) 2013-2015 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. @@ -23,14 +26,10 @@ */ MathJax.Extension["TeX/autoload-all"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { - var TEX = MathJax.InputJax.TeX, - MACROS = TEX.Definitions.macros, - ENVS = TEX.Definitions.environment; - var EXTENSIONS = { action: ["mathtip","texttip","toggle"], @@ -42,24 +41,37 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { "shoveleft","shoveright","xrightarrow","xleftarrow"], begingroup: ["begingroup","endgroup","gdef","global"], cancel: ["cancel","bcancel","xcancel","cancelto"], - color: ["color","colorbox","fcolorbox","DefineColor"], + color: ["color","textcolor","colorbox","fcolorbox","definecolor"], enclose: ["enclose"], extpfeil: ["Newextarrow","xlongequal","xmapsto","xtofrom", "xtwoheadleftarrow","xtwoheadrightarrow"], mhchem: ["ce","cee","cf"] }; - for (var name in EXTENSIONS) {if (EXTENSIONS.hasOwnProperty(name)) { - var macros = EXTENSIONS[name]; - for (var i = 0, m = macros.length; i < m; i++) { - MACROS[macros[i]] = ["Extension",name]; + var ENVIRONMENTS = { + AMSmath: ["subarray","smallmatrix","equation","equation*"], + AMScd: ["CD"] + }; + + var name, i, m, defs = {macros:{}, environment:{}}; + + for (name in EXTENSIONS) {if (EXTENSIONS.hasOwnProperty(name)) { + if (!MathJax.Extension["TeX/"+name]) { + var macros = EXTENSIONS[name]; + for (i = 0, m = macros.length; i < m; i++) + {defs.macros[macros[i]] = ["Extension",name]} } }} - ENVS["subarray"] = ['ExtensionEnv',null,'AMSmath']; - ENVS["smallmatrix"] = ['ExtensionEnv',null,'AMSmath']; - ENVS["equation"] = ['ExtensionEnv',null,'AMSmath']; - ENVS["equation*"] = ['ExtensionEnv',null,'AMSmath']; + for (name in ENVIRONMENTS) {if (ENVIRONMENTS.hasOwnProperty(name)) { + if (!MathJax.Extension["TeX/"+name]) { + var envs = ENVIRONMENTS[name]; + for (i = 0, m = envs.length; i < m; i++) + {defs.environment[envs[i]] = ["ExtensionEnv",null,name]} + } + }} + + MathJax.InputJax.TeX.Definitions.Add(defs); MathJax.Hub.Startup.signal.Post("TeX autoload-all Ready"); diff --git a/resources/viewer/mathjax/extensions/TeX/bbox.js b/resources/viewer/mathjax/extensions/TeX/bbox.js index 6bea56e82b..04d6da9036 100644 --- a/resources/viewer/mathjax/extensions/TeX/bbox.js +++ b/resources/viewer/mathjax/extensions/TeX/bbox.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/bbox.js @@ -27,7 +30,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -43,36 +46,43 @@ */ MathJax.Extension["TeX/bbox"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var TEX = MathJax.InputJax.TeX, MML = MathJax.ElementJax.mml; - - TEX.Definitions.macros.bbox = "BBox"; + + TEX.Definitions.Add({macros: {bbox: "BBox"}},null,true); TEX.Parse.Augment({ BBox: function (name) { var bbox = this.GetBrackets(name,""), math = this.ParseArg(name); var parts = bbox.split(/,/), def, background, style; - for (var i in parts) { + for (var i = 0, m = parts.length; i < m; i++) { var part = parts[i].replace(/^\s+/,'').replace(/\s+$/,''); var match = part.match(/^(\.\d+|\d+(\.\d*)?)(pt|em|ex|mu|px|in|cm|mm)$/); if (match) { + if (def) + {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2","Padding",name])} var pad = match[1]+match[3]; - if (def) {TEX.Error("Padding specified twice in "+name)} def = {height:"+"+pad, depth:"+"+pad, lspace:pad, width:"+"+(2*match[1])+match[3]}; } else if (part.match(/^([a-z0-9]+|\#[0-9a-f]{6}|\#[0-9a-f]{3})$/i)) { - if (background) {TEX.Error("Background specified twice in "+name)} + if (background) + {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2","Background",name])} background = part; } else if (part.match(/^[-a-z]+:/i)) { - if (style) {TEX.Error("Style specified twice in "+name)} - style = part; + if (style) + {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2", "Style",name])} + style = this.BBoxStyle(part); } else if (part !== "") { - TEX.Error("'"+part+"' doesn't look like a color, a padding dimension, or a style"); + TEX.Error( + ["InvalidBBoxProperty", + "'%1' doesn't look like a color, a padding dimension, or a style", + part] + ); } } if (def) {math = MML.mpadded(math).With(def)} @@ -80,7 +90,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { math = MML.mstyle(math).With({mathbackground:background, style:style}); } this.Push(math); - } + }, + BBoxStyle: function (styles) {return styles} }); MathJax.Hub.Startup.signal.Post("TeX bbox Ready"); diff --git a/resources/viewer/mathjax/extensions/TeX/begingroup.js b/resources/viewer/mathjax/extensions/TeX/begingroup.js index 5c542a16b1..53fc89c7ab 100644 --- a/resources/viewer/mathjax/extensions/TeX/begingroup.js +++ b/resources/viewer/mathjax/extensions/TeX/begingroup.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/begingroup.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -23,7 +26,7 @@ */ MathJax.Extension["TeX/begingroup"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -100,7 +103,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // Init: function (eqn) { this.isEqn = eqn; this.stack = []; - if (!eqn) {this.Push(NSFRAME(TEXDEF.macros,TEXDEF.environments))} + if (!eqn) {this.Push(NSFRAME(TEXDEF.macros,TEXDEF.environment))} else {this.Push(NSFRAME())} }, // @@ -186,10 +189,14 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // // Define the new macros // - TEXDEF.macros.begingroup = "BeginGroup"; - TEXDEF.macros.endgroup = "EndGroup"; - TEXDEF.macros.global = ["Extension","newcommand"]; - TEXDEF.macros.gdef = ["Extension","newcommand"]; + TEXDEF.Add({ + macros: { + begingroup: "BeginGroup", + endgroup: "EndGroup", + global: ["Extension","newcommand"], + gdef: ["Extension","newcommand"] + } + },null,true); TEX.Parse.Augment({ // @@ -209,7 +216,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { if (TEX.eqnStack.top > 1) { TEX.eqnStack.Pop(); } else if (TEX.rootStack.top === 1) { - TEX.Error("Extra "+name+" or missing \\begingroup"); + TEX.Error(["ExtraEndMissingBegin","Extra %1 or missing \\begingroup",name]); } else { TEX.eqnStack.Clear(); TEX.rootStack.Pop(); @@ -257,8 +264,12 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // // Add the commands that depend on the newcommand code // - TEXDEF.macros.global = "Global"; - TEXDEF.macros.gdef = ["Macro","\\global\\def"]; + TEXDEF.Add({ + macros: { + global: "Global", + gdef: ["Macro","\\global\\def"] + } + },null,true); TEX.Parse.Augment({ // @@ -280,8 +291,10 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // Global: function (name) { var i = this.i; var cs = this.GetCSname(name); this.i = i; - if (cs !== "let" && cs !== "def" && cs !== "newcommand") - {TEX.Error(name+" not followed by \\let, \\def, or \\newcommand")} + if (cs !== "let" && cs !== "def" && cs !== "newcommand") { + TEX.Error(["GlobalNotFollowedBy", + "%1 not followed by \\let, \\def, or \\newcommand",name]); + } this.stack.env.isGlobal = true; } diff --git a/resources/viewer/mathjax/extensions/TeX/boldsymbol.js b/resources/viewer/mathjax/extensions/TeX/boldsymbol.js index cf42cd3124..6f04536d55 100644 --- a/resources/viewer/mathjax/extensions/TeX/boldsymbol.js +++ b/resources/viewer/mathjax/extensions/TeX/boldsymbol.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/boldsymbol.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -23,7 +26,7 @@ */ MathJax.Extension["TeX/boldsymbol"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -41,7 +44,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { BOLDVARIANT["-tex-caligraphic"] = "-tex-caligraphic-bold"; BOLDVARIANT["-tex-oldstyle"] = "-tex-oldstyle-bold"; - TEXDEF.macros.boldsymbol = 'Boldsymbol'; + TEXDEF.Add({macros: {boldsymbol: 'Boldsymbol'}},null,true); TEX.Parse.Augment({ mmlToken: function (token) { @@ -69,58 +72,4 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }); -MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { - var HTMLCSS = MathJax.OutputJax["HTML-CSS"]; - var FONTS = HTMLCSS.FONTDATA.FONTS; - var VARIANT = HTMLCSS.FONTDATA.VARIANT; - - if (HTMLCSS.fontInUse === "TeX") { - FONTS["MathJax_Caligraphic-bold"] = "Caligraphic/Bold/Main.js"; - - VARIANT["-tex-caligraphic-bold"] = - {fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"], - offsetA: 0x41, variantA: "bold-italic"}; - VARIANT["-tex-oldstyle-bold"] = - {fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"]}; - - if (HTMLCSS.msieCheckGreek && HTMLCSS.Font.testFont({ - family:"MathJax_Greek", weight:"bold", style:"italic", testString: HTMLCSS.msieCheckGreek - })) { - VARIANT["bold-italic"].offsetG = 0x391; VARIANT["bold-italic"].variantG = "-Greek-Bold-Italic"; - VARIANT["-Greek-Bold-Italic"] = {fonts:["MathJax_Greek-bold-italic"]}; - FONTS["MathJax_Greek-bold-italic"] = "Greek/BoldItalic/Main.js"; - } - - if (MathJax.Hub.Browser.isChrome && !MathJax.Hub.Browser.versionAtLeast("5.0")) { - VARIANT["-tex-caligraphic-bold"].remap = {0x54: [0xE2F0,"-WinChrome"]}; - } - - } else if (HTMLCSS.fontInUse === "STIX") { - VARIANT["-tex-caligraphic-bold"] = { - fonts:["STIXGeneral-bold-italic","STIXNonUnicode-bold-italic","STIXNonUnicode","STIXGeneral","STIXSizeOneSym"], - offsetA: 0xE247, noLowerCase: 1 - }; - VARIANT["-tex-oldstyle-bold"] = { - fonts:["STIXGeneral-bold","STIXNonUnicode-bold","STIXGeneral","STIXSizeOneSym"], offsetN: 0xE263, - remap: {0xE264: 0xE267, 0xE265: 0xE26B, 0xE266: 0xE26F, 0xE267: 0xE273, - 0xE268: 0xE277, 0xE269: 0xE27B, 0xE26A: 0xE27F, 0xE26B: 0xE283, - 0xE26C: 0xE287} - }; - } -}); - -MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var SVG = MathJax.OutputJax.SVG; - var FONTS = SVG.FONTDATA.FONTS; - var VARIANT = SVG.FONTDATA.VARIANT; - - FONTS["MathJax_Caligraphic-bold"] = "Caligraphic/Bold/Main.js"; - - VARIANT["-tex-caligraphic-bold"] = - {fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"], - offsetA: 0x41, variantA: "bold-italic"}; - VARIANT["-tex-oldstyle-bold"] = - {fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"]}; -}); - MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/boldsymbol.js"); diff --git a/resources/viewer/mathjax/extensions/TeX/cancel.js b/resources/viewer/mathjax/extensions/TeX/cancel.js index 4731f8c994..0e075c910c 100644 --- a/resources/viewer/mathjax/extensions/TeX/cancel.js +++ b/resources/viewer/mathjax/extensions/TeX/cancel.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/cancel.js @@ -13,7 +16,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -29,13 +32,12 @@ */ MathJax.Extension["TeX/cancel"] = { - version: "2.0", + version: "2.6.0", // // The attributes allowed in \enclose{notation}[attributes]{math} // ALLOWED: { - arrow: 1, color: 1, mathcolor: 1, background: 1, mathbackground: 1, padding: 1, @@ -45,7 +47,6 @@ MathJax.Extension["TeX/cancel"] = { MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var TEX = MathJax.InputJax.TeX, - MACROS = TEX.Definitions.macros, MML = MathJax.ElementJax.mml, CANCEL = MathJax.Extension["TeX/cancel"]; @@ -65,12 +66,16 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }; // - // Set up macro + // Set up macros // - MACROS.cancel = ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE]; - MACROS.bcancel = ['Cancel',MML.NOTATION.DOWNDIAGONALSTRIKE]; - MACROS.xcancel = ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE+" "+MML.NOTATION.DOWNDIAGONALSTRIKE]; - MACROS.cancelto = 'CancelTo'; + TEX.Definitions.Add({ + macros: { + cancel: ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE], + bcancel: ['Cancel',MML.NOTATION.DOWNDIAGONALSTRIKE], + xcancel: ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE+" "+MML.NOTATION.DOWNDIAGONALSTRIKE], + cancelto: 'CancelTo' + } + },null,true); TEX.Parse.Augment({ // @@ -91,7 +96,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var value = this.ParseArg(name), attr = this.GetBrackets(name,""), math = this.ParseArg(name); - var def = CANCEL.setAttributes({notation: MML.NOTATION.UPDIAGONALSTRIKE, arrow:true},attr); + var def = CANCEL.setAttributes({notation: MML.NOTATION.UPDIAGONALSTRIKE+" "+MML.NOTATION.UPDIAGONALARROW},attr); value = MML.mpadded(value).With({depth:"-.1em",height:"+.1em",voffset:".1em"}); this.Push(MML.msup(MML.menclose(math).With(def),value)); } diff --git a/resources/viewer/mathjax/extensions/TeX/color.js b/resources/viewer/mathjax/extensions/TeX/color.js index 0945f37c93..2e75d105a3 100644 --- a/resources/viewer/mathjax/extensions/TeX/color.js +++ b/resources/viewer/mathjax/extensions/TeX/color.js @@ -1,14 +1,18 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/color.js * - * Implements LaTeX-compatible \color macro rather than MathJax's - * original (non-standard) version. It includes the rgb, gray, and - * named color models, and the \definecolor macro. + * Implements LaTeX-compatible \color macro rather than MathJax's original + * (non-standard) version. It includes the rgb, RGB, gray, and named color + * models, and the \textcolor, \definecolor, \colorbox, and \fcolorbox + * macros. * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -27,7 +31,7 @@ // The configuration defaults, augmented by the user settings // MathJax.Extension["TeX/color"] = { - version: "2.0", + version: "2.6.0", config: MathJax.Hub.CombineConfig("TeX.color",{ padding: "5px", @@ -111,21 +115,49 @@ MathJax.Extension["TeX/color"] = { getColor: function (model,def) { if (!model) {model = "named"} var fn = this["get_"+model]; - if (!fn) {this.TEX.Error("Color model '"+model+"' not defined")} + if (!fn) {this.TEX.Error(["UndefinedColorModel","Color model '%1' not defined",model])} return fn.call(this,def); }, + /* + * Get an rgb color + */ + get_rgb: function (rgb) { + rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#"; + if (rgb.length !== 3) + {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","rgb"])} + for (var i = 0; i < 3; i++) { + if (!rgb[i].match(/^(\d+(\.\d*)?|\.\d+)$/)) + {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])} + var n = parseFloat(rgb[i]); + if (n < 0 || n > 1) { + this.TEX.Error(["ModelArg2", + "Color values for the %1 model must be between %2 and %3", + "rgb",0,1]); + } + n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n} + RGB += n; + } + return RGB; + }, + /* * Get an RGB color */ - get_rgb: function (rgb) { - rgb = rgb.split(/,/); var RGB = "#"; - if (rgb.length !== 3) {this.TEX.Error("RGB colors require 3 decimal numbers")} + get_RGB: function (rgb) { + rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#"; + if (rgb.length !== 3) + {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","RGB"])} for (var i = 0; i < 3; i++) { - if (!rgb[i].match(/^(\d+(\.\d*)?|\.\d+)$/)) {this.TEX.Error("Invalid decimal number")} - var n = parseFloat(rgb[i]); - if (n < 0 || n > 1) {this.TEX.Error("RGB values must be between 0 and 1")} - n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n} + if (!rgb[i].match(/^\d+$/)) + {this.TEX.Error(["InvalidNumber","Invalid number"])} + var n = parseInt(rgb[i]); + if (n > 255) { + this.TEX.Error(["ModelArg2", + "Color values for the %1 model must be between %2 and %3", + "RGB",0,255]); + } + n = n.toString(16); if (n.length < 2) {n = "0"+n} RGB += n; } return RGB; @@ -135,9 +167,14 @@ MathJax.Extension["TeX/color"] = { * Get a gray-scale value */ get_gray: function (gray) { - if (!gray.match(/^(\d+(\.\d*)?|\.\d+)$/)) {this.TEX.Error("Invalid decimal number")} + if (!gray.match(/^\s*(\d+(\.\d*)?|\.\d+)\s*$/)) + {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])} var n = parseFloat(gray); - if (n < 0 || n > 1) {this.TEX.Error("Grey-scale values must be between 0 and 1")} + if (n < 0 || n > 1) { + this.TEX.Error(["ModelArg2", + "Color values for the %1 model must be between %2 and %3", + "gray",0,1]); + } n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n} return "#"+n+n+n; }, @@ -166,11 +203,16 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var COLOR = MathJax.Extension["TeX/color"]; COLOR.TEX = TEX; // for reference in getColor above - - TEX.Definitions.macros.color = "Color"; - TEX.Definitions.macros.definecolor = "DefineColor"; - TEX.Definitions.macros.colorbox = "ColorBox"; - TEX.Definitions.macros.fcolorbox = "fColorBox"; + + TEX.Definitions.Add({ + macros: { + color: "Color", + textcolor: "TextColor", + definecolor: "DefineColor", + colorbox: "ColorBox", + fcolorbox: "fColorBox" + } + },null,true); TEX.Parse.Augment({ @@ -185,6 +227,16 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { this.stack.env.color = color; this.Push(mml); }, + + TextColor: function (name) { + var model = this.GetBrackets(name), + color = this.GetArgument(name); + color = COLOR.getColor(model,color); + var old = this.stack.env.color; this.stack.env.color = color; + var math = this.ParseArg(name); + if (old) {this.stack.env.color} else {delete this.stack.env.color} + this.Push(MML.mstyle(math).With({mathcolor: color})); + }, // // Define the \definecolor macro diff --git a/resources/viewer/mathjax/extensions/TeX/enclose.js b/resources/viewer/mathjax/extensions/TeX/enclose.js index 7eff9576c7..0f4858ec9d 100644 --- a/resources/viewer/mathjax/extensions/TeX/enclose.js +++ b/resources/viewer/mathjax/extensions/TeX/enclose.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/enclose.js @@ -13,7 +16,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -29,7 +32,7 @@ */ MathJax.Extension["TeX/enclose"] = { - version: "2.0", + version: "2.6.0", // // The attributes allowed in \enclose{notation}[attributes]{math} @@ -51,7 +54,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // // Set up macro // - TEX.Definitions.macros.enclose = 'Enclose'; + TEX.Definitions.Add({macros: {enclose: 'Enclose'}},null,true); TEX.Parse.Augment({ // @@ -71,7 +74,9 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { keyvalue[1] = keyvalue[1].replace(/^"(.*)"$/,"$1"); if (keyvalue[1] === "true") {keyvalue[1] = true} if (keyvalue[1] === "false") {keyvalue[1] = false} - def[keyvalue[0]] = keyvalue[1]; + if (keyvalue[0] === "arrow" && keyvalue[1]) + {def.notation = def.notation + " updiagonalarrow"} else + {def[keyvalue[0]] = keyvalue[1]} } } } diff --git a/resources/viewer/mathjax/extensions/TeX/extpfeil.js b/resources/viewer/mathjax/extensions/TeX/extpfeil.js index 5b1c3f5d2f..0add437f2f 100644 --- a/resources/viewer/mathjax/extensions/TeX/extpfeil.js +++ b/resources/viewer/mathjax/extensions/TeX/extpfeil.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/extpfeil.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Extension["TeX/extpfeil"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -34,7 +37,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // Define the arrows to load the AMSmath extension // (since they need its xArrow method) // - MathJax.Hub.Insert(TEXDEF,{ + TEXDEF.Add({ macros: { xtwoheadrightarrow: ['Extension','AMSmath'], xtwoheadleftarrow: ['Extension','AMSmath'], @@ -43,7 +46,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { xtofrom: ['Extension','AMSmath'], Newextarrow: ['Extension','AMSmath'] } - }); + },null,true); // // Redefine the macros when AMSmath is loaded @@ -70,12 +73,24 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var cs = this.GetArgument(name), space = this.GetArgument(name), chr = this.GetArgument(name); - if (!cs.match(/^\\([a-z]+|.)$/i)) - {TEX.Error("First argument to "+name+" must be a control sequence name")} - if (!space.match(/^(\d+),(\d+)$/)) - {TEX.Error("Second argument to "+name+" must be two integers separated by a comma")} - if (!chr.match(/^(\d+|0x[0-9A-F]+)$/i)) - {TEX.Error("Third argument to "+name+" must be a unicode character number")} + if (!cs.match(/^\\([a-z]+|.)$/i)) { + TEX.Error(["NewextarrowArg1", + "First argument to %1 must be a control sequence name",name]); + } + if (!space.match(/^(\d+),(\d+)$/)) { + TEX.Error( + ["NewextarrowArg2", + "Second argument to %1 must be two integers separated by a comma", + name] + ); + } + if (!chr.match(/^(\d+|0x[0-9A-F]+)$/i)) { + TEX.Error( + ["NewextarrowArg3", + "Third argument to %1 must be a unicode character number", + name] + ); + } cs = cs.substr(1); space = space.split(","); chr = parseInt(chr); TEXDEF.macros[cs] = ['xArrow',chr,parseInt(space[0]),parseInt(space[1])]; } diff --git a/resources/viewer/mathjax/extensions/TeX/mathchoice.js b/resources/viewer/mathjax/extensions/TeX/mathchoice.js index da4e35502f..e122d06d5d 100644 --- a/resources/viewer/mathjax/extensions/TeX/mathchoice.js +++ b/resources/viewer/mathjax/extensions/TeX/mathchoice.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/mathchoice.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -22,16 +25,15 @@ */ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml; var TEX = MathJax.InputJax.TeX; var TEXDEF = TEX.Definitions; - TEXDEF.macros.mathchoice = 'MathChoice'; + TEXDEF.Add({macros: {mathchoice: 'MathChoice'}},null,true); TEX.Parse.Augment({ - MathChoice: function (name) { var D = this.ParseArg(name), T = this.ParseArg(name), @@ -39,20 +41,29 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { SS = this.ParseArg(name); this.Push(MML.TeXmathchoice(D,T,S,SS)); } - }); MML.TeXmathchoice = MML.mbase.Subclass({ - type: "TeXmathchoice", + type: "TeXmathchoice", notParent: true, choice: function () { - var values = this.getValues("displaystyle","scriptlevel"); - if (values.scriptlevel > 0) {return Math.min(3,values.scriptlevel + 1)} - return (values.displaystyle ? 0 : 1); + if (this.selection != null) return this.selection; + if (this.choosing) return 2; // prevent infinite loops: see issue #1151 + this.choosing = true; + var selection = 0, values = this.getValues("displaystyle","scriptlevel"); + if (values.scriptlevel > 0) {selection = Math.min(3,values.scriptlevel+1)} + else {selection = (values.displaystyle ? 0 : 1)} + // only cache the result if we are actually in place in a tag. + var node = this.inherit; while (node && node.type !== "math") node = node.inherit; + if (node) this.selection = selection; + this.choosing = false; + return selection; }, - setTeXclass: function (prev) {return this.Core().setTeXclass(prev)}, - isSpacelike: function () {return this.Core().isSpacelike()}, - isEmbellished: function () {return this.Core().isEmbellished()}, - Core: function () {return this.data[this.choice()]}, + selected: function () {return this.data[this.choice()]}, + setTeXclass: function (prev) {return this.selected().setTeXclass(prev)}, + isSpacelike: function () {return this.selected().isSpacelike()}, + isEmbellished: function () {return this.selected().isEmbellished()}, + Core: function () {return this.selected()}, + CoreMO: function () {return this.selected().CoreMO()}, toHTML: function (span) { span = this.HTMLcreateSpan(span); span.bbox = this.Core().toHTML(span).bbox; @@ -68,7 +79,25 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { } return span; }, - toSVG: function () {return this.Core().toSVG()} + toSVG: function () { + var svg = this.Core().toSVG(); + this.SVGsaveData(svg); + return svg; + }, + toCommonHTML: function (node) { + node = this.CHTMLcreateNode(node); + this.CHTMLhandleStyle(node); + this.CHTMLhandleColor(node); + this.CHTMLaddChild(node,this.choice(),{}); + return node; + }, + toPreviewHTML: function(span) { + span = this.PHTMLcreateSpan(span); + this.PHTMLhandleStyle(span); + this.PHTMLhandleColor(span); + this.PHTMLaddChild(span,this.choice(),{}); + return span; + } }); MathJax.Hub.Startup.signal.Post("TeX mathchoice Ready"); diff --git a/resources/viewer/mathjax/extensions/TeX/mediawiki-texvc.js b/resources/viewer/mathjax/extensions/TeX/mediawiki-texvc.js new file mode 100644 index 0000000000..e43351f2a6 --- /dev/null +++ b/resources/viewer/mathjax/extensions/TeX/mediawiki-texvc.js @@ -0,0 +1,106 @@ +MathJax.Extension["TeX/mediawiki-texvc"] = { + version: "2.6.0-beta.2" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () { + MathJax.InputJax.TeX.Definitions.Add({ + macros: { + AA: ["Macro", "\u00c5"], + alef: ["Macro", "\\aleph"], + alefsym: ["Macro", "\\aleph"], + Alpha: ["Macro", "\\mathrm{A}"], + and: ["Macro", "\\land"], + ang: ["Macro", "\\angle"], + Bbb: ["Macro", "\\mathbb"], + Beta: ["Macro", "\\mathrm{B}"], + bold: ["Macro", "\\mathbf"], + bull: ["Macro", "\\bullet"], + C: ["Macro", "\\mathbb{C}"], + Chi: ["Macro", "\\mathrm{X}"], + clubs: ["Macro", "\\clubsuit"], + cnums: ["Macro", "\\mathbb{C}"], + Complex: ["Macro", "\\mathbb{C}"], + coppa: ["Macro", "\u03D9"], + Coppa: ["Macro", "\u03D8"], + Dagger: ["Macro", "\\ddagger"], + Digamma: ["Macro", "\u03DC"], + darr: ["Macro", "\\downarrow"], + dArr: ["Macro", "\\Downarrow"], + Darr: ["Macro", "\\Downarrow"], + diamonds: ["Macro", "\\diamondsuit"], + empty: ["Macro", "\\emptyset"], + Epsilon: ["Macro", "\\mathrm{E}"], + Eta: ["Macro", "\\mathrm{H}"], + euro: ["Macro", "\u20AC"], + exist: ["Macro", "\\exists"], + geneuro: ["Macro", "\u20AC"], + geneuronarrow: ["Macro", "\u20AC"], + geneurowide: ["Macro", "\u20AC"], + H: ["Macro", "\\mathbb{H}"], + hAar: ["Macro", "\\Leftrightarrow"], + harr: ["Macro", "\\leftrightarrow"], + Harr: ["Macro", "\\Leftrightarrow"], + hearts: ["Macro", "\\heartsuit"], + image: ["Macro", "\\Im"], + infin: ["Macro", "\\infty"], + Iota: ["Macro", "\\mathrm{I}"], + isin: ["Macro", "\\in"], + Kappa: ["Macro", "\\mathrm{K}"], + koppa: ["Macro", "\u03DF"], + Koppa: ["Macro", "\u03DE"], + lang: ["Macro", "\\langle"], + larr: ["Macro", "\\leftarrow"], + Larr: ["Macro", "\\Leftarrow"], + lArr: ["Macro", "\\Leftarrow"], + lrarr: ["Macro", "\\leftrightarrow"], + Lrarr: ["Macro", "\\Leftrightarrow"], + lrArr: ["Macro", "\\Leftrightarrow"], + Mu: ["Macro", "\\mathrm{M}"], + N: ["Macro", "\\mathbb{N}"], + natnums: ["Macro", "\\mathbb{N}"], + Nu: ["Macro", "\\mathrm{N}"], + O: ["Macro", "\\emptyset"], + officialeuro: ["Macro", "\u20AC"], + Omicron: ["Macro", "\\mathrm{O}"], + or: ["Macro", "\\lor"], + P: ["Macro", "\u00B6"], + pagecolor: ['Macro','',1], // ignore \pagecolor{} + part: ["Macro", "\\partial"], + plusmn: ["Macro", "\\pm"], + Q: ["Macro", "\\mathbb{Q}"], + R: ["Macro", "\\mathbb{R}"], + rang: ["Macro", "\\rangle"], + rarr: ["Macro", "\\rightarrow"], + Rarr: ["Macro", "\\Rightarrow"], + rArr: ["Macro", "\\Rightarrow"], + real: ["Macro", "\\Re"], + reals: ["Macro", "\\mathbb{R}"], + Reals: ["Macro", "\\mathbb{R}"], + Rho: ["Macro", "\\mathrm{P}"], + sdot: ["Macro", "\\cdot"], + sampi: ["Macro", "\u03E1"], + Sampi: ["Macro", "\u03E0"], + sect: ["Macro", "\\S"], + spades: ["Macro", "\\spadesuit"], + stigma: ["Macro", "\u03DB"], + Stigma: ["Macro", "\u03DA"], + sub: ["Macro", "\\subset"], + sube: ["Macro", "\\subseteq"], + supe: ["Macro", "\\supseteq"], + Tau: ["Macro", "\\mathrm{T}"], + textvisiblespace: ["Macro", "\u2423"], + thetasym: ["Macro", "\\vartheta"], + uarr: ["Macro", "\\uparrow"], + uArr: ["Macro", "\\Uparrow"], + Uarr: ["Macro", "\\Uparrow"], + varcoppa: ["Macro", "\u03D9"], + varstigma: ["Macro", "\u03DB"], + vline: ['Macro','\\smash{\\large\\lvert}',0], + weierp: ["Macro", "\\wp"], + Z: ["Macro", "\\mathbb{Z}"], + Zeta: ["Macro", "\\mathrm{Z}"] + } + }); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mediawiki-texvc.js"); diff --git a/resources/viewer/mathjax/extensions/TeX/mhchem.js b/resources/viewer/mathjax/extensions/TeX/mhchem.js index 5326885f04..3e08a1d5ac 100644 --- a/resources/viewer/mathjax/extensions/TeX/mhchem.js +++ b/resources/viewer/mathjax/extensions/TeX/mhchem.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/mhchem.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -23,13 +26,12 @@ */ MathJax.Extension["TeX/mhchem"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { - var TEX = MathJax.InputJax.TeX, - MACROS = TEX.Definitions.macros; + var TEX = MathJax.InputJax.TeX; /* * This is the main class for handing the \ce and related commands. @@ -40,10 +42,13 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var CE = MathJax.Object.Subclass({ string: "", // the \ce string being parsed i: 0, // the current position in the string - tex: "", // the processed TeX result + tex: "", // the partially processed TeX result + TEX: "", // the full TeX result atom: false, // last processed token is an atom sup: "", // pending superscript sub: "", // pending subscript + presup: "", // pending pre-superscript + presub: "", // pending pre-subscript // // Store the string when a CE object is created @@ -81,6 +86,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { '<->': "leftrightarrow", '<=>': "rightleftharpoons", '<=>>': "Rightleftharpoons", + '<<=>': "Leftrightharpoons", '^': "uparrow", 'v': "downarrow" }, @@ -118,8 +124,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { else if (c.match(/[0-9]/)) {this.ParseNumber()} else {this["Parse"+(this.ParseTable[c]||"Other")](c)} } - this.FinishAtom(); - return this.tex; + this.FinishAtom(true); + return this.TEX; }, // @@ -136,7 +142,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { }, // - // Make a number of fraction preceeding an atom, + // Make a number or fraction preceeding an atom, // or a subscript for an atom. // ParseNumber: function () { @@ -204,7 +210,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // ParseLess: function (c) { this.FinishAtom(); - var arrow = this.Match(/^(<->?|<=>>?)/); + var arrow = this.Match(/^(<->?|<=>>?|<<=>)/); if (!arrow) {this.tex += c; this.i++} else {this.AddArrow(arrow)} }, @@ -215,7 +221,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { c = this.string.charAt(++this.i); if (c === "{") { this.i++; var m = this.Find("}"); - if (m === "-.") {this.sup += "{-}{\\cdot}"} else if (m) {this.sup += CE(m).Parse()} + if (m === "-.") {this.sup += "{-}{\\cdot}"} + else if (m) {this.sup += CE(m).Parse().replace(/^\{-\}/,"-")} } else if (c === " " || c === "") { this.tex += "{\\"+this.Arrows["^"]+"}"; this.i++; } else { @@ -228,7 +235,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // ParseSubscript: function (c) { if (this.string.charAt(++this.i) == "{") { - this.i++; this.sub += CE(this.Find("}")).Parse(); + this.i++; this.sub += CE(this.Find("}")).Parse().replace(/^\{-\}/,"-"); } else { var n = this.Match(/^\d+/); if (n) {this.sub += n} @@ -294,23 +301,34 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // // Handle the super and subscripts for an atom // - FinishAtom: function () { - if (this.sup || this.sub) { - if (this.sup && this.sub && !this.atom) { - // - // right-justify super- and subscripts when they are before the atom - // - var n = Math.abs(this.sup.length-this.sub.length); - if (n) { - var zeros = "0000000000".substr(0,n); - var script = (this.sup.length > this.sub.length ? "sub" : "sup"); - this[script] = "\\phantom{"+zeros+"}" + this[script]; + FinishAtom: function (force) { + if (this.sup || this.sub || this.presup || this.presub) { + if (!force && !this.atom) { + if (this.tex === "" && !this.sup && !this.sub) return; + if (!this.presup && !this.presub && + (this.tex === "" || this.tex === "{" || + (this.tex === "}" && this.TEX.substr(-1) === "{"))) { + this.presup = this.sup, this.presub = this.sub; // save for later + this.sub = this.sup = ""; + this.TEX += this.tex; this.tex = ""; + return; } } - if (!this.sup) {this.sup = "\\Space{0pt}{0pt}{.2em}"} // forces subscripts to align properly - this.tex += "^{"+this.sup+"}_{"+this.sub+"}"; + if (this.sub && !this.sup) {this.sup = "\\Space{0pt}{0pt}{.2em}"} // forces subscripts to align properly + if ((this.presup || this.presub) && this.tex !== "{") { + if (!this.presup && !this.sup) {this.presup = "\\Space{0pt}{0pt}{.2em}"} + this.tex = "\\CEprescripts{"+(this.presub||"\\CEnone")+"}{"+(this.presup||"\\CEnone")+"}" + + "{"+(this.tex !== "}" ? this.tex : "")+"}" + + "{"+(this.sub||"\\CEnone")+"}{"+(this.sup||"\\CEnone")+"}" + + (this.tex === "}" ? "}" : ""); + this.presub = this.presup = ""; + } else { + if (this.sup) this.tex += "^{"+this.sup+"}"; + if (this.sub) this.tex += "_{"+this.sub+"}"; + } this.sup = this.sub = ""; } + this.TEX += this.tex; this.tex = ""; this.atom = false; }, @@ -349,46 +367,93 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { if (C === "{") {braces++} else if (C === "}") { if (braces) {braces--} - else {TEX.Error("Extra close brace or missing open brace")} + else { + TEX.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"]) + } } } - if (braces) {TEX.Error("Missing close brace")}; - TEX.Error("Can't find closing "+c); + if (braces) {TEX.Error(["MissingCloseBrace","Missing close brace"])} + TEX.Error(["NoClosingChar","Can't find closing %1",c]); } }); + MathJax.Extension["TeX/mhchem"].CE = CE; /***************************************************************************/ - // - // Set up the macros for chemistry - // - MACROS.ce = 'CE'; - MACROS.cf = 'CE'; - MACROS.cee = 'CE'; + TEX.Definitions.Add({ + macros: { + // + // Set up the macros for chemistry + // + ce: 'CE', + cf: 'CE', + cee: 'CE', + + // + // Make these load AMSmath package (redefined below when loaded) + // + xleftrightarrow: ['Extension','AMSmath'], + xrightleftharpoons: ['Extension','AMSmath'], + xRightleftharpoons: ['Extension','AMSmath'], + xLeftrightharpoons: ['Extension','AMSmath'], + + // FIXME: These don't work well in FF NativeMML mode + longrightleftharpoons: ["Macro","\\stackrel{\\textstyle{{-}\\!\\!{\\rightharpoonup}}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"], + longRightleftharpoons: ["Macro","\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\small\\smash\\leftharpoondown}"], + longLeftrightharpoons: ["Macro","\\stackrel{\\rightharpoonup}{{{\\leftharpoondown}\\!\\!\\textstyle{-}}}"], + + // + // Add \hyphen used in some mhchem examples + // + hyphen: ["Macro","\\text{-}"], + + // + // Handle prescripts and none + // + CEprescripts: "CEprescripts", + CEnone: "CEnone", + + // + // Needed for \bond for the ~ forms + // + tripledash: ["Macro","\\raise3mu{\\tiny\\text{-}\\kern2mu\\text{-}\\kern2mu\\text{-}}"] + }, + + // + // Needed for \bond for the ~ forms + // + environment: { + CEstack: ['Array',null,null,null,'r',null,"0.001em",'T',1] + } + },null,true); + + if (!MathJax.Extension["TeX/AMSmath"]) { + TEX.Definitions.Add({ + macros: { + xrightarrow: ['Extension','AMSmath'], + xleftarrow: ['Extension','AMSmath'] + } + },null,true); + } // - // Include some missing arrows (some are hacks) + // These arrows need to wait until AMSmath is loaded // - MACROS.xleftrightarrow = ['xArrow',0x2194,6,6]; - MACROS.xrightleftharpoons = ['xArrow',0x21CC,5,7]; // FIXME: doesn't stretch in HTML-CSS output - MACROS.xRightleftharpoons = ['xArrow',0x21CC,5,7]; // FIXME: how should this be handled? - - // FIXME: These don't work well in FF NativeMML mode - MACROS.longrightleftharpoons = ["Macro","\\stackrel{\\textstyle{{-}\\!\\!{\\rightharpoonup}}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"]; - MACROS.longRightleftharpoons = ["Macro","\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\small\\smash\\leftharpoondown}"]; - - // - // Needed for \bond for the ~ forms - // - MACROS.tripledash = ["Macro","\\raise3mu{\\tiny\\text{-}\\kern2mu\\text{-}\\kern2mu\\text{-}}"]; - TEX.Definitions.environment.CEstack = ['Array',null,null,null,'r',null,"0.001em",'T',1] - - // - // Add \hyphen used in some mhchem examples - // - MACROS.hyphen = ["Macro","\\text{-}"]; + MathJax.Hub.Register.StartupHook("TeX AMSmath Ready",function () { + TEX.Definitions.Add({ + macros: { + // + // Some of these are hacks for now + // + xleftrightarrow: ['xArrow',0x2194,6,6], + xrightleftharpoons: ['xArrow',0x21CC,5,7], // FIXME: doesn't stretch in HTML-CSS output + xRightleftharpoons: ['xArrow',0x21CC,5,7], // FIXME: how should this be handled? + xLeftrightharpoons: ['xArrow',0x21CC,5,7] + } + },null,true); + }); TEX.Parse.Augment({ @@ -399,6 +464,22 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var arg = this.GetArgument(name); var tex = CE(arg).Parse(); this.string = tex + this.string.substr(this.i); this.i = 0; + }, + + // + // Implements \CEprescripts{presub}{presup}{base}{sub}{sup} + // + CEprescripts: function (name) { + var presub = this.ParseArg(name), + presup = this.ParseArg(name), + base = this.ParseArg(name), + sub = this.ParseArg(name), + sup = this.ParseArg(name); + var MML = MathJax.ElementJax.mml; + this.Push(MML.mmultiscripts(base,sub,sup,MML.mprescripts(),presub,presup)); + }, + CEnone: function (name) { + this.Push(MathJax.ElementJax.mml.none()); } }); diff --git a/resources/viewer/mathjax/extensions/TeX/newcommand.js b/resources/viewer/mathjax/extensions/TeX/newcommand.js index 266f4eb6f5..69eab28231 100644 --- a/resources/viewer/mathjax/extensions/TeX/newcommand.js +++ b/resources/viewer/mathjax/extensions/TeX/newcommand.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/newcommand.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -23,7 +26,7 @@ */ MathJax.Extension["TeX/newcommand"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -45,7 +48,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { TEX.Parse.Augment({ /* - * Implement \newcommand{\name}[n]{...} + * Implement \newcommand{\name}[n][default]{...} */ NewCommand: function (name) { var cs = this.trimSpaces(this.GetArgument(name)), @@ -53,10 +56,16 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { opt = this.GetBrackets(name), def = this.GetArgument(name); if (cs.charAt(0) === "\\") {cs = cs.substr(1)} - if (!cs.match(/^(.|[a-z]+)$/i)) {TEX.Error("Illegal control sequence name for "+name)} + if (!cs.match(/^(.|[a-z]+)$/i)) { + TEX.Error(["IllegalControlSequenceName", + "Illegal control sequence name for %1",name]); + } if (n) { n = this.trimSpaces(n); - if (!n.match(/^[0-9]+$/)) {TEX.Error("Illegal number of parameters specified in "+name)} + if (!n.match(/^[0-9]+$/)) { + TEX.Error(["IllegalParamNumber", + "Illegal number of parameters specified in %1",name]); + } } this.setDef(cs,['Macro',def,n,opt]); }, @@ -67,13 +76,17 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { NewEnvironment: function (name) { var env = this.trimSpaces(this.GetArgument(name)), n = this.GetBrackets(name), + opt = this.GetBrackets(name), bdef = this.GetArgument(name), edef = this.GetArgument(name); if (n) { n = this.trimSpaces(n); - if (!n.match(/^[0-9]+$/)) {TEX.Error("Illegal number of parameters specified in "+name)} + if (!n.match(/^[0-9]+$/)) { + TEX.Error(["IllegalParamNumber", + "Illegal number of parameters specified in %1",name]); + } } - this.setEnv(env,['BeginEnv','EndEnv',bdef,edef,n]); + this.setEnv(env,['BeginEnv',[null,'EndEnv'],bdef,edef,n,opt]); }, /* @@ -128,7 +141,10 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { */ GetCSname: function (cmd) { var c = this.GetNext(); - if (c !== "\\") {TEX.Error("\\ must be followed by a control sequence")} + if (c !== "\\") { + TEX.Error(["MissingCS", + "%1 must be followed by a control sequence", cmd]) + } var cs = this.trimSpaces(this.GetArgument(cmd)); return cs.substr(1); }, @@ -144,8 +160,14 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { if (c === '#') { if (i !== this.i) {params[n] = this.string.substr(i,this.i-i)} c = this.string.charAt(++this.i); - if (!c.match(/^[1-9]$/)) {TEX.Error("Illegal use of # in template for "+cs)} - if (parseInt(c) != ++n) {TEX.Error("Parameters for "+cs+" must be numbered sequentially")} + if (!c.match(/^[1-9]$/)) { + TEX.Error(["CantUseHash2", + "Illegal use of # in template for %1",cs]); + } + if (parseInt(c) != ++n) { + TEX.Error(["SequentialParam", + "Parameters for %1 must be numbered sequentially",cs]); + } i = this.i+1; } else if (c === '{') { if (i !== this.i) {params[n] = this.string.substr(i,this.i-i)} @@ -153,7 +175,8 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { } this.i++; } - TEX.Error("Missing replacement string for definition of "+cmd); + TEX.Error(["MissingReplacementString", + "Missing replacement string for definition of %1",cmd]); }, /* @@ -162,34 +185,43 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { MacroWithTemplate: function (name,text,n,params) { if (n) { var args = []; this.GetNext(); - if (params[0] && !this.MatchParam(params[0])) - {TEX.Error("Use of "+name+" doesn't match its definition")} + if (params[0] && !this.MatchParam(params[0])) { + TEX.Error(["MismatchUseDef", + "Use of %1 doesn't match its definition",name]); + } for (var i = 0; i < n; i++) {args.push(this.GetParameter(name,params[i+1]))} text = this.SubstituteArgs(args,text); } this.string = this.AddArgs(text,this.string.slice(this.i)); this.i = 0; - if (++this.macroCount > TEX.config.MAXMACROS) - {TEX.Error("MathJax maximum macro substitution count exceeded; is there a recursive macro call?")} + if (++this.macroCount > TEX.config.MAXMACROS) { + TEX.Error(["MaxMacroSub1", + "MathJax maximum macro substitution count exceeded; " + + "is there a recursive macro call?"]); + } }, /* * Process a user-defined environment */ - BeginEnv: function (begin,bdef,edef,n) { + BeginEnv: function (begin,bdef,edef,n,def) { if (n) { var args = []; - for (var i = 0; i < n; i++) {args.push(this.GetArgument("\\begin{"+name+"}"))} + if (def != null) { + var optional = this.GetBrackets("\\begin{"+name+"}"); + args.push(optional == null ? def : optional); + } + for (var i = args.length; i < n; i++) {args.push(this.GetArgument("\\begin{"+name+"}"))} bdef = this.SubstituteArgs(args,bdef); - edef = this.SubstituteArgs(args,edef); + edef = this.SubstituteArgs([],edef); // no args, but get errors for #n in edef } - begin.edef = edef; this.string = this.AddArgs(bdef,this.string.slice(this.i)); this.i = 0; return begin; }, - EndEnv: function (begin,row) { - this.string = this.AddArgs(begin.edef,this.string.slice(this.i)); this.i = 0 - return row; + EndEnv: function (begin,bdef,edef,n) { + var end = "\\end{\\end\\"+begin.name+"}"; // special version of \end for after edef + this.string = this.AddArgs(edef,end+this.string.slice(this.i)); this.i = 0; + return null; }, /* @@ -209,7 +241,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { this.i++; j++; hasBraces = 0; } } - TEX.Error("Runaway argument for "+name+"?"); + TEX.Error(["RunawayArgument","Runaway argument for %1?",name]); }, /* diff --git a/resources/viewer/mathjax/extensions/TeX/noErrors.js b/resources/viewer/mathjax/extensions/TeX/noErrors.js index 074ab9bab1..2d71ab3076 100644 --- a/resources/viewer/mathjax/extensions/TeX/noErrors.js +++ b/resources/viewer/mathjax/extensions/TeX/noErrors.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/noErrors.js @@ -52,7 +55,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -68,7 +71,7 @@ */ (function (HUB,HTML) { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var CONFIG = HUB.CombineConfig("TeX.noErrors",{ disabled: false, // set to true to return to original error messages @@ -151,7 +154,7 @@ span = this.HTMLcreateSpan(span); span.bbox = data.data[0].toHTML(span).bbox; } else { - span = MATH.call(this,span,node); + span = MATH.apply(this,arguments); } return span; } @@ -163,7 +166,7 @@ // MML.merror.Augment({ toHTML: function (span) { - if (!this.isError) {return MERROR.call(this,span)} + if (!this.isError) {return MERROR.apply(this,arguments)} span = this.HTMLcreateSpan(span); span.className = "noError" if (this.multiLine) {span.style.display = "inline-block"} var text = this.data[0].data[0].data.join("").split(/\n/); @@ -215,7 +218,7 @@ toSVG: function (span,node) { var data = this.data[0]; if (data && data.data[0] && data.data[0].isError) - {span = data.data[0].toSVG(span)} else {span = MATH.call(this,span,node)} + {span = data.data[0].toSVG(span)} else {span = MATH.apply(this,arguments)} return span; } }); @@ -226,7 +229,7 @@ // MML.merror.Augment({ toSVG: function (span) { - if (!this.isError || this.Parent().type !== "math") {return MERROR.call(this,span)} + if (!this.isError || this.Parent().type !== "math") {return MERROR.apply(this,arguments)} span = HTML.addElement(span,"span",{className: "noError", isMathJax:true}); if (this.multiLine) {span.style.display = "inline-block"} var text = this.data[0].data[0].data.join("").split(/\n/); @@ -264,7 +267,7 @@ toNativeMML: function (span) { var data = this.data[0]; if (data && data.data[0] && data.data[0].isError) - {span = data.data[0].toNativeMML(span)} else {span = MATH.call(this,span)} + {span = data.data[0].toNativeMML(span)} else {span = MATH.apply(this,arguments)} return span; } }); @@ -275,7 +278,7 @@ // MML.merror.Augment({ toNativeMML: function (span) { - if (!this.isError) {return MERROR.call(this,span)} + if (!this.isError) {return MERROR.apply(this,arguments)} span = span.appendChild(document.createElement("span")); var text = this.data[0].data[0].data.join("").split(/\n/); for (var i = 0, m = text.length; i < m; i++) { @@ -296,6 +299,102 @@ }); + /******************************************************************* + * + * Fix PreviewHTML output + */ + + HUB.Register.StartupHook("PreviewHTML Jax Config",function () { + HUB.Config({ + PreviewHTML: { + styles: { + ".MathJax_PHTML .noError": HUB.Insert({ + "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "") + },CONFIG.style) + } + } + }); + }); + + HUB.Register.StartupHook("PreviewHTML Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + var HTML = MathJax.HTML; + + var MERROR = MML.merror.prototype.toPreviewHTML; + + // + // Override merror toPreviewHTML routine so that it puts out the + // TeX code in an inline-block with line breaks as in the original + // + MML.merror.Augment({ + toPreviewHTML: function (span) { + if (!this.isError) return MERROR.apply(this,arguments); + span = this.PHTMLcreateSpan(span); span.className = "noError" + if (this.multiLine) span.style.display = "inline-block"; + var text = this.data[0].data[0].data.join("").split(/\n/); + for (var i = 0, m = text.length; i < m; i++) { + HTML.addText(span,text[i]); + if (i !== m-1) {HTML.addElement(span,"br",{isMathJax:true})} + } + return span; + } + }); + + }); + + /******************************************************************* + * + * Fix CommonHTML output + */ + + HUB.Register.StartupHook("CommonHTML Jax Config",function () { + HUB.Config({ + CommonHTML: { + styles: { + ".mjx-chtml .mjx-noError": HUB.Insert({ + "line-height": 1.2, + "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "") + },CONFIG.style) + } + } + }); + }); + + HUB.Register.StartupHook("CommonHTML Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + var CHTML = MathJax.OutputJax.CommonHTML; + var HTML = MathJax.HTML; + + var MERROR = MML.merror.prototype.toCommonHTML; + + // + // Override merror toCommonHTML routine so that it puts out the + // TeX code in an inline-block with line breaks as in the original + // + MML.merror.Augment({ + toCommonHTML: function (node) { + if (!this.isError) return MERROR.apply(this,arguments); + node = CHTML.addElement(node,"mjx-noError"); + var text = this.data[0].data[0].data.join("").split(/\n/); + for (var i = 0, m = text.length; i < m; i++) { + HTML.addText(node,text[i]); + if (i !== m-1) {CHTML.addElement(node,"br",{isMathJax:true})} + } + var bbox = this.CHTML = CHTML.BBOX.zero(); + bbox.w = (node.offsetWidth)/CHTML.em; + if (m > 1) { + var H2 = 1.2*m/2; + bbox.h = H2+.25; bbox.d = H2-.25; + node.style.verticalAlign = CHTML.Em(.45-H2); + } else { + bbox.h = 1; bbox.d = .2 + 2/CHTML.em; + } + return node; + } + }); + + }); + /*******************************************************************/ HUB.Startup.signal.Post("TeX noErrors Ready"); diff --git a/resources/viewer/mathjax/extensions/TeX/noUndefined.js b/resources/viewer/mathjax/extensions/TeX/noUndefined.js index 22ca60f86b..5021154c1f 100644 --- a/resources/viewer/mathjax/extensions/TeX/noUndefined.js +++ b/resources/viewer/mathjax/extensions/TeX/noUndefined.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/noUndefined.js @@ -22,7 +25,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -41,7 +44,7 @@ // The configuration defaults, augmented by the user settings // MathJax.Extension["TeX/noUndefined"] = { - version: "2.0", + version: "2.6.0", config: MathJax.Hub.CombineConfig("TeX.noUndefined",{ disabled: false, // set to true to return to original error messages attributes: { diff --git a/resources/viewer/mathjax/extensions/TeX/unicode.js b/resources/viewer/mathjax/extensions/TeX/unicode.js index 7ac185459b..6f5e1c508f 100644 --- a/resources/viewer/mathjax/extensions/TeX/unicode.js +++ b/resources/viewer/mathjax/extensions/TeX/unicode.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/unicode.js @@ -40,7 +43,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -59,7 +62,7 @@ // The configuration defaults, augmented by the user settings // MathJax.Extension["TeX/unicode"] = { - version: "2.0", + version: "2.6.0", unicode: {}, config: MathJax.Hub.CombineConfig("TeX.unicode",{ fonts: "STIXGeneral,'Arial Unicode MS'" @@ -74,7 +77,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { // // Add \unicode macro // - TEX.Definitions.macros.unicode = 'Unicode'; + TEX.Definitions.Add({macros: {unicode: 'Unicode'}},null,true); // // Implementation of \unicode in parser // @@ -121,7 +124,7 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { var GETVARIANT = MML.mbase.prototype.HTMLgetVariant; MML.mbase.Augment({ HTMLgetVariant: function () { - var variant = GETVARIANT.call(this); + var variant = GETVARIANT.apply(this,arguments); if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart if (!this.unicode) {return variant} variant.unicode = true; diff --git a/resources/viewer/mathjax/extensions/TeX/verb.js b/resources/viewer/mathjax/extensions/TeX/verb.js index 10af8ce38e..4fc0237e3e 100644 --- a/resources/viewer/mathjax/extensions/TeX/verb.js +++ b/resources/viewer/mathjax/extensions/TeX/verb.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/TeX/verb.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -23,7 +26,7 @@ */ MathJax.Extension["TeX/verb"] = { - version: "2.0" + version: "2.6.0" }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { @@ -32,7 +35,7 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var TEX = MathJax.InputJax.TeX; var TEXDEF = TEX.Definitions; - TEXDEF.macros.verb = 'Verb'; + TEXDEF.Add({macros: {verb: 'Verb'}},null,true); TEX.Parse.Augment({ @@ -41,11 +44,11 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { */ Verb: function (name) { var c = this.GetNext(); var start = ++this.i; - if (c == "" ) {TEX.Error(name+" requires an argument")} + if (c == "" ) {TEX.Error(["MissingArgFor","Missing argument for %1",name])} while (this.i < this.string.length && this.string.charAt(this.i) != c) {this.i++} - if (this.i == this.string.length) - {TEX.Error("Can't find closing delimiter for "+name)} - var text = this.string.slice(start,this.i); this.i++; + if (this.i == this.string.length) + {TEX.Error(["NoClosingDelim","Can't find closing delimiter for %1", name])} + var text = this.string.slice(start,this.i).replace(/ /g,"\u00A0"); this.i++; this.Push(MML.mtext(text).With({mathvariant:MML.VARIANT.MONOSPACE})); } diff --git a/resources/viewer/mathjax/extensions/asciimath2jax.js b/resources/viewer/mathjax/extensions/asciimath2jax.js index 2253da36f6..f6fae5206d 100644 --- a/resources/viewer/mathjax/extensions/asciimath2jax.js +++ b/resources/viewer/mathjax/extensions/asciimath2jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/asciimath2jax.js @@ -11,7 +14,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2012 Design Science, Inc. + * Copyright (c) 2012-2015 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. @@ -27,11 +30,11 @@ */ MathJax.Extension.asciimath2jax = { - version: "2.0", + version: "2.6.0", config: { delimiters: [['`','`']], // The star/stop delimiter pairs for asciimath code - skipTags: ["script","noscript","style","textarea","pre","code"], + skipTags: ["script","noscript","style","textarea","pre","code","annotation","annotation-xml"], // The names of the tags whose contents will not be // scanned for math delimiters @@ -75,7 +78,10 @@ MathJax.Extension.asciimath2jax = { } this.start = new RegExp(starts.sort(this.sortLength).join("|"),"g"); this.skipTags = new RegExp("^("+config.skipTags.join("|")+")$","i"); - this.ignoreClass = new RegExp("(^| )("+config.ignoreClass+")( |$)"); + var ignore = []; + if (MathJax.Hub.config.preRemoveClass) {ignore.push(MathJax.Hub.config.preRemoveClass)} + if (config.ignoreClass) {ignore.push(config.ignoreClass)} + this.ignoreClass = (ignore.length ? new RegExp("(^| )("+ignore.join("|")+")( |$)") : /^$/); this.processClass = new RegExp("(^| )("+config.processClass+")( |$)"); return true; }, @@ -201,9 +207,9 @@ MathJax.Extension.asciimath2jax = { }, createPreview: function (mode,asciimath) { - var preview; - if (this.config.preview === "AsciiMath") {preview = [this.filterPreview(asciimath)]} - else if (this.config.preview instanceof Array) {preview = this.config.preview} + var preview = this.config.preview; + if (preview === "none") return; + if (preview === "AsciiMath") {preview = [this.filterPreview(asciimath)]} if (preview) { preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview); this.insertNode(preview); @@ -224,5 +230,10 @@ MathJax.Extension.asciimath2jax = { }; +// 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.asciimath2jax]); MathJax.Ajax.loadComplete("[MathJax]/extensions/asciimath2jax.js"); diff --git a/resources/viewer/mathjax/extensions/fast-preview.js b/resources/viewer/mathjax/extensions/fast-preview.js new file mode 100644 index 0000000000..73f3ee43f8 --- /dev/null +++ b/resources/viewer/mathjax/extensions/fast-preview.js @@ -0,0 +1,155 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/fast-preview.js + * + * Implements a fast preview using the PreviewHTML output jax + * and then a slower update to the more accurate HTML-CSS output + * (or whatever the user has selected). + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2014-2015 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. + */ + +(function (HUB,HTML,BROWSER) { + + var SETTINGS = HUB.config.menuSettings; + var JAX = MathJax.OutputJax; + var msieColorBug = BROWSER.isMSIE && (document.documentMode||0) < 8; + + var FastPreview = MathJax.Extension["fast-preview"] = { + version: "2.6.0", + enabled: true, + + // + // Configuration for the chunking of the main output + // after the previews have been created, and other configuration. + // + config: HUB.CombineConfig("fast-preview",{ + Chunks: {EqnChunk: 10000, EqnChunkFactor: 1, EqnChunkDelay: 0}, + color: "inherit!important", + updateTime: 30, updateDelay: 6, + messageStyle: "none", + disabled: BROWSER.isMSIE && !BROWSER.versionAtLeast("8.0") + }), + + // + // Ajust the chunking of the output jax + // + Config: function () { + if (HUB.config["CHTML-preview"]) + MathJax.Hub.Config({"fast-preview": HUB.config["CHTML-preview"]}); + var update, delay, style, done, saved; + var config = this.config; + + if (!config.disabled && SETTINGS.FastPreview == null) + HUB.Config({menuSettings:{FastPreview:true}}); + if (SETTINGS.FastPreview) { + MathJax.Ajax.Styles({".MathJax_Preview .MJXf-math":{color:config.color}}); + HUB.Config({"HTML-CSS": config.Chunks, CommonHTML: config.Chunks, SVG: config.Chunks}); + } + HUB.Register.MessageHook("Begin Math Output",function () { + if (!done && FastPreview.Active()) { + update = HUB.processUpdateTime; delay = HUB.processUpdateDelay; + style = HUB.config.messageStyle; + HUB.processUpdateTime = config.updateTime; + HUB.processUpdateDelay = config.updateDelay; + HUB.Config({messageStyle: config.messageStyle}); + MathJax.Message.Clear(0,0); + saved = true; + } + }); + HUB.Register.MessageHook("End Math Output",function () { + if (!done && saved) { + HUB.processUpdateTime = update; + HUB.processUpdateDelay = delay; + HUB.Config({messageStyle: style}); + done = true; + } + }); + }, + + // + // Allow page to override user settings (for things like editor previews) + // + Disable: function () {this.enabled = false}, + Enable: function () {this.enabled = true}, + + Active: function () { + return SETTINGS.FastPreview && this.enabled && + !(JAX[SETTINGS.renderer]||{}).noFastPreview; + }, + + // + // Insert a preview span, if there isn't one already, + // and call the PreviewHTML output jax to create the preview + // + Preview: function (data) { + if (!this.Active()) return; + var preview = data.script.MathJax.preview || data.script.previousSibling; + if (!preview || preview.className !== MathJax.Hub.config.preRemoveClass) { + preview = HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass}); + data.script.parentNode.insertBefore(preview,data.script); + data.script.MathJax.preview = preview; + } + preview.innerHTML = ""; + preview.style.color = (msieColorBug ? "black" : "inherit"); + return this.postFilter(preview,data); + }, + postFilter: function (preview,data) { + // + // Load the PreviewHTML jax if it is not already loaded + // + if (!data.math.root.toPreviewHTML) { + var queue = MathJax.Callback.Queue(); + queue.Push( + ["Require",MathJax.Ajax,"[MathJax]/jax/output/PreviewHTML/config.js"], + ["Require",MathJax.Ajax,"[MathJax]/jax/output/PreviewHTML/jax.js"] + ); + HUB.RestartAfter(queue.Push({})); + } + data.math.root.toPreviewHTML(preview); + }, + + // + // Hook into the input jax postFilter to create the previews as + // the input jax are processed. + // + Register: function (name) { + HUB.Register.StartupHook(name+" Jax Require",function () { + var jax = MathJax.InputJax[name]; + jax.postfilterHooks.Add(["Preview",MathJax.Extension["fast-preview"]],50); + }); + } + } + + // + // Hook into each input jax + // + FastPreview.Register("TeX"); + FastPreview.Register("MathML"); + FastPreview.Register("AsciiMath"); + + HUB.Register.StartupHook("End Config",["Config",FastPreview]); + + HUB.Startup.signal.Post("fast-preview Ready"); + +})(MathJax.Hub,MathJax.HTML,MathJax.Hub.Browser); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/fast-preview.js"); + diff --git a/resources/viewer/mathjax/extensions/jsMath2jax.js b/resources/viewer/mathjax/extensions/jsMath2jax.js index acc8dc5f79..03b8ff3eea 100644 --- a/resources/viewer/mathjax/extensions/jsMath2jax.js +++ b/resources/viewer/mathjax/extensions/jsMath2jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/jsMath2jax.js @@ -15,7 +18,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -31,7 +34,7 @@ */ MathJax.Extension.jsMath2jax = { - version: "2.0", + version: "2.6.0", config: { preview: "TeX" // Set to "none" to prevent preview strings from being inserted @@ -70,9 +73,8 @@ MathJax.Extension.jsMath2jax = { }, createPreview: function (node) { - var preview; - if (this.config.preview === "TeX") {preview = [this.filterPreview(node.innerHTML)]} - else if (this.config.preview instanceof Array) {preview = this.config.preview} + var preview = this.config.preview; + if (preview === "TeX") {preview = [this.filterPreview(node.innerHTML)]} if (preview) { preview = MathJax.HTML.Element("span",{className: MathJax.Hub.config.preRemoveClass},preview); node.parentNode.insertBefore(preview,node); @@ -91,5 +93,10 @@ MathJax.Extension.jsMath2jax = { }; -MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.jsMath2jax]); +// 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.jsMath2jax],8); MathJax.Ajax.loadComplete("[MathJax]/extensions/jsMath2jax.js"); diff --git a/resources/viewer/mathjax/extensions/mml2jax.js b/resources/viewer/mathjax/extensions/mml2jax.js index ccd0f6c0f9..6b3ce1531c 100644 --- a/resources/viewer/mathjax/extensions/mml2jax.js +++ b/resources/viewer/mathjax/extensions/mml2jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/mml2jax.js @@ -8,7 +11,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -24,10 +27,13 @@ */ MathJax.Extension.mml2jax = { - version: "2.0", + version: "2.6.0", config: { - preview: "alttext" // Use the element's alttext as the + preview: "mathml" // Use the element as the // preview. Set to "none" for no preview, + // set to "alttext" to use the alttext attribute + // of the 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 @@ -43,28 +49,30 @@ MathJax.Extension.mml2jax = { } if (typeof(element) === "string") {element = document.getElementById(element)} if (!element) {element = document.body} + var mathArray = []; // // Handle all math tags with no namespaces // - this.ProcessMathArray(element.getElementsByTagName("math")); + this.PushMathElements(mathArray,element,"math"); // // Handle math with namespaces in XHTML // - if (element.getElementsByTagNameNS) - {this.ProcessMathArray(element.getElementsByTagNameNS(this.MMLnamespace,"math"))} + this.PushMathElements(mathArray,element,"math",this.MMLnamespace); // // Handle math with namespaces in HTML // var i, m; - if (document.namespaces) { + if (typeof(document.namespaces) !== "undefined") { // // 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"))} - } + 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 @@ -74,28 +82,45 @@ MathJax.Extension.mml2jax = { 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"))} + {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; - if (math.length) { + var i, m = math.length; + if (m) { if (this.MathTagBug) { - for (i = math.length-1; i >= 0; i--) { + for (i = 0; i < m; 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])} + 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); @@ -115,6 +140,7 @@ MathJax.Extension.mml2jax = { 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); @@ -141,7 +167,7 @@ MathJax.Extension.mml2jax = { html = "<"+node.nodeName.toLowerCase(); for (i = 0, m = node.attributes.length; i < m; i++) { var attribute = node.attributes[i]; - if (attribute.specified) { + 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 @@ -170,18 +196,41 @@ MathJax.Extension.mml2jax = { }, quoteHTML: function (string) { if (string == null) {string = ""} - return string.replace(/&/g,"&").replace(//g,">").replace(/"/g,"""); + return string.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} + var preview = this.config.preview; + if (preview === "none") return; + var isNodePreview = false; + 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) { - preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview); - script.parentNode.insertBefore(preview,script); + var span; + if (isNodePreview) { + span = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass}); + span.appendChild(preview); + } else { + span = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview); + } + script.parentNode.insertBefore(span,script); } }, @@ -201,5 +250,12 @@ MathJax.Extension.mml2jax = { }; -MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.mml2jax]); +// +// 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"); diff --git a/resources/viewer/mathjax/extensions/tex2jax.js b/resources/viewer/mathjax/extensions/tex2jax.js index 599b96e468..26238818b8 100644 --- a/resources/viewer/mathjax/extensions/tex2jax.js +++ b/resources/viewer/mathjax/extensions/tex2jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/tex2jax.js @@ -8,7 +11,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -24,7 +27,7 @@ */ MathJax.Extension.tex2jax = { - version: "2.0", + version: "2.6.0", config: { inlineMath: [ // The start/stop pairs for in-line math // ['$','$'], // (comment out any you don't want, or add your own, but @@ -40,7 +43,7 @@ MathJax.Extension.tex2jax = { // balanced within math delimiters (allows for nested // dollar signs). Set to false to get pre-v2.0 compatibility. - skipTags: ["script","noscript","style","textarea","pre","code"], + skipTags: ["script","noscript","style","textarea","pre","code","annotation","annotation-xml"], // The names of the tags whose contents will not be // scanned for math delimiters @@ -107,7 +110,10 @@ MathJax.Extension.tex2jax = { if (config.processRefs) {parts.push("\\\\(eq)?ref\\{[^}]*\\}")} this.start = new RegExp(parts.join("|"),"g"); this.skipTags = new RegExp("^("+config.skipTags.join("|")+")$","i"); - this.ignoreClass = new RegExp("(^| )("+config.ignoreClass+")( |$)"); + var ignore = []; + if (MathJax.Hub.config.preRemoveClass) {ignore.push(MathJax.Hub.config.preRemoveClass)}; + if (config.ignoreClass) {ignore.push(config.ignoreClass)} + this.ignoreClass = (ignore.length ? new RegExp("(^| )("+ignore.join("|")+")( |$)") : /^$/); this.processClass = new RegExp("(^| )("+config.processClass+")( |$)"); return (parts.length > 0); }, @@ -271,9 +277,9 @@ MathJax.Extension.tex2jax = { }, createPreview: function (mode,tex) { - var preview; - if (this.config.preview === "TeX") {preview = [this.filterPreview(tex)]} - else if (this.config.preview instanceof Array) {preview = this.config.preview} + var preview = this.config.preview; + if (preview === "none") return; + if (preview === "TeX") {preview = [this.filterPreview(tex)]} if (preview) { preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview); this.insertNode(preview); @@ -294,5 +300,10 @@ MathJax.Extension.tex2jax = { }; +// 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.tex2jax]); MathJax.Ajax.loadComplete("[MathJax]/extensions/tex2jax.js"); diff --git a/resources/viewer/mathjax/extensions/toMathML.js b/resources/viewer/mathjax/extensions/toMathML.js index 6894a62869..7c0594f6a2 100644 --- a/resources/viewer/mathjax/extensions/toMathML.js +++ b/resources/viewer/mathjax/extensions/toMathML.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/extensions/toMathML.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -23,9 +26,9 @@ */ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; - var MML = MathJax.ElementJax.mml + var MML = MathJax.ElementJax.mml, SETTINGS = MathJax.Hub.config.menuSettings; MML.mbase.Augment({ @@ -35,12 +38,12 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { if (space == null) {space = ""} var tag = this.type, attr = this.toMathMLattributes(); if (tag === "mspace") {return space + "<"+tag+attr+" />"} - var data = []; var SPACE = (this.isToken ? "" : space+(inferred ? "" : " ")); + var data = [], SPACE = (this.isToken ? "" : space+(inferred ? "" : " ")); for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i]) {data.push(this.data[i].toMathML(SPACE))} - else if (!this.isToken) {data.push(SPACE+"")} + else if (!this.isToken && !this.isChars) {data.push(SPACE+"")} } - if (this.isToken) {return space + "<"+tag+attr+">"+data.join("")+""} + if (this.isToken || this.isChars) {return space + "<"+tag+attr+">"+data.join("")+""} if (inferred) {return data.join("\n")} if (data.length === 0 || (data.length === 1 && data[0] === "")) {return space + "<"+tag+attr+" />"} @@ -48,26 +51,25 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { }, toMathMLattributes: function () { - var attr = [], defaults = this.defaults; - var copy = (this.attrNames||MML.copyAttributeNames), skip = MML.skipAttributes; + var defaults = (this.type === "mstyle" ? MML.math.prototype.defaults : this.defaults); + var names = (this.attrNames||MML.copyAttributeNames), + skip = MML.skipAttributes, copy = MML.copyAttributes; + var attr = []; - if (this.type === "math") {attr.push('xmlns="http://www.w3.org/1998/Math/MathML"')} + if (this.type === "math" && (!this.attr || !this.attr.xmlns)) + {attr.push('xmlns="http://www.w3.org/1998/Math/MathML"')} if (!this.attrNames) { - if (this.type === "mstyle") {defaults = MML.math.prototype.defaults} - for (var id in defaults) {if (!skip[id] && defaults.hasOwnProperty(id)) { - var force = (id === "open" || id === "close"); - if (this[id] != null && (force || this[id] !== defaults[id])) { - var value = this[id]; delete this[id]; - if (force || this.Get(id) !== value) - {attr.push(id+'="'+this.toMathMLattribute(value)+'"')} - this[id] = value; + for (var id in defaults) {if (!skip[id] && !copy[id] && defaults.hasOwnProperty(id)) { + if (this[id] != null && this[id] !== defaults[id]) { + if (this.Get(id,null,1) !== this[id]) + attr.push(id+'="'+this.toMathMLattribute(this[id])+'"'); } }} } - for (var i = 0, m = copy.length; i < m; i++) { - if (copy[i] === "class") continue; // this is handled separately below - value = (this.attr||{})[copy[i]]; if (value == null) {value = this[copy[i]]} - if (value != null) {attr.push(copy[i]+'="'+this.toMathMLquote(value)+'"')} + for (var i = 0, m = names.length; i < m; i++) { + if (copy[names[i]] === 1 && !defaults.hasOwnProperty(names[i])) continue; + value = (this.attr||{})[names[i]]; if (value == null) {value = this[names[i]]} + if (value != null) {attr.push(names[i]+'="'+this.toMathMLquote(value)+'"')} } this.toMathMLclass(attr); if (attr.length) {return " "+attr.join(" ")} else {return ""} @@ -80,7 +82,6 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { } if (this.mathvariant && this.toMathMLvariants[this.mathvariant]) {CLASS.push("MJX"+this.mathvariant)} - if (this.arrow) {CLASS.push("MJX-arrow")} if (this.variantForm) {CLASS.push("MJX-variant")} if (CLASS.length) {attr.unshift('class="'+CLASS.join(" ")+'"')} }, @@ -88,7 +89,7 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { if (typeof(value) === "string" && value.replace(/ /g,"").match(/^(([-+])?(\d+(\.\d*)?|\.\d+))mu$/)) { // FIXME: should take scriptlevel into account - return ((1/18)*RegExp.$1).toFixed(3).replace(/\.?0+$/,"")+"em"; + return (RegExp.$2||"")+((1/18)*RegExp.$3).toFixed(3).replace(/\.?0+$/,"")+"em"; } else if (this.toMathMLvariants[value]) {return this.toMathMLvariants[value]} return this.toMathMLquote(value); @@ -105,17 +106,69 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { string = String(string).split(""); for (var i = 0, m = string.length; i < m; i++) { var n = string[i].charCodeAt(0); - if (n < 0x20 || n > 0x7E) { - string[i] = "&#x"+n.toString(16).toUpperCase()+";"; + if (n <= 0xD7FF || 0xE000 <= n) { + // Code points U+0000 to U+D7FF and U+E000 to U+FFFF. + // They are directly represented by n. + if (n > 0x7E || (n < 0x20 && n !== 0x0A && n !== 0x0D && n !== 0x09)) { + string[i] = "&#x"+n.toString(16).toUpperCase()+";"; + } else { + var c = + {'&':'&', '<':'<', '>':'>', '"':'"'}[string[i]]; + if (c) {string[i] = c} + } + } else if (i+1 < m) { + // Code points U+10000 to U+10FFFF. + // n is the lead surrogate, let's read the trail surrogate. + var trailSurrogate = string[i+1].charCodeAt(0); + var codePoint = (((n-0xD800)<<10)+(trailSurrogate-0xDC00)+0x10000); + string[i] = "&#x"+codePoint.toString(16).toUpperCase()+";"; + string[i+1] = ""; + i++; } else { - var c = {'&':'&', '<':'<', '>':'>', '"':'"'}[string[i]]; - if (c) {string[i] = c} + // n is a lead surrogate without corresponding trail surrogate: + // remove that character. + string[i] = ""; } } return string.join(""); } }); + // + // Override math.toMathML in order to add semantics tag + // for the input format, if the user requests that in the + // Show As menu. + // + MML.math.Augment({ + toMathML: function (space,jax) { + var annotation; + if (space == null) {space = ""} + if (jax && jax.originalText && SETTINGS.semantics) + {annotation = MathJax.InputJax[jax.inputJax].annotationEncoding} + var nested = (this.data[0] && this.data[0].data.length > 1); + var tag = this.type, attr = this.toMathMLattributes(); + var data = [], SPACE = space + (annotation ? " " + (nested ? " " : "") : "") + " "; + for (var i = 0, m = this.data.length; i < m; i++) { + if (this.data[i]) {data.push(this.data[i].toMathML(SPACE))} + else {data.push(SPACE+"")} + } + if (data.length === 0 || (data.length === 1 && data[0] === "")) { + if (!annotation) {return "<"+tag+attr+" />"} + data.push(SPACE+""); + } + if (annotation) { + if (nested) {data.unshift(space+" "); data.push(space+" ")} + data.unshift(space+" "); + var xmlEscapedTex = jax.originalText.replace(/[&<>]/g, function(item) { + return { '>': '>', '<': '<','&': '&' }[item] + }); + data.push(space+' '+xmlEscapedTex+""); + data.push(space+" "); + } + return space+"<"+tag+attr+">\n"+data.join("\n")+"\n"+space+""; + } + }); + MML.msubsup.Augment({ toMathML: function (space) { var tag = this.type; diff --git a/resources/viewer/mathjax/jax/element/mml/jax.js b/resources/viewer/mathjax/jax/element/mml/jax.js index dd2821bec7..e5e5562c44 100644 --- a/resources/viewer/mathjax/jax/element/mml/jax.js +++ b/resources/viewer/mathjax/jax/element/mml/jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/element/mml/jax.js @@ -8,7 +11,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -27,7 +30,7 @@ MathJax.ElementJax.mml = MathJax.ElementJax({ mimeType: "jax/mml" },{ id: "mml", - version: "2.0", + version: "2.6.0", directory: MathJax.ElementJax.directory + "/mml", extensionDir: MathJax.ElementJax.extensionDir + "/mml", optableDir: MathJax.ElementJax.directory + "/mml/optable" @@ -129,8 +132,10 @@ MathJax.ElementJax.mml.Augment({ BOTTOM: "bottom", UPDIAGONALSTRIKE: "updiagonalstrike", DOWNDIAGONALSTRIKE: "downdiagonalstrike", + UPDIAGONALARROW: "updiagonalarrow", VERTICALSTRIKE: "verticalstrike", HORIZONTALSTRIKE: "horizontalstrike", + PHASORANGLE: "phasorangle", MADRUWB: "madruwb" }, ALIGN: { @@ -209,17 +214,41 @@ MathJax.ElementJax.mml.Augment({ NONE: -1 }, TEXCLASSNAMES: ["ORD", "OP", "BIN", "REL", "OPEN", "CLOSE", "PUNCT", "INNER", "VCENTER"], + skipAttributes: { + texClass:true, useHeight:true, texprimestyle:true + }, copyAttributes: { + displaystyle:1, scriptlevel:1, open:1, close:1, form:1, + actiontype: 1, fontfamily:true, fontsize:true, fontweight:true, fontstyle:true, color:true, background:true, - id:true, "class":true, href:true, style:true + id:true, "class":1, href:true, style:true }, - skipAttributes: {texClass: true, useHeight: true, texprimestyle: true}, copyAttributeNames: [ + "displaystyle", "scriptlevel", "open", "close", "form", // force these to be copied + "actiontype", "fontfamily", "fontsize", "fontweight", "fontstyle", "color", "background", "id", "class", "href", "style" - ] + ], + nocopyAttributes: { + fontfamily: true, fontsize: true, fontweight: true, fontstyle: true, + color: true, background: true, + id: true, 'class': true, href: true, style: true, + xmlns: true + }, + Error: function (message,def) { + var mml = this.merror(message), + dir = MathJax.Localization.fontDirection(), + font = MathJax.Localization.fontFamily(); + if (def) {mml = mml.With(def)} + if (dir || font) { + mml = this.mstyle(mml); + if (dir) {mml.dir = dir} + if (font) {mml.style.fontFamily = "font-family: "+font} + } + return mml; + } }); (function (MML) { @@ -228,18 +257,20 @@ MathJax.ElementJax.mml.Augment({ type: "base", isToken: false, defaults: { mathbackground: MML.INHERIT, - mathcolor: MML.INHERIT + mathcolor: MML.INHERIT, + dir: MML.INHERIT }, noInherit: {}, noInheritAttribute: { texClass: true }, + getRemoved: {}, linebreakContainer: false, Init: function () { this.data = []; if (this.inferRow && !(arguments.length === 1 && arguments[0].inferred)) - {this.Append(MML.mrow().With({inferred: true}))} + {this.Append(MML.mrow().With({inferred: true, notParent: true}))} this.Append.apply(this,arguments); }, With: function (def) { @@ -257,7 +288,7 @@ MathJax.ElementJax.mml.Augment({ SetData: function (i,item) { if (item != null) { if (!(item instanceof MML.mbase)) - {item = (this.isToken ? MML.chars(item) : MML.mtext(item))} + {item = (this.isToken || this.isChars ? MML.chars(item) : MML.mtext(item))} item.parent = this; item.setInherit(this.inheritFromMe ? this : this.inherit); } @@ -265,21 +296,25 @@ MathJax.ElementJax.mml.Augment({ }, Parent: function () { var parent = this.parent; - while (parent && parent.inferred) {parent = parent.parent} + while (parent && parent.notParent) {parent = parent.parent} return parent; }, - Get: function (name,nodefault) { - if (this[name] != null) {return this[name]} - if (this.attr && this.attr[name] != null) {return this.attr[name]} + Get: function (name,nodefault,noself) { + if (!noself) { + if (this[name] != null) {return this[name]} + if (this.attr && this.attr[name] != null) {return this.attr[name]} + } // FIXME: should cache these values and get from cache // (clear cache when appended to a new object?) var parent = this.Parent(); - if (parent && parent["adjustChild_"+name] != null) - {return (parent["adjustChild_"+name])(parent.childPosition(this))} + if (parent && parent["adjustChild_"+name] != null) { + return (parent["adjustChild_"+name])(this.childPosition(),nodefault); + } var obj = this.inherit; var root = obj; while (obj) { var value = obj[name]; if (value == null && obj.attr) {value = obj.attr[name]} - if (value != null && !obj.noInheritAttribute[name]) { + if (obj.removedStyles && obj.getRemoved[name] && value == null) value = obj.removedStyles[obj.getRemoved[name]]; + if (value != null && obj.noInheritAttribute && !obj.noInheritAttribute[name]) { var noInherit = obj.noInherit[this.type]; if (!(noInherit && noInherit[name])) {return value} } @@ -300,12 +335,13 @@ MathJax.ElementJax.mml.Augment({ {values[arguments[i]] = this.Get(arguments[i])} return values; }, - adjustChild_scriptlevel: function (i) {return this.Get("scriptlevel")}, // always inherit from parent - adjustChild_displaystyle: function (i) {return this.Get("displaystyle")}, // always inherit from parent - adjustChild_texprimestyle: function (i) {return this.Get("texprimestyle")}, // always inherit from parent - childPosition: function (child) { - if (child.parent.inferred) {child = child.parent} - for (var i = 0, m = this.data.length; i < m; i++) {if (this.data[i] === child) {return i}} + adjustChild_scriptlevel: function (i,nodef) {return this.Get("scriptlevel",nodef)}, // always inherit from parent + adjustChild_displaystyle: function (i,nodef) {return this.Get("displaystyle",nodef)}, // always inherit from parent + adjustChild_texprimestyle: function (i,nodef) {return this.Get("texprimestyle",nodef)}, // always inherit from parent + childPosition: function () { + var child = this, parent = child.parent; + while (parent.notParent) {child = parent; parent = child.parent} + for (var i = 0, m = parent.data.length; i < m; i++) {if (parent.data[i] === child) {return i}} return null; }, setInherit: function (obj) { @@ -365,6 +401,13 @@ MathJax.ElementJax.mml.Augment({ isEmbellished: function () {return false}, Core: function () {return this}, CoreMO: function () {return this}, + childIndex: function(child) { + if (child == null) return; + for (var i = 0, m = this.data.length; i < m; i++) if (child === this.data[i]) return i; + }, + CoreIndex: function () { + return (this.inferRow ? this.data[0]||this : this).childIndex(this.Core()); + }, hasNewline: function () { if (this.isEmbellished()) {return this.CoreMO().hasNewline()} if (this.isToken || this.linebreakContainer) {return false} @@ -374,7 +417,8 @@ MathJax.ElementJax.mml.Augment({ return false; }, array: function () {if (this.inferred) {return this.data} else {return [this]}}, - toString: function () {return this.type+"("+this.data.join(",")+")"} + toString: function () {return this.type+"("+this.data.join(",")+")"}, + getAnnotation: function () {return null} },{ childrenSpacelike: function () { for (var i = 0, m = this.data.length; i < m; i++) @@ -384,7 +428,7 @@ MathJax.ElementJax.mml.Augment({ childEmbellished: function () { return (this.data[0] && this.data[0].isEmbellished()); }, - childCore: function () {return this.data[0]}, + childCore: function () {return (this.inferRow && this.data[0] ? this.data[0].Core() : this.data[0])}, childCoreMO: function () {return (this.data[0] ? this.data[0].CoreMO() : null)}, setChildTeXclass: function (prev) { if (this.data[0]) { @@ -395,10 +439,12 @@ MathJax.ElementJax.mml.Augment({ }, setBaseTeXclasses: function (prev) { this.getPrevClass(prev); this.texClass = null; - if (this.isEmbellished()) { - prev = this.data[0].setTeXclass(prev); - this.updateTeXclass(this.Core()); - } else {if (this.data[0]) {this.data[0].setTeXclass()}; prev = this} + if (this.data[0]) { + if (this.isEmbellished() || this.data[0].isa(MML.mi)) { + prev = this.data[0].setTeXclass(prev); + this.updateTeXclass(this.Core()); + } else {this.data[0].setTeXclass(); prev = this} + } else {prev = this} for (var i = 1, m = this.data.length; i < m; i++) {if (this.data[i]) {this.data[i].setTeXclass()}} return prev; @@ -419,7 +465,8 @@ MathJax.ElementJax.mml.Augment({ mathvariant: MML.AUTO, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, - mathcolor: MML.INHERIT + mathcolor: MML.INHERIT, + dir: MML.INHERIT }, autoDefault: function (name) { if (name === "mathvariant") { @@ -429,7 +476,17 @@ MathJax.ElementJax.mml.Augment({ MML.VARIANT.ITALIC : MML.VARIANT.NORMAL); } return ""; - } + }, + setTeXclass: function (prev) { + this.getPrevClass(prev); + var name = this.data.join(""); + if (name.length > 1 && name.match(/^[a-z][a-z0-9]*$/i) && + this.texClass === MML.TEXCLASS.ORD) { + this.texClass = MML.TEXCLASS.OP; + this.autoOP = true; + } + return this; + } }); MML.mn = MML.mbase.Subclass({ @@ -439,7 +496,8 @@ MathJax.ElementJax.mml.Augment({ mathvariant: MML.INHERIT, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, - mathcolor: MML.INHERIT + mathcolor: MML.INHERIT, + dir: MML.INHERIT } }); @@ -450,6 +508,7 @@ MathJax.ElementJax.mml.Augment({ mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, + dir: MML.INHERIT, form: MML.AUTO, fence: MML.AUTO, separator: MML.AUTO, @@ -482,7 +541,7 @@ MathJax.ElementJax.mml.Augment({ lspace: MML.LENGTH.THICKMATHSPACE, rspace: MML.LENGTH.THICKMATHSPACE, stretchy: false, - symmetric: true, + symmetric: false, maxsize: MML.SIZE.INFINITY, minsize: '0em', //'1em', largeop: false, @@ -515,8 +574,8 @@ MathJax.ElementJax.mml.Augment({ if (!def) {def = this.CheckRange(mo)} if (!def && nodefault) {def = {}} else { if (!def) {def = MathJax.Hub.Insert({},this.defaultDef)} + if (this.parent) {this.def = def} else {def = MathJax.Hub.Insert({},def)} def.form = forms[0]; - this.def = def; } } this.useMMLspacing &= ~(this.SPACE_ATTR[name] || 0); @@ -564,12 +623,63 @@ MathJax.ElementJax.mml.Augment({ }, isEmbellished: function () {return true}, hasNewline: function () {return (this.Get("linebreak") === MML.LINEBREAK.NEWLINE)}, + CoreParent: function () { + var parent = this; + while (parent && parent.isEmbellished() && + parent.CoreMO() === this && !parent.isa(MML.math)) {parent = parent.Parent()} + return parent; + }, + CoreText: function (parent) { + if (!parent) {return ""} + if (parent.isEmbellished()) {return parent.CoreMO().data.join("")} + while ((((parent.isa(MML.mrow) || parent.isa(MML.TeXAtom) || + parent.isa(MML.mstyle) || parent.isa(MML.mphantom)) && + parent.data.length === 1) || parent.isa(MML.munderover)) && + parent.data[0]) {parent = parent.data[0]} + if (!parent.isToken) {return ""} else {return parent.data.join("")} + }, + remapChars: { + '*':"\u2217", + '"':"\u2033", + "\u00B0":"\u2218", + "\u00B2":"2", + "\u00B3":"3", + "\u00B4":"\u2032", + "\u00B9":"1" + }, + remap: function (text,map) { + text = text.replace(/-/g,"\u2212"); + if (map) { + text = text.replace(/'/g,"\u2032").replace(/`/g,"\u2035"); + if (text.length === 1) {text = map[text]||text} + } + return text; + }, setTeXclass: function (prev) { - this.getValues("lspace","rspace"); // sets useMMLspacing + var values = this.getValues("form","lspace","rspace","fence"); // sets useMMLspacing if (this.useMMLspacing) {this.texClass = MML.TEXCLASS.NONE; return this} - this.texClass = this.Get("texClass"); if (this.texClass === MML.TEXCLASS.NONE) {return prev} - if (prev) {this.prevClass = prev.texClass || MML.TEXCLASS.ORD; this.prevLevel = prev.Get("scriptlevel")} - else {this.prevClass = MML.TEXCLASS.NONE} + if (values.fence && !this.texClass) { + if (values.form === MML.FORM.PREFIX) {this.texClass = MML.TEXCLASS.OPEN} + if (values.form === MML.FORM.POSTFIX) {this.texClass = MML.TEXCLASS.CLOSE} + } + this.texClass = this.Get("texClass"); + if (this.data.join("") === "\u2061") { + // force previous node to be texClass OP, and skip this node + if (prev) {prev.texClass = MML.TEXCLASS.OP; prev.fnOP = true} + this.texClass = this.prevClass = MML.TEXCLASS.NONE; + return prev; + } + return this.adjustTeXclass(prev); + }, + adjustTeXclass: function (prev) { + if (this.texClass === MML.TEXCLASS.NONE) {return prev} + if (prev) { + if (prev.autoOP && (this.texClass === MML.TEXCLASS.BIN || + this.texClass === MML.TEXCLASS.REL)) + {prev.texClass = MML.TEXCLASS.ORD} + this.prevClass = prev.texClass || MML.TEXCLASS.ORD; + this.prevLevel = prev.Get("scriptlevel") + } else {this.prevClass = MML.TEXCLASS.NONE} if (this.texClass === MML.TEXCLASS.BIN && (this.prevClass === MML.TEXCLASS.NONE || this.prevClass === MML.TEXCLASS.BIN || @@ -583,6 +693,17 @@ MathJax.ElementJax.mml.Augment({ this.texClass === MML.TEXCLASS.CLOSE || this.texClass === MML.TEXCLASS.PUNCT)) { prev.texClass = this.prevClass = MML.TEXCLASS.ORD; + } else if (this.texClass === MML.TEXCLASS.BIN) { + // + // Check if node is the last one in its container since the rule + // above only takes effect if there is a node that follows. + // + var child = this, parent = this.parent; + while (parent && parent.parent && parent.isEmbellished() && + (parent.data.length === 1 || + (parent.type !== "mrow" && parent.Core() === child))) // handles msubsup and munderover + {child = parent; parent = parent.parent} + if (parent.data[parent.data.length-1] === child) this.texClass = MML.TEXCLASS.ORD; } return this; } @@ -596,7 +717,8 @@ MathJax.ElementJax.mml.Augment({ mathvariant: MML.INHERIT, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, - mathcolor: MML.INHERIT + mathcolor: MML.INHERIT, + dir: MML.INHERIT } }); @@ -611,7 +733,16 @@ MathJax.ElementJax.mml.Augment({ depth: "0ex", linebreak: MML.LINEBREAK.AUTO }, - hasNewline: function () {return (this.Get("linebreak") === MML.LINEBREAK.NEWLINE)} + hasDimAttr: function () { + return (this.hasValue("width") || this.hasValue("height") || + this.hasValue("depth")); + }, + hasNewline: function () { + // The MathML spec says that the linebreak attribute should be ignored + // if any dimensional attribute is set. + return (!this.hasDimAttr() && + this.Get("linebreak") === MML.LINEBREAK.NEWLINE); + } }); MML.ms = MML.mbase.Subclass({ @@ -622,6 +753,7 @@ MathJax.ElementJax.mml.Augment({ mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, + dir: MML.INHERIT, lquote: '"', rquote: '"' } @@ -644,7 +776,7 @@ MathJax.ElementJax.mml.Augment({ MML.mrow = MML.mbase.Subclass({ type: "mrow", isSpacelike: MML.mbase.childrenSpacelike, - inferred: false, + inferred: false, notParent: false, isEmbellished: function () { var isEmbellished = false; for (var i = 0, m = this.data.length; i < m; i++) { @@ -685,17 +817,37 @@ MathJax.ElementJax.mml.Augment({ return this.SUPER(arguments).toString.call(this); }, setTeXclass: function (prev) { - for (var i = 0, m = this.data.length; i < m; i++) - {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}} - if (this.data[0]) {this.updateTeXclass(this.data[0])} - return prev; + var i, m = this.data.length; + if ((this.open || this.close) && (!prev || !prev.fnOP)) { + // + // came from \left...\right + // so treat as subexpression (tex class INNER) + // + this.getPrevClass(prev); prev = null; + for (i = 0; i < m; i++) + {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}} + if (!this.hasOwnProperty("texClass")) this.texClass = MML.TEXCLASS.INNER; + return this; + } else { + // + // Normal , so treat as + // thorugh mrow is not there + // + for (i = 0; i < m; i++) + {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}} + if (this.data[0]) {this.updateTeXclass(this.data[0])} + return prev; + } + }, + getAnnotation: function (name) { + if (this.data.length != 1) return null; + return this.data[0].getAnnotation(name); } }); MML.mfrac = MML.mbase.Subclass({ type: "mfrac", num: 0, den: 1, linebreakContainer: true, - texClass: MML.TEXCLASS.INNER, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, @@ -763,6 +915,7 @@ MathJax.ElementJax.mml.Augment({ scriptminsize: "8pt", mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, + dir: MML.INHERIT, infixlinebreakstyle: MML.LINEBREAKSTYLE.BEFORE, decimalseparator: "." }, @@ -771,9 +924,7 @@ MathJax.ElementJax.mml.Augment({ if (level == null) { level = this.Get("scriptlevel"); } else if (String(level).match(/^ *[-+]/)) { - delete this.scriptlevel; - var LEVEL = this.Get("scriptlevel"); - this.scriptlevel = level; + var LEVEL = this.Get("scriptlevel",null,true); level = LEVEL + parseInt(level); } return level; @@ -783,6 +934,7 @@ MathJax.ElementJax.mml.Augment({ mpadded: {width: true, height: true, depth: true, lspace: true, voffset: true}, mtable: {width: true, height: true, depth: true, align: true} }, + getRemoved: {fontfamily:"fontFamily", fontweight:"fontWeight", fontstyle:"fontStyle", fontsize:"fontSize"}, setTeXclass: MML.mbase.setChildTeXclass }); @@ -832,42 +984,62 @@ MathJax.ElementJax.mml.Augment({ close: ')', separators: ',' }, - texClass: MML.TEXCLASS.OPEN, - setTeXclass: function (prev) { - this.getPrevClass(prev); + addFakeNodes: function () { var values = this.getValues("open","close","separators"); values.open = values.open.replace(/[ \t\n\r]/g,""); values.close = values.close.replace(/[ \t\n\r]/g,""); values.separators = values.separators.replace(/[ \t\n\r]/g,""); - // create a fake node for the open item + // + // Create a fake node for the open item + // if (values.open !== "") { - this.SetData("open",MML.mo(values.open).With({stretchy:true, texClass:MML.TEXCLASS.OPEN})); - prev = this.data.open.setTeXclass(prev); + this.SetData("open",MML.mo(values.open).With({ + fence:true, form:MML.FORM.PREFIX, texClass:MML.TEXCLASS.OPEN + })); + // + // Clear flag for using MML spacing even though form is specified + // + this.data.open.useMMLspacing = 0; } - // get the separators + // + // Create fake nodes for the separators + // if (values.separators !== "") { while (values.separators.length < this.data.length) {values.separators += values.separators.charAt(values.separators.length-1)} - } - // handle the first item, if any - if (this.data[0]) {prev = this.data[0].setTeXclass(prev)} - // add fake nodes for separators and handle the following item - for (var i = 1, m = this.data.length; i < m; i++) { - if (this.data[i]) { - if (values.separators !== "") { - this.SetData("sep"+i,MML.mo(values.separators.charAt(i-1))); - prev = this.data["sep"+i].setTeXclass(prev); + for (var i = 1, m = this.data.length; i < m; i++) { + if (this.data[i]) { + this.SetData("sep"+i,MML.mo(values.separators.charAt(i-1)).With({separator:true})) + this.data["sep"+i].useMMLspacing = 0; } - prev = this.data[i].setTeXclass(prev); } } - // create fake node for the close item + // + // Create fake node for the close item + // if (values.close !== "") { - this.SetData("close",MML.mo(values.close).With({stretchy:true, texClass:MML.TEXCLASS.CLOSE})); - prev = this.data.close.setTeXclass(prev); + this.SetData("close",MML.mo(values.close).With({ + fence:true, form:MML.FORM.POSTFIX, texClass:MML.TEXCLASS.CLOSE + })); + // + // Clear flag for using MML spacing even though form is specified + // + this.data.close.useMMLspacing = 0; } - // get the data from the open item + }, + texClass: MML.TEXCLASS.OPEN, + setTeXclass: function (prev) { + this.addFakeNodes(); + this.getPrevClass(prev); + if (this.data.open) {prev = this.data.open.setTeXclass(prev)} + if (this.data[0]) {prev = this.data[0].setTeXclass(prev)} + for (var i = 1, m = this.data.length; i < m; i++) { + if (this.data["sep"+i]) {prev = this.data["sep"+i].setTeXclass(prev)} + if (this.data[i]) {prev = this.data[i].setTeXclass(prev)} + } + if (this.data.close) {prev = this.data.close.setTeXclass(prev)} this.updateTeXclass(this.data.open); + this.texClass = MML.TEXCLASS.INNER; return prev; } }); @@ -887,7 +1059,6 @@ MathJax.ElementJax.mml.Augment({ MML.msubsup = MML.mbase.Subclass({ type: "msubsup", base: 0, sub: 1, sup: 2, - linebreakContainer: true, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, @@ -1007,13 +1178,19 @@ MathJax.ElementJax.mml.Augment({ texClass: MML.TEXCLASS.ORD, useHeight: 1 }, + adjustChild_displaystyle: function () { + return (this.displaystyle != null ? this.displaystyle : this.defaults.displaystyle); + }, inheritFromMe: true, noInherit: { + mover: {align: true}, + munder: {align: true}, + munderover: {align: true}, mtable: { align: true, rowalign: true, columnalign: true, groupalign: true, alignmentscope: true, columnwidth: true, width: true, rowspacing: true, columnspacing: true, rowlines: true, columnlines: true, frame: true, - framespacing: true, equalrows: true, equalcolumns: true, + framespacing: true, equalrows: true, equalcolumns: true, displaystyle: true, side: true, minlabelspacing: true, texClass: true, useHeight: 1 } }, @@ -1021,7 +1198,7 @@ MathJax.ElementJax.mml.Augment({ Append: function () { for (var i = 0, m = arguments.length; i < m; i++) { if (!((arguments[i] instanceof MML.mtr) || - (arguments[i] instanceof MML.mlabeledtr))) {arguments[i] = MML.mtd(arguments[i])} + (arguments[i] instanceof MML.mlabeledtr))) {arguments[i] = MML.mtr(arguments[i])} } this.SUPER(arguments).Append.apply(this,arguments); }, @@ -1072,7 +1249,7 @@ MathJax.ElementJax.mml.Augment({ }); MML.maligngroup = MML.mbase.Subclass({ - type: "malign", + type: "maligngroup", isSpacelike: function () {return true}, defaults: { mathbackground: MML.INHERIT, @@ -1113,11 +1290,20 @@ MathJax.ElementJax.mml.Augment({ isSpacelike: function () {return this.selected().isSpacelike()}, Core: function () {return this.selected().Core()}, CoreMO: function () {return this.selected().CoreMO()}, - setTeXclass: function (prev) {return this.selected().setTeXclass(prev)} + setTeXclass: function (prev) { + if (this.Get("actiontype") === MML.ACTIONTYPE.TOOLTIP && this.data[1]) { + // Make sure tooltip has proper spacing when typeset (see issue #412) + this.data[1].setTeXclass(); + } + var selected = this.selected(); + prev = selected.setTeXclass(prev); + this.updateTeXclass(selected); + return prev; + } }); MML.semantics = MML.mbase.Subclass({ - type: "semantics", + type: "semantics", notParent: true, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, @@ -1125,10 +1311,24 @@ MathJax.ElementJax.mml.Augment({ definitionURL: null, encoding: null }, - setTeXclass: MML.mbase.setChildTeXclass + setTeXclass: MML.mbase.setChildTeXclass, + getAnnotation: function (name) { + var encodingList = MathJax.Hub.config.MathMenu.semanticsAnnotations[name]; + if (encodingList) { + for (var i = 0, m = this.data.length; i < m; i++) { + var encoding = this.data[i].Get("encoding"); + if (encoding) { + for (var j = 0, n = encodingList.length; j < n; j++) { + if (encodingList[j] === encoding) return this.data[i]; + } + } + } + } + return null; + } }); MML.annotation = MML.mbase.Subclass({ - type: "annotation", isToken: true, + type: "annotation", isChars: true, linebreakContainer: true, defaults: { definitionURL: null, @@ -1157,6 +1357,7 @@ MathJax.ElementJax.mml.Augment({ mathsize: MML.SIZE.NORMAL, mathcolor: "", // should be "black", but allow it to inherit from surrounding text mathbackground: MML.COLOR.TRANSPARENT, + dir: "ltr", scriptlevel: 0, displaystyle: MML.AUTO, display: "inline", @@ -1186,7 +1387,11 @@ MathJax.ElementJax.mml.Augment({ return ""; }, linebreakContainer: true, - setTeXclass: MML.mbase.setChildTeXclass + setTeXclass: MML.mbase.setChildTeXclass, + getAnnotation: function (name) { + if (this.data.length != 1) return null; + return this.data[0].getAnnotation(name); + } }); MML.chars = MML.mbase.Subclass({ @@ -1234,7 +1439,6 @@ MathJax.ElementJax.mml.Augment({ var nNode, i, m; if (node.nodeType === 1) { // ELEMENT_NODE nNode = document.createElement(node.nodeName); - if (node.className) {nNode.className=iNode.className} for (i = 0, m = node.attributes.length; i < m; i++) { var attribute = node.attributes[i]; if (attribute.specified && attribute.nodeValue != null && attribute.nodeValue != '') @@ -1259,13 +1463,16 @@ MathJax.ElementJax.mml.Augment({ MML.TeXAtom = MML.mbase.Subclass({ type: "texatom", - inferRow: true, + inferRow: true, notParent: true, texClass: MML.TEXCLASS.ORD, + Core: MML.mbase.childCore, + CoreMO: MML.mbase.childCoreMO, + isEmbellished: MML.mbase.childEmbellished, setTeXclass: function (prev) { - this.getPrevClass(prev); this.data[0].setTeXclass(); - return this; - } + return this.adjustTeXclass(prev); + }, + adjustTeXclass: MML.mo.prototype.adjustTeXclass }); MML.NULL = MML.mbase().With({type:"null"}); @@ -1597,8 +1804,13 @@ MathJax.ElementJax.mml.Augment({ // These are not in the W3C table, but FF works this way, // and it makes sense, so add it here // - MML.mo.prototype.OPTABLE.infix["^"] = MO.WIDEREL; - MML.mo.prototype.OPTABLE.infix["_"] = MO.WIDEREL; + var OPTABLE = MML.mo.prototype.OPTABLE; + OPTABLE.infix["^"] = MO.WIDEREL; + OPTABLE.infix["_"] = MO.WIDEREL; + OPTABLE.prefix["\u2223"] = MO.OPEN; + OPTABLE.prefix["\u2225"] = MO.OPEN; + OPTABLE.postfix["\u2223"] = MO.CLOSE; + OPTABLE.postfix["\u2225"] = MO.CLOSE; })(MathJax.ElementJax.mml); diff --git a/resources/viewer/mathjax/jax/element/mml/optable/Arrows.js b/resources/viewer/mathjax/jax/element/mml/optable/Arrows.js index a063c8c96c..bf0e35364e 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/Arrows.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/Arrows.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/Arrows.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/BasicLatin.js b/resources/viewer/mathjax/jax/element/mml/optable/BasicLatin.js index 5bf2957bdc..f69468f2ad 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/BasicLatin.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/BasicLatin.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/CombDiacritMarks.js b/resources/viewer/mathjax/jax/element/mml/optable/CombDiacritMarks.js index a4675c4708..4f705c666e 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/CombDiacritMarks.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/CombDiactForSymbols.js b/resources/viewer/mathjax/jax/element/mml/optable/CombDiactForSymbols.js index c26052d50c..bcebec2bb5 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/CombDiactForSymbols.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/CombDiactForSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/CombDiactForSymbols.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/Dingbats.js b/resources/viewer/mathjax/jax/element/mml/optable/Dingbats.js index aa24c74e00..ed89722bfc 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/Dingbats.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/Dingbats.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/Dingbats.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/GeneralPunctuation.js b/resources/viewer/mathjax/jax/element/mml/optable/GeneralPunctuation.js index 4e9e775e0a..544ea647b9 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/GeneralPunctuation.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/GeneralPunctuation.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/GeneralPunctuation.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/GeometricShapes.js b/resources/viewer/mathjax/jax/element/mml/optable/GeometricShapes.js index 4f373d02c5..d94705eb8c 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/GeometricShapes.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/GeometricShapes.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/GeometricShapes.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/GreekAndCoptic.js b/resources/viewer/mathjax/jax/element/mml/optable/GreekAndCoptic.js index e49775e238..a5c3890d3b 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/GreekAndCoptic.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/GreekAndCoptic.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/GreekAndCoptic.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/Latin1Supplement.js b/resources/viewer/mathjax/jax/element/mml/optable/Latin1Supplement.js index 2f426e7e62..834491c713 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/Latin1Supplement.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/Latin1Supplement.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/Latin1Supplement.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/LetterlikeSymbols.js b/resources/viewer/mathjax/jax/element/mml/optable/LetterlikeSymbols.js index 345650e719..65c35350bd 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/LetterlikeSymbols.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/LetterlikeSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/LetterlikeSymbols.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/MathOperators.js b/resources/viewer/mathjax/jax/element/mml/optable/MathOperators.js index 02c89be27a..6ade8943c3 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/MathOperators.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/MathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/MathOperators.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsA.js b/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsA.js index 83f16a51e3..ee0f854c27 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsA.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/MiscMathSymbolsA.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsB.js b/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsB.js index 2117d88226..ab0ede7050 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsB.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/MiscMathSymbolsB.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/MiscMathSymbolsB.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/MiscSymbolsAndArrows.js b/resources/viewer/mathjax/jax/element/mml/optable/MiscSymbolsAndArrows.js index 2609dc1ad7..723ac61c0e 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/MiscSymbolsAndArrows.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/MiscSymbolsAndArrows.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/MiscSymbolsAndArrows.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/MiscTechnical.js b/resources/viewer/mathjax/jax/element/mml/optable/MiscTechnical.js index 98b3c4c6d2..ad478a1c66 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/MiscTechnical.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/MiscTechnical.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/MiscTechnical.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/SpacingModLetters.js b/resources/viewer/mathjax/jax/element/mml/optable/SpacingModLetters.js index 11ffc5d281..75c925fe39 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/SpacingModLetters.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/SpacingModLetters.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/SpacingModLetters.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/SuppMathOperators.js b/resources/viewer/mathjax/jax/element/mml/optable/SuppMathOperators.js index 5e2be20a18..ff2afac9f3 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/SuppMathOperators.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/SuppMathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/SuppMathOperators.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsA.js b/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsA.js index 652771af9d..47a853b10b 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsA.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/SupplementalArrowsA.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsB.js b/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsB.js index 035a31e7c6..a3ddf0a97b 100644 --- a/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsB.js +++ b/resources/viewer/mathjax/jax/element/mml/optable/SupplementalArrowsB.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/optable/SupplementalArrowsB.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/AsciiMath/config.js b/resources/viewer/mathjax/jax/input/AsciiMath/config.js index 1a3f4286c4..09ce7fe811 100644 --- a/resources/viewer/mathjax/jax/input/AsciiMath/config.js +++ b/resources/viewer/mathjax/jax/input/AsciiMath/config.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/input/AsciiMath/config.js @@ -10,7 +13,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2012 Design Science, Inc. + * Copyright (c) 2012-2015 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. @@ -27,13 +30,15 @@ MathJax.InputJax.AsciiMath = MathJax.InputJax({ id: "AsciiMath", - version: "2.0", + version: "2.6.0", directory: MathJax.InputJax.directory + "/AsciiMath", extensionDir: MathJax.InputJax.extensionDir + "/AsciiMath", config: { + fixphi: true, // switch phi and varphi unicode values + useMathMLspacing: true, // use MathML spacing rather than TeX spacing? displaystyle: true, // put limits above and below operators - decimal: "." // can change to "," but watch out for "(1,2)" + decimalsign: "." // can change to "," but watch out for "(1,2)" } }); MathJax.InputJax.AsciiMath.Register("math/asciimath"); diff --git a/resources/viewer/mathjax/jax/input/AsciiMath/jax.js b/resources/viewer/mathjax/jax/input/AsciiMath/jax.js index c44136566c..367fac9dce 100644 --- a/resources/viewer/mathjax/jax/input/AsciiMath/jax.js +++ b/resources/viewer/mathjax/jax/input/AsciiMath/jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/input/AsciiMath/jax.js @@ -8,8 +11,11 @@ * Originally adapted for MathJax by David Lippman. * Additional work done by Davide P. Cervone. * + * The current development repository for AsciiMathML is + * https://github.com/mathjax/asciimathml + * * A portion of this file is taken from - * ASCIIMathML.js Version 1.4.7 Aug 30, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen + * ASCIIMathML.js Version 2.2 Mar 3, 2014, (c) Peter Jipsen http://www.chapman.edu/~jipsen * and is used by permission of Peter Jipsen, who has agreed to allow us to * release it under the Apache2 license (see below). That portion is indicated * via comments. @@ -18,7 +24,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2012 Design Science, Inc. + * Copyright (c) 2012-2015 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. @@ -78,6 +84,9 @@ old.nextSibling = old.parent = null; return old; }, + hasChildNodes: function (node) { + return (this.childNodes.length>0); + }, toString: function () {return "{"+this.childNodes.join("")+"}"} }); @@ -92,7 +101,7 @@ MML.mbase.Augment({ firstChild: null, lastChild: null, - nodeValue: "", + nodeValue: null, nextSibling: null, Init: function () { var obj = MBASEINIT.apply(this,arguments) || this; @@ -114,7 +123,6 @@ if (!this.firstChild) {this.firstChild = node} this.Append(node); this.lastChild = node; - this.nodeValue += node.nodeValue; } return node; }, @@ -129,9 +137,6 @@ else {this.lastChild = this.childNodes[this.childNodes.length-1]} } if (i) {this.childNodes[i-1].nextSibling = node.nextSibling} - this.nodeValue = ""; - for (i = 0, m = this.childNodes.length; i < m; i++) - {this.nodeValue += this.childNodes[i].nodeValue} node.nextSibling = node.parent = null; return node; }, @@ -142,12 +147,12 @@ if (i) {this.childNodes[i-1].nextSibling = node} else {this.firstChild = node} if (i >= m-1) {this.lastChild = node} this.SetData(i,node); node.nextSibling = old.nextSibling; - this.nodeValue = ""; - for (i = 0, m = this.childNodes.length; i < m; i++) - {this.nodeValue += this.childNodes[i].nodeValue} old.nextSibling = old.parent = null; return old; }, + hasChildNodes: function (node) { + return (this.childNodes.length>0); + }, setAttribute: function (name,value) {this[name] = value} }); }; @@ -164,7 +169,11 @@ // var document = { getElementById: true, - createElementNS: function (ns,type) {return MML[type]()}, + createElementNS: function (ns,type) { + var node = MML[type](); + if (type === "mo" && ASCIIMATH.config.useMathMLspacing) {node.useMMLspacing = 0x80} + return node; + }, createTextNode: function (text) {return MML.chars(text).With({nodeValue:text})}, createDocumentFragment: function () {return DOCFRAG()} }; @@ -175,133 +184,228 @@ /****************************************************************** * - * The following section is ASCIIMathML.js Version 1.4.7 + * The following section is ASCIIMathML.js Version 2.2 * (c) Peter Jipsen, used with permission. * * Some sections are commented out to save space in the * minified version (but that is not strictly necessary). - * A few items are commented out and marked with DPVC comments - * in order to keep the minifier from complaining about the - * coding practices in ASCIIMathML.js * - * Two sections are modified to include changes from version 2.0.1 of - * ASCIIMathML.js and are marked with comments to that effect. This - * makes this version effectively the same as version 2.0.1, but - * without the overhead of the LaTeX-processing code. - * ******************************************************************/ /* ASCIIMathML.js ============== This file contains JavaScript functions to convert ASCII math notation -to Presentation MathML. The conversion is done while the (X)HTML page -loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet -Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/). -Just add the next line to your (X)HTML page with this file in the same folder: - -This is a convenient and inexpensive solution for authoring MathML. +and (some) LaTeX to Presentation MathML. The conversion is done while the +HTML page loads, and should work with Firefox and other browsers that can +render MathML. -Version 1.4.7 Aug 30, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen -Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js -For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt +Just add the next line to your HTML page with this file in the same folder: + + + +Version 2.2 Mar 3, 2014. +Latest version at https://github.com/mathjax/asciimathml If you use it on a webpage, please send the URL to jipsen@chapman.edu -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at -your option) any later version. +Copyright (c) 2014 Peter Jipsen and other ASCIIMathML.js contributors -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License (at http://www.gnu.org/copyleft/gpl.html) -for more details. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ +//var asciimath = {}; -//var checkForMathML = true; // check if browser can display MathML -//var notifyIfNoMathML = true; // display note if no MathML capability -//var alertIfNoMathML = true; // show alert box if no MathML capability -var mathcolor = "red"; // change it to "" (to inherit) or any other color -var mathfontfamily = "serif"; // change to "" to inherit (works in IE) - // or another family (e.g. "arial") +//(function(){ +var mathcolor = "blue"; // change it to "" (to inherit) or another color +//var mathfontsize = "1em"; // change to e.g. 1.2em for larger math +var mathfontfamily = "serif"; // change to "" to inherit (works in IE) + // or another family (e.g. "arial") +//var automathrecognize = false; // writing "amath" on page makes this true +//var checkForMathML = true; // check if browser can display MathML +//var notifyIfNoMathML = true; // display note at top if no MathML capability +//var alertIfNoMathML = false; // show alert box if no MathML capability +//var translateOnLoad = true; // set to false to do call translators from js +//var translateASCIIMath = true; // false to preserve `..` var displaystyle = true; // puts limits above and below large operators var showasciiformulaonhover = true; // helps students learn ASCIIMath var decimalsign = "."; // change to "," if you like, beware of `(1,2)`! //var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters -//var AMdelimiter2 = "$", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\$"; -//var doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1` - // for IE this works only in -//var separatetokens;// has been removed (email me if this is a problem) -var isIE = document.createElementNS==null; +//var AMdocumentId = "wikitext" // PmWiki element containing math (default=body) +var fixphi = true; //false to return to legacy phi/varphi mapping -/* - * if (document.getElementById==null) - * alert("This webpage requires a recent browser such as\ - * \nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer") - */ +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -// all further global variables start with "AM" +var isIE = (navigator.appName.slice(0,9)=="Microsoft"); +/* +var noMathML = false, translated = false; -function AMcreateElementXHTML(t) { +if (isIE) { // add MathPlayer info to IE webpages + document.write(""); + document.write(""); +} + +// Add a stylesheet, replacing any previous custom stylesheet (adapted from TW) +function setStylesheet(s) { + var id = "AMMLcustomStyleSheet"; + var n = document.getElementById(id); + if(document.createStyleSheet) { + // Test for IE's non-standard createStyleSheet method + if(n) + n.parentNode.removeChild(n); + // This failed without the   + document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd"," "); + } else { + if(n) { + n.replaceChild(document.createTextNode(s),n.firstChild); + } else { + n = document.createElement("style"); + n.type = "text/css"; + n.id = id; + n.appendChild(document.createTextNode(s)); + document.getElementsByTagName("head")[0].appendChild(n); + } + } +} + +setStylesheet("#AMMLcloseDiv \{font-size:0.8em; padding-top:1em; color:#014\}\n#AMMLwarningBox \{position:absolute; width:100%; top:0; left:0; z-index:200; text-align:center; font-size:1em; font-weight:bold; padding:0.5em 0 0.5em 0; color:#ffc; background:#c30\}"); + +function init(){ + var msg, warnings = new Array(); + if (document.getElementById==null){ + alert("This webpage requires a recent browser such as Mozilla Firefox"); + return null; + } + if (checkForMathML && (msg = checkMathML())) warnings.push(msg); + if (warnings.length>0) displayWarnings(warnings); + if (!noMathML) initSymbols(); + return true; +} + +function checkMathML(){ + if (navigator.appName.slice(0,8)=="Netscape") + if (navigator.appVersion.slice(0,1)>="5") noMathML = null; + else noMathML = true; + else if (navigator.appName.slice(0,9)=="Microsoft") + try { + var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); + noMathML = null; + } catch (e) { + noMathML = true; + } + else if (navigator.appName.slice(0,5)=="Opera") + if (navigator.appVersion.slice(0,3)>="9.5") noMathML = null; + else noMathML = true; +//noMathML = true; //uncomment to check + if (noMathML && notifyIfNoMathML) { + var msg = "To view the ASCIIMathML notation use Internet Explorer + MathPlayer or Mozilla Firefox 2.0 or later."; + if (alertIfNoMathML) + alert(msg); + else return msg; + } +} + +function hideWarning(){ + var body = document.getElementsByTagName("body")[0]; + body.removeChild(document.getElementById('AMMLwarningBox')); + body.onclick = null; +} + +function displayWarnings(warnings) { + var i, frag, nd = createElementXHTML("div"); + var body = document.getElementsByTagName("body")[0]; + body.onclick=hideWarning; + nd.id = 'AMMLwarningBox'; + for (i=0; i="5") return null; - * else return AMnoMathMLNote(); - * else if (navigator.appName.slice(0,9)=="Microsoft") - * try { - * var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); - * return null; - * } catch (e) { - * return AMnoMathMLNote(); - * } - * else return AMnoMathMLNote(); - * } - */ +var AMmathml = "http://www.w3.org/1998/Math/MathML"; + +function AMcreateElementMathML(t) { + if (isIE) return document.createElement("m:"+t); + else return document.createElementNS(AMmathml,t); +} + +function createMmlNode(t,frag) { + var node; + if (isIE) node = document.createElement("m:"+t); + else node = document.createElementNS(AMmathml,t); + if (frag) node.appendChild(frag); + return node; +} + +function newcommand(oldstr,newstr) { + AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr, + tex:null, ttype:DEFINITION}]); + // #### Added from Version 2.0.1 #### // + AMsymbols.sort(compareNames); + for (i=0; i<", tag:"mo", output:"\u22C9", tex:"ltimes", ttype:CONST}, +{input:"><|", tag:"mo", output:"\u22CA", tex:"rtimes", ttype:CONST}, +{input:"|><|", tag:"mo", output:"\u22C8", tex:"bowtie", ttype:CONST}, +{input:"-:", tag:"mo", output:"\u00F7", tex:"div", ttype:CONST}, +{input:"divide", tag:"mo", output:"-:", tex:null, ttype:DEFINITION}, {input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST}, {input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST}, {input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST}, @@ -371,11 +483,14 @@ var AMsymbols = [ {input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST}, {input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST}, {input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST}, +{input:"gt", tag:"mo", output:">", tex:null, ttype:CONST}, {input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST}, -{input:"geq", tag:"mo", output:"\u2265", tex:null, ttype:CONST}, +{input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST}, {input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST}, {input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST}, {input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST}, +{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST}, +{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST}, {input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST}, {input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST}, {input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST}, @@ -433,7 +548,11 @@ var AMsymbols = [ {input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST}, {input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST}, {input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST}, +{input:"/_\\", tag:"mo", output:"\u25B3", tex:"triangle", ttype:CONST}, +{input:"'", tag:"mo", output:"\u2032", tex:"prime", ttype:CONST}, +{input:"tilde", tag:"mover", output:"~", tex:null, ttype:UNARY, acc:true}, {input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST}, +{input:"frown", tag:"mo", output:"\u2322", tex:null, ttype:CONST}, {input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST}, {input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST}, {input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST}, @@ -465,6 +584,17 @@ var AMsymbols = [ {input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true}, {input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true}, {input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true}, +{input:"arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true}, +{input:"arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true}, +{input:"arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true}, +{input:"coth", tag:"mo", output:"coth", tex:null, ttype:UNARY, func:true}, +{input:"sech", tag:"mo", output:"sech", tex:null, ttype:UNARY, func:true}, +{input:"csch", tag:"mo", output:"csch", tex:null, ttype:UNARY, func:true}, +{input:"exp", tag:"mo", output:"exp", tex:null, ttype:UNARY, func:true}, +{input:"abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, rewriteleftright:["|","|"]}, +{input:"norm", tag:"mo", output:"norm", tex:null, ttype:UNARY, rewriteleftright:["\u2225","\u2225"]}, +{input:"floor", tag:"mo", output:"floor", tex:null, ttype:UNARY, rewriteleftright:["\u230A","\u230B"]}, +{input:"ceil", tag:"mo", output:"ceil", tex:null, ttype:UNARY, rewriteleftright:["\u2308","\u2309"]}, {input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true}, {input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true}, {input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true}, @@ -482,32 +612,48 @@ var AMsymbols = [ {input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST}, {input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST}, {input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST}, +{input:">->", tag:"mo", output:"\u21A3", tex:"rightarrowtail", ttype:CONST}, +{input:"->>", tag:"mo", output:"\u21A0", tex:"twoheadrightarrow", ttype:CONST}, +{input:">->>", tag:"mo", output:"\u2916", tex:"twoheadrightarrowtail", ttype:CONST}, {input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST}, {input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST}, {input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST}, {input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST}, {input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST}, {input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST}, - //commands with argument -AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup, +{input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY}, +{input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY}, +{input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY}, +{input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX}, +{input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, +{input:"overset", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, +{input:"underset", tag:"munder", output:"stackrel", tex:null, ttype:BINARY}, +{input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX}, +{input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX}, {input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true}, {input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true}, {input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true}, {input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true}, {input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true}, {input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true}, -AMtext, AMmbox, AMquote, -{input:"bb", tag:"mstyle", atname:"fontweight", atval:"bold", output:"bb", tex:null, ttype:UNARY}, -{input:"mathbf", tag:"mstyle", atname:"fontweight", atval:"bold", output:"mathbf", tex:null, ttype:UNARY}, -{input:"sf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY}, -{input:"mathsf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY}, +{input:"ubrace", tag:"munder", output:"\u23DF", tex:"underbrace", ttype:UNARYUNDEROVER, acc:true}, +{input:"obrace", tag:"mover", output:"\u23DE", tex:"overbrace", ttype:UNARYUNDEROVER, acc:true}, +{input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT}, +{input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT}, +{input:"color", tag:"mstyle", ttype:BINARY}, +{input:"cancel", tag:"menclose", output:"cancel", tex:null, ttype:UNARY}, +AMquote, +{input:"bb", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"bb", tex:null, ttype:UNARY}, +{input:"mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"mathbf", tex:null, ttype:UNARY}, +{input:"sf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY}, +{input:"mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY}, {input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb}, {input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb}, {input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal}, {input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal}, -{input:"tt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"tt", tex:null, ttype:UNARY}, -{input:"mathtt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY}, +{input:"tt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"tt", tex:null, ttype:UNARY}, +{input:"mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY}, {input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk}, {input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk} ]; @@ -519,39 +665,28 @@ function compareNames(s1,s2) { var AMnames = []; //list of input symbols -function AMinitSymbols() { +function initSymbols() { var texsymbols = [], i; for (i=0; i=n where str appears or would be inserted // assumes arr is sorted if (n==0) { @@ -594,7 +729,7 @@ function AMgetSymbol(str) { for (var i=1; i<=str.length && more; i++) { st = str.slice(0,i); //initial substring of length i j = k; - k = AMposition(AMnames, st, j); + k = position(AMnames, st, j); if (kst || st>"Z") && ("a">st || st>"z")?"mo":"mi"); } - // #### Replaced by lines from Version 2.0.1 #### // if (st=="-" && AMpreviousSymbol==INFIX) { AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse return {input:st, tag:tagst, output:st, ttype:UNARY, func:true}; } - // #### End of Replacement #### // return {input:st, tag:tagst, output:st, ttype:CONST}; } function AMremoveBrackets(node) { var st; - if (node.nodeName=="mrow") { + if (!node.hasChildNodes()) { return; } + if (node.firstChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) { st = node.firstChild.firstChild.nodeValue; if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild); } - if (node.nodeName=="mrow") { + if (node.lastChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) { st = node.lastChild.firstChild.nodeValue; if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild); } @@ -681,11 +815,10 @@ function AMparseSexpr(str) { //parses str and returns [node,tailstr] str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); symbol = AMgetSymbol(str); } - switch (symbol.ttype) { - case UNDEROVER: + switch (symbol.ttype) { case UNDEROVER: case CONST: str = AMremoveCharsAndBlanks(str,symbol.input.length); - return [AMcreateMmlNode(symbol.tag, //its a constant + return [createMmlNode(symbol.tag, //its a constant document.createTextNode(symbol.output)),str]; case LEFTBRACKET: //read (expr+) AMnestingDepth++; @@ -693,10 +826,10 @@ function AMparseSexpr(str) { //parses str and returns [node,tailstr] result = AMparseExpr(str,true); AMnestingDepth--; if (typeof symbol.invisible == "boolean" && symbol.invisible) - node = AMcreateMmlNode("mrow",result[0]); + node = createMmlNode("mrow",result[0]); else { - node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); - node = AMcreateMmlNode("mrow",node); + node = createMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mrow",node); node.appendChild(result[0]); } return [node,result[1]]; @@ -710,42 +843,53 @@ function AMparseSexpr(str) { //parses str and returns [node,tailstr] if (i==-1) i = str.length; st = str.slice(1,i); if (st.charAt(0) == " ") { - node = AMcreateElementMathML("mspace"); + node = createMmlNode("mspace"); node.setAttribute("width","1ex"); newFrag.appendChild(node); } newFrag.appendChild( - AMcreateMmlNode(symbol.tag,document.createTextNode(st))); + createMmlNode(symbol.tag,document.createTextNode(st))); if (st.charAt(st.length-1) == " ") { - node = AMcreateElementMathML("mspace"); + node = createMmlNode("mspace"); node.setAttribute("width","1ex"); newFrag.appendChild(node); } str = AMremoveCharsAndBlanks(str,i+1); - return [AMcreateMmlNode("mrow",newFrag),str]; + return [createMmlNode("mrow",newFrag),str]; + case UNARYUNDEROVER: case UNARY: str = AMremoveCharsAndBlanks(str,symbol.input.length); result = AMparseSexpr(str); - if (result[0]==null) return [AMcreateMmlNode(symbol.tag, + if (result[0]==null) return [createMmlNode(symbol.tag, document.createTextNode(symbol.output)),str]; if (typeof symbol.func == "boolean" && symbol.func) { // functions hack st = str.charAt(0); - if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") { - return [AMcreateMmlNode(symbol.tag, + if (st=="^" || st=="_" || st=="/" || st=="|" || st=="," || + (symbol.input.length==1 && symbol.input.match(/\w/) && st!="(")) { + return [createMmlNode(symbol.tag, document.createTextNode(symbol.output)),str]; } else { - node = AMcreateMmlNode("mrow", - AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); + node = createMmlNode("mrow", + createMmlNode(symbol.tag,document.createTextNode(symbol.output))); node.appendChild(result[0]); return [node,result[1]]; } } AMremoveBrackets(result[0]); if (symbol.input == "sqrt") { // sqrt - return [AMcreateMmlNode(symbol.tag,result[0]),result[1]]; + return [createMmlNode(symbol.tag,result[0]),result[1]]; + } else if (typeof symbol.rewriteleftright != "undefined") { // abs, floor, ceil + node = createMmlNode("mrow", createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[0]))); + node.appendChild(result[0]); + node.appendChild(createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[1]))); + return [node,result[1]]; + } else if (symbol.input == "cancel") { // cancel + node = createMmlNode(symbol.tag,result[0]); + node.setAttribute("notation","updiagonalstrike"); + return [node,result[1]]; } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent - node = AMcreateMmlNode(symbol.tag,result[0]); - node.appendChild(AMcreateMmlNode("mo",document.createTextNode(symbol.output))); + node = createMmlNode(symbol.tag,result[0]); + node.appendChild(createMmlNode("mo",document.createTextNode(symbol.output))); return [node,result[1]]; } else { // font change command if (!isIE && typeof symbol.codes != "undefined") { @@ -755,73 +899,84 @@ function AMparseSexpr(str) { //parses str and returns [node,tailstr] result[0].childNodes[i].firstChild.nodeValue); var newst = []; for (var j=0; j64 && st.charCodeAt(j)<91) newst = newst + - String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]); + if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) + newst = newst + symbol.codes[st.charCodeAt(j)-65]; + else if (st.charCodeAt(j)>96 && st.charCodeAt(j)<123) + newst = newst + symbol.codes[st.charCodeAt(j)-71]; else newst = newst + st.charAt(j); if (result[0].nodeName=="mi") - result[0]=AMcreateElementMathML("mo"). + result[0]=createMmlNode("mo"). appendChild(document.createTextNode(newst)); - else result[0].replaceChild(AMcreateElementMathML("mo"). - appendChild(document.createTextNode(newst)),result[0].childNodes[i]); + else result[0].replaceChild(createMmlNode("mo"). + appendChild(document.createTextNode(newst)), + result[0].childNodes[i]); } } - node = AMcreateMmlNode(symbol.tag,result[0]); + node = createMmlNode(symbol.tag,result[0]); node.setAttribute(symbol.atname,symbol.atval); return [node,result[1]]; } case BINARY: str = AMremoveCharsAndBlanks(str,symbol.input.length); result = AMparseSexpr(str); - if (result[0]==null) return [AMcreateMmlNode("mo", + if (result[0]==null) return [createMmlNode("mo", document.createTextNode(symbol.input)),str]; AMremoveBrackets(result[0]); var result2 = AMparseSexpr(result[1]); - if (result2[0]==null) return [AMcreateMmlNode("mo", + if (result2[0]==null) return [createMmlNode("mo", document.createTextNode(symbol.input)),str]; AMremoveBrackets(result2[0]); - if (symbol.input=="root" || symbol.input=="stackrel") + if (symbol.input=="color") { + if (str.charAt(0)=="{") i=str.indexOf("}"); + else if (str.charAt(0)=="(") i=str.indexOf(")"); + else if (str.charAt(0)=="[") i=str.indexOf("]"); + st = str.slice(1,i); + node = createMmlNode(symbol.tag,result2[0]); + node.setAttribute("mathcolor",st); + return [node,result2[1]]; + } + if (symbol.input=="root" || symbol.output=="stackrel") newFrag.appendChild(result2[0]); newFrag.appendChild(result[0]); if (symbol.input=="frac") newFrag.appendChild(result2[0]); - return [AMcreateMmlNode(symbol.tag,newFrag),result2[1]]; + return [createMmlNode(symbol.tag,newFrag),result2[1]]; case INFIX: str = AMremoveCharsAndBlanks(str,symbol.input.length); - return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str]; + return [createMmlNode("mo",document.createTextNode(symbol.output)),str]; case SPACE: str = AMremoveCharsAndBlanks(str,symbol.input.length); - node = AMcreateElementMathML("mspace"); + node = createMmlNode("mspace"); node.setAttribute("width","1ex"); newFrag.appendChild(node); newFrag.appendChild( - AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); - node = AMcreateElementMathML("mspace"); + createMmlNode(symbol.tag,document.createTextNode(symbol.output))); + node = createMmlNode("mspace"); node.setAttribute("width","1ex"); newFrag.appendChild(node); - return [AMcreateMmlNode("mrow",newFrag),str]; + return [createMmlNode("mrow",newFrag),str]; case LEFTRIGHT: // if (rightvert) return [null,str]; else rightvert = true; AMnestingDepth++; str = AMremoveCharsAndBlanks(str,symbol.input.length); result = AMparseExpr(str,false); AMnestingDepth--; - /*var*//*DPVC*/ st = ""; + st = ""; if (result[0].lastChild!=null) st = result[0].lastChild.firstChild.nodeValue; -//alert(result[0].lastChild+"***"+st); if (st == "|") { // its an absolute value subterm - node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); - node = AMcreateMmlNode("mrow",node); + node = createMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mrow",node); node.appendChild(result[0]); return [node,result[1]]; - } else { // the "|" is a \mid - node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); - node = AMcreateMmlNode("mrow",node); + } else { // the "|" is a \mid so use unicode 2223 (divides) for spacing + node = createMmlNode("mo",document.createTextNode("\u2223")); + node = createMmlNode("mrow",node); return [node,str]; } default: //alert("default"); str = AMremoveCharsAndBlanks(str,symbol.input.length); - return [AMcreateMmlNode(symbol.tag, //its a constant + return [createMmlNode(symbol.tag, //its a constant document.createTextNode(symbol.output)),str]; } } @@ -839,36 +994,48 @@ function AMparseIexpr(str) { // if (symbol.input == "/") result = AMparseIexpr(str); else ... result = AMparseSexpr(str); if (result[0] == null) // show box in place of missing argument - result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); + result[0] = createMmlNode("mo",document.createTextNode("\u25A1")); else AMremoveBrackets(result[0]); str = result[1]; // if (symbol.input == "/") AMremoveBrackets(node); + underover = (sym1.ttype == UNDEROVER || sym1.ttype == UNARYUNDEROVER); if (symbol.input == "_") { sym2 = AMgetSymbol(str); - underover = (sym1.ttype == UNDEROVER); if (sym2.input == "^") { str = AMremoveCharsAndBlanks(str,sym2.input.length); var res2 = AMparseSexpr(str); AMremoveBrackets(res2[0]); str = res2[1]; - node = AMcreateMmlNode((underover?"munderover":"msubsup"),node); + node = createMmlNode((underover?"munderover":"msubsup"),node); node.appendChild(result[0]); node.appendChild(res2[0]); - node = AMcreateMmlNode("mrow",node); // so sum does not stretch + node = createMmlNode("mrow",node); // so sum does not stretch } else { - node = AMcreateMmlNode((underover?"munder":"msub"),node); + node = createMmlNode((underover?"munder":"msub"),node); node.appendChild(result[0]); } + } else if (symbol.input == "^" && underover) { + node = createMmlNode("mover",node); + node.appendChild(result[0]); } else { - node = AMcreateMmlNode(symbol.tag,node); + node = createMmlNode(symbol.tag,node); node.appendChild(result[0]); } + if (typeof sym1.func != 'undefined' && sym1.func) { + sym2 = AMgetSymbol(str); + if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) { + result = AMparseIexpr(str); + node = createMmlNode("mrow",node); + node.appendChild(result[0]); + str = result[1]; + } + } } return [node,str]; } function AMparseExpr(str,rightbracket) { - var symbol, node, result, i, /*nodeList = [],*//*DPVC*/ + var symbol, node, result, i, newFrag = document.createDocumentFragment(); do { str = AMremoveCharsAndBlanks(str,0); @@ -880,11 +1047,11 @@ function AMparseExpr(str,rightbracket) { str = AMremoveCharsAndBlanks(str,symbol.input.length); result = AMparseIexpr(str); if (result[0] == null) // show box in place of missing argument - result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); + result[0] = createMmlNode("mo",document.createTextNode("\u25A1")); else AMremoveBrackets(result[0]); str = result[1]; AMremoveBrackets(node); - node = AMcreateMmlNode(symbol.tag,node); + node = createMmlNode(symbol.tag,node); node.appendChild(result[0]); newFrag.appendChild(node); symbol = AMgetSymbol(str); @@ -896,9 +1063,12 @@ function AMparseExpr(str,rightbracket) { if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) { // if (AMnestingDepth > 0) AMnestingDepth--; var len = newFrag.childNodes.length; - if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 && - newFrag.childNodes[len-2].nodeName == "mo" && - newFrag.childNodes[len-2].firstChild.nodeValue == ",") { //matrix + if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" + && newFrag.childNodes[len-1].lastChild + && newFrag.childNodes[len-1].lastChild.firstChild ) { //matrix + //removed to allow row vectors: //&& len>1 && + //newFrag.childNodes[len-2].nodeName == "mo" && + //newFrag.childNodes[len-2].firstChild.nodeValue == "," var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue; if (right==")" || right=="]") { var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue; @@ -921,6 +1091,7 @@ function AMparseExpr(str,rightbracket) { pos[i][pos[i].length]=j; if (matrix && i>1) matrix = pos[i].length == pos[i-2].length; } + matrix = matrix && (pos.length>1 || pos[0].length>0); if (matrix) { var row, frag, n, k, table = document.createDocumentFragment(); for (i=0; i2) { newFrag.removeChild(newFrag.firstChild); //remove ) newFrag.removeChild(newFrag.firstChild); //remove , } - table.appendChild(AMcreateMmlNode("mtr",row)); + table.appendChild(createMmlNode("mtr",row)); } - node = AMcreateMmlNode("mtable",table); + node = createMmlNode("mtable",table); if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left"); newFrag.replaceChild(node,newFrag.firstChild); } @@ -953,198 +1124,208 @@ function AMparseExpr(str,rightbracket) { } str = AMremoveCharsAndBlanks(str,symbol.input.length); if (typeof symbol.invisible != "boolean" || !symbol.invisible) { - node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); + node = createMmlNode("mo",document.createTextNode(symbol.output)); newFrag.appendChild(node); } } return [newFrag,str]; } -function AMparseMath(str) { - var /*result,*//*DPVC*/ node = AMcreateElementMathML("mstyle"); - if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); - if (displaystyle) node.setAttribute("displaystyle","true"); - if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); +function parseMath(str,latex) { + var frag, node; AMnestingDepth = 0; - node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false)[0]); - node = AMcreateMmlNode("math",node); + //some basic cleanup for dealing with stuff editors like TinyMCE adds + str = str.replace(/ /g,""); + str = str.replace(/>/g,">"); + str = str.replace(/</g,"<"); + str = str.replace(/(Sin|Cos|Tan|Arcsin|Arccos|Arctan|Sinh|Cosh|Tanh|Cot|Sec|Csc|Log|Ln|Abs)/g, function(v) { return v.toLowerCase(); }); + frag = AMparseExpr(str.replace(/^\s+/g,""),false)[0]; + node = createMmlNode("mstyle",frag); + if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); + if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); + if (displaystyle) node.setAttribute("displaystyle","true"); + node = createMmlNode("math",node); if (showasciiformulaonhover) //fixed by djhsu so newline node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko - if (mathfontfamily != "" && (isIE || mathfontfamily != "serif")) { - var fnode = AMcreateElementXHTML("font"); - fnode.setAttribute("face",mathfontfamily); - fnode.appendChild(node); - return fnode; - } return node; } -/* - * function AMstrarr2docFrag(arr, linebreaks) { - * var newFrag=document.createDocumentFragment(); - * var expr = false; - * for (var i=0; i1 || mtch) { - * if (checkForMathML) { - * checkForMathML = false; - * var nd = AMisMathMLavailable(); - * AMnoMathML = nd != null; - * if (AMnoMathML && notifyIfNoMathML) - * if (alertIfNoMathML) - * alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\ - * or Firefox/Mozilla/Netscape"); - * else AMbody.insertBefore(nd,AMbody.childNodes[0]); - * } - * if (!AMnoMathML) { - * frg = AMstrarr2docFrag(arr,n.nodeType==8); - * var len = frg.childNodes.length; - * n.parentNode.replaceChild(frg,n); - * return len-1; - * } else return 0; - * } - * } - * } else return 0; - * } else if (n.nodeName!="math") { - * for (i=0; i"); - * document.write(""); - * } - * - * // GO1.1 Generic onload by Brothercake - * // http://www.brothercake.com/ - * //onload function (replaces the onload="translate()" in the tag) - * function generic() - * { - * translate(); - * }; - * //setup onload function - * if(typeof window.addEventListener != 'undefined') - * { - * //.. gecko, safari, konqueror and standard - * window.addEventListener('load', generic, false); - * } - * else if(typeof document.addEventListener != 'undefined') - * { - * //.. opera 7 - * document.addEventListener('load', generic, false); - * } - * else if(typeof window.attachEvent != 'undefined') - * { - * //.. win/ie - * window.attachEvent('onload', generic); - * } - * //** remove this condition to degrade older browsers - * else - * { - * //.. mac/ie5 and anything else that gets this far - * //if there's an existing onload function - * if(typeof window.onload == 'function') - * { - * //store it - * var existing = onload; - * //add new onload handler - * window.onload = function() - * { - * //call existing onload function - * existing(); - * //call generic onload function - * generic(); - * }; - * } - * else - * { - * //setup onload function - * window.onload = generic; - * } - * } - */ +/* +function strarr2docFrag(arr, linebreaks, latex) { + var newFrag=document.createDocumentFragment(); + var expr = false; + for (var i=0; i,\\|!:;'~]|\\.(?!(?:\x20|$))|"+ambigAMtoken+englishAMtoken+simpleAMtoken; + var re = new RegExp("(^|\\s)((("+token+")\\s?)(("+token+secondenglishAMtoken+")\\s?)+)([,.?]?(?=\\s|$))","g"); + str = str.replace(re," `$2`$7"); + var arr = str.split(AMdelimiter1); + var re1 = new RegExp("(^|\\s)([b-zB-HJ-Z+*<>]|"+texcommand+ambigAMtoken+simpleAMtoken+")(\\s|\\n|$)","g"); + var re2 = new RegExp("(^|\\s)([a-z]|"+texcommand+ambigAMtoken+simpleAMtoken+")([,.])","g"); // removed |\d+ for now + for (i=0; i1 || mtch) { + if (!noMathML) { + frg = strarr2docFrag(arr,n.nodeType==8,latex); + var len = frg.childNodes.length; + n.parentNode.replaceChild(frg,n); + return len-1; + } else return 0; + } + } + } else return 0; + } else if (n.nodeName!="math") { + for (i=0; i", tex:null, ttype:CONST}, - {input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST}, - {input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST}, - {input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST}, - {input:"'", tag:"mo", output:"\u2032", tex:"prime", ttype:CONST}, - {input:"arcsin", tag:"mi", output:"arcsin", tex:null, ttype:UNARY, func:true}, - {input:"arccos", tag:"mi", output:"arccos", tex:null, ttype:UNARY, func:true}, - {input:"arctan", tag:"mi", output:"arctan", tex:null, ttype:UNARY, func:true}, - {input:"coth", tag:"mi", output:"coth", tex:null, ttype:UNARY, func:true}, - {input:"sech", tag:"mi", output:"sech", tex:null, ttype:UNARY, func:true}, - {input:"csch", tag:"mi", output:"csch", tex:null, ttype:UNARY, func:true}, - {input:"abs", tag:"mi", output:"abs", tex:null, ttype:UNARY, func:true}, - {input:"exp", tag:"mi", output:"exp", tex:null, ttype:UNARY, func:true}, - {input:"tilde", tag:"mover", output:"~", tex:null, ttype:UNARY, acc:true} -) - // // Access to AsciiMath functions and values // @@ -1193,69 +1352,79 @@ ASCIIMATH.Augment({ AM: { Init: function () { displaystyle = ASCIIMATH.config.displaystyle; - decimal = ASCIIMATH.config.decimal; + // Old versions use the "decimal" option, so take it into account if it + // is defined by the user. See issue 384. + decimalsign = (ASCIIMATH.config.decimal || ASCIIMATH.config.decimalsign); + // unfix phi and varphi, if requested + if (!ASCIIMATH.config.fixphi) { + for (var i = 0, m = AMsymbols.length; i < m; i++) { + if (AMsymbols[i].input === "phi") {AMsymbols[i].output = "\u03C6"} + if (AMsymbols[i].input === "varphi") {AMsymbols[i].output = "\u03D5"; i = m} + } + } + INITASCIIMATH(); - AMinitSymbols(); + initSymbols(); }, Augment: function (def) { for (var id in def) {if (def.hasOwnProperty(id)) { switch (id) { case "displaystyle": displaystyle = def[id]; break; case "decimal": decimal = def[id]; break; - case "parseMath": AMparseMath = def[id]; break; + case "parseMath": parseMath = def[id]; break; case "parseExpr": AMparseExpr = def[id]; break; case "parseIexpr": AMparseIexpr = def[id]; break; case "parseSexpr": AMparseSexpr = def[id]; break; case "removeBrackets": AMremoveBrackets = def[id]; break; case "getSymbol": AMgetSymbol = def[id]; break; - case "position": AMposition = def[id]; break; + case "position": position = def[id]; break; case "removeCharsAndBlanks": AMremoveCharsAndBlanks = def[id]; break; - case "createMmlNode": AMcreateMmlNode = def[id]; break; + case "createMmlNode": createMmlNode = def[id]; break; case "createElementMathML": AMcreateElementMathML = def[id]; break; - case "createElementXHTML": AMcreateElementXHTML = def[id]; break; - case "initSymbols": AMinitSymbols = def[id]; break; - case "compareNames": comareNames = def[id]; break; + case "createElementXHTML": createElementXHTML = def[id]; break; + case "initSymbols": initSymbols = def[id]; break; + case "refreshSymbols": refreshSymbols = def[id]; break; + case "compareNames": compareNames = def[id]; break; }; this[id] = def[id]; }}; }, - parseMath: AMparseMath, + parseMath: parseMath, parseExpr: AMparseExpr, parseIexpr: AMparseIexpr, parseSexr: AMparseSexpr, removeBrackets: AMremoveBrackets, getSymbol: AMgetSymbol, - position: AMposition, + position: position, removeCharsAndBlanks: AMremoveCharsAndBlanks, - createMmlNode: AMcreateMmlNode, + createMmlNode: createMmlNode, createElementMathML: AMcreateElementMathML, - createElementXHTML: AMcreateElementXHTML, - initSymbols: AMinitSymbols, + createElementXHTML: createElementXHTML, + initSymbols: initSymbols, + refreshSymbols: refreshSymbols, compareNames: compareNames, createDocumentFragment: DOCFRAG, document: document, - define: newcommand, + define: define, + newcommand: newcommand, symbols: AMsymbols, names: AMnames, TOKEN: { CONST:CONST, UNARY:UNARY, BINARY:BINARY, INFIX:INFIX, LEFTBRACKET:LEFTBRACKET, RIGHTBRACKET:RIGHTBRACKET, SPACE:SPACE, - UNDEROVER:UNDEROVER, DEFINITION:DEFINITION, LEFTRIGHT:LEFTRIGHT, TEXT:TEXT + UNDEROVER:UNDEROVER, DEFINITION:DEFINITION, LEFTRIGHT:LEFTRIGHT, TEXT:TEXT, + UNARYUNDEROVER:UNARYUNDEROVER } } }); // // Make minimizer think these have been used -var junk = [ - window, navigator //, -// checkForMathML, notifyIfNoMathML, alertIfNoMathML, AMdelimiter1, AMescape1, -// AMdelimiter2, AMescape2, AMdelimiter2regexp, doubleblankmathdelimiter -]; -junk = null; +// +var junk = [window, navigator]; junk = null; })(MathJax.InputJax.AsciiMath); @@ -1266,7 +1435,8 @@ junk = null; var MML; ASCIIMATH.Augment({ - sourceMenuTitle: "AsciiMath Input", + sourceMenuTitle: /*_(MathMenu)*/ ["AsciiMathInput","AsciiMath Input"], + annotationEncoding: "text/x-asciimath", prefilterHooks: MathJax.Callback.Hooks(true), // hooks to run before processing AsciiMath postfilterHooks: MathJax.Callback.Hooks(true), // hooks to run after processing AsciiMath @@ -1274,7 +1444,8 @@ junk = null; Translate: function (script) { var mml, math = MathJax.HTML.getScript(script); var data = {math:math, script:script}; - this.prefilterHooks.Execute(data); math = data.math; + var callback = this.prefilterHooks.Execute(data); if (callback) return callback; + math = data.math; try { mml = this.AM.parseMath(math); } catch(err) { @@ -1282,12 +1453,12 @@ junk = null; mml = this.formatError(err,math); } data.math = MML(mml); this.postfilterHooks.Execute(data); - return data.math; + return this.postfilterHooks.Execute(data) || data.math; }, formatError: function (err,math,script) { var message = err.message.replace(/\n.*/,""); MathJax.Hub.signal.Post(["AsciiMath Jax - parse error",message,math,script]); - return MML.merror(message); + return MML.Error(message); }, Error: function (message) { throw MathJax.Hub.Insert(Error(message),{asciimathError: true}); diff --git a/resources/viewer/mathjax/jax/input/MathML/config.js b/resources/viewer/mathjax/jax/input/MathML/config.js index 9253914dae..55d127e4bb 100644 --- a/resources/viewer/mathjax/jax/input/MathML/config.js +++ b/resources/viewer/mathjax/jax/input/MathML/config.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/input/MathML/config.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -24,7 +27,7 @@ MathJax.InputJax.MathML = MathJax.InputJax({ id: "MathML", - version: "2.0", + version: "2.6.0", directory: MathJax.InputJax.directory + "/MathML", extensionDir: MathJax.InputJax.extensionDir + "/MathML", entityDir: MathJax.InputJax.directory + "/MathML/entities", diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/a.js b/resources/viewer/mathjax/jax/input/MathML/entities/a.js index 3b14cdc5d7..84aaab800a 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/a.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/a.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/a.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/b.js b/resources/viewer/mathjax/jax/input/MathML/entities/b.js index c7c104084e..ca5274d80b 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/b.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/b.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/b.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/c.js b/resources/viewer/mathjax/jax/input/MathML/entities/c.js index 197140be91..d1bddd45a8 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/c.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/c.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/c.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/d.js b/resources/viewer/mathjax/jax/input/MathML/entities/d.js index 1722dfb3cc..b3b99cfba6 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/d.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/d.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/d.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/e.js b/resources/viewer/mathjax/jax/input/MathML/entities/e.js index 45475f1ce2..d8d209ba88 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/e.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/e.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/e.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/f.js b/resources/viewer/mathjax/jax/input/MathML/entities/f.js index 5d5348a75c..cf6ab496e8 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/f.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/f.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/f.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/fr.js b/resources/viewer/mathjax/jax/input/MathML/entities/fr.js index d6b2e12b1a..b1c5bb63fe 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/fr.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/fr.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/fr.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/g.js b/resources/viewer/mathjax/jax/input/MathML/entities/g.js index dad288e768..173e53f80e 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/g.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/g.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/g.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/h.js b/resources/viewer/mathjax/jax/input/MathML/entities/h.js index bf1ad4f7e9..d1cfe41a1b 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/h.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/h.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/h.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/i.js b/resources/viewer/mathjax/jax/input/MathML/entities/i.js index 059928ba6c..df2283a8e0 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/i.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/i.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/i.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/j.js b/resources/viewer/mathjax/jax/input/MathML/entities/j.js index 5147e2d7bb..2834cd3fac 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/j.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/j.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/j.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/k.js b/resources/viewer/mathjax/jax/input/MathML/entities/k.js index 2342a8c6fa..5c95e58ca9 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/k.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/k.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/k.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/l.js b/resources/viewer/mathjax/jax/input/MathML/entities/l.js index 2615de2a47..7ebb8797c3 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/l.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/l.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/l.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/m.js b/resources/viewer/mathjax/jax/input/MathML/entities/m.js index 4a5ed5e58e..8449974206 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/m.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/m.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/m.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/n.js b/resources/viewer/mathjax/jax/input/MathML/entities/n.js index 46495495da..7a1c65b4ef 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/n.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/n.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/n.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/o.js b/resources/viewer/mathjax/jax/input/MathML/entities/o.js index d15a9608ac..4246dd55d6 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/o.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/o.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/o.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/opf.js b/resources/viewer/mathjax/jax/input/MathML/entities/opf.js index cc8c55225d..9e5b9ed20e 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/opf.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/opf.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/opf.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/p.js b/resources/viewer/mathjax/jax/input/MathML/entities/p.js index e8ee2c3f92..8926f21047 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/p.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/p.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/p.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/q.js b/resources/viewer/mathjax/jax/input/MathML/entities/q.js index e2773ea268..9f3141eb29 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/q.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/q.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/q.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/r.js b/resources/viewer/mathjax/jax/input/MathML/entities/r.js index 9a25327b73..07440dff64 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/r.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/r.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/r.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/s.js b/resources/viewer/mathjax/jax/input/MathML/entities/s.js index 8c26da89cf..0cbe489f4b 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/s.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/s.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/s.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/scr.js b/resources/viewer/mathjax/jax/input/MathML/entities/scr.js index 062968b734..508cf7212c 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/scr.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/scr.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/scr.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/t.js b/resources/viewer/mathjax/jax/input/MathML/entities/t.js index 8b2746eb3f..f3461ef0af 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/t.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/t.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/t.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/u.js b/resources/viewer/mathjax/jax/input/MathML/entities/u.js index e4c9f38a9d..d40c549863 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/u.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/u.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/u.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/v.js b/resources/viewer/mathjax/jax/input/MathML/entities/v.js index b76e16d1ad..ec6475ab5a 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/v.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/v.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/v.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/w.js b/resources/viewer/mathjax/jax/input/MathML/entities/w.js index 73186eeac9..0970fb2a71 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/w.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/w.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/w.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/x.js b/resources/viewer/mathjax/jax/input/MathML/entities/x.js index f6bb122643..fedb4012bd 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/x.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/x.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/x.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/y.js b/resources/viewer/mathjax/jax/input/MathML/entities/y.js index 913d61daa7..1f47113b29 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/y.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/y.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/y.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/entities/z.js b/resources/viewer/mathjax/jax/input/MathML/entities/z.js index 385b9ffea4..df759e22f7 100644 --- a/resources/viewer/mathjax/jax/input/MathML/entities/z.js +++ b/resources/viewer/mathjax/jax/input/MathML/entities/z.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/HTML-CSS/entities/z.js * - * Copyright (c) 2010 Design Science, Inc. + * Copyright (c) 2010-2015 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. diff --git a/resources/viewer/mathjax/jax/input/MathML/jax.js b/resources/viewer/mathjax/jax/input/MathML/jax.js index a703cfd19f..df917f4802 100644 --- a/resources/viewer/mathjax/jax/input/MathML/jax.js +++ b/resources/viewer/mathjax/jax/input/MathML/jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/input/MathML/jax.js @@ -8,7 +11,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2010-2012 Design Science, Inc. + * Copyright (c) 2010-2015 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. @@ -26,39 +29,43 @@ (function (MATHML,BROWSER) { var MML; + var _ = function (id) { + return MathJax.Localization._.apply(MathJax.Localization, + [["MathML",id]].concat([].slice.call(arguments,1))) + }; + MATHML.Parse = MathJax.Object.Subclass({ - Init: function (string) {this.Parse(string)}, + Init: function (string,script) {this.Parse(string,script)}, // // Parse the MathML and check for errors // - Parse: function (math) { + Parse: function (math,script) { var doc; if (typeof math !== "string") {doc = math.parentNode} else { - if (math.match(/^<[a-z]+:/i) && !math.match(/^<[^<>]* xmlns:/)) - {math = math.replace(/^<([a-z]+)(:math)/i,'<$1$2 xmlns:$1="http://www.w3.org/1998/Math/MathML"')} - // HTML5 removes xmlns: namespaces, so put them back for XML - var match = math.match(/^(])+)>)/i); - if (match && match[2].match(/ (?!xmlns=)[a-z]+=\"http:/i)) { - math = match[1].replace(/ (?!xmlns=)([a-z]+=(['"])http:.*?\2)/ig," xmlns:$1 $1") + - math.substr(match[0].length); - } - math = math.replace(/^\s*(?:\/\/)?\s*$/,"$2"); - math = math.replace(/&([a-z][a-z0-9]*);/ig,this.replaceEntity); - doc = MATHML.ParseXML(math); if (doc == null) {MATHML.Error("Error parsing MathML")} + doc = MATHML.ParseXML(this.preProcessMath.call(this,math)); + if (doc == null) {MATHML.Error(["ErrorParsingMathML","Error parsing MathML"])} } var err = doc.getElementsByTagName("parsererror")[0]; - if (err) MATHML.Error("Error parsing MathML: "+err.textContent.replace(/This page.*?errors:|XML Parsing Error: |Below is a rendering of the page.*/g,"")); - if (doc.childNodes.length !== 1) MATHML.Error("MathML must be formed by a single element"); + if (err) MATHML.Error(["ParsingError","Error parsing MathML: %1", + err.textContent.replace(/This page.*?errors:|XML Parsing Error: |Below is a rendering of the page.*/g,"")]); + if (doc.childNodes.length !== 1) + {MATHML.Error(["MathMLSingleElement","MathML must be formed by a single element"])} if (doc.firstChild.nodeName.toLowerCase() === "html") { var h1 = doc.getElementsByTagName("h1")[0]; if (h1 && h1.textContent === "XML parsing error" && h1.nextSibling) - MATHML.Error("Error parsing MathML: "+String(h1.nextSibling.nodeValue).replace(/fatal parsing error: /,"")); + MATHML.Error(["ParsingError","Error parsing MathML: %1", + String(h1.nextSibling.nodeValue).replace(/fatal parsing error: /,"")]); } - if (doc.firstChild.nodeName.toLowerCase().replace(/^[a-z]+:/,"") !== "math") - MATHML.Error("MathML must be formed by a element, not <"+doc.firstChild.nodeName+">"); - this.mml = this.MakeMML(doc.firstChild); + if (doc.firstChild.nodeName.toLowerCase().replace(/^[a-z]+:/,"") !== "math") { + MATHML.Error(["MathMLRootElement", + "MathML must be formed by a element, not %1", + "<"+doc.firstChild.nodeName+">"]); + } + var data = {math:doc.firstChild, script:script}; + MATHML.DOMfilterHooks.Execute(data); + this.mml = this.MakeMML(data.math); }, // @@ -72,11 +79,11 @@ mml = this.TeXAtom(match[2]); } else if (!(MML[type] && MML[type].isa && MML[type].isa(MML.mbase))) { MathJax.Hub.signal.Post(["MathML Jax - unknown node type",type]); - return MML.merror("Unknown node type: "+type); + return MML.Error(_("UnknownNodeType","Unknown node type: %1",type)); } else { mml = MML[type](); } - this.AddAttributes(mml,node); this.CheckClass(mml,CLASS); + this.AddAttributes(mml,node); this.CheckClass(mml,mml["class"]); this.AddChildren(mml,node); if (MATHML.config.useMathMLspacing) {mml.useMMLspacing = 0x08} return mml; @@ -87,11 +94,15 @@ return mml; }, CheckClass: function (mml,CLASS) { - CLASS = CLASS.split(/ /); var NCLASS = []; + CLASS = (CLASS||"").split(/ /); var NCLASS = []; for (var i = 0, m = CLASS.length; i < m; i++) { if (CLASS[i].substr(0,4) === "MJX-") { if (CLASS[i] === "MJX-arrow") { - mml.arrow = true; + // This class was used in former versions of MathJax to attach an + // arrow to the updiagonalstrike notation. For backward + // compatibility, let's continue to accept this case. See issue 481. + if (!mml.notation.match("/"+MML.NOTATION.UPDIAGONALARROW+"/")) + mml.notation += " "+MML.NOTATION.UPDIAGONALARROW; } else if (CLASS[i] === "MJX-variant") { mml.variantForm = true; // @@ -126,14 +137,20 @@ var name = node.attributes[i].name; if (name == "xlink:href") {name = "href"} if (name.match(/:/)) continue; + if (name.match(/^_moz-math-((column|row)(align|line)|font-style)$/)) continue; var value = node.attributes[i].value; - if (value.toLowerCase() === "true") {value = true} - else if (value.toLowerCase() === "false") {value = false} - if (mml.defaults[name] != null || MML.copyAttributes[name]) - {mml[name] = value} else {mml.attr[name] = value} - mml.attrNames.push(name); + value = this.filterAttribute(name,value); + var defaults = (mml.type === "mstyle" ? MML.math.prototype.defaults : mml.defaults); + if (value != null) { + if (value.toLowerCase() === "true") {value = true} + else if (value.toLowerCase() === "false") {value = false} + if (defaults[name] != null || MML.copyAttributes[name]) + {mml[name] = value} else {mml.attr[name] = value} + mml.attrNames.push(name); + } } }, + filterAttribute: function (name,value) {return value}, // safe mode overrides this // // Create the children for the mml node @@ -143,11 +160,16 @@ var child = node.childNodes[i]; if (child.nodeName === "#comment") continue; if (child.nodeName === "#text") { - if (mml.isToken && !mml.mmlSelfClosing) { - var text = child.nodeValue.replace(/&([a-z][a-z0-9]*);/ig,this.replaceEntity); - mml.Append(MML.chars(this.trimSpace(text))); + if ((mml.isToken || mml.isChars) && !mml.mmlSelfClosing) { + var text = child.nodeValue; + if (mml.isToken) { + text = text.replace(/&([a-z][a-z0-9]*);/ig,this.replaceEntity); + text = this.trimSpace(text); + } + mml.Append(MML.chars(text)); } else if (child.nodeValue.match(/\S/)) { - MATHML.Error("Unexpected text node: '"+child.nodeValue+"'"); + MATHML.Error(["UnexpectedTextNode", + "Unexpected text node: %1","'"+child.nodeValue+"'"]); } } else if (mml.type === "annotation-xml") { mml.Append(MML.xml(child)); @@ -157,8 +179,37 @@ {mml.Append.apply(mml,cmml.data); cmml.data = []} } } + if (mml.type === "mrow" && mml.data.length >= 2) { + var first = mml.data[0], last = mml.data[mml.data.length-1]; + if (first.type === "mo" && first.Get("fence") && + last.type === "mo" && last.Get("fence")) { + if (first.data[0]) {mml.open = first.data.join("")} + if (last.data[0]) {mml.close = last.data.join("")} + } + } }, + // + // Clean Up the source to prepare for XML parsing + // + preProcessMath: function (math) { + if (math.match(/^<[a-z]+:/i) && !math.match(/^<[^<>]* xmlns:/)) { + math = math.replace(/^<([a-z]+)(:math)/i,'<$1$2 xmlns:$1="http://www.w3.org/1998/Math/MathML"') + } + // HTML5 removes xmlns: namespaces, so put them back for XML + var match = math.match(/^(])+)>)/i); + if (match && match[2].match(/ (?!xmlns=)[a-z]+=\"http:/i)) { + math = match[1].replace(/ (?!xmlns=)([a-z]+=(['"])http:.*?\2)/ig," xmlns:$1 $1") + + math.substr(match[0].length); + } + if (math.match(/^]* xmlns=/)) { + // append the MathML namespace + math = math.replace(/^<(math)/i,'\s*$/,"$2"); + return math.replace(/&([a-z][a-z0-9]*);/ig,this.replaceEntity); + }, + // // Remove attribute whitespace // @@ -192,10 +243,11 @@ /************************************************************************/ MATHML.Augment({ - sourceMenuTitle: "Original MathML", + sourceMenuTitle: /*_(MathMenu)*/ ["OriginalMathML","Original MathML"], - prefilterHooks: MathJax.Callback.Hooks(true), // hooks to run before processing MathML - postfilterHooks: MathJax.Callback.Hooks(true), // hooks to run after processing MathML + prefilterHooks: MathJax.Callback.Hooks(true), // hooks to run on MathML string before processing MathML + DOMfilterHooks: MathJax.Callback.Hooks(true), // hooks to run on MathML DOM before processing + postfilterHooks: MathJax.Callback.Hooks(true), // hooks to run on internal jax format after processing MathML Translate: function (script) { if (!this.ParseXML) {this.ParseXML = this.createParser()} @@ -203,29 +255,34 @@ if (script.firstChild && script.firstChild.nodeName.toLowerCase().replace(/^[a-z]+:/,"") === "math") { data.math = script.firstChild; - this.prefilterHooks.Execute(data); math = data.math; } else { math = MathJax.HTML.getScript(script); if (BROWSER.isMSIE) {math = math.replace(/( )+$/,"")} - data.math = math; this.prefilterHooks.Execute(data); math = data.math; + data.math = math; } + var callback = this.prefilterHooks.Execute(data); if (callback) return callback; + math = data.math; try { - mml = MATHML.Parse(math).mml; + mml = MATHML.Parse(math,script).mml; } catch(err) { if (!err.mathmlError) {throw err} mml = this.formatError(err,math,script); } - data.math = MML(mml); this.postfilterHooks.Execute(data); - return data.math; + data.math = MML(mml); + return this.postfilterHooks.Execute(data) || data.math; }, prefilterMath: function (math,script) {return math}, prefilterMathML: function (math,script) {return math}, formatError: function (err,math,script) { var message = err.message.replace(/\n.*/,""); MathJax.Hub.signal.Post(["MathML Jax - parse error",message,math,script]); - return MML.merror(message); + return MML.Error(message); }, Error: function (message) { + // + // Translate message if it is ["id","message",args] + // + if (message instanceof Array) {message = _.apply(_,message)} throw MathJax.Hub.Insert(Error(message),{mathmlError: true}); }, // @@ -234,10 +291,25 @@ parseDOM: function (string) {return this.parser.parseFromString(string,"text/xml")}, parseMS: function (string) {return (this.parser.loadXML(string) ? this.parser : null)}, parseDIV: function (string) { - this.div.innerHTML = string.replace(/<([a-z]+)([^>]*)\/>/g,"<$1$2>"); - return this.div; + this.div.innerHTML = + "
"+string.replace(/<([a-z]+)([^>]*)\/>/g,"<$1$2>")+"
"; + var doc = this.div.firstChild; + this.div.innerHTML = ""; + return doc; }, parseError: function (string) {return null}, + createMSParser: function() { + var parser = null; + var xml = ["MSXML2.DOMDocument.6.0","MSXML2.DOMDocument.5.0", + "MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0", + "MSXML2.DOMDocument.2.0","Microsoft.XMLDOM"]; + for (var i = 0, m = xml.length; i < m && !parser; i++) { + try { + parser = new ActiveXObject(xml[i]) + } catch (err) {} + } + return parser; + }, // // Create the parser using a DOMParser, or other fallback method // @@ -246,17 +318,9 @@ this.parser = new DOMParser(); return(this.parseDOM); } else if (window.ActiveXObject) { - var xml = ["MSXML2.DOMDocument.6.0","MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0", - "MSXML2.DOMDocument.3.0","MSXML2.DOMDocument.2.0","Microsoft.XMLDOM"]; - for (var i = 0, m = xml.length; i < m && !this.parser; i++) - {try {this.parser = new ActiveXObject(xml[i])} catch (err) {}} + this.parser = this.createMSParser(); if (!this.parser) { - alert("MathJax can't create an XML parser for MathML. Check that\n"+ - "the 'Script ActiveX controls marked safe for scripting' security\n"+ - "setting is enabled (use the Internet Options item in the Tools\n"+ - "menu, and select the Security panel, then press the Custom Level\n"+ - "button to check this).\n\n"+ - "MathML equations will not be able to be processed by MathJax."); + MathJax.Localization.Try(this.parserCreationError); return(this.parseError); } this.parser.async = false; @@ -270,6 +334,15 @@ else {document.body.insertBefore(this.div,document.body.firstChild)} return(this.parseDIV); }, + parserCreationError: function () { + alert(_("CantCreateXMLParser", + "MathJax can't create an XML parser for MathML. Check that\n"+ + "the 'Script ActiveX controls marked safe for scripting' security\n"+ + "setting is enabled (use the Internet Options item in the Tools\n"+ + "menu, and select the Security panel, then press the Custom Level\n"+ + "button to check this).\n\n"+ + "MathML equations will not be able to be processed by MathJax.")); + }, // // Initialize the parser object (whichever type is used) // @@ -278,6 +351,8 @@ MML.mspace.Augment({mmlSelfClosing: true}); MML.none.Augment({mmlSelfClosing: true}); MML.mprescripts.Augment({mmlSelfClosing:true}); + MML.maligngroup.Augment({mmlSelfClosing:true}); + MML.malignmark.Augment({mmlSelfClosing:true}); } }); diff --git a/resources/viewer/mathjax/jax/input/TeX/config.js b/resources/viewer/mathjax/jax/input/TeX/config.js index 5add16aa2f..6b4828288c 100644 --- a/resources/viewer/mathjax/jax/input/TeX/config.js +++ b/resources/viewer/mathjax/jax/input/TeX/config.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/input/TeX/config.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -24,7 +27,7 @@ MathJax.InputJax.TeX = MathJax.InputJax({ id: "TeX", - version: "2.0", + version: "2.6.0", directory: MathJax.InputJax.directory + "/TeX", extensionDir: MathJax.InputJax.extensionDir + "/TeX", diff --git a/resources/viewer/mathjax/jax/input/TeX/jax.js b/resources/viewer/mathjax/jax/input/TeX/jax.js index cf50a72884..1c1f8f69f5 100644 --- a/resources/viewer/mathjax/jax/input/TeX/jax.js +++ b/resources/viewer/mathjax/jax/input/TeX/jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/input/TeX/jax.js @@ -8,7 +11,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2009-2012 Design Science, Inc. + * Copyright (c) 2009-2015 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. @@ -26,6 +29,11 @@ (function (TEX,HUB,AJAX) { var MML, NBSP = "\u00A0"; + var _ = function (id) { + return MathJax.Localization._.apply(MathJax.Localization, + [["TeX", id]].concat([].slice.call(arguments,1))); + }; + var STACK = MathJax.Object.Subclass({ Init: function (env,inner) { this.global = {isInner: inner}; @@ -36,7 +44,7 @@ Push: function () { var i, m, item, top; for (i = 0, m = arguments.length; i < m; i++) { - item = arguments[i]; + item = arguments[i]; if (!item) continue; if (item instanceof MML.mbase) {item = STACKITEM.mml(item)} item.global = this.global; top = (this.data.length ? this.Top().checkItem(item) : true); @@ -72,8 +80,9 @@ var STACKITEM = STACK.Item = MathJax.Object.Subclass({ type: "base", - closeError: "Extra close brace or missing open brace", - rightError: "Missing \\left or extra \\right", + endError: /*_()*/ ["ExtraOpenMissingClose","Extra open brace or missing close brace"], + closeError: /*_()*/ ["ExtraCloseMissingOpen","Extra close brace or missing open brace"], + rightError: /*_()*/ ["MissingLeftExtraRight","Missing \\left or extra \\right"], Init: function () { if (this.isOpen) {this.env = {}} this.data = []; @@ -90,7 +99,7 @@ if (item.type === "over" && this.isOpen) {item.num = this.mmlData(false); this.data = []} if (item.type === "cell" && this.isOpen) { if (item.linebreak) {return false} - TEX.Error("Misplaced "+item.name); + TEX.Error(["Misplaced","Misplaced %1",item.name]); } if (item.isClose && this[item.type+"Error"]) {TEX.Error(this[item.type+"Error"])} if (!item.isNotStack) {return true} @@ -121,10 +130,10 @@ STACKITEM.open = STACKITEM.Subclass({ type: "open", isOpen: true, - stopError: "Extra open brace or missing close brace", + stopError: /*_()*/ ["ExtraOpenMissingClose","Extra open brace or missing close brace"], checkItem: function (item) { if (item.type === "close") { - var mml = this.mmlData(); // this.mmlData(true,true); // force row + var mml = this.mmlData(); return STACKITEM.mml(MML.TeXAtom(mml)); // TeXAtom make it an ORD to prevent spacing (FIXME: should be another way) } return this.SUPER(arguments).checkItem.call(this,item); @@ -135,18 +144,34 @@ type: "close", isClose: true }); + STACKITEM.prime = STACKITEM.Subclass({ + type: "prime", + checkItem: function (item) { + if (this.data[0].type !== "msubsup") + {return [MML.msup(this.data[0],this.data[1]),item]} + this.data[0].SetData(this.data[0].sup,this.data[1]); + return [this.data[0],item]; + } + }); + STACKITEM.subsup = STACKITEM.Subclass({ type: "subsup", - stopError: "Missing superscript or subscript argument", + stopError: /*_()*/ ["MissingScript","Missing superscript or subscript argument"], + supError: /*_()*/ ["MissingOpenForSup","Missing open brace for superscript"], + subError: /*_()*/ ["MissingOpenForSub","Missing open brace for subscript"], checkItem: function (item) { - var script = ["","subscript","superscript"][this.position]; if (item.type === "open" || item.type === "left") {return true} if (item.type === "mml") { + if (this.primes) { + if (this.position !== 2) {this.data[0].SetData(2,this.primes)} + else {item.data[0] = MML.mrow(this.primes.With({variantForm:true}),item.data[0])} + } this.data[0].SetData(this.position,item.data[0]); + if (this.movesupsub != null) {this.data[0].movesupsub = this.movesupsub} return STACKITEM.mml(this.data[0]); } if (this.SUPER(arguments).checkItem.call(this,item)) - {TEX.Error("Missing open brace for "+script)} + {TEX.Error(this[["","subError","supError"][this.position]])} }, Pop: function () {} }); @@ -154,14 +179,14 @@ STACKITEM.over = STACKITEM.Subclass({ type: "over", isClose: true, name: "\\over", checkItem: function (item,stack) { - if (item.type === "over") {TEX.Error("Ambiguous use of "+item.name)} + if (item.type === "over") + {TEX.Error(["AmbiguousUseOf","Ambiguous use of %1",item.name])} if (item.isClose) { var mml = MML.mfrac(this.num,this.mmlData(false)); if (this.thickness != null) {mml.linethickness = this.thickness} if (this.open || this.close) { - mml.texClass = MML.TEXCLASS.INNER; mml.texWithDelims = true; - mml = MML.mfenced(mml).With({open: this.open, close: this.close}); + mml = TEX.fixedFence(this.open,mml,this.close); } return [STACKITEM.mml(mml), item]; } @@ -172,12 +197,10 @@ STACKITEM.left = STACKITEM.Subclass({ type: "left", isOpen: true, delim: '(', - stopError: "Extra \\left or missing \\right", + stopError: /*_()*/ ["ExtraLeftMissingRight", "Extra \\left or missing \\right"], checkItem: function (item) { - if (item.type === "right") { - var mml = MML.mfenced(this.data.length === 1 ? this.data[0] : MML.mrow.apply(MML,this.data)); - return STACKITEM.mml(mml.With({open: this.delim, close: item.delim})); - } + if (item.type === "right") + {return STACKITEM.mml(TEX.fenced(this.delim,this.mmlData(),item.delim))} return this.SUPER(arguments).checkItem.call(this,item); } }); @@ -191,11 +214,12 @@ checkItem: function (item) { if (item.type === "end") { if (item.name !== this.name) - {TEX.Error("\\begin{"+this.name+"} ended with \\end{"+item.name+"}")} + {TEX.Error(["EnvBadEnd","\\begin{%1} ended with \\end{%2}",this.name,item.name])} if (!this.end) {return STACKITEM.mml(this.mmlData())} return this.parse[this.end].call(this.parse,this,this.data); } - if (item.type === "stop") {TEX.Error("Missing \\end{"+this.name+"}")} + if (item.type === "stop") + {TEX.Error(["EnvMissingEnd","Missing \\end{%1}",this.name])} return this.SUPER(arguments).checkItem.call(this,item); } }); @@ -216,7 +240,7 @@ STACKITEM.position = STACKITEM.Subclass({ type: "position", checkItem: function (item) { - if (item.isClose) {TEX.Error("Missing box for "+this.name)} + if (item.isClose) {TEX.Error(["MissingBoxFor","Missing box for %1",this.name])} if (item.isNotStack) { var mml = item.mmlData(); switch (this.move) { @@ -234,7 +258,7 @@ STACKITEM.array = STACKITEM.Subclass({ type: "array", isOpen: true, arraydef: {}, Init: function () { - this.table = []; this.row = []; this.env = {}; this.frame = [] + this.table = []; this.row = []; this.env = {}; this.frame = []; this.hfill = []; this.SUPER(arguments).Init.apply(this,arguments); }, checkItem: function (item) { @@ -242,6 +266,7 @@ if (item.isEntry) {this.EndEntry(); this.clearEnv(); return false} if (item.isCR) {this.EndEntry(); this.EndRow(); this.clearEnv(); return false} this.EndTable(); this.clearEnv(); + var scriptlevel = this.arraydef.scriptlevel; delete this.arraydef.scriptlevel; var mml = MML.mtable.apply(MML,this.table).With(this.arraydef); if (this.frame.length === 4) { mml.frame = (this.frame.dashed ? "dashed" : "solid"); @@ -252,20 +277,34 @@ if ((this.arraydef.columnlines||"none") != "none" || (this.arraydef.rowlines||"none") != "none") {mml.padding = 0} // HTML-CSS jax implements this } - if (this.open || this.close) { - mml = MML.mfenced(mml).With({open: this.open, close: this.close}); - } + if (scriptlevel) {mml = MML.mstyle(mml).With({scriptlevel: scriptlevel})} + if (this.open || this.close) {mml = TEX.fenced(this.open,mml,this.close)} mml = STACKITEM.mml(mml); if (this.requireClose) { if (item.type === 'close') {return mml} - TEX.Error("Missing close brace"); + TEX.Error(["MissingCloseBrace","Missing close brace"]); } return [mml,item]; } return this.SUPER(arguments).checkItem.call(this,item); }, - EndEntry: function () {this.row.push(MML.mtd.apply(MML,this.data)); this.data = []}, - EndRow: function () {this.table.push(MML.mtr.apply(MML,this.row)); this.row = []}, + EndEntry: function () { + var mtd = MML.mtd.apply(MML,this.data); + if (this.hfill.length) { + if (this.hfill[0] === 0) mtd.columnalign = "right"; + if (this.hfill[this.hfill.length-1] === this.data.length) + mtd.columnalign = (mtd.columnalign ? "center" : "left"); + } + this.row.push(mtd); this.data = []; this.hfill = []; + }, + EndRow: function () { + var mtr = MML.mtr; + if (this.isNumbered && this.row.length === 3) { + this.row.unshift(this.row.pop()); // move equation number to first position + mtr = MML.mlabeledtr; + } + this.table.push(mtr.apply(MML,this.row)); this.row = []; + }, EndTable: function () { if (this.data.length || this.row.length) {this.EndEntry(); this.EndRow()} this.checkLines(); @@ -282,7 +321,7 @@ } if (this.rowspacing) { var rows = this.arraydef.rowspacing.split(/ /); - while (rows.length < this.table.length) {rows.push(this.rowspacing)} + while (rows.length < this.table.length) {rows.push(this.rowspacing+"em")} this.arraydef.rowspacing = rows.join(' '); } }, @@ -304,10 +343,13 @@ type: "fn", checkItem: function (item) { if (this.data[0]) { - if (item.type !== "mml" || !item.data[0]) {return [this.data[0],item]} - if (item.data[0].isa(MML.mspace)) {return [this.data[0],item]} - var mml = item.data[0]; if (mml.isEmbellished()) {mml = mml.CoreMO()} - if ([0,0,1,1,0,1,1,0,0,0][mml.Get("texClass")]) {return [this.data[0],item]} + if (item.isOpen) {return true} + if (item.type !== "fn") { + if (item.type !== "mml" || !item.data[0]) {return [this.data[0],item]} + if (item.data[0].isa(MML.mspace)) {return [this.data[0],item]} + var mml = item.data[0]; if (mml.isEmbellished()) {mml = mml.CoreMO()} + if ([0,0,1,1,0,1,1,0,0,0][mml.Get("texClass")]) {return [this.data[0],item]} + } return [this.data[0],MML.mo(MML.entity("#x2061")).With({texClass:MML.TEXCLASS.NONE}),item]; } return this.SUPER(arguments).checkItem.apply(this,arguments); @@ -335,9 +377,11 @@ } }); STACKITEM.not.remap = { + 0x2190:0x219A, 0x2192:0x219B, 0x2194:0x21AE, + 0x21D0:0x21CD, 0x21D2:0x21CF, 0x21D4:0x21CE, 0x2208:0x2209, 0x220B:0x220C, 0x2223:0x2224, 0x2225:0x2226, 0x223C:0x2241, 0x007E:0x2241, 0x2243:0x2244, 0x2245:0x2247, - 0x2248:0x2249, 0x003D:0x2260, 0x2261:0x2262, + 0x2248:0x2249, 0x224D:0x226D, 0x003D:0x2260, 0x2261:0x2262, 0x003C:0x226E, 0x003E:0x226F, 0x2264:0x2270, 0x2265:0x2271, 0x2272:0x2274, 0x2273:0x2275, 0x2276:0x2278, 0x2277:0x2279, 0x227A:0x2280, 0x227B:0x2281, 0x2282:0x2284, 0x2283:0x2285, @@ -400,12 +444,14 @@ '%': 'Comment', '&': 'Entry', '#': 'Hash', + '\u00A0': 'Space', '\u2019': 'Prime' }, remap: { '-': '2212', - '*': '2217' + '*': '2217', + '`': '2018' // map ` to back quote }, mathchar0mi: { @@ -442,9 +488,9 @@ varphi: '03C6', // Ord symbols - S: '00A7', + S: ['00A7',{mathvariant: MML.VARIANT.NORMAL}], aleph: ['2135',{mathvariant: MML.VARIANT.NORMAL}], - hbar: '210F', + hbar: ['210F',{variantForm:true}], imath: '0131', jmath: '0237', ell: '2113', @@ -453,14 +499,14 @@ Im: ['2111',{mathvariant: MML.VARIANT.NORMAL}], partial: ['2202',{mathvariant: MML.VARIANT.NORMAL}], infty: ['221E',{mathvariant: MML.VARIANT.NORMAL}], - prime: ['2032',{mathvariant: MML.VARIANT.NORMAL}], + prime: ['2032',{mathvariant: MML.VARIANT.NORMAL, variantForm:true}], emptyset: ['2205',{mathvariant: MML.VARIANT.NORMAL}], nabla: ['2207',{mathvariant: MML.VARIANT.NORMAL}], top: ['22A4',{mathvariant: MML.VARIANT.NORMAL}], bot: ['22A5',{mathvariant: MML.VARIANT.NORMAL}], angle: ['2220',{mathvariant: MML.VARIANT.NORMAL}], triangle: ['25B3',{mathvariant: MML.VARIANT.NORMAL}], - backslash: ['2216',{mathvariant: MML.VARIANT.NORMAL}], + backslash: ['2216',{mathvariant: MML.VARIANT.NORMAL, variantForm:true}], forall: ['2200',{mathvariant: MML.VARIANT.NORMAL}], exists: ['2203',{mathvariant: MML.VARIANT.NORMAL}], neg: ['00AC',{mathvariant: MML.VARIANT.NORMAL}], @@ -527,7 +573,7 @@ pm: '00B1', circ: '2218', bigcirc: '25EF', - setminus: '2216', + setminus: ['2216',{variantForm:true}], cdot: '22C5', ast: '2217', times: '00D7', @@ -757,10 +803,12 @@ limits: ['Limits',1], nolimits: ['Limits',0], - overline: ['UnderOver','00AF'], + overline: ['UnderOver','00AF',null,1], underline: ['UnderOver','005F'], overbrace: ['UnderOver','23DE',1], underbrace: ['UnderOver','23DF',1], + overparen: ['UnderOver','23DC'], + underparen: ['UnderOver','23DD'], overrightarrow: ['UnderOver','2192'], underrightarrow: ['UnderOver','2192'], overleftarrow: ['UnderOver','2190'], @@ -862,18 +910,18 @@ hphantom: ['Phantom',0,1], smash: 'Smash', - acute: ['Accent', "02CA"], // or 0301 - grave: ['Accent', "02CB"], // or 0300 + acute: ['Accent', "00B4"], // or 0301 or 02CA + grave: ['Accent', "0060"], // or 0300 or 02CB ddot: ['Accent', "00A8"], // or 0308 - tilde: ['Accent', "02DC"], // or 0303 - bar: ['Accent', "02C9"], // or 0304 + tilde: ['Accent', "007E"], // or 0303 or 02DC + bar: ['Accent', "00AF"], // or 0304 or 02C9 breve: ['Accent', "02D8"], // or 0306 check: ['Accent', "02C7"], // or 030C - hat: ['Accent', "02C6"], // or 0302 - vec: ['Accent', "20D7"], + hat: ['Accent', "005E"], // or 0302 or 02C6 + vec: ['Accent', "2192"], // or 20D7 dot: ['Accent', "02D9"], // or 0307 - widetilde: ['Accent', "02DC",1], // or 0303 - widehat: ['Accent', "02C6",1], // or 0302 + widetilde: ['Accent', "007E",1], // or 0303 or 02DC + widehat: ['Accent', "005E",1], // or 0302 or 02C6 matrix: 'Matrix', array: 'Matrix', @@ -887,11 +935,14 @@ hline: ['HLine','solid'], hdashline: ['HLine','dashed'], // noalign: 'HandleNoAlign', - eqalignno: ['Matrix',null,null,"right left right",MML.LENGTH.THICKMATHSPACE+" 3em",".5em",'D'], - leqalignno: ['Matrix',null,null,"right left right",MML.LENGTH.THICKMATHSPACE+" 3em",".5em",'D'], + eqalignno: ['Matrix',null,null,"right left",MML.LENGTH.THICKMATHSPACE,".5em",'D',null,"right"], + leqalignno: ['Matrix',null,null,"right left",MML.LENGTH.THICKMATHSPACE,".5em",'D',null,"left"], + hfill: 'HFill', + hfil: 'HFill', // \hfil treated as \hfill for now + hfilll: 'HFill', // \hfilll treated as \hfill for now // TeX substitution macros - bmod: ['Macro','\\mathbin{\\mmlToken{mo}{mod}}'], + bmod: ['Macro','\\mmlToken{mo}[lspace="thickmathspace" rspace="thickmathspace"]{mod}'], pmod: ['Macro','\\pod{\\mmlToken{mi}{mod}\\kern 6mu #1}',1], mod: ['Macro','\\mathchoice{\\kern18mu}{\\kern12mu}{\\kern12mu}{\\kern12mu}\\mmlToken{mi}{mod}\\,\\,#1',1], pod: ['Macro','\\mathchoice{\\kern18mu}{\\kern8mu}{\\kern8mu}{\\kern8mu}(#1)',1], @@ -908,8 +959,10 @@ mathsf: ['Macro','{\\sf #1}',1], mathtt: ['Macro','{\\tt #1}',1], textrm: ['Macro','\\mathord{\\rm\\text{#1}}',1], - textit: ['Macro','\\mathord{\\it{\\text{#1}}}',1], - textbf: ['Macro','\\mathord{\\bf{\\text{#1}}}',1], + textit: ['Macro','\\mathord{\\it\\text{#1}}',1], + textbf: ['Macro','\\mathord{\\bf\\text{#1}}',1], + textsf: ['Macro','\\mathord{\\sf\\text{#1}}',1], + texttt: ['Macro','\\mathord{\\tt\\text{#1}}',1], pmb: ['Macro','\\rlap{#1}\\kern1px{#1}',1], TeX: ['Macro','T\\kern-.14em\\lower.5ex{E}\\kern-.115em X'], LaTeX: ['Macro','L\\kern-.325em\\raise.21em{\\scriptstyle{A}}\\kern-.17em\\TeX'], @@ -919,11 +972,12 @@ not: 'Not', dots: 'Dots', space: 'Tilde', + '\u00A0': 'Tilde', // LaTeX - begin: 'Begin', - end: 'End', + begin: 'BeginEnd', + end: 'BeginEnd', newcommand: ['Extension','newcommand'], renewcommand: ['Extension','newcommand'], @@ -967,13 +1021,14 @@ Bmatrix: ['Array',null,'\\{','\\}','c'], vmatrix: ['Array',null,'\\vert','\\vert','c'], Vmatrix: ['Array',null,'\\Vert','\\Vert','c'], - cases: ['Array',null,'\\{','.','ll',null,".1em"], - eqnarray: ['Array',null,null,null,'rcl',MML.LENGTH.THICKMATHSPACE,".5em",'D'], - 'eqnarray*': ['Array',null,null,null,'rcl',MML.LENGTH.THICKMATHSPACE,".5em",'D'], + cases: ['Array',null,'\\{','.','ll',null,".2em",'T'], equation: [null,'Equation'], 'equation*': [null,'Equation'], + eqnarray: ['ExtensionEnv',null,'AMSmath'], + 'eqnarray*': ['ExtensionEnv',null,'AMSmath'], + align: ['ExtensionEnv',null,'AMSmath'], 'align*': ['ExtensionEnv',null,'AMSmath'], aligned: ['ExtensionEnv',null,'AMSmath'], @@ -1034,7 +1089,7 @@ return this.stack.Top().data[0]; }, mmlToken: function (token) {return token}, // used by boldsymbol extension - + /************************************************************************/ /* * Handle various token classes @@ -1099,7 +1154,7 @@ // (overridden in noUndefined extension) // csUndefined: function (name) { - TEX.Error("Undefined control sequence "+name); + TEX.Error(["UndefinedControlSequence","Undefined control sequence %1",name]); }, /* @@ -1139,56 +1194,69 @@ Superscript: function (c) { if (this.GetNext().match(/\d/)) // don't treat numbers as a unit {this.string = this.string.substr(0,this.i+1)+" "+this.string.substr(this.i+1)} - var position, base = this.stack.Prev(); if (!base) {base = MML.mi("")} + var primes, base, top = this.stack.Top(); + if (top.type === "prime") {base = top.data[0]; primes = top.data[1]; this.stack.Pop()} + else {base = this.stack.Prev(); if (!base) {base = MML.mi("")}} if (base.isEmbellishedWrapper) {base = base.data[0].data[0]} - if (base.type === "msubsup") { - if (base.data[base.sup]) { - if (!base.data[base.sup].isPrime) {TEX.Error("Double exponent: use braces to clarify")} + var movesupsub = base.movesupsub, position = base.sup; + if ((base.type === "msubsup" && base.data[base.sup]) || + (base.type === "munderover" && base.data[base.over] && !base.subsupOK)) + {TEX.Error(["DoubleExponent","Double exponent: use braces to clarify"])} + if (base.type !== "msubsup") { + if (movesupsub) { + if (base.type !== "munderover" || base.data[base.over]) { + if (base.movablelimits && base.isa(MML.mi)) {base = this.mi2mo(base)} + base = MML.munderover(base,null,null).With({movesupsub:true}) + } + position = base.over; + } else { base = MML.msubsup(base,null,null); + position = base.sup; } - position = base.sup; - } else if (base.movesupsub) { - if (base.type !== "munderover" || base.data[base.over]) { - if (base.movablelimits && base.isa(MML.mi)) {base = this.mi2mo(base)} - base = MML.munderover(base,null,null).With({movesupsub:true}) - } - position = base.over; - } else { - base = MML.msubsup(base,null,null); - position = base.sup; } - this.Push(STACKITEM.subsup(base).With({position: position})); + this.Push(STACKITEM.subsup(base).With({ + position: position, primes: primes, movesupsub: movesupsub + })); }, Subscript: function (c) { if (this.GetNext().match(/\d/)) // don't treat numbers as a unit {this.string = this.string.substr(0,this.i+1)+" "+this.string.substr(this.i+1)} - var position, base = this.stack.Prev(); if (!base) {base = MML.mi("")} + var primes, base, top = this.stack.Top(); + if (top.type === "prime") {base = top.data[0]; primes = top.data[1]; this.stack.Pop()} + else {base = this.stack.Prev(); if (!base) {base = MML.mi("")}} if (base.isEmbellishedWrapper) {base = base.data[0].data[0]} - if (base.type === "msubsup") { - if (base.data[base.sub]) {TEX.Error("Double subscripts: use braces to clarify")} - position = base.sub; - } else if (base.movesupsub) { - if (base.type !== "munderover" || base.data[base.under]) { - if (base.movablelimits && base.isa(MML.mi)) {base = this.mi2mo(base)} - base = MML.munderover(base,null,null).With({movesupsub:true}) + var movesupsub = base.movesupsub, position = base.sub; + if ((base.type === "msubsup" && base.data[base.sub]) || + (base.type === "munderover" && base.data[base.under] && !base.subsupOK)) + {TEX.Error(["DoubleSubscripts","Double subscripts: use braces to clarify"])} + if (base.type !== "msubsup") { + if (movesupsub) { + if (base.type !== "munderover" || base.data[base.under]) { + if (base.movablelimits && base.isa(MML.mi)) {base = this.mi2mo(base)} + base = MML.munderover(base,null,null).With({movesupsub:true}) + } + position = base.under; + } else { + base = MML.msubsup(base,null,null); + position = base.sub; } - position = base.under; - } else { - base = MML.msubsup(base,null,null); - position = base.sub; } - this.Push(STACKITEM.subsup(base).With({position: position})); + this.Push(STACKITEM.subsup(base).With({ + position: position, primes: primes, movesupsub: movesupsub + })); }, PRIME: "\u2032", SMARTQUOTE: "\u2019", Prime: function (c) { var base = this.stack.Prev(); if (!base) {base = MML.mi()} - if (base.type === "msubsup" && base.data[base.sup]) - {TEX.Error("Prime causes double exponent: use braces to clarify")} + if (base.type === "msubsup" && base.data[base.sup]) { + TEX.Error(["DoubleExponentPrime", + "Prime causes double exponent: use braces to clarify"]); + } var sup = ""; this.i--; do {sup += this.PRIME; this.i++, c = this.GetNext()} while (c === "'" || c === this.SMARTQUOTE); - sup = this.mmlToken(MML.mo(MML.chars(sup)).With({isPrime: true})); - this.Push(MML.msup(base,sup)); + sup = ["","\u2032","\u2033","\u2034","\u2057"][sup.length] || sup; + this.Push(STACKITEM.prime(base,this.mmlToken(MML.mo(sup)))); }, mi2mo: function (mi) { var mo = MML.mo(); mo.Append.apply(mo,mi.data); var id; @@ -1210,15 +1278,16 @@ * Handle hash marks outside of definitions */ Hash: function (c) { - TEX.Error("You can't use 'macro parameter character #' in math mode"); + TEX.Error(["CantUseHash1", + "You can't use 'macro parameter character #' in math mode"]); }, /* * Handle other characters (as elements) */ Other: function (c) { - var def = {stretchy: false}, mo; - if (this.stack.env.font) {def.mathvariant = this.stack.env.font} + var def, mo; + if (this.stack.env.font) {def = {mathvariant: this.stack.env.font}} if (TEXDEF.remap[c]) { c = TEXDEF.remap[c]; if (c instanceof Array) {def = c[1]; c = c[0]} @@ -1226,6 +1295,7 @@ } else { mo = MML.mo(c).With(def); } + if (mo.autoDefault("stretchy",true)) {mo.stretchy = false} if (mo.autoDefault("texClass",true) == "") {mo = MML.TeXAtom(mo)} this.Push(this.mmlToken(mo)); }, @@ -1263,7 +1333,8 @@ Middle: function (name) { var delim = this.GetDelimiter(name); - if (this.stack.Top().type !== "left") {TEX.Error(name+" must be within \\left and \\right")} + if (this.stack.Top().type !== "left") + {TEX.Error(["MisplacedMiddle","%1 must be within \\left and \\right",name])} this.Push(MML.mo(delim).With({stretchy:true})); }, @@ -1286,9 +1357,16 @@ }, Limits: function (name,limits) { var op = this.stack.Prev("nopop"); - if (op.texClass !== MML.TEXCLASS.OP) {TEX.Error(name+" is allowed only on operators")} + if (!op || (op.Get("texClass") !== MML.TEXCLASS.OP && op.movesupsub == null)) + {TEX.Error(["MisplacedLimits","%1 is allowed only on operators",name])} + var top = this.stack.Top(); + if (op.type === "munderover" && !limits) { + op = top.data[top.data.length-1] = MML.msubsup.apply(MML.subsup,op.data); + } else if (op.type === "msubsup" && limits) { + op = top.data[top.data.length-1] = MML.munderover.apply(MML.underover,op.data); + } op.movesupsub = (limits ? true : false); - op.movablelimits = false; + op.Core().movablelimits = false; }, Over: function (name,open,close) { @@ -1335,10 +1413,13 @@ return n; }, MoveRoot: function (name,id) { - if (!this.stack.env.inRoot) TEX.Error(name+" can appear only within a root"); - if (this.stack.global[id]) TEX.Error("Multiple use of "+name); + if (!this.stack.env.inRoot) + {TEX.Error(["MisplacedMoveRoot","%1 can appear only within a root",name])} + if (this.stack.global[id]) + {TEX.Error(["MultipleMoveRoot","Multiple use of %1",name])} var n = this.GetArgument(name); - if (!n.match(/-?[0-9]+/)) TEX.Error("The argument to "+name+" must be an integer"); + if (!n.match(/-?[0-9]+/)) + {TEX.Error(["IntegerArg","The argument to %1 must be an integer",name])} n = (n/15)+"em"; if (n.substr(0,1) !== "-") {n = "+"+n} this.stack.global[id] = n; @@ -1352,15 +1433,21 @@ this.Push(MML.TeXAtom(MML.munderover(c,null,mml).With({accent: true}))); }, - UnderOver: function (name,c,stack) { + UnderOver: function (name,c,stack,noaccent) { var pos = {o: "over", u: "under"}[name.charAt(1)]; var base = this.ParseArg(name); if (base.Get("movablelimits")) {base.movablelimits = false} + if (base.isa(MML.munderover) && base.isEmbellished()) { + base.Core().With({lspace:0,rspace:0}); // get spacing right for NativeMML + base = MML.mrow(MML.mo().With({rspace:0}),base); // add an empty so it's not embellished any more + } var mml = MML.munderover(base,null,null); - if (stack) {mml.movesupsub = true} - mml.data[mml[pos]] = - this.mmlToken(MML.mo(MML.entity("#x"+c)).With({stretchy:true, accent:(pos == "under")})); - this.Push(mml); + mml.SetData( + mml[pos], + this.mmlToken(MML.mo(MML.entity("#x"+c)).With({stretchy:true, accent:!noaccent})) + ); + if (stack) {mml = MML.TeXAtom(mml).With({texClass:MML.TEXCLASS.OP, movesupsub:true})} + this.Push(mml.With({subsupOK:true})); }, Overset: function (name) { @@ -1393,18 +1480,29 @@ attr = this.GetBrackets(name,"").replace(/^\s+/,""), data = this.GetArgument(name), def = {attrNames:[]}, match; - if (!MML[type] || !MML[type].prototype.isToken) {TEX.Error(type+" is not a token element")} + if (!MML[type] || !MML[type].prototype.isToken) + {TEX.Error(["NotMathMLToken","%1 is not a token element",type])} while (attr !== "") { - match = attr.match(/^([a-z]+)\s*=\s*('[^']*'|"[^"]*"|[^ ]*)\s*/i); - if (!match) {TEX.Error("Invalid MathML attribute: "+attr)} - if (!MML[type].prototype.defaults[match[1]] && !this.MmlTokenAllow[match[1]]) - {TEX.Error(match[1]+" is not a recognized attribute for "+type)} - def[match[1]] = match[2].replace(/^(['"])(.*)\1$/,"$2"); - def.attrNames.push(match[1]); + match = attr.match(/^([a-z]+)\s*=\s*('[^']*'|"[^"]*"|[^ ,]*)\s*,?\s*/i); + if (!match) + {TEX.Error(["InvalidMathMLAttr","Invalid MathML attribute: %1",attr])} + if (MML[type].prototype.defaults[match[1]] == null && !this.MmlTokenAllow[match[1]]) { + TEX.Error(["UnknownAttrForElement", + "%1 is not a recognized attribute for %2", + match[1],type]); + } + var value = this.MmlFilterAttribute(match[1],match[2].replace(/^(['"])(.*)\1$/,"$2")); + if (value) { + if (value.toLowerCase() === "true") {value = true} + else if (value.toLowerCase() === "false") {value = false} + def[match[1]] = value; + def.attrNames.push(match[1]); + } attr = attr.substr(match[0].length); } this.Push(this.mmlToken(MML[type](data).With(def))); }, + MmlFilterAttribute: function (name,value) {return value}, MmlTokenAllow: { fontfamily:1, fontsize:1, fontweight:1, fontstyle:1, color:1, background:1, @@ -1438,7 +1536,7 @@ Lap: function (name) { var mml = MML.mpadded(this.ParseArg(name)).With({width: 0}); - if (name === "\\llap") {mml.lspace = "-1 width"} + if (name === "\\llap") {mml.lspace = "-1width"} this.Push(MML.TeXAtom(mml)); }, @@ -1483,9 +1581,9 @@ MakeBig: function (name,mclass,size) { size *= TEXDEF.p_height; size = String(size).replace(/(\.\d\d\d).+/,'$1')+"em"; - var delim = this.GetDelimiter(name); + var delim = this.GetDelimiter(name,true); this.Push(MML.TeXAtom(MML.mo(delim).With({ - minsize: size, maxsize: size, scriptlevel: 0, + minsize: size, maxsize: size, fence: true, stretchy: true, symmetric: true })).With({texClass: mclass})); }, @@ -1493,7 +1591,7 @@ BuildRel: function (name) { var top = this.ParseUpTo(name,"\\over"); var bot = this.ParseArg(name); - this.Push(MML.TeXAtom(MML.munderover(bot,null,top)).With({mclass: MML.TEXCLASS.REL})); + this.Push(MML.TeXAtom(MML.munderover(bot,null,top)).With({texClass: MML.TEXCLASS.REL})); }, HBox: function (name,style) { @@ -1544,12 +1642,17 @@ } this.string = this.AddArgs(macro,this.string.slice(this.i)); this.i = 0; - if (++this.macroCount > TEX.config.MAXMACROS) - {TEX.Error("MathJax maximum macro substitution count exceeded; is there a recursive macro call?")} + if (++this.macroCount > TEX.config.MAXMACROS) { + TEX.Error(["MaxMacroSub1", + "MathJax maximum macro substitution count exceeded; " + + "is there a recursive macro call?"]); + } }, - Matrix: function (name,open,close,align,spacing,vspacing,style,cases) { - var c = this.GetNext(); if (c === "") {TEX.Error("Missing argument for "+name)} + Matrix: function (name,open,close,align,spacing,vspacing,style,cases,numbered) { + var c = this.GetNext(); + if (c === "") + {TEX.Error(["MissingArgFor","Missing argument for %1",name])} if (c === "{") {this.i++} else {this.string = c+"}"+this.string.slice(this.i+1); this.i = 0} var array = STACKITEM.array().With({ requireClose: true, @@ -1559,6 +1662,7 @@ } }); if (cases) {array.isCases = true} + if (numbered) {array.isNumbered = true; array.arraydef.side = numbered} if (open || close) {array.open = open; array.close = close} if (style === "D") {array.arraydef.displaystyle = true} if (align != null) {array.arraydef.columnalign = align} @@ -1574,14 +1678,15 @@ var c = string.charAt(i); if (c === "{") {braces++; i++} else if (c === "}") {if (braces === 0) {m = 0} else {braces--; i++}} - else if (c === "&" && braces === 0) {TEX.Error("Extra alignment tab in \\cases text")} - else if (c === "\\") { + else if (c === "&" && braces === 0) { + TEX.Error(["ExtraAlignTab","Extra alignment tab in \\cases text"]); + } else if (c === "\\") { if (string.substr(i).match(/^((\\cr)[^a-zA-Z]|\\\\)/)) {m = 0} else {i += 2} } else {i++} } var text = string.substr(this.i,i-this.i); if (!text.match(/^\s*\\text[^a-zA-Z]/)) { - this.Push.apply(this,this.InternalMath(text)); + this.Push.apply(this,this.InternalMath(text,0)); this.i = i; } } @@ -1592,43 +1697,58 @@ }, CrLaTeX: function (name) { - var n = this.GetBrackets(name,"").replace(/ /g,""); - if (n && !n.match(/^(((\.\d+|\d+(\.\d*)?))(pt|em|ex|mu|mm|cm|in|pc))$/)) - {TEX.Error("Bracket argument to "+name+" must be a dimension")} + var n; + if (this.string.charAt(this.i) === "[") { + n = this.GetBrackets(name,"").replace(/ /g,"").replace(/,/,"."); + if (n && !this.matchDimen(n)) { + TEX.Error(["BracketMustBeDimension", + "Bracket argument to %1 must be a dimension",name]); + } + } this.Push(STACKITEM.cell().With({isCR: true, name: name, linebreak: true})); var top = this.stack.Top(); if (top.isa(STACKITEM.array)) { if (n && top.arraydef.rowspacing) { var rows = top.arraydef.rowspacing.split(/ /); if (!top.rowspacing) {top.rowspacing = this.dimen2em(rows[0])} - while (rows.length < top.table.length) {rows.push(top.rowspacing)} - rows[top.table.length-1] = (top.rowspacing+this.dimen2em(n)) + "em"; + while (rows.length < top.table.length) {rows.push(this.Em(top.rowspacing))} + rows[top.table.length-1] = this.Em(Math.max(0,top.rowspacing+this.dimen2em(n))); top.arraydef.rowspacing = rows.join(' '); } } else { if (n) {this.Push(MML.mspace().With({depth:n}))} - this.Push(MML.mo().With({linebreak:MML.LINEBREAK.NEWLINE})); + this.Push(MML.mspace().With({linebreak:MML.LINEBREAK.NEWLINE})); } }, emPerInch: 7.2, + pxPerInch: 72, + matchDimen: function (dim) { + return dim.match(/^(-?(?:\.\d+|\d+(?:\.\d*)?))(px|pt|em|ex|mu|pc|in|mm|cm)$/); + }, dimen2em: function (dim) { - var match = dim.match(/^((?:\.\d+|\d+(?:\.\d*)?))(pt|em|ex|mu|pc|in|mm|cm)/); + var match = this.matchDimen(dim); var m = parseFloat(match[1]||"1"), unit = match[2]; if (unit === "em") {return m} if (unit === "ex") {return m * .43} if (unit === "pt") {return m / 10} // 10 pt to an em if (unit === "pc") {return m * 1.2} // 12 pt to a pc + if (unit === "px") {return m * this.emPerInch / this.pxPerInch} if (unit === "in") {return m * this.emPerInch} if (unit === "cm") {return m * this.emPerInch / 2.54} // 2.54 cm to an inch if (unit === "mm") {return m * this.emPerInch / 25.4} // 10 mm to a cm if (unit === "mu") {return m / 18} return 0; }, + Em: function (m) { + if (Math.abs(m) < .0006) {return "0em"} + return m.toFixed(3).replace(/\.?0+$/,"") + "em"; + }, HLine: function (name,style) { if (style == null) {style = "solid"} var top = this.stack.Top(); - if (!top.isa(STACKITEM.array) || top.data.length) {TEX.Error("Misplaced "+name)} + if (!top.isa(STACKITEM.array) || top.data.length) + {TEX.Error(["Misplaced","Misplaced %1",name])} if (top.table.length == 0) { top.frame.push("top"); } else { @@ -1639,25 +1759,44 @@ } }, + HFill: function (name) { + var top = this.stack.Top(); + if (top.isa(STACKITEM.array)) top.hfill.push(top.data.length); + else TEX.Error(["UnsupportedHFill","Unsupported use of %1",name]); + }, + + + /************************************************************************/ /* * LaTeX environments */ - Begin: function (name) { - var env = this.GetArgument(name); - if (env.match(/[^a-z*]/i)) {TEX.Error('Invalid environment name "'+env+'"')} - var cmd = this.envFindName(env); if (!cmd) {TEX.Error('Unknown environment "'+env+'"')} - if (++this.macroCount > TEX.config.MAXMACROS) - {TEX.Error("MathJax maximum substitution count exceeded; is there a recursive latex environment?")} + BeginEnd: function (name) { + var env = this.GetArgument(name), isEnd = false; + if (env.match(/^\\end\\/)) {isEnd = true; env = env.substr(5)} // special \end{} for \newenvironment environments + if (env.match(/\\/i)) {TEX.Error(["InvalidEnv","Invalid environment name '%1'",env])} + var cmd = this.envFindName(env); + if (!cmd) {TEX.Error(["UnknownEnv","Unknown environment '%1'",env])} if (!(cmd instanceof Array)) {cmd = [cmd]} - var mml = STACKITEM.begin().With({name: env, end: cmd[1], parse:this}); - if (cmd[0] && this[cmd[0]]) {mml = this[cmd[0]].apply(this,[mml].concat(cmd.slice(2)))} + var end = (cmd[1] instanceof Array ? cmd[1][0] : cmd[1]); + var mml = STACKITEM.begin().With({name: env, end: end, parse:this}); + if (name === "\\end") { + if (!isEnd && cmd[1] instanceof Array && this[cmd[1][1]]) { + mml = this[cmd[1][1]].apply(this,[mml].concat(cmd.slice(2))); + } else { + mml = STACKITEM.end().With({name: env}); + } + } else { + if (++this.macroCount > TEX.config.MAXMACROS) { + TEX.Error(["MaxMacroSub2", + "MathJax maximum substitution count exceeded; " + + "is there a recursive latex environment?"]); + } + if (cmd[0] && this[cmd[0]]) {mml = this[cmd[0]].apply(this,[mml].concat(cmd.slice(2)))} + } this.Push(mml); }, - End: function (name) { - this.Push(STACKITEM.end().With({name: this.GetArgument(name)})); - }, envFindName: function (name) {return TEXDEF.environment[name]}, Equation: function (begin,row) {return row}, @@ -1686,6 +1825,7 @@ if (open) {array.open = this.convertDelimiter(open)} if (close) {array.close = this.convertDelimiter(close)} if (style === "D") {array.arraydef.displaystyle = true} + else if (style) {array.arraydef.displaystyle = false} if (style === "S") {array.arraydef.scriptlevel = 1} // FIXME: should use mstyle? if (raggedHeight) {array.arraydef.useHeight = false} this.Push(begin); @@ -1733,7 +1873,7 @@ * Check if the next character is a space */ nextIsSpace: function () { - return this.string.charAt(this.i).match(/[ \n\r\t]/); + return this.string.charAt(this.i).match(/\s/); }, /* @@ -1759,10 +1899,13 @@ GetArgument: function (name,noneOK) { switch (this.GetNext()) { case "": - if (!noneOK) {TEX.Error("Missing argument for "+name)} + if (!noneOK) {TEX.Error(["MissingArgFor","Missing argument for %1",name])} return null; case '}': - if (!noneOK) {TEX.Error("Extra close brace or missing open brace")} + if (!noneOK) { + TEX.Error(["ExtraCloseMissingOpen", + "Extra close brace or missing open brace"]); + } return null; case '\\': this.i++; return "\\"+this.GetCS(); @@ -1773,12 +1916,11 @@ case '\\': this.i++; break; case '{': parens++; break; case '}': - if (parens == 0) {TEX.Error("Extra close brace")} if (--parens == 0) {return this.string.slice(j,this.i-1)} break; } } - TEX.Error("Missing close brace"); + TEX.Error(["MissingCloseBrace","Missing close brace"]); break; } return this.string.charAt(this.i++); @@ -1795,27 +1937,33 @@ case '{': parens++; break; case '\\': this.i++; break; case '}': - if (parens-- <= 0) {TEX.Error("Extra close brace while looking for ']'")} + if (parens-- <= 0) { + TEX.Error(["ExtraCloseLooking", + "Extra close brace while looking for %1","']'"]); + } break; case ']': if (parens == 0) {return this.string.slice(j,this.i-1)} break; } } - TEX.Error("Couldn't find closing ']' for argument to "+name); + TEX.Error(["MissingCloseBracket", + "Couldn't find closing ']' for argument to %1",name]); }, /* * Get the name of a delimiter (check it in the delimiter list). */ - GetDelimiter: function (name) { + GetDelimiter: function (name,braceOK) { while (this.nextIsSpace()) {this.i++} - var c = this.string.charAt(this.i); - if (this.i < this.string.length) { - this.i++; if (c == "\\") {c += this.GetCS(name)} + var c = this.string.charAt(this.i); this.i++; + if (this.i <= this.string.length) { + if (c == "\\") {c += this.GetCS(name)} + else if (c === "{" && braceOK) {this.i--; c = this.GetArgument(name)} if (TEXDEF.delimiter[c] != null) {return this.convertDelimiter(c)} } - TEX.Error("Missing or unrecognized delimiter for "+name); + TEX.Error(["MissingOrUnrecognizedDelim", + "Missing or unrecognized delimiter for %1",name]); }, /* @@ -1826,17 +1974,18 @@ if (this.nextIsSpace()) {this.i++} if (this.string.charAt(this.i) == '{') { dimen = this.GetArgument(name); - if (dimen.match(/^\s*([-+]?(\.\d+|\d+(\.\d*)?))\s*(pt|em|ex|mu|px|mm|cm|in|pc)\s*$/)) - {return dimen.replace(/ /g,"")} + if (dimen.match(/^\s*([-+]?([.,]\d+|\d+([.,]\d*)?))\s*(pt|em|ex|mu|px|mm|cm|in|pc)\s*$/)) + {return dimen.replace(/ /g,"").replace(/,/,".")} } else { dimen = this.string.slice(this.i); - var match = dimen.match(/^\s*(([-+]?(\.\d+|\d+(\.\d*)?))\s*(pt|em|ex|mu|px|mm|cm|in|pc)) ?/); + var match = dimen.match(/^\s*(([-+]?([.,]\d+|\d+([.,]\d*)?))\s*(pt|em|ex|mu|px|mm|cm|in|pc)) ?/); if (match) { this.i += match[0].length; - return match[1].replace(/ /g,""); + return match[1].replace(/ /g,"").replace(/,/,"."); } } - TEX.Error("Missing dimension or its units for "+name); + TEX.Error(["MissingDimOrUnits", + "Missing dimension or its units for %1",name]); }, /* @@ -1851,13 +2000,17 @@ case '\\': c += this.GetCS(); break; case '{': parens++; break; case '}': - if (parens == 0) {TEX.Error("Extra close brace while looking for "+token)} + if (parens == 0) { + TEX.Error(["ExtraCloseLooking", + "Extra close brace while looking for %1",token]) + } parens--; break; } if (parens == 0 && c == token) {return this.string.slice(j,k)} } - TEX.Error("Couldn't find "+token+" for "+name); + TEX.Error(["TokenNotFoundForCommand", + "Couldn't find %1 for %2",token,name]); }, /* @@ -1868,46 +2021,58 @@ /* * Break up a string into text and math blocks - * @@@ FIXME: skip over braced groups? @@@ * @@@ FIXME: pass environment to TEX.Parse? @@@ */ InternalMath: function (text,level) { - var def = {displaystyle: false}; if (level != null) {def.scriptlevel = level} - if (this.stack.env.font) {def.mathvariant = this.stack.env.font} - if (!text.match(/\$|\\\(|\\(eq)?ref\s*\{/)) {return [this.InternalText(text,def)]} - var i = 0, k = 0, c, match = ''; - var mml = []; - while (i < text.length) { - c = text.charAt(i++); - if (c === '$') { - if (match === '$') { - mml.push(MML.TeXAtom(TEX.Parse(text.slice(k,i-1),{}).mml().With(def))); - match = ''; k = i; - } else if (match === '') { - if (k < i-1) {mml.push(this.InternalText(text.slice(k,i-1),def))} - match = '$'; k = i; - } - } else if (c === '}' && match === '}') { - mml.push(MML.TeXAtom(TEX.Parse(text.slice(k,i),{}).mml().With(def))); - match = ''; k = i; - } else if (c === '\\') { - if (match === '' && text.substr(i).match(/^(eq)?ref\s*\{/)) { - if (k < i-1) {mml.push(this.InternalText(text.slice(k,i-1),def))} - match = '}'; k = i-1; - } else { - c = text.charAt(i++); - if (c === '(' && match === '') { - if (k < i-2) {mml.push(this.InternalText(text.slice(k,i-2),def))} - match = ')'; k = i; - } else if (c === ')' && match === ')') { - mml.push(MML.TeXAtom(TEX.Parse(text.slice(k,i-2),{}).mml().With(def))); + var def = (this.stack.env.font ? {mathvariant: this.stack.env.font} : {}); + var mml = [], i = 0, k = 0, c, match = '', braces = 0; + if (text.match(/\\?[${}\\]|\\\(|\\(eq)?ref\s*\{/)) { + while (i < text.length) { + c = text.charAt(i++); + if (c === '$') { + if (match === '$' && braces === 0) { + mml.push(MML.TeXAtom(TEX.Parse(text.slice(k,i-1),{}).mml().With(def))); match = ''; k = i; + } else if (match === '') { + if (k < i-1) mml.push(this.InternalText(text.slice(k,i-1),def)); + match = '$'; k = i; + } + } else if (c === '{' && match !== '') { + braces++; + } else if (c === '}') { + if (match === '}' && braces === 0) { + mml.push(MML.TeXAtom(TEX.Parse(text.slice(k,i),{}).mml().With(def))); + match = ''; k = i; + } else if (match !== '') { + if (braces) braces--; + } + } else if (c === '\\') { + if (match === '' && text.substr(i).match(/^(eq)?ref\s*\{/)) { + var len = RegExp["$&"].length; + if (k < i-1) mml.push(this.InternalText(text.slice(k,i-1),def)); + match = '}'; k = i-1; i += len; + } else { + c = text.charAt(i++); + if (c === '(' && match === '') { + if (k < i-2) mml.push(this.InternalText(text.slice(k,i-2),def)); + match = ')'; k = i; + } else if (c === ')' && match === ')' && braces === 0) { + mml.push(MML.TeXAtom(TEX.Parse(text.slice(k,i-2),{}).mml().With(def))); + match = ''; k = i; + } else if (c.match(/[${}\\]/) && match === '') { + i--; text = text.substr(0,i-1) + text.substr(i); // remove \ from \$, \{, \}, or \\ + } } } } + if (match !== '') TEX.Error(["MathNotTerminated","Math not terminated in text box"]); + } + if (k < text.length) mml.push(this.InternalText(text.slice(k),def)); + if (level != null) { + mml = [MML.mstyle.apply(MML,mml).With({displaystyle:false,scriptlevel:level})]; + } else if (mml.length > 1) { + mml = [MML.mrow.apply(MML,mml)]; } - if (match !== '') {TEX.Error("Math not terminated in text box")} - if (k < text.length) {mml.push(this.InternalText(text.slice(k),def))} return mml; }, InternalText: function (text,def) { @@ -1926,8 +2091,10 @@ else if (c === '#') { c = string.charAt(i++); if (c === '#') {text += c} else { - if (!c.match(/[1-9]/) || c > args.length) - {TEX.Error("Illegal macro parameter reference")} + if (!c.match(/[1-9]/) || c > args.length) { + TEX.Error(["IllegalMacroParam", + "Illegal macro parameter reference"]); + } newstring = this.AddArgs(this.AddArgs(newstring,text),args[c-1]); text = ''; } @@ -1942,8 +2109,10 @@ */ AddArgs: function (s1,s2) { if (s2.match(/^[a-z]/i) && s1.match(/(^|[^\\])(\\\\)*\\[a-z]+$/i)) {s1 += ' '} - if (s1.length + s2.length > TEX.config.MAXBUFFER) - {TEX.Error("MathJax internal buffer size exceeded; is there a recursive macro call?")} + if (s1.length + s2.length > TEX.config.MAXBUFFER) { + TEX.Error(["MaxBufferSize", + "MathJax internal buffer size exceeded; is there a recursive macro call?"]); + } return s1+s2; } @@ -1959,7 +2128,8 @@ MAXBUFFER: 5*1024 // maximum size of TeX string to process }, - sourceMenuTitle: "TeX Commands", + sourceMenuTitle: /*_(MathMenu)*/ ["TeXCommands","TeX Commands"], + annotationEncoding: "application/x-tex", prefilterHooks: MathJax.Callback.Hooks(true), // hooks to run before processing TeX postfilterHooks: MathJax.Callback.Hooks(true), // hooks to run after processing TeX @@ -1983,20 +2153,21 @@ var mml, isError = false, math = MathJax.HTML.getScript(script); var display = (script.type.replace(/\n/g," ").match(/(;|\s|\n)mode\s*=\s*display(;|\s|\n|$)/) != null); var data = {math:math, display:display, script:script}; - this.prefilterHooks.Execute(data); math = data.math; + var callback = this.prefilterHooks.Execute(data); if (callback) return callback; + math = data.math; try { mml = TEX.Parse(math).mml(); -// mml = MML.semantics(mml,MML.annotation(math).With({encoding:"application:x-tex"})); } catch(err) { if (!err.texError) {throw err} mml = this.formatError(err,math,display,script); isError = true; } + if (mml.isa(MML.mtable) && mml.displaystyle === "inherit") mml.displaystyle = display; // for tagged equations if (mml.inferred) {mml = MML.apply(MathJax.ElementJax,mml.data)} else {mml = MML(mml)} if (display) {mml.root.display = "block"} if (isError) {mml.texError = true} - data.math = mml; this.postfilterHooks.Execute(data); - return data.math; + data.math = mml; + return this.postfilterHooks.Execute(data) || data.math; }, prefilterMath: function (math,displaystyle,script) { return math; @@ -2008,13 +2179,17 @@ formatError: function (err,math,display,script) { var message = err.message.replace(/\n.*/,""); HUB.signal.Post(["TeX Jax - parse error",message,math,display,script]); - return MML.merror(message); + return MML.Error(message); }, // // Produce an error and stop processing this equation // Error: function (message) { + // + // Translate message if it is ["id","message",args] + // + if (message instanceof Array) {message = _.apply(_,message)} throw HUB.Insert(Error(message),{texError: true}); }, @@ -2026,6 +2201,32 @@ TEXDEF.macros[name].isUser = true; }, + /* + * Create an mrow that has stretchy delimiters at either end, as needed + */ + fenced: function (open,mml,close) { + var mrow = MML.mrow().With({open:open, close:close, texClass:MML.TEXCLASS.INNER}); + mrow.Append(MML.mo(open).With({fence:true, stretchy:true, texClass:MML.TEXCLASS.OPEN})); + if (mml.type === "mrow") {mrow.Append.apply(mrow,mml.data)} else {mrow.Append(mml)} + mrow.Append(MML.mo(close).With({fence:true, stretchy:true, texClass:MML.TEXCLASS.CLOSE})); + return mrow; + }, + /* + * Create an mrow that has \mathchoice using \bigg and \big for the delimiters + */ + fixedFence: function (open,mml,close) { + var mrow = MML.mrow().With({open:open, close:close, texClass:MML.TEXCLASS.ORD}); + if (open) {mrow.Append(this.mathPalette(open,"l"))} + if (mml.type === "mrow") {mrow.Append.apply(mrow,mml.data)} else {mrow.Append(mml)} + if (close) {mrow.Append(this.mathPalette(close,"r"))} + return mrow; + }, + mathPalette: function (fence,side) { + if (fence === '{' || fence === '}') {fence = "\\"+fence} + var D = '{\\bigg'+side+' '+fence+'}', T = '{\\big'+side+' '+fence+'}'; + return TEX.Parse('\\mathchoice'+D+T+T+T,{}).mml(); + }, + // // Combine adjacent elements that are relations // (since MathML treats the spacing very differently) diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/annotation-xml.js b/resources/viewer/mathjax/jax/output/SVG/autoload/annotation-xml.js index 33772d56ed..2707595cc1 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/annotation-xml.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/annotation-xml.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/annotation-xml.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2012 Design Science, Inc. + * Copyright (c) 2013-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG; var BBOX = SVG.BBOX; diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/maction.js b/resources/viewer/mathjax/jax/output/SVG/autoload/maction.js index 68fff6caf8..a194c0e31c 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/maction.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/maction.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/maction.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax["SVG"]; @@ -44,20 +47,22 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { this.SVGgetStyles(); var svg = this.SVG(); var selected = this.selected(); - if (selected) { - svg.Add(this.SVGdataStretched(this.Get("selection")-1,HW,D)); - this.SVGhandleHitBox(svg); - } + if (selected.type == "null") {this.SVGsaveData(svg);return svg;} + svg.Add(this.SVGdataStretched(this.Get("selection")-1,HW,D)); + svg.removeable = false; + this.SVGhandleHitBox(svg); this.SVGhandleSpace(svg); this.SVGhandleColor(svg); this.SVGsaveData(svg); return svg; }, SVGhandleHitBox: function (svg) { - var frame = SVG.addElement(svg.element,"rect", + var frame = SVG.Element("rect", {width:svg.w, height:svg.h+svg.d, y:-svg.d, fill:"none", "pointer-events":"all"}); + svg.element.insertBefore(frame,svg.element.firstChild); var type = this.Get("actiontype"); - if (this.SVGaction[type]) {this.SVGaction[type].call(this,svg,frame,this.Get("selection"))} + if (this.SVGaction[type]) + {this.SVGaction[type].call(this,svg,svg.element,this.Get("selection"))} }, SVGstretchH: MML.mbase.prototype.SVGstretchH, SVGstretchV: MML.mbase.prototype.SVGstretchV, @@ -109,11 +114,14 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // SVGsetStatus: function (event) { // FIXME: Do something better with non-token elements - window.status = + this.messageID = MathJax.Message.Set ((this.data[1] && this.data[1].isToken) ? this.data[1].data.join("") : this.data[1].toString()); }, - SVGclearStatus: function (event) {window.status = ""}, + SVGclearStatus: function (event) { + if (this.messageID) {MathJax.Message.Clear(this.messageID,0)} + delete this.messageID; + }, // // Handle tooltips @@ -154,7 +162,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { var math = this; while (math.type !== "math") {math = math.inherit} var jax = MathJax.Hub.getJaxFor(math.inputID); this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex; - this.linebreakWidth = jax.SVG.lineWidth * 1000; this.cwidth = jax.SVG.cwidth; + this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth; // // Make a new math element and temporarily move the tooltip to it diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/menclose.js b/resources/viewer/mathjax/jax/output/SVG/autoload/menclose.js index 6cba994ad6..e0e75b0992 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/menclose.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/menclose.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/menclose.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG, BBOX = SVG.BBOX; @@ -96,7 +99,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { toSVG: function (HW,DD) { this.SVGgetStyles(); - var svg = this.SVG(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); this.SVGhandleSpace(svg); var base = this.SVGdataStretched(0,HW,DD); @@ -104,16 +107,22 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { if (values.color && !this.mathcolor) {values.mathcolor = values.color} if (values.thickness == null) {values.thickness = ".075em"} if (values.padding == null) {values.padding = ".2em"} - var mu = this.SVGgetMu(svg), scale = this.SVGgetScale(); - var p = SVG.length2em(values.padding,mu,1/SVG.em) * scale; - var t = SVG.length2em(values.thickness,mu,1/SVG.em) * scale; + var mu = this.SVGgetMu(svg); + var p = SVG.length2em(values.padding,mu,1/SVG.em) * scale; // padding for enclosure + var t = SVG.length2em(values.thickness,mu,1/SVG.em); // thickness of lines + t = Math.max(1/SVG.em,t); // see issue #414 var H = base.h+p+t, D = base.d+p+t, W = base.w+2*(p+t); - var notation = values.notation.split(/ /); var dx = 0, w, h, i, m, borders = [false,false,false,false]; if (!values.mathcolor) {values.mathcolor = "black"} + + // perform some reduction e.g. eliminate duplicate notations. + var nl = MathJax.Hub.SplitList(values.notation), notation = {}; + for (i = 0, m = nl.length; i < m; i++) notation[nl[i]] = true; + if (notation[MML.NOTATION.UPDIAGONALARROW]) notation[MML.NOTATION.UPDIAGONALSTRIKE] = false; - for (i = 0, m = notation.length; i < m; i++) { - switch (notation[i]) { + for (var n in notation) { + if (!notation.hasOwnProperty(n) || !notation[n]) continue; + switch (n) { case MML.NOTATION.BOX: borders = [true,true,true,true]; break; @@ -154,21 +163,26 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { break; case MML.NOTATION.UPDIAGONALSTRIKE: - if (this.arrow) { - var l = Math.sqrt(W*W + (H+D)*(H+D)), f = 1/l * 10/SVG.em * t/.075; - w = W * f; h = (H+D) * f; var x = .4*h; - svg.Add(BBOX.DLINE(H-.5*h,D,W-.5*w,t,values.mathcolor,"up")); - svg.Add(BBOX.FPOLY( - [[x+w,h], [x-.4*h,.4*w], [x+.3*w,.3*h], [x+.4*h,-.4*w], [x+w,h]], - values.mathcolor),W-w-x,H-h); - } else { - svg.Add(BBOX.DLINE(H,D,W,t,values.mathcolor,"up")); - } + svg.Add(BBOX.DLINE(H,D,W,t,values.mathcolor,"up")); + break; + + case MML.NOTATION.UPDIAGONALARROW: + var l = Math.sqrt(W*W + (H+D)*(H+D)), f = 1/l * 10/SVG.em * t/.075; + w = W * f; h = (H+D) * f; var x = .4*h; + svg.Add(BBOX.DLINE(H-.5*h,D,W-.5*w,t,values.mathcolor,"up")); + svg.Add(BBOX.FPOLY( + [[x+w,h], [x-.4*h,.4*w], [x+.3*w,.3*h], [x+.4*h,-.4*w], [x+w,h]], + values.mathcolor),W-w-x,H-h); break; case MML.NOTATION.DOWNDIAGONALSTRIKE: svg.Add(BBOX.DLINE(H,D,W,t,values.mathcolor,"down")); break; + + case MML.NOTATION.PHASORANGLE: + borders[2] = true; W -= 2*p; p = (H+D)/2; W += p; + svg.Add(BBOX.DLINE(H,D,p,t,values.mathcolor,"up")); + break; case MML.NOTATION.MADRUWB: borders[1] = borders[2] = true; diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/mglyph.js b/resources/viewer/mathjax/jax/output/SVG/autoload/mglyph.js index b62b2f36dd..0c332ca655 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/mglyph.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/mglyph.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/mglyph.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,10 +25,11 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG, - BBOX = SVG.BBOX; + BBOX = SVG.BBOX, + LOCALE = MathJax.Localization; var XLINKNS = "http://www.w3.org/1999/xlink"; @@ -33,9 +37,10 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { type: "image", removeable: false, Init: function (img,w,h,align,mu,def) { if (def == null) {def = {}} - var W = img.width*1000/SVG.em, H = img.height*1000/SVG.em, y = 0; - if (w !== "") {W = SVG.length2em(w,mu,W)} - if (h !== "") {H = SVG.length2em(h,mu,H)} + var W = img.width*1000/SVG.em, H = img.height*1000/SVG.em; + var WW = W, HH = H, y = 0; + if (w !== "") {W = SVG.length2em(w,mu,WW); H = (WW ? W/WW * HH : 0)} + if (h !== "") {H = SVG.length2em(h,mu,HH); if (w === "") {W = (HH ? H/HH * WW : 0)}} if (align !== "" && align.match(/\d/)) {y = SVG.length2em(align,mu); def.y = -y} def.height = Math.floor(H); def.width = Math.floor(W); def.transform = "translate(0,"+H+") matrix(1 0 0 -1 0 0)"; @@ -70,7 +75,9 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { MathJax.Hub.RestartAfter(img.onload); } if (this.img.status !== "OK") { - err = MML.merror("Bad mglyph: "+values.src).With({mathsize:"75%"}); + err = MML.Error( + LOCALE._(["MathML","BadMglyph"],"Bad mglyph: %1",values.src), + {mathsize:"75%"}); this.Append(err); svg = err.toSVG(); this.data.pop(); } else { var mu = this.SVGgetMu(svg); diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/mmultiscripts.js b/resources/viewer/mathjax/jax/output/SVG/autoload/mmultiscripts.js index b0164f7c35..0f7c4e058c 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/mmultiscripts.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/mmultiscripts.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/mmultiscripts.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,14 +25,14 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG; MML.mmultiscripts.Augment({ toSVG: function (HW,D) { - var svg = this.SVG(); this.SVGhandleSpace(); - var scale = this.SVGgetScale(); + this.SVGgetStyles(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); this.SVGhandleSpace(svg); var base = (this.data[this.base] ? this.SVGdataStretched(this.base,HW,D) : SVG.BBOX.G().Clean()); var x_height = SVG.TeX.x_height * scale, s = SVG.TeX.scriptspace * scale * .75; // FIXME: .75 can be removed when IC is right? @@ -89,20 +92,27 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { svg.Clean(); this.SVGhandleColor(svg); this.SVGsaveData(svg); + var data = this.SVGdata; + data.dx = dx; data.s = s; data.u = u, data.v = v; data.delta = delta; return svg; }, SVGgetScripts: function (s) { var sup, sub, BOX = []; var i = 1, m = this.data.length, W = 0; for (var k = 0; k < 4; k += 2) { - while (i < m && this.data[i].type !== "mprescripts") { + while (i < m && (this.data[i]||{}).type !== "mprescripts") { + var box = [null,null,null,null]; for (var j = k; j < k+2; j++) { - if (this.data[i] && this.data[i].type !== "none") { + if (this.data[i] && this.data[i].type !== "none" && this.data[i].type !== "mprescripts") { if (!BOX[j]) {BOX[j] = SVG.BBOX.G()} - BOX[j].Add(this.data[i].toSVG().With({x:W})); + box[j] = this.data[i].toSVG(); } - i++; + if ((this.data[i]||{}).type !== "mprescripts") i++; } + var isPre = (k === 2); + if (isPre) W += Math.max((box[k]||{w:0}).w,(box[k+1]||{w:0}).w); + if (box[k]) BOX[k].Add(box[k].With({x:W-(isPre?box[k].w:0)})); + if (box[k+1]) BOX[k+1].Add(box[k+1].With({x:W-(isPre?box[k+1].w:0)})); sub = BOX[k]||{w:0}; sup = BOX[k+1]||{w:0}; sub.w = sup.w = W = Math.max(sub.w,sup.w); } diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/ms.js b/resources/viewer/mathjax/jax/output/SVG/autoload/ms.js index ec2f9baf0f..22c4c4c0ce 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/ms.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/ms.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/ms.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,31 +25,28 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG; MML.ms.Augment({ toSVG: function () { + this.SVGgetStyles(); var svg = this.SVG(); this.SVGhandleSpace(svg); - var values = this.getValues("lquote","rquote"); + var values = this.getValues("lquote","rquote","mathvariant"); + if (!this.hasValue("lquote") || values.lquote === '"') values.lquote = "\u201C"; + if (!this.hasValue("rquote") || values.rquote === '"') values.rquote = "\u201D"; + if (values.lquote === "\u201C" && values.mathvariant === "monospace") values.lquote = '"'; + if (values.rquote === "\u201D" && values.mathvariant === "monospace") values.rquote = '"'; var variant = this.SVGgetVariant(), scale = this.SVGgetScale(); - var text = this.data.join(""); // FIXME: handle mglyph? - var pattern = []; - if (values.lquote.length === 1) {pattern.push(this.SVGquoteRegExp(values.lquote))} - if (values.rquote.length === 1) {pattern.push(this.SVGquoteRegExp(values.rquote))} - if (pattern.length) {text = text.replace(RegExp("("+pattern.join("|")+")","g"),"\\$1")} - svg.Add(this.SVGhandleVariant(variant,scale,values.lquote+text+values.rquote)); + var text = values.lquote+this.data.join("")+values.rquote; // FIXME: handle mglyph? + svg.Add(this.SVGhandleVariant(variant,scale,text)); svg.Clean(); this.SVGhandleColor(svg); this.SVGsaveData(svg); return svg; - }, - SVGquoteRegExp: function (string) { - return string.replace(/([.*+?|{}()\[\]\\])/g,"\\$1"); } }); - MML.ms.prototype.defaults.mathvariant = 'monospace'; MathJax.Hub.Startup.signal.Post("SVG ms Ready"); MathJax.Ajax.loadComplete(SVG.autoloadDir+"/ms.js"); diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/mtable.js b/resources/viewer/mathjax/jax/output/SVG/autoload/mtable.js index 413c43b47e..ee3a18159e 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/mtable.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/mtable.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/mtable.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,61 +25,81 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG, BBOX = SVG.BBOX; MML.mtable.Augment({ toSVG: function (span) { - var svg = this.SVG(); - if (this.data.length === 0) {return svg} + this.SVGgetStyles(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); + if (this.data.length === 0) {this.SVGsaveData(svg);return svg} var values = this.getValues("columnalign","rowalign","columnspacing","rowspacing", "columnwidth","equalcolumns","equalrows", "columnlines","rowlines","frame","framespacing", "align","useHeight","width","side","minlabelspacing"); // Handle relative width as fixed width in relation to container if (values.width.match(/%$/)) - {svg.width = values.width = Math.floor(SVG.cwidth*parseFloat(values.width)/100)+"px"} - var scale = this.SVGgetScale(), mu = this.SVGgetMu(svg); + {svg.width = values.width = SVG.Em((SVG.cwidth/1000)*(parseFloat(values.width)/100))} + + var mu = this.SVGgetMu(svg); var LABEL = -1; - var H = [], D = [], W = [], A = [], C = [], i, j, J = -1, m, M, s, row; - var LHD = SVG.FONTDATA.baselineskip * scale * values.useHeight, - LH = SVG.FONTDATA.lineH * scale, LD = SVG.FONTDATA.lineD * scale; + var H = [], D = [], W = [], A = [], C = [], i, j, J = -1, + m, M, s, row, cell, mo, HD; + var LH = SVG.FONTDATA.lineH * scale * values.useHeight, + LD = SVG.FONTDATA.lineD * scale * values.useHeight; // // Create cells and measure columns and rows // for (i = 0, m = this.data.length; i < m; i++) { row = this.data[i]; s = (row.type === "mlabeledtr" ? LABEL : 0); - A[i] = []; H[i] = D[i] = 0; + A[i] = []; H[i] = LH; D[i] = LD; for (j = s, M = row.data.length + s; j < M; j++) { if (W[j] == null) { if (j > J) {J = j} C[j] = BBOX.G(); W[j] = -SVG.BIGDIMEN; } - A[i][j] = row.data[j-s].toSVG(); + cell = row.data[j-s]; + A[i][j] = cell.toSVG(); // if (row.data[j-s].isMultiline) {A[i][j].style.width = "100%"} + if (cell.isEmbellished()) { + mo = cell.CoreMO(); + var min = mo.Get("minsize",true); + if (min) { + if (mo.SVGcanStretch("Vertical")) { + HD = mo.SVGdata.h + mo.SVGdata.d; + if (HD) { + min = SVG.length2em(min,mu,HD); + if (min*mo.SVGdata.h/HD > H[i]) {H[i] = min*mo.SVGdata.h/HD} + if (min*mo.SVGdata.d/HD > D[i]) {D[i] = min*mo.SVGdata.d/HD} + } + } else if (mo.SVGcanStretch("Horizontal")) { + min = SVG.length2em(min,mu,mo.SVGdata.w); + if (min > W[j]) {W[j] = min} + } + } + } if (A[i][j].h > H[i]) {H[i] = A[i][j].h} if (A[i][j].d > D[i]) {D[i] = A[i][j].d} if (A[i][j].w > W[j]) {W[j] = A[i][j].w} } } - if (H[0]+D[0]) {H[0] = Math.max(H[0],LH)} - if (H[A.length-1]+D[A.length-1]) {D[A.length-1] = Math.max(D[A.length-1],LD)} // // Determine spacing and alignment // - var CSPACE = values.columnspacing.split(/ /), - RSPACE = values.rowspacing.split(/ /), - CALIGN = values.columnalign.split(/ /), - RALIGN = values.rowalign.split(/ /), - CLINES = values.columnlines.split(/ /), - RLINES = values.rowlines.split(/ /), - CWIDTH = values.columnwidth.split(/ /), + var SPLIT = MathJax.Hub.SplitList; + var CSPACE = SPLIT(values.columnspacing), + RSPACE = SPLIT(values.rowspacing), + CALIGN = SPLIT(values.columnalign), + RALIGN = SPLIT(values.rowalign), + CLINES = SPLIT(values.columnlines), + RLINES = SPLIT(values.rowlines), + CWIDTH = SPLIT(values.columnwidth), RCALIGN = []; for (i = 0, m = CSPACE.length; i < m; i++) {CSPACE[i] = SVG.length2em(CSPACE[i],mu)} for (i = 0, m = RSPACE.length; i < m; i++) {RSPACE[i] = SVG.length2em(RSPACE[i],mu)} @@ -98,7 +121,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { row = this.data[i]; RCALIGN[i] = []; if (row.rowalign) {RALIGN[i] = row.rowalign} if (row.columnalign) { - RCALIGN[i] = row.columnalign.split(/ /); + RCALIGN[i] = SPLIT(row.columnalign); while (RCALIGN[i].length <= J) {RCALIGN[i].push(RCALIGN[i][RCALIGN[i].length-1])} } } @@ -118,17 +141,22 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // // Determine array total height // - var HD = H[0] + D[A.length-1]; + HD = H[0] + D[A.length-1]; for (i = 0, m = A.length-1; i < m; i++) - {HD += Math.max((H[i]+D[i] ? LHD : 0),D[i]+H[i+1]+RSPACE[i])} + {HD += Math.max(0,D[i]+H[i+1]+RSPACE[i])} // // Determine frame and line sizes // var fx = 0, fy = 0, fW, fH = HD; if (values.frame !== "none" || (values.columnlines+values.rowlines).match(/solid|dashed/)) { - fx = SVG.length2em(values.framespacing.split(/[, ]+/)[0],mu); - fy = SVG.length2em(values.framespacing.split(/[, ]+/)[1],mu); + var frameSpacing = SPLIT(values.framespacing); + if (frameSpacing.length != 2) { + // invalid attribute value: use the default. + frameSpacing = SPLIT(this.defaults.framespacing); + } + fx = SVG.length2em(frameSpacing[0],mu); + fy = SVG.length2em(frameSpacing[1],mu); fH = HD + 2*fy; // fW waits until svg.w is determined } // @@ -137,7 +165,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { var Y, fY, n = ""; if (typeof(values.align) !== "string") {values.align = String(values.align)} if (values.align.match(/(top|bottom|center|baseline|axis)( +(-?\d+))?/)) - {n = RegExp.$3; values.align = RegExp.$1} else {values.align = this.defaults.align} + {n = RegExp.$3||""; values.align = RegExp.$1} else {values.align = this.defaults.align} if (n !== "") { // // Find the height of the given row @@ -148,7 +176,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { Y = 0; fY = -(HD + fy) + H[0]; for (i = 0, m = n-1; i < m; i++) { // FIXME: Should handle values.align for final row - var dY = Math.max((H[i]+D[i] ? LHD : 0),D[i]+H[i+1]+RSPACE[i]); + var dY = Math.max(0,D[i]+H[i+1]+RSPACE[i]); Y += dY; fY += dY; } } else { @@ -177,9 +205,9 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // Get total width minus column spacing WW = SVG.length2em(values.width,mu); - for (i = 0, m = Math.min(J+1,CSPACE.length); i < m; i++) {WW -= CSPACE[i]} + for (i = 0, m = Math.min(J,CSPACE.length); i < m; i++) {WW -= CSPACE[i]} // Determine individual column widths - WW /= J+1; + WW /= J; for (i = 0, m = Math.min(J+1,CWIDTH.length); i < m; i++) {W[i] = WW} } else { // @@ -199,7 +227,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { if (WP > .98) {Wf = Wp/(Wt+Wp); WW = Wt + Wp} else {WW = Wt / (1-WP)} } else { WW = SVG.length2em(values.width,mu); - for (i = 0, m = Math.min(J+1,CSPACE.length); i < m; i++) {WW -= CSPACE[i]} + for (i = 0, m = Math.min(J,CSPACE.length); i < m; i++) {WW -= CSPACE[i]} } // Determine the relative column widths for (i = 0, m = P.length; i < m; i++) { @@ -229,11 +257,11 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { for (i = 0, m = A.length; i < m; i++) { if (A[i][j]) { s = (this.data[i].type === "mlabeledtr" ? LABEL : 0); - var cell = this.data[i].data[j-s]; + cell = this.data[i].data[j-s]; if (cell.SVGcanStretch("Horizontal")) { A[i][j] = cell.SVGstretchH(W[j]); } else if (cell.SVGcanStretch("Vertical")) { - var mo = cell.CoreMO(); + mo = cell.CoreMO(); var symmetric = mo.symmetric; mo.symmetric = false; A[i][j] = cell.SVGstretchV(H[i],D[i]); mo.symmetric = symmetric; @@ -242,11 +270,11 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { dy = ({top: H[i] - A[i][j].h, bottom: A[i][j].d - D[i], center: ((H[i]-D[i]) - (A[i][j].h-A[i][j].d))/2, - baseline: 0, axis: 0})[align]; // FIXME: handle axis better? + baseline: 0, axis: 0})[align] || 0; // FIXME: handle axis better? align = (cell.columnalign||RCALIGN[i][j]||CALIGN[j]) C[j].Align(A[i][j],align,0,y+dy); } - if (i < A.length-1) {y -= Math.max((H[i]+D[i] ? LHD : 0),D[i]+H[i+1]+RSPACE[i])} + if (i < A.length-1) {y -= Math.max(0,D[i]+H[i+1]+RSPACE[i])} } y = Y; } @@ -279,7 +307,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // y = Y - lw/2; for (i = 0, m = A.length-1; i < m; i++) { - dy = Math.max(LHD,D[i]+H[i+1]+RSPACE[i]); + dy = Math.max(0,D[i]+H[i+1]+RSPACE[i]); if (RLINES[i] !== "none") {svg.Add(BBOX.HLINE(fW,lw,RLINES[i]),0,y-D[i]-(dy-D[i]-H[i+1])/2)} y -= dy; @@ -296,25 +324,40 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // Place the labels, if any // if (C[LABEL]) { + svg.tw = Math.max(svg.w,svg.r) - Math.min(0,svg.l); var indent = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift"); if (indent.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {indent.indentalign = indent.indentalignfirst} if (indent.indentalign === MML.INDENTALIGN.AUTO) {indent.indentalign = this.displayAlign} if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {indent.indentshift = indent.indentshiftfirst} - if (indent.indentshift === "auto") {indent.indentshift = this.displayIndent} - var shift = (indent.indentshift ? SVG.length2em(indent.indentshift,mu) : 0); - var labelshift = SVG.length2em(values.minlabelspacing,mu); - var eqn = svg; svg = this.SVG(); + if (indent.indentshift === "auto" || indent.indentshift === "") {indent.indentshift = "0"} + var shift = SVG.length2em(indent.indentshift,mu,SVG.cwidth); + var labelspace = SVG.length2em(values.minlabelspacing,mu,SVG.cwidth); + var labelW = labelspace + C[LABEL].w, labelshift = 0, tw = svg.w; + var dIndent = SVG.length2em(this.displayIndent,mu,SVG.cwidth); + s = (CALIGN[LABEL] === MML.INDENTALIGN.RIGHT ? -1 : 1); if (indent.indentalign === MML.INDENTALIGN.CENTER) { - svg.w = svg.r = SVG.length2em(SVG.cwidth+"px"); shift = 0; svg.hasIndent = true; - } else if (CALIGN[LABEL] !== indent.indentalign) { - svg.w = svg.r = SVG.length2em(SVG.cwidth+"px") - shift - labelshift; - shift = labelshift = 0; + var dx = (SVG.cwidth-tw)/2; shift += dIndent; + if (labelW + s*labelshift > dx + s*shift) { + indent.indentalign = CALIGN[LABEL]; + shift = s*(labelW + s*labelshift); tw += labelW + Math.max(0,shift); + } + } else if (CALIGN[LABEL] === indent.indentalign) { + if (dIndent < 0) {labelshift = s*dIndent; dIndent = 0} + shift += s*dIndent; if (labelW > s*shift) shift = s*labelW; shift += labelshift; + tw += s*shift; } else { - svg.w = svg.r = eqn.w + shift; - svg.hasIndent = true; + shift -= s*dIndent; + if (tw - s*shift + labelW > SVG.cwidth) { + shift = s*(tw + labelW - SVG.cwidth); + if (s*shift > 0) {tw = SVG.cwidth + s*shift; shift = 0} + } } - svg.Align(eqn,indent.indentalign,shift,0); - svg.Align(C[LABEL],CALIGN[LABEL],labelshift,0); + var eqn = svg; svg = this.SVG(); + svg.hasIndent = true; + svg.w = svg.r = Math.max(tw,SVG.cwidth); + svg.Align(C[LABEL],CALIGN[LABEL],0,0,labelshift); + svg.Align(eqn,indent.indentalign,0,0,shift); + svg.tw = tw; } this.SVGsaveData(svg); diff --git a/resources/viewer/mathjax/jax/output/SVG/autoload/multiline.js b/resources/viewer/mathjax/jax/output/SVG/autoload/multiline.js index 4ee0ce4f7a..6a918e5991 100644 --- a/resources/viewer/mathjax/jax/output/SVG/autoload/multiline.js +++ b/resources/viewer/mathjax/jax/output/SVG/autoload/multiline.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/autoload/multiline.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,7 +25,7 @@ */ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { - var VERSION = "2.0"; + var VERSION = "2.6.0"; var MML = MathJax.ElementJax.mml, SVG = MathJax.OutputJax.SVG, BBOX = SVG.BBOX; @@ -37,7 +40,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { badbreak: [+200], auto: [0], - toobig: 500, + toobig: 800, nestfactor: 400, spacefactor: -100, spaceoffset: 2, @@ -83,14 +86,17 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // // Start with a fresh SVG element // and make it full width if we are breaking to a specific width + // in the top-level math element // svg = this.SVG(); - if (SVG.linebreakWidth < SVG.BIGDIMEN) {svg.w = SVG.linebreakWidth} - else {svg.w = SVG.cwidth/SVG.em * 1000} + if (isTop && parent.type !== "mtd") { + if (SVG.linebreakWidth < SVG.BIGDIMEN) {svg.w = SVG.linebreakWidth} + else {svg.w = SVG.cwidth} + } var state = { n: 0, Y: 0, - scale: this.SVGgetScale(), + scale: this.scale || 1, isTop: isTop, values: {}, VALUES: VALUES @@ -109,7 +115,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // Break the expression at its best line breaks // while (this.SVGbetterBreak(end,state) && - (end.scanW >= SVG.linebreakWidth || end.penalty == PENALTY.newline)) { + (end.scanW >= SVG.linebreakWidth || end.penalty === PENALTY.newline)) { this.SVGaddLine(svg,start,end.index,state,end.values,broken); start = end.index.slice(0); broken = true; align = this.SVGgetAlign(state,end.values); @@ -149,32 +155,40 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // Get the current breakpoint position and other data // var index = info.index.slice(0), i = info.index.shift(), - m = this.data.length, W, scanW = info.W, - broken = (info.index.length > 0), better = false; - if (i == null) {i = -1}; if (!broken) {i++; info.W += info.w}; - info.w = 0; info.nest++; + m = this.data.length, W, w, scanW, broken = (info.index.length > 0), better = false; + if (i == null) {i = -1}; if (!broken) {i++; info.W += info.w; info.w = 0} + scanW = info.scanW = info.W; info.nest++; // // Look through the line for breakpoints, // (as long as we are not too far past the breaking width) // - while (i < m && info.W < 1.33*SVG.linebreakWidth) { + while (i < m && info.scanW < 1.33*SVG.linebreakWidth) { if (this.data[i]) { if (this.data[i].SVGbetterBreak(info,state)) { - better = true; index = [i].concat(info.index); W = info.W; - if (info.penalty === PENALTY.newline) {info.index = index; info.nest--; return true} - } - if (!broken) { - var svg = this.data[i].SVGdata; - scanW += svg.w + svg.x; if (svg.X) {scanW += svg.X} - info.W = info.scanW = scanW; + better = true; index = [i].concat(info.index); W = info.W; w = info.w; + if (info.penalty === PENALTY.newline) { + info.index = index; + if (info.nest) {info.nest--} + return true; + } } + scanW = (broken ? info.scanW : this.SVGaddWidth(i,info,scanW)); } info.index = []; i++; broken = false; } - info.nest--; info.index = index; + if (info.nest) {info.nest--} + info.index = index; if (better) {info.W = W} return better; }, + SVGaddWidth: function (i,info,scanW) { + if (this.data[i]) { + var svg = this.data[i].SVGdata; + scanW += svg.w + svg.x; if (svg.X) {scanW += svg.X} + info.W = info.scanW = scanW; info.w = 0; + } + return scanW; + }, /****************************************************************/ // @@ -197,24 +211,18 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { var align = this.SVGgetAlign(state,values), shift = this.SVGgetShift(state,values,align); // - // Add in space for the shift - // - if (shift) { - if (align === MML.INDENTALIGN.LEFT) {line.x = shift} else - if (align === MML.INDENTALIGN.RIGHT) {line.w += shift; line.r = line.w} - } - // // Set the Y offset based on previous depth, leading, and current height // if (state.n > 0) { var LHD = SVG.FONTDATA.baselineskip * state.scale; - var leading = (state.values.lineleading == null ? state.VALUES : state.values).lineleading; + var leading = (state.values.lineleading == null ? state.VALUES : state.values).lineleading * state.scale; state.Y -= Math.max(LHD,state.d + line.h + leading); } // // Place the new line // - svg.Align(line,align,0,state.Y); + if (line.w + shift > svg.w) svg.w = line.w + shift; + svg.Align(line,align,0,state.Y,shift); // // Save the values needed for the future // @@ -235,14 +243,18 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { return align; }, SVGgetShift: function (state,values,align) { - if (align === MML.INDENTALIGN.CENTER) {return 0} var cur = values, prev = state.values, def = state.VALUES, shift; if (state.n === 0) {shift = cur.indentshiftfirst || prev.indentshiftfirst || def.indentshiftfirst} else if (state.isLast) {shift = prev.indentshiftlast || def.indentshiftlast} else {shift = prev.indentshift || def.indentshift} if (shift === MML.INDENTSHIFT.INDENTSHIFT) {shift = prev.indentshift || def.indentshift} - if (shift === "auto" || shift === "") {shift = (state.isTSop ? this.displayIndent : "0")} - return SVG.length2em(shift,0); + if (shift === "auto" || shift === "") {shift = "0"} + shift = SVG.length2em(shift,1,SVG.cwidth); + if (state.isTop && this.displayIndent !== "0") { + var indent = SVG.length2em(this.displayIndent,1,SVG.cwidth); + shift += (align === MML.INDENTALIGN.RIGHT ? -indent: indent); + } + return shift; }, /****************************************************************/ @@ -303,8 +315,8 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { /****************************************************************/ // - // Move an element from its original span to its new location in - // a split element or the new line's span + // Move an element from its original position to its new location in + // a split element or the new line's position // SVGmove: function (line,state,values) { // FIXME: handle linebreakstyle === "duplicate" @@ -314,24 +326,240 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { (state.last && values.linebreakstyle === MML.LINEBREAKSTYLE.AFTER)) { // // Recreate output - // Remove padding (if first, remove at right, if last remove at left) + // Remove padding (if first, remove at leftt, if last remove at right) // Add to line // var svg = this.toSVG(this.SVGdata.HW,this.SVGdata.D); - if (state.last) {svg.x = 0} - if (state.first || state.nextIsFirst) {delete state.nextIsFirst; if (svg.X) {svg.X = 0}} + if (state.first || state.nextIsFirst) {svg.x = 0} + if (state.last && svg.X) {svg.X = 0} line.Add(svg,line.w,0,true); - } else if (state.first) {state.nextIsFirst = true} else {delete state.nextIsFirst} + } + if (state.first && svg && svg.w === 0) {state.nextIsFirst = true} + else {delete state.nextIsFirst} } }); /**************************************************************************/ + MML.mfenced.Augment({ + SVGbetterBreak: function (info,state) { + // + // Get the current breakpoint position and other data + // + var index = info.index.slice(0), i = info.index.shift(), + m = this.data.length, W, w, scanW, broken = (info.index.length > 0), better = false; + if (i == null) {i = -1}; if (!broken) {i++; info.W += info.w; info.w = 0} + scanW = info.scanW = info.W; info.nest++; + // + // Create indices that include the delimiters and separators + // + if (!this.dataI) { + this.dataI = []; + if (this.data.open) {this.dataI.push("open")} + if (m) {this.dataI.push(0)} + for (var j = 1; j < m; j++) { + if (this.data["sep"+j]) {this.dataI.push("sep"+j)} + this.dataI.push(j); + } + if (this.data.close) {this.dataI.push("close")} + } + m = this.dataI.length; + // + // Look through the line for breakpoints, including the open, close, and separators + // (as long as we are not too far past the breaking width) + // + while (i < m && info.scanW < 1.33*SVG.linebreakWidth) { + var k = this.dataI[i]; + if (this.data[k]) { + if (this.data[k].SVGbetterBreak(info,state)) { + better = true; index = [i].concat(info.index); W = info.W; w = info.w; + if (info.penalty === PENALTY.newline) { + info.index = index; + if (info.nest) {info.nest--} + return true; + } + } + scanW = (broken ? info.scanW : this.SVGaddWidth(i,info,scanW)); + } + info.index = []; i++; broken = false; + } + if (info.nest) {info.nest--} + info.index = index; + if (better) {info.W = W; info.w = w} + return better; + }, + + SVGmoveLine: function (start,end,svg,state,values) { + var i = start[0], j = end[0]; + if (i == null) {i = -1}; if (j == null) {j = this.dataI.length-1} + if (i === j && start.length > 1) { + // + // If starting and ending in the same element move the subpiece to the new line + // + this.data[this.dataI[i]].SVGmoveSlice(start.slice(1),end.slice(1),svg,state,values,"paddingLeft"); + } else { + // + // Otherwise, move the remainder of the initial item + // and any others (including open and separators) up to the last one + // + var last = state.last; state.last = false; var k = this.dataI[i]; + while (i < j) { + if (this.data[k]) { + if (start.length <= 1) {this.data[k].SVGmove(svg,state,values)} + else {this.data[k].SVGmoveSlice(start.slice(1),[],svg,state,values,"paddingLeft")} + } + i++; k = this.dataI[i]; state.first = false; start = []; + } + // + // If the last item is complete, move it + // + state.last = last; + if (this.data[k]) { + if (end.length <= 1) {this.data[k].SVGmove(svg,state,values)} + else {this.data[k].SVGmoveSlice([],end.slice(1),svg,state,values,"paddingRight")} + } + } + } + + }); + + /**************************************************************************/ + + MML.msubsup.Augment({ + SVGbetterBreak: function (info,state) { + if (!this.data[this.base]) {return false} + // + // Get the current breakpoint position and other data + // + var index = info.index.slice(0), i = info.index.shift(), + W, w, scanW, broken = (info.index.length > 0), better = false; + if (!broken) {info.W += info.w; info.w = 0} + scanW = info.scanW = info.W; + // + // Record the width of the base and the super- and subscripts + // + if (i == null) {this.SVGdata.dw = this.SVGdata.w - this.data[this.base].SVGdata.w} + // + // Check if the base can be broken + // + if (this.data[this.base].SVGbetterBreak(info,state)) { + better = true; index = [this.base].concat(info.index); W = info.W; w = info.w; + if (info.penalty === PENALTY.newline) {better = broken = true} + } + // + // Add in the base if it is unbroken, and add the scripts + // + if (!broken) {this.SVGaddWidth(this.base,info,scanW)} + info.scanW += this.SVGdata.dw; info.W = info.scanW; + info.index = []; if (better) {info.W = W; info.w = w; info.index = index} + return better; + }, + + SVGmoveLine: function (start,end,svg,state,values) { + // + // Move the proper part of the base + // + if (this.data[this.base]) { + if (start.length > 1) { + this.data[this.base].SVGmoveSlice(start.slice(1),end.slice(1),svg,state,values,"paddingLeft"); + } else { + if (end.length <= 1) {this.data[this.base].SVGmove(svg,state,values)} + else {this.data[this.base].SVGmoveSlice([],end.slice(1),svg,state,values,"paddingRight")} + } + } + // + // If this is the end, check for super and subscripts, and move those + // by moving the stack that contains them, and shifting by the amount of the + // base that has been removed. Remove the empty base box from the stack. + // + if (end.length === 0) { + var sup = this.data[this.sup], sub = this.data[this.sub], w = svg.w, data; + if (sup) {data = sup.SVGdata||{}; svg.Add(sup.toSVG(),w+(data.dx||0),data.dy)} + if (sub) {data = sub.SVGdata||{}; svg.Add(sub.toSVG(),w+(data.dx||0),data.dy)} + } + } + + }); + + /**************************************************************************/ + + MML.mmultiscripts.Augment({ + SVGbetterBreak: function (info,state) { + if (!this.data[this.base]) {return false} + // + // Get the current breakpoint position and other data + // + var index = info.index.slice(0); info.index.shift(); + var W, w, scanW, broken = (info.index.length > 0), better = false; + if (!broken) {info.W += info.w; info.w = 0} + info.scanW = info.W; + // + // The width of the postscripts + // + var dw = this.SVGdata.w - this.data[this.base].SVGdata.w - this.SVGdata.dx; + // + // Add in the prescripts + // + info.scanW += this.SVGdata.dx; scanW = info.scanW; + // + // Check if the base can be broken (but don't break between prescripts and base) + // + if (this.data[this.base].SVGbetterBreak(info,state)) { + better = true; index = [this.base].concat(info.index); W = info.W; w = info.w; + if (info.penalty === PENALTY.newline) {better = broken = true} + } + // + // Add in the base if it is unbroken, and add the postscripts + // + if (!broken) {this.SVGaddWidth(this.base,info,scanW)} + info.scanW += dw; info.W = info.scanW; + info.index = []; if (better) {info.W = W; info.w = w; info.index = index} + return better; + }, + + SVGmoveLine: function (start,end,svg,state,values) { + var dx, data = this.SVGdata; + // + // If this is the start, move the prescripts, if any. + // + if (start.length < 1) { + this.scriptBox = this.SVGgetScripts(this.SVGdata.s); + var presub = this.scriptBox[2], presup = this.scriptBox[3]; dx = svg.w + data.dx; + if (presup) {svg.Add(presup,dx+data.delta-presup.w,data.u)} + if (presub) {svg.Add(presub,dx-presub.w,-data.v)} + } + // + // Move the proper part of the base + // + if (this.data[this.base]) { + if (start.length > 1) { + this.data[this.base].SVGmoveSlice(start.slice(1),end.slice(1),svg,state,values,"paddingLeft"); + } else { + if (end.length <= 1) {this.data[this.base].SVGmove(svg,state,values)} + else {this.data[this.base].SVGmoveSlice([],end.slice(1),svg,state,values,"paddingRight")} + } + } + // + // If this is the end, move the postscripts, if any. + // + if (end.length === 0) { + var sub = this.scriptBox[0], sup = this.scriptBox[1]; dx = svg.w + data.s; + if (sup) {svg.Add(sup,dx,data.u)} + if (sub) {svg.Add(sub,dx-data.delta,-data.v)} + delete this.scriptBox; + } + } + + }); + + /**************************************************************************/ + MML.mo.Augment({ // // Override the method for checking line breaks to properly handle // SVGbetterBreak: function (info,state) { + if (info.values && info.values.last === this) {return false} var values = this.getValues( "linebreak","linebreakstyle","lineleading","linebreakmultchar", "indentalign","indentshift", @@ -346,14 +574,16 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // mrows for nesting, but can leave these unbalanced. // if (values.texClass === MML.TEXCLASS.OPEN) {info.nest++} - if (values.texClass === MML.TEXCLASS.CLOSE) {info.nest--} + if (values.texClass === MML.TEXCLASS.CLOSE && info.nest) {info.nest--} // // Get the default penalty for this location // - var W = info.W, mo = (info.embellished||this); delete info.embellished; + var W = info.scanW, mo = info.embellished; delete info.embellished; + if (!mo || !mo.SVGdata) {mo = this} var svg = mo.SVGdata, w = svg.w + svg.x; if (values.linebreakstyle === MML.LINEBREAKSTYLE.AFTER) {W += w; w = 0} - if (W - info.shift === 0) {return false} // don't break at zero width (FIXME?) + if (W - info.shift === 0 && values.linebreak !== MML.LINEBREAK.NEWLINE) + {return false} // don't break at zero width (FIXME?) var offset = SVG.linebreakWidth - W; // adjust offest for explicit first-line indent and align if (state.n === 0 && (values.indentshiftfirst !== state.VALUES.indentshiftfirst || @@ -385,7 +615,8 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // if (penalty >= info.penalty) {return false} info.penalty = penalty; info.values = values; info.W = W; info.w = w; - values.lineleading = SVG.length2em(values.lineleading,state.VALUES.lineleading); + values.lineleading = SVG.length2em(values.lineleading,1,state.VALUES.lineleading); + values.last = this; return true; } }); @@ -397,12 +628,18 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // Override the method for checking line breaks to properly handle // SVGbetterBreak: function (info,state) { + if (info.values && info.values.last === this) {return false} var values = this.getValues("linebreak"); + var linebreakValue = values.linebreak; + if (!linebreakValue || this.hasDimAttr()) { + // The MathML spec says that the linebreak attribute should be ignored + // if any dimensional attribute is set. + linebreakValue = MML.LINEBREAK.AUTO; + } // // Get the default penalty for this location // - var W = info.W, svg = this.SVGdata, w = svg.w + svg.x; - if (values.linebreakstyle === MML.LINEBREAKSTYLE.AFTER) {W += w; w = 0} + var W = info.scanW, svg = this.SVGdata, w = svg.w + svg.x; if (W - info.shift === 0) {return false} // don't break at zero width (FIXME?) var offset = SVG.linebreakWidth - W; // @@ -413,9 +650,10 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // Get the penalty for this type of break and // use it to modify the default penalty // - var linebreak = PENALTY[values.linebreak||MML.LINEBREAK.AUTO]; - if (values.linebreak === MML.LINEBREAK.AUTO && w >= PENALTY.spacelimit*1000) - {linebreak = [(w+PENALTY.spaceoffset)*PENALTY.spacefactor]} + var linebreak = PENALTY[linebreakValue]; + if (linebreakValue === MML.LINEBREAK.AUTO && w >= PENALTY.spacelimit*1000 && + !this.mathbackground && !this.backrgound) + {linebreak = [(w/1000+PENALTY.spaceoffset)*PENALTY.spacefactor]} if (!(linebreak instanceof Array)) { // for breaks past the width, don't modify penalty if (offset >= 0) {penalty = linebreak * info.nest} @@ -426,7 +664,8 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { // if (penalty >= info.penalty) {return false} info.penalty = penalty; info.values = values; info.W = W; info.w = w; - values.lineleading = state.VALUES.lineleading; values.linebreakstyle = "before"; + values.lineleading = state.VALUES.lineleading; + values.linebreakstyle = "before"; values.last = this; return true; } }); @@ -455,24 +694,6 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { SVGmoveLine: function (start,end,svg,state,values) { return this.Core().SVGmoveSlice(start,end,svg,state,values); }, - /* - * // - * // Split and move the hit boxes as well - * // - * SVGmoveSlice: function (start,end,svg,state,values,padding) { - * var hitbox = document.getElementById("MathJax-HitBox-"+this.spanID+SVG.idPostfix); - * if (hitbox) {hitbox.parentNode.removeChild(hitbox)} - * var slice = this.SUPER(arguments).SVGmoveSlice.apply(this,arguments); - * if (end.length === 0) { - * span = this.SVGspanElement(); var n = 0; - * while (span) { - * hitbox = this.SVGhandleHitBox(span,"-Continue-"+n); - * span = span.nextMathJaxSpan; n++; - * } - * } - * return slice; - * } - */ }); // diff --git a/resources/viewer/mathjax/jax/output/SVG/config.js b/resources/viewer/mathjax/jax/output/SVG/config.js index 6d43d6b57c..800db40826 100644 --- a/resources/viewer/mathjax/jax/output/SVG/config.js +++ b/resources/viewer/mathjax/jax/output/SVG/config.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/config.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -24,7 +27,7 @@ MathJax.OutputJax.SVG = MathJax.OutputJax({ id: "SVG", - version: "2.0", + version: "2.6.0", directory: MathJax.OutputJax.directory + "/SVG", extensionDir: MathJax.OutputJax.extensionDir + "/SVG", autoloadDir: MathJax.OutputJax.directory + "/SVG/autoload", @@ -33,11 +36,13 @@ MathJax.OutputJax.SVG = MathJax.OutputJax({ config: { scale: 100, minScaleAdjust: 50, // global math scaling factor, and minimum adjusted scale factor font: "TeX", // currently the only font available - blacker: 10, // stroke-width to make fonts blacker + blacker: 1, // stroke-width to make fonts blacker mtextFontInherit: false, // to make be in page font rather than MathJax font undefinedFamily: "STIXGeneral,'Arial Unicode MS',serif", // fonts to use for missing characters addMMLclasses: false, // keep MathML structure and use CSS classes to mark elements + useFontCache: true, // use elements to re-use font paths rather than repeat paths every time + useGlobalCache: true, // store fonts in a global for use in all equations, or one in each equation EqnChunk: (MathJax.Hub.Browser.isMobile ? 10: 50), // number of equations to process before showing them @@ -55,12 +60,34 @@ MathJax.OutputJax.SVG = MathJax.OutputJax({ // use "nn%" for a portion of the window size }, + merrorStyle: { + fontSize:"90%", color:"#C00", background:"#FF8", + border: "1px solid #C00", padding:"3px" + }, + styles: { ".MathJax_SVG_Display": { "text-align": "center", margin: "1em 0em" }, + // + // For mtextFontInherit version of \texttt{} + // + ".MathJax_SVG .MJX-monospace": { + "font-family": "monospace" + }, + + // + // For mtextFontInherit version of \textsf{} + // + ".MathJax_SVG .MJX-sans-serif": { + "font-family": "sans-serif" + }, + + // + // For tooltips + // "#MathJax_SVG_Tooltip": { "background-color": "InfoBackground", color: "InfoText", border: "1px solid black", @@ -68,7 +95,8 @@ MathJax.OutputJax.SVG = MathJax.OutputJax({ "-webkit-box-shadow": "2px 2px 5px #AAAAAA", // Safari 3 and Chrome "-moz-box-shadow": "2px 2px 5px #AAAAAA", // Forefox 3.5 "-khtml-box-shadow": "2px 2px 5px #AAAAAA", // Konqueror - padding: "3px 4px" + padding: "3px 4px", + "z-index": 401 } } } diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Arrows.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Arrows.js index b110994d9d..f8d4e0f611 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Arrows.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Arrows.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/Arrows.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/BoxDrawing.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/BoxDrawing.js index 994e2b3b4e..efb11889d5 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/BoxDrawing.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/BoxDrawing.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/BoxDrawing.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/CombDiacritMarks.js index e36bc9bd0b..00f9faf0c0 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Dingbats.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Dingbats.js index 6deba6337c..3abb3557d1 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Dingbats.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Dingbats.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/Dingbats.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/EnclosedAlphanum.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/EnclosedAlphanum.js index 7135ec883b..574464c536 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/EnclosedAlphanum.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/EnclosedAlphanum.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/EnclosedAlphanum.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeneralPunctuation.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeneralPunctuation.js index d017a1a43a..2395c71884 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeneralPunctuation.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeneralPunctuation.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/GeneralPunctuation.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeometricShapes.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeometricShapes.js index 325929dbe7..a9acbc3bee 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeometricShapes.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GeometricShapes.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/GeometricShapes.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GreekAndCoptic.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GreekAndCoptic.js index 0177ca31b9..f481b7d5ae 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GreekAndCoptic.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/GreekAndCoptic.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/GreekAndCoptic.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Latin1Supplement.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Latin1Supplement.js index 277d1b7a8f..9000725242 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Latin1Supplement.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Latin1Supplement.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/Latin1Supplement.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LatinExtendedA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LatinExtendedA.js index 8bbcf7d621..d097ce0a9f 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LatinExtendedA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LatinExtendedA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/LatinExtendedA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LetterlikeSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LetterlikeSymbols.js index 5dd114d306..20fb58b5b4 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LetterlikeSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/LetterlikeSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/LetterlikeSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Main.js index ffe9344d66..ea80fca669 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MathOperators.js index 2f05181329..4c14b0fd24 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/MathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscMathSymbolsB.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscMathSymbolsB.js index 4078f01ac5..85e0ea9160 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscMathSymbolsB.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscMathSymbolsB.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/MiscMathSymbolsB.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscSymbols.js index 18e64e698e..697d946c6b 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/MiscSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscTechnical.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscTechnical.js index 72ef594d32..d52172dcef 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscTechnical.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/MiscTechnical.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/MiscTechnical.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/PUA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/PUA.js index 34ca9ad008..021ce53ecf 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/PUA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/PUA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/PUA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SpacingModLetters.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SpacingModLetters.js index a5f3c67dc6..ccd6c6de30 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SpacingModLetters.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SpacingModLetters.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/SpacingModLetters.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SuppMathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SuppMathOperators.js index 5574761895..8f8bfdfe5c 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SuppMathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/AMS/Regular/SuppMathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/AMS/Regular/SuppMathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Bold/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Bold/Main.js index 1a066fd21b..b2d5a83975 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Bold/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Bold/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Caligraphic/Bold/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Regular/Main.js index 392217fd01..12148542da 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Caligraphic/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Caligraphic/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/BasicLatin.js index 02b1f8ee55..2c81d38547 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Bold/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Main.js index 9d9e1f1765..7cf5fdaaf4 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Bold/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Other.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Other.js index df2c038ef8..71b794acc2 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Other.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/Other.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Bold/Other.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/PUA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/PUA.js index aaca3b8a91..c83ff79146 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/PUA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Bold/PUA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Bold/PUA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/BasicLatin.js index 3de2aeab1e..101498add6 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Regular/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Main.js index 4824de11db..620cc788e7 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Other.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Other.js index 061eb1fb29..1c4820bdda 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Other.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/Other.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Regular/Other.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/PUA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/PUA.js index db97a1fe66..e8da68217e 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/PUA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Fraktur/Regular/PUA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Fraktur/Regular/PUA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Arrows.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Arrows.js index 26638a0b62..14628b53c9 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Arrows.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Arrows.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/Arrows.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/BasicLatin.js index 0ea6be8b69..7115a559dc 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiacritMarks.js index eada8990eb..c5f96789f5 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiactForSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiactForSymbols.js index 16c278b248..93c35b0e5a 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiactForSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/CombDiactForSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/CombDiactForSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeneralPunctuation.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeneralPunctuation.js index 664ecf3a5b..b3709c9843 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeneralPunctuation.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeneralPunctuation.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/GeneralPunctuation.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeometricShapes.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeometricShapes.js index 1c5b9a5995..6ca970045f 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeometricShapes.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GeometricShapes.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/GeometricShapes.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GreekAndCoptic.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GreekAndCoptic.js index a5db918302..bd5a975f34 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GreekAndCoptic.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/GreekAndCoptic.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/GreekAndCoptic.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -24,6 +24,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [680,0,692,39,643,'425 0L228 3Q63 3 51 0H39V62H147V618H39V680H612V676Q614 670 627 552T643 428V424H581V428Q580 430 576 461T562 524T532 576Q512 596 481 605T426 616T357 618H304V62H439V0H425'], + // GREEK CAPITAL LETTER DELTA + 0x394: [698,0,958,56,901,'901 12Q901 7 892 0H479Q65 0 62 2Q56 6 56 11Q56 14 242 347T433 685Q438 694 450 696Q454 698 480 698H506L523 687Q526 683 711 354T899 17Q901 13 901 12ZM653 137L427 538L202 137L315 136H540L653 137'], + // GREEK CAPITAL LETTER THETA 0x398: [696,10,894,64,830,'629 -10T446 -10T164 89T64 340Q64 380 71 420T102 510T163 596T266 662T418 696H438Q488 696 499 695Q582 686 644 655T741 584T796 495T823 409T829 338Q829 188 729 89ZM439 645Q416 645 390 638T333 615T275 564T236 480Q221 423 221 341Q221 272 230 228Q247 144 301 94T447 43T592 93T663 228Q672 272 672 341Q672 645 439 645ZM286 242V446H348V412H545V446H607V242H545V276H348V242H286'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Latin1Supplement.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Latin1Supplement.js index bf8a5740dc..fe0e89ff21 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Latin1Supplement.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Latin1Supplement.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/Latin1Supplement.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedA.js index d1e22739ec..deeac27e82 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/LatinExtendedA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedB.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedB.js index 7f4f27d7be..0e0c8d39da 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedB.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedB.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/LatinExtendedB.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LetterlikeSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LetterlikeSymbols.js index 9bec9333c5..c3a5eefd44 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LetterlikeSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/LetterlikeSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/LetterlikeSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Main.js index 6de61b9ac6..ce456e7461 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MathOperators.js index 0991bd54c8..ed69c3d229 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/MathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscMathSymbolsA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscMathSymbolsA.js index 0d0033969d..1333b2890e 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscMathSymbolsA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscMathSymbolsA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/MiscMathSymbolsA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscSymbols.js index cb5c1962cd..303934e6b1 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/MiscSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscTechnical.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscTechnical.js index a5fadb9d22..0e19d84bec 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscTechnical.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/MiscTechnical.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/MiscTechnical.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SpacingModLetters.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SpacingModLetters.js index 3163f117be..53a16f216f 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SpacingModLetters.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SpacingModLetters.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/SpacingModLetters.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SuppMathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SuppMathOperators.js index 18e2d0baee..494b71a946 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SuppMathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SuppMathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/SuppMathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SupplementalArrowsA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SupplementalArrowsA.js index 0df50e998f..225db4921f 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SupplementalArrowsA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Bold/SupplementalArrowsA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Bold/SupplementalArrowsA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/BasicLatin.js index 6901857d45..ab4546307c 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/CombDiacritMarks.js index ac51828312..0222ffcdce 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GeneralPunctuation.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GeneralPunctuation.js index 52b108e56e..d2abad0380 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GeneralPunctuation.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GeneralPunctuation.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/GeneralPunctuation.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GreekAndCoptic.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GreekAndCoptic.js index 17184b3ef3..de370446fd 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GreekAndCoptic.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/GreekAndCoptic.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/GreekAndCoptic.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -24,6 +24,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [680,0,627,54,705,'337 46Q339 46 342 46Q360 46 363 45T367 34Q367 13 359 5Q356 0 343 0Q339 0 320 0T268 1T196 2Q98 2 72 0H61Q54 7 54 11Q54 27 61 41Q65 46 95 46Q131 47 142 50T159 62L194 200Q229 337 264 477T299 623Q299 630 292 631T248 634Q216 634 214 638Q213 641 213 646Q213 674 224 678Q226 680 462 680H698Q705 676 705 669Q705 665 691 557T675 447Q673 440 652 440H637Q630 445 630 451Q630 452 632 467T636 504T638 543Q638 569 632 586T615 613T586 627T549 633T500 634Q491 634 487 634Q426 634 414 633T399 625Q397 621 327 342T257 59Q257 54 261 52T283 48T337 46'], + // GREEK CAPITAL LETTER DELTA + 0x394: [716,0,818,70,751,'409 0H145Q117 0 103 0T81 1T72 3T70 6Q70 9 310 354T557 707Q559 711 565 713Q570 716 587 716Q608 716 613 710Q616 704 683 358Q752 9 750 6Q750 2 747 2Q745 0 409 0ZM581 342L531 597Q530 597 352 342T174 85T403 84T632 86Q632 87 581 342'], + // GREEK CAPITAL LETTER THETA 0x398: [704,22,767,149,788,'149 237Q149 326 186 413T282 563T412 665T552 704Q619 704 667 678T741 611T777 528T788 444Q788 328 728 219T572 44T377 -22Q275 -22 212 50T149 237ZM691 480Q691 569 652 618T551 668Q458 668 367 562Q307 485 277 382T246 202Q246 147 260 108T298 51T343 24T387 16Q408 16 433 22T494 51T562 109T626 211T677 363Q691 423 691 480ZM302 275Q302 281 317 346T338 415L341 418H356Q380 418 380 408Q380 405 378 398T375 385Q375 384 480 384H585L588 398Q592 412 598 418H613Q636 418 636 409Q636 406 621 340Q617 326 612 306Q603 272 598 267L597 266H582Q558 266 558 276Q558 279 560 286T563 299Q563 300 458 300H353L350 286Q346 272 340 266H325Q302 266 302 275'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedA.js index 205e2a9ff7..870cbd6a52 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/LatinExtendedA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedB.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedB.js index 9e3b0c5701..992b68f4ff 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedB.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedB.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/LatinExtendedB.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LetterlikeSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LetterlikeSymbols.js index 3e18ef46fb..7518bc8e8f 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LetterlikeSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/LetterlikeSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/LetterlikeSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/Main.js index 6afca29d26..a2f380f347 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/MathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/MathOperators.js index be49d5b967..aef973c556 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/MathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Italic/MathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Italic/MathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/BasicLatin.js index f3ec8b117b..7c85edc26a 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/CombDiacritMarks.js index 28617befb1..ac31369f4b 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GeometricShapes.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GeometricShapes.js index 88647ba8be..e218c11c09 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GeometricShapes.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GeometricShapes.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/GeometricShapes.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GreekAndCoptic.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GreekAndCoptic.js index 4b50fa863b..52e4d33d4a 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GreekAndCoptic.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/GreekAndCoptic.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/GreekAndCoptic.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -24,6 +24,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [680,0,625,25,582,'128 619Q121 626 117 628T101 631T58 634H25V680H554V676Q556 670 568 560T582 444V440H542V444Q542 445 538 478T523 545T492 598Q454 634 349 634H334Q264 634 249 633T233 621Q232 618 232 339L233 61Q240 54 245 52T270 48T333 46H360V0H348Q324 3 182 3Q51 3 36 0H25V46H58Q100 47 109 49T128 61V619'], + // GREEK CAPITAL LETTER DELTA + 0x394: [716,0,833,46,786,'51 0Q46 4 46 7Q46 9 215 357T388 709Q391 716 416 716Q439 716 444 709Q447 705 616 357T786 7Q786 4 781 0H51ZM507 344L384 596L137 92L383 91H630Q630 93 507 344'], + // GREEK CAPITAL LETTER THETA 0x398: [705,23,778,56,722,'56 340Q56 423 86 494T164 610T270 680T388 705Q521 705 621 601T722 341Q722 260 693 191T617 75T510 4T388 -22T267 3T160 74T85 189T56 340ZM610 339Q610 428 590 495T535 598T463 651T384 668Q332 668 289 638T221 566Q168 485 168 339Q168 274 176 235Q189 158 228 105T324 28Q356 16 388 16Q415 16 442 24T501 54T555 111T594 205T610 339ZM223 263V422H263V388H514V422H554V263H514V297H263V263H223'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedA.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedA.js index 18b41e0f07..71cd2635ca 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedA.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedA.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/LatinExtendedA.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedB.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedB.js index a4dc0def81..6810e45812 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedB.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedB.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/LatinExtendedB.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LetterlikeSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LetterlikeSymbols.js index aa71c31a2b..a05cda4269 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LetterlikeSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/LetterlikeSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/LetterlikeSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/Main.js index f57a3ed2ca..f6a493cf7a 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MathOperators.js index b806eff27c..2a76ab16ae 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/MathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MiscSymbols.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MiscSymbols.js index 1095e5a4e9..cc984e1b9d 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MiscSymbols.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/MiscSymbols.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/MiscSymbols.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SpacingModLetters.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SpacingModLetters.js index 37f5f419bb..1a362a550d 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SpacingModLetters.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SpacingModLetters.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/SpacingModLetters.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SuppMathOperators.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SuppMathOperators.js index ef4fa71d65..d5d272c9fd 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SuppMathOperators.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Main/Regular/SuppMathOperators.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Main/Regular/SuppMathOperators.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/BoldItalic/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/BoldItalic/Main.js index b24dfbac9d..361fc1c7bb 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/BoldItalic/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/BoldItalic/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Math/BoldItalic/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -268,6 +268,9 @@ MathJax.OutputJax.SVG.FONTDATA.FONTS['MathJax_Math-bold-italic'] = { // GREEK CAPITAL LETTER GAMMA 0x393: [680,0,657,43,777,'257 618H231Q198 618 198 636Q202 672 214 678L219 680H763Q769 677 772 673T776 666L777 664Q777 659 766 549T751 433Q745 424 723 424Q704 424 699 427T693 441Q693 444 695 467T697 513Q697 543 689 563T670 594T636 610T592 617T534 618H516H456L455 614Q455 613 387 339T317 64Q317 62 375 62H411Q430 62 438 59T447 44Q444 7 430 2Q426 0 416 0Q409 0 359 1T231 2Q152 2 111 1T65 0Q48 0 43 15Q47 54 60 60Q64 62 113 62H162L163 66Q163 67 231 341T301 616Q301 618 257 618'], + // GREEK CAPITAL LETTER DELTA + 0x394: [711,0,958,59,904,'65 0Q59 6 59 9T61 16Q64 20 334 357T608 698Q616 706 629 710Q630 710 634 710T644 710T656 711Q686 711 694 703Q698 699 700 693Q706 674 805 345T904 14Q904 7 894 1L479 0H65ZM630 342L567 551L232 134L462 133H693Q693 137 630 342'], + // GREEK CAPITAL LETTER THETA 0x398: [702,17,867,54,844,'358 -17Q218 -17 136 49T54 243Q54 298 70 356T123 474T211 582T338 663T504 702H527Q578 702 590 701Q709 688 776 622T844 441Q844 379 825 315T765 192T668 86T532 11T358 -17ZM700 474Q700 525 685 561T642 616T587 643T528 652Q390 652 301 534Q252 472 225 373T198 210Q198 160 214 125T256 71T311 44T372 36Q484 36 571 119Q639 189 669 299T700 474ZM366 428Q366 425 364 419T362 411H466L570 412L573 422Q576 437 581 441T604 445Q620 445 623 444Q636 440 636 429Q636 423 616 340T593 253Q586 243 572 243H566Q545 243 539 249Q536 251 535 253T534 258T534 263T535 270T537 277H329L326 266Q323 251 318 247T295 243Q279 243 276 244Q263 248 263 259Q263 265 283 346Q288 366 295 394Q304 431 308 438T326 445H334H338Q366 445 366 428'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/Italic/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/Italic/Main.js index 80b8cd2a00..61be7e1348 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/Italic/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Math/Italic/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Math/Italic/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -267,6 +267,9 @@ MathJax.OutputJax.SVG.FONTDATA.FONTS['MathJax_Math-italic'] = { // GREEK CAPITAL LETTER GAMMA 0x393: [680,-1,615,31,721,'49 1Q31 1 31 10Q31 12 34 24Q39 43 44 45Q48 46 59 46H65Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 661Q197 674 203 680H714Q721 676 721 669Q721 664 708 557T694 447Q692 440 674 440H662Q655 445 655 454Q655 455 658 480T661 534Q661 572 652 592Q638 619 603 626T501 634H471Q398 633 393 630Q389 628 386 622Q385 619 315 341T245 60Q245 46 333 46H345Q366 46 366 35Q366 33 363 21T358 6Q356 1 339 1Q334 1 292 1T187 2Q122 2 88 2T49 1'], + // GREEK CAPITAL LETTER DELTA + 0x394: [716,0,833,48,788,'574 715L582 716Q589 716 595 716Q612 716 616 714Q621 712 621 709Q622 707 705 359T788 8Q786 5 785 3L781 0H416Q52 0 50 2T48 6Q48 9 305 358T567 711Q572 712 574 715ZM599 346L538 602L442 474Q347 345 252 217T157 87T409 86T661 88L654 120Q646 151 629 220T599 346'], + // GREEK CAPITAL LETTER THETA 0x398: [704,22,763,50,740,'740 435Q740 320 676 213T511 42T304 -22Q207 -22 138 35T51 201Q50 209 50 244Q50 346 98 438T227 601Q351 704 476 704Q514 704 524 703Q621 689 680 617T740 435ZM640 466Q640 523 625 565T583 628T532 658T479 668Q370 668 273 559T151 255Q150 245 150 213Q150 156 165 116T207 55T259 26T313 17Q385 17 451 63T561 184Q590 234 615 312T640 466ZM510 276Q510 278 512 288L515 298Q515 299 384 299H253L250 285Q246 271 244 268T231 265H227Q216 265 214 266T207 274Q207 278 223 345T244 416Q247 419 260 419H263Q280 419 280 408Q280 406 278 396L275 386Q275 385 406 385H537L540 399Q544 413 546 416T559 419H563Q574 419 576 418T583 410Q583 403 566 339Q549 271 544 267Q542 265 538 265H530H527Q510 265 510 276'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/BasicLatin.js index 9305fd05d9..2e7e6b5aaa 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Bold/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/CombDiacritMarks.js index bcb2f53abb..b15323eb26 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Bold/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Main.js index 336d85e2a5..4ad6887e23 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Bold/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Other.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Other.js index 28426b5e40..af8b3e1d79 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Other.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Bold/Other.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Bold/Other.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -30,6 +30,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [691,0,581,92,534,'92 664Q98 683 118 690Q121 691 312 691T508 689Q534 682 534 644V632V618Q534 582 508 573L502 572Q496 572 489 572Q486 572 463 572T416 573Q333 573 291 575H253V303Q253 31 251 25Q242 0 199 0H170L119 1Q99 7 92 28V664'], + // GREEK CAPITAL LETTER DELTA + 0x394: [694,0,917,60,856,'381 692Q386 694 458 694Q516 694 527 693T549 687Q564 680 575 663Q576 658 715 349T856 27Q856 6 838 1H826Q815 1 795 1T747 1T686 1T616 0T539 0T458 0T378 0T300 0T230 0T169 1T122 1T90 1H78Q60 6 60 27Q62 38 201 349T341 663Q356 687 381 692ZM627 148Q626 149 581 250T492 453L447 554Q447 553 446 552Q444 546 326 278L268 148Q268 147 448 147Q627 147 627 148'], + // GREEK CAPITAL LETTER THETA 0x398: [716,22,856,62,793,'62 340Q62 716 425 716Q511 716 576 696T681 642T747 559T783 458T793 341Q793 264 777 203T721 89T608 7T428 -22Q62 -22 62 340ZM638 333Q638 365 637 387T632 441T621 495T600 542T567 583T518 611T451 628Q443 629 427 629Q402 629 378 624T327 608T276 571T240 511Q217 453 217 345Q217 254 231 204T279 120Q333 69 428 69Q522 69 576 120Q638 183 638 333ZM279 349V373Q279 413 305 420Q309 422 427 422H487Q550 422 563 414T576 369V349Q576 345 576 337T577 324Q577 284 550 277Q545 275 428 275H369Q306 275 293 283T279 329V349'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/BasicLatin.js index 5a9e47c2ac..685cab02c7 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Italic/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/CombDiacritMarks.js index 9caa7151df..657f4c332e 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Italic/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Main.js index 13111cb4c0..9cf9ef2625 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Italic/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Other.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Other.js index 386bf55cfa..549114ba5a 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Other.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Italic/Other.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Italic/Other.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -30,6 +30,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [691,0,542,87,646,'87 2Q88 4 160 346T234 689Q234 691 440 691T646 689Q643 686 629 611H475L321 612Q193 4 191 2V0H87V2'], + // GREEK CAPITAL LETTER DELTA + 0x394: [694,0,833,42,790,'273 343L510 694H617Q790 2 790 0H416L42 1L273 343ZM539 576Q536 597 536 600Q536 602 535 605Q534 607 534 607Q527 580 222 130L201 98H651L648 110Q645 123 639 149T627 198Q554 489 539 576'], + // GREEK CAPITAL LETTER THETA 0x398: [715,22,778,119,804,'119 260Q119 348 157 433T254 579T387 677T533 715Q701 715 772 574Q804 511 804 431Q804 315 744 209T586 41T384 -22Q262 -22 191 59T119 260ZM706 426Q706 524 655 582T525 640Q454 640 395 600T293 502Q256 447 237 383T218 266Q218 168 269 112T401 55Q518 55 612 166T706 426ZM283 349L293 397H473Q652 397 652 396Q647 374 642 347L632 299H452Q273 299 273 300Q278 322 283 349'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/BasicLatin.js index a619443b45..abfc0b7a2e 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Regular/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/CombDiacritMarks.js index a03860815b..ca85d99e4c 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Regular/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Main.js index 2909a8b106..d7260985c1 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Other.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Other.js index 69e46ed61c..93d25b5c99 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Other.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/SansSerif/Regular/Other.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/SansSerif/Regular/Other.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -30,6 +30,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [691,0,542,87,499,'87 0V691H499V611H345L191 612V0H87'], + // GREEK CAPITAL LETTER DELTA + 0x394: [694,0,833,42,790,'203 348L362 694H470L629 348Q789 2 790 1Q790 0 416 0T42 1Q43 2 203 348ZM630 98Q630 100 584 198T481 422T407 603L405 610L403 600Q388 544 191 122L180 99L405 98H630'], + // GREEK CAPITAL LETTER THETA 0x398: [716,21,778,56,722,'56 344Q56 430 86 502T164 619T271 690T388 716Q448 716 506 691T613 619T692 501T722 344Q722 188 624 84T389 -21Q252 -21 154 83T56 344ZM624 345Q624 423 597 488T513 596T380 639Q343 639 305 621T232 568T175 475T153 344Q153 216 222 136T388 56Q487 56 555 138T624 345ZM209 299V397H568V299H209'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/BasicLatin.js index ccf3e15d35..23b3a0654a 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Script/Regular/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/Main.js index 37fc12e5a9..5715031cbb 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Script/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Script/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size1/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size1/Regular/Main.js index f2c713e19f..f600ca650d 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size1/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size1/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Size1/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size2/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size2/Regular/Main.js index c66a12d4f1..676541927d 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size2/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size2/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Size2/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size3/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size3/Regular/Main.js index fff991c49a..ea9a8be6fe 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size3/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size3/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Size3/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size4/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size4/Regular/Main.js index 39b2786d50..5bcb438488 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size4/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Size4/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Size4/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/BasicLatin.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/BasicLatin.js index 7d29689a8b..f3b160f041 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/BasicLatin.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/BasicLatin.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Typewriter/Regular/BasicLatin.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/CombDiacritMarks.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/CombDiacritMarks.js index 636d455b00..9ee14f8fa4 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/CombDiacritMarks.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/CombDiacritMarks.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Typewriter/Regular/CombDiacritMarks.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Main.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Main.js index 393ea1af5b..fe74dedcb9 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Main.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Main.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Typewriter/Regular/Main.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Other.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Other.js index 5e143426fd..f0f230afb4 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Other.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/Typewriter/Regular/Other.js @@ -2,7 +2,7 @@ * * MathJax/jax/output/SVG/fonts/TeX/svg/Typewriter/Regular/Other.js * - * Copyright (c) 2011 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -30,6 +30,9 @@ MathJax.Hub.Insert( // GREEK CAPITAL LETTER GAMMA 0x393: [611,0,525,25,488,'466 611Q468 609 473 606T479 602T483 598T486 593T487 586T488 576T488 562V526V488Q488 452 470 444Q466 442 446 442Q421 442 413 450Q406 457 405 463T404 501V535H185V76H222H239Q260 76 270 69T281 38Q281 12 270 6T209 0H155H104Q48 0 37 5T25 38Q25 59 35 69Q44 76 76 76H101V535H76H64Q36 535 27 552Q25 557 25 573T27 594Q33 606 43 608T106 611H258H466'], + // GREEK CAPITAL LETTER DELTA + 0x394: [623,0,525,35,489,'232 622H237Q242 622 249 622T264 623H293Q295 622 300 619T308 613T314 608T319 601Q322 597 405 316T489 19Q489 9 473 1Q471 0 262 0T51 1Q35 9 35 19Q35 34 118 315T205 601Q214 616 232 622ZM267 501Q266 504 265 510T263 521T261 526V523Q261 508 211 332Q142 91 138 82H386Q385 84 345 224Q281 439 267 501'], + // GREEK CAPITAL LETTER THETA 0x398: [621,10,525,56,468,'102 588Q140 621 240 621Q323 621 335 620Q393 613 422 588Q450 560 459 493T468 306Q468 185 460 118T422 23Q382 -10 289 -10H262H235Q142 -10 102 23Q74 50 65 118T56 306Q56 427 64 494T102 588ZM262 66Q285 66 300 67T329 74T351 86T366 108T376 138T381 181T383 235T384 306Q384 452 371 492T304 544Q296 545 251 545Q230 545 215 543T188 534T169 520T155 497T147 466T143 423T141 371T140 306Q140 247 141 215T146 151T158 107T179 82T212 69T262 66ZM179 356Q187 378 219 378H223Q240 377 249 372T260 360L261 355Q261 353 262 353T263 355Q263 362 272 369Q280 377 304 377H310Q325 377 331 374T346 356V256Q338 241 331 238T309 234H304Q280 234 272 242Q263 249 263 256Q263 258 262 258T261 256Q261 249 252 242Q244 234 220 234H216Q186 234 179 256V356'], diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata-extra.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata-extra.js index bc38bb5ca8..5b1c995efb 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata-extra.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata-extra.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/fonts/TeX/fontdata-extra.js @@ -6,7 +9,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,6 +25,7 @@ */ (function (SVG) { + var VERSION = "2.6.0"; var DELIMITERS = SVG.FONTDATA.DELIMITERS; @@ -48,12 +52,12 @@ 0x21A4: // left arrow from bar { dir: H, HW: [], - stretch: {left:[0x2190,MAIN], rep:[0x2212,MAIN], right:[0x2223,SIZE1,0,-.05,.9]} + stretch: {min:1, left:[0x2190,MAIN], rep:[0x2212,MAIN], right:[0x2223,SIZE1,0,-.05,.9]} }, 0x21A5: // up arrow from bar { dir: V, HW: [], - stretch: {bot:[0x22A5,BOLD,0,0,.75], ext:[0x23D0,SIZE1], top:[0x2191,SIZE1]} + stretch: {min:.6, bot:[0x22A5,BOLD,0,0,.75], ext:[0x23D0,SIZE1], top:[0x2191,SIZE1]} }, 0x21A6: // right arrow from bar { @@ -63,7 +67,7 @@ 0x21A7: // down arrow from bar { dir: V, HW: [], - stretch: {top:[0x22A4,BOLD,0,0,.75], ext:[0x23D0,SIZE1], bot:[0x2193,SIZE1]} + stretch: {min:.6, top:[0x22A4,BOLD,0,0,.75], ext:[0x23D0,SIZE1], bot:[0x2193,SIZE1]} }, 0x21B0: // up arrow with top leftwards { @@ -128,12 +132,12 @@ 0x23B4: // top square bracket { dir: H, HW: [], - stretch: {left:[0x250C,AMS,0,-.1], rep:[0x2212,MAIN,0,.325], right:[0x2510,AMS,0,-.1]} + stretch: {min:.5, left:[0x250C,AMS,0,-.1], rep:[0x2212,MAIN,0,.325], right:[0x2510,AMS,0,-.1]} }, 0x23B5: // bottom square bracket { dir: H, HW: [], - stretch: {left:[0x2514,AMS,0,.26], rep:[0x2212,MAIN,0,0,0,.25], right:[0x2518,AMS,0,.26]} + stretch: {min:.5, left:[0x2514,AMS,0,.26], rep:[0x2212,MAIN,0,0,0,.25], right:[0x2518,AMS,0,.26]} }, 0x23DC: // top paren { @@ -148,82 +152,82 @@ 0x23E0: // top tortoise shell { dir: H, HW: [], - stretch: {left:[0x2CA,MAIN,-.1], rep:[0x2C9,MAIN,0,.13], right:[0x2CB,MAIN], fullExtenders:true} + stretch: {min:1.25, left:[0x2CA,MAIN,-.1], rep:[0x2C9,MAIN,-.05,.13], right:[0x2CB,MAIN], fullExtenders:true} }, 0x23E1: // bottom tortoise shell { dir: H, HW: [], - stretch: {left:[0x2CB,MAIN,-.1,.1], rep:[0x2C9,MAIN], right:[0x2CA,MAIN,-.1,.1], fullExtenders:true} + stretch: {min:1.5, left:[0x2CB,MAIN,-.1,.1], rep:[0x2C9,MAIN,-.1], right:[0x2CA,MAIN,-.1,.1], fullExtenders:true} }, 0x2906: // leftwards double arrow from bar { dir: H, HW: [], - stretch: {left:[0x21D0,MAIN], rep:[0x3D,MAIN], right:[0x2223,SIZE1,0,-.1]} + stretch: {min:1, left:[0x21D0,MAIN], rep:[0x3D,MAIN], right:[0x2223,SIZE1,0,-.1]} }, 0x2907: // rightwards double arrow from bar { dir: H, HW: [], - stretch: {left:[0x22A8,AMS,0,-.12], rep:[0x3D,MAIN], right:[0x21D2,MAIN]} + stretch: {min:.7, left:[0x22A8,AMS,0,-.12], rep:[0x3D,MAIN], right:[0x21D2,MAIN]} }, 0x294E: // left barb up right barb up harpoon { dir: H, HW: [], - stretch: {left:[0x21BC,MAIN], rep:[0x2212,MAIN], right:[0x21C0,MAIN]} + stretch: {min:.5, left:[0x21BC,MAIN], rep:[0x2212,MAIN], right:[0x21C0,MAIN]} }, 0x294F: // up barb right down barb right harpoon { dir: V, HW: [], - stretch: {top:[0x21BE,AMS,.12,0,1.1], ext:[0x23D0,SIZE1], bot:[0x21C2,AMS,.12,0,1.1]} + stretch: {min:.5, top:[0x21BE,AMS,.12,0,1.1], ext:[0x23D0,SIZE1], bot:[0x21C2,AMS,.12,0,1.1]} }, 0x2950: // left barb dow right barb down harpoon { dir: H, HW: [], - stretch: {left:[0x21BD,MAIN], rep:[0x2212,MAIN], right:[0x21C1,MAIN]} + stretch: {min:.5, left:[0x21BD,MAIN], rep:[0x2212,MAIN], right:[0x21C1,MAIN]} }, 0x2951: // up barb left down barb left harpoon { dir: V, HW: [], - stretch: {top:[0x21BF,AMS,.12,0,1.1], ext:[0x23D0,SIZE1], bot:[0x21C3,AMS,.12,0,1.1]} + stretch: {min:.5, top:[0x21BF,AMS,.12,0,1.1], ext:[0x23D0,SIZE1], bot:[0x21C3,AMS,.12,0,1.1]} }, 0x295A: // leftwards harpoon with barb up from bar { dir: H, HW: [], - stretch: {left:[0x21BC,MAIN], rep:[0x2212,MAIN], right:[0x2223,SIZE1,0,-.05,.9]} + stretch: {min:1, left:[0x21BC,MAIN], rep:[0x2212,MAIN], right:[0x2223,SIZE1,0,-.05,.9]} }, 0x295B: // rightwards harpoon with barb up from bar { dir: H, HW: [], - stretch: {left:[0x2223,SIZE1,-.09,-.05,.9], rep:[0x2212,MAIN], right:[0x21C0,MAIN]} + stretch: {min:1, left:[0x2223,SIZE1,-.05,-.05,.9], rep:[0x2212,MAIN], right:[0x21C0,MAIN]} }, 0x295C: // up harpoon with barb right from bar { dir: V, HW: [], - stretch: {bot:[0x22A5,BOLD,0,0,.75], ext:[0x23D0,SIZE1], top:[0x21BE,AMS,.12,0,1.1]} + stretch: {min:.7, bot:[0x22A5,BOLD,0,0,.75], ext:[0x23D0,SIZE1], top:[0x21BE,AMS,.12,0,1.1]} }, 0x295D: // down harpoon with barb right from bar { dir: V, HW: [], - stretch: {top:[0x22A4,BOLD,0,0,.75], ext:[0x23D0,SIZE1], bot:[0x21C2,AMS,.12,0,1.1]} + stretch: {min:.7, top:[0x22A4,BOLD,0,0,.75], ext:[0x23D0,SIZE1], bot:[0x21C2,AMS,.12,0,1.1]} }, 0x295E: // leftwards harpoon with barb down from bar { dir: H, HW: [], - stretch: {left:[0x21BD,MAIN], rep:[0x2212,MAIN], right:[0x2223,SIZE1,0,-.05,.9]} + stretch: {min:1, left:[0x21BD,MAIN], rep:[0x2212,MAIN], right:[0x2223,SIZE1,0,-.05,.9]} }, 0x295F: // rightwards harpoon with barb down from bar { dir: H, HW: [], - stretch: {left:[0x2223,SIZE1,-.09,-.05,.9], rep:[0x2212,MAIN], right:[0x21C1,MAIN]} + stretch: {min:1, left:[0x2223,SIZE1,-.05,-.05,.9], rep:[0x2212,MAIN], right:[0x21C1,MAIN]} }, 0x2960: // up harpoon with barb left from bar { dir: V, HW: [], - stretch: {bot:[0x22A5,BOLD,0,0,.75], ext:[0x23D0,SIZE1], top:[0x21BF,AMS,.12,0,1.1]} + stretch: {min:.7, bot:[0x22A5,BOLD,0,0,.75], ext:[0x23D0,SIZE1], top:[0x21BF,AMS,.12,0,1.1]} }, 0x2961: // down harpoon with barb left from bar { dir: V, HW: [], - stretch: {top:[0x22A4,BOLD,0,0,.75], ext:[0x23D0,SIZE1], bot:[0x21C3,AMS,.12,0,1.1]} + stretch: {min:.7, top:[0x22A4,BOLD,0,0,.75], ext:[0x23D0,SIZE1], bot:[0x21C3,AMS,.12,0,1.1]} } }; diff --git a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata.js b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata.js index e7d610e5b9..752df6866c 100644 --- a/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata.js +++ b/resources/viewer/mathjax/jax/output/SVG/fonts/TeX/fontdata.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/fonts/TeX/fontdata.js @@ -7,7 +10,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -22,8 +25,8 @@ * limitations under the License. */ -(function (SVG,MML,AJAX) { - var VERSION = "2.0"; +(function (SVG,MML,AJAX,HUB) { + var VERSION = "2.6.0"; var MAIN = "MathJax_Main", BOLD = "MathJax_Main-bold", @@ -35,6 +38,8 @@ SIZE4 = "MathJax_Size4"; var H = "H", V = "V", EXTRAH = {load:"extra", dir:H}, EXTRAV = {load:"extra", dir:V}; var STDHW = [[1000,MAIN],[1200,SIZE1],[1800,SIZE2],[2400,SIZE3],[3000,SIZE4]]; + var ARROWREP = [0x2212,MAIN,0,0,0,0,.1]; // add depth for arrow extender + var DARROWREP = [0x3D,MAIN,0,0,0,0,.1]; // add depth for arrow extender SVG.Augment({ FONTDATA: { @@ -61,7 +66,8 @@ "MathJax_SansSerif-bold": "SansSerif/Bold/Main.js", "MathJax_SansSerif-italic": "SansSerif/Italic/Main.js", "MathJax_Script": "Script/Regular/Main.js", - "MathJax_Typewriter": "Typewriter/Regular/Main.js" + "MathJax_Typewriter": "Typewriter/Regular/Main.js", + "MathJax_Caligraphic-bold": "Caligraphic/Bold/Main.js" }, VARIANT: { @@ -69,12 +75,18 @@ offsetG: 0x03B1, variantG: "italic", remap: {0x391:0x41, 0x392:0x42, 0x395:0x45, 0x396:0x5A, 0x397:0x48, 0x399:0x49, 0x39A:0x4B, 0x39C:0x4D, 0x39D:0x4E, 0x39F:0x4F, - 0x3A1:0x50, 0x3A4:0x54, 0x3A7:0x58, 0x29F8:[0x002F,"italic"]}}, + 0x3A1:0x50, 0x3A4:0x54, 0x3A7:0x58, + 0x2216:[0x2216,"-TeX-variant"], // \smallsetminus + 0x210F:[0x210F,"-TeX-variant"], // \hbar + 0x2032:[0x27,"sans-serif-italic"], // HACK: a smaller prime + 0x29F8:[0x002F,MML.VARIANT.ITALIC]}}, "bold": {fonts:[BOLD,SIZE1,AMS], bold:true, offsetG: 0x03B1, variantG: "bold-italic", remap: {0x391:0x41, 0x392:0x42, 0x395:0x45, 0x396:0x5A, 0x397:0x48, 0x399:0x49, 0x39A:0x4B, 0x39C:0x4D, 0x39D:0x4E, 0x39F:0x4F, 0x3A1:0x50, 0x3A4:0x54, 0x3A7:0x58, 0x29F8:[0x002F,"bold-italic"], + 0x219A:"\u2190\u0338", 0x219B:"\u2192\u0338", 0x21AE:"\u2194\u0338", + 0x21CD:"\u21D0\u0338", 0x21CE:"\u21D4\u0338", 0x21CF:"\u21D2\u0338", 0x2204:"\u2203\u0338", 0x2224:"\u2223\u0338", 0x2226:"\u2225\u0338", 0x2241:"\u223C\u0338", 0x2247:"\u2245\u0338", 0x226E:"<\u0338", 0x226F:">\u0338", @@ -111,8 +123,20 @@ remap: {0x391:0x41, 0x392:0x42, 0x395:0x45, 0x396:0x5A, 0x397:0x48, 0x399:0x49, 0x39A:0x4B, 0x39C:0x4D, 0x39D:0x4E, 0x39F:0x4F, 0x3A1:0x50, 0x3A4:0x54, 0x3A7:0x58}}, + "-TeX-variant": {fonts:[AMS,MAIN,SIZE1], // HACK: to get larger prime for \prime + remap: { + 0x2268: 0xE00C, 0x2269: 0xE00D, 0x2270: 0xE011, 0x2271: 0xE00E, + 0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2224: 0xE006, 0x2226: 0xE007, + 0x2288: 0xE016, 0x2289: 0xE018, 0x228A: 0xE01A, 0x228B: 0xE01B, + 0x2ACB: 0xE017, 0x2ACC: 0xE019, 0x03DC: 0xE008, 0x03F0: 0xE009, + 0x2216:[0x2216,MML.VARIANT.NORMAL], // \setminus + 0x210F:[0x210F,MML.VARIANT.NORMAL] // \hslash + }}, "-largeOp": {fonts:[SIZE2,SIZE1,MAIN]}, - "-smallOp": {fonts:[SIZE1,MAIN]} + "-smallOp": {fonts:[SIZE1,MAIN]}, + "-tex-caligraphic-bold": {fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"], bold:true, + offsetA: 0x41, variantA: "bold-italic"}, + "-tex-oldstyle-bold": {fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"], bold:true} }, RANGES: [ @@ -140,13 +164,16 @@ 0x2022: 0x2219, 0x2044: 0x2F, // bullet, fraction slash 0x2305: 0x22BC, 0x2306: 0x2A5E, // barwedge, doublebarwedge 0x25AA: 0x25A0, 0x25B4: 0x25B2, // blacksquare, blacktriangle - 0x25B5: 0x25B3, 0x25BE: 0x25BC, // triangle, blacktriangledown - 0x25BF: 0x25BD, 0x25C2: 0x25C0, // triangledown, blacktriangleleft + 0x25B5: 0x25B3, 0x25B8: 0x25B6, // triangle, blacktriangleright + 0x25BE: 0x25BC, 0x25BF: 0x25BD, // blacktriangledown, triangledown + 0x25C2: 0x25C0, // blacktriangleleft 0x2329: 0x27E8, 0x232A: 0x27E9, // langle, rangle 0x3008: 0x27E8, 0x3009: 0x27E9, // langle, rangle 0x2758: 0x2223, // VerticalSeparator 0x2A2F: 0xD7, // cross product + 0x25FB: 0x25A1, 0x25FC: 0x25A0, // square, blacksquare + // // Letter-like symbols (that appear elsewhere) // @@ -157,7 +184,7 @@ 0x210D: [0x0048,MML.VARIANT.DOUBLESTRUCK], 0x210E: [0x0068,MML.VARIANT.ITALIC], 0x2110: [0x004A,MML.VARIANT.SCRIPT], - 0x2111: [0x004A,MML.VARIANT.FRAKTUR], + 0x2111: [0x0049,MML.VARIANT.FRAKTUR], 0x2112: [0x004C,MML.VARIANT.SCRIPT], 0x2115: [0x004E,MML.VARIANT.DOUBLESTRUCK], 0x2119: [0x0050,MML.VARIANT.DOUBLESTRUCK], @@ -185,9 +212,10 @@ // 0x2204: "\u2203\u0338", // \not\exists 0x220C: "\u220B\u0338", // \not\ni - 0x2244: "\u2243\u0338", // \not\cong + 0x2244: "\u2243\u0338", // \not\simeq 0x2249: "\u2248\u0338", // \not\approx 0x2262: "\u2261\u0338", // \not\equiv + 0x226D: "\u224D\u0338", // \not\asymp 0x2274: "\u2272\u0338", // \not\lesssim 0x2275: "\u2273\u0338", // \not\gtrsim 0x2278: "\u2276\u0338", // \not\lessgtr @@ -197,15 +225,21 @@ 0x22E2: "\u2291\u0338", // \not\sqsubseteq 0x22E3: "\u2292\u0338", // \not\sqsupseteq + 0x2A0C: "\u222C\u222C", // quadruple integral + 0x2033: "\u2032\u2032", // double prime 0x2034: "\u2032\u2032\u2032", // triple prime 0x2036: "\u2035\u2035", // double back prime 0x2037: "\u2035\u2035\u2035", // trile back prime - 0x2057: "\u2032\u2032\u2032\u2032" // quadruple prime + 0x2057: "\u2032\u2032\u2032\u2032", // quadruple prime + 0x20DB: "...", // combining three dots above (only works with mover/under) + 0x20DC: "...." // combining four dots above (only works with mover/under) }, REMAPACCENT: { - "\u2192":"\u20D7" + "\u2192":"\u20D7", + "\u2032":"'", + "\u2035":"`" }, REMAPACCENTUNDER: { }, @@ -339,7 +373,7 @@ }, 0x2190: // left arrow { - dir: H, HW: [[1000,MAIN]], stretch: {left:[0x2190,MAIN],rep:[0x2212,MAIN], fuzz:300} + dir: H, HW: [[1000,MAIN]], stretch: {left:[0x2190,MAIN], rep:ARROWREP, fuzz:300} }, 0x2191: // \uparrow { @@ -347,7 +381,7 @@ }, 0x2192: // right arrow { - dir: H, HW: [[1000,MAIN]], stretch: {rep:[0x2212,MAIN], right:[0x2192,MAIN], fuzz:300} + dir: H, HW: [[1000,MAIN]], stretch: {rep:ARROWREP, right:[0x2192,MAIN], fuzz:300} }, 0x2193: // \downarrow { @@ -356,7 +390,7 @@ 0x2194: // left-right arrow { dir: H, HW: [[1000,MAIN]], - stretch: {left:[0x2190,MAIN],rep:[0x2212,MAIN], right:[0x2192,MAIN], fuzz:300} + stretch: {left:[0x2190,MAIN], rep:ARROWREP, right:[0x2192,MAIN], fuzz:300} }, 0x2195: // \updownarrow { @@ -365,7 +399,7 @@ }, 0x21D0: // left double arrow { - dir: H, HW: [[1000,MAIN]], stretch: {left:[0x21D0,MAIN],rep:[0x3D,MAIN], fuzz:300} + dir: H, HW: [[1000,MAIN]], stretch: {left:[0x21D0,MAIN], rep:DARROWREP, fuzz:300} }, 0x21D1: // \Uparrow { @@ -373,7 +407,7 @@ }, 0x21D2: // right double arrow { - dir: H, HW: [[1000,MAIN]], stretch: {rep:[0x3D,MAIN], right:[0x21D2,MAIN], fuzz:300} + dir: H, HW: [[1000,MAIN]], stretch: {rep:DARROWREP, right:[0x21D2,MAIN], fuzz:300} }, 0x21D3: // \Downarrow { @@ -382,7 +416,7 @@ 0x21D4: // left-right double arrow { dir: H, HW: [[1000,MAIN]], - stretch: {left:[0x21D0,MAIN],rep:[0x3D,MAIN], right:[0x21D2,MAIN], fuzz:300} + stretch: {left:[0x21D0,MAIN], rep:DARROWREP, right:[0x21D2,MAIN], fuzz:300} }, 0x21D5: // \Updownarrow { @@ -391,7 +425,7 @@ }, 0x2212: // horizontal line { - dir: H, HW: [[611,MAIN]], stretch: {rep:[0x2212,MAIN], fuzz:300} + dir: H, HW: [[778,MAIN]], stretch: {rep:[0x2212,MAIN], fuzz:300} }, 0x221A: // \surd { @@ -444,12 +478,12 @@ 0x23DE: // horizontal brace down { dir: H, HW: [], - stretch: {left:[0xE150,SIZE4], mid:[[0xE153,0xE152],SIZE4], right:[0xE151,SIZE4], rep:[0xE154,SIZE4]} + stretch: {min:.9, left:[0xE150,SIZE4], mid:[[0xE153,0xE152],SIZE4], right:[0xE151,SIZE4], rep:[0xE154,SIZE4]} }, 0x23DF: // horizontal brace up { dir: H, HW: [], - stretch: {left:[0xE152,SIZE4], mid:[[0xE151,0xE150],SIZE4], right:[0xE153,SIZE4], rep:[0xE154,SIZE4]} + stretch: {min:.9, left:[0xE152,SIZE4], mid:[[0xE151,0xE150],SIZE4], right:[0xE153,SIZE4], rep:[0xE154,SIZE4]} }, 0x27E8: // \langle { @@ -531,6 +565,9 @@ 0x295F: EXTRAH, // rightwards harpoon with barb down from bar 0x2960: EXTRAV, // up harpoon with barb left from bar 0x2961: EXTRAV, // down harpoon with barb left from bar + 0x2312: {alias: 0x23DC, dir:H}, // arc + 0x2322: {alias: 0x23DC, dir:H}, // frown + 0x2323: {alias: 0x23DD, dir:H}, // smile 0x27F5: {alias: 0x2190, dir:H}, // long left arrow 0x27F6: {alias: 0x2192, dir:H}, // long right arrow 0x27F7: {alias: 0x2194, dir:H}, // long left-right arrow @@ -546,13 +583,6 @@ }); - MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () { - var TEX = MathJax.InputJax.TeX; - TEX.Definitions.mathchar0mi.ell = ['2113',{mathvariant: MML.VARIANT.NORMAL}]; - TEX.Definitions.mathchar0mi.hbar = ['210F',{mathvariant: MML.VARIANT.NORMAL}]; - TEX.Definitions.mathchar0mi.S = ['00A7',{mathvariant: MML.VARIANT.SCRIPT}]; - }); - SVG.FONTDATA.FONTS['MathJax_Main'] = { directory: 'Main/Regular', family: 'MathJax_Main', @@ -1533,20 +1563,43 @@ SVG.FONTDATA.FONTS['MathJax_Main'][0x22EE][0] += 400; // adjust height for \vdots SVG.FONTDATA.FONTS['MathJax_Main'][0x22F1][0] += 700; // adjust height for \ddots - SVG.FONTDATA.FONTS['MathJax_Main'][0x2212][1] += 100; // adjust depth of minus (used as arrow extender) - SVG.FONTDATA.FONTS['MathJax_Main'][0x003D][1] += 100; // adjust depth of = (used as arrow extender) - MathJax.Hub.Register.LoadHook(SVG.fontDir+"/Size4/Regular/Main.js",function () { - SVG.FONTDATA.FONTS['MathJax_Size4'][0xE154][0] += 200; // adjust height for brace extender - SVG.FONTDATA.FONTS['MathJax_Size4'][0xE154][1] += 200; // adjust depth for brace extender - }); - - SVG.FONTDATA.FONTS['MathJax_Main'][0x2245][2] -= 222; // fix incorrect right bearing in font - MathJax.Hub.Register.LoadHook(SVG.fontDir+"/Main/Bold/MathOperators.js",function () { - SVG.FONTDATA.FONTS['MathJax_Main-bold'][0x2245][2] -= 106; // fix incorrect right bearing in font + // + // Add some spacing characters (more will come later) + // + MathJax.Hub.Insert(SVG.FONTDATA.FONTS['MathJax_Main'],{ + 0x2000: [0,0,500,0,0,{space:1}], // en quad + 0x2001: [0,0,1000,0,0,{space:1}], // em quad + 0x2002: [0,0,500,0,0,{space:1}], // en space + 0x2003: [0,0,1000,0,0,{space:1}], // em space + 0x2004: [0,0,333,0,0,{space:1}], // 3-per-em space + 0x2005: [0,0,250,0,0,{space:1}], // 4-per-em space + 0x2006: [0,0,167,0,0,{space:1}], // 6-per-em space + 0x2009: [0,0,167,0,0,{space:1}], // thin space + 0x200A: [0,0,83,0,0,{space:1}], // hair space + 0x200B: [0,0,0,0,0,{space:1}], // zero-width space + 0xEEE0: [0,0,-575,0,0,{space:1}], + 0xEEE1: [0,0,-300,0,0,{space:1}], + 0xEEE8: [0,0,25,0,0,{space:1}] }); - AJAX.loadComplete(SVG.fontDir + "/fontdata.js"); - -})(MathJax.OutputJax.SVG,MathJax.ElementJax.mml,MathJax.Ajax); + HUB.Register.StartupHook("SVG Jax Require",function () { + HUB.Register.LoadHook(SVG.fontDir+"/Size4/Regular/Main.js",function () { + SVG.FONTDATA.FONTS['MathJax_Size4'][0xE154][0] += 200; // adjust height for brace extender + SVG.FONTDATA.FONTS['MathJax_Size4'][0xE154][1] += 200; // adjust depth for brace extender + }); + + SVG.FONTDATA.FONTS['MathJax_Main'][0x2245][2] -= 222; // fix incorrect right bearing in font + HUB.Register.LoadHook(SVG.fontDir+"/Main/Bold/MathOperators.js",function () { + SVG.FONTDATA.FONTS['MathJax_Main-bold'][0x2245][2] -= 106; // fix incorrect right bearing in font + }); + + HUB.Register.LoadHook(SVG.fontDir+"/Typewriter/Regular/BasicLatin.js",function () { + SVG.FONTDATA.FONTS['MathJax_Typewriter'][0x20][2] += 275; // fix incorrect width + }); + + AJAX.loadComplete(SVG.fontDir + "/fontdata.js"); + }); + +})(MathJax.OutputJax.SVG,MathJax.ElementJax.mml,MathJax.Ajax,MathJax.Hub); diff --git a/resources/viewer/mathjax/jax/output/SVG/jax.js b/resources/viewer/mathjax/jax/output/SVG/jax.js index 644f21df7b..021a37c2b4 100644 --- a/resources/viewer/mathjax/jax/output/SVG/jax.js +++ b/resources/viewer/mathjax/jax/output/SVG/jax.js @@ -1,3 +1,6 @@ +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + /************************************************************* * * MathJax/jax/output/SVG/jax.js @@ -8,7 +11,7 @@ * * --------------------------------------------------------------------- * - * Copyright (c) 2011-2012 Design Science, Inc. + * Copyright (c) 2011-2015 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. @@ -31,6 +34,9 @@ var XLINKNS = "http://www.w3.org/1999/xlink"; SVG.Augment({ + HFUZZ: 2, // adjustments for height and depth of final svg element + DFUZZ: 2, // to get baselines right (fragile). + config: { styles: { ".MathJax_SVG": { @@ -49,24 +55,43 @@ "white-space": "nowrap", "float": "none", "direction": "ltr", + "max-width": "none", "max-height": "none", + "min-width": 0, "min-height": 0, border: 0, padding: 0, margin: 0 }, ".MathJax_SVG_Display": { position: "relative", - display: "block", + display: "block!important", + "text-indent": 0, + "max-width": "none", "max-height": "none", + "min-width": 0, "min-height": 0, width: "100%" }, + + ".MathJax_SVG *": { + transition: "none", + "-webkit-transition": "none", + "-moz-transition": "none", + "-ms-transition": "none", + "-o-transition": "none" + }, + + ".mjx-svg-href": { + fill: "blue", stroke: "blue" + }, ".MathJax_SVG_Processing": { visibility: "hidden", position:"absolute", top:0, left:0, - width:0, height: 0, overflow:"hidden", display:"block" + width:0, height: 0, overflow:"hidden", display:"block!important" }, ".MathJax_SVG_Processed": {display:"none!important"}, ".MathJax_SVG_ExBox": { - display:"block", overflow:"hidden", - width:"1px", height:"60ex" + display:"block!important", overflow:"hidden", + width:"1px", height:"60ex", + "min-height": 0, "max-height":"none", + padding:0, border: 0, margin: 0 }, "#MathJax_SVG_Tooltip": { @@ -79,11 +104,23 @@ hideProcessedMath: true, // use display:none until all math is processed + fontNames: ["TeX","STIX","STIX-Web","Asana-Math", + "Gyre-Termes","Gyre-Pagella","Latin-Modern","Neo-Euler"], + + Config: function () { - var settings = HUB.config.menuSettings; - if (settings.scale) {this.config.scale = settings.scale} this.SUPER(arguments).Config.apply(this,arguments); - this.fontInUse = this.config.font; this.fontDir += "/" + this.config.font; + var settings = HUB.config.menuSettings, config = this.config, font = settings.font; + if (settings.scale) {config.scale = settings.scale} + if (font && font !== "Auto") { + font = font.replace(/(Local|Web|Image)$/i,""); + font = font.replace(/([a-z])([A-Z])/,"$1-$2"); + this.fontInUse = font; + } else { + this.fontInUse = config.font || "TeX"; + } + if (this.fontNames.indexOf(this.fontInUse) < 0) {this.fontInUse = "TeX"} + this.fontDir += "/" + this.fontInUse; if (!this.require) {this.require = []} this.require.push(this.fontDir+"/fontdata.js"); this.require.push(MathJax.OutputJax.extensionDir+"/MathEvents.js"); @@ -119,8 +156,8 @@ this.textSVG = this.Element("svg"); // Global defs for font glyphs - DEFS = this.addElement(this.addElement(this.hiddenDiv.parentNode,"svg"),"defs",{id:"MathJax_SVG_glyphs"}); - GLYPHS = {}; + BBOX.GLYPH.defs = this.addElement(this.addElement(this.hiddenDiv.parentNode,"svg"), + "defs",{id:"MathJax_SVG_glyphs"}); // Used in preTranslate to get scaling factors this.ExSpan = HTML.Element("span", @@ -132,7 +169,7 @@ this.linebreakSpan = HTML.Element("span",null, [["hr",{style: {width:"auto", size:1, padding:0, border:0, margin:0}}]]); - // Set up styles + // Set up styles return AJAX.Styles(this.config.styles,["InitializeSVG",this]); }, @@ -170,20 +207,22 @@ // Remove any existing output // prev = script.previousSibling; - if (prev && String(prev.className).match(/^MathJax(_SVG)?(_Display)?$/)) + if (prev && String(prev.className).match(/^MathJax(_SVG)?(_Display)?( MathJax(_SVG)?_Processing)?$/)) {prev.parentNode.removeChild(prev)} // // Add the span, and a div if in display mode, // then set the role and mark it as being processed // - jax = script.MathJax.elementJax; + jax = script.MathJax.elementJax; if (!jax) continue; jax.SVG = {display: (jax.root.Get("display") === "block")} span = div = HTML.Element("span",{ - style: {"font-size": this.scale+"%", display:"inline-block"}, + style: {"font-size": this.config.scale+"%", display:"inline-block"}, className:"MathJax_SVG", id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id, oncontextmenu:EVENT.Menu, onmousedown: EVENT.Mousedown, onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout, onmousemove:EVENT.Mousemove, - onclick:EVENT.Click, ondblclick:EVENT.DblClick + onclick:EVENT.Click, ondblclick:EVENT.DblClick, + // Added for keyboard accessible menu. + onkeydown: EVENT.Keydown, tabIndex: "0" }); if (HUB.Browser.noContextMenu) { span.ontouchstart = TOUCH.start; @@ -193,11 +232,6 @@ div = HTML.Element("div",{className:"MathJax_SVG_Display"}); div.appendChild(span); } - // - // Mark math for screen readers - // (screen readers don't know about role="math" yet, so use "textbox" instead) - // - div.setAttribute("role","textbox"); div.setAttribute("aria-readonly","true"); div.className += " MathJax_SVG_Processing"; script.parentNode.insertBefore(div,script); // @@ -213,7 +247,7 @@ for (i = 0; i < m; i++) { script = scripts[i]; if (!script.parentNode) continue; test = script.previousSibling; div = test.previousSibling; - jax = script.MathJax.elementJax; + jax = script.MathJax.elementJax; if (!jax) continue; ex = test.firstChild.offsetHeight/60; cwidth = div.previousSibling.firstChild.offsetWidth; if (relwidth) {maxwidth = cwidth} @@ -223,19 +257,20 @@ this.hiddenDiv.appendChild(div); jax.SVG.isHidden = true; ex = this.defaultEx; cwidth = this.defaultWidth; - if (relwidth) {maxwidth = this.defaultWidth} + if (relwidth) {maxwidth = cwidth} } - jax.SVG.ex = ex; jax.SVG.cwidth = cwidth; + jax.SVG.ex = ex; jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height - jax.SVG.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/em) : 1000000); + jax.SVG.cwidth = cwidth/em * 1000; + jax.SVG.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/em*1000) : SVG.BIGDIMEN); } // // Remove the test spans used for determining scales and linebreak widths // for (i = 0; i < m; i++) { script = scripts[i]; if (!script.parentNode) continue; - test = scripts[i].previousSibling; jax = scripts[i].MathJax.elementJax; - span = test.previousSibling; + test = scripts[i].previousSibling; span = test.previousSibling; + jax = scripts[i].MathJax.elementJax; if (!jax) continue; if (!jax.SVG.isHidden) {span = span.previousSibling} span.parentNode.removeChild(span); test.parentNode.removeChild(test); @@ -243,7 +278,7 @@ // // Set state variables used for displaying equations in chunks // - state.SVGeqn = state.SVGlast = 0; + state.SVGeqn = state.SVGlast = 0; state.SVGi = -1; state.SVGchunk = this.config.EqnChunk; state.SVGdelay = false; }, @@ -264,21 +299,25 @@ // var jax = script.MathJax.elementJax, math = jax.root, span = document.getElementById(jax.inputID+"-Frame"), - div = (jax.SVG.display ? span.parentNode : span); + div = (jax.SVG.display ? (span||{}).parentNode : span), + localCache = (SVG.config.useFontCache && !SVG.config.useGlobalCache); + if (!div) return; // // Set the font metrics // this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex; - this.linebreakWidth = jax.SVG.lineWidth * 1000; this.cwidth = jax.SVG.cwidth; + this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth; // // Typeset the math // this.mathDiv = div; span.appendChild(this.textSVG); + if (localCache) {SVG.resetGlyphs()} this.initSVG(math,span); math.setTeXclass(); try {math.toSVG(span,div)} catch (err) { if (err.restart) {while (span.firstChild) {span.removeChild(span.firstChild)}} + if (localCache) {BBOX.GLYPH.n--} throw err; } span.removeChild(this.textSVG); @@ -302,16 +341,16 @@ // // Check if we should show this chunk of equations // - state.SVGeqn++; + state.SVGeqn += (state.i - state.SVGi); state.SVGi = state.i; if (state.SVGeqn >= state.SVGlast + state.SVGchunk) { - this.postTranslate(state); + this.postTranslate(state,true); state.SVGchunk = Math.floor(state.SVGchunk*this.config.EqnChunkFactor); state.SVGdelay = true; // delay if there are more scripts } } }, - postTranslate: function (state) { + postTranslate: function (state,partial) { var scripts = state.jax[this.id]; if (!this.hideProcessedMath) return; // @@ -319,7 +358,7 @@ // for (var i = state.SVGlast, m = state.SVGeqn; i < m; i++) { var script = scripts[i]; - if (script) { + if (script && script.MathJax.elementJax) { // // Remove the processed marker // @@ -340,10 +379,36 @@ // state.SVGlast = state.SVGeqn; }, + + resetGlyphs: function (reset) { + if (this.config.useFontCache) { + var GLYPH = BBOX.GLYPH; + if (this.config.useGlobalCache) { + GLYPH.defs = document.getElementById("MathJax_SVG_glyphs"); + GLYPH.defs.innerHTML = ""; + } else { + GLYPH.defs = this.Element("defs"); + GLYPH.n++; + } + GLYPH.glyphs = {}; + if (reset) {GLYPH.n = 0} + } + }, + + // + // Return the containing HTML element rather than the SVG element, since + // most browsers can't position to an SVG element properly. + // + hashCheck: function (target) { + if (target && target.nodeName.toLowerCase() === "g") + {do {target = target.parentNode} while (target && target.firstChild.nodeName !== "svg")} + return target; + }, getJaxFromMath: function (math) { if (math.parentNode.className === "MathJax_SVG_Display") {math = math.parentNode} - return HUB.getJaxFor(math.nextSibling); + do {math = math.nextSibling} while (math && math.nodeName.toLowerCase() !== "script"); + return HUB.getJaxFor(math); }, getHoverSpan: function (jax,math) { math.style.position = "relative"; // make sure inline containers have position set @@ -366,11 +431,34 @@ // var emex = span.appendChild(this.ExSpan.cloneNode(true)); var ex = emex.firstChild.offsetHeight/60; - this.em = MML.mbase.prototype.em = ex / SVG.TeX.x_height * 1000; - this.cwidth = .85*SVG.defaultWidth; + this.em = MML.mbase.prototype.em = ex / SVG.TeX.x_height * 1000; this.ex = ex; + this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth; emex.parentNode.removeChild(emex); + span.appendChild(this.textSVG); + this.mathDIV = span; this.zoomScale = parseInt(HUB.config.menuSettings.zscale) / 100; + var tw = jax.root.data[0].SVGdata.tw; if (tw && tw < this.cwidth) this.cwidth = tw; this.idPostfix = "-zoom"; jax.root.toSVG(span,span); this.idPostfix = ""; + this.zoomScale = 1; + span.removeChild(this.textSVG); + + // + // Don't allow overlaps on any edge + // + var svg = span.getElementsByTagName("svg")[0].style; + svg.marginTop = svg.marginRight = svg.marginLeft = 0; + if (svg.marginBottom.charAt(0) === "-") + span.style.marginBottom = svg.marginBottom.substr(1); + + if (this.operaZoomRefresh) + {setTimeout(function () {span.firstChild.style.border="1px solid transparent"},1)} + // + // WebKit bug (issue #749) + // + if (span.offsetWidth < span.firstChild.offsetWidth) { + span.style.minWidth = span.firstChild.offsetWidth + "px"; + math.style.minWidth = math.firstChild.offsetWidth + "px"; + } // // Get height and width of zoomed math and original math // @@ -394,17 +482,21 @@ }, Em: function (m) { - if (Math.abs(m) < .0006) {return "0em"} + if (Math.abs(m) < .0006) return "0"; return m.toFixed(3).replace(/\.?0+$/,"") + "em"; }, Ex: function (m) { m = m / this.TeX.x_height; - if (Math.abs(m) < .0006) {return "0ex"} + if (Math.abs(m) < .0006) return "0"; return m.toFixed(3).replace(/\.?0+$/,"") + "ex"; }, Percent: function (m) { return (100*m).toFixed(1).replace(/\.?0+$/,"") + "%"; }, + Fixed: function (m,n) { + if (Math.abs(m) < .0006) return "0"; + return m.toFixed(n||3).replace(/\.?0+$/,""); + }, length2em: function (length,mu,size) { if (typeof(length) !== "string") {length = length.toString()} if (length === "") {return ""} @@ -413,18 +505,19 @@ if (length === MML.SIZE.SMALL) {return 710} if (length === "infinity") {return SVG.BIGDIMEN} if (length.match(/mathspace$/)) {return 1000*SVG.MATHSPACE[length]} + var emFactor = (this.zoomScale || 1) / SVG.em; var match = length.match(/^\s*([-+]?(?:\.\d+|\d+(?:\.\d*)?))?(pt|em|ex|mu|px|pc|in|mm|cm|%)?/); var m = parseFloat(match[1]||"1") * 1000, unit = match[2]; if (size == null) {size = 1000}; if (mu == null) {mu = 1} if (unit === "em") {return m} if (unit === "ex") {return m * SVG.TeX.x_height/1000} if (unit === "%") {return m / 100 * size / 1000} - if (unit === "px") {return m / SVG.em} - if (unit === "pt") {return m / 10} // 10 pt to an em - if (unit === "pc") {return m * 1.2} // 12 pt to a pc - if (unit === "in") {return m * this.pxPerInch / SVG.em} - if (unit === "cm") {return m * this.pxPerInch / SVG.em / 2.54} // 2.54 cm to an inch - if (unit === "mm") {return m * this.pxPerInch / SVG.em / 25.4} // 10 mm to a cm + if (unit === "px") {return m * emFactor} + if (unit === "pt") {return m / 10} // 10 pt to an em + if (unit === "pc") {return m * 1.2} // 12 pt to a pc + if (unit === "in") {return m * this.pxPerInch * emFactor} + if (unit === "cm") {return m * this.pxPerInch * emFactor / 2.54} // 2.54 cm to an inch + if (unit === "mm") {return m * this.pxPerInch * emFactor / 25.4} // 10 mm to a cm if (unit === "mu") {return m / 18 * mu} return m*size / 1000; // relative to given size (or 1em as default) }, @@ -436,26 +529,26 @@ return this.length2em(length,mu,thick); }, - getPadding: function (span) { + getPadding: function (styles) { var padding = {top:0, right:0, bottom:0, left:0}, has = false; for (var id in padding) {if (padding.hasOwnProperty(id)) { - var pad = span.style["padding"+id.charAt(0).toUpperCase()+id.substr(1)]; + var pad = styles["padding"+id.charAt(0).toUpperCase()+id.substr(1)]; if (pad) {padding[id] = this.length2em(pad); has = true;} }} return (has ? padding : false); }, - getBorders: function (span) { + getBorders: function (styles) { var border = {top:0, right:0, bottom:0, left:0}, has = false; for (var id in border) {if (border.hasOwnProperty(id)) { var ID = "border"+id.charAt(0).toUpperCase()+id.substr(1); - var style = span.style[ID+"Style"]; - if (style) { + var style = styles[ID+"Style"]; + if (style && style !== "none") { has = true; - border[id] = this.length2em(span.style[ID+"Width"]); - border[id+"Style"] = span.style[ID+"Style"]; - border[id+"Color"] = span.style[ID+"Color"]; + border[id] = this.length2em(styles[ID+"Width"]); + border[id+"Style"] = styles[ID+"Style"]; + border[id+"Color"] = styles[ID+"Color"]; if (border[id+"Color"] === "initial") {border[id+"Color"] = ""} - } + } else {delete border[id]} }} return (has ? border : false); }, @@ -509,50 +602,44 @@ } } if (variant.remap && variant.remap[n]) { - if (variant.remap[n] instanceof Array) { - var remap = variant.remap[n]; - n = remap[0]; variant = this.FONTDATA.VARIANT[remap[1]]; - } else if (typeof(variant.remap[n]) === "string") { - text = variant.remap[n]+text.substr(i+1); - i = 0; m = text.length; n = text.charCodeAt(0); - } else { - n = variant.remap[n]; - if (variant.remap.variant) {variant = this.FONTDATA.VARIANT[variant.remap.variant]} - } - } - if (this.FONTDATA.REMAP[n] && !variant.noRemap) { + n = variant.remap[n]; + if (variant.remap.variant) {variant = this.FONTDATA.VARIANT[variant.remap.variant]} + } else if (this.FONTDATA.REMAP[n] && !variant.noRemap) { n = this.FONTDATA.REMAP[n]; - if (n instanceof Array) {variant = this.FONTDATA.VARIANT[n[1]]; n = n[0]} - if (typeof(n) === "string") { - text = n+text.substr(i+1); - i = 0; m = text.length; - n = n.charCodeAt(0); - } + } + if (n instanceof Array) {variant = this.FONTDATA.VARIANT[n[1]]; n = n[0]} + if (typeof(n) === "string") { + text = n+text.substr(i+1); + m = text.length; i = -1; + continue; } font = this.lookupChar(variant,n); c = font[n]; if (c) { - c = [scale,font.id+"-"+n.toString(16).toUpperCase()].concat(c); - svg.Add(BBOX.GLYPH.apply(BBOX,c),svg.w,0); + if ((c[5] && c[5].space) || (c[5] === "" && c[0]+c[1] === 0)) {svg.w += c[2]} else { + c = [scale,font.id+"-"+n.toString(16).toUpperCase()].concat(c); + svg.Add(BBOX.GLYPH.apply(BBOX,c),svg.w,0); + } } else if (this.FONTDATA.DELIMITERS[n]) { - svg.Add(this.createDelimiter(n,0,1,font),svg.w,0); + c = this.createDelimiter(n,0,1,font); + svg.Add(c,svg.w,(this.FONTDATA.DELIMITERS[n].dir === "V" ? c.d: 0)); } else { if (n <= 0xFFFF) {c = String.fromCharCode(n)} else { N = n - 0x10000; c = String.fromCharCode((N>>10)+0xD800) + String.fromCharCode((N&0x3FF)+0xDC00); } - text = BBOX.TEXT(scale,c,{ + var box = BBOX.TEXT(scale*100/SVG.config.scale,c,{ "font-family":variant.defaultFamily||SVG.config.undefinedFamily, "font-style":(variant.italic?"italic":""), "font-weight":(variant.bold?"bold":"") }) - if (variant.h != null) {text.h = variant.h}; if (variant.d != null) {text.d = variant.d} - c = BBOX.G(); c.Add(text); svg.Add(c,svg.w,0); text = ""; + if (variant.h != null) {box.h = variant.h}; if (variant.d != null) {box.d = variant.d} + c = BBOX.G(); c.Add(box); svg.Add(c,svg.w,0); HUB.signal.Post(["SVG Jax - unknown char",n,variant]); } } if (text.length == 1 && font.skew && font.skew[n]) {svg.skew = font.skew[n]*1000} - if (svg.element.childNodes.length === 1) { + if (svg.element.childNodes.length === 1 && !svg.element.firstChild.getAttribute("x")) { svg.element = svg.element.firstChild; svg.removeable = false; svg.scale = scale; } @@ -631,12 +718,12 @@ if (data[0] instanceof Array) { for (var i = 0, m = data[0].length; i < m; i++) {text += String.fromCharCode(data[0][i])} } else {text = String.fromCharCode(data[0])} + if (data[4]) {scale = scale*data[4]} var svg = this.HandleVariant(variant,scale,text); if (data[2]) {svg.x = data[2]*1000} if (data[3]) {svg.y = data[3]*1000} if (data[5]) {svg.h += data[5]*1000} if (data[6]) {svg.d += data[6]*1000} - // FIXME handle data[4] (scale factor) return svg; }, extendDelimiterV: function (svg,H,delim,scale,font) { @@ -645,6 +732,7 @@ var h = top.h + top.d + bot.h + bot.d; var y = -top.h; svg.Add(top,0,y); y -= top.d; if (delim.mid) {var mid = this.createChar(scale,delim.mid,font); h += mid.h + mid.d} + if (delim.min && H < h*delim.min) {H = h*delim.min} if (H > h) { var ext = this.createChar(scale,delim.ext,font); var k = (delim.mid ? 2 : 1), eH = (H-h) / k, s = (eH+100) / (ext.h+ext.d); @@ -668,6 +756,7 @@ svg.Add(left,-left.l,0); var w = (left.r - left.l) + (right.r - right.l), x = left.r - left.l; if (delim.mid) {var mid = this.createChar(scale,delim.mid,font); w += mid.w} + if (delim.min && W < w*delim.min) {W = w*delim.min} if (W > w) { var rep = this.createChar(scale,delim.rep,font), fuzz = delim.fuzz || 0; var k = (delim.mid ? 2 : 1), rW = (W-w) / k, s = (rW+fuzz) / (rep.r-rep.l); @@ -677,8 +766,7 @@ if (delim.mid && k) {svg.Add(mid,x,0); x += mid.w} } } else if (delim.mid) { - var dx = Math.min(w - W,left.w/2); - x -= dx/2; svg.Add(mid,x,0); x += mid.w - dx/2; + x -= (w - W)/2; svg.Add(mid,x,0); x += mid.w - (w - W)/2; } else { x -= (w - W); } @@ -736,7 +824,7 @@ scriptspace: 100, nulldelimiterspace: 120, delimiterfactor: 901, - delimitershortfall: 100, // originally 300, + delimitershortfall: 300, min_rule_thickness: 1.25, // in pixels min_root_space: 1.5 // in pixels @@ -759,27 +847,31 @@ if (dx) {svg.x += dx}; if (dy) {svg.y += dy}; if (svg.element) { if (svg.removeable && svg.element.childNodes.length === 1 && svg.n === 1) { - var child = svg.element.firstChild; - if (child.nodeName === "use" || child.nodeName === "rect") { + var child = svg.element.firstChild, nodeName = child.nodeName.toLowerCase(); + if (nodeName === "use" || nodeName === "rect") { svg.element = child; svg.scale = svg.childScale; var x = svg.childX, y = svg.childY; svg.x += x; svg.y += y; svg.h -= y; svg.d += y; svg.H -= y; svg.D +=y; svg.w -= x; svg.r -= x; svg.l += x; svg.removeable = false; + child.setAttribute("x",Math.floor(svg.x/svg.scale)); + child.setAttribute("y",Math.floor(svg.y/svg.scale)); } } if (Math.abs(svg.x) < 1 && Math.abs(svg.y) < 1) { svg.remove = svg.removeable; } else { - if (svg.element.nodeName === "g") { + nodeName = svg.element.nodeName.toLowerCase(); + if (nodeName === "g") { if (!svg.element.firstChild) {svg.remove = svg.removeable} else {svg.element.setAttribute("transform","translate("+Math.floor(svg.x)+","+Math.floor(svg.y)+")")} - } else if (svg.element.nodeName === "line" || - svg.element.nodeName === "polygon" || - svg.element.nodeName === "path" || - svg.element.nodeName === "a") { - svg.element.setAttribute("transform","translate("+Math.floor(svg.x)+","+Math.floor(svg.y)+")"); + } else if (nodeName === "line" || nodeName === "polygon" || + nodeName === "path" || nodeName === "a") { + var transform = svg.element.getAttribute("transform") || ""; + if (transform) transform = " "+transform; + transform = "translate("+Math.floor(svg.x)+","+Math.floor(svg.y)+")"+transform; + svg.element.setAttribute("transform",transform); } else { svg.element.setAttribute("x",Math.floor(svg.x/svg.scale)); svg.element.setAttribute("y",Math.floor(svg.y/svg.scale)); @@ -801,6 +893,7 @@ delete svg.element; } if (svg.hasIndent) {this.hasIndent = svg.hasIndent} + if (svg.tw != null) {this.tw = svg.tw} if (svg.d - svg.y > this.d) {this.d = svg.d - svg.y; if (this.d > this.D) {this.D = this.d}} if (svg.y + svg.h > this.h) {this.h = svg.y + svg.h; if (this.h > this.H) {this.H = this.h}} if (svg.D - svg.y > this.D) {this.D = svg.D - svg.y} @@ -811,9 +904,9 @@ this.childScale = svg.scale; this.childX = svg.x; this.childY = svg.y; this.n++; return svg; }, - Align: function (svg,align,dx,dy) { + Align: function (svg,align,dx,dy,shift) { dx = ({left: dx, center: (this.w - svg.w)/2, right: this.w - svg.w - dx})[align] || 0; - this.Add(svg,dx,dy); + var w = this.w; this.Add(svg,dx+(shift||0),dy); this.w = w; }, Clean: function () { if (this.h === -SVG.BIGDIMEN) {this.h = this.d = this.l = 0} @@ -835,8 +928,13 @@ Stretch: function () { for (var i = 0, m = this.svg.length; i < m; i++) { - var svg = this.svg[i]; - if (svg.mml) {svg = svg.mml.SVGstretchV(this.sh,this.sd)} + var svg = this.svg[i], mml = svg.mml; + if (mml) { + if (mml.forceStretch || mml.SVGdata.h !== this.sh || mml.SVGdata.d !== this.sd) { + svg = mml.SVGstretchV(this.sh,this.sd); + } + mml.SVGdata.HW = this.sh; mml.SVGdata.D = this.sd; + } if (svg.ic) {this.ic = svg.ic} else {delete this.ic} this.Add(svg,this.w,0,true); } @@ -858,7 +956,7 @@ type: "rect", removeable: false, Init: function (h,d,w,t,dash,color,def) { if (def == null) {def = {}}; def.fill = "none"; - def["stroke-width"] = t.toFixed(2).replace(/\.?0+$/,""); + def["stroke-width"] = SVG.Fixed(t,2); def.width = Math.floor(w-t); def.height = Math.floor(h+d-t); def.transform = "translate("+Math.floor(t/2)+","+Math.floor(-d+t/2)+")"; if (dash === "dashed") @@ -872,14 +970,18 @@ BBOX.HLINE = BBOX.Subclass({ type: "line", removeable: false, Init: function (w,t,dash,color,def) { - if (def == null) {def = {}} + if (def == null) {def = {"stroke-linecap":"square"}} if (color && color !== "") {def.stroke = color} - def["stroke-width"] = t.toFixed(2).replace(/\.?0+$/,""); - def.x1 = 0; def.y1 = def.y2 = t/2; def.x2 = Math.floor(w); + def["stroke-width"] = SVG.Fixed(t,2); + def.x1 = def.y1 = def.y2 = Math.floor(t/2); def.x2 = Math.floor(w-t/2); if (dash === "dashed") { - var n = Math.floor(w/(6*t)), m = Math.floor(w/(2*n+1)); + var n = Math.floor(Math.max(0,w-t)/(6*t)), m = Math.floor(Math.max(0,w-t)/(2*n+1)); def["stroke-dasharray"] = m+" "+m; } + if (dash === "dotted") { + def["stroke-dasharray"] = [1,Math.max(150,Math.floor(2*t))].join(" "); + def["stroke-linecap"] = "round"; + } this.SUPER(arguments).Init.call(this,def); this.w = this.r = w; this.l = 0; this.h = this.H = t; this.d = this.D = 0; } @@ -888,14 +990,18 @@ BBOX.VLINE = BBOX.Subclass({ type: "line", removeable: false, Init: function (h,t,dash,color,def) { - if (def == null) {def = {}} + if (def == null) {def = {"stroke-linecap":"square"}} if (color && color !== "") {def.stroke = color} - def["stroke-width"] = t.toFixed(2).replace(/\.?0+$/,""); - def.x1 = def.x2 = t/2; def.y1 = 0; def.y2 = Math.floor(h); + def["stroke-width"] = SVG.Fixed(t,2); + def.x1 = def.x2 = def.y1 = Math.floor(t/2); def.y2 = Math.floor(h-t/2); if (dash === "dashed") { - var n = Math.floor(h/(6*t)), m = Math.floor(h/(2*n+1)); + var n = Math.floor(Math.max(0,h-t)/(6*t)), m = Math.floor(Math.max(0,h-t)/(2*n+1)); def["stroke-dasharray"] = m+" "+m; } + if (dash === "dotted") { + def["stroke-dasharray"] = [1,Math.max(150,Math.floor(2*t))].join(" "); + def["stroke-linecap"] = "round"; + } this.SUPER(arguments).Init.call(this,def); this.w = this.r = t; this.l = 0; this.h = this.H = h; this.d = this.D = 0; } @@ -905,13 +1011,15 @@ type: "text", removeable: false, Init: function (scale,text,def) { if (!def) {def = {}}; def.stroke = "none"; + if (def["font-style"] === "") delete def["font-style"]; + if (def["font-weight"] === "") delete def["font-weight"]; this.SUPER(arguments).Init.call(this,def); SVG.addText(this.element,text); SVG.textSVG.appendChild(this.element); var bbox = this.element.getBBox(); SVG.textSVG.removeChild(this.element); scale *= 1000/SVG.em; - this.element.setAttribute("transform","scale("+scale+") matrix(1 0 0 -1 0 0)"); + this.element.setAttribute("transform","scale("+SVG.Fixed(scale)+") matrix(1 0 0 -1 0 0)"); this.w = this.r = bbox.width*scale; this.l = 0; this.h = this.H = -bbox.y*scale; this.d = this.D = (bbox.height + bbox.y)*scale; @@ -927,26 +1035,34 @@ } }); - var GLYPHS, DEFS; // data for which glyphs are used - BBOX.GLYPH = BBOX.Subclass({ type: "path", removeable: false, Init: function (scale,id,h,d,w,l,r,p) { - var def, t = SVG.config.blacker; - if (!GLYPHS[id]) { - def = {id:id, "stroke-width":t}; - if (p !== "") {def.d = "M"+p+"Z"} + var def, t = SVG.config.blacker, GLYPH = BBOX.GLYPH; + var cache = SVG.config.useFontCache; + var transform = (scale === 1 ? null : "scale("+SVG.Fixed(scale)+")"); + if (cache && !SVG.config.useGlobalCache) {id = "E"+GLYPH.n+"-"+id} + if (!cache || !GLYPH.glyphs[id]) { + def = {"stroke-width":t}; + if (cache) {def.id = id} else if (transform) {def.transform = transform} + def.d = (p ? "M"+p+"Z" : ""); this.SUPER(arguments).Init.call(this,def); - DEFS.appendChild(this.element); GLYPHS[id] = true; + if (cache) {GLYPH.defs.appendChild(this.element); GLYPH.glyphs[id] = true;} + } + if (cache) { + def = {}; if (transform) {def.transform = transform} + this.element = SVG.Element("use",def); + this.element.setAttributeNS(XLINKNS,"href","#"+id); } - def = {}; if (scale !== 1) {def.transform = "scale("+scale+")"} - this.element = SVG.Element("use",def); - this.element.setAttributeNS(XLINKNS,"href","#"+id); this.h = (h+t) * scale; this.d = (d+t) * scale; this.w = (w+t/2) *scale; this.l = (l+t/2) * scale; this.r = (r+t/2) * scale; this.H = Math.max(0,this.h); this.D = Math.max(0,this.d); this.x = this.y = 0; this.scale = scale; } + },{ + glyphs: {}, // which glpyhs have been used + defs: null, // the SVG element where glyphs are stored + n: 0 // the ID for local for self-contained SVG elements }); HUB.Register.StartupHook("mml Jax Ready",function () { @@ -958,16 +1074,16 @@ toSVG: function () { this.SVGgetStyles(); var variant = this.SVGgetVariant(); - var svg = this.SVG(); - svg.scale = this.SVGgetScale(); this.SVGhandleSpace(svg); - for (var i = 0, m = this.data.length; i < m; i++) { + var svg = this.SVG(); this.SVGgetScale(svg); + this.SVGhandleSpace(svg); + for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i]) { var child = svg.Add(this.data[i].toSVG(variant,svg.scale),svg.w,0,true); if (child.skew) {svg.skew = child.skew} } } svg.Clean(); var text = this.data.join(""); - if (svg.skew && text.length !== 1) {delete svg.skew} + if (svg.skew && text.length !== 1) {delete svg.skew} if (svg.r > svg.w && text.length === 1 && !variant.noIC) {svg.ic = svg.r - svg.w; svg.w = svg.r} this.SVGhandleColor(svg); @@ -975,8 +1091,13 @@ return svg; }, + SVGchildSVG: function (i) { + return (this.data[i] ? this.data[i].toSVG() : BBOX()); + }, + SVGdataStretched: function (i,HW,D) { this.SVGdata = {HW:HW, D:D}; + if (!this.data[i]) {return BBOX()} if (D != null) {return this.data[i].SVGstretchV(HW,D)} if (HW != null) {return this.data[i].SVGstretchH(HW)} return this.data[i].toSVG(); @@ -985,58 +1106,106 @@ SVGsaveData: function (svg) { if (!this.SVGdata) {this.SVGdata = {}} this.SVGdata.w = svg.w, this.SVGdata.x = svg.x; + this.SVGdata.h = svg.h, this.SVGdata.d = svg.d; + if (svg.y) {this.SVGdata.h += svg.y; this.SVGdata.d -= svg.y} if (svg.X != null) {this.SVGdata.X = svg.X} + if (svg.tw != null) {this.SVGdata.tw = svg.tw} + if (svg.skew) {this.SVGdata.skew = svg.skew} + if (svg.ic) {this.SVGdata.ic = svg.ic} if (this["class"]) {svg.removeable = false; SVG.Element(svg.element,{"class":this["class"]})} // FIXME: if an element is split by linebreaking, the ID will be the same on both parts // FIXME: if an element has an id, its zoomed copy will have the same ID if (this.id) {svg.removeable = false; SVG.Element(svg.element,{"id":this.id})} if (this.href) { - var a = SVG.Element("a"); + var a = SVG.Element("a",{"class":"mjx-svg-href"}); a.setAttributeNS(XLINKNS,"href",this.href); + a.onclick = this.SVGlink; SVG.addElement(a,"rect",{width:svg.w, height:svg.h+svg.d, y:-svg.d, - fill:"none", stroke:"none", "pointer-events":"all"}); + fill:"none", stroke:"none", "pointer-events":"all"}); if (svg.type === "svg") { // for svg element, put
inside the main element var g = svg.element.firstChild; while (g.firstChild) {a.appendChild(g.firstChild)} g.appendChild(a); } else { - // if removeable, move contents of to , otherise move element to - if (svg.removeable && svg.element.nodeName === "g") { - while (svg.element.firstChild) {a.appendChild(svg.element.firstChild)} - } else {a.appendChild(svg.element)} - svg.element = a; + a.appendChild(svg.element); svg.element = a; } svg.removeable = false; } if (SVG.config.addMMLclasses) { + this.SVGaddClass(svg.element,"mjx-svg-"+this.type); svg.removeable = false; - svg.element.setAttribute("className","mjx-svg-"+this.type); } - var style = this.Get("style"); - if (style) { + var style = this.style; + if (style && svg.element) { svg.element.style.cssText = style; if (svg.element.style.fontSize) {svg.element.style.fontSize = ""} // handled by scale svg.element.style.border = svg.element.style.padding = ""; - if (svg.removeable) {svg.removeable = svg.element.style.cssText === ""} + if (svg.removeable) {svg.removeable = (svg.element.style.cssText === "")} } + this.SVGaddAttributes(svg); + }, + SVGaddClass: function (node,name) { + var classes = node.getAttribute("class"); + node.setAttribute("class",(classes ? classes+" " : "")+name); + }, + SVGaddAttributes: function (svg) { + // + // Copy RDFa, aria, and other tags from the MathML to the HTML-CSS + // output spans Don't copy those in the MML.nocopyAttributes list, + // the ignoreMMLattributes configuration list, or anything tha + // already exists as a property of the span (e.g., no "onlick", etc.) + // If a name in the ignoreMMLattributes object is set to false, then + // the attribute WILL be copied. + // + if (this.attrNames) { + var copy = this.attrNames, skip = MML.nocopyAttributes, ignore = HUB.config.ignoreMMLattributes; + var defaults = (this.type === "mstyle" ? MML.math.prototype.defaults : this.defaults); + for (var i = 0, m = copy.length; i < m; i++) { + var id = copy[i]; + if (ignore[id] == false || (!skip[id] && !ignore[id] && + defaults[id] == null && typeof(svg.element[id]) === "undefined")) { + svg.element.setAttribute(id,this.attr[id]); + svg.removeable = false; + } + } + } + }, + // + // WebKit currently scrolls to the BOTTOM of an svg element if it contains the + // target of the link, so implement link by hand, to the containing span element. + // + SVGlink: function () { + var href = this.href.animVal; + if (href.charAt(0) === "#") { + var target = SVG.hashCheck(document.getElementById(href.substr(1))); + if (target && target.scrollIntoView) + {setTimeout(function () {target.parentNode.scrollIntoView(true)},1)} + } + document.location = href; }, SVGgetStyles: function () { if (this.style) { var span = HTML.Element("span"); span.style.cssText = this.style; - this.styles = {border:SVG.getBorders(span), padding:SVG.getPadding(span)} - if (span.style.fontSize) {this.styles.fontSize = span.style.fontSize} - if (span.style.color) {this.styles.color = span.style.color} - if (span.style.backgroundColor) {this.styles.background = span.style.backgroundColor} - if (span.style.fontStyle) {this.styles.fontStyle = span.style.fontStyle} - if (span.style.fontWeight) {this.styles.fontWeight = span.style.fontWeight} - if (span.style.fontFamily) {this.styles.fontFamily = span.style.fontFamily} - if (this.styles.fontWeight && this.styles.fontWeight.match(/^\d+$/)) - {this.styles.fontWeight = (parseInt(this.styles.fontWeight) > 600 ? "bold" : "normal")} + this.styles = this.SVGprocessStyles(span.style); } }, + SVGprocessStyles: function (style) { + var styles = {border:SVG.getBorders(style), padding:SVG.getPadding(style)}; + if (!styles.border) {delete styles.border} + if (!styles.padding) {delete styles.padding} + if (style.fontSize) {styles.fontSize = style.fontSize} + if (style.color) {styles.color = style.color} + if (style.backgroundColor) {styles.background = style.backgroundColor} + if (style.fontStyle) {styles.fontStyle = style.fontStyle} + if (style.fontWeight) {styles.fontWeight = style.fontWeight} + if (style.fontFamily) {styles.fontFamily = style.fontFamily} + if (styles.fontWeight && styles.fontWeight.match(/^\d+$/)) + {styles.fontWeight = (parseInt(styles.fontWeight) > 600 ? "bold" : "normal")} + return styles; + }, SVGhandleSpace: function (svg) { if (this.useMMLspacing) { @@ -1054,7 +1223,8 @@ } } else { var space = this.texSpacing(); - if (space !== "") {svg.x += SVG.length2em(space,this.SVGgetScale())/svg.scale} + this.SVGgetScale(); + if (space !== "") {svg.x += SVG.length2em(space,this.scale)*this.mscale} } }, @@ -1083,15 +1253,16 @@ // // Adjust size by padding and dashed borders (left is taken care of above) // - if (padding) {svg.w += padding.right; svg.h += padding.top; svg.d += padding.bottom} - if (borders) {svg.w += borders.right; svg.h += borders.top; svg.d += borders.bottom} + if (padding) {svg.w += padding.right||0; svg.h += padding.top||0; svg.d += padding.bottom||0} + if (borders) {svg.w += borders.right||0; svg.h += borders.top||0; svg.d += borders.bottom||0} // // Add background color // if (values.background !== MML.COLOR.TRANSPARENT) { - if (svg.element.nodeName !== "g" && svg.element.nodeName !== "svg") { + var nodeName = svg.element.nodeName.toLowerCase(); + if (nodeName !== "g" && nodeName !== "svg") { var g = SVG.Element("g"); g.appendChild(svg.element); - svg.element = g; svg.removable = true; + svg.element = g; svg.removeable = true; } svg.Add(BBOX.RECT(svg.h,svg.d,svg.w,{fill:values.background,stroke:"none"}),0,0,false,true) } @@ -1121,7 +1292,8 @@ SVGgetVariant: function () { var values = this.getValues("mathvariant","fontfamily","fontweight","fontstyle"); - var variant = values.mathvariant; if (this.variantForm) {variant = "-TeX-variant"} + var variant = values.mathvariant; + if (this.variantForm) variant = "-"+SVG.fontInUse+"-variant"; values.hasVariant = this.Get("mathvariant",true); // null if not explicitly specified if (!values.hasVariant) { values.family = values.fontfamily; @@ -1169,22 +1341,33 @@ "sans-serif-bold-italic":MML.VARIANT.BOLDSANSSERIF }[variant]||variant; } + if (!(variant in SVG.FONTDATA.VARIANT)) { + // If the mathvariant value is invalid or not supported by this + // font, fallback to normal. See issue 363. + variant = "normal"; + } return SVG.FONTDATA.VARIANT[variant]; }, - SVGgetScale: function () { - var scale = 1, - values = this.getValues("mathsize","scriptlevel","fontsize"); - if ((this.styles||{}).fontSize && !values.fontsize) {values.fontsize = this.styles.fontSize} - if (values.fontsize && !this.mathsize) {values.mathsize = values.fontsize} - if (values.scriptlevel !== 0) { - if (values.scriptlevel > 2) {values.scriptlevel = 2} - scale = Math.pow(this.Get("scriptsizemultiplier"),values.scriptlevel); - values.scriptminsize = SVG.length2em(this.Get("scriptminsize"))/1000; - if (scale < values.scriptminsize) {scale = values.scriptminsize} - } - scale *= SVG.length2em(values.mathsize)/1000; - return scale; + SVGgetScale: function (svg) { + var scale = 1; + if (this.mscale) { + scale = this.scale; + } else { + var values = this.getValues("scriptlevel","fontsize"); + values.mathsize = (this.isToken ? this : this.Parent()).Get("mathsize"); + if ((this.styles||{}).fontSize && !values.fontsize) {values.fontsize = this.styles.fontSize} + if (values.fontsize && !this.mathsize) {values.mathsize = values.fontsize} + if (values.scriptlevel !== 0) { + if (values.scriptlevel > 2) {values.scriptlevel = 2} + scale = Math.pow(this.Get("scriptsizemultiplier"),values.scriptlevel); + values.scriptminsize = SVG.length2em(this.Get("scriptminsize"))/1000; + if (scale < values.scriptminsize) {scale = values.scriptminsize} + } + this.scale = scale; this.mscale = SVG.length2em(values.mathsize)/1000; + } + if (svg) {svg.scale = scale; if (this.isToken) {svg.scale *= this.mscale}} + return scale * this.mscale; }, SVGgetMu: function (svg) { var mu = 1, values = this.getValues("scriptlevel","scriptsizemultiplier"); @@ -1206,8 +1389,15 @@ }, SVGcanStretch: function (direction) { - if (this.isEmbellished()) {return this.Core().SVGcanStretch(direction)} - return false; + var can = false; + if (this.isEmbellished()) { + var core = this.Core(); + if (core && core !== this) { + can = core.SVGcanStretch(direction); + if (can && core.forceStretch) {this.forceStretch = true} + } + } + return can; }, SVGstretchV: function (h,d) {return this.toSVG(h,d)}, SVGstretchH: function (w) {return this.toSVG(w)}, @@ -1215,6 +1405,12 @@ SVGlineBreaks: function () {return false} },{ + SVGemptySVG: function () { + var svg = this.SVG(); + svg.Clean(); + this.SVGsaveData(svg); + return svg; + }, SVGautoload: function () { var file = SVG.autoloadDir+"/"+this.type+".js"; HUB.RestartAfter(AJAX.Require(file)); @@ -1233,20 +1429,29 @@ } }); MML.entity.Augment({ - toSVG: function (variant,scale) { - return this.SVGhandleVariant(variant,scale,this.toString().replace(/[\u2061-\u2064]/g,"")); // remove invisibles + toSVG: function (variant,scale,remap,chars) { + var text = this.toString().replace(/[\u2061-\u2064]/g,""); // remove invisibles + if (remap) {text = remap(text,chars)} + return this.SVGhandleVariant(variant,scale,text); } }); MML.mo.Augment({ - toSVG: function () { + toSVG: function (HW,D) { this.SVGgetStyles(); - var svg = this.svg = this.SVG(); this.SVGhandleSpace(svg); + var svg = this.svg = this.SVG(); + var scale = this.SVGgetScale(svg); + this.SVGhandleSpace(svg); if (this.data.length == 0) {svg.Clean(); this.SVGsaveData(svg); return svg} // + // Stretch the operator, if that is requested + // + if (D != null) {return this.SVGstretchV(HW,D)} + else if (HW != null) {return this.SVG.strechH(HW)} + // // Get the variant, and check for operator size // - var scale = this.SVGgetScale(), variant = this.SVGgetVariant(); + var variant = this.SVGgetVariant(); var values = this.getValues("largeop","displaystyle"); if (values.largeop) {variant = SVG.FONTDATA.VARIANT[values.displaystyle ? "-largeOp" : "-smallOp"]} @@ -1255,7 +1460,7 @@ // var parent = this.CoreParent(), isScript = (parent && parent.isa(MML.msubsup) && this !== parent.data[0]), - mapchars = (isScript?this.SVGremapChars:null); + mapchars = (isScript?this.remapChars:null); if (this.data.join("").length === 1 && parent && parent.isa(MML.munderover) && this.CoreText(parent.data[parent.base]).length === 1) { var over = parent.data[parent.over], under = parent.data[parent.under]; @@ -1263,11 +1468,16 @@ else if (under && this === under.CoreMO() && parent.Get("accentunder")) {mapchars = SVG.FONTDATA.REMAPACCENTUNDER} } // + // Primes must come from another font + // + if (isScript && this.data.join("").match(/['`"\u00B4\u2032-\u2037\u2057]/)) + {variant = SVG.FONTDATA.VARIANT["-"+SVG.fontInUse+"-variant"]} + // // Typeset contents // for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i]) { - var text = this.data[i].toSVG(variant,scale,this.SVGremap,mapchars), x = svg.w; + var text = this.data[i].toSVG(variant,scale,this.remap,mapchars), x = svg.w; if (x === 0 && -text.l > 10*text.w) {x += -text.l} // initial combining character doesn't combine svg.Add(text,x,0,true); if (text.skew) {svg.skew = text.skew} @@ -1279,7 +1489,7 @@ // Handle large operator centering // if (values.largeop) { - svg.y = (svg.h - svg.d)/2/scale - SVG.TeX.axis_height; + svg.y = SVG.TeX.axis_height - (svg.h - svg.d)/2/scale; if (svg.r > svg.w) {svg.ic = svg.r - svg.w; svg.w = svg.r} } // @@ -1289,36 +1499,6 @@ this.SVGsaveData(svg); return svg; }, - CoreParent: function () { - var parent = this; - while (parent && parent.isEmbellished() && - parent.CoreMO() === this && !parent.isa(MML.math)) {parent = parent.Parent()} - return parent; - }, - CoreText: function (parent) { - if (!parent) {return ""} - if (parent.isEmbellished()) {return parent.CoreMO().data.join("")} - while (parent.isa(MML.mrow) && parent.data.length === 1 && parent.data[0]) - {parent = parent.data[0]} - if (!parent.isToken) {return ""} else {return parent.data.join("")} - }, - SVGremapChars: { - '*':"\u2217", - '"':"\u2033", - "\u00B0":"\u2218", - "\u00B2":"2", - "\u00B3":"3", - "\u00B4":"\u2032", - "\u00B9":"1" - }, - SVGremap: function (text,map) { - text = text.replace(/-/g,"\u2212"); - if (map) { - text = text.replace(/'/g,"\u2032").replace(/`/g,"\u2035"); - if (text.length === 1) {text = map[text]||text} - } - return text; - }, SVGcanStretch: function (direction) { if (!this.Get("stretchy")) {return false} var c = this.data.join(""); @@ -1333,24 +1513,28 @@ c = SVG.FONTDATA.DELIMITERS[c.charCodeAt(0)]; var can = (c && c.dir == direction.substr(0,1)); if (!can) {delete this.svg} + this.forceStretch = can && (this.Get("minsize",true) || this.Get("maxsize",true)); return can; }, SVGstretchV: function (h,d) { var svg = this.svg || this.toSVG(); var values = this.getValues("symmetric","maxsize","minsize"); - var axis = SVG.TeX.axis_height, mu = this.SVGgetMu(svg), H; + var axis = SVG.TeX.axis_height*svg.scale, mu = this.SVGgetMu(svg), H; if (values.symmetric) {H = 2*Math.max(h-axis,d+axis)} else {H = h + d} values.maxsize = SVG.length2em(values.maxsize,mu,svg.h+svg.d); values.minsize = SVG.length2em(values.minsize,mu,svg.h+svg.d); H = Math.max(values.minsize,Math.min(values.maxsize,H)); + if (H != values.minsize) + {H = [Math.max(H*SVG.TeX.delimiterfactor/1000,H-SVG.TeX.delimitershortfall),H]} svg = SVG.createDelimiter(this.data.join("").charCodeAt(0),H,svg.scale); if (values.symmetric) {H = (svg.h + svg.d)/2 + axis} else {H = (svg.h + svg.d) * h/(h + d)} svg.y = H - svg.h; this.SVGhandleSpace(svg); this.SVGhandleColor(svg); - delete this.svg; + delete this.svg.element; this.SVGsaveData(svg); + svg.stretched = true; return svg; }, SVGstretchH: function (w) { @@ -1365,28 +1549,26 @@ svg = SVG.createDelimiter(this.data.join("").charCodeAt(0),w,svg.scale,values.mathvariant); this.SVGhandleSpace(svg); this.SVGhandleColor(svg); - delete this.svg; + delete this.svg.element; this.SVGsaveData(svg); + svg.stretched = true; return svg; } }); MML.mtext.Augment({ toSVG: function () { - this.SVGgetStyles(); - var svg, text, scale = this.SVGgetScale(); - if (this.Parent().type === "merror") { - // *** FIXME: Make color, style, scale configurable - svg = this.SVG(); this.SVGhandleSpace(svg); - text = BBOX.G(); text.Add(BBOX.TEXT(.9*scale,this.data.join(""),{fill:"#C00"})); - svg.Add(BBOX.RECT(text.h+100,text.d+100,text.w+200,{fill:"#FF8",stroke:"#C00","stroke-width":50}),0,0); - svg.Add(text,150,0); svg.H += 150; svg.D += 50; - svg.Clean(); - this.SVGsaveData(svg); - return svg; - } else if (SVG.config.mtextFontInherit) { - svg = this.SVG(); this.SVGhandleSpace(svg); - svg.Add(BBOX.TEXT(scale,this.data.join(""))); svg.Clean(); + if (SVG.config.mtextFontInherit || this.Parent().type === "merror") { + this.SVGgetStyles(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); + this.SVGhandleSpace(svg); + var variant = this.SVGgetVariant(), def = {direction:this.Get("dir")}; + if (variant.bold) {def["font-weight"] = "bold"} + if (variant.italic) {def["font-style"] = "italic"} + variant = this.Get("mathvariant"); + if (variant === "monospace") {def["class"] = "MJX-monospace"} + else if (variant.match(/sans-serif/)) {def["class"] = "MJX-sans-serif"} + svg.Add(BBOX.TEXT(scale*100/SVG.config.scale,this.data.join(""),def)); svg.Clean(); this.SVGhandleColor(svg); this.SVGsaveData(svg); return svg; @@ -1395,6 +1577,34 @@ } } }); + + MML.merror.Augment({ + toSVG: function (HW,D) { + this.SVGgetStyles(); + var svg = this.SVG(), scale = SVG.length2em(this.styles.fontSize||1)/1000; + this.SVGhandleSpace(svg); + var def = (scale !== 1 ? {transform:"scale("+SVG.Fixed(scale)+")"} : {}); + var bbox = BBOX(def); + bbox.Add(this.SVGchildSVG(0)); bbox.Clean(); + if (scale !== 1) { + bbox.removeable = false; + var adjust = ["w","h","d","l","r","D","H"]; + for (var i = 0, m = adjust.length; i < m; i++) {bbox[adjust[i]] *= scale} + } + svg.Add(bbox); svg.Clean(); + this.SVGhandleColor(svg); + this.SVGsaveData(svg); + return svg; + }, + SVGgetStyles: function () { + var span = HTML.Element("span",{style: SVG.config.merrorStyle}); + this.styles = this.SVGprocessStyles(span.style); + if (this.style) { + span.style.cssText = this.style; + HUB.Insert(this.styles,this.SVGprocessStyles(span.style)); + } + } + }); MML.ms.Augment({toSVG: MML.mbase.SVGautoload}); @@ -1406,10 +1616,11 @@ var values = this.getValues("height","depth","width"); values.mathbackground = this.mathbackground; if (this.background && !this.mathbackground) {values.mathbackground = this.background} - var svg = this.SVG(), mu = this.SVGgetMu(svg); - svg.h = SVG.length2em(values.height,mu) / svg.scale; - svg.d = SVG.length2em(values.depth,mu) / svg.scale; - svg.w = svg.r = SVG.length2em(values.width,mu) / svg.scale; + var svg = this.SVG(); this.SVGgetScale(svg); + var scale = this.mscale, mu = this.SVGgetMu(svg); + svg.h = SVG.length2em(values.height,mu) * scale; + svg.d = SVG.length2em(values.depth,mu) * scale; + svg.w = svg.r = SVG.length2em(values.width,mu) * scale; if (svg.w < 0) {svg.x = svg.w; svg.w = svg.r = 0} if (svg.h < -svg.d) {svg.d = -svg.h} svg.l = 0; svg.Clean(); @@ -1422,14 +1633,14 @@ MML.mphantom.Augment({ toSVG: function (HW,D) { this.SVGgetStyles(); - var svg = this.SVG(); + var svg = this.SVG(); this.SVGgetScale(svg); if (this.data[0] != null) { this.SVGhandleSpace(svg); svg.Add(this.SVGdataStretched(0,HW,D)); svg.Clean(); while (svg.element.firstChild) {svg.element.removeChild(svg.element.firstChild)} } this.SVGhandleColor(svg); - if (!svg.element.firstChild) {delete svg.element} this.SVGsaveData(svg); + if (svg.removeable && !svg.element.firstChild) {delete svg.element} return svg; } }); @@ -1439,14 +1650,14 @@ this.SVGgetStyles(); var svg = this.SVG(); if (this.data[0] != null) { - this.SVGhandleSpace(svg); + this.SVGgetScale(svg); this.SVGhandleSpace(svg); var pad = this.SVGdataStretched(0,HW,D), mu = this.SVGgetMu(svg); - var values = this.getValues("height","depth","width","lspace","voffset"), x = 0, y = 0; - if (values.lspace) {x = this.SVGlength2em(pad,values.lspace,mu)} - if (values.voffset) {y = this.SVGlength2em(pad,values.voffset,mu)} - var h = pad.h, d = pad.d, w = pad.w; // these can change durring the Add() - svg.Add(pad,x,y); svg.Clean(); - svg.h = h; svg.d = d; svg.w = w; svg.removeable = false; + var values = this.getValues("height","depth","width","lspace","voffset"), X = 0, Y = 0; + if (values.lspace) {X = this.SVGlength2em(pad,values.lspace,mu)} + if (values.voffset) {Y = this.SVGlength2em(pad,values.voffset,mu)} + var h = pad.h, d = pad.d, w = pad.w, y = pad.y; // these can change durring the Add() + svg.Add(pad,X,Y); svg.Clean(); + svg.h = h+y; svg.d = d-y; svg.w = w; svg.removeable = false; if (values.height !== "") {svg.h = this.SVGlength2em(svg,values.height,mu,"h",0)} if (values.depth !== "") {svg.d = this.SVGlength2em(svg,values.depth,mu,"d",0)} if (values.width !== "") {svg.w = this.SVGlength2em(svg,values.width,mu,"w",0)} @@ -1460,7 +1671,7 @@ if (m == null) {m = -SVG.BIGDIMEN} var match = String(length).match(/width|height|depth/); var size = (match ? svg[match[0].charAt(0)] : (d ? svg[d] : 0)); - var v = SVG.length2em(length,mu,size); + var v = SVG.length2em(length,mu,size/this.mscale)*this.mscale; if (d && String(length).match(/^\s*[-+]/)) {return Math.max(m,svg[d]+v)} else {return v} } @@ -1468,13 +1679,18 @@ MML.mrow.Augment({ SVG: BBOX.ROW, - toSVG: function () { + toSVG: function (h,d) { this.SVGgetStyles(); var svg = this.SVG(); this.SVGhandleSpace(svg); + if (d != null) {svg.sh = h; svg.sd = d} for (var i = 0, m = this.data.length; i < m; i++) {if (this.data[i]) {svg.Check(this.data[i])}} svg.Stretch(); svg.Clean(); + if (this.data.length === 1 && this.data[0]) { + var data = this.data[0].SVGdata; + if (data.skew) {svg.skew = data.skew} + } if (this.SVGlineBreaks(svg)) {svg = this.SVGmultiline(svg)} this.SVGhandleColor(svg); this.SVGsaveData(svg); @@ -1487,16 +1703,14 @@ }, SVGmultiline: function (span) {MML.mbase.SVGautoloadFile("multiline")}, SVGstretchH: function (w) { - var svg = this.data[this.core].SVGstretchH(w); - this.SVGhandleColor(svg); + var svg = this.SVG(); + this.SVGhandleSpace(svg); + for (var i = 0, m = this.data.length; i < m; i++) + {svg.Add(this.SVGdataStretched(i,w),svg.w,0)} + svg.Clean(); + this.SVGhandleColor(svg); this.SVGsaveData(svg); - return svg; - }, - SVGstretchV: function (h,d) { - var svg = this.data[this.core].SVGstretchV(h,d); - this.SVGhandleColor(svg); - this.SVGsaveData(svg); - return svg; + return svg; } }); @@ -1524,21 +1738,22 @@ MML.mfrac.Augment({ toSVG: function () { this.SVGgetStyles(); - var svg = this.SVG(); this.SVGhandleSpace(svg); - var num = this.data[0].toSVG(), den = this.data[1].toSVG(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); + var frac = BBOX(); frac.scale = svg.scale; this.SVGhandleSpace(frac); + var num = this.SVGchildSVG(0), den = this.SVGchildSVG(1); var values = this.getValues("displaystyle","linethickness","numalign","denomalign","bevelled"); - var scale = svg.scale = this.SVGgetScale(), isDisplay = values.displaystyle; + var isDisplay = values.displaystyle; var a = SVG.TeX.axis_height * scale; if (values.bevelled) { var delta = (isDisplay ? 400 : 150); var H = Math.max(num.h+num.d,den.h+den.d)+2*delta; var bevel = SVG.createDelimiter(0x2F,H); - svg.Add(num,0,(num.d-num.h)/2+a+delta); - svg.Add(bevel,num.w-delta/2,(bevel.d-bevel.h)/2+a); - svg.Add(den,num.w+bevel.w-delta,(den.d-den.h)/2+a-delta); + frac.Add(num,0,(num.d-num.h)/2+a+delta); + frac.Add(bevel,num.w-delta/2,(bevel.d-bevel.h)/2+a); + frac.Add(den,num.w+bevel.w-delta,(den.d-den.h)/2+a-delta); } else { var W = Math.max(num.w,den.w); - var t = SVG.thickness2em(values.linethickness,scale), p,q, u,v; + var t = SVG.thickness2em(values.linethickness,this.scale)*this.mscale, p,q, u,v; var mt = SVG.TeX.min_rule_thickness/SVG.em * 1000; if (isDisplay) {u = SVG.TeX.num1; v = SVG.TeX.denom1} else {u = (t === 0 ? SVG.TeX.num3 : SVG.TeX.num2); v = SVG.TeX.denom2} @@ -1547,36 +1762,39 @@ p = Math.max((isDisplay ? 7 : 3) * SVG.TeX.rule_thickness, 2*mt); // force to at least 2 px q = (u - num.d) - (den.h - v); if (q < p) {u += (p - q)/2; v += (p - q)/2} - svg.w = W; t = 0; + frac.w = W; t = 0; } else {// \over p = Math.max((isDisplay ? 2 : 0) * mt + t, t/2 + 1.5*mt); // force to be at least 1.5px q = (u - num.d) - (a + t/2); if (q < p) {u += p - q} q = (a - t/2) - (den.h - v); if (q < p) {v += p - q} - svg.Add(BBOX.RECT(t/2,t/2,W+2*t),0,a); + frac.Add(BBOX.RECT(t/2,t/2,W+2*t),0,a); } - svg.Align(num,values.numalign,t,u); - svg.Align(den,values.denomalign,t,-v); + frac.Align(num,values.numalign,t,u); + frac.Align(den,values.denomalign,t,-v); } - svg.Clean(); + frac.Clean(); svg.Add(frac,0,0); svg.Clean(); this.SVGhandleColor(svg); this.SVGsaveData(svg); return svg; }, SVGcanStretch: function (direction) {return false}, SVGhandleSpace: function (svg) { - if (!this.texWithDelims) { - svg.x = (this.useMMLspacing ? 0 : SVG.length2em(this.texSpacing()||0)) + 120; - svg.X = 120; - } + if (!this.texWithDelims && !this.useMMLspacing) { + // + // Add nulldelimiterspace around the fraction + // (TeXBook pg 150 and Appendix G rule 15e) + // + svg.x = svg.X = SVG.TeX.nulldelimiterspace * this.mscale; + } + this.SUPER(arguments).SVGhandleSpace.call(this,svg); } }); MML.msqrt.Augment({ toSVG: function () { this.SVGgetStyles(); - var svg = this.SVG(); this.SVGhandleSpace(svg); - var base = this.data[0].toSVG(), rule, surd; - var scale = this.SVGgetScale(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); this.SVGhandleSpace(svg); + var base = this.SVGchildSVG(0), rule, surd; var t = SVG.TeX.rule_thickness * scale, p,q, H, x = 0; if (this.Get("displaystyle")) {p = SVG.TeX.x_height * scale} else {p = t} q = Math.max(t + p/4,1000*SVG.TeX.min_root_space/SVG.em); @@ -1667,9 +1885,7 @@ if (!values.displaystyle && this.data[this.base] != null && this.data[this.base].CoreMO().Get("movablelimits")) {return MML.msubsup.prototype.toSVG.call(this)} - var svg = this.SVG(); - this.SVGhandleSpace(svg); - var scale = svg.scale = this.SVGgetScale(); + var svg = this.SVG(), scale = this.SVGgetScale(svg); this.SVGhandleSpace(svg); var boxes = [], stretch = [], box, i, m, W = -SVG.BIGDIMEN, WW = W; for (i = 0, m = this.data.length; i < m; i++) { if (this.data[i] != null) { @@ -1677,7 +1893,7 @@ boxes[i] = this.SVGdataStretched(i,HW,D); stretch[i] = (D != null || HW == null) && this.data[i].SVGcanStretch("Horizontal"); } else { - boxes[i] = this.data[i].toSVG(); + boxes[i] = this.data[i].toSVG(); boxes[i].x = 0; delete boxes[i].X; stretch[i] = this.data[i].SVGcanStretch("Horizontal"); } if (boxes[i].w > WW) {WW = boxes[i].w} @@ -1686,11 +1902,14 @@ } if (D == null && HW != null) {W = HW} else if (W == -SVG.BIGDIMEN) {W = WW} for (i = WW = 0, m = this.data.length; i < m; i++) {if (this.data[i]) { - if (stretch[i]) {boxes[i] = this.data[i].SVGstretchH(W)} + if (stretch[i]) { + boxes[i] = this.data[i].SVGstretchH(W); + if (i !== this.base) {boxes[i].x = 0; delete boxes[i].X} + } if (boxes[i].w > WW) {WW = boxes[i].w} }} - var t = SVG.TeX.rule_thickness; - var base = boxes[this.base] || {w:0, h:0, d:0, H:0, D:0, l:0, r:0, scale:scale}; + var t = SVG.TeX.rule_thickness * this.mscale; + var base = boxes[this.base] || {w:0, h:0, d:0, H:0, D:0, l:0, r:0, y:0, scale:scale}; var x, y, z1, z2, z3, dw, k, delta = 0; if (base.ic) {delta = 1.3*base.ic + .05} // adjust faked IC to be more in line with expeted results for (i = 0, m = this.data.length; i < m; i++) { @@ -1709,14 +1928,17 @@ if (i == this.over) { if (accent) { k = t * scale; z3 = 0; - if (base.skew) {x += base.skew} + if (base.skew) { + x += base.skew; svg.skew = base.skew; + if (x+box.w > WW) {svg.skew += (WW-box.w-x)/2} + } } else { z1 = SVG.TeX.big_op_spacing1 * scale; z2 = SVG.TeX.big_op_spacing3 * scale; k = Math.max(z1,z2-Math.max(0,box.d)); } k = Math.max(k,1500/SVG.em); - x += delta/2; y = base.h + box.d + k; + x += delta/2; y = base.y + base.h + box.d + k; box.h += z3; if (box.h > box.H) {box.H = box.h} } else if (i == this.under) { if (accent) { @@ -1727,7 +1949,7 @@ k = Math.max(z1,z2-box.h); } k = Math.max(k,1500/SVG.em); - x -= delta/2; y = -(base.d + box.h + k); + x -= delta/2; y = base.y -(base.d + box.h + k); box.d += z3; if (box.d > box.D) {box.D = box.d} } svg.Add(box,x,y); @@ -1743,9 +1965,8 @@ MML.msubsup.Augment({ toSVG: function (HW,D) { this.SVGgetStyles(); - var svg = this.SVG(); - this.SVGhandleSpace(svg); - var scale = svg.scale = this.SVGgetScale(), mu = this.SVGgetMu(svg); + var svg = this.SVG(), scale = this.SVGgetScale(svg); this.SVGhandleSpace(svg); + var mu = this.SVGgetMu(svg); var base = svg.Add(this.SVGdataStretched(this.base,HW,D)); var sscale = (this.data[this.sup] || this.data[this.sub] || this).SVGgetScale(); var x_height = SVG.TeX.x_height * scale, s = SVG.TeX.scriptspace * scale; @@ -1759,7 +1980,7 @@ sub.w += s; sub.r = Math.max(sub.w,sub.r); } var q = SVG.TeX.sup_drop * sscale, r = SVG.TeX.sub_drop * sscale; - var u = base.h - q, v = base.d + r, delta = 0, p; + var u = base.h+(base.y||0) - q, v = base.d-(base.y||0) + r, delta = 0, p; if (base.ic) { base.w -= base.ic; // remove IC (added by mo and mi) delta = 1.3*base.ic+.05; // adjust faked IC to be more in line with expeted results @@ -1772,17 +1993,20 @@ var min = this.getValues("subscriptshift","superscriptshift"); min.subscriptshift = (min.subscriptshift === "" ? 0 : SVG.length2em(min.subscriptshift,mu)); min.superscriptshift = (min.superscriptshift === "" ? 0 : SVG.length2em(min.superscriptshift,mu)); + var x = base.w + base.x; if (!sup) { if (sub) { v = Math.max(v,SVG.TeX.sub1*scale,sub.h-(4/5)*x_height,min.subscriptshift); - svg.Add(sub,base.w,-v); + svg.Add(sub,x,-v); this.data[this.sub].SVGdata.dy = -v; } } else { if (!sub) { values = this.getValues("displaystyle","texprimestyle"); p = SVG.TeX[(values.displaystyle ? "sup1" : (values.texprimestyle ? "sup3" : "sup2"))]; u = Math.max(u,p*scale,sup.d+(1/4)*x_height,min.superscriptshift); - svg.Add(sup,base.w+delta,u); + svg.Add(sup,x+delta,u); + this.data[this.sup].SVGdata.dx = delta; + this.data[this.sup].SVGdata.dy = u; } else { v = Math.max(v,SVG.TeX.sub2*scale); var t = SVG.TeX.rule_thickness * scale; @@ -1791,8 +2015,11 @@ q = (4/5)*x_height - (u - sup.d); if (q > 0) {u += q; v -= q} } - svg.Add(sup,base.w+delta,Math.max(u,min.superscriptshift)); - svg.Add(sub,base.w,-Math.max(v,min.subscriptshift)); + svg.Add(sup,x+delta,Math.max(u,min.superscriptshift)); + svg.Add(sub,x,-Math.max(v,min.subscriptshift)); + this.data[this.sup].SVGdata.dx = delta; + this.data[this.sup].SVGdata.dy = Math.max(u,min.superscriptshift); + this.data[this.sub].SVGdata.dy = -Math.max(v,min.subscriptshift); } } svg.Clean(); @@ -1809,65 +2036,97 @@ MML.math.Augment({ SVG: BBOX.Subclass({type:"svg", removeable: false}), toSVG: function (span,div) { + var CONFIG = SVG.config; + // + // All the data should be in an inferrerd row + // if (this.data[0]) { this.SVGgetStyles(); MML.mbase.prototype.displayAlign = HUB.config.displayAlign; MML.mbase.prototype.displayIndent = HUB.config.displayIndent; + if (String(HUB.config.displayIndent).match(/^0($|[a-z%])/i)) + MML.mbase.prototype.displayIndent = "0"; // // Put content in a with defaults and matrix that flips y axis. // Put that in an with xlink defined. // - var box = BBOX.G({ - stroke:"black", fill:"black", "stroke-thickness":0, - transform: "matrix(1 0 0 -1 0 0)" - }).With({removeable: false}); - box.Add(this.data[0].toSVG(),0,0,true); box.Clean(); + var box = BBOX.G(); box.Add(this.data[0].toSVG(),0,0,true); box.Clean(); this.SVGhandleColor(box); - var svg = this.SVG(); svg.element.setAttribute("xmlns:xlink",XLINKNS); + SVG.Element(box.element,{ + stroke:"currentColor", fill:"currentColor", "stroke-width":0, + transform: "matrix(1 0 0 -1 0 0)" + }); + box.removeable = false; + var svg = this.SVG(); + svg.element.setAttribute("xmlns:xlink",XLINKNS); + if (CONFIG.useFontCache && !CONFIG.useGlobalCache) + {svg.element.appendChild(BBOX.GLYPH.defs)} svg.Add(box); svg.Clean(); this.SVGsaveData(svg); // + // If this element is not the top-level math element + // remove the transform and return the svg object + // (issue #614). + // + if (!span) { + svg.element = svg.element.firstChild; // remove element + svg.element.removeAttribute("transform"); + svg.removable = true; + return svg; + } + // // Style the to get the right size and placement // var l = Math.max(-svg.l,0), r = Math.max(svg.r-svg.w,0); - var style = svg.element.style; - style.width = SVG.Ex(l+svg.w+r); - style.height = SVG.Ex(svg.H+svg.D); - style.verticalAlign = SVG.Ex(-svg.D-2*SVG.em); // remove 2 extra pixels added below - style.marginLeft = SVG.Ex(-l); style.marginRight = SVG.Ex(-r); - svg.element.setAttribute("viewBox",(-l)+" "+(-svg.H)+" "+(l+svg.w+r)+" "+(svg.H+svg.D)); - svg.element.style.margin="1px 0px"; // 1px above and below to prevent lines from touching + var style = svg.element.style, px = SVG.TeX.x_height/SVG.ex; + var H = (Math.ceil(svg.H/px)+1)*px+SVG.HFUZZ, // round to pixels and add padding + D = (Math.ceil(svg.D/px)+1)*px+SVG.DFUZZ; + svg.element.setAttribute("width",SVG.Ex(l+svg.w+r)); + svg.element.setAttribute("height",SVG.Ex(H+D)); + style.verticalAlign = SVG.Ex(-D); + if (l) style.marginLeft = SVG.Ex(-l); + if (r) style.marginRight = SVG.Ex(-r); + svg.element.setAttribute("viewBox",SVG.Fixed(-l,1)+" "+SVG.Fixed(-H,1)+" "+ + SVG.Fixed(l+svg.w+r,1)+" "+SVG.Fixed(H+D,1)); // // If there is extra height or depth, hide that // - if (svg.H > svg.h || svg.D > svg.d) { - var frame = HTML.Element( - "span",{style: {display:"inline-block", "white-space":"nowrap", padding:"1px 0px"}, isMathJax:true},[[ - "span",{style: {display:"inline-block", position:"relative", isMathJax:true, - width:SVG.Ex(svg.w), height:SVG.Ex(svg.h+svg.d), - "vertical-align":SVG.Ex(-svg.d)}}]]); - frame.firstChild.appendChild(svg.element); svg.element = frame; - style.verticalAlign = ""; style.position = "absolute"; - style.bottom = SVG.Ex(svg.d-svg.D); style.left = 0; - } + if (svg.H > svg.h) style.marginTop = SVG.Ex(svg.h-H); + if (svg.D > svg.d) { + style.marginBottom = SVG.Ex(svg.d-D); + style.verticalAlign = SVG.Ex(-svg.d); + } // // Add it to the MathJax span // - span.appendChild(svg.element); svg.element = null; + var alttext = this.Get("alttext"); + if (alttext && !svg.element.getAttribute("aria-label")) svg.element.setAttribute("aria-label",alttext); + if (!svg.element.getAttribute("role")) svg.element.setAttribute("role","img"); + svg.element.setAttribute("focusable","false"); + span.appendChild(svg.element); + svg.element = null; // // Handle indentalign and indentshift for single-line displays // - if (!this.isMultiline && this.Get("display") === "block") { + if (!this.isMultiline && this.Get("display") === "block" && !svg.hasIndent) { var values = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift"); if (values.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {values.indentalign = values.indentalignfirst} if (values.indentalign === MML.INDENTALIGN.AUTO) {values.indentalign = this.displayAlign} - div.style.textAlign = values.indentalign; if (values.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {values.indentshift = values.indentshiftfirst} - if (values.indentshift === "auto") {values.indentshift = this.displayIndent} - if (values.indentshift && values.indentalign !== MML.INDENTALIGN.CENTER && !svg.hasIndent) { - span.style[{left:"marginLeft",right:"marginRight"}[values.indentalign]] = - SVG.Ex(SVG.length2em(values.indentshift)); - } + if (values.indentshift === "auto") {values.indentshift = "0"} + var shift = SVG.length2em(values.indentshift,1,SVG.cwidth); + if (this.displayIndent !== "0") { + var indent = SVG.length2em(this.displayIndent,1,SVG.cwidth); + shift += (values.indentalign === MML.INDENTALIGN.RIGHT ? -indent : indent); + } + div.style.textAlign = values.indentalign; + if (shift) { + HUB.Insert(style,({ + left: {marginLeft: SVG.Ex(shift)}, + right: {marginRight: SVG.Ex(-shift), marginLeft: SVG.Ex(Math.max(0,shift-(l+svg.w+r)))}, + center: {marginLeft: SVG.Ex(shift), marginRight: SVG.Ex(-shift)} + })[values.indentalign]); + } } } return span; @@ -1875,18 +2134,16 @@ }); MML.TeXAtom.Augment({ - toSVG: function () { + toSVG: function (HW,D) { this.SVGgetStyles(); var svg = this.SVG(); this.SVGhandleSpace(svg); if (this.data[0] != null) { - var box = this.data[0].toSVG(), y = 0; - if (this.texClass === MML.TEXCLASS.VCENTER) { - // FIXME: should the axis height be scaled? - y = SVG.TeX.axis_height - (box.h+box.d)/2 + box.d; - } + var box = this.SVGdataStretched(0,HW,D), y = 0; + if (this.texClass === MML.TEXCLASS.VCENTER) + {y = SVG.TeX.axis_height - (box.h+box.d)/2 + box.d} svg.Add(box,0,y); - svg.ic = box.ic; + svg.ic = box.ic; svg.skew = box.skew; } this.SVGhandleColor(svg); this.SVGsaveData(svg); @@ -1894,6 +2151,14 @@ } }); + // + // Make sure these don't generate output + // + MML.maligngroup.Augment({toSVG: MML.mbase.SVGemptySVG}); + MML.malignmark.Augment({toSVG: MML.mbase.SVGemptySVG}); + MML.mprescripts.Augment({toSVG: MML.mbase.SVGemptySVG}); + MML.none.Augment({toSVG: MML.mbase.SVGemptySVG}); + // // Loading isn't complete until the element jax is modified, // but can't call loadComplete within the callback for "mml Jax Ready" @@ -1908,6 +2173,14 @@ }); }); + HUB.Browser.Select({ + Opera: function (browser) { + SVG.Augment({ + operaZoomRefresh: true // Opera needs a kick to redraw zoomed equations + }); + } + }); + HUB.Register.StartupHook("End Cookie", function () { if (HUB.config.menuSettings.zoom !== "None") {AJAX.Require("[MathJax]/extensions/MathZoom.js")}