From 11011d7c373c655830053b155eeaf632c2658ac7 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Thu, 24 Jun 2021 17:50:34 +1000 Subject: Updated. - added mathjax (freed) - added rss.py - updated publish.el - etc. --- js/mathjax/extensions/AssistiveMML.js | 167 ++ js/mathjax/extensions/CHTML-preview.js | 32 + js/mathjax/extensions/FontWarnings.js | 315 ++++ js/mathjax/extensions/HTML-CSS/handle-floats.js | 51 + js/mathjax/extensions/HelpDialog.js | 205 +++ js/mathjax/extensions/MatchWebFonts.js | 311 ++++ js/mathjax/extensions/MathEvents.js | 624 +++++++ js/mathjax/extensions/MathML/content-mathml.js | 1745 +++++++++++++++++++ js/mathjax/extensions/MathML/mml3.js | 786 +++++++++ js/mathjax/extensions/MathMenu.js | 1666 ++++++++++++++++++ js/mathjax/extensions/MathZoom.js | 368 ++++ js/mathjax/extensions/Safe.js | 430 +++++ js/mathjax/extensions/TeX/AMScd.js | 160 ++ js/mathjax/extensions/TeX/AMSmath.js | 665 ++++++++ js/mathjax/extensions/TeX/AMSsymbols.js | 351 ++++ js/mathjax/extensions/TeX/HTML.js | 108 ++ js/mathjax/extensions/TeX/action.js | 85 + js/mathjax/extensions/TeX/autobold.js | 52 + js/mathjax/extensions/TeX/autoload-all.js | 85 + js/mathjax/extensions/TeX/bbox.js | 104 ++ js/mathjax/extensions/TeX/begingroup.js | 294 ++++ js/mathjax/extensions/TeX/boldsymbol.js | 77 + js/mathjax/extensions/TeX/cancel.js | 112 ++ js/mathjax/extensions/TeX/color.js | 283 ++++ js/mathjax/extensions/TeX/enclose.js | 93 + js/mathjax/extensions/TeX/extpfeil.js | 104 ++ js/mathjax/extensions/TeX/mathchoice.js | 109 ++ js/mathjax/extensions/TeX/mediawiki-texvc.js | 138 ++ js/mathjax/extensions/TeX/mhchem.js | 522 ++++++ js/mathjax/extensions/TeX/mhchem3/mhchem.js | 1776 ++++++++++++++++++++ js/mathjax/extensions/TeX/newcommand.js | 272 +++ js/mathjax/extensions/TeX/noErrors.js | 407 +++++ js/mathjax/extensions/TeX/noUndefined.js | 74 + js/mathjax/extensions/TeX/text-macros.js | 489 ++++++ js/mathjax/extensions/TeX/unicode.js | 172 ++ js/mathjax/extensions/TeX/verb.js | 63 + js/mathjax/extensions/a11y/accessibility-menu.js | 186 ++ js/mathjax/extensions/a11y/auto-collapse.js | 500 ++++++ js/mathjax/extensions/a11y/collapsible.js | 743 ++++++++ js/mathjax/extensions/a11y/explorer.js | 827 +++++++++ js/mathjax/extensions/a11y/invalid_keypress.mp3 | Bin 0 -> 9030 bytes js/mathjax/extensions/a11y/invalid_keypress.ogg | Bin 0 -> 5353 bytes js/mathjax/extensions/a11y/mathjax-sre.js | 1633 ++++++++++++++++++ js/mathjax/extensions/a11y/mathmaps/de.js | 104 ++ js/mathjax/extensions/a11y/mathmaps/en.js | 110 ++ js/mathjax/extensions/a11y/mathmaps/es.js | 104 ++ js/mathjax/extensions/a11y/mathmaps/fr.js | 104 ++ js/mathjax/extensions/a11y/mathmaps/mathmaps_ie.js | 518 ++++++ js/mathjax/extensions/a11y/mathmaps/nemeth.js | 104 ++ js/mathjax/extensions/a11y/semantic-enrich.js | 208 +++ js/mathjax/extensions/a11y/wgxpath.install.js | 77 + js/mathjax/extensions/asciimath2jax.js | 256 +++ js/mathjax/extensions/fast-preview.js | 157 ++ js/mathjax/extensions/jsMath2jax.js | 107 ++ js/mathjax/extensions/mml2jax.js | 265 +++ js/mathjax/extensions/tex2jax.js | 321 ++++ js/mathjax/extensions/toMathML.js | 243 +++ 57 files changed, 19862 insertions(+) create mode 100644 js/mathjax/extensions/AssistiveMML.js create mode 100644 js/mathjax/extensions/CHTML-preview.js create mode 100644 js/mathjax/extensions/FontWarnings.js create mode 100644 js/mathjax/extensions/HTML-CSS/handle-floats.js create mode 100644 js/mathjax/extensions/HelpDialog.js create mode 100644 js/mathjax/extensions/MatchWebFonts.js create mode 100644 js/mathjax/extensions/MathEvents.js create mode 100644 js/mathjax/extensions/MathML/content-mathml.js create mode 100644 js/mathjax/extensions/MathML/mml3.js create mode 100644 js/mathjax/extensions/MathMenu.js create mode 100644 js/mathjax/extensions/MathZoom.js create mode 100644 js/mathjax/extensions/Safe.js create mode 100644 js/mathjax/extensions/TeX/AMScd.js create mode 100644 js/mathjax/extensions/TeX/AMSmath.js create mode 100644 js/mathjax/extensions/TeX/AMSsymbols.js create mode 100644 js/mathjax/extensions/TeX/HTML.js create mode 100644 js/mathjax/extensions/TeX/action.js create mode 100644 js/mathjax/extensions/TeX/autobold.js create mode 100644 js/mathjax/extensions/TeX/autoload-all.js create mode 100644 js/mathjax/extensions/TeX/bbox.js create mode 100644 js/mathjax/extensions/TeX/begingroup.js create mode 100644 js/mathjax/extensions/TeX/boldsymbol.js create mode 100644 js/mathjax/extensions/TeX/cancel.js create mode 100644 js/mathjax/extensions/TeX/color.js create mode 100644 js/mathjax/extensions/TeX/enclose.js create mode 100644 js/mathjax/extensions/TeX/extpfeil.js create mode 100644 js/mathjax/extensions/TeX/mathchoice.js create mode 100644 js/mathjax/extensions/TeX/mediawiki-texvc.js create mode 100644 js/mathjax/extensions/TeX/mhchem.js create mode 100644 js/mathjax/extensions/TeX/mhchem3/mhchem.js create mode 100644 js/mathjax/extensions/TeX/newcommand.js create mode 100644 js/mathjax/extensions/TeX/noErrors.js create mode 100644 js/mathjax/extensions/TeX/noUndefined.js create mode 100644 js/mathjax/extensions/TeX/text-macros.js create mode 100644 js/mathjax/extensions/TeX/unicode.js create mode 100644 js/mathjax/extensions/TeX/verb.js create mode 100644 js/mathjax/extensions/a11y/accessibility-menu.js create mode 100644 js/mathjax/extensions/a11y/auto-collapse.js create mode 100644 js/mathjax/extensions/a11y/collapsible.js create mode 100644 js/mathjax/extensions/a11y/explorer.js create mode 100644 js/mathjax/extensions/a11y/invalid_keypress.mp3 create mode 100644 js/mathjax/extensions/a11y/invalid_keypress.ogg create mode 100644 js/mathjax/extensions/a11y/mathjax-sre.js create mode 100644 js/mathjax/extensions/a11y/mathmaps/de.js create mode 100644 js/mathjax/extensions/a11y/mathmaps/en.js create mode 100644 js/mathjax/extensions/a11y/mathmaps/es.js create mode 100644 js/mathjax/extensions/a11y/mathmaps/fr.js create mode 100644 js/mathjax/extensions/a11y/mathmaps/mathmaps_ie.js create mode 100644 js/mathjax/extensions/a11y/mathmaps/nemeth.js create mode 100644 js/mathjax/extensions/a11y/semantic-enrich.js create mode 100644 js/mathjax/extensions/a11y/wgxpath.install.js create mode 100644 js/mathjax/extensions/asciimath2jax.js create mode 100644 js/mathjax/extensions/fast-preview.js create mode 100644 js/mathjax/extensions/jsMath2jax.js create mode 100644 js/mathjax/extensions/mml2jax.js create mode 100644 js/mathjax/extensions/tex2jax.js create mode 100644 js/mathjax/extensions/toMathML.js (limited to 'js/mathjax/extensions') diff --git a/js/mathjax/extensions/AssistiveMML.js b/js/mathjax/extensions/AssistiveMML.js new file mode 100644 index 0000000..a41b24b --- /dev/null +++ b/js/mathjax/extensions/AssistiveMML.js @@ -0,0 +1,167 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9", + + config: HUB.CombineConfig("AssistiveMML",{ + 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", + // + // Don't allow the assistive MathML become part of the selection + // + "-webkit-touch-callout": "none", + "-webkit-user-select": "none", + "-khtml-user-select": "none", + "-moz-user-select": "none", + "-ms-user-select": "none", + "user-select": "none" + }, + ".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; + var MML = MathJax.ElementJax.mml; + MML.copyAttributes.id = 1; + while (state.i < m) { + jax = state.jax[state.i]; + frame = document.getElementById(jax.inputID+"-Frame"); + if (jax.outputJax !== "NativeMML" && jax.outputJax !== "PlainSource" && + frame && !frame.getAttribute("data-mathml")) { + try { + mml = jax.root.toMathML("").replace(/\n */g,"").replace(//g,""); + } catch (err) { + MML.copyAttributes.id = true; + 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, unselectable: "on", + className: "MJX_Assistive_MathML" + + (jax.root.Get("display") === "block" ? " MJX_Assistive_MathML_Block" : "") + }); + try {span.innerHTML = mml} catch (err) {} + frame.style.position = "relative"; + frame.setAttribute("role","presentation"); + frame.firstChild.setAttribute("aria-hidden","true"); + span.setAttribute("role","presentation"); + } + state.i++; + } + MML.copyAttributes.id = true; + 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]); + } +); + +// @license-end diff --git a/js/mathjax/extensions/CHTML-preview.js b/js/mathjax/extensions/CHTML-preview.js new file mode 100644 index 0000000..1c7597a --- /dev/null +++ b/js/mathjax/extensions/CHTML-preview.js @@ -0,0 +1,32 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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"] +); +// @license-end diff --git a/js/mathjax/extensions/FontWarnings.js b/js/mathjax/extensions/FontWarnings.js new file mode 100644 index 0000000..04c1490 --- /dev/null +++ b/js/mathjax/extensions/FontWarnings.js @@ -0,0 +1,315 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/FontWarnings.js + * + * Implements a font warning message window that appears when + * the image fonts, no fonts, or web fonts are used, informing + * the user where to download the fonts, or to update to a more + * modern browser. The window will fade out automatically after + * a time, and the user can dismiss it by a close box. + * + * To include font warning messages, add "FontWarnings.js" to the + * extensions array in your MathJax configuration. + * + * You can customize the warning messages in a number of ways. Use the + * FontWarnings section of the configuration to specify any of the items + * shown in the CONFIG variable below. These include + * + * messageStyle the style to apply to the warning box that is + * displayed when MathJax uses one of its fallback + * methods. + * + * removeAfter the amount of time to show the warning message (in ms) + * fadeoutTime how long the message should take to fade out + * fadeoutSteps how many separate steps to use during the fade out + * (set to 0 to use no fadeout and simply remove the window) + * + * Messages stores the descriptions of the messages to use for the + * various warnings (webFonts, imageFonts, and noFonts). + * These are arrays of strings to be inserted into the window, + * or identifiers within brackets, which refer to the HTML + * snippets in the HTML section described below. To disable a + * specific message, set its value to null (see example below). + * + * HTML stores snippets of HTML descriptions for various + * common parts of the error messages. These include + * the closeBox, the message about web fonts being available + * in modern browser, and messages about downloadable fonts. + * The STIX and TeX font messages are used when only one + * of these is in the availableFonts list. The data for these + * are arrays of either strings to include or a description of + * an HTML item enclosed in square brackets. That description + * has (up to) three parts: the name of the tag to be included, + * a list (enclosed in braces) of attributes and their values + * to be set on the tag (optional), and an array of the contents + * of the tag (optional). See the definitions below for examples. + * + * For example, + * + * MathJax.Hub.Config({ + * ... + * extensions: ["FontWarnings.js"], + * FontWarnings: { + * removeAfter: 20*1000, // 20 seconds + * messageStyle: { + * border: "2px solid black", + * padding: "2em" + * }, + * Message: { + * webFont: null // no webfont messages (only image and no fonts) + * } + * } + * }); + * + * would extend the time the message is displayed from 12 seconds to 20, + * and changes the border to a solid black one, with 2em of padding + * rather than the default of 1em. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 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) { + var VERSION = "2.7.9"; + + 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",{ + // + // The CSS for the message window + // + messageStyle: { + position:"fixed", bottom:"4em", left:"3em", width:"40em", + border: "3px solid #880000", "background-color": "#E0E0E0", color: "black", + padding: "1em", "font-size":"small", "white-space":"normal", + + "border-radius": ".75em", // Opera 10.5 and IE9 + "-webkit-border-radius": ".75em", // Safari and Chrome + "-moz-border-radius": ".75em", // Firefox + "-khtml-border-radius": ".75em", // Konqueror + + "box-shadow": "4px 4px 10px #AAAAAA", // Opera 10.5 and IE9 + "-webkit-box-shadow": "4px 4px 10px #AAAAAA", // Safari 3 and Chrome + "-moz-box-shadow": "4px 4px 10px #AAAAAA", // Forefox 3.5 + "-khtml-box-shadow": "4px 4px 10px #AAAAAA", // Konqueror + filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=3, OffY=3, Color='gray', Positive='true')" // IE + }, + + // + // The messages for the various situations + // + Message: { + + webFont: [ + ["closeBox"], + ["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"], + ["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"] + ], + + noFonts: [ + ["closeBox"], + ["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"] + ] + }, + + // + // HTML objects that can be referred to in the message definitions + // + HTML: { + // + // The definition of the close box + // + closeBox: [[ + "div",{ + style: { + position:"absolute", overflow:"hidden", top:".1em", right:".1em", + border: "1px outset", width:"1em", height:"1em", + "text-align": "center", cursor: "pointer", + "background-color": "#EEEEEE", color:"#606060", + + "border-radius": ".5em", // Opera 10.5 + "-webkit-border-radius": ".5em", // Safari and Chrome + "-moz-border-radius": ".5em", // Firefox + "-khtml-border-radius": ".5em" // Konqueror + }, + onclick: function () { + if (DATA.div && DATA.fade === 0) + {if (DATA.timer) {clearTimeout(DATA.timer)}; DATA.div.style.display = "none"} + } + }, + [["span",{style:{position:"relative", bottom:".2em"}},["x"]]] + ]], + + webFonts: [ + ["p"], + ["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"], + ["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"], + ["STIXPage", + "This page is designed to use the [STIX fonts](%1). " + + "Download and install those fonts to improve your MathJax experience.", + STIXURL + ] + ], + + TeXfonts: [ + ["p"], + ["TeXPage", + "This page is designed to use the [MathJax TeX fonts](%1). " + + "Download and install those fonts to improve your MathJax experience.", + MATHJAXURL + ] + ] + + }, + + removeAfter: 12*1000, // time to show message (in ms) + fadeoutSteps: 10, // fade-out steps + fadeoutTime: 1.5*1000 // fadeout over this amount of time (in ms) + + }); + if (MathJax.Hub.Browser.isIE9 && document.documentMode >= 9) + {delete CONFIG.messageStyle.filter} + + // + // Data for the window + // + var DATA = { + div: null, // the message window, when displayed + fade: 0 // number of fade-out steps so far + }; + + // + // Create the message window and start the fade-out timer + // + var CREATEMESSAGE = function (data) { + if (DATA.div) return; + var HTMLCSS = MathJax.OutputJax["HTML-CSS"], frame = document.body; + if (HUB.Browser.isMSIE) { + if (CONFIG.messageStyle.position === "fixed") { + MathJax.Message.Init(); // make sure MathJax_MSIE_frame exists + 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 (MathJax.Object.isArray(data[i])) { + 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); + MathJax.Localization.setCSS(DATA.div); + if (CONFIG.removeAfter) { + HUB.Register.StartupHook("End",function () + {DATA.timer = setTimeout(FADEOUT,CONFIG.removeAfter)}); + } + HTML.Cookie.Set("fontWarn",{warned:true}); + }; + + // + // Set the opacity based on the number of steps taken so far + // and remove the window when it gets to 0 + // + var FADEOUT = function () { + DATA.fade++; if (DATA.timer) {delete DATA.timer} + if (DATA.fade < CONFIG.fadeoutSteps) { + var opacity = 1 - DATA.fade/CONFIG.fadeoutSteps; + DATA.div.style.opacity = opacity; + DATA.div.style.filter = "alpha(opacity="+Math.floor(100*opacity)+")"; + setTimeout(FADEOUT,CONFIG.fadeoutTime/CONFIG.fadeoutSteps); + } else { + DATA.div.style.display = "none"; + } + }; + + // + // Check that we haven't already issued a warning + // + if (!HTML.Cookie.Get("fontWarn").warned) { + // + // Hook into the Startup signal and look for font warning messages. + // When one comes, issue the correct message. + // + HUB.Startup.signal.Interest(function (message) { + if (message.match(/HTML-CSS Jax - /) && !DATA.div) { + var HTMLCSS = MathJax.OutputJax["HTML-CSS"], FONTS = HTMLCSS.config.availableFonts, MSG; + var localFonts = (FONTS && FONTS.length); + if (!localFonts) {CONFIG.HTML.fonts = [""]} + else if (FONTS.length === 1) {CONFIG.HTML.fonts = CONFIG.HTML[FONTS[0]+"fonts"]} + if (HTMLCSS.allowWebFonts) {CONFIG.HTML.webfonts = [""]} + 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]) + {MathJax.Localization.loadDomain("FontWarnings",[CREATEMESSAGE,CONFIG.Message[MSG]])} + } + }); + } + +})(MathJax.Hub,MathJax.HTML); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/FontWarnings.js"); +// @license-end diff --git a/js/mathjax/extensions/HTML-CSS/handle-floats.js b/js/mathjax/extensions/HTML-CSS/handle-floats.js new file mode 100644 index 0000000..7afeba9 --- /dev/null +++ b/js/mathjax/extensions/HTML-CSS/handle-floats.js @@ -0,0 +1,51 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9" +}; + +// +// This file is now obsolete, since the HTML-CSS output already handles +// floating elements properly. +// + +MathJax.Hub.Startup.signal.Post("HTML-CSS handle-floats Ready"); +MathJax.Ajax.loadComplete("[MathJax]/extensions/HTML-CSS/handle-floats.js"); +// @license-end diff --git a/js/mathjax/extensions/HelpDialog.js b/js/mathjax/extensions/HelpDialog.js new file mode 100644 index 0000000..c7663c0 --- /dev/null +++ b/js/mathjax/extensions/HelpDialog.js @@ -0,0 +1,205 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * MathJax/extensions/HelpDialog.js + * + * Implements the MathJax Help dialog box. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2020 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.7.9" + }; + + 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,"HelpDialog Ready"], + ["loadComplete",AJAX,"[MathJax]/extensions/HelpDialog.js"] + ); + +})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.OutputJax,MathJax.Localization); +// @license-end diff --git a/js/mathjax/extensions/MatchWebFonts.js b/js/mathjax/extensions/MatchWebFonts.js new file mode 100644 index 0000000..95e168c --- /dev/null +++ b/js/mathjax/extensions/MatchWebFonts.js @@ -0,0 +1,311 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9"; + + 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); +// @license-end diff --git a/js/mathjax/extensions/MathEvents.js b/js/mathjax/extensions/MathEvents.js new file mode 100644 index 0000000..2f83e05 --- /dev/null +++ b/js/mathjax/extensions/MathEvents.js @@ -0,0 +1,624 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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,CALLBACK,LOCALE,OUTPUT,INPUT) { + var VERSION = "2.7.9"; + + 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: { + x: 3.5, y: 5, // frame padding and + bwidth: 1, // frame border width (in pixels) + bcolor: "#A6D", // frame border color + hwidth: "15px", // haze width + hcolor: "#83A" // haze color + }, + button: { + 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 + fadeDelay: 50, // delay between fade-in or fade-out steps + fadeoutStart: 400, // delay before fade-out after mouseout + fadeoutDelay: 15*1000, // delay before automatic fade-out + + styles: { + ".MathJax_Hover_Frame": { + "border-radius": ".25em", // Opera 10.5 and IE9 + "-webkit-border-radius": ".25em", // Safari and Chrome + "-moz-border-radius": ".25em", // Firefox + "-khtml-border-radius": ".25em", // Konqueror + + "box-shadow": "0px 0px 15px #83A", // Opera 10.5 and IE9 + "-webkit-box-shadow": "0px 0px 15px #83A", // Safari and Chrome + "-moz-box-shadow": "0px 0px 15px #83A", // Forefox + "-khtml-box-shadow": "0px 0px 15px #83A", // Konqueror + + border: "1px solid #A6D ! important", + display: "inline-block", position:"absolute" + }, + + ".MathJax_Menu_Button .MathJax_Hover_Arrow": { + position:"absolute", + 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, + LESS: 188, + GREATER: 190, + DASH: 189 + }, + + 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)}, + Mouseover: function (event) {return EVENT.Handler(event,"Mouseover",this)}, + Mouseout: function (event) {return EVENT.Handler(event,"Mouseout",this)}, + 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 + // + Handler: function (event,type,math) { + if (AJAX.loadingMathMenu) {return EVENT.False(event)} + var jax = OUTPUT[math.jaxID]; + if (!event) {event = window.event} + event.isContextMenu = (type === "ContextMenu"); + 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()} else {event.returnValue = false} + if (event.stopPropagation) {event.stopPropagation()} + event.cancelBubble = true; + } + 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 + // + ContextMenu: function (event,math,force) { + // + // Check if we are showing menus + // + var JAX = OUTPUT[math.jaxID], jax = JAX.getJaxFromMath(math); + var show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu; + if (!show || (SETTINGS.context !== "MathJax" && !force)) return; + + // + // Remove selections, remove hover fades + // + if (ME.msieEventBug) {event = window.event || event} + EVENT.ClearSelection(); HOVER.ClearHoverTimer(); + if (jax.hover) { + if (jax.hover.remove) {clearTimeout(jax.hover.remove); delete jax.hover.remove} + jax.hover.nofade = true; + } + + // + // 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 load, fn; + if (MENU) { + 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 = {}} + } + } + 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 + // + AltContextMenu: function (event,math) { + var JAX = OUTPUT[math.jaxID]; + var show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu; + if (show) { + show = (JAX.config.showMathMenuMSIE != null ? JAX : HUB).config.showMathMenuMSIE; + if (SETTINGS.context === "MathJax" && !SETTINGS.mpContext && show) { + if (!ME.noContextMenuBug || event.button !== EVENT.RIGHTBUTTON) return; + } else { + if (!event[EVENT.MENUKEY] || event.button !== EVENT.LEFTBUTTON) return; + } + 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 + // timer for the hover + // + Mouseover: function (event,math) { + if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") { + var from = event.fromElement || event.relatedTarget, + to = event.toElement || event.target; + 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)} + return EVENT.False(event); + } + } + }, + // + // Check if we are moving from a MathJax element to a non-MathJax one + // and either start fading out, or clear the timer if we haven't + // hovered yet + // + Mouseout: function (event,math) { + if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") { + var from = event.fromElement || event.relatedTarget, + to = event.toElement || event.target; + 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()} + return EVENT.False(event); + } + } + }, + // + // Restart hover timer if the mouse moves + // + Mousemove: function (event,math) { + if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") { + var jax = this.getJaxFromMath(math); if (jax.hover) return; + if (HOVER.lastX == event.clientX && HOVER.lastY == event.clientY) return; + HOVER.lastX = event.clientX; HOVER.lastY = event.clientY; + HOVER.HoverTimer(jax,math); + return EVENT.False(event); + } + }, + + // + // Clear the old timer and start a new one + // + HoverTimer: function (jax,math) { + this.ClearHoverTimer(); + this.hoverTimer = setTimeout(CALLBACK(["Hover",this,jax,math]),CONFIG.hover); + }, + ClearHoverTimer: function () { + if (this.hoverTimer) {clearTimeout(this.hoverTimer); delete this.hoverTimer} + }, + + // + // Handle putting up the hover frame + // + Hover: function (jax,math) { + // + // Check if Zoom handles the hover event + // + if (EXTENSION.MathZoom && EXTENSION.MathZoom.Hover({},math)) return; + // + // Get the hover data + // + var JAX = OUTPUT[jax.outputJax], + span = JAX.getHoverSpan(jax,math), + bbox = JAX.getHoverBBox(jax,span,math), + show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu; + var dx = CONFIG.frame.x, dy = CONFIG.frame.y, dd = CONFIG.frame.bwidth; // frame size + if (ME.msieBorderWidthBug) {dd = 0} + jax.hover = {opacity:0, id:jax.inputID+"-Hover"}; + // + // The frame and menu button + // + var frame = HTML.Element("span",{ + id:jax.hover.id, isMathJax: true, + style:{display:"inline-block", width:0, height:0, position:"relative"} + },[["span",{ + className:"MathJax_Hover_Frame", isMathJax: true, + style:{ + display:"inline-block", position:"absolute", + top:this.Px(-bbox.h-dy-dd-(bbox.y||0)), left:this.Px(-dx-dd+(bbox.x||0)), + width:this.Px(bbox.w+2*dx), height:this.Px(bbox.h+bbox.d+2*dy), + opacity:0, filter:"alpha(opacity=0)" + }} + ]] + ); + var button = HTML.Element("span",{ + isMathJax: true, id:jax.hover.id+"Menu", className:"MathJax_Menu_Button", + style:{display:"inline-block", "z-index": 1, width:0, height:0, position:"relative"} + },[["span",{ + className: "MathJax_Hover_Arrow", isMathJax: true, math: math, + 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; + frame.style.marginRight = button.style.marginRight = "-"+bbox.width; + frame.firstChild.style.width = bbox.width; + button.firstChild.style.left = ""; + button.firstChild.style.right = this.Px(CONFIG.button.wx); + } + // + // Add the frame and button + // + span.parentNode.insertBefore(frame,span); + if (show) {span.parentNode.insertBefore(button,span)} + if (span.style) {span.style.position = "relative"} // so math is on top of hover frame + // + // Start the hover fade-in + // + this.ReHover(jax); + }, + // + // Restart the hover fade in and fade-out timers + // + ReHover: function (jax) { + if (jax.hover.remove) {clearTimeout(jax.hover.remove)} + jax.hover.remove = setTimeout(CALLBACK(["UnHover",this,jax]),CONFIG.fadeoutDelay); + this.HoverFadeTimer(jax,CONFIG.fadeinInc); + }, + // + // Start the fade-out + // + UnHover: function (jax) { + if (!jax.hover.nofade) {this.HoverFadeTimer(jax,-CONFIG.fadeoutInc,CONFIG.fadeoutStart)} + }, + // + // Handle the fade-in and fade-out + // + HoverFade: function (jax) { + delete jax.hover.timer; + jax.hover.opacity = Math.max(0,Math.min(1,jax.hover.opacity + jax.hover.inc)); + jax.hover.opacity = Math.floor(1000*jax.hover.opacity)/1000; + var frame = document.getElementById(jax.hover.id), + button = document.getElementById(jax.hover.id+"Menu"); + frame.firstChild.style.opacity = jax.hover.opacity; + frame.firstChild.style.filter = "alpha(opacity="+Math.floor(100*jax.hover.opacity)+")"; + if (button) { + button.firstChild.style.opacity = jax.hover.opacity; + button.firstChild.style.filter = frame.style.filter; + } + if (jax.hover.opacity === 1) {return} + if (jax.hover.opacity > 0) {this.HoverFadeTimer(jax,jax.hover.inc); return} + frame.parentNode.removeChild(frame); + if (button) {button.parentNode.removeChild(button)} + if (jax.hover.remove) {clearTimeout(jax.hover.remove)} + delete jax.hover; + }, + // + // Set the fade to in or out (via inc) and start the timer, if needed + // + HoverFadeTimer: function (jax,inc,delay) { + jax.hover.inc = inc; + if (!jax.hover.timer) { + jax.hover.timer = setTimeout(CALLBACK(["HoverFade",this,jax]),(delay||CONFIG.fadeDelay)); + } + }, + + // + // Handle a click on the menu button + // + HoverMenu: function (event) { + if (!event) {event = window.event} + return OUTPUT[this.jax].ContextMenu(event,this.math,true); + }, + + // + // Clear all hover timers + // + ClearHover: function (jax) { + if (jax.hover.remove) {clearTimeout(jax.hover.remove)} + if (jax.hover.timer) {clearTimeout(jax.hover.timer)} + HOVER.ClearHoverTimer(); + delete jax.hover; + }, + + // + // Make a measurement in pixels + // + Px: function (m) { + if (Math.abs(m) < .006) {return "0px"} + return m.toFixed(2).replace(/\.?0+$/,"") + "px"; + }, + + // + // Preload images so they show up with the menu + // + getImages: function () { + if (SETTINGS.discoverable) { + var menu = new Image(); + menu.src = CONFIG.button.src; + } + } + + }; + + // + // Handle touch events. + // + // Use double-tap-and-hold as a replacement for context menu event. + // Use double-tap as a replacement for double click. + // + var TOUCH = ME.Touch = { + + 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.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 + // 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; 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; 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; + * } + */ + + // + // Set up browser-specific values + // + HUB.Browser.Select({ + MSIE: function (browser) { + var mode = (document.documentMode || 0); + var isIE8 = browser.versionAtLeast("8.0"); + ME.msieBorderWidthBug = (document.compatMode === "BackCompat"); // borders are inside offsetWidth/Height + ME.msieEventBug = browser.isIE9; // must get event from window even though event is passed + ME.msieAlignBug = (!isIE8 || mode < 8); // inline-block spans don't rest on baseline + if (mode < 9) {EVENT.LEFTBUTTON = 1} // IE < 9 has wrong event.button values + }, + Safari: function (browser) { + ME.safariContextMenuBug = true; // selection can be started by contextmenu event + }, + Opera: function (browser) { + ME.operaPositionBug = true; // position is wrong unless border is used + }, + Konqueror: function (browser) { + ME.noContextMenuBug = true; // doesn't produce contextmenu event + } + }); + + // + // Used in measuring zoom and hover positions + // + ME.topImg = (ME.msieAlignBug ? + HTML.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}) : + HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}}) + ); + if (ME.operaPositionBug) {ME.topImg.style.border="1px solid"} + + // + // Get configuration from user + // + ME.config = CONFIG = HUB.CombineConfig("MathEvents",CONFIG); + var SETFRAME = function () { + var haze = CONFIG.styles[".MathJax_Hover_Frame"]; + haze.border = CONFIG.frame.bwidth+"px solid "+CONFIG.frame.bcolor+" ! important"; + haze["box-shadow"] = haze["-webkit-box-shadow"] = + haze["-moz-box-shadow"] = haze["-khtml-box-shadow"] = + "0px 0px "+CONFIG.frame.hwidth+" "+CONFIG.frame.hcolor; + }; + + // + // Queue the events needed for startup + // + CALLBACK.Queue( + HUB.Register.StartupHook("End Config",{}), // wait until config is complete + [SETFRAME], + ["getImages",HOVER], + ["Styles",AJAX,CONFIG.styles], + ["Post",HUB.Startup.signal,"MathEvents Ready"], + ["loadComplete",AJAX,"[MathJax]/extensions/MathEvents.js"] + ); + +})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback, + MathJax.Localization,MathJax.OutputJax,MathJax.InputJax); +// @license-end diff --git a/js/mathjax/extensions/MathML/content-mathml.js b/js/mathjax/extensions/MathML/content-mathml.js new file mode 100644 index 0000000..250ce43 --- /dev/null +++ b/js/mathjax/extensions/MathML/content-mathml.js @@ -0,0 +1,1745 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9", + 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; jn instead of -n + // + element.appendChild(document.createTextNode(textContent.substr(1))); + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u2212'); + mrow.appendChild(element); + element = mrow; + } else { + element.appendChild(document.createTextNode(textContent)); + } + parentNode.appendChild(element); + return element; + }, + + /* Transform a Content MathML node to Presentation MathML node(s), and attach it to the parent + */ + applyTransform: function(parentNode,contentMMLNode,precedence) { + if (!contentMMLNode) { + var merror = CToP.createElement('merror'); + CToP.appendToken(merror,'mtext','Missing child node'); + parentNode.appendChild(merror); + return; + } + var nodeName = contentMMLNode.nodeName.replace(/.*:/,''); + if (contentMMLNode.nodeType === 1) { + if (CToP.tokens[nodeName]) { + CToP.tokens[nodeName](parentNode,contentMMLNode,precedence); + } else if (contentMMLNode.childNodes.length === 0) { + var mml = CToP.MML[nodeName]; + if (mml && mml.isa && mml.isa(CToP.mbase)) { + parentNode.appendChild(CToP.cloneNode(contentMMLNode)); + } else { + CToP.appendToken(parentNode,'mi',nodeName); + } + } else { + var clonedChild = CToP.cloneNode(contentMMLNode); + parentNode.appendChild(clonedChild); + for (var j = 0, l = contentMMLNode.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'); + children[1].textContent = -n; // OK to change MathML since it is being discarded afterward + 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"); +// @license-end diff --git a/js/mathjax/extensions/MathMenu.js b/js/mathjax/extensions/MathMenu.js new file mode 100644 index 0000000..48b1244 --- /dev/null +++ b/js/mathjax/extensions/MathMenu.js @@ -0,0 +1,1666 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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,CALLBACK,OUTPUT) { + var VERSION = "2.7.9"; + + 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 isArray = MathJax.Object.isArray; + + 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 + + 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: 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", + 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":"nowrap", "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_About.MathJax_MousePost": { + outline:"none" + }, + + ".MathJax_Menu": { + position:"absolute", "background-color":"white", color:"black", + width:"auto", padding:(isPC ? "2px" : "5px 0px"), + border:"1px solid #CCCCCC", margin:0, cursor:"default", + font: "menu", "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", "z-index":201, + + "border-radius": ROUND, // Opera 10.5 and IE9 + "-webkit-border-radius": ROUND, // Safari and Chrome + "-moz-border-radius": ROUND, // Firefox + "-khtml-border-radius": ROUND, // 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_MenuItem": { + padding: (isPC ? "2px 2em" : "1px 2em"), + background:"transparent" + }, + + ".MathJax_MenuArrow": { + 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_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, 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 = 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,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.Element("div",{ + onmouseup: MENU.Mouseup, ondblclick: FALSE, + ondragstart: FALSE, onselectstart: FALSE, oncontextmenu: FALSE, + 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_MenuClose", menu: parent, + ontouchstart: MENU.Close, ontouchend: FALSE, onmousedown: MENU.Close, onmouseup: FALSE + },[["span",{},"\u00D7"]]); + } + + div.appendChild(menu); + this.posted = true; + if (menu.offsetWidth) menu.style.width = (menu.offsetWidth+2) + "px"; + var x = event.pageX, y = event.pageY; + var bbox = document.body.getBoundingClientRect(); + var styles = (window.getComputedStyle ? window.getComputedStyle(document.body) : {marginLeft: "0px"}); + var bodyRight = bbox.right - Math.min(0,bbox.left) + parseFloat(styles.marginLeft); + 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 > bodyRight - this.margin) + {x = bodyRight - menu.offsetWidth - this.margin} + if (MENU.isMobile) {x = Math.max(5,x-Math.floor(menu.offsetWidth/2)); y -= 20} + MENU.skipUp = event.isContextMenu; + } else { + var side = "left", mw = parent.offsetWidth; + x = (MENU.isMobile ? 30 : mw - 2); y = 0; + while (parent && parent !== div) { + x += parent.offsetLeft; y += parent.offsetTop; + parent = parent.parentNode; + } + if (!MENU.isMobile) { + if ((MENU.isRTL && x - mw - menu.offsetWidth > this.margin) || + (!MENU.isRTL && x + menu.offsetWidth > bodyRight - 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 + menu.style["WebkitBorderRadiusTop"+side] = 0; // Safari and Chrome + menu.style["MozBorderRadiusTop"+side] = 0; // Firefox + 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); + }, + + /* + * Remove the menu from the screen + */ + Remove: function (event,menu) { + SIGNAL.Post(["unpost",MENU.jax]); + var div = document.getElementById("MathJax_MenuFrame"); + if (div) { + div.parentNode.removeChild(div); + if (this.msieFixedPositionBug) {detachEvent("onresize",MENU.Resize)} + } + if (MENU.jax.hover) { + delete MENU.jax.hover.nofade; + HOVER.UnHover(MENU.jax); + } + MENU.Unfocus(menu); + if (event.type === "mousedown") MENU.CurrentNode().blur(); + return FALSE(event); + }, + + /* + * 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) {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[n] === name) { + if (names.length) { + 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) {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[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, + + 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" || + (type === "Mousedown" && !MENU.skipMousedown)) {delete MENU.skipUp} + } + if (!event) {event = window.event} + var item = menu.menuItem; + if (item && item[type]) {return item[type](event,menu)} + return null; + }, + /* + * Style for the background DIV + */ + BGSTYLE: { + position:"absolute", left:0, top:0, "z-index":200, + width:"100%", height:"100%", border:0, padding:0, margin:0 + }, + + Background: function (menu) { + 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) { + // 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) { + // 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(); + attachEvent("onresize",this.Resize); + } else { + // otherwise, use a fixed position DIV to cover the viewport + bg.style.position = "fixed"; + } + return div; + }, + Resize: function () {setTimeout(MENU.SetWH,0)}, + SetWH: function () { + var bg = document.getElementById("MathJax_MenuFrame"); + if (bg) { + bg = bg.firstChild; + bg.style.width = bg.style.height = "1px"; // so scrollWidth/Height will be right below + bg.style.width = document.body.scrollWidth + "px"; + 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) { + MENU.UnsetTabIndex(); + MENU.posted = true; + }, + Unfocus: function() { + MENU.ActiveNode().tabIndex = -1; + MENU.SetTabIndex(); + 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;}); + }, + UnsetTabIndex: function () { + var jaxs = MENU.AllNodes(); + for (var j = 0, jax; jax = jaxs[j]; j++) { + if (jax.tabIndex > 0) { + jax.oldTabIndex = jax.tabIndex; + } + jax.tabIndex = -1; + } + }, + SetTabIndex: function () { + var jaxs = MENU.AllNodes(); + for (var j = 0, jax; jax = jaxs[j]; j++) { + if (jax.oldTabIndex !== undefined) { + jax.tabIndex = jax.oldTabIndex + delete jax.oldTabIndex; + } else { + jax.tabIndex = HUB.getTabOrder(jax); + } + } + }, + + //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")} + + }); + + MathJax.Menu.NAV = NAV; + + /*************************************************************/ + /* + * Abstract class of menu items. + */ + 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 = 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--; + } + }, + + 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) { + if (this !== ITEM.lastItem) { + if (ITEM.lastMenu) {MENU.Event(event,ITEM.lastMenu,"Mouseout")} + MENU.Event(event,menu,"Mouseover",true); + ITEM.lastItem = this; ITEM.lastMenu = menu; + } + if (this.nativeTouch) {return null} + MENU.Event(event,menu,type); + return false; + }, + + Remove: function (event,menu) { + menu = menu.parentNode.menuItem; + return menu.Remove(event,menu); + }, + + 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/,""); + } + + }); + + /*************************************************************/ + /* + * A menu item that performs a command when selected + */ + MENU.ITEM.COMMAND = MENU.ENTRY.Subclass({ + action: function () {}, + + Init: function (name,action,def) { + if (!isArray(name)) {name = [name,name]} // make [id,label] pair + this.name = name; this.action = action; + this.With(def); + }, + + Label: function (def,menu) {return [this.Name()]}, + Mouseup: function (event,menu) { + if (!this.disabled) { + this.Remove(event,menu); + SIGNAL.Post(["command",this]); + this.action.call(this,event); + } + return FALSE(event); + } + }); + + /*************************************************************/ + /* + * A menu item that posts a submenu + */ + 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 (!isArray(name)) {name = [name,name]} // make [id,label] pair + this.name = name; var i = 1; + if (!(def instanceof MENU.ITEM)) {this.With(def), i++} + this.submenu = MENU.apply(MENU,[].slice.call(arguments,i)); + }, + Label: function (def,menu) { + this.submenu.posted = false; + return [this.Name()+" ",["span",{ + className:"MathJax_MenuArrow" + this.rtlClass() + },[this.isRTL() ? this.markerRTL : this.marker]]]; + }, + Timer: function (event,menu) { + 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.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.submenu.posted) { + this.ClearTimer(); + this.submenu.Post(event, menu, this.ltr); + MENU.Focus(menu); + } else { + 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]); + } + } + }); + + /*************************************************************/ + /* + * A menu item that is one of several radio buttons + */ + 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 (!isArray(name)) {name = [name,name]} // make [id,label] pair + this.name = name; this.variable = variable; this.With(def); + if (this.value == null) {this.value = this.name[0]} + }, + Label: function (def,menu) { + 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"; + } + } + menu.firstChild.display = ""; + CONFIG.settings[this.variable] = this.value; + MENU.cookie[this.variable] = CONFIG.settings[this.variable]; MENU.saveCookie(); + SIGNAL.Post(["radio button",this]); + } + this.Remove(event,menu); + if (this.action && !this.disabled) {this.action.call(MENU,this)} + return FALSE(event); + } + }); + + /*************************************************************/ + /* + * A menu item that is checkable + */ + 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 (!isArray(name)) {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" + this.rtlClass()}; + if (!CONFIG.settings[this.variable]) {span = {style:{display:"none"}}} + return [["span",span,[this.marker]]," "+this.Name()]; + }, + Mouseup: function (event,menu) { + if (!this.disabled) { + menu.firstChild.display = (CONFIG.settings[this.variable] ? "none" : ""); + CONFIG.settings[this.variable] = !CONFIG.settings[this.variable]; + MENU.cookie[this.variable] = CONFIG.settings[this.variable]; MENU.saveCookie(); + SIGNAL.Post(["checkbox",this]); + } + this.Remove(event,menu); + if (this.action && !this.disabled) {this.action.call(MENU,this)} + return FALSE(event); + } + }); + + /*************************************************************/ + /* + * A menu item that is a label + */ + MENU.ITEM.LABEL = MENU.ENTRY.Subclass({ + role: "menuitem", // Aria role. + + Init: function (name,def) { + if (!isArray(name)) {name = [name,name]} // make [id,label] pair + this.name = name; this.With(def); + }, + Label: function (def,menu) { + def.className += " MathJax_MenuLabel"; + return [this.Name()]; + }, + Activate: function(event, menu) { + this.Deactivate(menu); + MENU.Focus(menu); + }, + Mouseup: function (event,menu) { } + }); + + /*************************************************************/ + /* + * 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) { + def.className += " MathJax_MenuRule"; + return null; + } + }); + + /*************************************************************/ + /*************************************************************/ + + /* + * Handle the ABOUT box + */ + 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,["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","%1 Extension v%2"],true); + jax.push(["div",{style:{"border-top":"groove 2px",margin:".25em 0"}}],["center",{},[ + 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", tabIndex: 0, onkeydown: MENU.About.Keydown + },[ + ["b",{style:{fontSize:"120%"}},["MathJax"]]," v"+MathJax.version,["br"], + _(font.replace(/ /g,""),"using "+font),["br"],["br"], + ["span",{style:{ + display:"inline-block", "text-align":"left", "font-size":"80%", + "max-height":"20em", overflow:"auto", + "background-color":"#E4E4E4", padding:".4em .6em", border:"1px inset" + }, 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) { + about.style.width = "20em"; about.style.position = "absolute"; + about.style.left = Math.floor((document.documentElement.scrollWidth - about.offsetWidth)/2)+"px"; + about.style.top = (Math.floor((H-about.offsetHeight)/3)+document.body.scrollTop)+"px"; + } else { + about.style.marginLeft = Math.floor(-about.offsetWidth/2)+"px"; + about.style.top = Math.floor((H-about.offsetHeight)/3)+"px"; + } + }; + 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(_(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 (event) { + AJAX.Require("[MathJax]/extensions/HelpDialog.js", + function () {MathJax.Extension.Help.Dialog({type:event.type})}); + }; + + /* + * Handle showing of element's source + */ + MENU.ShowSource = function (event) { + if (!event) {event = window.event} + var EVENT = {screenX:event.screenX, screenY:event.screenY}; + if (!MENU.jax) return; + if (this.format === "MathML") { + 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("",MENU.jax),event)} catch (err) { + if (!err.restart) {throw err} + CALLBACK.After([this,MENU.ShowSource,EVENT],err.restart); + } + } else if (!AJAX.loadingToMathML) { + AJAX.loadingToMathML = true; + MENU.ShowSource.Window(event); // WeBKit needs to open window on click event + CALLBACK.Queue( + AJAX.Require("[MathJax]/extensions/toMathML.js"), + function () { + delete AJAX.loadingToMathML; + if (!MML.mbase.prototype.toMathML) {MML.mbase.prototype.toMathML = function () {}} + }, + [this,MENU.ShowSource,EVENT] // call this function again + ); + 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(_("NoOriginalForm","No original form available")); + return; + } + MENU.ShowSource.Text(MENU.jax.originalText,event); + } + }; + MENU.ShowSource.Window = function (event) { + if (!MENU.ShowSource.w) { + var def = [], DEF = CONFIG.windowSettings; + for (var id in DEF) {if (DEF.hasOwnProperty(id)) {def.push(id+"="+DEF[id])}} + MENU.ShowSource.w = window.open("","_blank",def.join(",")); + } + return MENU.ShowSource.w; + }; + MENU.ShowSource.Text = function (text,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(""+title+""); + w.document.write("
"+text+"
"); + w.document.write("
"); + w.document.write(""); + w.document.close(); + } else { + w.document.open(); + w.document.write(""+title+""); + w.document.write("
"+text+"
"); + w.document.write(""); + w.document.close(); + var table = w.document.body.firstChild; + 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); + } + }; + + /* + * Handle rescaling all the math + */ + MENU.Scale = function () { + 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+(\.\d*)?\s*%?\s*$/)) { + scale = parseFloat(scale); + if (scale) { + if (scale !== SCALE) { + 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(_("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 + */ + MENU.Renderer = function () { + var jax = HUB.outputJax["jax/mml"]; + if (jax[0] !== CONFIG.settings.renderer) { + var BROWSER = HUB.Browser, message, MESSAGE = MENU.Renderer.Messages, warned; + // + // Check that the new renderer is appropriate for the browser + // + switch (CONFIG.settings.renderer) { + case "NativeMML": + if (!CONFIG.settings.warnedMML) { + 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"; + } + break; + + case "SVG": + if (!CONFIG.settings.warnedSVG) { + if (BROWSER.isMSIE && !isIE9) {message = MESSAGE.SVG.MSIE} + } + break; + } + if (message) { + 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( + ["setRenderer",HUB,CONFIG.settings.renderer,"jax/mml"], + ["Rerender",HUB] + ); + } + }; + MENU.Renderer.Messages = { + MML: { + 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: ["MSIENativeMMLWarning", + "Internet Explorer requires the MathPlayer plugin " + + "in order to process MathML output."], + + 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: ["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."] + } + }; + + /* + * Toggle assistive MML settings + */ + 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 + */ + MENU.Font = function () { + 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 + */ + MENU.MPEvents = function (item) { + var discoverable = CONFIG.settings.discoverable, + MESSAGE = MENU.MPEvents.Messages; + if (!isIE9) { + 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(); + return; + } + CONFIG.settings.mpContext = CONFIG.settings.mpMouse; + MENU.cookie.mpContext = MENU.cookie.mpMouse = CONFIG.settings.mpMouse; + MENU.saveCookie(); + MathJax.Hub.Queue(["Rerender",MathJax.Hub]) + } else if (!discoverable && item.name[1] === "Menu Events" && CONFIG.settings.mpContext) { + alert(_.apply(_,MESSAGE.IE9warning)); + } + }; + + MENU.MPEvents.Messages = { + 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?"], + + IE9warning: ["IE9warning", + "The MathJax contextual menu will be disabled, but you can " + + "Alt-Click on an expression to obtain the MathJax menu instead."] + }; + + /*************************************************************/ + /*************************************************************/ + + HUB.Browser.Select({ + MSIE: function (browser) { + var quirks = (document.compatMode === "BackCompat"); + var isIE8 = browser.versionAtLeast("8.0") && document.documentMode > 7; + MENU.Augment({ + margin: 20, + msieBackgroundBug: ((document.documentMode||0) < 9), + msieFixedPositionBug: (quirks || !isIE8), + 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; + delete CONFIG.styles[".MathJax_Menu"].filter; + } + }, + Firefox: function (browser) { + MENU.skipMouseover = browser.isMobile && browser.versionAtLeast("6.0"); + MENU.skipMousedown = browser.isMobile; + } + }); + MENU.isMobile = HUB.Browser.isMobile; + MENU.noContextMenu = HUB.Browser.noContextMenu; + + /*************************************************************/ + + // + // 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 () { + + /* + * Get the menu settings from the HUB (which includes the + * data from the cookie already), and add the format, if + * it wasn't set in the cookie. + */ + CONFIG.settings = HUB.config.menuSettings; + if (typeof(CONFIG.settings.showRenderer) !== "undefined") {CONFIG.showRenderer = CONFIG.settings.showRenderer} + if (typeof(CONFIG.settings.showFontMenu) !== "undefined") {CONFIG.showFontMenu = CONFIG.settings.showFontMenu} + if (typeof(CONFIG.settings.showContext) !== "undefined") {CONFIG.showContext = CONFIG.settings.showContext} + MENU.getCookie(); + + /* + * The main menu + */ + // Localization: items used as key, should be refactored. + MENU.menu = MENU( + 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(["texHints","Show TeX hints in MathML"], "texHints"), + ITEM.CHECKBOX(["semantics","Add original form as annotation"], "semantics") + ), + ITEM.RULE(), + 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(["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(["ZoomFactor","Zoom Factor"], + ITEM.RADIO("125%", "zscale"), + ITEM.RADIO("133%", "zscale"), + ITEM.RADIO("150%", "zscale"), + ITEM.RADIO("175%", "zscale"), + ITEM.RADIO("200%", "zscale"), + ITEM.RADIO("250%", "zscale"), + ITEM.RADIO("300%", "zscale"), + ITEM.RADIO("400%", "zscale") + ), + ITEM.RULE(), + ITEM.SUBMENU(["Renderer","Math Renderer"], {hidden:!CONFIG.showRenderer}, + ITEM.RADIO(["HTML-CSS","HTML-CSS"], "renderer", {action: MENU.Renderer}), + ITEM.RADIO(["CommonHTML","Common HTML"], "renderer", {action: MENU.Renderer, value:"CommonHTML"}), + ITEM.RADIO(["PreviewHTML","Preview HTML"],"renderer", {action: MENU.Renderer, value:"PreviewHTML"}), + ITEM.RADIO(["MathML","MathML"], "renderer", {action: MENU.Renderer, value:"NativeMML"}), + ITEM.RADIO(["SVG","SVG"], "renderer", {action: MENU.Renderer}), + ITEM.RADIO(["PlainSource","Plain Source"],"renderer", {action: MENU.Renderer, value:"PlainSource"}), + ITEM.RULE(), + ITEM.CHECKBOX(["FastPreview","Fast Preview"], "FastPreview") + ), + 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","MathJax"], "context"), + ITEM.RADIO(["Browser","Browser"], "context") + ), + 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(["Accessibility","Accessibility"], + ITEM.CHECKBOX(["AssistiveMML","Assistive MathML"], "assistiveMML", {action:MENU.AssistiveMML}), + ITEM.CHECKBOX(["InTabOrder","Include in Tab Order"], "inTabOrder") + ), + 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","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").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) { + MENU.cookie.showRenderer = CONFIG.showRenderer = show; MENU.saveCookie(); + MENU.menu.Find("Math Settings","Math Renderer").hidden = !show; + }; + MENU.showMathPlayer = function (show) { + MENU.cookie.showMathPlayer = CONFIG.showMathPlayer = show; MENU.saveCookie(); + MENU.menu.Find("Math Settings","MathPlayer").hidden = !show; + }; + MENU.showFontMenu = function (show) { + MENU.cookie.showFontMenu = CONFIG.showFontMenu = show; MENU.saveCookie(); + MENU.menu.Find("Math Settings","Font Preference").hidden = !show; + }; + MENU.showContext = function (show) { + MENU.cookie.showContext = CONFIG.showContext = show; MENU.saveCookie(); + MENU.menu.Find("Math Settings","Contextual Menu").hidden = !show; + }; + MENU.showDiscoverable = function (show) { + 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 + ["Styles",AJAX,CONFIG.styles], + ["Post",HUB.Startup.signal,"MathMenu Ready"], + ["loadComplete",AJAX,"[MathJax]/extensions/MathMenu.js"] + ); + +})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.CallBack,MathJax.OutputJax); +// @license-end diff --git a/js/mathjax/extensions/MathZoom.js b/js/mathjax/extensions/MathZoom.js new file mode 100644 index 0000000..610746d --- /dev/null +++ b/js/mathjax/extensions/MathZoom.js @@ -0,0 +1,368 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/MathZoom.js + * + * Implements the zoom feature for enlarging math expressions. It is + * loaded automatically when the Zoom menu selection changes from "None". + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 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,HTMLCSS,nMML) { + var VERSION = "2.7.9"; + + var CONFIG = HUB.CombineConfig("MathZoom",{ + styles: { + // + // The styles for the MathZoom display box + // + "#MathJax_Zoom": { + position:"absolute", "background-color":"#F0F0F0", overflow:"auto", + display:"block", "z-index":301, padding:".5em", border:"1px solid black", margin:0, + "font-weight":"normal", "font-style":"normal", + "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 + "-khtml-box-shadow":"5px 5px 15px #AAAAAA", // Konqueror + filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')" // IE + }, + + // + // The styles for the hidden overlay (should not need to be adjusted by the page author) + // + "#MathJax_ZoomOverlay": { + position:"absolute", left:0, top:0, "z-index":300, display:"inline-block", + width:"100%", height:"100%", border:0, padding:0, margin:0, + "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, + "background-color":"white", opacity:0, filter:"alpha(opacity=0)" + } + } + }); + + var FALSE, HOVER, EVENT; + MathJax.Hub.Register.StartupHook("MathEvents Ready",function () { + EVENT = MathJax.Extension.MathEvents.Event; + FALSE = MathJax.Extension.MathEvents.Event.False; + HOVER = MathJax.Extension.MathEvents.Hover; + }); + + /*************************************************************/ + + var ZOOM = MathJax.Extension.MathZoom = { + version: VERSION, + settings: HUB.config.menuSettings, + scrollSize: 18, // width of scrool bars + + // + // Process events passed from output jax + // + HandleEvent: function (event,type,math) { + if (ZOOM.settings.CTRL && !event.ctrlKey) return true; + if (ZOOM.settings.ALT && !event.altKey) return true; + if (ZOOM.settings.CMD && !event.metaKey) return true; + if (ZOOM.settings.Shift && !event.shiftKey) return true; + if (!ZOOM[type]) return true; + return ZOOM[type](event,math); + }, + + // + // Zoom on click + // + Click: function (event,math) { + if (this.settings.zoom === "Click") {return this.Zoom(event,math)} + }, + + // + // Zoom on double click + // + DblClick: function (event,math) { + if (this.settings.zoom === "Double-Click" || this.settings.zoom === "DoubleClick") {return this.Zoom(event,math)} + }, + + // + // Zoom on hover (called by MathEvents.Hover) + // + Hover: function (event,math) { + if (this.settings.zoom === "Hover") {this.Zoom(event,math); return true} + return false; + }, + + + // + // Handle the actual zooming + // + Zoom: function (event,math) { + // + // Remove any other zoom and clear timers + // + this.Remove(); HOVER.ClearHoverTimer(); EVENT.ClearSelection(); + + // + // Find the jax + // + var JAX = MathJax.OutputJax[math.jaxID]; + var jax = JAX.getJaxFromMath(math); + if (jax.hover) {HOVER.UnHover(jax)} + + // + // Create the DOM elements for the zoom box + // + 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",{id:"MathJax_ZoomFrame"},[ + ["span",{id:"MathJax_ZoomOverlay", onmousedown:this.Remove}], + ["span",{ + id:"MathJax_Zoom", onclick:this.Remove, + 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(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); + } + + // + // Display the zoomed math + // + if (this.msieZIndexBug) { + // MSIE doesn't do z-index properly, so move the div to the document.body, + // and use an image as a tracker for the usual position + var tracker = HTML.addElement(document.body,"img",{ + src:"about:blank", id:"MathJax_ZoomTracker", width:0, height:0, + style:{width:0, height:0, position:"relative"} + }); + div.style.position = "relative"; + div.style.zIndex = CONFIG.styles["#MathJax_ZoomOverlay"]["z-index"]; + div = tracker; + } + + var bbox = JAX.Zoom(jax,span,math,Mw,Mh); + + // + // Fix up size and position for browsers with bugs (IE) + // + if (this.msiePositionBug) { + if (this.msieSizeBug) + {zoom.style.height = bbox.zH+"px"; zoom.style.width = bbox.zW+"px"} // IE8 gets the dimensions completely wrong + if (zoom.offsetHeight > Mh) {zoom.style.height = Mh+"px"; zoom.style.width = (bbox.zW+this.scrollSize)+"px"} // IE doesn't do max-height? + 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 > 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"; + trap.style.left = (parseFloat(zoom.style.left)+zoom.clientLeft)+"px"; + trap.style.top = (parseFloat(zoom.style.top)+zoom.clientTop)+"px"; + } + zoom.style.visibility = ""; + + // + // Add event handlers + // + if (this.settings.zoom === "Hover") {overlay.onmouseover = this.Remove} + if (window.addEventListener) {addEventListener("resize",this.Resize,false)} + else if (window.attachEvent) {attachEvent("onresize",this.Resize)} + else {this.onresize = window.onresize; window.onresize = this.Resize} + + // + // Let others know about the zoomed math + // + HUB.signal.Post(["math zoomed",jax]); + + // + // Canel further actions + // + return FALSE(event); + }, + + // + // 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; + 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 + }, + + // + // Handle resizing of overlay while zoom is displayed + // + Resize: function (event) { + if (ZOOM.onresize) {ZOOM.onresize(event)} + 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 = ""} + return {x:x, y:y}; + }, + + // + // Remove zoom display and event handlers + // + Remove: function (event) { + var div = document.getElementById("MathJax_ZoomFrame"); + if (div) { + 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"); + if (div) {div.parentNode.removeChild(div)} + if (ZOOM.operaRefreshBug) { + // force a redisplay of the page + // (Opera doesn't refresh properly after the zoom is removed) + var overlay = HTML.addElement(document.body,"div",{ + style:{position:"fixed", left:0, top:0, width:"100%", height:"100%", + backgroundColor:"white", opacity:0}, + id: "MathJax_OperaDiv" + }); + document.body.removeChild(overlay); + } + if (window.removeEventListener) {removeEventListener("resize",ZOOM.Resize,false)} + else if (window.detachEvent) {detachEvent("onresize",ZOOM.Resize)} + else {window.onresize = ZOOM.onresize; delete ZOOM.onresize} + } + return FALSE(event); + } + + }; + + + /*************************************************************/ + + HUB.Browser.Select({ + MSIE: function (browser) { + var mode = (document.documentMode || 0); + var isIE9 = (mode >= 9); + ZOOM.msiePositionBug = !isIE9; + ZOOM.msieSizeBug = browser.versionAtLeast("7.0") && + (!document.documentMode || mode === 7 || mode === 8); + ZOOM.msieZIndexBug = (mode <= 7); + ZOOM.msieInlineBlockAlignBug = (mode <= 7); + ZOOM.msieTrapEventBug = !window.addEventListener; + if (document.compatMode === "BackCompat") {ZOOM.scrollSize = 52} // don't know why this is so far off + if (isIE9) {delete CONFIG.styles["#MathJax_Zoom"].filter} + }, + + Opera: function (browser) { + ZOOM.operaPositionBug = true; + ZOOM.operaRefreshBug = true; + } + }); + + ZOOM.topImg = (ZOOM.msieInlineBlockAlignBug ? + HTML.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}) : + HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}}) + ); + if (ZOOM.operaPositionBug || ZOOM.msieTopBug) {ZOOM.topImg.style.border="1px solid"} + + /*************************************************************/ + + MathJax.Callback.Queue( + ["StartupHook",MathJax.Hub.Register,"Begin Styles",{}], + ["Styles",AJAX,CONFIG.styles], + ["Post",HUB.Startup.signal,"MathZoom Ready"], + ["loadComplete",AJAX,"[MathJax]/extensions/MathZoom.js"] + ); + +})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.OutputJax["HTML-CSS"],MathJax.OutputJax.NativeMML); +// @license-end diff --git a/js/mathjax/extensions/Safe.js b/js/mathjax/extensions/Safe.js new file mode 100644 index 0000000..8b77af4 --- /dev/null +++ b/js/mathjax/extensions/Safe.js @@ -0,0 +1,430 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9"; + + 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 + lengthMax: 3, // largest padding/border/margin, etc. in em's + 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 + }, + // + // CSS styles that have Top/Right/Bottom/Left versions + // + styleParts: { + border: true, + padding: true, + margin: true, + outline: true + }, + // + // CSS styles that are lengths needing max/min testing + // A string value means test that style value; + // An array gives [min,max] in em's + // Otherwise use [-lengthMax,lengthMax] from above + // + styleLengths: { + borderTop: "borderTopWidth", + borderRight: "borderRightWidth", + borderBottom: "borderBottomWidth", + borderLeft: "borderLeftWidth", + paddingTop: true, + paddingRight: true, + paddingBottom: true, + paddingLeft: true, + marginTop: true, + marginRight: true, + marginBottom: true, + marginLeft: true, + outlineTop: true, + outlineRight: true, + outlineBottom: true, + outlineLeft: true, + fontSize: [.7,1.44] + } + }); + + 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, value; + STYLE1.cssText = styles; STYLE2.cssText = ""; + // + // Check each allowed style and transfer OK ones to div2 + // If the style has Top/Right/Bottom/Left, look at all four separately + // + for (var name in CONFIG.safeStyles) {if (CONFIG.safeStyles.hasOwnProperty(name)) { + if (CONFIG.styleParts[name]) { + for (var i = 0; i < 4; i++) { + var NAME = name+["Top","Right","Bottom","Left"][i] + value = this.filterStyle(NAME,STYLE1); + if (value) {STYLE2[NAME] = value} + } + } else { + value = this.filterStyle(name,STYLE1); + if (value) {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,styles) { + var value = styles[name]; + if (typeof value !== "string" || value === "") {return null} + if (value.match(/^\s*expression/)) {return null} + if (value.match(/javascript:/)) {return null} + var NAME = name.replace(/Top|Right|Left|Bottom/,""); + if (!CONFIG.safeStyles[name] && !CONFIG.safeStyles[NAME]) {return null} + if (!CONFIG.styleLengths[name]) {return value} + return (this.filterStyleLength(name,value,styles) ? value : null); + }, + filterStyleLength: function (name,value,styles) { + if (typeof CONFIG.styleLengths[name] === "string") value = styles[CONFIG.styleLengths[name]]; + value = this.length2em(value); + if (value == null) return false; + var mM = [-CONFIG.lengthMax,CONFIG.lengthMax]; + if (MathJax.Object.isArray(CONFIG.styleLengths[name])) mM = CONFIG.styleLengths[name]; + return (value >= mM[0] && value <= mM[1]); + }, + // + // Conversion of units to em's + // + unit2em: { + em: 1, + ex: .5, // assume 1ex = .5em + ch: .5, // assume 1ch = .5em + rem: 1, // assume 1rem = 1em + px: 1/16, // assume 1em = 16px + mm: 96/25.4/16, // 25.4mm = 96px + cm: 96/2.54/16, // 2.54cm = 96px + 'in': 96/16, // 1in = 96px + pt: 96/72/16, // 72pt = 1in + pc: 96/6/16 // 1pc = 12pt + }, + length2em: function (value) { + var match = value.match(/(.+)(em|ex|ch|rem|px|mm|cm|in|pt|pc)/); + if (!match) return null; + return parseFloat(match[1])*this.unit2em[match[2]]; + }, + + // + // 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)}, + BBoxPadding: function (pad) { + var styles = SAFE.filterStyles("padding: "+pad); + return (styles ? pad : 0); + } + }); + + }); + + 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); +// @license-end diff --git a/js/mathjax/extensions/TeX/AMScd.js b/js/mathjax/extensions/TeX/AMScd.js new file mode 100644 index 0000000..d6bee02 --- /dev/null +++ b/js/mathjax/extensions/TeX/AMScd.js @@ -0,0 +1,160 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9", + 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"); +// @license-end diff --git a/js/mathjax/extensions/TeX/AMSmath.js b/js/mathjax/extensions/TeX/AMSmath.js new file mode 100644 index 0000000..70d5183 --- /dev/null +++ b/js/mathjax/extensions/TeX/AMSmath.js @@ -0,0 +1,665 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/AMSmath.js + * + * Implements AMS math environments and macros. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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/AMSmath"] = { + version: "2.7.9", + + 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 +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var MML = MathJax.ElementJax.mml, + TEX = MathJax.InputJax.TeX, + AMS = MathJax.Extension["TeX/AMSmath"]; + + var TEXDEF = TEX.Definitions, + STACKITEM = TEX.Stack.Item, + CONFIG = TEX.config.equationNumbers; + + 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(" "); + }; + + // + // Get the URL of the page (for use with formatURL) when there + // is a element on the page. + // + var baseURL = (document.getElementsByTagName("base").length === 0) ? "" : + String(document.location).replace(/#.*$/,""); + + + /******************************************************************************/ + + TEXDEF.Add({ + mathchar0mo: { + iiiint: ['2A0C',{texClass: MML.TEXCLASS.OP}] + }, + + macros: { + mathring: ['Accent','2DA'], // or 0x30A + + nobreakspace: 'Tilde', + negmedspace: ['Spacer',MML.LENGTH.NEGATIVEMEDIUMMATHSPACE], + negthickspace: ['Spacer',MML.LENGTH.NEGATIVETHICKMATHSPACE], + +// 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'], // 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: ['Accent','20DB'], + ddddot: ['Accent','20DC'], + + sideset: ['Macro','\\mathop{\\mathop{\\rlap{\\phantom{#3}}}\\nolimits#1\\!\\mathop{#3}\\nolimits#2}',3], + + boxed: ['Macro','\\fbox{$\\displaystyle{#1}$}',1], + + tag: 'HandleTag', + notag: 'HandleNoTag', + label: 'HandleLabel', + ref: 'HandleRef', + eqref: ['HandleRef',true], + + substack: ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1], + + 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}}}'], + varprojlim: ['Macro','\\mathop{\\underleftarrow{\\mmlToken{mi}{lim}}}'], + + DeclareMathOperator: 'HandleDeclareOp', + operatorname: 'HandleOperatorName', + SkipLimits: 'SkipLimits', + + genfrac: 'Genfrac', + frac: ['Genfrac',"","","",""], + tfrac: ['Genfrac',"","","",1], + dfrac: ['Genfrac',"","","",0], + binom: ['Genfrac',"(",")","0",""], + tbinom: ['Genfrac',"(",")","0",1], + dbinom: ['Genfrac',"(",")","0",0], + + cfrac: 'CFrac', + + shoveleft: ['HandleShove',MML.ALIGN.LEFT], + shoveright: ['HandleShove',MML.ALIGN.RIGHT], + + xrightarrow: ['xArrow',0x2192,5,6], + xleftarrow: ['xArrow',0x2190,7,3] + }, + + environment: { + 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([0])], + gather: ['AMSarray',null,true,true, 'c'], + 'gather*': ['AMSarray',null,false,true, 'c'], + + alignat: ['AlignAt',null,true,true], + 'alignat*': ['AlignAt',null,false,true], + alignedat: ['AlignAt',null,false,false], + + 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.1em",'S',1], + smallmatrix: ['Array',null,null,null,'c',COLS([1/3]),".2em",'S',1], + + 'equation': ['EquationBegin','Equation',true], + '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: { + '\\lvert': ['007C',{texClass:MML.TEXCLASS.OPEN}], + '\\rvert': ['007C',{texClass:MML.TEXCLASS.CLOSE}], + '\\lVert': ['2016',{texClass:MML.TEXCLASS.OPEN}], + '\\rVert': ['2016',{texClass:MML.TEXCLASS.CLOSE}] + } + },null,true); + + + /******************************************************************************/ + + TEX.Parse.Augment({ + + /* + * Add the tag to the environment (to be added to the table row later) + */ + HandleTag: function (name) { + var star = this.GetStar(); + 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(["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) { + if (this.stack.global.tag) {delete this.stack.global.tag} + this.stack.global.notag = true; // prevent auto-tagging + }, + + /* + * Record a label name for a tag + */ + HandleLabel: function (name) { + var global = this.stack.global, label = this.GetArgument(name); + if (label === "") return; + if (!AMS.refUpdate) { + if (global.label) {TEX.Error(["MultipleCommand","Multiple %1",name])} + global.label = label; + 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 + } + }, + + /* + * Handle a label reference + */ + HandleRef: function (name,eqref) { + var label = this.GetArgument(name); + var ref = AMS.labels[label] || AMS.eqlabels[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(ref.id,baseURL), "class":"MathJax_ref" + })); + }, + + /* + * Handle \DeclareMathOperator + */ + HandleDeclareOp: function (name) { + 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); + if (!op.match(/\\text/)) op = op.replace(/\*/g,'\\text{*}').replace(/-/g,'\\text{-}'); + this.setDef(cs, ['Macro', '\\mathop{\\rm '+op+'}'+limits]); + }, + + HandleOperatorName: function (name) { + var limits = (this.GetStar() ? "" : "\\nolimits\\SkipLimits"); + var op = this.trimSpaces(this.GetArgument(name)); + if (!op.match(/\\text/)) 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") { + TEX.Error(["CommandInMultline", + "%1 can only appear within the multline environment",name]); + } + if (top.data.length) { + TEX.Error(["CommandAtTheBeginingOfLine", + "%1 must come at the beginning of the line",name]); + } + top.data.shove = shove; + }, + + /* + * Handle \cfrac + */ + CFrac: function (name) { + var lr = this.trimSpaces(this.GetBrackets(name,"")), + num = this.GetArgument(name), + den = this.GetArgument(name); + 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(["IllegalAlign","Illegal alignment specified in %1",name])} + if (lr) {frac.numalign = frac.denomalign = lr} + this.Push(frac); + }, + + /* + * Implement AMS generalized fraction + */ + Genfrac: function (name,left,right,thick,style) { + 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 = TEX.fixedFence(left,frac.With({texWithDelims:true}),right)} + if (style !== "") { + var STYLE = (["D","T","S","SS"])[style]; + 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} + } + this.Push(frac); + }, + + /* + * Implements multline environment (mostly handled through STACKITEM below) + */ + Multline: function (begin,numbered) { + this.Push(begin); this.checkEqnEnv(); + return STACKITEM.multline(numbered,this.stack).With({ + arraydef: { + displaystyle: true, + rowspacing: ".5em", + width: TEX.config.MultLineWidth, columnwidth:"100%", + side: TEX.config.TagSide, + minlabelspacing: TEX.config.TagIndent + } + }); + }, + + /* + * Handle AMS aligned environments + */ + AMSarray: function (begin,numbered,taggable,align,spacing) { + this.Push(begin); if (taggable) {this.checkEqnEnv()} + align = align.replace(/[^clr]/g,'').split('').join(' '); + align = align.replace(/l/g,'left').replace(/r/g,'right').replace(/c/g,'center'); + return STACKITEM.AMSarray(begin.name,numbered,taggable,this.stack).With({ + arraydef: { + displaystyle: true, + rowspacing: ".5em", + columnalign: align, + columnspacing: (spacing||"1em"), + rowspacing: "3pt", + side: TEX.config.TagSide, + minlabelspacing: TEX.config.TagIndent + } + }); + }, + + AlignedAMSArray: function (begin) { + var align = this.GetBrackets("\\begin{"+begin.name+"}"); + return this.setArrayAlign(this.AMSarray.apply(this,arguments),align); + }, + + /* + * Handle alignat environments + */ + AlignAt: function (begin,numbered,taggable) { + 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(["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.AMSarray(begin,numbered,taggable,align,spacing); + return this.setArrayAlign(array,valign); + }, + + /* + * Handle equation environment + */ + EquationBegin: function (begin,force) { + this.checkEqnEnv(); + this.stack.global.forcetag = (force && CONFIG.autoNumber !== "none"); + return begin; + }, + EquationStar: function (begin,row) { + this.stack.global.tagged = true; // prevent automatic tagging + return row; + }, + + /* + * Check for bad nesting of equation environments + */ + checkEqnEnv: function () { + if (this.stack.global.eqnenv) + {TEX.Error(["ErroneousNestingEq","Erroneous nesting of equation structures"])} + this.stack.global.eqnenv = true; + }, + + /* + * Handle multiple integrals (make a mathop if followed by limits) + */ + MultiIntegral: function (name,integral) { + var next = this.GetNext(); + if (next === "\\") { + var i = this.i; next = this.GetArgument(name); this.i = i; + if (next === "\\limits") { + if (name === "\\idotsint") {integral = "\\!\\!\\mathop{\\,\\,"+integral+"}"} + else {integral = "\\!\\!\\!\\mathop{\\,\\,\\,"+integral+"}"} + } + } + this.string = integral + " " + this.string.slice(this.i); + this.i = 0; + }, + + /* + * Handle stretchable arrows + */ + xArrow: function (name,chr,l,r) { + var def = {width: "+"+(l+r)+"mu", lspace: l+"mu"}; + var bot = this.GetBrackets(name), + top = this.ParseArg(name); + var arrow = MML.mo(MML.chars(String.fromCharCode(chr))).With({ + stretchy: true, texClass: MML.TEXCLASS.REL + }); + var mml = MML.munderover(arrow); + mml.SetData(mml.over,MML.mpadded(top).With(def).With({voffset:".15em"})); + if (bot) { + bot = TEX.Parse(bot,this.stack.env).mml() + mml.SetData(mml.under,MML.mpadded(bot).With(def).With({voffset:"-.24em"})); + } + this.Push(mml.With({subsupOK:true})); + }, + + /* + * Get a delimiter or empty argument + */ + GetDelimiterArg: function (name) { + var c = this.trimSpaces(this.GetArgument(name)); + if (c == "") return null; + if (c in TEXDEF.delimiter) return c; + TEX.Error(["MissingOrUnrecognizedDelim","Missing or unrecognized delimiter for %1",name]); + }, + + /* + * Get a star following a control sequence name, if any + */ + GetStar: function () { + var star = (this.GetNext() === "*"); + if (star) {this.i++} + return star; + } + + }); + + /******************************************************************************/ + + STACKITEM.Augment({ + /* + * Increment equation number and form tag mtd element + */ + autoTag: function () { + var global = this.global; + 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)}); + } + }, + + /* + * Get the tag and record the label, if any + */ + getTag: function () { + var global = this.global, tag = global.tag; global.tagged = true; + if (global.label) { + if (CONFIG.useLabelIds) {tag.id = CONFIG.formatID(global.label)} + AMS.eqlabels[global.label] = {tag:global.tagID, id:tag.id}; + } + // + // 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 , precede 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[i].type === "texatom" && data[i].texClass === MML.TEXCLASS.REL)) data.unshift(MML.mi()); + break; + } + } + } + }); + + /* + * Implement multline environment via a STACKITEM + */ + STACKITEM.multline = STACKITEM.array.Subclass({ + type: "multline", + Init: function (numbered,stack) { + this.SUPER(arguments).Init.apply(this); + this.numbered = (numbered && CONFIG.autoNumber !== "none"); + this.save = {notag: stack.global.notag}; + 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(["MultlineRowsOneCol", + "The rows within the %1 environment must have exactly one column", + "multline"]); + } + this.table.push(this.row); this.row = []; + }, + EndTable: function () { + this.SUPER(arguments).EndTable.call(this); + if (this.table.length) { + var m = this.table.length-1, i, label = -1; + if (!this.table[0][0].columnalign) {this.table[0][0].columnalign = MML.ALIGN.LEFT} + if (!this.table[m][0].columnalign) {this.table[m][0].columnalign = MML.ALIGN.RIGHT} + if (!this.global.tag && this.numbered) {this.autoTag()} + if (this.global.tag && !this.global.notags) { + label = (this.arraydef.side === "left" ? 0 : this.table.length - 1); + this.table[label] = [this.getTag()].concat(this.table[label]); + } + for (i = 0, m = this.table.length; i < m; i++) { + var mtr = (i === label ? MML.mlabeledtr : MML.mtr); + this.table[i] = mtr.apply(MML,this.table[i]); + } + } + this.global.notag = this.save.notag; + } + }); + + /* + * Save data about numbering and taging equations, and add + * tags at the ends of rows. + */ + STACKITEM.AMSarray = STACKITEM.array.Subclass({ + type: "AMSarray", + Init: function (name,numbered,taggable,stack) { + this.SUPER(arguments).Init.apply(this); + this.numbered = (numbered && CONFIG.autoNumber !== "none"); + this.save = {notags: stack.global.notags, notag: stack.global.notag}; + stack.global.notags = (taggable ? null : name); + stack.global.tagged = !numbered && taggable && !stack.global.forcetag; // prevent automatic tagging in starred environments + }, + EndEntry: function () { + if (this.row.length % 2 === 1) {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.notags) { + if (this.global.tag) { + 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 = []; + }, + EndTable: function () { + this.SUPER(arguments).EndTable.call(this); + this.global.notags = this.save.notags; + this.global.notag = this.save.notag; + } + }); + + // + // Look for \tag on a formula and make an mtable to include it + // + STACKITEM.start.Augment({ + oldCheckItem: STACKITEM.start.prototype.checkItem, + checkItem: function (item) { + if (item.type === "stop") { + var mml = this.mmlData(), global = this.global; + if (AMS.display && !global.tag && !global.tagged && !global.isInner && + (CONFIG.autoNumber === "all" || global.forcetag)) {this.autoTag()} + if (global.tag) { + var row = [this.getTag(),MML.mtd(mml)]; + var def = { + side: TEX.config.TagSide, + minlabelspacing: TEX.config.TagIndent, + displaystyle: "inherit" // replaced by TeX input jax Translate() function with actual value + }; + mml = MML.mtable(MML.mlabeledtr.apply(MML,row)).With(def); + } + return STACKITEM.mml(mml); + } + return this.oldCheckItem.call(this,item); + } + }); + + /******************************************************************************/ + + /* + * Add pre- and post-filters to handle the equation number maintenance. + */ + TEX.prefilterHooks.Add(function (data) { + AMS.display = data.display; + AMS.number = AMS.startNumber; // reset equation numbers (in case the equation restarted) + 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 + AMS.refUpdate = false; + }); + MathJax.Hub.Register.MessageHook("End Math Input",function (message) { + if (AMS.refs.length) { + AMS.refUpdate = true; + for (var i = 0, m = AMS.refs.length; i < m; i++) + {AMS.refs[i].MathJax.state = MathJax.ElementJax.STATE.UPDATE} + return MathJax.Hub.processInput({ + scripts:AMS.refs, + start: new Date().getTime(), + i:0, j:0, jax:{}, jaxIDs:[] + }); + } + return null; + }); + + // + // Clear the equation numbers and labels + // + TEX.resetEquationNumbers = function (n,keepLabels) { + AMS.startNumber = (n || 0); + if (!keepLabels) { + AMS.labels = {}; + AMS.IDs = {}; + } + } + + /******************************************************************************/ + + MathJax.Hub.Startup.signal.Post("TeX AMSmath Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSmath.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/AMSsymbols.js b/js/mathjax/extensions/TeX/AMSsymbols.js new file mode 100644 index 0000000..ef7ae5f --- /dev/null +++ b/js/mathjax/extensions/TeX/AMSsymbols.js @@ -0,0 +1,351 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/AMSsymbols.js + * + * Implements macros for accessing the AMS symbol fonts. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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/AMSsymbols"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var MML = MathJax.ElementJax.mml, + TEXDEF = MathJax.InputJax.TeX.Definitions; + + TEXDEF.Add({ + + mathchar0mi: { + // Lowercase Greek letters + digamma: '03DD', + varkappa: '03F0', + + // Uppercase Greek letters + varGamma: ['0393',{mathvariant: MML.VARIANT.ITALIC}], + varDelta: ['0394',{mathvariant: MML.VARIANT.ITALIC}], + varTheta: ['0398',{mathvariant: MML.VARIANT.ITALIC}], + varLambda: ['039B',{mathvariant: MML.VARIANT.ITALIC}], + varXi: ['039E',{mathvariant: MML.VARIANT.ITALIC}], + varPi: ['03A0',{mathvariant: MML.VARIANT.ITALIC}], + varSigma: ['03A3',{mathvariant: MML.VARIANT.ITALIC}], + varUpsilon: ['03A5',{mathvariant: MML.VARIANT.ITALIC}], + varPhi: ['03A6',{mathvariant: MML.VARIANT.ITALIC}], + varPsi: ['03A8',{mathvariant: MML.VARIANT.ITALIC}], + varOmega: ['03A9',{mathvariant: MML.VARIANT.ITALIC}], + + // Hebrew letters + beth: '2136', + gimel: '2137', + daleth: '2138', + + // Miscellaneous symbols +// hbar: '0127', // in TeX/jax.js + backprime: ['2035',{variantForm: true}], + hslash: '210F', + varnothing: ['2205',{variantForm: true}], + 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 TeX/jax.js + sphericalangle: '2222', + measuredangle: '2221', + nexists: '2204', + complement: '2201', + mho: '2127', + eth: ['00F0',{mathvariant: MML.VARIANT.NORMAL}], + Finv: '2132', + diagup: '2571', + Game: '2141', + diagdown: '2572', + Bbbk: ['006B',{mathvariant: MML.VARIANT.DOUBLESTRUCK}], + + yen: '00A5', + circledR: '00AE', + checkmark: '2713', + maltese: '2720' + }, + + mathchar0mo: { + // Binary operators + dotplus: '2214', + ltimes: '22C9', + smallsetminus: '2216', + rtimes: '22CA', + Cap: '22D2', + doublecap: '22D2', + leftthreetimes: '22CB', + Cup: '22D3', + doublecup: '22D3', + rightthreetimes: '22CC', + barwedge: '22BC', + curlywedge: '22CF', + veebar: '22BB', + curlyvee: '22CE', + doublebarwedge: '2A5E', + boxminus: '229F', + circleddash: '229D', + boxtimes: '22A0', + circledast: '229B', + boxdot: '22A1', + circledcirc: '229A', + boxplus: '229E', + centerdot: ['22C5',{variantForm: true}], + divideontimes: '22C7', + intercal: '22BA', + + // Binary relations + leqq: '2266', + geqq: '2267', + leqslant: '2A7D', + geqslant: '2A7E', + eqslantless: '2A95', + eqslantgtr: '2A96', + lesssim: '2272', + gtrsim: '2273', + lessapprox: '2A85', + gtrapprox: '2A86', + approxeq: '224A', + lessdot: '22D6', + gtrdot: '22D7', + lll: '22D8', + llless: '22D8', + ggg: '22D9', + gggtr: '22D9', + lessgtr: '2276', + gtrless: '2277', + lesseqgtr: '22DA', + gtreqless: '22DB', + lesseqqgtr: '2A8B', + gtreqqless: '2A8C', + doteqdot: '2251', + Doteq: '2251', + eqcirc: '2256', + risingdotseq: '2253', + circeq: '2257', + fallingdotseq: '2252', + triangleq: '225C', + backsim: '223D', + thicksim: ['223C',{variantForm: true}], + backsimeq: '22CD', + thickapprox: ['2248',{variantForm: true}], + subseteqq: '2AC5', + supseteqq: '2AC6', + Subset: '22D0', + Supset: '22D1', + sqsubset: '228F', + sqsupset: '2290', + preccurlyeq: '227C', + succcurlyeq: '227D', + curlyeqprec: '22DE', + curlyeqsucc: '22DF', + precsim: '227E', + succsim: '227F', + precapprox: '2AB7', + succapprox: '2AB8', + vartriangleleft: '22B2', + lhd: '22B2', + vartriangleright: '22B3', + rhd: '22B3', + trianglelefteq: '22B4', + unlhd: '22B4', + trianglerighteq: '22B5', + unrhd: '22B5', + vDash: '22A8', + Vdash: '22A9', + Vvdash: '22AA', + smallsmile: ['2323',{variantForm: true}], + shortmid: ['2223',{variantForm: true}], + smallfrown: ['2322',{variantForm: true}], + shortparallel: ['2225',{variantForm: true}], + bumpeq: '224F', + between: '226C', + Bumpeq: '224E', + pitchfork: '22D4', + varpropto: '221D', + backepsilon: '220D', + blacktriangleleft: '25C2', + blacktriangleright: '25B8', + therefore: '2234', + because: '2235', + eqsim: '2242', + vartriangle: ['25B3',{variantForm: true}], + Join: '22C8', + + // Negated relations + nless: '226E', + ngtr: '226F', + nleq: '2270', + ngeq: '2271', + nleqslant: ['2A87',{variantForm: true}], + ngeqslant: ['2A88',{variantForm: true}], + nleqq: ['2270',{variantForm: true}], + ngeqq: ['2271',{variantForm: true}], + lneq: '2A87', + gneq: '2A88', + lneqq: '2268', + gneqq: '2269', + lvertneqq: ['2268',{variantForm: true}], + gvertneqq: ['2269',{variantForm: true}], + lnsim: '22E6', + gnsim: '22E7', + lnapprox: '2A89', + gnapprox: '2A8A', + nprec: '2280', + nsucc: '2281', + npreceq: ['22E0',{variantForm: true}], + nsucceq: ['22E1',{variantForm: true}], + precneqq: '2AB5', + succneqq: '2AB6', + precnsim: '22E8', + succnsim: '22E9', + precnapprox: '2AB9', + succnapprox: '2ABA', + nsim: '2241', + ncong: '2246', + nshortmid: ['2224',{variantForm: true}], + nshortparallel: ['2226',{variantForm: true}], + nmid: '2224', + nparallel: '2226', + nvdash: '22AC', + nvDash: '22AD', + nVdash: '22AE', + nVDash: '22AF', + ntriangleleft: '22EA', + ntriangleright: '22EB', + ntrianglelefteq: '22EC', + ntrianglerighteq: '22ED', + nsubseteq: '2288', + nsupseteq: '2289', + nsubseteqq: ['2288',{variantForm: true}], + nsupseteqq: ['2289',{variantForm: true}], + subsetneq: '228A', + supsetneq: '228B', + varsubsetneq: ['228A',{variantForm: true}], + varsupsetneq: ['228B',{variantForm: true}], + subsetneqq: '2ACB', + supsetneqq: '2ACC', + varsubsetneqq: ['2ACB',{variantForm: true}], + varsupsetneqq: ['2ACC',{variantForm: true}], + + + // Arrows + leftleftarrows: '21C7', + rightrightarrows: '21C9', + leftrightarrows: '21C6', + rightleftarrows: '21C4', + Lleftarrow: '21DA', + Rrightarrow: '21DB', + twoheadleftarrow: '219E', + twoheadrightarrow: '21A0', + leftarrowtail: '21A2', + rightarrowtail: '21A3', + looparrowleft: '21AB', + looparrowright: '21AC', + leftrightharpoons: '21CB', + rightleftharpoons: ['21CC',{variantForm: true}], + curvearrowleft: '21B6', + curvearrowright: '21B7', + circlearrowleft: '21BA', + circlearrowright: '21BB', + Lsh: '21B0', + Rsh: '21B1', + upuparrows: '21C8', + downdownarrows: '21CA', + upharpoonleft: '21BF', + upharpoonright: '21BE', + downharpoonleft: '21C3', + restriction: '21BE', + multimap: '22B8', + downharpoonright: '21C2', + leftrightsquigarrow: '21AD', + rightsquigarrow: '21DD', + leadsto: '21DD', + dashrightarrow: '21E2', + dashleftarrow: '21E0', + + // Negated arrows + nleftarrow: '219A', + nrightarrow: '219B', + nLeftarrow: '21CD', + nRightarrow: '21CF', + nleftrightarrow: '21AE', + nLeftrightarrow: '21CE' + }, + + delimiter: { + // corners + "\\ulcorner": '231C', + "\\urcorner": '231D', + "\\llcorner": '231E', + "\\lrcorner": '231F' + }, + + macros: { + implies: ['Macro','\\;\\Longrightarrow\\;'], + impliedby: ['Macro','\\;\\Longleftarrow\\;'] + } + + },null,true); + + var REL = MML.mo.OPTYPES.REL; + + MathJax.Hub.Insert(MML.mo.prototype,{ + OPTABLE: { + infix: { + '\u2322': REL, // smallfrown + '\u2323': REL, // smallsmile + '\u25B3': REL, // vartriangle + '\uE006': REL, // nshortmid + '\uE007': REL, // nshortparallel + '\uE00C': REL, // lvertneqq + '\uE00D': REL, // gvertneqq + '\uE00E': REL, // ngeqq + '\uE00F': REL, // ngeqslant + '\uE010': REL, // nleqslant + '\uE011': REL, // nleqq + '\uE016': REL, // nsubseteqq + '\uE017': REL, // varsubsetneqq + '\uE018': REL, // nsupseteqq + '\uE019': REL, // varsupsetneqq + '\uE01A': REL, // varsubsetneq + '\uE01B': REL, // varsupsetneq + '\uE04B': REL, // npreceq + '\uE04F': REL // nsucceq + } + } + }); + + MathJax.Hub.Startup.signal.Post("TeX AMSsymbols Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSsymbols.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/HTML.js b/js/mathjax/extensions/TeX/HTML.js new file mode 100644 index 0000000..75e4e45 --- /dev/null +++ b/js/mathjax/extensions/TeX/HTML.js @@ -0,0 +1,108 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/HTML.js + * + * Implements the \href, \class, \style, \cssId macros. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 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/HTML"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var TEX = MathJax.InputJax.TeX; + var TEXDEF = TEX.Definitions; + + TEXDEF.Add({ + macros: { + href: 'HREF_attribute', + "class": 'CLASS_attribute', + style: 'STYLE_attribute', + cssId: 'ID_attribute' + } + },null,true); + + TEX.Parse.Augment({ + + // + // Implements \href{url}{math} + // + HREF_attribute: function (name) { + var url = this.GetArgument(name), + arg = this.GetArgumentMML(name); + this.Push(arg.With({href:url})); + }, + + // + // Implements \class{name}{math} + // + CLASS_attribute: function (name) { + var CLASS = this.GetArgument(name), + arg = this.GetArgumentMML(name); + if (arg["class"] != null) {CLASS = arg["class"] + " " + CLASS} + this.Push(arg.With({"class":CLASS})); + }, + + // + // Implements \style{style-string}{math} + // + STYLE_attribute: function (name) { + var style = this.GetArgument(name), + arg = this.GetArgumentMML(name); + // check that it looks like a style string + if (arg.style != null) { + if (style.charAt(style.length-1) !== ";") {style += ";"} + style = arg.style + " " + style; + } + this.Push(arg.With({style: style})); + }, + + // + // Implements \cssId{id}{math} + // + ID_attribute: function (name) { + var ID = this.GetArgument(name), + arg = this.GetArgumentMML(name); + this.Push(arg.With({id:ID})); + }, + + // + // returns an argument that is a single MathML element + // (in an mrow if necessary) + // + GetArgumentMML: function (name) { + var arg = this.ParseArg(name); + if (arg.inferred && arg.data.length == 1) + {arg = arg.data[0]} else {delete arg.inferred} + return arg; + } + + }); + + MathJax.Hub.Startup.signal.Post("TeX HTML Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/HTML.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/action.js b/js/mathjax/extensions/TeX/action.js new file mode 100644 index 0000000..5ef06fd --- /dev/null +++ b/js/mathjax/extensions/TeX/action.js @@ -0,0 +1,85 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/action.js + * + * Implements the \mathtip, \texttip, and \toggle macros, which give + * access from TeX to the tag in the MathML that underlies + * MathJax's internal format. + * + * Usage: + * + * \mathtip{math}{tip} % use "tip" (in math mode) as tooltip for "math" + * \texttip{math}{tip} % use "tip" (in text mode) as tooltip for "math" + * \toggle{math1}{math2}...\endtoggle + * % show math1, and when clicked, show math2, and so on. + * % When the last one is clicked, go back to math1. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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/action"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX, + MML = MathJax.ElementJax.mml; + + // + // Set up control sequenecs + // + TEX.Definitions.Add({ + macros: { + toggle: 'Toggle', + mathtip: 'Mathtip', + texttip: ['Macro','\\mathtip{#1}{\\text{#2}}',2] + } + },null,true); + + TEX.Parse.Augment({ + + // + // Implement \toggle {math1} {math2} ... \endtoggle + // (as an ) + // + Toggle: function (name) { + var data = [], arg; + while ((arg = this.GetArgument(name)) !== "\\endtoggle") + {data.push(TEX.Parse(arg,this.stack.env).mml())} + this.Push(MML.maction.apply(MML,data).With({actiontype: MML.ACTIONTYPE.TOGGLE})); + }, + + // + // Implement \mathtip{math}{tip} + // (an an ) + // + Mathtip: function(name) { + var arg = this.ParseArg(name), tip = this.ParseArg(name); + this.Push(MML.maction(arg,tip).With({actiontype: MML.ACTIONTYPE.TOOLTIP})); + } + }); + + MathJax.Hub.Startup.signal.Post("TeX action Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/action.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/autobold.js b/js/mathjax/extensions/TeX/autobold.js new file mode 100644 index 0000000..1d058ee --- /dev/null +++ b/js/mathjax/extensions/TeX/autobold.js @@ -0,0 +1,52 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/autobold.js + * + * Adds \boldsymbol around mathematics that appears in a section + * of an HTML page that is in bold. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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/autobold"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX; + + TEX.prefilterHooks.Add(function (data) { + var span = data.script.parentNode.insertBefore(document.createElement("span"),data.script); + span.visibility = "hidden"; + span.style.fontFamily = "Times, serif"; + span.appendChild(document.createTextNode("ABCXYZabcxyz")); + var W = span.offsetWidth; + span.style.fontWeight = "bold"; + if (W && span.offsetWidth === W) {data.math = "\\boldsymbol{"+data.math+"}"} + span.parentNode.removeChild(span); + }); + + MathJax.Hub.Startup.signal.Post("TeX autobold Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/autobold.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/autoload-all.js b/js/mathjax/extensions/TeX/autoload-all.js new file mode 100644 index 0000000..6032aad --- /dev/null +++ b/js/mathjax/extensions/TeX/autoload-all.js @@ -0,0 +1,85 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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 + * + * Provides pre-defined macros to autoload all the extensions + * so that all macros that MathJax knows about are available. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2020 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/autoload-all"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var EXTENSIONS = { + action: ["mathtip","texttip","toggle"], + AMSmath: ["mathring","nobreakspace","negmedspace","negthickspace","intI", + "iiiint","idotsint","dddot","ddddot","sideset","boxed", + "substack","injlim","projlim","varliminf","varlimsup", + "varinjlim","varprojlim","DeclareMathOperator","operatorname", + "genfrac","tfrac","dfrac","binom","tbinom","dbinom","cfrac", + "shoveleft","shoveright","xrightarrow","xleftarrow"], + begingroup: ["begingroup","endgroup","gdef","global"], + cancel: ["cancel","bcancel","xcancel","cancelto"], + color: ["color","textcolor","colorbox","fcolorbox","definecolor"], + enclose: ["enclose"], + extpfeil: ["Newextarrow","xlongequal","xmapsto","xtofrom", + "xtwoheadleftarrow","xtwoheadrightarrow"], + mhchem: ["ce","cee","cf"] + }; + + 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]} + } + }} + + 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"); + +}); + +MathJax.Callback.Queue( + ["Require",MathJax.Ajax,"[MathJax]/extensions/TeX/AMSsymbols.js"], + ["loadComplete",MathJax.Ajax,"[MathJax]/extensions/TeX/autoload-all.js"] +); +// @license-end diff --git a/js/mathjax/extensions/TeX/bbox.js b/js/mathjax/extensions/TeX/bbox.js new file mode 100644 index 0000000..cc5440a --- /dev/null +++ b/js/mathjax/extensions/TeX/bbox.js @@ -0,0 +1,104 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/bbox.js + * + * This file implements the \bbox macro, which creates an box that + * can be styled (for background colors, and so on). You can include + * an optional dimension that tells how much extra padding to include + * around the bounding box for the mathematics, or a color specification + * for the background color to use, or both. E.g., + * + * \bbox[2pt]{x+y} % an invisible box around x+y with 2pt of extra space + * \bbox[green]{x+y} % a green box around x+y + * \bbox[green,2pt]{x+y} % a green box with 2pt of extra space + * + * You can also specify style attributes, for example + * + * \bbox[red,border:3px solid blue,5px]{x+y} + * + * would give a red background with a 3px solid blue border that has 5px + * of padding between the border and the mathematics. Note that not all + * output formats support the style specifications. In particular, the + * NativeMML output depends on the browser to render the attributes, and + * not all MathML renderers will honor them (e.g., MathPlayer2 doesn't + * render border styles). + * + * This file will be loaded automatically when \bbox is first used. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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/bbox"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var TEX = MathJax.InputJax.TeX, + MML = MathJax.ElementJax.mml; + + 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 = 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 = this.BBoxPadding(match[1]+match[3]); + if (pad) 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(["MultipleBBoxProperty","%1 specified twice in %2","Background",name])} + background = part; + } else if (part.match(/^[-a-z]+:/i)) { + if (style) + {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2", "Style",name])} + style = this.BBoxStyle(part); + } else if (part !== "") { + 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)} + if (background || style) { + math = MML.mstyle(math).With({mathbackground:background, style:style}); + } + this.Push(math); + }, + BBoxStyle: function (styles) {return styles}, + BBoxPadding: function (pad) {return pad} + }); + + MathJax.Hub.Startup.signal.Post("TeX bbox Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/bbox.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/begingroup.js b/js/mathjax/extensions/TeX/begingroup.js new file mode 100644 index 0000000..f750fc5 --- /dev/null +++ b/js/mathjax/extensions/TeX/begingroup.js @@ -0,0 +1,294 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/begingroup.js + * + * Implements \begingroup and \endgroup commands that make local + * definitions possible and are removed when the \endgroup occurs. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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/begingroup"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var TEX = MathJax.InputJax.TeX, + TEXDEF = TEX.Definitions; + + /****************************************************/ + + // + // A namespace for localizing macros and environments + // (\begingroup and \endgroup create and destroy these) + // + var NSFRAME = MathJax.Object.Subclass({ + macros: null, // the local macro definitions + environments: null, // the local environments + Init: function (macros,environments) { + this.macros = (macros || {}); + this.environments = (environments || {}); + }, + // + // Find a macro or environment by name + // + Find: function (name,type) {if (this[type].hasOwnProperty(name)) {return this[type][name]}}, + // + // Define or remove a macro or environment + // + Def: function (name,value,type) {this[type][name] = value}, + Undef: function (name,type) {delete this[type][name]}, + // + // Merge two namespaces (used when the equation namespace is combined with the root one) + // + Merge: function (frame) { + MathJax.Hub.Insert(this.macros,frame.macros); + MathJax.Hub.Insert(this.environments,frame.environments); + }, + // + // Move global macros to the stack (globally) and remove from the frame + // + MergeGlobals: function (stack) { + var macros = this.macros; + for (var cs in macros) {if (macros.hasOwnProperty(cs) && macros[cs].global) { + stack.Def(cs,macros[cs],"macros",true); + delete macros[cs].global; delete macros[cs]; + }} + }, + // + // Clear the macro and environment lists + // (but not global macros unless "all" is true) + // + Clear: function (all) { + this.environments = {}; + if (all) {this.macros = {}} else { + var macros = this.macros; + for (var cs in macros) { + if (macros.hasOwnProperty(cs) && !macros[cs].global) {delete macros[cs]} + } + } + return this; + } + }); + + /****************************************************/ + + // + // A Stack of namespace frames + // + var NSSTACK = TEX.nsStack = MathJax.Object.Subclass({ + stack: null, // the namespace frames + top: 0, // the current top one (we don't pop for real until the equation completes) + isEqn: false, // true if this is the equation stack (not the global one) + // + // Set up the initial stack frame + // + Init: function (eqn) { + this.isEqn = eqn; this.stack = []; + if (!eqn) {this.Push(NSFRAME(TEXDEF.macros,TEXDEF.environment))} + else {this.Push(NSFRAME())} + }, + // + // Define a macro or environment in the top frame + // + Def: function (name,value,type,global) { + var n = this.top-1; + if (global) { + // + // Define global macros in the base frame and remove that cs + // from all other frames. Mark the global ones in equations + // so they can be made global when merged with the root stack. + // + while (n > 0) {this.stack[n].Undef(name,type); n--} + if (!MathJax.Object.isArray(value)) {value = [value]} + if (this.isEqn) {value.global = true} + } + this.stack[n].Def(name,value,type); + }, + // + // Push a new namespace frame on the stack + // + Push: function (frame) { + this.stack.push(frame); + this.top = this.stack.length; + }, + // + // Pop the top stack frame + // (if it is the root, just keep track of the pop so we can + // reset it if the equation is reprocessed) + // + Pop: function () { + var top; + if (this.top > 1) { + top = this.stack[--this.top]; + if (this.isEqn) {this.stack.pop()} + } else if (this.isEqn) { + this.Clear(); + } + return top; + }, + // + // Search the stack from top to bottom for the first + // definition of the given control sequence in the given type + // + Find: function (name,type) { + for (var i = this.top-1; i >= 0; i--) { + var def = this.stack[i].Find(name,type); + if (def) {return def} + } + return null; + }, + // + // Combine the equation stack with the global one + // (The bottom frame of the equation goes with the top frame of the global one, + // and the remainder are pushed on the global stack, truncated to the + // position where items were poped from it.) + // + Merge: function (stack) { + stack.stack[0].MergeGlobals(this); + this.stack[this.top-1].Merge(stack.stack[0]); + var data = [this.top,this.stack.length-this.top].concat(stack.stack.slice(1)); + this.stack.splice.apply(this.stack,data); + this.top = this.stack.length; + }, + // + // Put back the temporarily poped items + // + Reset: function () {this.top = this.stack.length}, + // + // Clear the stack and start with a blank frame + // + Clear: function (all) { + this.stack = [this.stack[0].Clear()]; + this.top = this.stack.length; + } + },{ + nsFrame: NSFRAME + }); + + /****************************************************/ + + // + // Define the new macros + // + TEXDEF.Add({ + macros: { + begingroup: "BeginGroup", + endgroup: "EndGroup", + global: "Global", + gdef: ["Macro","\\global\\def"] + } + },null,true); + + TEX.Parse.Augment({ + // + // Implement \begingroup + // + BeginGroup: function (name) { + TEX.eqnStack.Push(NSFRAME()); + }, + // + // Implements \endgroup + // + EndGroup: function (name) { + // + // If the equation has pushed frames, pop one, + // Otherwise clear the equation stack and pop the top global one + // + if (TEX.eqnStack.top > 1) { + TEX.eqnStack.Pop(); + } else if (TEX.rootStack.top === 1) { + TEX.Error(["ExtraEndMissingBegin","Extra %1 or missing \\begingroup",name]); + } else { + TEX.eqnStack.Clear(); + TEX.rootStack.Pop(); + } + }, + + // + // Replace the original routines with ones that looks through the + // equation and root stacks for the given name + // + csFindMacro: function (name) { + return (TEX.eqnStack.Find(name,"macros") || TEX.rootStack.Find(name,"macros")); + }, + envFindName: function (name) { + return (TEX.eqnStack.Find(name,"environments") || TEX.rootStack.Find(name,"environments")); + }, + + // + // Modify the way macros and environments are defined + // to make them go into the equation namespace stack + // + setDef: function (name,value) { + value.isUser = true; + TEX.eqnStack.Def(name,value,"macros",this.stack.env.isGlobal); + delete this.stack.env.isGlobal; + }, + setEnv: function (name,value) { + value.isUser = true; + TEX.eqnStack.Def(name,value,"environments") + }, + + // + // Implement \global (for \global\let, \global\def and \global\newcommand) + // + Global: function (name) { + var i = this.i; var cs = this.GetCSname(name); this.i = i; + if (cs !== "let" && cs !== "def" && cs !== "newcommand" && + cs !== "DeclareMathOperator" && cs !== "Newextarrow") { + TEX.Error(["GlobalNotFollowedBy", + "%1 not followed by \\let, \\def, or \\newcommand",name]); + } + this.stack.env.isGlobal = true; + } + }); + + /****************************************************/ + + TEX.rootStack = NSSTACK(); // the global namespace stack + TEX.eqnStack = NSSTACK(true); // the equation stack + + // + // Reset the global stack and clear the equation stack + // (this gets us back to the initial stack state as it was + // before the equation was first processed, in case the equation + // get restarted due to an autoloaded file) + // + TEX.prefilterHooks.Add(function () {TEX.rootStack.Reset(); TEX.eqnStack.Clear(true)}); + + // + // We only get here if there were no errors and the equation is fully + // processed (all restarts are complete). So we merge the equation + // stack into the global stack, thus making the changes from this + // equation permanent. + // + TEX.postfilterHooks.Add(function () {TEX.rootStack.Merge(TEX.eqnStack)}); + + /*********************************************************/ + + MathJax.Hub.Startup.signal.Post("TeX begingroup Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/begingroup.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/boldsymbol.js b/js/mathjax/extensions/TeX/boldsymbol.js new file mode 100644 index 0000000..e25fff0 --- /dev/null +++ b/js/mathjax/extensions/TeX/boldsymbol.js @@ -0,0 +1,77 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/boldsymbol.js + * + * Implements the \boldsymbol{...} command to make bold + * versions of all math characters (not just variables). + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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/boldsymbol"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var MML = MathJax.ElementJax.mml; + var TEX = MathJax.InputJax.TeX; + var TEXDEF = TEX.Definitions; + + var BOLDVARIANT = {}; + BOLDVARIANT[MML.VARIANT.NORMAL] = MML.VARIANT.BOLD; + BOLDVARIANT[MML.VARIANT.ITALIC] = MML.VARIANT.BOLDITALIC; + BOLDVARIANT[MML.VARIANT.FRAKTUR] = MML.VARIANT.BOLDFRAKTUR; + BOLDVARIANT[MML.VARIANT.SCRIPT] = MML.VARIANT.BOLDSCRIPT; + BOLDVARIANT[MML.VARIANT.SANSSERIF] = MML.VARIANT.BOLDSANSSERIF; + BOLDVARIANT["-tex-caligraphic"] = "-tex-caligraphic-bold"; + BOLDVARIANT["-tex-oldstyle"] = "-tex-oldstyle-bold"; + + TEXDEF.Add({macros: {boldsymbol: 'Boldsymbol'}},null,true); + + TEX.Parse.Augment({ + mmlToken: function (token) { + if (this.stack.env.boldsymbol) { + var variant = token.Get("mathvariant"); + if (variant == null) {token.mathvariant = MML.VARIANT.BOLD} + else {token.mathvariant = (BOLDVARIANT[variant]||variant)} + } + return token; + }, + + Boldsymbol: function (name) { + var boldsymbol = this.stack.env.boldsymbol, + font = this.stack.env.font; + this.stack.env.boldsymbol = true; + this.stack.env.font = null; + var mml = this.ParseArg(name); + this.stack.env.font = font; + this.stack.env.boldsymbol = boldsymbol; + this.Push(mml); + } + }); + + MathJax.Hub.Startup.signal.Post("TeX boldsymbol Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/boldsymbol.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/cancel.js b/js/mathjax/extensions/TeX/cancel.js new file mode 100644 index 0000000..9f2afe8 --- /dev/null +++ b/js/mathjax/extensions/TeX/cancel.js @@ -0,0 +1,112 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/cancel.js + * + * Implements the \cancel, \bcancel, \xcancel, and \cancelto macros. + * + * Usage: + * + * \cancel{math} % strikeout math from lower left to upper right + * \bcancel{math} % strikeout from upper left to lower right + * \xcancel{math} % strikeout with an X + * \cancelto{value}{math} % strikeout with arrow going to value + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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/cancel"] = { + version: "2.7.9", + + // + // The attributes allowed in \enclose{notation}[attributes]{math} + // + ALLOWED: { + color: 1, mathcolor: 1, + background: 1, mathbackground: 1, + padding: 1, + thickness: 1 + } +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX, + MML = MathJax.ElementJax.mml, + CANCEL = MathJax.Extension["TeX/cancel"]; + + CANCEL.setAttributes = function (def,attr) { + if (attr !== "") { + attr = attr.replace(/ /g,"").split(/,/); + for (var i = 0, m = attr.length; i < m; i++) { + var keyvalue = attr[i].split(/[:=]/); + if (CANCEL.ALLOWED[keyvalue[0]]) { + if (keyvalue[1] === "true") {keyvalue[1] = true} + if (keyvalue[1] === "false") {keyvalue[1] = false} + def[keyvalue[0]] = keyvalue[1]; + } + } + } + return def; + }; + + // + // Set up macros + // + 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({ + // + // Implement \cancel[attributes]{math}, + // \bcancel[attributes]{math}, and + // \xcancel[attributes]{math} + // + Cancel: function(name,notation) { + var attr = this.GetBrackets(name,""), math = this.ParseArg(name); + var def = CANCEL.setAttributes({notation: notation},attr); + this.Push(MML.menclose(math).With(def)); + }, + + // + // Implement \cancelto{value}[attributes]{math} + // + CancelTo: function(name,notation) { + var value = this.ParseArg(name), + attr = this.GetBrackets(name,""), + math = this.ParseArg(name); + 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)); + } + + }); + + MathJax.Hub.Startup.signal.Post("TeX cancel Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/cancel.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/color.js b/js/mathjax/extensions/TeX/color.js new file mode 100644 index 0000000..45c9b9e --- /dev/null +++ b/js/mathjax/extensions/TeX/color.js @@ -0,0 +1,283 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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, RGB, gray, and named color + * models, and the \textcolor, \definecolor, \colorbox, and \fcolorbox + * macros. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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. + */ + +// +// The configuration defaults, augmented by the user settings +// +MathJax.Extension["TeX/color"] = { + version: "2.7.9", + + config: MathJax.Hub.CombineConfig("TeX.color",{ + padding: "5px", + border: "2px" + }), + + colors: { + Apricot: "#FBB982", + Aquamarine: "#00B5BE", + Bittersweet: "#C04F17", + Black: "#221E1F", + Blue: "#2D2F92", + BlueGreen: "#00B3B8", + BlueViolet: "#473992", + BrickRed: "#B6321C", + Brown: "#792500", + BurntOrange: "#F7921D", + CadetBlue: "#74729A", + CarnationPink: "#F282B4", + Cerulean: "#00A2E3", + CornflowerBlue: "#41B0E4", + Cyan: "#00AEEF", + Dandelion: "#FDBC42", + DarkOrchid: "#A4538A", + Emerald: "#00A99D", + ForestGreen: "#009B55", + Fuchsia: "#8C368C", + Goldenrod: "#FFDF42", + Gray: "#949698", + Green: "#00A64F", + GreenYellow: "#DFE674", + JungleGreen: "#00A99A", + Lavender: "#F49EC4", + LimeGreen: "#8DC73E", + Magenta: "#EC008C", + Mahogany: "#A9341F", + Maroon: "#AF3235", + Melon: "#F89E7B", + MidnightBlue: "#006795", + Mulberry: "#A93C93", + NavyBlue: "#006EB8", + OliveGreen: "#3C8031", + Orange: "#F58137", + OrangeRed: "#ED135A", + Orchid: "#AF72B0", + Peach: "#F7965A", + Periwinkle: "#7977B8", + PineGreen: "#008B72", + Plum: "#92268F", + ProcessBlue: "#00B0F0", + Purple: "#99479B", + RawSienna: "#974006", + Red: "#ED1B23", + RedOrange: "#F26035", + RedViolet: "#A1246B", + Rhodamine: "#EF559F", + RoyalBlue: "#0071BC", + RoyalPurple: "#613F99", + RubineRed: "#ED017D", + Salmon: "#F69289", + SeaGreen: "#3FBC9D", + Sepia: "#671800", + SkyBlue: "#46C5DD", + SpringGreen: "#C6DC67", + Tan: "#DA9D76", + TealBlue: "#00AEB3", + Thistle: "#D883B7", + Turquoise: "#00B4CE", + Violet: "#58429B", + VioletRed: "#EF58A0", + White: "#FFFFFF", + WildStrawberry: "#EE2967", + Yellow: "#FFF200", + YellowGreen: "#98CC70", + YellowOrange: "#FAA21A" + }, + + /* + * Look up a color based on its model and definition + */ + getColor: function (model,def) { + if (!model) {model = "named"} + var fn = this["get_"+model]; + 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.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+$/)) + {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; + }, + + /* + * Get a gray-scale value + */ + get_gray: function (gray) { + 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(["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; + }, + + /* + * Get a named value + */ + get_named: function (name) { + if (this.colors.hasOwnProperty(name)) {return this.colors[name]} + return name; + }, + + padding: function () { + var pad = "+"+this.config.padding; + var unit = this.config.padding.replace(/^.*?([a-z]*)$/,"$1"); + var pad2 = "+"+(2*parseFloat(pad))+unit; + return {width:pad2, height:pad, depth:pad, lspace:this.config.padding}; + } + +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX, + MML = MathJax.ElementJax.mml; + var STACKITEM = TEX.Stack.Item; + var COLOR = MathJax.Extension["TeX/color"]; + + COLOR.TEX = TEX; // for reference in getColor above + + TEX.Definitions.Add({ + macros: { + color: "Color", + textcolor: "TextColor", + definecolor: "DefineColor", + colorbox: "ColorBox", + fcolorbox: "fColorBox" + } + },null,true); + + TEX.Parse.Augment({ + + // + // Override \color macro definition + // + Color: function (name) { + var model = this.GetBrackets(name), + color = this.GetArgument(name); + color = COLOR.getColor(model,color); + var mml = STACKITEM.style().With({styles:{mathcolor:color}}); + 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 + // + DefineColor: function (name) { + var cname = this.GetArgument(name), + model = this.GetArgument(name), + def = this.GetArgument(name); + COLOR.colors[cname] = COLOR.getColor(model,def); + }, + + // + // Produce a text box with a colored background + // + ColorBox: function (name) { + var cname = this.GetArgument(name), + arg = this.InternalMath(this.GetArgument(name)); + this.Push(MML.mpadded.apply(MML,arg).With({ + mathbackground:COLOR.getColor("named",cname) + }).With(COLOR.padding())); + }, + + // + // Procude a framed text box with a colored background + // + fColorBox: function (name) { + var fname = this.GetArgument(name), + cname = this.GetArgument(name), + arg = this.InternalMath(this.GetArgument(name)); + this.Push(MML.mpadded.apply(MML,arg).With({ + mathbackground: COLOR.getColor("named",cname), + style: "border: "+COLOR.config.border+" solid "+COLOR.getColor("named",fname) + }).With(COLOR.padding())); + } + + }); + + MathJax.Hub.Startup.signal.Post("TeX color Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/color.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/enclose.js b/js/mathjax/extensions/TeX/enclose.js new file mode 100644 index 0000000..0976984 --- /dev/null +++ b/js/mathjax/extensions/TeX/enclose.js @@ -0,0 +1,93 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/enclose.js + * + * Implements the \enclose macros, which give access from TeX to the + * tag in the MathML that underlies MathJax's internal format. + * + * Usage: + * + * \enclose{notation}{math} % enclose math using given notation + * \enclose{notation,notation,...}{math} % enclose with several notations + * \enclose{notation}[attributes]{math} % enclose with attributes + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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/enclose"] = { + version: "2.7.9", + + // + // The attributes allowed in \enclose{notation}[attributes]{math} + // + ALLOWED: { + arrow: 1, + color: 1, mathcolor: 1, + background: 1, mathbackground: 1, + padding: 1, + thickness: 1 + } +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX, + MML = MathJax.ElementJax.mml, + ALLOW = MathJax.Extension["TeX/enclose"].ALLOWED; + + // + // Set up macro + // + TEX.Definitions.Add({macros: {enclose: 'Enclose'}},null,true); + + TEX.Parse.Augment({ + // + // Implement \enclose{notation}[attr]{math} + // (create math) + // + Enclose: function(name) { + var notation = this.GetArgument(name), + attr = this.GetBrackets(name), + math = this.ParseArg(name); + var def = {notation: notation.replace(/,/g," ")}; + if (attr) { + attr = attr.replace(/ /g,"").split(/,/); + for (var i = 0, m = attr.length; i < m; i++) { + var keyvalue = attr[i].split(/[:=]/); + if (ALLOW[keyvalue[0]]) { + keyvalue[1] = keyvalue[1].replace(/^"(.*)"$/,"$1"); + if (keyvalue[1] === "true") {keyvalue[1] = true} + if (keyvalue[1] === "false") {keyvalue[1] = false} + if (keyvalue[0] === "arrow" && keyvalue[1]) + {def.notation = def.notation + " updiagonalarrow"} else + {def[keyvalue[0]] = keyvalue[1]} + } + } + } + this.Push(MML.menclose(math).With(def)); + } + }); + + MathJax.Hub.Startup.signal.Post("TeX enclose Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/enclose.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/extpfeil.js b/js/mathjax/extensions/TeX/extpfeil.js new file mode 100644 index 0000000..f07adac --- /dev/null +++ b/js/mathjax/extensions/TeX/extpfeil.js @@ -0,0 +1,104 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/extpfeil.js + * + * Implements additional stretchy arrow macros. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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/extpfeil"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var TEX = MathJax.InputJax.TeX, + TEXDEF = TEX.Definitions; + + // + // Define the arrows to load the AMSmath extension + // (since they need its xArrow method) + // + TEXDEF.Add({ + macros: { + xtwoheadrightarrow: ['Extension','AMSmath'], + xtwoheadleftarrow: ['Extension','AMSmath'], + xmapsto: ['Extension','AMSmath'], + xlongequal: ['Extension','AMSmath'], + xtofrom: ['Extension','AMSmath'], + Newextarrow: ['Extension','AMSmath'] + } + },null,true); + + // + // Redefine the macros when AMSmath is loaded + // + MathJax.Hub.Register.StartupHook("TeX AMSmath Ready",function () { + MathJax.Hub.Insert(TEXDEF,{ + macros: { + xtwoheadrightarrow: ['xArrow',0x21A0,12,16], + xtwoheadleftarrow: ['xArrow',0x219E,17,13], + xmapsto: ['xArrow',0x21A6,6,7], + xlongequal: ['xArrow',0x003D,7,7], + xtofrom: ['xArrow',0x21C4,12,12], + Newextarrow: 'NewExtArrow' + } + }); + }); + + // + // Implements \Newextarrow to define a new arrow (not compatible with \newextarrow, but + // the equivalent for MathJax) + // + TEX.Parse.Augment({ + NewExtArrow: function (name) { + var cs = this.GetArgument(name), + space = this.GetArgument(name), + chr = this.GetArgument(name); + 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); + this.setDef(cs, ['xArrow', chr, parseInt(space[0]), parseInt(space[1])]); + } + }); + + MathJax.Hub.Startup.signal.Post("TeX extpfeil Ready"); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/extpfeil.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/mathchoice.js b/js/mathjax/extensions/TeX/mathchoice.js new file mode 100644 index 0000000..7042395 --- /dev/null +++ b/js/mathjax/extensions/TeX/mathchoice.js @@ -0,0 +1,109 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/mathchoice.js + * + * Implements the \mathchoice macro (rarely used) + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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.Hub.Register.StartupHook("TeX Jax Ready",function () { + var VERSION = "2.7.9"; + + var MML = MathJax.ElementJax.mml; + var TEX = MathJax.InputJax.TeX; + var TEXDEF = TEX.Definitions; + + TEXDEF.Add({macros: {mathchoice: 'MathChoice'}},null,true); + + TEX.Parse.Augment({ + MathChoice: function (name) { + var D = this.ParseArg(name), + T = this.ParseArg(name), + S = this.ParseArg(name), + SS = this.ParseArg(name); + this.Push(MML.TeXmathchoice(D,T,S,SS)); + } + }); + + MML.TeXmathchoice = MML.mbase.Subclass({ + type: "TeXmathchoice", notParent: true, + choice: function () { + 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; + }, + 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; + // Firefox doesn't correctly handle a span with a negatively sized content, + // so move marginLeft to main span (this is a hack to get \iiiint to work). + // FIXME: This is a symptom of a more general problem with Firefox, and + // there probably needs to be a more general solution (e.g., modifying + // HTMLhandleSpace() to get the width and adjust the right margin to + // compensate for negative-width contents) + if (span.firstChild && span.firstChild.style.marginLeft) { + span.style.marginLeft = span.firstChild.style.marginLeft; + span.firstChild.style.marginLeft = ""; + } + return span; + }, + 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"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mathchoice.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/mediawiki-texvc.js b/js/mathjax/extensions/TeX/mediawiki-texvc.js new file mode 100644 index 0000000..ab1ed42 --- /dev/null +++ b/js/mathjax/extensions/TeX/mediawiki-texvc.js @@ -0,0 +1,138 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * MathJax/extensions/TeX/mediawiki-texvc.js + * + * Implements macros used by mediawiki with their texvc preprocessor. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2015-2020 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/mediawiki-texvc"] = { + version: "2.7.9" +}; + +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"], + dashint: ["Macro", "\\unicodeInt{x2A0D}"], + ddashint: ["Macro", "\\unicodeInt{x2A0E}"], + 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"], + oiint: ["Macro", "\\unicodeInt{x222F}"], + oiiint: ["Macro", "\\unicodeInt{x2230}"], + ointctrclockwise: ["Macro", "\\unicodeInt{x2233}"], + 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"], + unicodeInt: ["Macro", "\\mathop{\\vcenter{\\mathchoice{\\huge\\unicode{#1}\\,}{\\unicode{#1}}{\\unicode{#1}}{\\unicode{#1}}}\\,}\\nolimits", 1], + varcoppa: ["Macro", "\u03D9"], + varstigma: ["Macro", "\u03DB"], + varointclockwise: ["Macro", "\\unicodeInt{x2232}"], + 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"); +// @license-end diff --git a/js/mathjax/extensions/TeX/mhchem.js b/js/mathjax/extensions/TeX/mhchem.js new file mode 100644 index 0000000..9d15876 --- /dev/null +++ b/js/mathjax/extensions/TeX/mhchem.js @@ -0,0 +1,522 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/mhchem.js + * + * Implements the \ce command for handling chemical formulas + * from the mhchem LaTeX package. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2020 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. + */ + + +// +// Don't replace [Contrib]/mhchem if it is already loaded +// +if (MathJax.Extension["TeX/mhchem"]) { + MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mhchem.js"); +} else { + +MathJax.Extension["TeX/mhchem"] = { + version: "2.7.9", + config: MathJax.Hub.CombineConfig("TeX.mhchem",{ + legacy: true + }) +}; + +// +// Load [mhchem]/mhchem.js if not configured for legacy vesion +// +if (!MathJax.Extension["TeX/mhchem"].config.legacy) { + if (!MathJax.Ajax.config.path.mhchem) { + MathJax.Ajax.config.path.mhchem = MathJax.Hub.config.root + "/extensions/TeX/mhchem3"; + } + MathJax.Callback.Queue( + ["Require",MathJax.Ajax,"[mhchem]/mhchem.js"], + ["loadComplete",MathJax.Ajax,"[MathJax]/extensions/TeX/mhchem.js"] + ); +} else { + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var TEX = MathJax.InputJax.TeX; + + /* + * This is the main class for handing the \ce and related commands. + * Its main method is Parse() which takes the argument to \ce and + * returns the corresponding TeX string. + */ + + var CE = MathJax.Object.Subclass({ + string: "", // the \ce string being parsed + i: 0, // the current position in the string + 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 + // + Init: function (string) {this.string = string}, + + // + // These are the special characters and the methods that + // handle them. All others are passed through verbatim. + // + ParseTable: { + '-': "Minus", + '+': "Plus", + '(': "Open", + ')': "Close", + '[': "Open", + ']': "Close", + '<': "Less", + '^': "Superscript", + '_': "Subscript", + '*': "Dot", + '.': "Dot", + '=': "Equal", + '#': "Pound", + '$': "Math", + '\\': "Macro", + ' ': "Space" + }, + // + // Basic arrow names for reactions + // + Arrows: { + '->': "rightarrow", + '<-': "leftarrow", + '<->': "leftrightarrow", + '<=>': "rightleftharpoons", + '<=>>': "Rightleftharpoons", + '<<=>': "Leftrightharpoons", + '^': "uparrow", + 'v': "downarrow" + }, + + // + // Implementations for the various bonds + // (the ~ ones are hacks that don't work well in NativeMML) + // + Bonds: { + '-': "-", + '=': "=", + '#': "\\equiv", + '~': "\\tripledash", + '~-': "\\begin{CEstack}{}\\tripledash\\\\-\\end{CEstack}", + '~=': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}", + '~--': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}", + '-~-': "\\raise2mu{\\begin{CEstack}{}-\\\\\\tripledash\\\\-\\end{CEstack}}", + '...': "{\\cdot}{\\cdot}{\\cdot}", + '....': "{\\cdot}{\\cdot}{\\cdot}{\\cdot}", + '->': "\\rightarrow", + '<-': "\\leftarrow", + '??': "\\text{??}" // unknown bond + }, + + // + // This converts the CE string to a TeX string. + // It loops through the string and calls the proper + // method depending on the ccurrent character. + // + Parse: function () { + this.tex = ""; this.atom = false; + while (this.i < this.string.length) { + var c = this.string.charAt(this.i); + if (c.match(/[a-z]/i)) {this.ParseLetter()} + else if (c.match(/[0-9]/)) {this.ParseNumber()} + else {this["Parse"+(this.ParseTable[c]||"Other")](c)} + } + this.FinishAtom(true); + return this.TEX; + }, + + // + // Make an atom name or a down arrow + // + ParseLetter: function () { + this.FinishAtom(); + if (this.Match(/^v( |$)/)) { + this.tex += "{\\"+this.Arrows["v"]+"}"; + } else { + this.tex += "\\text{"+this.Match(/^[a-z]+/i)+"}"; + this.atom = true; + } + }, + + // + // Make a number or fraction preceding an atom, + // or a subscript for an atom. + // + ParseNumber: function () { + var n = this.Match(/^\d+/); + if (this.atom && !this.sub) { + this.sub = n; + } else { + this.FinishAtom(); + var match = this.Match(/^\/\d+/); + if (match) { + var frac = "\\frac{"+n+"}{"+match.substr(1)+"}"; + this.tex += "\\mathchoice{\\textstyle"+frac+"}{"+frac+"}{"+frac+"}{"+frac+"}"; + } else { + this.tex += n; + if (this.i < this.string.length) {this.tex += "\\,"} + } + } + }, + + // + // Make a superscript minus, or an arrow, or a single bond. + // + ParseMinus: function (c) { + if (this.atom && (this.i === this.string.length-1 || this.string.charAt(this.i+1) === " ")) { + this.sup += c; + } else { + this.FinishAtom(); + if (this.string.substr(this.i,2) === "->") {this.i += 2; this.AddArrow("->"); return} + else {this.tex += "{-}"} + } + this.i++; + }, + + // + // Make a superscript plus, or pass it through + // + ParsePlus: function (c) { + if (this.atom) {this.sup += c} else {this.FinishAtom(); this.tex += c} + this.i++; + }, + + // + // Handle dots and double or triple bonds + // + ParseDot: function (c) {this.FinishAtom(); this.tex += "\\cdot "; this.i++}, + ParseEqual: function (c) {this.FinishAtom(); this.tex += "{=}"; this.i++}, + ParsePound: function (c) {this.FinishAtom(); this.tex += "{\\equiv}"; this.i++}, + + // + // Look for (v) or (^), or pass it through + // + ParseOpen: function (c) { + this.FinishAtom(); + var match = this.Match(/^\([v^]\)/); + if (match) {this.tex += "{\\"+this.Arrows[match.charAt(1)]+"}"} + else {this.tex += "{"+c; this.i++} + }, + // + // Allow ) and ] to get super- and subscripts + // + ParseClose: function (c) {this.FinishAtom(); this.atom = true; this.tex += c+"}"; this.i++}, + + // + // Make the proper arrow + // + ParseLess: function (c) { + this.FinishAtom(); + var arrow = this.Match(/^(<->?|<=>>?|<<=>)/); + if (!arrow) {this.tex += c; this.i++} else {this.AddArrow(arrow)} + }, + + // + // Look for a superscript, or an up arrow + // + ParseSuperscript: function (c) { + 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().replace(/^\{-\}/,"-")} + } else if (c === " " || c === "") { + this.tex += "{\\"+this.Arrows["^"]+"}"; this.i++; + } else { + var n = this.Match(/^(\d+|-\.)/); + if (n) {this.sup += n} + } + }, + // + // Look for subscripts + // + ParseSubscript: function (c) { + if (this.string.charAt(++this.i) == "{") { + this.i++; this.sub += CE(this.Find("}")).Parse().replace(/^\{-\}/,"-"); + } else { + var n = this.Match(/^\d+/); + if (n) {this.sub += n} + } + }, + + // + // Look for raw TeX code to include + // + ParseMath: function (c) { + this.FinishAtom(); + this.i++; this.tex += this.Find(c); + }, + + // + // Look for specific macros for bonds + // and allow \} to have subscripts + // + ParseMacro: function (c) { + this.FinishAtom(); + this.i++; var match = this.Match(/^([a-z]+|.)/i)||" "; + if (match === "sbond") {this.tex += "{-}"} + else if (match === "dbond") {this.tex += "{=}"} + else if (match === "tbond") {this.tex += "{\\equiv}"} + else if (match === "bond") { + var bond = (this.Match(/^\{.*?\}/)||""); + bond = bond.substr(1,bond.length-2); + this.tex += "{"+(this.Bonds[bond]||"\\text{??}")+"}"; + } + else if (match === "{") {this.tex += "{\\{"} + else if (match === "}") {this.tex += "\\}}"; this.atom = true} + else {this.tex += c+match} + }, + + // + // Ignore spaces + // + ParseSpace: function (c) {this.FinishAtom(); this.i++}, + + // + // Pass anything else on verbatim + // + ParseOther: function (c) {this.FinishAtom(); this.tex += c; this.i++}, + + // + // Process an arrow (looking for brackets for above and below) + // + AddArrow: function (arrow) { + var c = this.Match(/^[CT]\[/); + if (c) {this.i--; c = c.charAt(0)} + var above = this.GetBracket(c), below = this.GetBracket(c); + arrow = this.Arrows[arrow]; + if (above || below) { + if (below) {arrow += "["+below+"]"} + arrow += "{"+above+"}"; + arrow = "\\mathrel{\\x"+arrow+"}"; + } else { + arrow = "\\long"+arrow+" "; + } + this.tex += arrow; + }, + + // + // Handle the super and subscripts for an atom + // + 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.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; + }, + + // + // Find a bracket group and handle C and T prefixes + // + GetBracket: function (c) { + if (this.string.charAt(this.i) !== "[") {return ""} + this.i++; var bracket = this.Find("]"); + if (c === "C") {bracket = "\\ce{"+bracket+"}"} else + if (c === "T") { + if (!bracket.match(/^\{.*\}$/)) {bracket = "{"+bracket+"}"} + bracket = "\\text"+bracket; + }; + return bracket; + }, + + // + // Check if the string matches a regular expression + // and move past it if so, returning the match + // + Match: function (regex) { + var match = regex.exec(this.string.substr(this.i)); + if (match) {match = match[0]; this.i += match.length} + return match; + }, + + // + // Find a particular character, skipping over braced groups + // + Find: function (c) { + var m = this.string.length, i = this.i, braces = 0; + while (this.i < m) { + var C = this.string.charAt(this.i++); + if (C === c && braces === 0) {return this.string.substr(i,this.i-i-1)} + if (C === "{") {braces++} else + if (C === "}") { + if (braces) {braces--} + else { + TEX.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"]) + } + } + } + if (braces) {TEX.Error(["MissingCloseBrace","Missing close brace"])} + TEX.Error(["NoClosingChar","Can't find closing %1",c]); + } + + }); + + MathJax.Extension["TeX/mhchem"].CE = 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); + } + + // + // These arrows need to wait until AMSmath is loaded + // + 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({ + + // + // Implements \ce and friends + // + CE: function (name) { + 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()); + } + + }); + + // + // Indicate that the extension is ready + // + MathJax.Hub.Startup.signal.Post("TeX mhchem Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mhchem.js"); + +}} +// @license-end diff --git a/js/mathjax/extensions/TeX/mhchem3/mhchem.js b/js/mathjax/extensions/TeX/mhchem3/mhchem.js new file mode 100644 index 0000000..2caa810 --- /dev/null +++ b/js/mathjax/extensions/TeX/mhchem3/mhchem.js @@ -0,0 +1,1776 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/mhchem.js + * + * Implements the \ce command for handling chemical formulas + * from the mhchem LaTeX package. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2011-2015 The MathJax Consortium + * Copyright (c) 2015-2019 Martin Hensel + * + * 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. + */ + +// +// Coding Style +// - use '' for identifiers that can by minified/uglified +// - use "" for strings that need to stay untouched + + +MathJax.Extension["TeX/mhchem"] = { + version: "3.3.2" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () { + + var TEX = MathJax.InputJax.TeX; + + // + // This is the main class for handing the \ce and related commands. + // Its main method is Parse() which takes the argument to \ce and + // returns the corresponding TeX string. + // + + var CE = MathJax.Object.Subclass({ + string: "", // the \ce string being parsed + + // + // Store the string when a CE object is created + // + Init: function (string) { this.string = string; }, + + // + // This converts the CE string to a TeX string. + // + Parse: function (stateMachine) { + try { + return texify.go(mhchemParser.go(this.string, stateMachine)); + } catch (ex) { + TEX.Error(ex); + } + } + }); + + // + // Core parser for mhchem syntax (recursive) + // + /** @type {MhchemParser} */ + var mhchemParser = { + // + // Parses mchem \ce syntax + // + // Call like + // go("H2O"); + // + go: function (input, stateMachine) { + if (!input) { return []; } + if (stateMachine === undefined) { stateMachine = 'ce'; } + var state = '0'; + + // + // String buffers for parsing: + // + // buffer.a == amount + // buffer.o == element + // buffer.b == left-side superscript + // buffer.p == left-side subscript + // buffer.q == right-side subscript + // buffer.d == right-side superscript + // + // buffer.r == arrow + // buffer.rdt == arrow, script above, type + // buffer.rd == arrow, script above, content + // buffer.rqt == arrow, script below, type + // buffer.rq == arrow, script below, content + // + // buffer.text_ + // buffer.rm + // etc. + // + // buffer.parenthesisLevel == int, starting at 0 + // buffer.sb == bool, space before + // buffer.beginsWithBond == bool + // + // These letters are also used as state names. + // + // Other states: + // 0 == begin of main part (arrow/operator unlikely) + // 1 == next entity + // 2 == next entity (arrow/operator unlikely) + // 3 == next atom + // c == macro + // + /** @type {Buffer} */ + var buffer = {}; + buffer['parenthesisLevel'] = 0; + + input = input.replace(/\n/g, " "); + input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-"); + input = input.replace(/[\u2026]/g, "..."); + + // + // Looks through mhchemParser.transitions, to execute a matching action + // (recursive) + // + var lastInput; + var watchdog = 10; + /** @type {ParserOutput[]} */ + var output = []; + while (true) { + if (lastInput !== input) { + watchdog = 10; + lastInput = input; + } else { + watchdog--; + } + // + // Find actions in transition table + // + var machine = mhchemParser.stateMachines[stateMachine]; + var t = machine.transitions[state] || machine.transitions['*']; + iterateTransitions: + for (var i=0; i 0) { + if (!task.revisit) { + input = matches.remainder; + } + if (!task.toContinue) { + break iterateTransitions; + } + } else { + return output; + } + } + } + // + // Prevent infinite loop + // + if (watchdog <= 0) { + throw ["MhchemBugU", "mhchem bug U. Please report."]; // Unexpected character + } + } + }, + concatArray: function (a, b) { + if (b) { + if (Object.prototype.toString.call(b) === "[object Array]") { // Array.isArray(b) + for (var iB=0; iB': /^[=<>]/, + '#': /^[#\u2261]/, + '+': /^\+/, + '-$': /^-(?=[\s_},;\]/]|$|\([a-z]+\))/, // -space -, -; -] -/ -$ -state-of-aggregation + '-9': /^-(?=[0-9])/, + '- orbital overlap': /^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/, + '-': /^-/, + 'pm-operator': /^(?:\\pm|\$\\pm\$|\+-|\+\/-)/, + 'operator': /^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/, + 'arrowUpDown': /^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/, + '\\bond{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\bond{", "", "", "}"); }, + '->': /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/, + 'CMT': /^[CMT](?=\[)/, + '[(...)]': function (input) { return mhchemParser.patterns.findObserveGroups(input, "[", "", "", "]"); }, + '1st-level escape': /^(&|\\\\|\\hline)\s*/, + '\\,': /^(?:\\[,\ ;:])/, // \\x - but output no space before + '\\x{}{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); }, + '\\x{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", ""); }, + '\\ca': /^\\ca(?:\s+|(?![a-zA-Z]))/, + '\\x': /^(?:\\[a-zA-Z]+\s*|\\[_&{}%])/, + 'orbital': /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/, // only those with numbers in front, because the others will be formatted correctly anyway + 'others': /^[\/~|]/, + '\\frac{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\frac{", "", "", "}", "{", "", "", "}"); }, + '\\overset{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\overset{", "", "", "}", "{", "", "", "}"); }, + '\\underset{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\underset{", "", "", "}", "{", "", "", "}"); }, + '\\underbrace{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\underbrace{", "", "", "}_", "{", "", "", "}"); }, + '\\color{(...)}0': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}"); }, + '\\color{(...)}{(...)}1': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}", "{", "", "", "}"); }, + '\\color(...){(...)}2': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\color", "\\", "", /^(?=\{)/, "{", "", "", "}"); }, + '\\ce{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\ce{", "", "", "}"); }, + 'oxidation$': /^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, + 'd-oxidation$': /^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, // 0 could be oxidation or charge + 'roman numeral': /^[IVX]+/, + '1/2$': /^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/, + 'amount': function (input) { + var match; + // e.g. 2, 0.5, 1/2, -2, n/2, +; $a$ could be added later in parsing + match = input.match(/^(?:(?:(?:\([+\-]?[0-9]+\/[0-9]+\)|[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+|[+\-]?[0-9]+[.,][0-9]+|[+\-]?\.[0-9]+|[+\-]?[0-9]+)(?:[a-z](?=\s*[A-Z]))?)|[+\-]?[a-z](?=\s*[A-Z])|\+(?!\s))/); + if (match) { + return { match_: match[0], remainder: input.substr(match[0].length) }; + } + var a = mhchemParser.patterns.findObserveGroups(input, "", "$", "$", ""); + if (a) { // e.g. $2n-1$, $-$ + match = a.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/); + if (match) { + return { match_: match[0], remainder: input.substr(match[0].length) }; + } + } + return null; + }, + 'amount2': function (input) { return this['amount'](input); }, + '(KV letters),': /^(?:[A-Z][a-z]{0,2}|i)(?=,)/, + 'formula$': function (input) { + if (input.match(/^\([a-z]+\)$/)) { return null; } // state of aggregation = no formula + var match = input.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/); + if (match) { + return { match_: match[0], remainder: input.substr(match[0].length) }; + } + return null; + }, + 'uprightEntities': /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/, + '/': /^\s*(\/)\s*/, + '//': /^\s*(\/\/)\s*/, + '*': /^\s*[*.]\s*/ + }, + findObserveGroups: function (input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) { + /** @type {{(input: string, pattern: string | RegExp): string | string[] | null;}} */ + var _match = function (input, pattern) { + if (typeof pattern === "string") { + if (input.indexOf(pattern) !== 0) { return null; } + return pattern; + } else { + var match = input.match(pattern); + if (!match) { return null; } + return match[0]; + } + }; + /** @type {{(input: string, i: number, endChars: string | RegExp): {endMatchBegin: number, endMatchEnd: number} | null;}} */ + var _findObserveGroups = function (input, i, endChars) { + var braces = 0; + while (i < input.length) { + var a = input.charAt(i); + var match = _match(input.substr(i), endChars); + if (match !== null && braces === 0) { + return { endMatchBegin: i, endMatchEnd: i + match.length }; + } else if (a === "{") { + braces++; + } else if (a === "}") { + if (braces === 0) { + throw ["ExtraCloseMissingOpen", "Extra close brace or missing open brace"]; + } else { + braces--; + } + } + i++; + } + if (braces > 0) { + return null; + } + return null; + }; + var match = _match(input, begExcl); + if (match === null) { return null; } + input = input.substr(match.length); + match = _match(input, begIncl); + if (match === null) { return null; } + var e = _findObserveGroups(input, match.length, endIncl || endExcl); + if (e === null) { return null; } + var match1 = input.substring(0, (endIncl ? e.endMatchEnd : e.endMatchBegin)); + if (!(beg2Excl || beg2Incl)) { + return { + match_: match1, + remainder: input.substr(e.endMatchEnd) + }; + } else { + var group2 = this.findObserveGroups(input.substr(e.endMatchEnd), beg2Excl, beg2Incl, end2Incl, end2Excl); + if (group2 === null) { return null; } + /** @type {string[]} */ + var matchRet = [match1, group2.match_]; + return { + match_: (combine ? matchRet.join("") : matchRet), + remainder: group2.remainder + }; + } + }, + + // + // Matching function + // e.g. match("a", input) will look for the regexp called "a" and see if it matches + // returns null or {match_:"a", remainder:"bc"} + // + match_: function (m, input) { + var pattern = mhchemParser.patterns.patterns[m]; + if (pattern === undefined) { + throw ["MhchemBugP", "mhchem bug P. Please report. (" + m + ")"]; // Trying to use non-existing pattern + } else if (typeof pattern === "function") { + return mhchemParser.patterns.patterns[m](input); // cannot use cached var pattern here, because some pattern functions need this===mhchemParser + } else { // RegExp + var match = input.match(pattern); + if (match) { + var mm; + if (match[2]) { + mm = [ match[1], match[2] ]; + } else if (match[1]) { + mm = match[1]; + } else { + mm = match[0]; + } + return { match_: mm, remainder: input.substr(match[0].length) }; + } + return null; + } + } + }, + + // + // Generic state machine actions + // + actions: { + 'a=': function (buffer, m) { buffer.a = (buffer.a || "") + m; }, + 'b=': function (buffer, m) { buffer.b = (buffer.b || "") + m; }, + 'p=': function (buffer, m) { buffer.p = (buffer.p || "") + m; }, + 'o=': function (buffer, m) { buffer.o = (buffer.o || "") + m; }, + 'q=': function (buffer, m) { buffer.q = (buffer.q || "") + m; }, + 'd=': function (buffer, m) { buffer.d = (buffer.d || "") + m; }, + 'rm=': function (buffer, m) { buffer.rm = (buffer.rm || "") + m; }, + 'text=': function (buffer, m) { buffer.text_ = (buffer.text_ || "") + m; }, + 'insert': function (buffer, m, a) { return { type_: a }; }, + 'insert+p1': function (buffer, m, a) { return { type_: a, p1: m }; }, + 'insert+p1+p2': function (buffer, m, a) { return { type_: a, p1: m[0], p2: m[1] }; }, + 'copy': function (buffer, m) { return m; }, + 'rm': function (buffer, m) { return { type_: 'rm', p1: m || ""}; }, + 'text': function (buffer, m) { return mhchemParser.go(m, 'text'); }, + '{text}': function (buffer, m) { + var ret = [ "{" ]; + mhchemParser.concatArray(ret, mhchemParser.go(m, 'text')); + ret.push("}"); + return ret; + }, + 'tex-math': function (buffer, m) { return mhchemParser.go(m, 'tex-math'); }, + 'tex-math tight': function (buffer, m) { return mhchemParser.go(m, 'tex-math tight'); }, + 'bond': function (buffer, m, k) { return { type_: 'bond', kind_: k || m }; }, + 'color0-output': function (buffer, m) { return { type_: 'color0', color: m[0] }; }, + 'ce': function (buffer, m) { return mhchemParser.go(m); }, + '1/2': function (buffer, m) { + /** @type {ParserOutput[]} */ + var ret = []; + if (m.match(/^[+\-]/)) { + ret.push(m.substr(0, 1)); + m = m.substr(1); + } + var n = m.match(/^([0-9]+|\$[a-z]\$|[a-z])\/([0-9]+)(\$[a-z]\$|[a-z])?$/); + n[1] = n[1].replace(/\$/g, ""); + ret.push({ type_: 'frac', p1: n[1], p2: n[2] }); + if (n[3]) { + n[3] = n[3].replace(/\$/g, ""); + ret.push({ type_: 'tex-math', p1: n[3] }); + } + return ret; + }, + '9,9': function (buffer, m) { return mhchemParser.go(m, '9,9'); } + }, + // + // createTransitions + // convert { 'letter': { 'state': { action_: 'output' } } } to { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] } + // with expansion of 'a|b' to 'a' and 'b' (at 2 places) + // + createTransitions: function (o) { + var pattern, state; + /** @type {string[]} */ + var stateArray; + var i; + // + // 1. Collect all states + // + /** @type {Transitions} */ + var transitions = {}; + for (pattern in o) { + for (state in o[pattern]) { + stateArray = state.split("|"); + o[pattern][state].stateArray = stateArray; + for (i=0; i': { + '0|1|2|3': { action_: 'r=', nextState: 'r' }, + 'a|as': { action_: [ 'output', 'r=' ], nextState: 'r' }, + '*': { action_: [ 'output', 'r=' ], nextState: 'r' } }, + '+': { + 'o': { action_: 'd= kv', nextState: 'd' }, + 'd|D': { action_: 'd=', nextState: 'd' }, + 'q': { action_: 'd=', nextState: 'qd' }, + 'qd|qD': { action_: 'd=', nextState: 'qd' }, + 'dq': { action_: [ 'output', 'd=' ], nextState: 'd' }, + '3': { action_: [ 'sb=false', 'output', 'operator' ], nextState: '0' } }, + 'amount': { + '0|2': { action_: 'a=', nextState: 'a' } }, + 'pm-operator': { + '0|1|2|a|as': { action_: [ 'sb=false', 'output', { type_: 'operator', option: '\\pm' } ], nextState: '0' } }, + 'operator': { + '0|1|2|a|as': { action_: [ 'sb=false', 'output', 'operator' ], nextState: '0' } }, + '-$': { + 'o|q': { action_: [ 'charge or bond', 'output' ], nextState: 'qd' }, + 'd': { action_: 'd=', nextState: 'd' }, + 'D': { action_: [ 'output', { type_: 'bond', option: "-" } ], nextState: '3' }, + 'q': { action_: 'd=', nextState: 'qd' }, + 'qd': { action_: 'd=', nextState: 'qd' }, + 'qD|dq': { action_: [ 'output', { type_: 'bond', option: "-" } ], nextState: '3' } }, + '-9': { + '3|o': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '3' } }, + '- orbital overlap': { + 'o': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '2' }, + 'd': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '2' } }, + '-': { + '0|1|2': { action_: [ { type_: 'output', option: 1 }, 'beginsWithBond=true', { type_: 'bond', option: "-" } ], nextState: '3' }, + '3': { action_: { type_: 'bond', option: "-" } }, + 'a': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '2' }, + 'as': { action_: [ { type_: 'output', option: 2 }, { type_: 'bond', option: "-" } ], nextState: '3' }, + 'b': { action_: 'b=' }, + 'o': { action_: { type_: '- after o/d', option: false }, nextState: '2' }, + 'q': { action_: { type_: '- after o/d', option: false }, nextState: '2' }, + 'd|qd|dq': { action_: { type_: '- after o/d', option: true }, nextState: '2' }, + 'D|qD|p': { action_: [ 'output', { type_: 'bond', option: "-" } ], nextState: '3' } }, + 'amount2': { + '1|3': { action_: 'a=', nextState: 'a' } }, + 'letters': { + '0|1|2|3|a|as|b|p|bp|o': { action_: 'o=', nextState: 'o' }, + 'q|dq': { action_: ['output', 'o='], nextState: 'o' }, + 'd|D|qd|qD': { action_: 'o after d', nextState: 'o' } }, + 'digits': { + 'o': { action_: 'q=', nextState: 'q' }, + 'd|D': { action_: 'q=', nextState: 'dq' }, + 'q': { action_: [ 'output', 'o=' ], nextState: 'o' }, + 'a': { action_: 'o=', nextState: 'o' } }, + 'space A': { + 'b|p|bp': {} }, + 'space': { + 'a': { nextState: 'as' }, + '0': { action_: 'sb=false' }, + '1|2': { action_: 'sb=true' }, + 'r|rt|rd|rdt|rdq': { action_: 'output', nextState: '0' }, + '*': { action_: [ 'output', 'sb=true' ], nextState: '1'} }, + '1st-level escape': { + '1|2': { action_: [ 'output', { type_: 'insert+p1', option: '1st-level escape' } ] }, + '*': { action_: [ 'output', { type_: 'insert+p1', option: '1st-level escape' } ], nextState: '0' } }, + '[(...)]': { + 'r|rt': { action_: 'rd=', nextState: 'rd' }, + 'rd|rdt': { action_: 'rq=', nextState: 'rdq' } }, + '...': { + 'o|d|D|dq|qd|qD': { action_: [ 'output', { type_: 'bond', option: "..." } ], nextState: '3' }, + '*': { action_: [ { type_: 'output', option: 1 }, { type_: 'insert', option: 'ellipsis' } ], nextState: '1' } }, + '. |* ': { + '*': { action_: [ 'output', { type_: 'insert', option: 'addition compound' } ], nextState: '1' } }, + 'state of aggregation $': { + '*': { action_: [ 'output', 'state of aggregation' ], nextState: '1' } }, + '{[(': { + 'a|as|o': { action_: [ 'o=', 'output', 'parenthesisLevel++' ], nextState: '2' }, + '0|1|2|3': { action_: [ 'o=', 'output', 'parenthesisLevel++' ], nextState: '2' }, + '*': { action_: [ 'output', 'o=', 'output', 'parenthesisLevel++' ], nextState: '2' } }, + ')]}': { + '0|1|2|3|b|p|bp|o': { action_: [ 'o=', 'parenthesisLevel--' ], nextState: 'o' }, + 'a|as|d|D|q|qd|qD|dq': { action_: [ 'output', 'o=', 'parenthesisLevel--' ], nextState: 'o' } }, + ', ': { + '*': { action_: [ 'output', 'comma' ], nextState: '0' } }, + '^_': { // ^ and _ without a sensible argument + '*': { } }, + '^{(...)}|^($...$)': { + '0|1|2|as': { action_: 'b=', nextState: 'b' }, + 'p': { action_: 'b=', nextState: 'bp' }, + '3|o': { action_: 'd= kv', nextState: 'D' }, + 'q': { action_: 'd=', nextState: 'qD' }, + 'd|D|qd|qD|dq': { action_: [ 'output', 'd=' ], nextState: 'D' } }, + '^a|^\\x{}{}|^\\x{}|^\\x|\'': { + '0|1|2|as': { action_: 'b=', nextState: 'b' }, + 'p': { action_: 'b=', nextState: 'bp' }, + '3|o': { action_: 'd= kv', nextState: 'd' }, + 'q': { action_: 'd=', nextState: 'qd' }, + 'd|qd|D|qD': { action_: 'd=' }, + 'dq': { action_: [ 'output', 'd=' ], nextState: 'd' } }, + '_{(state of aggregation)}$': { + 'd|D|q|qd|qD|dq': { action_: [ 'output', 'q=' ], nextState: 'q' } }, + '_{(...)}|_($...$)|_9|_\\x{}{}|_\\x{}|_\\x': { + '0|1|2|as': { action_: 'p=', nextState: 'p' }, + 'b': { action_: 'p=', nextState: 'bp' }, + '3|o': { action_: 'q=', nextState: 'q' }, + 'd|D': { action_: 'q=', nextState: 'dq' }, + 'q|qd|qD|dq': { action_: [ 'output', 'q=' ], nextState: 'q' } }, + '=<>': { + '0|1|2|3|a|as|o|q|d|D|qd|qD|dq': { action_: [ { type_: 'output', option: 2 }, 'bond' ], nextState: '3' } }, + '#': { + '0|1|2|3|a|as|o': { action_: [ { type_: 'output', option: 2 }, { type_: 'bond', option: "#" } ], nextState: '3' } }, + '{}': { + '*': { action_: { type_: 'output', option: 1 }, nextState: '1' } }, + '{...}': { + '0|1|2|3|a|as|b|p|bp': { action_: 'o=', nextState: 'o' }, + 'o|d|D|q|qd|qD|dq': { action_: [ 'output', 'o=' ], nextState: 'o' } }, + '$...$': { + 'a': { action_: 'a=' }, // 2$n$ + '0|1|2|3|as|b|p|bp|o': { action_: 'o=', nextState: 'o' }, // not 'amount' + 'as|o': { action_: 'o=' }, + 'q|d|D|qd|qD|dq': { action_: [ 'output', 'o=' ], nextState: 'o' } }, + '\\bond{(...)}': { + '*': { action_: [ { type_: 'output', option: 2 }, 'bond' ], nextState: "3" } }, + '\\frac{(...)}': { + '*': { action_: [ { type_: 'output', option: 1 }, 'frac-output' ], nextState: '3' } }, + '\\overset{(...)}': { + '*': { action_: [ { type_: 'output', option: 2 }, 'overset-output' ], nextState: '3' } }, + '\\underset{(...)}': { + '*': { action_: [ { type_: 'output', option: 2 }, 'underset-output' ], nextState: '3' } }, + '\\underbrace{(...)}': { + '*': { action_: [ { type_: 'output', option: 2 }, 'underbrace-output' ], nextState: '3' } }, + '\\color{(...)}{(...)}1|\\color(...){(...)}2': { + '*': { action_: [ { type_: 'output', option: 2 }, 'color-output' ], nextState: '3' } }, + '\\color{(...)}0': { + '*': { action_: [ { type_: 'output', option: 2 }, 'color0-output' ] } }, + '\\ce{(...)}': { + '*': { action_: [ { type_: 'output', option: 2 }, 'ce' ], nextState: '3' } }, + '\\,': { + '*': { action_: [ { type_: 'output', option: 1 }, 'copy' ], nextState: '1' } }, + '\\x{}{}|\\x{}|\\x': { + '0|1|2|3|a|as|b|p|bp|o|c0': { action_: [ 'o=', 'output' ], nextState: '3' }, + '*': { action_: ['output', 'o=', 'output' ], nextState: '3' } }, + 'others': { + '*': { action_: [ { type_: 'output', option: 1 }, 'copy' ], nextState: '3' } }, + 'else2': { + 'a': { action_: 'a to o', nextState: 'o', revisit: true }, + 'as': { action_: [ 'output', 'sb=true' ], nextState: '1', revisit: true }, + 'r|rt|rd|rdt|rdq': { action_: [ 'output' ], nextState: '0', revisit: true }, + '*': { action_: [ 'output', 'copy' ], nextState: '3' } } + }), + actions: { + 'o after d': function (buffer, m) { + var ret; + if ((buffer.d || "").match(/^[0-9]+$/)) { + var tmp = buffer.d; + buffer.d = undefined; + ret = this['output'](buffer); + buffer.b = tmp; + } else { + ret = this['output'](buffer); + } + mhchemParser.actions['o='](buffer, m); + return ret; + }, + 'd= kv': function (buffer, m) { + buffer.d = m; + buffer.dType = 'kv'; + }, + 'charge or bond': function (buffer, m) { + if (buffer['beginsWithBond']) { + /** @type {ParserOutput[]} */ + var ret = []; + mhchemParser.concatArray(ret, this['output'](buffer)); + mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-")); + return ret; + } else { + buffer.d = m; + } + }, + '- after o/d': function (buffer, m, isAfterD) { + var c1 = mhchemParser.patterns.match_('orbital', buffer.o || ""); + var c2 = mhchemParser.patterns.match_('one lowercase greek letter $', buffer.o || ""); + var c3 = mhchemParser.patterns.match_('one lowercase latin letter $', buffer.o || ""); + var c4 = mhchemParser.patterns.match_('$one lowercase latin letter$ $', buffer.o || ""); + var hyphenFollows = m==="-" && ( c1 && c1.remainder==="" || c2 || c3 || c4 ); + if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) { + buffer.o = '$' + buffer.o + '$'; + } + /** @type {ParserOutput[]} */ + var ret = []; + if (hyphenFollows) { + mhchemParser.concatArray(ret, this['output'](buffer)); + ret.push({ type_: 'hyphen' }); + } else { + c1 = mhchemParser.patterns.match_('digits', buffer.d || ""); + if (isAfterD && c1 && c1.remainder==='') { + mhchemParser.concatArray(ret, mhchemParser.actions['d='](buffer, m)); + mhchemParser.concatArray(ret, this['output'](buffer)); + } else { + mhchemParser.concatArray(ret, this['output'](buffer)); + mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-")); + } + } + return ret; + }, + 'a to o': function (buffer) { + buffer.o = buffer.a; + buffer.a = undefined; + }, + 'sb=true': function (buffer) { buffer.sb = true; }, + 'sb=false': function (buffer) { buffer.sb = false; }, + 'beginsWithBond=true': function (buffer) { buffer['beginsWithBond'] = true; }, + 'beginsWithBond=false': function (buffer) { buffer['beginsWithBond'] = false; }, + 'parenthesisLevel++': function (buffer) { buffer['parenthesisLevel']++; }, + 'parenthesisLevel--': function (buffer) { buffer['parenthesisLevel']--; }, + 'state of aggregation': function (buffer, m) { + return { type_: 'state of aggregation', p1: mhchemParser.go(m, 'o') }; + }, + 'comma': function (buffer, m) { + var a = m.replace(/\s*$/, ''); + var withSpace = (a !== m); + if (withSpace && buffer['parenthesisLevel'] === 0) { + return { type_: 'comma enumeration L', p1: a }; + } else { + return { type_: 'comma enumeration M', p1: a }; + } + }, + 'output': function (buffer, m, entityFollows) { + // entityFollows: + // undefined = if we have nothing else to output, also ignore the just read space (buffer.sb) + // 1 = an entity follows, never omit the space if there was one just read before (can only apply to state 1) + // 2 = 1 + the entity can have an amount, so output a\, instead of converting it to o (can only apply to states a|as) + /** @type {ParserOutput | ParserOutput[]} */ + var ret; + if (!buffer.r) { + ret = []; + if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) { + //ret = []; + } else { + if (buffer.sb) { + ret.push({ type_: 'entitySkip' }); + } + if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows!==2) { + buffer.o = buffer.a; + buffer.a = undefined; + } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) { + buffer.o = buffer.a; + buffer.d = buffer.b; + buffer.q = buffer.p; + buffer.a = buffer.b = buffer.p = undefined; + } else { + if (buffer.o && buffer.dType==='kv' && mhchemParser.patterns.match_('d-oxidation$', buffer.d || "")) { + buffer.dType = 'oxidation'; + } else if (buffer.o && buffer.dType==='kv' && !buffer.q) { + buffer.dType = undefined; + } + } + ret.push({ + type_: 'chemfive', + a: mhchemParser.go(buffer.a, 'a'), + b: mhchemParser.go(buffer.b, 'bd'), + p: mhchemParser.go(buffer.p, 'pq'), + o: mhchemParser.go(buffer.o, 'o'), + q: mhchemParser.go(buffer.q, 'pq'), + d: mhchemParser.go(buffer.d, (buffer.dType === 'oxidation' ? 'oxidation' : 'bd')), + dType: buffer.dType + }); + } + } else { // r + /** @type {ParserOutput[]} */ + var rd; + if (buffer.rdt === 'M') { + rd = mhchemParser.go(buffer.rd, 'tex-math'); + } else if (buffer.rdt === 'T') { + rd = [ { type_: 'text', p1: buffer.rd || "" } ]; + } else { + rd = mhchemParser.go(buffer.rd); + } + /** @type {ParserOutput[]} */ + var rq; + if (buffer.rqt === 'M') { + rq = mhchemParser.go(buffer.rq, 'tex-math'); + } else if (buffer.rqt === 'T') { + rq = [ { type_: 'text', p1: buffer.rq || ""} ]; + } else { + rq = mhchemParser.go(buffer.rq); + } + ret = { + type_: 'arrow', + r: buffer.r, + rd: rd, + rq: rq + }; + } + for (var p in buffer) { + if (p !== 'parenthesisLevel' && p !== 'beginsWithBond') { + delete buffer[p]; + } + } + return ret; + }, + 'oxidation-output': function (buffer, m) { + var ret = [ "{" ]; + mhchemParser.concatArray(ret, mhchemParser.go(m, 'oxidation')); + ret.push("}"); + return ret; + }, + 'frac-output': function (buffer, m) { + return { type_: 'frac-ce', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) }; + }, + 'overset-output': function (buffer, m) { + return { type_: 'overset', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) }; + }, + 'underset-output': function (buffer, m) { + return { type_: 'underset', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) }; + }, + 'underbrace-output': function (buffer, m) { + return { type_: 'underbrace', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) }; + }, + 'color-output': function (buffer, m) { + return { type_: 'color', color1: m[0], color2: mhchemParser.go(m[1]) }; + }, + 'r=': function (buffer, m) { buffer.r = m; }, + 'rdt=': function (buffer, m) { buffer.rdt = m; }, + 'rd=': function (buffer, m) { buffer.rd = m; }, + 'rqt=': function (buffer, m) { buffer.rqt = m; }, + 'rq=': function (buffer, m) { buffer.rq = m; }, + 'operator': function (buffer, m, p1) { return { type_: 'operator', kind_: (p1 || m) }; } + } + }, + 'a': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': {} }, + '1/2$': { + '0': { action_: '1/2' } }, + 'else': { + '0': { nextState: '1', revisit: true } }, + '$(...)$': { + '*': { action_: 'tex-math tight', nextState: '1' } }, + ',': { + '*': { action_: { type_: 'insert', option: 'commaDecimal' } } }, + 'else2': { + '*': { action_: 'copy' } } + }), + actions: {} + }, + 'o': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': {} }, + '1/2$': { + '0': { action_: '1/2' } }, + 'else': { + '0': { nextState: '1', revisit: true } }, + 'letters': { + '*': { action_: 'rm' } }, + '\\ca': { + '*': { action_: { type_: 'insert', option: 'circa' } } }, + '\\x{}{}|\\x{}|\\x': { + '*': { action_: 'copy' } }, + '${(...)}$|$(...)$': { + '*': { action_: 'tex-math' } }, + '{(...)}': { + '*': { action_: '{text}' } }, + 'else2': { + '*': { action_: 'copy' } } + }), + actions: {} + }, + 'text': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': { action_: 'output' } }, + '{...}': { + '*': { action_: 'text=' } }, + '${(...)}$|$(...)$': { + '*': { action_: 'tex-math' } }, + '\\greek': { + '*': { action_: [ 'output', 'rm' ] } }, + '\\,|\\x{}{}|\\x{}|\\x': { + '*': { action_: [ 'output', 'copy' ] } }, + 'else': { + '*': { action_: 'text=' } } + }), + actions: { + 'output': function (buffer) { + if (buffer.text_) { + /** @type {ParserOutput} */ + var ret = { type_: 'text', p1: buffer.text_ }; + for (var p in buffer) { delete buffer[p]; } + return ret; + } + } + } + }, + 'pq': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': {} }, + 'state of aggregation $': { + '*': { action_: 'state of aggregation' } }, + 'i$': { + '0': { nextState: '!f', revisit: true } }, + '(KV letters),': { + '0': { action_: 'rm', nextState: '0' } }, + 'formula$': { + '0': { nextState: 'f', revisit: true } }, + '1/2$': { + '0': { action_: '1/2' } }, + 'else': { + '0': { nextState: '!f', revisit: true } }, + '${(...)}$|$(...)$': { + '*': { action_: 'tex-math' } }, + '{(...)}': { + '*': { action_: 'text' } }, + 'a-z': { + 'f': { action_: 'tex-math' } }, + 'letters': { + '*': { action_: 'rm' } }, + '-9.,9': { + '*': { action_: '9,9' } }, + ',': { + '*': { action_: { type_: 'insert+p1', option: 'comma enumeration S' } } }, + '\\color{(...)}{(...)}1|\\color(...){(...)}2': { + '*': { action_: 'color-output' } }, + '\\color{(...)}0': { + '*': { action_: 'color0-output' } }, + '\\ce{(...)}': { + '*': { action_: 'ce' } }, + '\\,|\\x{}{}|\\x{}|\\x': { + '*': { action_: 'copy' } }, + 'else2': { + '*': { action_: 'copy' } } + }), + actions: { + 'state of aggregation': function (buffer, m) { + return { type_: 'state of aggregation subscript', p1: mhchemParser.go(m, 'o') }; + }, + 'color-output': function (buffer, m) { + return { type_: 'color', color1: m[0], color2: mhchemParser.go(m[1], 'pq') }; + } + } + }, + 'bd': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': {} }, + 'x$': { + '0': { nextState: '!f', revisit: true } }, + 'formula$': { + '0': { nextState: 'f', revisit: true } }, + 'else': { + '0': { nextState: '!f', revisit: true } }, + '-9.,9 no missing 0': { + '*': { action_: '9,9' } }, + '.': { + '*': { action_: { type_: 'insert', option: 'electron dot' } } }, + 'a-z': { + 'f': { action_: 'tex-math' } }, + 'x': { + '*': { action_: { type_: 'insert', option: 'KV x' } } }, + 'letters': { + '*': { action_: 'rm' } }, + '\'': { + '*': { action_: { type_: 'insert', option: 'prime' } } }, + '${(...)}$|$(...)$': { + '*': { action_: 'tex-math' } }, + '{(...)}': { + '*': { action_: 'text' } }, + '\\color{(...)}{(...)}1|\\color(...){(...)}2': { + '*': { action_: 'color-output' } }, + '\\color{(...)}0': { + '*': { action_: 'color0-output' } }, + '\\ce{(...)}': { + '*': { action_: 'ce' } }, + '\\,|\\x{}{}|\\x{}|\\x': { + '*': { action_: 'copy' } }, + 'else2': { + '*': { action_: 'copy' } } + }), + actions: { + 'color-output': function (buffer, m) { + return { type_: 'color', color1: m[0], color2: mhchemParser.go(m[1], 'bd') }; + } + } + }, + 'oxidation': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': {} }, + 'roman numeral': { + '*': { action_: 'roman-numeral' } }, + '${(...)}$|$(...)$': { + '*': { action_: 'tex-math' } }, + 'else': { + '*': { action_: 'copy' } } + }), + actions: { + 'roman-numeral': function (buffer, m) { return { type_: 'roman numeral', p1: m || "" }; } + } + }, + 'tex-math': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': { action_: 'output' } }, + '\\ce{(...)}': { + '*': { action_: [ 'output', 'ce' ] } }, + '{...}|\\,|\\x{}{}|\\x{}|\\x': { + '*': { action_: 'o=' } }, + 'else': { + '*': { action_: 'o=' } } + }), + actions: { + 'output': function (buffer) { + if (buffer.o) { + /** @type {ParserOutput} */ + var ret = { type_: 'tex-math', p1: buffer.o }; + for (var p in buffer) { delete buffer[p]; } + return ret; + } + } + } + }, + 'tex-math tight': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': { action_: 'output' } }, + '\\ce{(...)}': { + '*': { action_: [ 'output', 'ce' ] } }, + '{...}|\\,|\\x{}{}|\\x{}|\\x': { + '*': { action_: 'o=' } }, + '-|+': { + '*': { action_: 'tight operator' } }, + 'else': { + '*': { action_: 'o=' } } + }), + actions: { + 'tight operator': function (buffer, m) { buffer.o = (buffer.o || "") + "{"+m+"}"; }, + 'output': function (buffer) { + if (buffer.o) { + /** @type {ParserOutput} */ + var ret = { type_: 'tex-math', p1: buffer.o }; + for (var p in buffer) { delete buffer[p]; } + return ret; + } + } + } + }, + '9,9': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': {} }, + ',': { + '*': { action_: 'comma' } }, + 'else': { + '*': { action_: 'copy' } } + }), + actions: { + 'comma': function () { return { type_: 'commaDecimal' }; } + } + }, + //#endregion + // + // \pu state machines + // + //#region pu + 'pu': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': { action_: 'output' } }, + 'space$': { + '*': { action_: [ 'output', 'space' ] } }, + '{[(|)]}': { + '0|a': { action_: 'copy' } }, + '(-)(9)^(-9)': { + '0': { action_: 'number^', nextState: 'a' } }, + '(-)(9.,9)(e)(99)': { + '0': { action_: 'enumber', nextState: 'a' } }, + 'space': { + '0|a': {} }, + 'pm-operator': { + '0|a': { action_: { type_: 'operator', option: '\\pm' }, nextState: '0' } }, + 'operator': { + '0|a': { action_: 'copy', nextState: '0' } }, + '//': { + 'd': { action_: 'o=', nextState: '/' } }, + '/': { + 'd': { action_: 'o=', nextState: '/' } }, + '{...}|else': { + '0|d': { action_: 'd=', nextState: 'd' }, + 'a': { action_: [ 'space', 'd=' ], nextState: 'd' }, + '/|q': { action_: 'q=', nextState: 'q' } } + }), + actions: { + 'enumber': function (buffer, m) { + /** @type {ParserOutput[]} */ + var ret = []; + if (m[0] === "+-" || m[0] === "+/-") { + ret.push("\\pm "); + } else if (m[0]) { + ret.push(m[0]); + } + if (m[1]) { // 1.2 + mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9')); + if (m[2]) { + if (m[2].match(/[,.]/)) { // 1.23456(0.01111) + mhchemParser.concatArray(ret, mhchemParser.go(m[2], 'pu-9,9')); + } else { // 1.23456(1111) - without spacings + ret.push(m[2]); + } + } + if (m[3] || m[4]) { // 1.2e7 1.2x10^7 + if (m[3] === "e" || m[4] === "*") { + ret.push({ type_: 'cdot' }); + } else { + ret.push({ type_: 'times' }); + } + } + } + if (m[5]) { // 10^7 + ret.push("10^{"+m[5]+"}"); + } + return ret; + }, + 'number^': function (buffer, m) { + /** @type {ParserOutput[]} */ + var ret = []; + if (m[0] === "+-" || m[0] === "+/-") { + ret.push("\\pm "); + } else if (m[0]) { + ret.push(m[0]); + } + mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9')); + ret.push("^{"+m[2]+"}"); + return ret; + }, + 'operator': function (buffer, m, p1) { return { type_: 'operator', kind_: (p1 || m) }; }, + 'space': function () { return { type_: 'pu-space-1' }; }, + 'output': function (buffer) { + /** @type {ParserOutput | ParserOutput[]} */ + var ret; + var md = mhchemParser.patterns.match_('{(...)}', buffer.d || ""); + if (md && md.remainder === '') { buffer.d = md.match_; } + var mq = mhchemParser.patterns.match_('{(...)}', buffer.q || ""); + if (mq && mq.remainder === '') { buffer.q = mq.match_; } + if (buffer.d) { + buffer.d = buffer.d.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C"); + buffer.d = buffer.d.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F"); + } + if (buffer.q) { // fraction + buffer.q = buffer.q.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C"); + buffer.q = buffer.q.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F"); + var b5 = { + d: mhchemParser.go(buffer.d, 'pu'), + q: mhchemParser.go(buffer.q, 'pu') + }; + if (buffer.o === '//') { + ret = { type_: 'pu-frac', p1: b5.d, p2: b5.q }; + } else { + ret = b5.d; + if (b5.d.length > 1 || b5.q.length > 1) { + ret.push({ type_: ' / ' }); + } else { + ret.push({ type_: '/' }); + } + mhchemParser.concatArray(ret, b5.q); + } + } else { // no fraction + ret = mhchemParser.go(buffer.d, 'pu-2'); + } + for (var p in buffer) { delete buffer[p]; } + return ret; + } + } + }, + 'pu-2': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '*': { action_: 'output' } }, + '*': { + '*': { action_: [ 'output', 'cdot' ], nextState: '0' } }, + '\\x': { + '*': { action_: 'rm=' } }, + 'space': { + '*': { action_: [ 'output', 'space' ], nextState: '0' } }, + '^{(...)}|^(-1)': { + '1': { action_: '^(-1)' } }, + '-9.,9': { + '0': { action_: 'rm=', nextState: '0' }, + '1': { action_: '^(-1)', nextState: '0' } }, + '{...}|else': { + '*': { action_: 'rm=', nextState: '1' } } + }), + actions: { + 'cdot': function () { return { type_: 'tight cdot' }; }, + '^(-1)': function (buffer, m) { buffer.rm += "^{"+m+"}"; }, + 'space': function () { return { type_: 'pu-space-2' }; }, + 'output': function (buffer) { + /** @type {ParserOutput | ParserOutput[]} */ + var ret = []; + if (buffer.rm) { + var mrm = mhchemParser.patterns.match_('{(...)}', buffer.rm || ""); + if (mrm && mrm.remainder === '') { + ret = mhchemParser.go(mrm.match_, 'pu'); + } else { + ret = { type_: 'rm', p1: buffer.rm }; + } + } + for (var p in buffer) { delete buffer[p]; } + return ret; + } + } + }, + 'pu-9,9': { + transitions: mhchemParser.createTransitions({ + 'empty': { + '0': { action_: 'output-0' }, + 'o': { action_: 'output-o' } }, + ',': { + '0': { action_: [ 'output-0', 'comma' ], nextState: 'o' } }, + '.': { + '0': { action_: [ 'output-0', 'copy' ], nextState: 'o' } }, + 'else': { + '*': { action_: 'text=' } } + }), + actions: { + 'comma': function () { return { type_: 'commaDecimal' }; }, + 'output-0': function (buffer) { + /** @type {ParserOutput[]} */ + var ret = []; + buffer.text_ = buffer.text_ || ""; + if (buffer.text_.length > 4) { + var a = buffer.text_.length % 3; + if (a === 0) { a = 3; } + for (var i=buffer.text_.length-3; i>0; i-=3) { + ret.push(buffer.text_.substr(i, 3)); + ret.push({ type_: '1000 separator' }); + } + ret.push(buffer.text_.substr(0, a)); + ret.reverse(); + } else { + ret.push(buffer.text_); + } + for (var p in buffer) { delete buffer[p]; } + return ret; + }, + 'output-o': function (buffer) { + /** @type {ParserOutput[]} */ + var ret = []; + buffer.text_ = buffer.text_ || ""; + if (buffer.text_.length > 4) { + var a = buffer.text_.length - 3; + for (var i=0; i" || buf.r === "<=>>" || buf.r === "<<=>" || buf.r === "<-->") { + // arrows that cannot stretch correctly yet, https://github.com/mathjax/MathJax/issues/1491 + arrow = "\\long"+arrow; + if (b6.rd) { arrow = "\\overset{"+b6.rd+"}{"+arrow+"}"; } + if (b6.rq) { + if (buf.r === "<-->") { + arrow = "\\underset{\\lower2mu{"+b6.rq+"}}{"+arrow+"}"; + } else { + arrow = "\\underset{\\lower6mu{"+b6.rq+"}}{"+arrow+"}"; // align with ->[][under] + } + } + arrow = " {}\\mathrel{"+arrow+"}{} "; + } else { + if (b6.rq) { arrow += "[{"+b6.rq+"}]"; } + arrow += "{"+b6.rd+"}"; + arrow = " {}\\mathrel{\\x"+arrow+"}{} "; + } + } else { + arrow = " {}\\mathrel{\\long"+arrow+"}{} "; + } + res = arrow; + break; + case 'operator': + res = texify._getOperator(buf.kind_); + break; + case '1st-level escape': + res = buf.p1+" "; // &, \\\\, \\hlin + break; + case 'space': + res = " "; + break; + case 'entitySkip': + res = "~"; + break; + case 'pu-space-1': + res = "~"; + break; + case 'pu-space-2': + res = "\\mkern3mu "; + break; + case '1000 separator': + res = "\\mkern2mu "; + break; + case 'commaDecimal': + res = "{,}"; + break; + case 'comma enumeration L': + res = "{"+buf.p1+"}\\mkern6mu "; + break; + case 'comma enumeration M': + res = "{"+buf.p1+"}\\mkern3mu "; + break; + case 'comma enumeration S': + res = "{"+buf.p1+"}\\mkern1mu "; + break; + case 'hyphen': + res = "\\text{-}"; + break; + case 'addition compound': + res = "\\,{\\cdot}\\,"; + break; + case 'electron dot': + res = "\\mkern1mu \\bullet\\mkern1mu "; + break; + case 'KV x': + res = "{\\times}"; + break; + case 'prime': + res = "\\prime "; + break; + case 'cdot': + res = "\\cdot "; + break; + case 'tight cdot': + res = "\\mkern1mu{\\cdot}\\mkern1mu "; + break; + case 'times': + res = "\\times "; + break; + case 'circa': + res = "{\\sim}"; + break; + case '^': + res = "uparrow"; + break; + case 'v': + res = "downarrow"; + break; + case 'ellipsis': + res = "\\ldots "; + break; + case '/': + res = "/"; + break; + case ' / ': + res = "\\,/\\,"; + break; + default: + assertNever(buf); + throw ["MhchemBugT", "mhchem bug T. Please report."]; // Missing texify rule or unknown MhchemParser output + } + assertString(res); + return res; + }, + _getArrow: function (a) { + switch (a) { + case "->": return "rightarrow"; + case "\u2192": return "rightarrow"; + case "\u27F6": return "rightarrow"; + case "<-": return "leftarrow"; + case "<->": return "leftrightarrow"; + case "<-->": return "leftrightarrows"; + case "<=>": return "rightleftharpoons"; + case "\u21CC": return "rightleftharpoons"; + case "<=>>": return "Rightleftharpoons"; + case "<<=>": return "Leftrightharpoons"; + default: + assertNever(a); + throw ["MhchemBugT", "mhchem bug T. Please report."]; + } + }, + _getBond: function (a) { + switch (a) { + case "-": return "{-}"; + case "1": return "{-}"; + case "=": return "{=}"; + case "2": return "{=}"; + case "#": return "{\\equiv}"; + case "3": return "{\\equiv}"; + case "~": return "{\\tripledash}"; + case "~-": return "{\\rlap{\\lower.1em{-}}\\raise.1em{\\tripledash}}"; + case "~=": return "{\\rlap{\\lower.2em{-}}\\rlap{\\raise.2em{\\tripledash}}-}"; + case "~--": return "{\\rlap{\\lower.2em{-}}\\rlap{\\raise.2em{\\tripledash}}-}"; + case "-~-": return "{\\rlap{\\lower.2em{-}}\\rlap{\\raise.2em{-}}\\tripledash}"; + case "...": return "{{\\cdot}{\\cdot}{\\cdot}}"; + case "....": return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}"; + case "->": return "{\\rightarrow}"; + case "<-": return "{\\leftarrow}"; + case "<": return "{<}"; + case ">": return "{>}"; + default: + assertNever(a); + throw ["MhchemBugT", "mhchem bug T. Please report."]; + } + }, + _getOperator: function (a) { + switch (a) { + case "+": return " {}+{} "; + case "-": return " {}-{} "; + case "=": return " {}={} "; + case "<": return " {}<{} "; + case ">": return " {}>{} "; + case "<<": return " {}\\ll{} "; + case ">>": return " {}\\gg{} "; + case "\\pm": return " {}\\pm{} "; + case "\\approx": return " {}\\approx{} "; + case "$\\approx$": return " {}\\approx{} "; + case "v": return " \\downarrow{} "; + case "(v)": return " \\downarrow{} "; + case "^": return " \\uparrow{} "; + case "(^)": return " \\uparrow{} "; + default: + assertNever(a); + throw ["MhchemBugT", "mhchem bug T. Please report."]; + } + } + }; + + // + // Helpers for code anaylsis + // Will show type error at calling position + // + /** @param {number} a */ + function assertNever(a) {} + /** @param {string} a */ + function assertString(a) {} + + // + // MathJax definitions + // + MathJax.Extension["TeX/mhchem"].CE = CE; + + /***************************************************************************/ + + TEX.Definitions.Add({ + macros: { + // + // Set up the macros for chemistry + // + ce: "CE", + pu: "PU", + + // + // 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}}{\\smash{\\leftharpoondown}}"], + longLeftrightharpoons: ["Macro", "\\stackrel{\\textstyle\\vphantom{{-}}{\\rightharpoonup}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"], + longleftrightarrows: ["Macro", "\\raise-3mu{\\stackrel{\\longrightarrow}{\\raise2mu{\\smash{\\longleftarrow}}}}"], + + // + // Needed for \bond for the ~ forms + // Not perfectly aligned when zoomed in, but on 100% + // + tripledash: ["Macro", "\\vphantom{-}\\raise2mu{\\kern2mu\\tiny\\text{-}\\kern1mu\\text{-}\\kern1mu\\text{-}\\kern2mu}"] + } + }, null, true); + + if (!MathJax.Extension["TeX/AMSmath"]) { + TEX.Definitions.Add({ + macros: { + xrightarrow: ["Extension", "AMSmath"], + xleftarrow: ["Extension", "AMSmath"] + } + }, null, true); + } + + // + // These arrows need to wait until AMSmath is loaded + // + 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({ + + // + // Implements \ce and friends + // + CE: function (name) { + var arg = this.GetArgument(name); + var tex = CE(arg).Parse(); + this.string = tex + this.string.substr(this.i); this.i = 0; + }, + + PU: function (name) { + var arg = this.GetArgument(name); + var tex = CE(arg).Parse('pu'); + this.string = tex + this.string.substr(this.i); this.i = 0; + } + + }); + + // + // Indicate that the extension is ready + // + MathJax.Hub.Startup.signal.Post("TeX mhchem Ready"); + +}); + +MathJax.Ajax.loadComplete("[mhchem]/mhchem.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/newcommand.js b/js/mathjax/extensions/TeX/newcommand.js new file mode 100644 index 0000000..d106811 --- /dev/null +++ b/js/mathjax/extensions/TeX/newcommand.js @@ -0,0 +1,272 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/newcommand.js + * + * Implements the \newcommand, \newenvironment and \def + * macros, and is loaded automatically when needed. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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/newcommand"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var TEX = MathJax.InputJax.TeX; + var TEXDEF = TEX.Definitions; + + TEXDEF.Add({ + macros: { + newcommand: 'NewCommand', + renewcommand: 'NewCommand', + newenvironment: 'NewEnvironment', + renewenvironment: 'NewEnvironment', + def: 'MacroDef', + 'let': 'Let' + } + },null,true); + + TEX.Parse.Augment({ + + /* + * Implement \newcommand{\name}[n][default]{...} + */ + NewCommand: function (name) { + var cs = this.trimSpaces(this.GetArgument(name)), + n = this.GetBrackets(name), + opt = this.GetBrackets(name), + def = this.GetArgument(name); + if (cs.charAt(0) === "\\") {cs = cs.substr(1)} + 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(["IllegalParamNumber", + "Illegal number of parameters specified in %1",name]); + } + } + this.setDef(cs,['Macro',def,n,opt]); + }, + + /* + * Implement \newenvironment{name}[n][default]{begincmd}{endcmd} + */ + 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(["IllegalParamNumber", + "Illegal number of parameters specified in %1",name]); + } + } + this.setEnv(env,['BeginEnv',[null,'EndEnv'],bdef,edef,n,opt]); + }, + + /* + * Implement \def command + */ + MacroDef: function (name) { + var cs = this.GetCSname(name), + params = this.GetTemplate(name,"\\"+cs), + def = this.GetArgument(name); + if (!(params instanceof Array)) {this.setDef(cs,['Macro',def,params])} + else {this.setDef(cs,['MacroWithTemplate',def].concat(params))} + }, + + /* + * Implements the \let command + */ + Let: function (name) { + var cs = this.GetCSname(name), macro; + var c = this.GetNext(); if (c === "=") {this.i++; c = this.GetNext()} + // + // All \let commands create entries in the macros array, but we + // have to look in the various mathchar and delimiter arrays if + // the source isn't a macro already, and attach the data to a + // macro with the proper routine to process it. + // + // A command of the form \let\cs=char produces a macro equivalent + // to \def\cs{char}, which is as close as MathJax can get for this. + // So \let\bgroup={ is possible, but doesn't work as it does in TeX. + // + if (c === "\\") { + name = this.GetCSname(name); + macro = this.csFindMacro(name); + if (!macro) { + if (TEXDEF.mathchar0mi.hasOwnProperty(name)) {macro = ["csMathchar0mi",TEXDEF.mathchar0mi[name]]} else + if (TEXDEF.mathchar0mo.hasOwnProperty(name)) {macro = ["csMathchar0mo",TEXDEF.mathchar0mo[name]]} else + if (TEXDEF.mathchar7.hasOwnProperty(name)) {macro = ["csMathchar7",TEXDEF.mathchar7[name]]} else + if (TEXDEF.delimiter.hasOwnProperty("\\"+name)) {macro = ["csDelimiter",TEXDEF.delimiter["\\"+name]]} else + return; + } + } else {macro = ["Macro",c]; this.i++} + this.setDef(cs,macro); + }, + + /* + * Get a CS name or give an error + */ + GetCSname: function (cmd) { + var c = this.GetNext(); + 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); + }, + + /* + * Get a \def parameter template + */ + GetTemplate: function (cmd,cs) { + var c, params = [], n = 0; + c = this.GetNext(); var i = this.i; + while (this.i < this.string.length) { + c = this.GetNext(); + 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(["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)} + if (params.length > 0) {return [n,params]} else {return n} + } + this.i++; + } + TEX.Error(["MissingReplacementString", + "Missing replacement string for definition of %1",cmd]); + }, + + /* + * Process a macro with a parameter template + */ + MacroWithTemplate: function (name,text,n,params) { + if (n) { + var args = []; this.GetNext(); + 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(["MaxMacroSub1", + "MathJax maximum macro substitution count exceeded; " + + "is there a recursive macro call?"]); + } + }, + + /* + * Process a user-defined environment + */ + BeginEnv: function (begin,bdef,edef,n,def) { + if (n) { + var args = []; + 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([],edef); // no args, but get errors for #n in edef + } + this.string = this.AddArgs(bdef,this.string.slice(this.i)); this.i = 0; + return begin; + }, + 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; + }, + + /* + * Find a single parameter delimited by a trailing template + */ + GetParameter: function (name,param) { + if (param == null) {return this.GetArgument(name)} + var i = this.i, j = 0, hasBraces = 0; + while (this.i < this.string.length) { + var c = this.string.charAt(this.i); + if (c === '{') { + if (this.i === i) {hasBraces = 1} + this.GetArgument(name); j = this.i - i; + } else if (this.MatchParam(param)) { + if (hasBraces) {i++; j -= 2} + return this.string.substr(i,j); + } else if (c === "\\") { + this.i++; j++; hasBraces = 0; + var match = this.string.substr(this.i).match(/[a-z]+|./i); + if (match) {this.i += match[0].length; j = this.i - i} + } else { + this.i++; j++; hasBraces = 0; + } + } + TEX.Error(["RunawayArgument","Runaway argument for %1?",name]); + }, + + /* + * Check if a template is at the current location. + * (The match must be exact, with no spacing differences. TeX is + * a little more forgiving than this about spaces after macro names) + */ + MatchParam: function (param) { + if (this.string.substr(this.i,param.length) !== param) {return 0} + if (param.match(/\\[a-z]+$/i) && + this.string.charAt(this.i+param.length).match(/[a-z]/i)) {return 0} + this.i += param.length; + return 1; + } + + }); + + TEX.Environment = function (name) { + TEXDEF.environment[name] = ['BeginEnv',[null,'EndEnv']].concat([].slice.call(arguments,1)); + TEXDEF.environment[name].isUser = true; + } + + MathJax.Hub.Startup.signal.Post("TeX newcommand Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/newcommand.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/noErrors.js b/js/mathjax/extensions/TeX/noErrors.js new file mode 100644 index 0000000..ae3f7f0 --- /dev/null +++ b/js/mathjax/extensions/TeX/noErrors.js @@ -0,0 +1,407 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/noErrors.js + * + * Prevents the TeX error messages from being displayed and shows the + * original TeX code instead. You can configure whether the dollar signs + * are shown or not for in-line math, and whether to put all the TeX on + * one line or use multiple-lines. + * + * To configure this extension, use + * + * MathJax.Hub.Config({ + * TeX: { + * noErrors: { + * inlineDelimiters: ["",""], // or ["$","$"] or ["\\(","\\)"] + * multiLine: true, // false for TeX on all one line + * style: { + * "font-size": "90%", + * "text-align": "left", + * "color": "black", + * "padding": "1px 3px", + * "border": "1px solid" + * // add any additional CSS styles that you want + * // (be sure there is no extra comma at the end of the last item) + * } + * } + * } + * }); + * + * Display-style math is always shown in multi-line format, and without + * delimiters, as it will already be set off in its own centered + * paragraph, like standard display mathematics. + * + * The default settings place the invalid TeX in a multi-line box with a + * black border. If you want it to look as though the TeX is just part of + * the paragraph, use + * + * MathJax.Hub.Config({ + * TeX: { + * noErrors: { + * inlineDelimiters: ["$","$"], // or ["",""] or ["\\(","\\)"] + * multiLine: false, + * style: { + * "font-size": "normal", + * "border": "" + * } + * } + * } + * }); + * + * You may also wish to set the font family, as the default is "serif" + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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) { + var VERSION = "2.7.9"; + + var CONFIG = HUB.CombineConfig("TeX.noErrors",{ + disabled: false, // set to true to return to original error messages + multiLine: true, + inlineDelimiters: ["",""], // or use ["$","$"] or ["\\(","\\)"] + style: { + "font-size": "90%", + "text-align": "left", + "color": "black", + "padding": "1px 3px", + "border": "1px solid" + } + }); + + var NBSP = "\u00A0"; + + // + // The configuration defaults, augmented by the user settings + // + MathJax.Extension["TeX/noErrors"] = { + version: VERSION, + config: CONFIG + }; + + HUB.Register.StartupHook("TeX Jax Ready",function () { + var FORMAT = MathJax.InputJax.TeX.formatError; + + MathJax.InputJax.TeX.Augment({ + // + // Make error messages be the original TeX code + // Mark them as errors and multi-line or not, and for + // multi-line TeX, make spaces non-breakable (to get formatting right) + // + formatError: function (err,math,displaystyle,script) { + if (CONFIG.disabled) {return FORMAT.apply(this,arguments)} + var message = err.message.replace(/\n.*/,""); + HUB.signal.Post(["TeX Jax - parse error",message,math,displaystyle,script]); + var delim = CONFIG.inlineDelimiters; + var multiLine = (displaystyle || CONFIG.multiLine); + if (!displaystyle) {math = delim[0] + math + delim[1]} + if (multiLine) {math = math.replace(/ /g,NBSP)} else {math = math.replace(/\n/g," ")} + return MathJax.ElementJax.mml.merror(math).With({isError:true, multiLine: multiLine}); + } + }); + }); + + /******************************************************************* + * + * Fix HTML-CSS output + */ + + HUB.Register.StartupHook("HTML-CSS Jax Config",function () { + HUB.Config({ + "HTML-CSS": { + styles: { + ".MathJax .noError": HUB.Insert({ + "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "") + },CONFIG.style) + } + } + }); + }); + + HUB.Register.StartupHook("HTML-CSS Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + var HTMLCSS = MathJax.OutputJax["HTML-CSS"]; + + var MATH = MML.math.prototype.toHTML, + MERROR = MML.merror.prototype.toHTML; + + // + // Override math toHTML routine so that error messages + // don't have the clipping and other unneeded overhead + // + MML.math.Augment({ + toHTML: function (span,node) { + var data = this.data[0]; + if (data && data.data[0] && data.data[0].isError) { + span.style.fontSize = ""; + span = this.HTMLcreateSpan(span); + span.bbox = data.data[0].toHTML(span).bbox; + } else { + span = MATH.apply(this,arguments); + } + return span; + } + }); + + // + // Override merror toHTML routine so that it puts out the + // TeX code in an inline-block with line breaks as in the original + // + MML.merror.Augment({ + toHTML: function (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/); + for (var i = 0, m = text.length; i < m; i++) { + HTMLCSS.addText(span,text[i]); + if (i !== m-1) {HTMLCSS.addElement(span,"br",{isMathJax:true})} + } + var HD = HTMLCSS.getHD(span.parentNode), W = HTMLCSS.getW(span.parentNode); + if (m > 1) { + var H = (HD.h + HD.d)/2, x = HTMLCSS.TeX.x_height/2; + span.parentNode.style.verticalAlign = HTMLCSS.Em(HD.d+(x-H)); + HD.h = x + H; HD.d = H - x; + } + span.bbox = {h: HD.h, d: HD.d, w: W, lw: 0, rw: W}; + return span; + } + }); + + }); + + /******************************************************************* + * + * Fix SVG output + */ + + HUB.Register.StartupHook("SVG Jax Config",function () { + HUB.Config({ + "SVG": { + styles: { + ".MathJax_SVG .noError": HUB.Insert({ + "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "") + },CONFIG.style) + } + } + }); + }); + + HUB.Register.StartupHook("SVG Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + + var MATH = MML.math.prototype.toSVG, + MERROR = MML.merror.prototype.toSVG; + + // + // Override math toSVG routine so that error messages + // don't have the clipping and other unneeded overhead + // + MML.math.Augment({ + 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.apply(this,arguments)} + return span; + } + }); + + // + // Override merror toSVG routine so that it puts out the + // TeX code in an inline-block with line breaks as in the original + // + MML.merror.Augment({ + toSVG: function (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/); + 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})} + } + if (m > 1) { + var H = span.offsetHeight/2; + span.style.verticalAlign = (-H+(H/m))+"px"; + } + return span; + } + }); + + }); + + /******************************************************************* + * + * Fix NativeMML output + */ + + HUB.Register.StartupHook("NativeMML Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + var CONFIG = MathJax.Extension["TeX/noErrors"].config; + + var MATH = MML.math.prototype.toNativeMML, + MERROR = MML.merror.prototype.toNativeMML; + + // + // Override math toNativeMML routine so that error messages + // don't get placed inside math tags. + // + MML.math.Augment({ + 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.apply(this,arguments)} + return span; + } + }); + + // + // Override merror toNativeMML routine so that it puts out the + // TeX code in an inline-block with line breaks as in the original + // + MML.merror.Augment({ + toNativeMML: function (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++) { + span.appendChild(document.createTextNode(text[i])); + if (i !== m-1) {span.appendChild(document.createElement("br"))} + } + if (this.multiLine) { + span.style.display = "inline-block"; + if (m > 1) {span.style.verticalAlign = "middle"} + } + for (var id in CONFIG.style) {if (CONFIG.style.hasOwnProperty(id)) { + var ID = id.replace(/-./g,function (c) {return c.charAt(1).toUpperCase()}); + span.style[ID] = CONFIG.style[id]; + }} + return span; + } + }); + + }); + + /******************************************************************* + * + * 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"); + +})(MathJax.Hub,MathJax.HTML); + + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/noErrors.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/noUndefined.js b/js/mathjax/extensions/TeX/noUndefined.js new file mode 100644 index 0000000..463a446 --- /dev/null +++ b/js/mathjax/extensions/TeX/noUndefined.js @@ -0,0 +1,74 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/noUndefined.js + * + * This causes undefined control sequences to be shown as their macro + * names rather than producing an error message. So $X_{\xxx}$ would + * display as an X with a subscript consiting of the text "\xxx". + * + * To configure this extension, use for example + * + * MathJax.Hub.Config({ + * TeX: { + * noUndefined: { + * attributes: { + * mathcolor: "red", + * mathbackground: "#FFEEEE", + * mathsize: "90%" + * } + * } + * } + * }); + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 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. + */ + +// +// The configuration defaults, augmented by the user settings +// +MathJax.Extension["TeX/noUndefined"] = { + version: "2.7.9", + config: MathJax.Hub.CombineConfig("TeX.noUndefined",{ + disabled: false, // set to true to return to original error messages + attributes: { + mathcolor: "red" + } + }) +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var CONFIG = MathJax.Extension["TeX/noUndefined"].config; + var MML = MathJax.ElementJax.mml; + var UNDEFINED = MathJax.InputJax.TeX.Parse.prototype.csUndefined; + + MathJax.InputJax.TeX.Parse.Augment({ + csUndefined: function (name) { + if (CONFIG.disabled) {return UNDEFINED.apply(this,arguments)} + MathJax.Hub.signal.Post(["TeX Jax - undefined control sequence",name]); + this.Push(MML.mtext(name).With(CONFIG.attributes)); + } + }); + + MathJax.Hub.Startup.signal.Post("TeX noUndefined Ready"); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/noUndefined.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/text-macros.js b/js/mathjax/extensions/TeX/text-macros.js new file mode 100644 index 0000000..447a853 --- /dev/null +++ b/js/mathjax/extensions/TeX/text-macros.js @@ -0,0 +1,489 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * MathJax/extensions/TeX/text-macros.js + * + * Implements the processing of some text-mode macros inside + * \text{} and other text boxes. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2018-2020 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/text-macros"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () { + var MML = MathJax.ElementJax.mml; + var TEX = MathJax.InputJax.TeX; + var TEXDEF = TEX.Definitions; + + TEX.Parse.Augment({ + // + // Replace InternalMath with parser that handles some text macros + // + InternalMath: function(text,level) { + var mml = TextParser(text, {}).Parse(); + 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)]; + } + return mml; + }, + + // + // Correctly skip newline as well as comment + // + Comment: function (c) { + while (this.i < this.string.length && this.string.charAt(this.i) != "\n") {this.i++} + this.i++; + }, + + // + // Correctly skip trailing space as well + // + GetCS: function () { + var CS = this.string.slice(this.i).match(/^([a-z]+|.) ?/i); + if (CS) {this.i += CS[0].length; return CS[1]} else {this.i++; return " "} + } + + }); + + // + // The text parser is a subclass of the math parser, so we can use + // some of the existing methods (like GetArgument()), and some of the + // control sequence implementations (like Macro, Spacer, etc.) + // + var TextParser = TEX.TextParser = TEX.Parse.Subclass({ + + Init: function (text, env) { + this.env = MathJax.Hub.Insert({},env); + this.stack = {env: this.env}; + this.string = text; + this.i = 0; + this.mml = []; // the accumulated MathML elements + this.text = ''; // the accumulated text so far + }, + + // + // These are the special characters in text mode + // + textSpecial: { + '\\': 'ControlSequence', + '$': 'Math', + '%': 'Comment', + '^': 'MathModeOnly', + '_': 'MathModeOnly', + '&': 'Misplaced', + '#': 'Misplaced', + '~': 'Tilde', + ' ': 'Space', + '\t': 'Space', + '\r': 'Space', + '\n': 'Space', + '\u00A0': 'Tilde', + '{': 'OpenBrace', + '}': 'CloseBrace', + '`': 'OpenQuote', + "'": 'CloseQuote' + }, + + // + // These are text-mode macros we support + // + textMacros: { + '(': 'Math', + + '$': 'SelfQuote', + '_': 'SelfQuote', + '%': 'SelfQuote', + '{': 'SelfQuote', + '}': 'SelfQuote', + ' ': 'SelfQuote', + '&': 'SelfQuote', + '#': 'SelfQuote', + '\\': 'SelfQuote', + + "'": ['Accent', '\u00B4'], + '`': ['Accent', '\u0060'], + '^': ['Accent', '^'], + '"': ['Accent', '\u00A8'], + '~': ['Accent', '~'], + '=': ['Accent', '\u00AF'], + '.': ['Accent', '\u02D9'], + 'u': ['Accent', '\u02D8'], + 'v': ['Accent', '\u02C7'], + + emph: 'Emph', + rm: ['SetFont',MML.VARIANT.NORMAL], + mit: ['SetFont',MML.VARIANT.ITALIC], + oldstyle: ['SetFont',MML.VARIANT.OLDSTYLE], + cal: ['SetFont',MML.VARIANT.CALIGRAPHIC], + it: ['SetFont','-tex-mathit'], // needs special handling + bf: ['SetFont',MML.VARIANT.BOLD], + bbFont: ['SetFont',MML.VARIANT.DOUBLESTRUCK], + scr: ['SetFont',MML.VARIANT.SCRIPT], + frak: ['SetFont',MML.VARIANT.FRAKTUR], + sf: ['SetFont',MML.VARIANT.SANSSERIF], + tt: ['SetFont',MML.VARIANT.MONOSPACE], + + tiny: ['SetSize',0.5], + Tiny: ['SetSize',0.6], // non-standard + scriptsize: ['SetSize',0.7], + small: ['SetSize',0.85], + normalsize: ['SetSize',1.0], + large: ['SetSize',1.2], + Large: ['SetSize',1.44], + LARGE: ['SetSize',1.73], + huge: ['SetSize',2.07], + Huge: ['SetSize',2.49], + + mathcal: 'MathModeOnly', + mathscr: 'MathModeOnly', + mathrm: 'MathModeOnly', + mathbf: 'MathModeOnly', + mathbb: 'MathModeOnly', + mathit: 'MathModeOnly', + mathfrak: 'MathModeOnly', + mathsf: 'MathModeOnly', + mathtt: 'MathModeOnly', + Bbb: ['Macro','{\\bbFont #1}',1], + textrm: ['Macro','{\\rm #1}',1], + textit: ['Macro','{\\it #1}',1], + textbf: ['Macro','{\\bf #1}',1], + textsf: ['Macro','{\\sf #1}',1], + texttt: ['Macro','{\\tt #1}',1], + + dagger: ['Insert', '\u2020'], + ddagger: ['Insert', '\u2021'], + S: ['Insert', '\u00A7'] + }, + + // + // These are the original macros that are allowed in text mode + // + useMathMacros: { + ',': true, + ':': true, + '>': true, + ';': true, + '!': true, + enspace: true, + quad: true, + qquad: true, + thinspace: true, + negthinspace: true, + + hskip: true, + hspace: true, + kern: true, + mskip: true, + mspace: true, + mkern: true, + rule: true, + Rule: true, + Space: true, + + color: true, + href: true, + unicode: true, + + ref: true, + eqref: true + }, + + // + // Look through the text for special characters and process them. + // Save any accumulated text aat the end and return the MathML + // elements produced. + // + Parse: function () { + var c; + while ((c = this.string.charAt(this.i++))) { + if (this.textSpecial.hasOwnProperty(c)) { + this[this.textSpecial[c]](c); + } else { + this.text += c; + } + } + this.SaveText(); + return this.mml; + }, + + // + // Handle a control sequence name + // If it is a text-mode macro, use it. + // Otherwise look for it in the math-mode lists + // Report an error if it is not there + // Otherwise check if it is a macro or one of the allowed control sequences + // Run the macro (with arguments if given) + // + ControlSequence: function (c) { + var cs = this.GetCS(), name = c + cs, cmd; + if (this.textMacros.hasOwnProperty(cs)) { + cmd = this.textMacros[cs]; + } else { + cmd = this.LookupCS(cs); + if (!cmd) { + this.Error(["UndefinedControlSequence","Undefined control sequence %1",name]); + } + if ((!(cmd instanceof Array) || cmd[0] !== 'Macro') && + !this.useMathMacros.hasOwnProperty(cs)) { + this.Error(["MathMacro","'%1' is only supported in math mode",name]); + } + } + if (cmd instanceof Array) { + if (!this.hasOwnProperty[cmd[0]]) this.SaveText(); + this[cmd[0]].apply(this,[name].concat(cmd.slice(1))); + } else { + if (!this.hasOwnProperty[cmd]) this.SaveText(); + this[cmd].call(this,name); + } + }, + + // + // Lookup the CS as a math-mode macro + // + LookupCS: function(cs) { + if (TEXDEF.macros.hasOwnProperty(cs)) return TEXDEF.macros[cs]; + if (TEXDEF.mathchar0mi.hasOwnProperty(cs)) return TEXDEF.mathchar0mi[cs]; + if (TEXDEF.mathchar0mo.hasOwnProperty(cs)) return TEXDEF.mathchar0mo[cs]; + if (TEXDEF.mathchar7.hasOwnProperty(cs)) return TEXDEF.mathchar7[cs]; + if (TEXDEF.delimiter.hasOwnProperty('\\'+cs)) return TEXDEF.delimiter['\\'+cs]; + return null; + }, + + // + // Handle internal math mode + // Look for the close delimiter and process the contents + // + Math: function (open) { + this.SaveText(); + var i = this.i, j; + var braces = 0, c; + while ((c = this.GetNext())) { + j = this.i++; + switch(c) { + case '\\': + var cs = this.GetCS(); + if (cs === ')') c = '\\('; + case '$': + if (braces === 0 && open === c) { + this.Push(TEX.Parse(this.string.substr(i, j-i),this.env).mml()); + return; + } + break; + + case '{': + braces++; + break; + + case '}': + if (braces == 0) { + this.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"]); + } + braces--; + break; + } + } + this.Error(["MathNotTerminated","Math not terminated in text box"]); + }, + + // + // Character can only be used in math mode + // + MathModeOnly: function (c) { + this.Error(["MathModeOnly","'%1' allowed only in math mode",c]); + }, + + // + // Character is being used out of place + // + Misplaced: function (c) { + this.Error(["Misplaced","'%1' can not be used here",c]); + }, + + // + // Braces start new environments + // + OpenBrace: function (c) { + var env = this.env; + this.env = MathJax.Hub.Insert({}, env); + this.env.oldEnv = env; + }, + CloseBrace: function (c) { + if (this.env.oldEnv) { + this.SaveText(); + this.env = this.env.oldEnv; + } else { + this.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"]); + } + }, + + // + // Handle open and close quotes + // + OpenQuote: function (c) { + if (this.string.charAt(this.i) === c) { + this.text += "\u201C"; + this.i++; + } else { + this.text += "\u2018" + } + }, + CloseQuote: function (c) { + if (this.string.charAt(this.i) === c) { + this.text += "\u201D"; + this.i++; + } else { + this.text += "\u2019" + } + }, + + // + // Handle non-breaking and regular spaces + // + Tilde: function (c) { + this.text += '\u00A0'; + }, + Space: function (c) { + this.text += ' '; + while (this.GetNext().match(/\s/)) this.i++; + }, + + // + // Insert the escaped characer + // + SelfQuote: function (name) { + this.text += name.substr(1); + }, + + // + // Insert a given character + // + Insert: function (name, c) { + this.text += c; + }, + + // + // Create an accented character using mover + // + Accent: function (name, c) { + this.SaveText(); + var base = this.ParseArg(name); + var accent = MML.mo(MML.chars(c)); + if (this.env.mathvariant) accent.mathvariant = this.env.mathvariant; + this.Push(MML.mover(base,accent)); + }, + + // + // Switch to/from italics + // + Emph: function (name) { + this.UseFont(name, this.env.mathvariant === '-tex-mathit' ? 'normal' : '-tex-mathit'); + }, + + // + // Use a given font on its argument + // + UseFont: function (name, variant) { + this.SaveText(); + this.Push(this.ParseTextArg(name,{mathvariant: variant})); + }, + + // + // Set a font for the rest of the text + // + SetFont: function (name, variant) { + this.SaveText(); + this.env.mathvariant = variant; + }, + + // + // Set the size to use + // + SetSize: function (name, size) { + this.SaveText(); + this.env.mathsize = size; + }, + + // + // Process the argument as text with the given environment settings + // + ParseTextArg: function (name, env) { + var text = this.GetArgument(name); + env = MathJax.Hub.Insert(MathJax.Hub.Insert({}, this.env), env); + delete env.oldEnv; + return TextParser(text, env).Parse(); + }, + + // + // Process an argument as text (overrides the math-mode version) + // + ParseArg: function (name) { + var mml = TextParser(this.GetArgument(name), this.env).Parse(); + if (mml.length === 0) return mml[0]; + return MML.mrow.apply(MML.mrow, mml); + }, + + // + // Create an mtext element with the accumulated text, if any + // and set it variant + // + SaveText: function () { + if (this.text) { + var text = MML.mtext(MML.chars(this.text)); + if (this.env.mathvariant) text.mathvariant = this.env.mathvariant; + this.Push(text); + } + this.text = ""; + }, + + // + // Save a MathML element or array, setting its size and color, if any + // + Push: function (mml) { + if (mml instanceof Array) { + if (this.env.mathsize || this.env.mathcolor) { + mml = MML.mstyle.apply(MML,mml); + if (this.env.mathsize) mml.mathsize = this.env.mathsize; + if (this.env.mathcolor) mml.mathcolor = this.env.mathcolor; + } + this.mml.push.apply(this.mml,mml); + } else { + if (this.env.mathsize && !mml.mathsize) mml.mathsize = this.env.mathsize; + if (this.env.mathcolor && !mml.mathcolor) mml.mathcolor = this.env.mathcolor; + this.mml.push(mml); + } + }, + + // + // Throw an error + // + Error: function (message) { + TEX.Error(message); + } + + }); + + MathJax.Hub.Startup.signal.Post('TeX text-macros Ready'); + +}); + +MathJax.Ajax.loadComplete('[MathJax]/extensions/TeX/text-macros.js'); +// @license-end diff --git a/js/mathjax/extensions/TeX/unicode.js b/js/mathjax/extensions/TeX/unicode.js new file mode 100644 index 0000000..0c3e50a --- /dev/null +++ b/js/mathjax/extensions/TeX/unicode.js @@ -0,0 +1,172 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/unicode.js + * + * Implements the \unicode extension to TeX to allow arbitrary unicode + * code points to be entered into the TeX file. You can specify + * the height and depth of the character (the width is determined by + * the browser), and the default font from which to take the character. + * + * Examples: + * \unicode{65} % the character 'A' + * \unicode{x41} % the character 'A' + * \unicode[.55,0.05]{x22D6} % less-than with dot, with height .55 and depth 0.05 + * \unicode[.55,0.05][Geramond]{x22D6} % same taken from Geramond font + * \unicode[Garamond]{x22D6} % same, but with default height, depth of .8,.2 + * + * Once a size and font are provided for a given code point, they need + * not be specified again in subsequent \unicode calls for that character. + * Note that a font list can be given, but Internet Explorer has a buggy + * implementation of font-family where it only looks in the first + * available font and if the glyph is not in that, it does not look at + * later fonts, but goes directly to the default font as set in the + * Internet-Options/Font panel. For this reason, the default font list is + * "STIXGeneral,'Arial Unicode MS'", so if the user has STIX fonts, the + * symbol will be taken from that (almost all the symbols are in + * STIXGeneral), otherwise Arial Unicode MS is tried. + * + * To configure the default font list, use + * + * MathJax.Hub.Config({ + * TeX: { + * unicode: { + * fonts: "STIXGeneral,'Arial Unicode MS'" + * } + * } + * }); + * + * The result of \unicode will have TeX class ORD (i.e., it will act like a + * variable). Use \mathbin, \mathrel, etc, to specify a different class. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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. + */ + +// +// The configuration defaults, augmented by the user settings +// +MathJax.Extension["TeX/unicode"] = { + version: "2.7.9", + unicode: {}, + config: MathJax.Hub.CombineConfig("TeX.unicode",{ + fonts: "STIXGeneral,'Arial Unicode MS'" + }) +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + var TEX = MathJax.InputJax.TeX; + var MML = MathJax.ElementJax.mml; + var UNICODE = MathJax.Extension["TeX/unicode"].unicode; + + // + // Add \unicode macro + // + TEX.Definitions.Add({macros: {unicode: 'Unicode'}},null,true); + // + // Implementation of \unicode in parser + // + TEX.Parse.Augment({ + Unicode: function(name) { + var HD = this.GetBrackets(name), font; + if (HD) { + if (HD.replace(/ /g,"").match(/^(\d+(\.\d*)?|\.\d+),(\d+(\.\d*)?|\.\d+)$/)) + {HD = HD.replace(/ /g,"").split(/,/); font = this.GetBrackets(name)} + else {font = HD; HD = null} + } + var n = this.trimSpaces(this.GetArgument(name)).replace(/^0x/,"x"); + if (!n.match(/^(x[0-9A-Fa-f]+|[0-9]+)$/)) { + TEX.Error(["BadUnicode","Argument to \\unicode must be a number"]); + } + var N = parseInt(n.match(/^x/) ? "0"+n : n); + if (!UNICODE[N]) {UNICODE[N] = [800,200,font,N]} + else if (!font) {font = UNICODE[N][2]} + if (HD) { + UNICODE[N][0] = Math.floor(HD[0]*1000); + UNICODE[N][1] = Math.floor(HD[1]*1000); + } + var variant = this.stack.env.font, def = {}; + if (font) { + UNICODE[N][2] = def.fontfamily = font.replace(/"/g,"'"); + if (variant) { + if (variant.match(/bold/)) {def.fontweight = "bold"} + if (variant.match(/italic|-mathit/)) {def.fontstyle = "italic"} + } + } else if (variant) {def.mathvariant = variant} + def.unicode = [].concat(UNICODE[N]); // make a copy + this.Push(MML.mtext(MML.entity("#"+n)).With(def)); + } + }); + + MathJax.Hub.Startup.signal.Post("TeX unicode Ready"); + +}); + +MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + var FONTS = MathJax.Extension["TeX/unicode"].config.fonts; + + // + // Override getVariant to make one that includes the font and size + // + var GETVARIANT = MML.mbase.prototype.HTMLgetVariant; + MML.mbase.Augment({ + HTMLgetVariant: function () { + 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; + if (!variant.defaultFont) { + variant = MathJax.Hub.Insert({},variant); // make a copy + variant.defaultFont = {family:FONTS}; + } + var family = this.unicode[2]; if (family) {family += ","+FONTS} else {family = FONTS} + variant.defaultFont[this.unicode[3]] = [ + this.unicode[0],this.unicode[1],500,0,500, + {isUnknown:true, isUnicode:true, font:family} + ]; + return variant; + } + }); +}); + +MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { + var MML = MathJax.ElementJax.mml; + var FONTS = MathJax.Extension["TeX/unicode"].config.fonts; + + // + // Override getVariant to make one that includes the font and size + // + var GETVARIANT = MML.mbase.prototype.SVGgetVariant; + MML.mbase.Augment({ + SVGgetVariant: function () { + var variant = GETVARIANT.call(this); + if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart + if (!this.unicode) {return variant} + variant.unicode = true; + if (!variant.forceFamily) {variant = MathJax.Hub.Insert({},variant)} // make a copy + variant.defaultFamily = FONTS; variant.noRemap = true; + variant.h = this.unicode[0]; variant.d = this.unicode[1]; + return variant; + } + }); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/unicode.js"); +// @license-end diff --git a/js/mathjax/extensions/TeX/verb.js b/js/mathjax/extensions/TeX/verb.js new file mode 100644 index 0000000..0f6f845 --- /dev/null +++ b/js/mathjax/extensions/TeX/verb.js @@ -0,0 +1,63 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/TeX/verb.js + * + * Implements the \verb|...| command for including text verbatim + * (with no processing of macros or special characters). + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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/verb"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { + + var MML = MathJax.ElementJax.mml; + var TEX = MathJax.InputJax.TeX; + var TEXDEF = TEX.Definitions; + + TEXDEF.Add({macros: {verb: 'Verb'}},null,true); + + TEX.Parse.Augment({ + + /* + * Implement \verb|...| + */ + Verb: function (name) { + var c = this.GetNext(); var start = ++this.i; + 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(["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})); + } + + }); + + MathJax.Hub.Startup.signal.Post("TeX verb Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/verb.js"); +// @license-end diff --git a/js/mathjax/extensions/a11y/accessibility-menu.js b/js/mathjax/extensions/a11y/accessibility-menu.js new file mode 100644 index 0000000..7262c22 --- /dev/null +++ b/js/mathjax/extensions/a11y/accessibility-menu.js @@ -0,0 +1,186 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * [Contrib]/a11y/accessibility-menu.js + * + * A thin extension to add opt-in menu items for the accessibility + * extensions in the a11y contributed directory. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2016-2017 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(HUB,EXTENSIONS) { + var SETTINGS = HUB.config.menuSettings; + var ITEM, MENU; // filled in when MathMenu extension loads + + var BIND = (Function.prototype.bind ? function (f,t) {return f.bind(t)} : + function (f,t) {return function () {f.apply(t,arguments)}}); + var KEYS = Object.keys || function (obj) { + var keys = []; + for (var id in obj) {if (obj.hasOwnProperty(id)) keys.push(id)} + return keys; + }; + + // + // Set up the a11y path,if it isn't already in place + // + var PATH = MathJax.Ajax.config.path; + if (!PATH.a11y) PATH.a11y = HUB.config.root + "/extensions/a11y"; + + var Accessibility = EXTENSIONS["accessibility-menu"] = { + version: '1.6.0', + prefix: '', //'Accessibility-', + defaults: {}, + modules: [], + MakeOption: function(name) { + return Accessibility.prefix + name; + }, + GetOption: function(option) { + return SETTINGS[Accessibility.MakeOption(option)]; + }, + AddDefaults: function() { + var keys = KEYS(Accessibility.defaults); + for (var i = 0, key; key = keys[i]; i++) { + var option = Accessibility.MakeOption(key); + if (typeof(SETTINGS[option]) === 'undefined') { + SETTINGS[option] = Accessibility.defaults[key]; + } + } + }, + // Attaches the menu items; + AddMenu: function() { + var items = Array(this.modules.length); + for (var i = 0, module; module = this.modules[i]; i++) items[i] = module.placeHolder; + var menu = MENU.FindId('Accessibility'); + if (menu) { + items.unshift(ITEM.RULE()); + menu.submenu.items.push.apply(menu.submenu.items,items); + } else { + var renderer = (MENU.FindId("Settings","Renderer")||{}).submenu; + if (renderer) { + // move AssitiveMML and InTabOrder from Renderer to Accessibility menu + items.unshift(ITEM.RULE()); + items.unshift(renderer.items.pop()); + items.unshift(renderer.items.pop()); + } + items.unshift("Accessibility"); + var menu = ITEM.SUBMENU.apply(ITEM.SUBMENU,items); + var locale = MENU.IndexOfId('Locale'); + if (locale) { + MENU.items.splice(locale,0,menu); + } else { + MENU.items.push(ITEM.RULE(), menu); + } + } + }, + Register: function(module) { + Accessibility.defaults[module.option] = false; + Accessibility.modules.push(module); + }, + Startup: function() { + ITEM = MathJax.Menu.ITEM; + MENU = MathJax.Menu.menu; + for (var i = 0, module; module = this.modules[i]; i++) module.CreateMenu(); + this.AddMenu(); + }, + LoadExtensions: function () { + var extensions = []; + for (var i = 0, module; module = this.modules[i]; i++) { + if (SETTINGS[module.option]) extensions.push(module.module); + } + return (extensions.length ? HUB.Startup.loadArray(extensions) : null); + } + }; + + var ModuleLoader = MathJax.Extension.ModuleLoader = MathJax.Object.Subclass({ + option: '', + name: ['',''], + module: '', + placeHolder: null, + submenu: false, + extension: null, + Init: function(option, name, module, extension, submenu) { + this.option = option; + this.name = [name.replace(/ /g,''),name]; + this.module = module; + this.extension = extension; + this.submenu = (submenu || false); + }, + CreateMenu: function() { + var load = BIND(this.Load,this); + if (this.submenu) { + this.placeHolder = + ITEM.SUBMENU(this.name, + ITEM.CHECKBOX(["Activate","Activate"], + Accessibility.MakeOption(this.option), {action: load}), + ITEM.RULE(), + ITEM.COMMAND(["OptionsWhenActive","(Options when Active)"],null,{disabled:true}) + ); + } else { + this.placeHolder = ITEM.CHECKBOX( + this.name, Accessibility.MakeOption(this.option), {action: load} + ); + } + }, + Load: function() { + HUB.Queue(["Require",MathJax.Ajax,this.module,["Enable",this]]); + }, + Enable: function(menu) { + var extension = MathJax.Extension[this.extension]; + if (extension) { + extension.Enable(true,true); + MathJax.Menu.saveCookie(); + } + } + }); + + Accessibility.Register( + ModuleLoader( + 'collapsible', 'Collapsible Math', '[a11y]/collapsible.js', 'collapsible' + ) + ); + Accessibility.Register( + ModuleLoader( + 'autocollapse', 'Auto Collapse', '[a11y]/auto-collapse.js', 'auto-collapse' + ) + ); + Accessibility.Register( + ModuleLoader( + 'explorer', 'Explorer', '[a11y]/explorer.js', 'explorer', true + ) + ); + + Accessibility.AddDefaults(); + + HUB.Register.StartupHook('End Extensions', function () { + HUB.Register.StartupHook('MathMenu Ready', function () { + Accessibility.Startup(); + HUB.Startup.signal.Post('Accessibility Menu Ready'); + },5); // run before other extensions' menu hooks even if they are loaded first + },5); + + MathJax.Hub.Register.StartupHook("End Cookie", function () { + MathJax.Callback.Queue( + ["LoadExtensions",Accessibility], + ["loadComplete",MathJax.Ajax,"[a11y]/accessibility-menu.js"] + ); + }); + +})(MathJax.Hub,MathJax.Extension); + + +// @license-end diff --git a/js/mathjax/extensions/a11y/auto-collapse.js b/js/mathjax/extensions/a11y/auto-collapse.js new file mode 100644 index 0000000..d18eca9 --- /dev/null +++ b/js/mathjax/extensions/a11y/auto-collapse.js @@ -0,0 +1,500 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * [Contrib]/a11y/auto-collapse.js + * + * Implements the ability to have long expressions collapse + * automatically on screen size changes. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2016-2017 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function (HUB) { + var SETTINGS = HUB.config.menuSettings; + var COOKIE = {}; // replaced when menu is available + + // + // Set up the a11y path,if it isn't already in place + // + var PATH = MathJax.Ajax.config.path; + if (!PATH.a11y) PATH.a11y = HUB.config.root + "/extensions/a11y"; + + var Collapse = MathJax.Extension["auto-collapse"] = { + version: "1.6.0", + config: HUB.CombineConfig("auto-collapse",{ + disabled: false + }), + dependents: [], // the extensions that depend on this one + + /*****************************************************************/ + + Enable: function (update,menu) { + SETTINGS.autocollapse = true; + if (menu) COOKIE.autocollapse = true + this.config.disabled = false; + MathJax.Extension.collapsible.Enable(false,menu); + if (update) { + HUB.Queue( + ["Reprocess",HUB], + ["CollapseWideMath",this] + ); + } + }, + Disable: function (update,menu) { + SETTINGS.autocollapse = false; + if (menu) COOKIE.autocollapse = false; + this.config.disabled = true; + for (var i = this.dependents.length-1; i >= 0; i--) { + var dependent = this.dependents[i]; + if (dependent.Disable) dependent.Disable(false,menu); + } + if (update) HUB.Queue(["Rerender",HUB]); + }, + + // + // Register a dependent + // + Dependent: function (extension) { + this.dependents.push(extension); + }, + + Startup: function () { + // + // Inform collapsible extension that we are a dependent + // + var Collapsible = MathJax.Extension.collapsible; + if (Collapsible) Collapsible.Dependent(this); + // + // Add the filter into the post-input hooks (priority 150, so other + // hooks run first, in particular, the enrichment and complexity hooks). + // + HUB.postInputHooks.Add(["Filter",Collapse],150); + // + // Add the auto-collapsing + // + HUB.Queue(function () {return Collapse.CollapseWideMath()}); + // + // Add a resize handler to check for math that needs + // to be collapsed or expanded. + // + if (window.addEventListener) window.addEventListener("resize",Collapse.resizeHandler,false); + else if (window.attachEvent) window.attachEvent("onresize",Collapse.resizeHandler); + else window.onresize = Collapse.resizeHandler; + }, + + // + // If the math is block-level (or in an element "by itself"), then + // add the SRE actions for this element. + // + Filter: function (jax,id,script) { + if (!jax.enriched || this.config.disabled) return; + if (jax.root.Get("display") === "block" || + script.parentNode.childNodes.length <= 3) { + jax.root.SRE = {action: this.Actions(jax.root)}; + } + }, + // + // Produce an array of collapsible actions + // sorted by depth and complexity + // + Actions: function (node) { + var actions = []; + this.getActions(node,0,actions); + return this.sortActions(actions); + }, + getActions: function (node,depth,actions) { + if (node.isToken || !node.data) return; + depth++; + for (var i = 0, m = node.data.length; i < m; i++) { + if (node.data[i]) { + var child = node.data[i]; + if (child.collapsible) { + if (!actions[depth]) actions[depth] = []; + actions[depth].push(child); + this.getActions(child.data[1],depth,actions); + } else { + this.getActions(child,depth,actions); + } + } + } + }, + sortActions: function (actions) { + var ACTIONS = []; + for (var i = 0, m = actions.length; i < m; i++) { + if (actions[i]) ACTIONS = ACTIONS.concat(actions[i].sort(this.sortActionsBy)); + } + return ACTIONS; + }, + sortActionsBy: function (a,b) { + a = a.data[1].complexity; b = b.data[1].complexity; + return (a < b ? -1 : a > b ? 1 : 0); + }, + + /*****************************************************************/ + /* + * These routines implement the automatic collapsing of equations + * based on container widths. + */ + + // + // Find math that is too wide and collapse it. + // + CollapseWideMath: function (element) { + if (this.config.disabled) return; + this.GetContainerWidths(element); + var jax = HUB.getAllJax(element); + var state = {collapse: [], jax: jax, m: jax.length, i: 0, changed:false}; + return this.collapseState(state); + }, + collapseState: function (state) { + var collapse = state.collapse; + while (state.i < state.m) { + var jax = state.jax[state.i]; + var SRE = jax.root.SRE; state.changed = false; + if (SRE && SRE.action.length) { + if (SRE.cwidth < SRE.m || SRE.cwidth > SRE.M) { + var restart = this.getActionWidths(jax,state); if (restart) return restart; + this.collapseActions(SRE,state); + if (state.changed) collapse.push(jax.SourceElement()); + } + } + state.i++; + } + if (collapse.length === 0) return; + if (collapse.length === 1) collapse = collapse[0]; + return HUB.Rerender(collapse); + }, + + // + // Find the actions that need to be collapsed to acheive + // the correct width, and retain the sizes that would cause + // the equation to be expanded or collapsed further. + // + collapseActions: function (SRE,state) { + var w = SRE.width, m = w, M = 1000000; + for (var j = SRE.action.length-1; j >= 0; j--) { + var action = SRE.action[j], selection = action.selection; + if (w > SRE.cwidth) { + action.selection = 1; + m = action.SREwidth; M = w; + } else { + action.selection = 2; + } + w = action.SREwidth; + if (SRE.DOMupdate) { + document.getElementById(action.id).setAttribute("selection",action.selection); + } else if (action.selection !== selection) { + state.changed = true; + } + } + SRE.m = m; SRE.M = M; + }, + + // + // Get the widths of the different collapsings, + // trapping any restarts, and restarting the process + // when the event has occurred. + // + getActionWidths: function (jax,state) { + if (!jax.root.SRE.actionWidths) { + MathJax.OutputJax[jax.outputJax].getMetrics(jax); + try {this.computeActionWidths(jax)} catch (err) { + if (!err.restart) throw err; + return MathJax.Callback.After(["collapseState",this,state],err.restart); + } + state.changed = true; + } + return null; + }, + // + // Compute the action widths by collapsing each maction, + // and recording the width of the complete equation. + // + computeActionWidths: function (jax) { + var SRE = jax.root.SRE, actions = SRE.action, j, state = {}; + SRE.width = jax.sreGetRootWidth(state); + for (j = actions.length-1; j >= 0; j--) actions[j].selection = 2; + for (j = actions.length-1; j >= 0; j--) { + var action = actions[j]; + if (action.SREwidth == null) { + action.selection = 1; + action.SREwidth = jax.sreGetActionWidth(state,action); + } + } + SRE.actionWidths = true; + }, + + // + // Get the widths of the containers of tall the math elements + // that can be collapsed (so we can tell which ones NEED to be + // collapsed). Do this in a way that only causes two reflows. + // + GetContainerWidths: function (element) { + var JAX = HUB.getAllJax(element); + var i, m, script, span = MathJax.HTML.Element("span",{style:{display:"block"}}); + var math = [], jax, root; + for (i = 0, m = JAX.length; i < m; i++) { + jax = JAX[i], root = jax.root, SRE = root.SRE; + if (SRE && SRE.action.length) { + if (SRE.width == null) { + jax.sreGetMetrics(); + SRE.m = SRE.width; SRE.M = 1000000; + } + script = jax.SourceElement(); + script.previousSibling.style.display = "none"; + script.parentNode.insertBefore(span.cloneNode(false),script); + math.push([jax,script]); + } + } + for (i = 0, m = math.length; i < m; i++) { + jax = math[i][0], script = math[i][1]; + if (script.previousSibling.offsetWidth) + jax.root.SRE.cwidth = script.previousSibling.offsetWidth * jax.root.SRE.em; + } + for (i = 0, m = math.length; i < m; i++) { + jax = math[i][0], script = math[i][1]; + script.parentNode.removeChild(script.previousSibling); + script.previousSibling.style.display = ""; + } + }, + + /*****************************************************************/ + + // + // A resize handler that can be tied to the window resize event + // to collapse math automatically on resize. + // + + timer: null, + running: false, + retry: false, + saved_delay: 0, + + resizeHandler: function (event) { + if (Collapse.config.disabled) return; + if (Collapse.running) {Collapse.retry = true; return} + if (Collapse.timer) clearTimeout(Collapse.timer); + Collapse.timer = setTimeout(Collapse.resizeAction, 100); + }, + resizeAction: function () { + Collapse.timer = null; + Collapse.running = true; + HUB.Queue( + function () { + // + // Prevent flicker between input and output phases. + // + Collapse.saved_delay = HUB.processSectionDelay; + HUB.processSectionDelay = 0; + }, + ["CollapseWideMath",Collapse], + ["resizeCheck",Collapse] + ); + }, + resizeCheck: function () { + Collapse.running = false; + HUB.processSectionDelay = Collapse.saved_delay; + if (Collapse.retry) { + Collapse.retry = false; + setTimeout(Collapse.resizeHandler,0); + } + } + + }; + + HUB.Register.StartupHook("End Extensions", function () { + if (SETTINGS.autocollapse == null) { + SETTINGS.autocollapse = !Collapse.config.disabled; + } else { + Collapse.config.disabled = !SETTINGS.autocollapse; + } + HUB.Register.StartupHook("MathMenu Ready", function () { + COOKIE = MathJax.Menu.cookie; + var Switch = function(menu) { + Collapse[SETTINGS.autocollapse ? "Enable" : "Disable"](true,true); + MathJax.Menu.saveCookie(); + }; + var ITEM = MathJax.Menu.ITEM, + MENU = MathJax.Menu.menu; + var menu = ITEM.CHECKBOX( + ['AutoCollapse','Auto Collapse'], 'autocollapse', {action: Switch} + ); + var submenu = (MENU.FindId('Accessibility')||{}).submenu, index; + if (submenu) { + index = submenu.IndexOfId('AutoCollapse'); + if (index !== null) { + submenu.items[index] = menu; + } else { + index = submenu.IndexOfId('CollapsibleMath'); + submenu.items.splice(index+1,0,menu); + } + } else { + index = MENU.IndexOfId('CollapsibleMath'); + MENU.items.splice(index+1,0,menu); + } + var init = function () {Collapse[SETTINGS.autocollapse ? "Enable" : "Disable"]()}; + if (MathJax.Extension.collapse) init(); + else MathJax.Hub.Register.StartupHook("Auto Collapse Ready", init); + },25); // after Assistive-Explore + },25); + +})(MathJax.Hub); + + +/*****************************************************************/ +/* + * Add methods to the ElementJax and OutputJax to get the + * widths of the collapsed elements. + */ + +// +// Add SRE methods to ElementJax. +// +MathJax.ElementJax.Augment({ + sreGetMetrics: function () { + MathJax.OutputJax[this.outputJax].sreGetMetrics(this,this.root.SRE); + }, + sreGetRootWidth: function (state) { + return MathJax.OutputJax[this.outputJax].sreGetRootWidth(this,state); + }, + sreGetActionWidth: function (state,action) { + return MathJax.OutputJax[this.outputJax].sreGetActionWidth(this,state,action); + } +}); + +// +// Add default methods to base OutputJax class. +// +MathJax.OutputJax.Augment({ + getMetrics: function () {}, // make sure it is defined + sreGetMetrics: function (jax,SRE) {SRE.cwidth = 1000000; SRE.width = 0; SRE.em = 12}, + sreGetRootWidth: function (jax,state) {return 0}, + sreGetActionWidth: function (jax,state,action) {return 0} +}); + +// +// Specific implementations for HTML-CSS output. +// +MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { + MathJax.OutputJax["HTML-CSS"].Augment({ + sreGetMetrics: function (jax,SRE) { + SRE.width = jax.root.data[0].HTMLspanElement().parentNode.bbox.w; + SRE.em = 1 / jax.HTMLCSS.em / jax.HTMLCSS.scale; + }, + sreGetRootWidth: function (jax,state) { + var html = jax.root.data[0].HTMLspanElement(); + state.box = html.parentNode; + return state.box.bbox.w; + }, + sreGetActionWidth: function (jax,state,action) { + return jax.root.data[0].toHTML(state.box).bbox.w; + } + }); +}); + +// +// Specific implementations for SVG output. +// +MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { + MathJax.OutputJax.SVG.Augment({ + getMetrics: function (jax) { + this.em = MathJax.ElementJax.mml.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex; + this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth; + }, + sreGetMetrics: function (jax,SRE) { + SRE.width = jax.root.SVGdata.w/1000; + SRE.em = 1/jax.SVG.em; + }, + sreGetRootWidth: function (jax,state) { + state.span = document.getElementById(jax.inputID+"-Frame"); + return jax.root.SVGdata.w/1000; + }, + sreGetActionWidth: function (jax,state,action) { + this.mathDiv = state.span; + state.span.appendChild(this.textSVG); + try {var svg = jax.root.data[0].toSVG()} catch(err) {var error = err} + state.span.removeChild(this.textSVG); + if (error) throw error; // can happen when a restart is needed + return jax.root.data[0].SVGdata.w/1000; + } + }); +}); + +// +// Specific implementations for CommonHTML output. +// +MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () { + MathJax.OutputJax.CommonHTML.Augment({ + sreGetMetrics: function (jax,SRE) { + SRE.width = jax.root.CHTML.w; + SRE.em = 1 / jax.CHTML.em / jax.CHTML.scale; + }, + sreGetRootWidth: function (jax,state) { + state.span = document.getElementById(jax.inputID+"-Frame").firstChild; + state.tmp = document.createElement("span"); + state.tmp.className = state.span.className; + return jax.root.CHTML.w / jax.CHTML.scale; + }, + sreGetActionWidth: function (jax,state,action) { + state.span.parentNode.replaceChild(state.tmp,state.span); + MathJax.OutputJax.CommonHTML.CHTMLnode = state.tmp; + try {jax.root.data[0].toCommonHTML(state.tmp)} catch (err) {var error = err} + state.tmp.parentNode.replaceChild(state.span,state.tmp); + if (error) throw error; // can happen when a restart is needed + return jax.root.data[0].CHTML.w / jax.CHTML.scale; + } + }); +}); + +// +// Specific implementations for NativeMML output. +// +MathJax.Hub.Register.StartupHook("NativeMML Jax Ready",function () { + MathJax.OutputJax.NativeMML.Augment({ + sreGetMetrics: function (jax,SRE) { + var span = document.getElementById(jax.inputID+"-Frame"); + SRE.width = span.offsetWidth; + SRE.em = 1; SRE.DOMupdate = true; + }, + sreGetRootWidth: function (jax,state) { + state.span = document.getElementById(jax.inputID+"-Frame").firstChild; + return state.span.offsetWidth; + }, + sreGetActionWidth: function (jax,state,action) { + var maction = document.getElementById(action.id); + maction.setAttribute("selection",1); + var w = state.span.offsetWidth; + return w; + } + }); +}); + + +/*****************************************************************/ + +// +// Load the collapsible extension and +// signal the start up when that has loaded. +// +MathJax.Ajax.Require("[a11y]/collapsible.js"); +MathJax.Hub.Register.StartupHook("Collapsible Ready", function () { + MathJax.Extension["auto-collapse"].Startup(); // Initialize the collapsing process + MathJax.Hub.Startup.signal.Post("Auto Collapse Ready"); + MathJax.Ajax.loadComplete("[a11y]/auto-collapse.js"); +}); + +// @license-end diff --git a/js/mathjax/extensions/a11y/collapsible.js b/js/mathjax/extensions/a11y/collapsible.js new file mode 100644 index 0000000..cc396f6 --- /dev/null +++ b/js/mathjax/extensions/a11y/collapsible.js @@ -0,0 +1,743 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * [Contrib]/a11y/collapsible.js + * + * A filter to add maction elements to the enriched MathML for parts that + * can be collapsed. We determine this based on a "complexity" value and + * collapse those terms that exceed a given complexity. + * + * The parameters controlling the complexity measure still need work. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2016-2017 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function (HUB) { + var MML; + + var SETTINGS = HUB.config.menuSettings; + var COOKIE = {}; // replaced when menu is available + + var NOCOLLAPSE = 10000000; // really big complexity + var COMPLEXATTR = "data-semantic-complexity"; + + // + // Set up the a11y path,if it isn't already in place + // + var PATH = MathJax.Ajax.config.path; + if (!PATH.a11y) PATH.a11y = HUB.config.root + "/extensions/a11y"; + + var Collapsible = MathJax.Extension.collapsible = { + version: "1.6.0", + config: HUB.CombineConfig("collapsible",{ + disabled: false + }), + dependents: [], // the extensions that depend on this one + COMPLEXATTR: COMPLEXATTR, // attribute name for the complexity value + + /*****************************************************************/ + + // + // Complexity values to use for different structures + // + COMPLEXITY: { + TEXT: .5, // each character of a token element adds this to complexity + TOKEN: .5, // each toekn element gets this additional complexity + CHILD: 1, // child nodes add this to their parent node's complexity + + SCRIPT: .8, // script elements reduce their complexity by this factor + SQRT: 2, // sqrt adds this extra complexity + SUBSUP: 2, // sub-sup adds this extra complexity + UNDEROVER: 2, // under-over adds this extra complexity + FRACTION: 2, // fractions add this extra complexity + ACTION: 2, // maction adds this extra complexity + PHANTOM: 0, // mphantom makes complexity 0? + XML: 2, // Can't really measure complexity of annotation-xml, so punt + GLYPH: 2 // Can't really measure complexity of mglyph, to punt + }, + // + // These are the cut-off complexity values for when + // the structure should collapse + // + COLLAPSE: { + identifier: 3, + number: 3, + text: 10, + infixop: 15, + relseq: 15, + multirel: 15, + fenced: 18, + bigop: 20, + integral: 20, + fraction: 12, + sqrt: 9, + root: 12, + vector: 15, + matrix: 15, + cases: 15, + superscript: 9, + subscript: 9, + subsup: 9, + punctuated: { + endpunct: NOCOLLAPSE, + startpunct: NOCOLLAPSE, + value: 12 + } + }, + // + // These are the characters to use for the various collapsed elements + // (if an object, then semantic-role is used to get the character + // from the object) + // + MARKER: { + identifier: "x", + number: "#", + text: "...", + appl: { + "limit function": "lim", + value: "f()" + }, + fraction: "/", + sqrt: "\u221A", + root: "\u221A", + superscript: "\u25FD\u02D9", + subscript: "\u25FD.", + subsup:"\u25FD:", + vector: { + binomial: "(:)", + determinant: "|:|", + value: "\u27E8:\u27E9" + }, + matrix: { + squarematrix: "[::]", + rowvector: "\u27E8\u22EF\u27E9", + columnvector: "\u27E8\u22EE\u27E9", + determinant: "|::|", + value: "(::)" + }, + cases: "{:", + infixop: { + addition: "+", + subtraction: "\u2212", + multiplication: "\u22C5", + implicit: "\u22C5", + value: "+" + }, + punctuated: { + text: "...", + value: "," + } + }, + + /*****************************************************************/ + + Enable: function (update,menu) { + SETTINGS.collapsible = true; + if (menu) COOKIE.collapsible = true; + this.config.disabled = false; + MathJax.Extension["semantic-enrich"].Enable(false,menu); + if (update) HUB.Queue(["Reprocess",HUB]); + }, + Disable: function (update,menu) { + SETTINGS.collapsible = false; + if (menu) COOKIE.collapsible = false; + this.config.disabled = true; + for (var i = this.dependents.length-1; i >= 0; i--) { + var dependent = this.dependents[i]; + if (dependent.Disable) dependent.Disable(false,menu); + } + if (update) HUB.Queue(["Reprocess",HUB]); + }, + + // + // Register a dependent + // + Dependent: function (extension) { + this.dependents.push(extension); + }, + + Startup: function () { + MML = MathJax.ElementJax.mml; + // + // Inform semantic-enrich extension that we are a dependent + // + var Enrich = MathJax.Extension["semantic-enrich"]; + if (Enrich) Enrich.Dependent(this); + // + // Add the filter into the post-input hooks (priority 100, so other + // hooks run first, in particular, the enrichment hook). + // + HUB.postInputHooks.Add(["Filter",Collapsible],100); + }, + + // + // The main filter: add mactions for collapsing the math. + // + Filter: function (jax,id,script) { + if (!jax.enriched || this.config.disabled) return; + jax.root = jax.root.Collapse(); + jax.root.inputID = script.id; + }, + + /*****************************************************************/ + + // + // Create a marker from a given string of characters + // (several possibilities are commented out) + // +// Marker: function (c) {return MML.mtext("\u25C3"+c+"\u25B9").With({mathcolor:"blue",attr:{},attrNames:[]})}, +// Marker: function (c) {return MML.mtext("\u25B9"+c+"\u25C3").With({mathcolor:"blue",attr:{},attrNames:[]})}, + Marker: function (c) {return MML.mtext("\u25C2"+c+"\u25B8").With({mathcolor:"blue",attr:{},attrNames:[]})}, +// Marker: function (c) {return MML.mtext("\u25B8"+c+"\u25C2").With({mathcolor:"blue",attr:{},attrNames:[]})}, +// Marker: function (c) {return MML.mtext("\u27EA"+c+"\u27EB").With({mathcolor:"blue",attr:{},attrNames:[]})}, + + + + /*****************************************************************/ + + // + // Make a collapsible element using maction that contains + // an appropriate marker, and the expanded MathML. + // If the MathML is a node, make an mrow to use instead, + // and move the semantic data to it (I guess it would have been + // easier to have had that done initially, oh well). + // + MakeAction: function (collapse,mml) { + var maction = MML.maction(collapse).With({ + id:this.getActionID(), actiontype:"toggle", + complexity:collapse.getComplexity(), collapsible:true, + attrNames:["id","actiontype","selection",COMPLEXATTR], attr:{}, selection:2 + }); + maction.attr[COMPLEXATTR] = maction.complexity; + if (mml.type === "math") { + var mrow = MML.mrow().With({ + complexity: mml.complexity, + attrNames: [], attr: {} + }); + mrow.Append.apply(mrow,mml.data[0].data); mml.data[0].data = []; + for (var i = mml.attrNames.length-1, name; name = mml.attrNames[i]; i--) { + if (name.substr(0,14) === "data-semantic-") { + mrow.attr[name] = mml.attr[name]; + mrow.attrNames.push(name); + delete mml.attr[name]; + mml.attrNames.splice(i,1); + } + } + mrow.complexity = mml.complexity; + maction.Append(mrow); mml.Append(maction); + mml.complexity = maction.complexity; maction = mml; + } else { + maction.Append(mml); + } + return maction; + }, + + actionID: 1, + getActionID: function () {return "MJX-Collapse-"+this.actionID++}, + + /*****************************************************************/ + + // + // If there is a specific routine for the type, do that, otherwise + // check if there is a complexity cut-off and marker for this type. + // If so, check if the complexity exceeds the cut off, and + // collapse using the appropriate marker for the type + // Return the (possibly modified) MathML + // + Collapse: function (mml) { + mml.getComplexity(); + var type = (mml.attr||{})["data-semantic-type"]; + if (type) { + if (this["Collapse_"+type]) mml = (this["Collapse_"+type])(mml); + else if (this.COLLAPSE[type] && this.MARKER[type]) { + var role = mml.attr["data-semantic-role"]; + var complexity = this.COLLAPSE[type]; + if (typeof(complexity) !== "number") complexity = complexity[role] || complexity.value; + if (mml.complexity > complexity) { + var marker = this.MARKER[type]; + if (typeof(marker) !== "string") marker = marker[role] || marker.value; + mml = this.MakeAction(this.Marker(marker),mml); + } + } + } + return mml; + }, + + // + // If a parent is going to be collapsible, if can call this + // to put back a collapsed child (rather than have too many + // nested collapsings) + // + UncollapseChild: function (mml,n,m) { + if (m == null) m = 1; + if (this.SplitAttribute(mml,"children").length === m) { + var child = (mml.data.length === 1 && mml.data[0].inferred ? mml.data[0] : mml); + if (child && child.data[n] && child.data[n].collapsible) { + child.SetData(n,child.data[n].data[1]); + mml.complexity = child.complexity = null; mml.getComplexity(); + return 1; + } + } + return 0; + }, + + // + // Locate child node and return its text + // + FindChildText: function (mml,id) { + var child = this.FindChild(mml,id); + return (child ? (child.CoreMO()||child).data.join("") : "?"); + }, + FindChild: function (mml,id) { + if (mml) { + if (mml.attr && mml.attr["data-semantic-id"] === id) return mml; + if (!mml.isToken) { + for (var i = 0, m = mml.data.length; i < m; i++) { + var child = this.FindChild(mml.data[i],id); + if (child) return child; + } + } + } + return null; + }, + + // + // Split a data attribute at commas + // + SplitAttribute: function (mml,id) { + return (mml.attr["data-semantic-"+id]||"").split(/,/); + }, + + /*****************************************************************/ + /* + * These routines implement the collapsing of the various semantic types + */ + + // + // For fenced elements, if the contents are collapsed, + // collapse the fence instead. + // + Collapse_fenced: function (mml) { + this.UncollapseChild(mml,1); + if (mml.complexity > this.COLLAPSE.fenced) { + if (mml.attr["data-semantic-role"] === "leftright") { + var marker = mml.data[0].data.join("") + mml.data[mml.data.length-1].data.join(""); + mml = this.MakeAction(this.Marker(marker),mml); + } + } + return mml; + }, + + // + // Collapse function applications if the argument is collapsed + // (Handle role="limit function" a bit better?) + // + Collapse_appl: function (mml) { + if (this.UncollapseChild(mml,2,2)) { + var marker = this.MARKER.appl; + marker = marker[mml.attr["data-semantic-role"]] || marker.value; + mml = this.MakeAction(this.Marker(marker),mml); + } + return mml; + }, + + // + // For sqrt elements, if the contents are collapsed, + // collapse the sqrt instead. + // + Collapse_sqrt: function (mml) { + this.UncollapseChild(mml,0); + if (mml.complexity > this.COLLAPSE.sqrt) + mml = this.MakeAction(this.Marker(this.MARKER.sqrt),mml); + return mml; + }, + Collapse_root: function (mml) { + this.UncollapseChild(mml,0); + if (mml.complexity > this.COLLAPSE.sqrt) + mml = this.MakeAction(this.Marker(this.MARKER.sqrt),mml); + return mml; + }, + + // + // For enclose, include enclosure in collapsed child, if any + // + Collapse_enclose: function (mml) { + if (this.SplitAttribute(mml,"children").length === 1) { + var child = (mml.data.length === 1 && mml.data[0].inferred ? mml.data[0] : mml); + if (child.data[0] && child.data[0].collapsible) { + // + // Move menclose into the maction element + // + var maction = child.data[0]; + child.SetData(0,maction.data[1]); + maction.SetData(1,mml); + mml = maction; + } + } + return mml; + }, + + // + // For bigops, get the character to use from the largeop at its core. + // + Collapse_bigop: function (mml) { + if (mml.complexity > this.COLLAPSE.bigop || mml.data[0].type !== "mo") { + var id = this.SplitAttribute(mml,"content").pop(); + var op = Collapsible.FindChildText(mml,id); + mml = this.MakeAction(this.Marker(op),mml); + } + return mml; + }, + Collapse_integral: function (mml) { + if (mml.complexity > this.COLLAPSE.integral || mml.data[0].type !== "mo") { + var id = this.SplitAttribute(mml,"content")[0]; + var op = Collapsible.FindChildText(mml,id); + mml = this.MakeAction(this.Marker(op),mml); + } + return mml; + }, + + // + // For multirel and relseq, use proper symbol + // + Collapse_relseq: function (mml) { + if (mml.complexity > this.COLLAPSE.relseq) { + var content = this.SplitAttribute(mml,"content"); + var marker = Collapsible.FindChildText(mml,content[0]); + if (content.length > 1) marker += "\u22EF"; + mml = this.MakeAction(this.Marker(marker),mml); + } + return mml; + }, + Collapse_multirel: function (mml) { + if (mml.complexity > this.COLLAPSE.multirel) { + var content = this.SplitAttribute(mml,"content"); + var marker = Collapsible.FindChildText(mml,content[0]) + "\u22EF"; + mml = this.MakeAction(this.Marker(marker),mml); + } + return mml; + }, + + // + // Include super- and subscripts into a collapsed base + // + Collapse_superscript: function (mml) { + this.UncollapseChild(mml,0,2); + if (mml.complexity > this.COLLAPSE.superscript) + mml = this.MakeAction(this.Marker(this.MARKER.superscript),mml); + return mml; + }, + Collapse_subscript: function (mml) { + this.UncollapseChild(mml,0,2); + if (mml.complexity > this.COLLAPSE.subscript) + mml = this.MakeAction(this.Marker(this.MARKER.subscript),mml); + return mml; + }, + Collapse_subsup: function (mml) { + this.UncollapseChild(mml,0,3); + if (mml.complexity > this.COLLAPSE.subsup) + mml = this.MakeAction(this.Marker(this.MARKER.subsup),mml); + return mml; + } + }; + + HUB.Register.StartupHook("End Extensions", function () { + if (SETTINGS.collapsible == null) { + SETTINGS.collapsible = !Collapsible.config.disabled; + } else { + Collapsible.config.disabled = !SETTINGS.collapsible; + } + HUB.Register.StartupHook("MathMenu Ready", function () { + COOKIE = MathJax.Menu.cookie; + var Switch = function(menu) { + Collapsible[SETTINGS.collapsible ? "Enable" : "Disable"](true,true); + MathJax.Menu.saveCookie(); + }; + var ITEM = MathJax.Menu.ITEM, + MENU = MathJax.Menu.menu; + var menu = ITEM.CHECKBOX( + ['CollapsibleMath','Collapsible Math'], 'collapsible', {action: Switch} + ); + var submenu = (MENU.FindId('Accessibility')||{}).submenu, index; + if (submenu) { + index = submenu.IndexOfId('CollapsibleMath'); + if (index !== null) { + submenu.items[index] = menu; + } else { + submenu.items.push(ITEM.RULE(),menu); + } + } else { + index = MENU.IndexOfId('About'); + MENU.items.splice(index,0,menu,ITEM.RULE()); + } + },15); // before explorer extension + },15); + +})(MathJax.Hub); + + +/*****************************************************************/ +/* + * Add Collapse() and getComplexity() methods to the internal + * MathML elements, and override these in the elements that need + * special handling. + */ + +MathJax.Ajax.Require("[a11y]/semantic-enrich.js"); +MathJax.Hub.Register.StartupHook("Semantic Enrich Ready", function () { + var MML = MathJax.ElementJax.mml, + Collapsible = MathJax.Extension.collapsible, + COMPLEXITY = Collapsible.COMPLEXITY, + COMPLEXATTR = Collapsible.COMPLEXATTR; + + Collapsible.Startup(); // Initialize the collapsing process + + MML.mbase.Augment({ + // + // Just call the Collapse() method from the extension by default + // (but can be overridden) + // + Collapse: function () {return Collapsible.Collapse(this)}, + // + // If we don't have a cached complexity value, + // For token elements, just use the data length, + // Otherwise + // Add up the complexities of the (collapsed) children + // and add the child complexity based on the number of children + // Cache the complexity result + // return the complexity + // + getComplexity: function () { + if (this.complexity == null) { + var complexity = 0; + if (this.isToken) { + complexity = COMPLEXITY.TEXT * this.data.join("").length + COMPLEXITY.TOKEN; + } else { + for (var i = 0, m = this.data.length; i < m; i++) { + if (this.data[i]) { + this.SetData(i,this.data[i].Collapse()); + complexity += this.data[i].complexity; + } + } + if (m > 1) complexity += m * COMPLEXITY.CHILD; + } + if (this.attrNames && !("complexity" in this)) this.attrNames.push(COMPLEXATTR); + if (this.attr) this.attr[COMPLEXATTR] = complexity; + this.complexity = complexity; + } + return this.complexity; + }, + reportComplexity: function () { + if (this.attr && this.attrNames && !(COMPLEXATTR in this.attr)) { + this.attrNames.push(COMPLEXATTR); + this.attr[COMPLEXATTR] = this.complexity; + } + } + }); + + // + // For fractions, scale the complexity of the parts, and add + // a complexity for fractions. + // + MML.mfrac.Augment({ + getComplexity: function () { + if (this.complexity == null) { + this.SUPER(arguments).getComplexity.call(this); + this.complexity *= COMPLEXITY.SCRIPT; + this.complexity += COMPLEXITY.FRACTION; + this.attr[COMPLEXATTR] = this.complexity; + } + return this.complexity; + } + }); + + // + // Square roots add extra complexity + // + MML.msqrt.Augment({ + getComplexity: function () { + if (this.complexity == null) { + this.SUPER(arguments).getComplexity.call(this); + this.complexity += COMPLEXITY.SQRT; + this.attr[COMPLEXATTR] = this.complexity; + } + return this.complexity; + } + }); + MML.mroot.Augment({ + getComplexity: function () { + if (this.complexity == null) { + this.SUPER(arguments).getComplexity.call(this); + this.complexity -= (1-COMPLEXITY.SCRIPT) * this.data[1].getComplexity(); + this.complexity += COMPLEXITY.SQRT; + this.attr[COMPLEXATTR] = this.complexity; + } + return this.complexity; + } + }); + + // + // For msubsup, use the script complexity factor, + // take the maximum of the scripts, + // and add the sub-sup complexity + // + MML.msubsup.Augment({ + getComplexity: function () { + if (this.complexity == null) { + var C = 0; + if (this.data[this.sub]) C = this.data[this.sub].getComplexity() + COMPLEXITY.CHILD; + if (this.data[this.sup]) C = Math.max(this.data[this.sup].getComplexity(),C); + C *= COMPLEXITY.SCRIPT; + if (this.data[this.sub]) C += COMPLEXITY.CHILD; + if (this.data[this.sup]) C += COMPLEXITY.CHILD; + if (this.data[this.base]) C += this.data[this.base].getComplexity() + COMPLEXITY.CHILD; + this.complexity = C + COMPLEXITY.SUBSUP; + this.reportComplexity(); + } + return this.complexity; + } + }); + + // + // For munderover, use the script complexity factor, + // take the maximum of the scripts and the base, + // and add the under-over complexity + // + MML.munderover.Augment({ + getComplexity: function () { + if (this.complexity == null) { + var C = 0; + if (this.data[this.sub]) C = this.data[this.sub].getComplexity() + COMPLEXITY.CHILD; + if (this.data[this.sup]) C = Math.max(this.data[this.sup].getComplexity(),C); + C *= COMPLEXITY.SCRIPT; + if (this.data[this.base]) C = Math.max(this.data[this.base].getComplexity(),C); + if (this.data[this.sub]) C += COMPLEXITY.CHILD; + if (this.data[this.sup]) C += COMPLEXITY.CHILD; + if (this.data[this.base]) C += COMPLEXITY.CHILD; + this.complexity = C + COMPLEXITY.UNDEROVER; + this.reportComplexity(); + } + return this.complexity; + } + }); + + // + // For mphantom, complexity is 0? + // + MML.mphantom.Augment({ + getComplexity: function () { + this.complexity = COMPLEXITY.PHANTOM; + this.reportComplexity(); + return this.complexity; + } + }); + + // + // For ms, add width of quotes. Don't cache the result, since + // mstyle above it could affect the result. + // + MML.ms.Augment({ + getComplexity: function () { + this.SUPER(arguments).getComplexity.call(this); + this.complexity += this.Get("lquote").length * COMPLEXITY.TEXT; + this.complexity += this.Get("rquote").length * COMPLEXITY.TEXT; + this.attr[COMPLEXATTR] = this.complexity; + return this.complexity; + } + }); + +// ### FIXME: getComplexity special cases: +// mtable, mfenced, mmultiscript + + // + // For menclose, complexity goes up by a fixed amount + // + MML.menclose.Augment({ + getComplexity: function () { + if (this.complexity == null) { + this.SUPER(arguments).getComplexity.call(this); + this.complexity += COMPLEXITY.ACTION; + this.attr[COMPLEXATTR] = this.complexity; + } + return this.complexity; + } + }); + + // + // For maction, complexity is complexity of selected element + // + MML.maction.Augment({ + getComplexity: function () { + // + // Don't cache it, since selection can change. + // + this.complexity = (this.collapsible ? this.data[0] : this.selected()).getComplexity(); + this.reportComplexity(); + return this.complexity; + } + }); + + // + // For semantics, complexity is complexity of first child + // + MML.semantics.Augment({ + getComplexity: function () { + if (this.complexity == null) { + this.complexity = (this.data[0] ? this.data[0].getComplexity() : 0); + this.reportComplexity(); + } + return this.complexity; + } + }); + + // + // Use fixed complexity, since we can't really measure it + // + MML["annotation-xml"].Augment({ + getComplexity: function () { + this.complexity = COMPLEXITY.XML; + this.reportComplexity(); + return this.complexity; + } + }); + MML.annotation.Augment({ + getComplexity: function () { + this.complexity = COMPLEXITY.XML; + this.reportComplexity(); + return this.complexity; + } + }); + + // + // Use fixed complexity, since we can't really measure it + // + MML.mglyph.Augment({ + getComplexity: function () { + this.complexity = COMPLEXITY.GLYPH; + this.reportComplexity(); + return this.complexity; + } + }); + + // + // Signal that we are ready + // + MathJax.Hub.Startup.signal.Post("Collapsible Ready"); + MathJax.Ajax.loadComplete("[a11y]/collapsible.js"); +}); + +// @license-end diff --git a/js/mathjax/extensions/a11y/explorer.js b/js/mathjax/extensions/a11y/explorer.js new file mode 100644 index 0000000..bba3edd --- /dev/null +++ b/js/mathjax/extensions/a11y/explorer.js @@ -0,0 +1,827 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * [Contrib]/a11y/explorer.js + * + * Implements expression exploration via the SRE explorer. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2016-2017 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +MathJax.Hub.Register.StartupHook('Sre Ready', function() { + var FALSE, KEY; + var SETTINGS = MathJax.Hub.config.menuSettings; + var COOKIE = {}; // replaced when menu is available + + MathJax.Hub.Register.StartupHook('MathEvents Ready', function() { + FALSE = MathJax.Extension.MathEvents.Event.False; + KEY = MathJax.Extension.MathEvents.Event.KEY; + }); + + var Assistive = MathJax.Extension.explorer = { + version: '1.6.0', + dependents: [], // the extensions that depend on this one + // + // Default configurations. + // + defaults: { + walker: 'table', + highlight: 'none', + background: 'blue', + foreground: 'black', + speech: true, + generation: 'lazy', + subtitle: false, + ruleset: 'mathspeak-default' + }, + eagerComplexity: 80, + prefix: 'Assistive-', + hook: null, + locHook: null, + oldrules: null, + addMenuOption: function(key, value) { + SETTINGS[Assistive.prefix + key] = value; + }, + + addDefaults: function() { + var defaults = MathJax.Hub.CombineConfig('explorer', Assistive.defaults); + var keys = Object.keys(defaults); + for (var i = 0, key; key = keys[i]; i++) { + if (typeof(SETTINGS[Assistive.prefix + key]) === 'undefined') { + Assistive.addMenuOption(key, defaults[key]); + } + } + Assistive.setSpeechOption(); + Explorer.Reset(); + }, + + setOption: function(key, value) { + if (SETTINGS[Assistive.prefix + key] === value) return; + Assistive.addMenuOption(key, value); + Explorer.Reset(); + }, + + getOption: function(key) { + return SETTINGS[Assistive.prefix + key]; + }, + + speechOption: function(msg) { + if (Assistive.oldrules === msg.value) return; + Assistive.setSpeechOption(); + Explorer.Regenerate(); + }, + + setSpeechOption: function() { + var ruleset = SETTINGS[Assistive.prefix + 'ruleset']; + var cstr = ruleset.split('-'); + sre.System.getInstance().setupEngine({ + locale: MathJax.Localization.locale, + domain: Assistive.Domain(cstr[0]), + style: cstr[1] + }); + Assistive.oldrules = ruleset; + }, + + Domain: function(domain) { + switch (domain) { + case 'chromevox': + return 'default'; + case 'clearspeak': + return 'clearspeak'; + case 'mathspeak': + default: + return 'mathspeak'; + } + }, + + hook: null, + locHook: null, + Enable: function(update, menu) { + SETTINGS.explorer = true; + if (menu) COOKIE.explorer = true; + MathJax.Extension.collapsible.Enable(false, menu); + if (MathJax.Extension.AssistiveMML) { + MathJax.Extension.AssistiveMML.config.disabled = true; + SETTINGS.assistiveMML = false; + if (menu) COOKIE.assistiveMML = false; + } + this.DisableMenus(false); + if (!this.hook) { + this.hook = MathJax.Hub.Register.MessageHook( + 'New Math', ['Register', this.Explorer]); + } + if (!this.locHook) { + this.locHook = MathJax.Hub.Register.MessageHook( + 'Locale Reset', ['RemoveSpeech', this.Explorer]); + } + if (update) MathJax.Hub.Queue(['Reprocess', MathJax.Hub]); + }, + Disable: function(update, menu) { + SETTINGS.explorer = false; + if (menu) COOKIE.explorer = false; + this.DisableMenus(true); + if (this.hook) { + MathJax.Hub.UnRegister.MessageHook(this.hook); + this.hook = null; + } + for (var i = this.dependents.length - 1; i >= 0; i--) { + var dependent = this.dependents[i]; + if (dependent.Disable) dependent.Disable(false, menu); + } + // Reprocess on update? I don't think it is necessary + // (now that we check for being enabled in the event handlers) + }, + DisableMenus: function(state) { + if (MathJax.Menu) { + var menu = MathJax.Menu.menu.FindId('Accessibility', 'Explorer'); + if (menu) { + menu = menu.submenu; + var items = menu.items; + for (var i = 2, item; item = items[i]; i++) item.disabled = state; + if (!state && menu.FindId('SpeechOutput') && !SETTINGS[Assistive.prefix + 'speech']) { + menu.FindId('Subtitles').disabled = true; + } + } + } + }, + // + // Register a dependent + // + Dependent: function(extension) { + this.dependents.push(extension); + } + }; + + var LiveRegion = MathJax.Object.Subclass({ + div: null, + inner: null, + Init: function() { + this.div = LiveRegion.Create('assertive'); + this.inner = MathJax.HTML.addElement(this.div, 'div'); + }, + // + // Adds the speech div. + // + Add: function() { + if (LiveRegion.added) return; + document.body.appendChild(this.div); + LiveRegion.added = true; + }, + // + // Shows the live region as a subtitle of a node. + // + Show: function(node, highlighter) { + this.div.classList.add('MJX_LiveRegion_Show'); + var rect = node.getBoundingClientRect(); + var bot = rect.bottom + 10 + window.pageYOffset; + var left = rect.left + window.pageXOffset; + this.div.style.top = bot + 'px'; + this.div.style.left = left + 'px'; + var color = highlighter.colorString(); + this.inner.style.backgroundColor = color.background; + this.inner.style.color = color.foreground; + }, + // + // Takes the live region out of the page flow. + // + Hide: function(node) { + this.div.classList.remove('MJX_LiveRegion_Show'); + }, + // + // Clears the speech div. + // + Clear: function() { + this.Update(''); + this.inner.style.top = ''; + this.inner.style.backgroundColor = ''; + }, + // + // Speaks a string by poking it into the speech div. + // + Update: function(speech) { + if (Assistive.getOption('speech')) { + LiveRegion.Update(this.inner, speech); + } + } + }, { + ANNOUNCE: 'Navigatable Math in page. Explore with enter or shift space and arrow' + + ' keys. Expand or collapse elements hitting enter.', + announced: false, + added: false, + styles: {'.MJX_LiveRegion': + { + position: 'absolute', top: '0', height: '1px', width: '1px', + padding: '1px', overflow: 'hidden' + }, + '.MJX_LiveRegion_Show': + { + top: '0', position: 'absolute', width: 'auto', height: 'auto', + padding: '0px 0px', opacity: 1, 'z-index': '202', + left: 0, right: 0, 'margin': '0 auto', + 'background-color': 'white', 'box-shadow': '0px 10px 20px #888', + border: '2px solid #CCCCCC' + } + }, + // + // Creates a live region with a particular type. + // + Create: function(type) { + var element = MathJax.HTML.Element( + 'div', {className: 'MJX_LiveRegion'}); + element.setAttribute('aria-live', type); + return element; + }, + // + // Updates a live region's text content. + // + Update: MathJax.Hub.Browser.isPC ? + function(div, speech) { + div.textContent = ''; + setTimeout(function() {div.textContent = speech;}, 100); + } : function(div, speech) { + div.textContent = ''; + div.textContent = speech; + }, + // + // Speaks the announce string. + // + Announce: function() { + if (!Assistive.getOption('speech')) return; + LiveRegion.announced = true; + MathJax.Ajax.Styles(LiveRegion.styles); + var div = LiveRegion.Create('polite'); + document.body.appendChild(div); + LiveRegion.Update(div, LiveRegion.ANNOUNCE); + setTimeout(function() {document.body.removeChild(div);}, 1000); + } + }); + MathJax.Extension.explorer.LiveRegion = LiveRegion; + + var A11Y_PATH = MathJax.Ajax.fileURL(MathJax.Ajax.config.path.a11y); + + var Explorer = MathJax.Extension.explorer.Explorer = { + liveRegion: LiveRegion(), + walker: null, + highlighter: null, + hoverer: null, + flamer: null, + speechDiv: null, + earconFile: A11Y_PATH + '/invalid_keypress' + + (['Firefox', 'Chrome', 'Opera'].indexOf(MathJax.Hub.Browser.name) !== -1 ? + '.ogg' : '.mp3'), + expanded: false, + focusoutEvent: MathJax.Hub.Browser.isFirefox ? 'blur' : 'focusout', + focusinEvent: 'focus', + ignoreFocusOut: false, + jaxCache: {}, + messageID: null, + // + // Resets the explorer, rerunning methods not triggered by events. + // + Reset: function() { + Explorer.FlameEnriched(); + }, + // + // Registers new Maths and adds a key event if it is enriched. + // + Register: function(msg) { + if (!Assistive.hook) return; + var script = document.getElementById(msg[1]); + if (script && script.id) { + var jax = MathJax.Hub.getJaxFor(script.id); + if (jax && jax.enriched) { + Explorer.StateChange(script.id, jax); + Explorer.liveRegion.Add(); + Explorer.AddEvent(script); + } + } + }, + StateChange: function(id, jax) { + Explorer.GetHighlighter(.2); + var oldJax = Explorer.jaxCache[id]; + if (oldJax && oldJax === jax.root) return; + if (oldJax) { + sre.Walker.resetState(id + '-Frame'); + } + Explorer.jaxCache[id] = jax.root; + }, + // + // Adds Aria attributes. + // + AddAria: function(math) { + math.setAttribute('role', 'application'); + math.setAttribute('aria-label', 'Math'); + }, + // + // Add hook to run at End Math to restart walking on an expansion element. + // + AddHook: function(jax) { + Explorer.RemoveHook(); + Explorer.hook = MathJax.Hub.Register.MessageHook( + 'End Math', function(message) { + var newid = message[1].id + '-Frame'; + var math = document.getElementById(newid); + if (jax && newid === Explorer.expanded) { + Explorer.ActivateWalker(math, jax); + math.focus(); + Explorer.expanded = false; + } + }); + }, + // + // Remove and unregister the explorer hook. + // + RemoveHook: function() { + if (Explorer.hook) { + MathJax.Hub.UnRegister.MessageHook(Explorer.hook); + Explorer.hook = null; + } + }, + AddMessage: function() { + return MathJax.Message.Set('Generating Speech Output'); + }, + RemoveMessage: function(id) { + if (id) MathJax.Message.Clear(id); + }, + // + // Adds a key event to an enriched jax. + // + AddEvent: function(script) { + var id = script.id + '-Frame'; + var sibling = script.previousSibling; + if (!sibling) return; + var math = sibling.id !== id ? sibling.firstElementChild : sibling; + Explorer.AddAria(math); + Explorer.AddMouseEvents(math); + if (math.className === 'MathJax_MathML') { + math = math.firstElementChild; + } + if (!math) return; + math.onkeydown = Explorer.Keydown; + Explorer.Flame(math); + math.addEventListener( + Explorer.focusinEvent, + function(event) { + if (!Assistive.hook) return; + if (!LiveRegion.announced) LiveRegion.Announce(); + }); + math.addEventListener( + Explorer.focusoutEvent, + function(event) { + if (!Assistive.hook) return; + // A fix for Edge. + if (Explorer.ignoreFocusOut) { + Explorer.ignoreFocusOut = false; + if (Explorer.walker.moved === 'enter') { + event.target.focus(); + return; + } + } + if (Explorer.walker) Explorer.DeactivateWalker(); + }); + // + if (Assistive.getOption('speech')) { + Explorer.AddSpeech(math); + } + // + }, + // + // Add speech output. + // + AddSpeech: function(math) { + var id = math.id; + var jax = MathJax.Hub.getJaxFor(id); + var mathml = jax.root.toMathML(); + if (!math.getAttribute('haslabel')) { + Explorer.AddMathLabel(mathml, id); + } + if (math.getAttribute('hasspeech')) return; + switch (MathJax.Hub.config.explorer.generation) { + case 'eager': + Explorer.AddSpeechEager(mathml, id); + break; + case 'mixed': + var complexity = math.querySelectorAll('[data-semantic-complexity]'); + if (complexity.length >= Assistive.eagerComplexity) { + Explorer.AddSpeechEager(mathml, id); + } + break; + case 'lazy': + default: + break; + } + }, + AddSpeechLazy: function(math) { + var generator = new sre.TreeSpeechGenerator(); + generator.setRebuilt(Explorer.walker.getRebuilt()); + generator.getSpeech(Explorer.walker.rootNode, Explorer.walker.getXml()); + math.setAttribute('hasspeech', 'true'); + }, + // + // + // Adds speech strings to the node using a web worker. + // + AddSpeechEager: function(mathml, id) { + Explorer.MakeSpeechTask( + mathml, id, sre.TreeSpeechGenerator, + function(math, speech) {math.setAttribute('hasspeech', 'true');}, 5); + }, + // + // Attaches the Math expression as an aria label. + // + AddMathLabel: function(mathml, id) { + Explorer.MakeSpeechTask( + mathml, id, sre.SummarySpeechGenerator, + function(math, speech) { + math.setAttribute('haslabel', 'true'); + math.setAttribute('aria-label', speech);}, + 5); + }, + // + // The actual speech task generator. + // + MakeSpeechTask: function(mathml, id, constructor, onSpeech, time) { + var messageID = Explorer.AddMessage(); + setTimeout(function() { + var speechGenerator = new constructor(); + var math = document.getElementById(id); + var dummy = new sre.DummyWalker( + math, speechGenerator, Explorer.highlighter, mathml); + var speech = dummy.speech(); + if (speech) { + onSpeech(math, speech); + } + Explorer.RemoveMessage(messageID); + }, time); + }, + // + // Event execution on keydown. Subsumes the same method of MathEvents. + // + Keydown: function(event) { + var code = event.keyCode; + if (code === KEY.ESCAPE) { + if (!Explorer.walker) return; + Explorer.RemoveHook(); + Explorer.DeactivateWalker(); + FALSE(event); + return; + } + // If walker is active we redirect there. + if (Explorer.walker && Explorer.walker.isActive()) { + // Maps the return key to dash for SRE v3. + code = code === KEY.RETURN ? KEY.DASH : code; + if (typeof(Explorer.walker.modifier) !== 'undefined') { + Explorer.walker.modifier = event.shiftKey; + } + var move = Explorer.walker.move(code); + if (move === null) return; + if (move) { + if (Explorer.walker.moved === 'expand') { + Explorer.expanded = Explorer.walker.node.id; + // This sometimes blurs in Edge and sometimes it does not. + if (MathJax.Hub.Browser.isEdge) { + Explorer.ignoreFocusOut = true; + Explorer.DeactivateWalker(); + return; + } + // This does not blur in FF, IE. + if (MathJax.Hub.Browser.isFirefox || MathJax.Hub.Browser.isMSIE) { + Explorer.DeactivateWalker(); + return; + } + } + Explorer.liveRegion.Update(Explorer.walker.speech()); + Explorer.Highlight(); + } else { + Explorer.PlayEarcon(); + } + FALSE(event); + return; + } + var math = event.target; + if (code === KEY.SPACE && !event.shiftKey) { + MathJax.Extension.MathEvents.Event.ContextMenu(event, math); + FALSE(event); + return; + } + if (Assistive.hook && (code === KEY.RETURN || + (code === KEY.SPACE && event.shiftKey))) { + var jax = MathJax.Hub.getJaxFor(math); + Explorer.ActivateWalker(math, jax); + Explorer.AddHook(jax); + FALSE(event); + return; + } + }, + GetHighlighter: function(alpha) { + Explorer.highlighter = sre.HighlighterFactory.highlighter( + {color: Assistive.getOption('background'), alpha: alpha}, + {color: Assistive.getOption('foreground'), alpha: 1}, + {renderer: MathJax.Hub.outputJax['jax/mml'][0].id, + browser: MathJax.Hub.Browser.name} + ); + }, + // + // Adds mouse events to maction items in an enriched jax. + // + AddMouseEvents: function(node) { + sre.HighlighterFactory.addEvents( + node, + {'mouseover': Explorer.MouseOver, + 'mouseout': Explorer.MouseOut}, + {renderer: MathJax.Hub.outputJax['jax/mml'][0].id, + browser: MathJax.Hub.Browser.name} + ); + }, + MouseOver: function(event) { + if (Assistive.getOption('highlight') === 'none') return; + if (Assistive.getOption('highlight') === 'hover') { + var frame = event.currentTarget; + Explorer.GetHighlighter(.1); + Explorer.highlighter.highlight([frame]); + Explorer.hoverer = true; + } + FALSE(event); + }, + MouseOut: function(event) { + if (Explorer.hoverer) { + Explorer.highlighter.unhighlight(); + Explorer.hoverer = false; + } + return FALSE(event); + }, + // + // Activates Flaming + // + Flame: function(node) { + if (Assistive.getOption('highlight') === 'flame') { + Explorer.GetHighlighter(.05); + Explorer.highlighter.highlightAll(node); + Explorer.flamer = true; + return; + } + }, + UnFlame: function() { + if (Explorer.flamer) { + Explorer.highlighter.unhighlightAll(); + Explorer.flamer = null; + } + }, + FlameEnriched: function() { + Explorer.UnFlame(); + for (var i = 0, all = MathJax.Hub.getAllJax(), jax; jax = all[i]; i++) { + Explorer.Flame(jax.SourceElement().previousSibling); + } + }, + // + // Activates the walker. + // + Walkers: { + 'syntactic': sre.SyntaxWalker, + 'table': sre.TableWalker, + 'semantic': sre.SemanticWalker, + 'none': sre.DummyWalker + }, + ActivateWalker: function(math, jax) { + var speechOn = Assistive.getOption('speech'); + var constructor = Assistive.getOption('walker') ? + Explorer.Walkers[MathJax.Hub.config.explorer.walker] : + Explorer.Walkers['none']; + var speechGenerator = speechOn ? new sre.DirectSpeechGenerator() : + new sre.DummySpeechGenerator(); + var options = sre.System.getInstance().engineSetup(); + speechGenerator.setOptions({ + locale: options.locale, domain: options.domain, + style: options.style, modality: 'speech'}); + Explorer.GetHighlighter(.2); + Explorer.walker = new constructor( + math, speechGenerator, Explorer.highlighter, jax.root.toMathML()); + if (speechOn && !math.getAttribute('hasspeech')) { + Explorer.AddSpeechLazy(math); + } + Explorer.walker.activate(); + if (speechOn) { + if (Assistive.getOption('subtitle')) { + Explorer.liveRegion.Show(math, Explorer.highlighter); + } + Explorer.liveRegion.Update(Explorer.walker.speech()); + } + Explorer.Highlight(); + // A fix for Edge. + if (Explorer.ignoreFocusOut) { + setTimeout(function() {Explorer.ignoreFocusOut = false;}, 500); + } + }, + // + // Deactivates the walker. + // + DeactivateWalker: function() { + var setup = sre.System.getInstance().engineSetup(); + var domain = setup.domain; + var style = domain === 'clearspeak' ? 'default' : setup.style; + Assistive.setOption('ruleset', setup.domain + '-' + style); + Explorer.liveRegion.Clear(); + Explorer.liveRegion.Hide(); + Explorer.Unhighlight(); + Explorer.currentHighlight = null; + Explorer.walker.deactivate(); + Explorer.walker = null; + }, + // + // Highlights the focused nodes. + // + Highlight: function() { + Explorer.Unhighlight(); + Explorer.highlighter.highlight(Explorer.walker.getFocus().getNodes()); + }, + // + // Unhighlights the old nodes. + // + Unhighlight: function() { + Explorer.highlighter.unhighlight(); + }, + // + // Plays the earcon. + // + // Every time we make new Audio element, as some browsers do not allow to + // play audio elements more than once (e.g., Safari). + // + PlayEarcon: function() { + var audio = new Audio(Explorer.earconFile); + audio.play(); + }, + // + // Toggle speech output. + // + SpeechOutput: function() { + Explorer.Reset(); + var speechItems = ['Subtitles']; + speechItems.forEach( + function(x) { + var item = MathJax.Menu.menu.FindId('Accessibility', 'Explorer', x); + if (item) { + item.disabled = !item.disabled; + }}); + Explorer.Regenerate(); + }, + // + // Remove speech and resets SRE options. + // + RemoveSpeech: function() { + Assistive.setSpeechOption(); + for (var i = 0, all = MathJax.Hub.getAllJax(), jax; jax = all[i]; i++) { + var math = document.getElementById(jax.inputID + '-Frame'); + if (math) { + math.removeAttribute('hasspeech'); + math.removeAttribute('haslabel'); + } + } + }, + // + // Regenerates speech. + // + Regenerate: function() { + for (var i = 0, all = MathJax.Hub.getAllJax(), jax; jax = all[i]; i++) { + var math = document.getElementById(jax.inputID + '-Frame'); + if (math) { + math.removeAttribute('hasspeech'); + Explorer.AddSpeech(math); + } + } + }, + Startup: function() { + var Collapsible = MathJax.Extension.collapsible; + if (Collapsible) Collapsible.Dependent(Assistive); + Assistive.addDefaults(); + } + }; + + MathJax.Hub.Register.StartupHook('End Extensions', function() { + Assistive[SETTINGS.explorer === false ? 'Disable' : 'Enable'](); + MathJax.Hub.Startup.signal.Post('Explorer Ready'); + MathJax.Hub.Register.StartupHook('MathMenu Ready', function() { + COOKIE = MathJax.Menu.cookie; + var Switch = function(menu) { + Assistive[SETTINGS.explorer ? 'Enable' : 'Disable'](true, true); + MathJax.Menu.saveCookie(); + }; + var ITEM = MathJax.Menu.ITEM, + MENU = MathJax.Menu.menu; + var reset = {action: Explorer.Reset}; + var speech = {action: Assistive.speechOption}; + var explorerMenu = + ITEM.SUBMENU(['Explorer', 'Explorer'], + ITEM.CHECKBOX(['Active', 'Active'], 'explorer', {action: Switch}), + ITEM.RULE(), + ITEM.CHECKBOX(['Walker', 'Walker'], 'Assistive-walker'), + ITEM.SUBMENU(['Highlight', 'Highlight'], + ITEM.RADIO(['none', 'None'], 'Assistive-highlight', reset), + ITEM.RADIO(['hover', 'Hover'], 'Assistive-highlight', reset), + ITEM.RADIO(['flame', 'Flame'], 'Assistive-highlight', reset) + ), + ITEM.SUBMENU(['Background', 'Background'], + ITEM.RADIO(['blue', 'Blue'], 'Assistive-background', reset), + ITEM.RADIO(['red', 'Red'], 'Assistive-background', reset), + ITEM.RADIO(['green', 'Green'], 'Assistive-background', reset), + ITEM.RADIO(['yellow', 'Yellow'], 'Assistive-background', reset), + ITEM.RADIO(['cyan', 'Cyan'], 'Assistive-background', reset), + ITEM.RADIO(['magenta', 'Magenta'], 'Assistive-background', reset), + ITEM.RADIO(['white', 'White'], 'Assistive-background', reset), + ITEM.RADIO(['black', 'Black'], 'Assistive-background', reset) + ), + ITEM.SUBMENU(['Foreground', 'Foreground'], + ITEM.RADIO(['black', 'Black'], 'Assistive-foreground', reset), + ITEM.RADIO(['white', 'White'], 'Assistive-foreground', reset), + ITEM.RADIO(['magenta', 'Magenta'], 'Assistive-foreground', reset), + ITEM.RADIO(['cyan', 'Cyan'], 'Assistive-foreground', reset), + ITEM.RADIO(['yellow', 'Yellow'], 'Assistive-foreground', reset), + ITEM.RADIO(['green', 'Green'], 'Assistive-foreground', reset), + ITEM.RADIO(['red', 'Red'], 'Assistive-foreground', reset), + ITEM.RADIO(['blue', 'Blue'], 'Assistive-foreground', reset) + ), + ITEM.RULE(), + ITEM.CHECKBOX(['SpeechOutput', 'Speech Output'], + 'Assistive-speech', {action: Explorer.SpeechOutput}), + ITEM.CHECKBOX(['Subtitles', 'Subtitles'], 'Assistive-subtitle', + {disabled: !SETTINGS['Assistive-speech']}), + ITEM.RULE(), + ITEM.SUBMENU(['Mathspeak', 'Mathspeak Rules'], + ITEM.RADIO(['mathspeak-default', 'Verbose'], + 'Assistive-ruleset', speech), + ITEM.RADIO(['mathspeak-brief', 'Brief'], 'Assistive-ruleset', speech), + ITEM.RADIO(['mathspeak-sbrief', 'Superbrief'], + 'Assistive-ruleset', speech) + ), + ITEM.RADIO(['clearspeak-default', 'Clearspeak Rules'], + 'Assistive-ruleset', speech), + ITEM.SUBMENU(['Chromevox', 'ChromeVox Rules'], + ITEM.RADIO(['chromevox-default', 'Verbose'], + 'Assistive-ruleset', speech), + ITEM.RADIO(['chromevox-alternative', 'Alternative'], + 'Assistive-ruleset', speech) + ) + ); + var submenu = (MENU.FindId('Accessibility') || {}).submenu, index; + if (submenu) { + index = submenu.IndexOfId('Explorer'); + if (index !== null) { + submenu.items[index] = explorerMenu; + } else { + index = submenu.IndexOfId('CollapsibleMath'); + submenu.items.splice(index + 1, 0, explorerMenu); + } + } else { + index = MENU.IndexOfId('CollapsibleMath'); + MENU.items.splice(index + 1, 0, explorerMenu); + } + if (!SETTINGS.explorer) Assistive.DisableMenus(true); + },20); // Between collapsible and auto-collapse extensions + },20); + +}); + +// +// Patch problem with SVG getJaxForMath when used from explorer +// (can be removed after the next release of MathJax). +// +MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { + MathJax.Hub.Config({SVG: {addMMLclasses: true}}); + var SVG = MathJax.OutputJax.SVG; + if (parseFloat(SVG.version) < 2.7) { + var JAXFROMMATH = SVG.getJaxFromMath; + SVG.Augment({ + getJaxFromMath: function (math) { + if (math.parentNode.className.match(/MathJax_SVG_Display/)) math = math.parentNode; + return JAXFROMMATH.call(this,math); + } + }); + } +}); + +// +// Set up the a11y path,if it isn't already in place +// +if (!MathJax.Ajax.config.path.a11y) { + MathJax.Ajax.config.path.a11y = MathJax.Hub.config.root + "/extensions/a11y"; +} + +MathJax.Ajax.Require('[a11y]/collapsible.js'); +MathJax.Hub.Register.StartupHook('Collapsible Ready', function() { + MathJax.Extension.explorer.Explorer.Startup(); + MathJax.Ajax.loadComplete('[a11y]/explorer.js'); +}); +// @license-end diff --git a/js/mathjax/extensions/a11y/invalid_keypress.mp3 b/js/mathjax/extensions/a11y/invalid_keypress.mp3 new file mode 100644 index 0000000..cba44de Binary files /dev/null and b/js/mathjax/extensions/a11y/invalid_keypress.mp3 differ diff --git a/js/mathjax/extensions/a11y/invalid_keypress.ogg b/js/mathjax/extensions/a11y/invalid_keypress.ogg new file mode 100644 index 0000000..292cefd Binary files /dev/null and b/js/mathjax/extensions/a11y/invalid_keypress.ogg differ diff --git a/js/mathjax/extensions/a11y/mathjax-sre.js b/js/mathjax/extensions/a11y/mathjax-sre.js new file mode 100644 index 0000000..6984f72 --- /dev/null +++ b/js/mathjax/extensions/a11y/mathjax-sre.js @@ -0,0 +1,1633 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +// Copyright 2014-2019 Volker Sorge +// +// 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. +/* + + Copyright The Closure Library Authors. + SPDX-License-Identifier: Apache-2.0 +*/ +var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return bb||1342177279>>=1)c+=c;return d}},"es6","es3");var COMPILED=!0,goog=goog||{};goog.global=this||self; +goog.exportPath_=function(a,b,c){a=a.split(".");c=c||goog.global;a[0]in c||"undefined"==typeof c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c=c[d]&&c[d]!==Object.prototype[d]?c[d]:c[d]={}:c[d]=b}; +goog.define=function(a,b){if(!COMPILED){var c=goog.global.CLOSURE_UNCOMPILED_DEFINES,d=goog.global.CLOSURE_DEFINES;c&&void 0===c.nodeType&&Object.prototype.hasOwnProperty.call(c,a)?b=c[a]:d&&void 0===d.nodeType&&Object.prototype.hasOwnProperty.call(d,a)&&(b=d[a])}return b};goog.FEATURESET_YEAR=2012;goog.DEBUG=!0;goog.LOCALE="en";goog.TRUSTED_SITE=!0;goog.STRICT_MODE_COMPATIBLE=!1;goog.DISALLOW_TEST_ONLY_CODE=COMPILED&&!goog.DEBUG;goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING=!1; +goog.provide=function(a){if(goog.isInModuleLoader_())throw Error("goog.provide cannot be used within a module.");if(!COMPILED&&goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');goog.constructNamespace_(a)};goog.constructNamespace_=function(a,b){if(!COMPILED){delete goog.implicitNamespaces_[a];for(var c=a;(c=c.substring(0,c.lastIndexOf(".")))&&!goog.getObjectByName(c);)goog.implicitNamespaces_[c]=!0}goog.exportPath_(a,b)}; +goog.getScriptNonce=function(a){if(a&&a!=goog.global)return goog.getScriptNonce_(a.document);null===goog.cspNonce_&&(goog.cspNonce_=goog.getScriptNonce_(goog.global.document));return goog.cspNonce_};goog.NONCE_PATTERN_=/^[\w+/_-]+[=]{0,2}$/;goog.cspNonce_=null;goog.getScriptNonce_=function(a){return(a=a.querySelector&&a.querySelector("script[nonce]"))&&(a=a.nonce||a.getAttribute("nonce"))&&goog.NONCE_PATTERN_.test(a)?a:""};goog.VALID_MODULE_RE_=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/; +goog.module=function(a){if("string"!==typeof a||!a||-1==a.search(goog.VALID_MODULE_RE_))throw Error("Invalid module identifier");if(!goog.isInGoogModuleLoader_())throw Error("Module "+a+" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide."); +if(goog.moduleLoaderState_.moduleName)throw Error("goog.module may only be called once per module.");goog.moduleLoaderState_.moduleName=a;if(!COMPILED){if(goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');delete goog.implicitNamespaces_[a]}};goog.module.get=function(a){return goog.module.getInternal_(a)}; +goog.module.getInternal_=function(a){if(!COMPILED){if(a in goog.loadedModules_)return goog.loadedModules_[a].exports;if(!goog.implicitNamespaces_[a])return a=goog.getObjectByName(a),null!=a?a:null}return null};goog.ModuleType={ES6:"es6",GOOG:"goog"};goog.moduleLoaderState_=null;goog.isInModuleLoader_=function(){return goog.isInGoogModuleLoader_()||goog.isInEs6ModuleLoader_()};goog.isInGoogModuleLoader_=function(){return!!goog.moduleLoaderState_&&goog.moduleLoaderState_.type==goog.ModuleType.GOOG}; +goog.isInEs6ModuleLoader_=function(){if(goog.moduleLoaderState_&&goog.moduleLoaderState_.type==goog.ModuleType.ES6)return!0;var a=goog.global.$jscomp;return a?"function"!=typeof a.getCurrentModulePath?!1:!!a.getCurrentModulePath():!1}; +goog.module.declareLegacyNamespace=function(){if(!COMPILED&&!goog.isInGoogModuleLoader_())throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module");if(!COMPILED&&!goog.moduleLoaderState_.moduleName)throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace.");goog.moduleLoaderState_.declareLegacyNamespace=!0}; +goog.declareModuleId=function(a){if(!COMPILED){if(!goog.isInEs6ModuleLoader_())throw Error("goog.declareModuleId may only be called from within an ES6 module");if(goog.moduleLoaderState_&&goog.moduleLoaderState_.moduleName)throw Error("goog.declareModuleId may only be called once per module.");if(a in goog.loadedModules_)throw Error('Module with namespace "'+a+'" already exists.');}if(goog.moduleLoaderState_)goog.moduleLoaderState_.moduleName=a;else{var b=goog.global.$jscomp;if(!b||"function"!=typeof b.getCurrentModulePath)throw Error('Module with namespace "'+ +a+'" has been loaded incorrectly.');b=b.require(b.getCurrentModulePath());goog.loadedModules_[a]={exports:b,type:goog.ModuleType.ES6,moduleId:a}}};goog.setTestOnly=function(a){if(goog.DISALLOW_TEST_ONLY_CODE)throw a=a||"",Error("Importing test-only code into non-debug environment"+(a?": "+a:"."));};goog.forwardDeclare=function(a){};COMPILED||(goog.isProvided_=function(a){return a in goog.loadedModules_||!goog.implicitNamespaces_[a]&&null!=goog.getObjectByName(a)},goog.implicitNamespaces_={"goog.module":!0}); +goog.getObjectByName=function(a,b){a=a.split(".");b=b||goog.global;for(var c=0;c>>0);goog.uidCounter_=0;goog.getHashCode=goog.getUid;goog.removeHashCode=goog.removeUid; +goog.cloneObject=function(a){var b=goog.typeOf(a);if("object"==b||"array"==b){if("function"===typeof a.clone)return a.clone();b="array"==b?[]:{};for(var c in a)b[c]=goog.cloneObject(a[c]);return b}return a};goog.bindNative_=function(a,b,c){return a.call.apply(a.bind,arguments)}; +goog.bindJs_=function(a,b,c){if(!a)throw Error();if(2{"use strict";class X{constructor(){if(new.target!=String)throw 1;this.x=42}}let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a==2)continue;function f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()==3}})()')}); +a("es7",function(){return b("2 ** 2 == 4")});a("es8",function(){return b("async () => 1, true")});a("es9",function(){return b("({...rest} = {}), true")});a("es_next",function(){return!1});return{target:c,map:d}},goog.Transpiler.prototype.needsTranspile=function(a,b){if("always"==goog.TRANSPILE)return!0;if("never"==goog.TRANSPILE)return!1;if(!this.requiresTranspilation_){var c=this.createRequiresTranspilation_();this.requiresTranspilation_=c.map;this.transpilationTarget_=this.transpilationTarget_|| +c.target}if(a in this.requiresTranspilation_)return this.requiresTranspilation_[a]?!0:!goog.inHtmlDocument_()||"es6"!=b||"noModule"in goog.global.document.createElement("script")?!1:!0;throw Error("Unknown language mode: "+a);},goog.Transpiler.prototype.transpile=function(a,b){return goog.transpile_(a,b,this.transpilationTarget_)},goog.transpiler_=new goog.Transpiler,goog.protectScriptTag_=function(a){return a.replace(/<\/(SCRIPT)/ig,"\\x3c/$1")},goog.DebugLoader_=function(){this.dependencies_={}; +this.idToPath_={};this.written_={};this.loadingDeps_=[];this.depsToLoad_=[];this.paused_=!1;this.factory_=new goog.DependencyFactory(goog.transpiler_);this.deferredCallbacks_={};this.deferredQueue_=[]},goog.DebugLoader_.prototype.bootstrap=function(a,b){function c(){d&&(goog.global.setTimeout(d,0),d=null)}var d=b;if(a.length){b=[];for(var e=0;e\x3c/script>";b.write(goog.TRUSTED_TYPES_POLICY_?goog.TRUSTED_TYPES_POLICY_.createHTML(d):d)}else{var e=b.createElement("script");e.defer=goog.Dependency.defer_;e.async=!1;e.type="text/javascript";(d=goog.getScriptNonce())&&e.setAttribute("nonce",d);goog.DebugLoader_.IS_OLD_IE_? +(a.pause(),e.onreadystatechange=function(){if("loaded"==e.readyState||"complete"==e.readyState)a.loaded(),a.resume()}):e.onload=function(){e.onload=null;a.loaded()};e.src=goog.TRUSTED_TYPES_POLICY_?goog.TRUSTED_TYPES_POLICY_.createScriptURL(this.path):this.path;b.head.appendChild(e)}}else goog.logToConsole_("Cannot use default debug loader outside of HTML documents."),"deps.js"==this.relativePath?(goog.logToConsole_("Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, or setting CLOSURE_NO_DEPS to true."), +a.loaded()):a.pause()},goog.Es6ModuleDependency=function(a,b,c,d,e){goog.Dependency.call(this,a,b,c,d,e)},goog.inherits(goog.Es6ModuleDependency,goog.Dependency),goog.Es6ModuleDependency.prototype.load=function(a){function b(l,m){l=m?'");return a};sre.ColorPicker=function(a,b){this.foreground=sre.ColorPicker.getChannelColor_(b,sre.ColorPicker.DEFAULT_FOREGROUND_);this.background=sre.ColorPicker.getChannelColor_(a,sre.ColorPicker.DEFAULT_BACKGROUND_)};sre.ColorPicker.DEFAULT_BACKGROUND_="blue";sre.ColorPicker.DEFAULT_FOREGROUND_="black"; +sre.ColorPicker.namedColors_={red:{red:255,green:0,blue:0},green:{red:0,green:255,blue:0},blue:{red:0,green:0,blue:255},yellow:{red:255,green:255,blue:0},cyan:{red:0,green:255,blue:255},magenta:{red:255,green:0,blue:255},white:{red:255,green:255,blue:255},black:{red:0,green:0,blue:0}};sre.ColorPicker.getChannelColor_=function(a,b){a=a||{color:b};var c=a.color?sre.ColorPicker.namedColors_[a.color]:a;c||(c=sre.ColorPicker.namedColors_[b]);c.alpha=a.hasOwnProperty("alpha")?a.alpha:1;return sre.ColorPicker.normalizeColor_(c)}; +sre.ColorPicker.normalizeColor_=function(a){var b=function(c){c=Math.max(c,0);c=Math.min(255,c);return Math.round(c)};a.red=b(a.red);a.green=b(a.green);a.blue=b(a.blue);a.alpha=Math.max(a.alpha,0);a.alpha=Math.min(1,a.alpha);return a};sre.ColorPicker.prototype.rgba=function(){var a=function(b){return"rgba("+b.red+","+b.green+","+b.blue+","+b.alpha+")"};return{background:a(this.background),foreground:a(this.foreground)}}; +sre.ColorPicker.prototype.rgb=function(){var a=function(b){return"rgb("+b.red+","+b.green+","+b.blue+")"};return{background:a(this.background),alphaback:this.background.alpha.toString(),foreground:a(this.foreground),alphafore:this.foreground.alpha.toString()}}; +sre.ColorPicker.prototype.hex=function(){var a=function(b){return"#"+sre.ColorPicker.toHex_(b.red)+sre.ColorPicker.toHex_(b.green)+sre.ColorPicker.toHex_(b.blue)};return{background:a(this.background),alphaback:this.background.alpha.toString(),foreground:a(this.foreground),alphafore:this.foreground.alpha.toString()}};sre.ColorPicker.toHex_=function(a){a=a.toString(16);return 1===a.length?"0"+a:a};sre.ContrastPicker=function(){this.hue=10;this.sat=100;this.incr=this.light=50}; +sre.ContrastPicker.prototype.generate=function(){return sre.ColorPicker.RGB2hex_(sre.ColorPicker.rgb2RGB_(sre.ColorPicker.hsl2rgb_(this.hue,this.sat,this.light)))};sre.ContrastPicker.prototype.increment=function(){this.hue=(this.hue+this.incr)%360}; +sre.ColorPicker.hsl2rgb_=function(a,b,c){c=1a?(a=$jscomp.makeIterator([d,e,0]),b=a.next().value,f=a.next().value,g=a.next().value):60<=a&&120>a?(a=$jscomp.makeIterator([e,d,0]),b=a.next().value,f=a.next().value,g=a.next().value):120<=a&&180>a?(a=$jscomp.makeIterator([0,d,e]),b=a.next().value,f=a.next().value,g=a.next().value):180<=a&&240>a?(a=$jscomp.makeIterator([0,e,d]),b=a.next().value,f= +a.next().value,g=a.next().value):240<=a&&300>a?(a=$jscomp.makeIterator([e,0,d]),b=a.next().value,f=a.next().value,g=a.next().value):300<=a&&360>a&&(a=$jscomp.makeIterator([d,0,e]),b=a.next().value,f=a.next().value,g=a.next().value);return{red:b+c,green:f+c,blue:g+c}};sre.ColorPicker.rgb2RGB_=function(a){return{red:Math.round(255*a.red),green:Math.round(255*a.green),blue:Math.round(255*a.blue)}};sre.ColorPicker.RGB2hex_=function(a){return"rgb("+a.red+","+a.green+","+a.blue+")"};sre.Highlighter=function(){};sre.Highlighter.prototype.highlight=function(a){};sre.Highlighter.prototype.unhighlight=function(){};sre.Highlighter.prototype.highlightAll=function(a){};sre.Highlighter.prototype.unhighlightAll=function(){};sre.Highlighter.prototype.setColor=function(a){};sre.Highlighter.prototype.addEvents=function(a,b){};sre.AbstractHighlighter=function(){this.currentHighlights_=[];this.color=null;this.mactionName=""};sre.AbstractHighlighter.ATTR="sre-highlight";sre.AbstractHighlighter.prototype.highlight=function(a){this.currentHighlights_.push(a.map(goog.bind(function(b){var c=this.highlightNode(b);this.setHighlighted(b);return c},this)))};sre.AbstractHighlighter.prototype.highlightNode=goog.abstractMethod;sre.AbstractHighlighter.prototype.highlightAll=function(a){a=this.getMactionNodes(a);for(var b=0,c;c=a[b];b++)this.highlight([c])}; +sre.AbstractHighlighter.prototype.unhighlight=function(){var a=this.currentHighlights_.pop();a&&a.forEach(goog.bind(function(b){this.isHighlighted(b.node)&&(this.unhighlightNode(b),this.unsetHighlighted(b.node))},this))};sre.AbstractHighlighter.prototype.unhighlightNode=goog.abstractMethod;sre.AbstractHighlighter.prototype.unhighlightAll=function(){for(;0=a.length)return a;for(var c=[],d=0,e;e=b[d],a.length;d++)e.close&&e.close.length&&e.close.forEach(function(f){var g=a.indexOf(f);-1!==g&&(c.unshift(f),a.splice(g,1))});return c};sre.AudioUtil.PersonalityRanges_={};sre.AudioUtil.LastOpen_=[]; +sre.AudioUtil.personalityMarkup=function(a){sre.AudioUtil.PersonalityRanges_={};sre.AudioUtil.LastOpen_=[];for(var b=[],c={},d=0,e;e=a[d];d++){var f=null,g=e.descriptionSpan(),h=e.personality;e=h[sre.Engine.personalityProps.JOIN];delete h[sre.Engine.personalityProps.JOIN];"undefined"!==typeof h[sre.Engine.personalityProps.PAUSE]&&(f={},f[sre.Engine.personalityProps.PAUSE]=h[sre.Engine.personalityProps.PAUSE],delete h[sre.Engine.personalityProps.PAUSE]);h=sre.AudioUtil.personalityDiff_(h,c);sre.AudioUtil.appendMarkup_(b, +g,h,e,f,!0)}b=b.concat(sre.AudioUtil.finaliseMarkup_());return b=sre.AudioUtil.simplifyMarkup_(b)}; +sre.AudioUtil.appendElement_=function(a,b){var c=a[a.length-1];if(c)if(sre.AudioUtil.isSpanElement(b)&&sre.AudioUtil.isSpanElement(c))if("undefined"===typeof c.join)c.span=c.span.concat(b.span);else{a=c.span.pop();var d=b.span.shift();c.span.push(a+c.join+d);c.span=c.span.concat(b.span);c.join=b.join}else sre.AudioUtil.isPauseElement(b)&&sre.AudioUtil.isPauseElement(c)?c.pause=sre.AudioUtil.mergePause_(c.pause,b.pause):a.push(b);else a.push(b)}; +sre.AudioUtil.simplifyMarkup_=function(a){for(var b={},c=[],d=0,e;e=a[d];d++)if(sre.AudioUtil.isMarkupElement(e))if(!e.close||1!==e.close.length||e.open.length)sre.AudioUtil.copyValues_(e,b),c.push(e);else{var f=a[d+1];if(!f||sre.AudioUtil.isSpanElement(f))sre.AudioUtil.copyValues_(e,b),c.push(e);else{var g=sre.AudioUtil.isPauseElement(f)?f:null;g&&(f=a[d+2]);f&&sre.AudioUtil.isMarkupElement(f)&&f.open[0]===e.close[0]&&!f.close.length&&f[f.open[0]]===b[f.open[0]]?g?(sre.AudioUtil.appendElement_(c, +g),d+=2):d+=1:(sre.AudioUtil.copyValues_(e,b),c.push(e))}}else sre.AudioUtil.appendElement_(c,e);return c};sre.AudioUtil.copyValues_=function(a,b){a.rate&&(b.rate=a.rate);a.pitch&&(b.pitch=a.pitch);a.volume&&(b.volume=a.volume)};sre.AudioUtil.finaliseMarkup_=function(){for(var a=[],b=sre.AudioUtil.LastOpen_.length-1;0<=b;b--){var c=sre.AudioUtil.LastOpen_[b];if(c.length){for(var d={open:[],close:[]},e=0;e=a?"short":500>=a?"medium":"long":a]||""};sre.XmlRenderer=function(){sre.MarkupRenderer.call(this)};goog.inherits(sre.XmlRenderer,sre.MarkupRenderer); +sre.XmlRenderer.prototype.markup=function(a){this.setScaleFunction(-2,2,-100,100,2);a=sre.AudioUtil.personalityMarkup(a);for(var b=[],c=[],d=0,e;e=a[d];d++)if(e.span)b.push(this.merge(e.span));else if(sre.AudioUtil.isPauseElement(e))b.push(this.pause(e));else{if(e.close.length)for(var f=0;f'+this.getSeparator()+a+this.getSeparator()+""};sre.SableRenderer.prototype.pause=function(a){return''}; +sre.SableRenderer.prototype.prosodyElement=function(a,b){b=this.applyScaleFunction(b);switch(a){case sre.Engine.personalityProps.PITCH:return'';case sre.Engine.personalityProps.RATE:return'';case sre.Engine.personalityProps.VOLUME:return'';default:return"<"+a.toUpperCase()+' VALUE="'+b+'">'}};sre.SableRenderer.prototype.closeTag=function(a){return""};sre.SsmlRenderer=function(){sre.XmlRenderer.call(this)};goog.inherits(sre.SsmlRenderer,sre.XmlRenderer);sre.SsmlRenderer.prototype.finalize=function(a){return''+this.getSeparator()+a+this.getSeparator()+""};sre.SsmlRenderer.prototype.pause=function(a){return''}; +sre.SsmlRenderer.prototype.prosodyElement=function(a,b){b=Math.floor(this.applyScaleFunction(b));b=0>b?b.toString():"+"+b.toString();return"":'%">')};sre.SsmlRenderer.prototype.closeTag=function(a){return""};sre.SsmlStepRenderer=function(){sre.SsmlRenderer.call(this)};goog.inherits(sre.SsmlStepRenderer,sre.SsmlRenderer);sre.SsmlStepRenderer.prototype.markup=function(a){sre.SsmlStepRenderer.MARKS={};return sre.SsmlStepRenderer.superClass_.markup.call(this,a)};sre.SsmlStepRenderer.CHARACTER_ATTR_="character";sre.SsmlStepRenderer.MARKS={}; +sre.SsmlStepRenderer.prototype.merge=function(a){for(var b=[],c=0;c'),sre.SsmlStepRenderer.MARKS[e]=!0);1===d.string.length&&d.string.match(/[a-zA-Z]/)?b.push(''+d.string+""):b.push(d.string)}return b.join(this.getSeparator())};sre.StringRenderer=function(){sre.AbstractAudioRenderer.call(this)};goog.inherits(sre.StringRenderer,sre.AbstractAudioRenderer);sre.StringRenderer.prototype.markup=function(a){var b="";a=a.filter(function(g){return g.descriptionString()});if(!a.length)return b;for(var c=0;c "+this.action.toString()};sre.SpeechRule.Type={NODE:"NODE",MULTI:"MULTI",TEXT:"TEXT",PERSONALITY:"PERSONALITY"}; +sre.SpeechRule.Type.fromString=function(a){switch(a){case "[n]":return sre.SpeechRule.Type.NODE;case "[m]":return sre.SpeechRule.Type.MULTI;case "[t]":return sre.SpeechRule.Type.TEXT;case "[p]":return sre.SpeechRule.Type.PERSONALITY;default:throw"Parse error: "+a;}}; +sre.SpeechRule.Type.toString=function(a){switch(a){case sre.SpeechRule.Type.NODE:return"[n]";case sre.SpeechRule.Type.MULTI:return"[m]";case sre.SpeechRule.Type.TEXT:return"[t]";case sre.SpeechRule.Type.PERSONALITY:return"[p]";default:throw"Unknown type error: "+a;}};sre.SpeechRule.Component=function(a){this.type=a.type;this.content=a.content;this.attributes=a.attributes;this.grammar=a.grammar}; +sre.SpeechRule.Component.fromString=function(a){var b={};b.type=sre.SpeechRule.Type.fromString(a.substring(0,3));a=a.slice(3).trim();if(!a)throw new sre.SpeechRule.OutputError("Missing content.");switch(b.type){case sre.SpeechRule.Type.TEXT:if('"'==a[0]){var c=sre.SpeechRule.splitString_(a,"\\(")[0].trim();if('"'!=c.slice(-1))throw new sre.SpeechRule.OutputError("Invalid string syntax.");b.content=c;a=a.slice(c.length).trim();-1==a.indexOf("(")&&(a="");break}case sre.SpeechRule.Type.NODE:case sre.SpeechRule.Type.MULTI:c= +a.indexOf(" ("),-1==c?(b.content=a.trim(),a=""):(b.content=a.substring(0,c).trim(),a=a.slice(c).trim())}a&&(a=sre.SpeechRule.Component.attributesFromString(a),a.grammar&&(b.grammar=a.grammar,delete a.grammar),Object.keys(a).length&&(b.attributes=a));return b=new sre.SpeechRule.Component(b)};sre.SpeechRule.Component.prototype.toString=function(){var a=""+sre.SpeechRule.Type.toString(this.type);a+=this.content?" "+this.content:"";var b=this.attributesToString();return a+(b?" "+b:"")}; +sre.SpeechRule.Component.grammarFromString=function(a){return sre.Grammar.parseInput(a)};sre.SpeechRule.Component.prototype.grammarToString=function(){return this.getGrammar().join(":")};sre.SpeechRule.Component.prototype.getGrammar=function(){var a=[],b;for(b in this.grammar)!0===this.grammar[b]?a.push(b):!1===this.grammar[b]?a.push("!"+b):a.push(b+"="+this.grammar[b]);return a}; +sre.SpeechRule.Component.attributesFromString=function(a){if("("!=a[0]||")"!=a.slice(-1))throw new sre.SpeechRule.OutputError("Invalid attribute expression: "+a);var b={};a=sre.SpeechRule.splitString_(a.slice(1,-1),",");for(var c=0,d=a.length;c "+this.getRule().action:this.constraint};sre.TrieNodeFactory={};sre.TrieNodeFactory.getNode=function(a,b,c){switch(a){case sre.TrieNode.Kind.ROOT:return new sre.RootTrieNode;case sre.TrieNode.Kind.DYNAMIC:return new sre.DynamicTrieNode(b);case sre.TrieNode.Kind.QUERY:return new sre.QueryTrieNode(b,c);case sre.TrieNode.Kind.BOOLEAN:return new sre.BooleanTrieNode(b,c);default:return null}};sre.RootTrieNode=function(){sre.AbstractTrieNode.call(this,"",function(){return!0});this.kind=sre.TrieNode.Kind.ROOT};goog.inherits(sre.RootTrieNode,sre.AbstractTrieNode); +sre.DynamicTrieNode=function(a){sre.AbstractTrieNode.call(this,a,function(b){return b===a});this.kind=sre.TrieNode.Kind.DYNAMIC};goog.inherits(sre.DynamicTrieNode,sre.AbstractTrieNode); +sre.TrieNodeFactory.constraintTest_=function(a){if(a.match(/^self::\*$/))return function(f){return!0};if(a.match(/^self::\w+$/)){var b=a.slice(6).toUpperCase();return function(f){return f.tagName&&sre.DomUtil.tagName(f)===b}}if(a.match(/^self::\w+:\w+$/)){a=a.split(":");var c=sre.XpathUtil.resolveNameSpace(a[2]);if(!c)return null;b=a[3].toUpperCase();return function(f){return f.localName&&f.localName.toUpperCase()===b&&f.namespaceURI===c}}if(a.match(/^@\w+$/)){var d=a.slice(1);return function(f){return f.hasAttribute&& +f.hasAttribute(d)}}if(a.match(/^@\w+="[\w\d ]+"$/)){a=a.split("=");d=a[0].slice(1);var e=a[1].slice(1,-1);return function(f){return f.hasAttribute&&f.hasAttribute(d)&&f.getAttribute(d)===e}}return a.match(/^@\w+!="[\w\d ]+"$/)?(a=a.split("!="),d=a[0].slice(1),e=a[1].slice(1,-1),function(f){return!f.hasAttribute||!f.hasAttribute(d)||f.getAttribute(d)!==e}):a.match(/^contains\(\s*@grammar\s*,\s*"[\w\d ]+"\s*\)$/)?(a=a.split('"'),e=a[1],function(f){return sre.Grammar.getInstance().getParameter(e)}): +a.match(/^not\(\s*contains\(\s*@grammar\s*,\s*"[\w\d ]+"\s*\)\s*\)$/)?(a=a.split('"'),e=a[1],function(f){return!sre.Grammar.getInstance().getParameter(e)}):null};sre.QueryTrieNode=function(a,b){this.context_=b;sre.StaticTrieNode.call(this,a,sre.TrieNodeFactory.constraintTest_(a));this.kind=sre.TrieNode.Kind.QUERY};goog.inherits(sre.QueryTrieNode,sre.StaticTrieNode);sre.QueryTrieNode.prototype.applyTest=function(a){return this.test?this.test(a):this.context_.applyQuery(a,this.constraint)===a}; +sre.BooleanTrieNode=function(a,b){this.context_=b;sre.StaticTrieNode.call(this,a,sre.TrieNodeFactory.constraintTest_(a));this.kind=sre.TrieNode.Kind.BOOLEAN};goog.inherits(sre.BooleanTrieNode,sre.StaticTrieNode);sre.BooleanTrieNode.prototype.applyTest=function(a){return this.test?this.test(a):this.context_.applyConstraint(a,this.constraint)};sre.Trie=function(a){this.store=a;this.root=sre.TrieNodeFactory.getNode(sre.TrieNode.Kind.ROOT,"",this.store.context)};sre.Trie.prototype.addRule=function(a){for(var b=this.root,c=a.context,d=a.dynamicCstr.getValues(),e=0,f=d.length;e=c&&1=d&&1b?-1:aa)return String.fromCharCode(a);a-=65536;return String.fromCharCode((a>>10)+55296,(a&1023)+56320)};sre.MathMap=function(){this.store=sre.MathCompoundStore.getInstance();this.loaded_=[];this.addRules={functions:goog.bind(this.store.addFunctionRules,this.store),symbols:goog.bind(this.store.addSymbolRules,this.store),units:goog.bind(this.store.addUnitRules,this.store)}};goog.addSingletonGetter(sre.MathMap);sre.MathMap.oldInst_=sre.MathMap.getInstance;sre.MathMap.getInstance=function(){var a=sre.MathMap.oldInst_();a.loadLocale();return a}; +sre.MathMap.prototype.loadLocale=function(){var a=sre.Engine.getInstance().locale;if(-1===this.loaded_.indexOf(a)){var b=sre.Engine.getInstance().mode===sre.Engine.Mode.ASYNC;b&&(sre.Engine.getInstance().mode=sre.Engine.Mode.SYNC);this.loaded_.push(a);this.retrieveMaps(a);b&&(sre.Engine.getInstance().mode=sre.Engine.Mode.ASYNC)}};sre.MathMap.toFetch_=0;sre.Engine.registerTest(function(){return sre.MathMap.getInstance()&&!sre.MathMap.toFetch_}); +sre.MathMap.prototype.retrieveFiles=function(a){a=sre.BaseUtil.makePath(sre.SystemExternal.jsonPath)+a+".js";switch(sre.Engine.getInstance().mode){case sre.Engine.Mode.ASYNC:sre.MathMap.toFetch_++;var b=goog.bind(this.parseMaps,this);sre.MathMap.fromFile_(a,function(c,d){sre.MathMap.toFetch_--;c||b(d)});break;case sre.Engine.Mode.HTTP:sre.MathMap.toFetch_++;this.getJsonAjax_(a);break;default:a=sre.MathMap.loadFile(a),this.parseMaps(a)}}; +sre.MathMap.prototype.parseMaps=function(a){a=JSON.parse(a);this.addMaps(a)};sre.MathMap.prototype.addMaps=function(a,b){for(var c=0,d;d=Object.keys(a)[c];c++){var e=d.split("/");b&&b!==e[0]||a[d].forEach(this.addRules[e[1]])}};sre.MathMap.prototype.retrieveMaps=function(a){sre.AlphabetGenerator.generate(a,this.store);sre.Engine.getInstance().isIE&&sre.Engine.getInstance().mode===sre.Engine.Mode.HTTP?this.getJsonIE_(a):this.retrieveFiles(a)}; +sre.MathMap.prototype.getJsonIE_=function(a,b){var c=b||1;sre.BrowserUtil.mapsForIE?this.addMaps(sre.BrowserUtil.mapsForIE,a):5>=c&&setTimeout(goog.bind(function(){this.getJsonIE_(a,c++)},this),300)};sre.MathMap.fromFile_=function(a,b){return sre.SystemExternal.fs.readFile(a,"utf8",b)};sre.MathMap.loadFile=function(a){try{return sre.MathMap.readJSON_(a)}catch(b){console.error("Unable to load file: "+a+"\n"+b)}return"{}"};sre.MathMap.readJSON_=function(a){return sre.SystemExternal.fs.readFileSync(a)}; +sre.MathMap.prototype.getJsonAjax_=function(a){var b=new XMLHttpRequest,c=goog.bind(this.parseMaps,this);b.onreadystatechange=function(){4===b.readyState&&(sre.MathMap.toFetch_--,200===b.status&&c(b.responseText))};b.open("GET",a,!0);b.send()};sre.StoreUtil={};sre.StoreUtil.nodeCounter=function(a,b){var c=a.length,d=0,e=b;b||(e="");return function(){db&&0a}; +sre.ClearspeakUtil.hasPreference=function(a){return sre.Engine.getInstance().style===a};sre.ClearspeakUtil.simpleExpression=function(){return new sre.SemanticAnnotator("clearspeak",function(a){return sre.ClearspeakUtil.isSimpleExpression(a)?"simple":""})};sre.ClearspeakUtil.simpleNode=function(a){if(!a.hasAttribute("annotation"))return!1;a=a.getAttribute("annotation");return!!/clearspeak:simple$|clearspeak:simple;/.exec(a)}; +sre.ClearspeakUtil.simpleCell_=function(a){if(sre.ClearspeakUtil.simpleNode(a))return!0;if(a.tagName!==sre.SemanticAttr.Type.SUBSCRIPT)return!1;a=a.childNodes[0].childNodes;var b=a[1];return a[0].tagName===sre.SemanticAttr.Type.IDENTIFIER&&(sre.ClearspeakUtil.isInteger_(b)||b.tagName===sre.SemanticAttr.Type.INFIXOP&&b.hasAttribute("role")&&b.getAttribute("role")===sre.SemanticAttr.Role.IMPLICIT&&sre.ClearspeakUtil.allIndices_(b))}; +sre.ClearspeakUtil.isInteger_=function(a){return a.tagName===sre.SemanticAttr.Type.NUMBER&&a.hasAttribute("role")&&a.getAttribute("role")===sre.SemanticAttr.Role.INTEGER};sre.ClearspeakUtil.allIndices_=function(a){return sre.XpathUtil.evalXPath("children/*",a).every(function(b){return sre.ClearspeakUtil.isInteger_(b)||b.tagName===sre.SemanticAttr.Type.IDENTIFIER})}; +sre.ClearspeakUtil.allCellsSimple=function(a){return sre.XpathUtil.evalXPath(a.tagName===sre.SemanticAttr.Type.MATRIX?"children/row/children/cell/children/*":"children/line/children/*",a).every(sre.ClearspeakUtil.simpleCell_)?[a]:[]};sre.ClearspeakUtil.isSmallVulgarFraction=function(a){return sre.NumbersUtil.vulgarFractionSmall(a,20,11)?[a]:[]}; +sre.ClearspeakUtil.isUnitExpression=function(a){return a.type===sre.SemanticAttr.Type.TEXT||a.type===sre.SemanticAttr.Type.PUNCTUATED&&a.role===sre.SemanticAttr.Role.TEXT&&sre.ClearspeakUtil.isNumber_(a.childNodes[0])&&sre.ClearspeakUtil.allTextLastContent_(a.childNodes.slice(1))||a.type===sre.SemanticAttr.Type.IDENTIFIER&&a.role===sre.SemanticAttr.Role.UNIT||a.type===sre.SemanticAttr.Type.INFIXOP&&(a.role===sre.SemanticAttr.Role.IMPLICIT||a.role===sre.SemanticAttr.Role.UNIT)}; +sre.ClearspeakUtil.allTextLastContent_=function(a){for(var b=0;b2],self::infixop,@role="unit",name(children/*[1])="number",children/*[1][text()=1]'.split(","),'Rule,unit-divide,default,[n] children/*[1]; [t] "per"; [n] children/*[2] (grammar:singularUnit),self::fraction,@role="unit"'.split(","),'Rule{currency{default{[m] children/*[position()>1]; [n] children/*[1];{self::infixop{contains(@annotation, "clearspeak:unit"){children/*[1][@role="unit"]{CQFfirstCurrency'.split("{"), +'Rule;currency;Currency_Position;[m] children/*;self::infixop;contains(@annotation, "clearspeak:unit")'.split(";"),["SpecializedRule","currency","Currency_Position","Currency_Prefix"],'Rule{currency{Currency_Prefix{[n] children/*[last()]; [m] children/*[position()2{./children/punctuation[@role="ellipsis"]'.split("{"), +'Rule{multi-equality{default{[t] "equation sequence"; [m] children/* (context:"part",ctxtFunc:CTXFnodeCounter,sepFunc:CTXFcontentIterator){self::relseq[@role="equality"]{count(./children/*)>2'.split("{"),'Rule,equality,default,[t] "equation"; [t] "left hand side"; [n] children/*[1];[p] (pause:200); [n] content/*[1] (pause:200);[t] "right hand side"; [n] children/*[2],self::relseq[@role="equality"],count(./children/*)=2'.split(","),'Rule,simple-equality,default,[n] children/*[1]; [p] (pause:200); [n] content/*[1] (pause:200);[n] children/*[2],self::relseq[@role="equality"],count(./children/*)=2,./children/identifier or ./children/number'.split(","), +'Rule,simple-equality2,default,[n] children/*[1]; [p] (pause:200); [n] content/*[1] (pause:200);[n] children/*[2],self::relseq[@role="equality"],count(./children/*)=2,./children/function or ./children/appl'.split(","),["Rule","relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],'Rule;implicit;default;[m] children/*;self::infixop;@role="implicit";children/*[1][@role="latinletter"] or children/*[1][@role="greekletter"] or children/*[1][@role="otherletter"] or name(children/*[1])="number";children/*[2][@role="latinletter"] or children/*[2][@role="greekletter"] or children/*[2][@role="otherletter"] or name(children/*[2])="number"'.split(";"), +["Rule","binary-operation","default","[p] (pause:100); [m] children/* (sepFunc:CTXFcontentIterator); [p] (pause:100);","self::infixop"],'Rule,variable-addition,default,[t] "sum with variable number of summands";[p] (pause:400); [m] children/* (sepFunc:CTXFcontentIterator),self::infixop[@role="addition"],count(children/*)>2,children/punctuation[@role="ellipsis"]'.split(","),["Rule","prefix","default",'[t] "prefix"; [n] text(); [t] "of" (pause 150);[n] children/*[1]',"self::prefixop"],'Rule,negative,default,[t] "negative"; [n] children/*[1],self::prefixop,self::prefixop[@role="negative"]'.split(","), +["Rule","postfix","default",'[n] children/*[1]; [t] "postfix"; [n] text() (pause 300)',"self::postfixop"],["Rule","identifier","default","[n] text()","self::identifier"],["Rule","number","default","[n] text()","self::number"],'Rule{font{default{[t] @font; [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"),'Rule{font-identifier-short{default{[t] @font; [n] CQFhideFont; [t] CSFshowFont{self::identifier{string-length(text())=1{@font{@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[t] @font; [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1;@font;not(contains(@grammar, "ignoreFont"));@font="italic"'.split(";"),'Rule,simple-fraction,default,[p] (pause:100); [n] children/*[1] (rate:0.35); [t] "over"; [n] children/*[2] (rate:0.35); [p] (pause:100),self::fraction,name(children/*[1])="number" or name(children/*[1])="identifier",name(children/*[2])="number" or name(children/*[2])="identifier"'.split(","), +'Rule;vulgar-fraction;default;[t] CSFvulgarFraction;self::fraction;@role="vulgar";CQFvulgarFractionSmall'.split(";"),["Rule","fraction","default",'[p] (pause:250); [n] children/*[1] (rate:0.35); [p] (pause:250); [t] "divided by"; [p] (pause:250); [n] children/*[2] (rate:0.35); [p] (pause:250)',"self::fraction"],["Rule","superscript","default",'[n] children/*[1]; [t] "super"; [n] children/*[2] (pitch:0.35);[p] (pause:300)',"self::superscript"],["Rule","subscript","default",'[n] children/*[1]; [t] "sub"; [n] children/*[2] (pitch:-0.35);[p] (pause:300)', +"self::subscript"],'Rule,ellipsis,default,[p] (pause:200); [t] "ellipsis"; [p] (pause:300),self::punctuation,self::punctuation[@role="ellipsis"]'.split(","),'Rule;fence-single;default;[n] text();self::punctuation;self::punctuation[@role="openfence"]'.split(";"),["Alias","fence-single","self::punctuation",'self::punctuation[@role="closefence"]'],["Alias","fence-single","self::punctuation",'self::punctuation[@role="vbar"]'],["Alias","fence-single","self::punctuation",'self::punctuation[@role="application"]'], +["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule,fences-open-close,default,[p] (pause:200); [n] children/*[1] (rate:0.35); [p] (pause:200),self::fenced,@role="leftright"'.split(","),'Rule,fences-open-close-in-appl,default,[p] (pause:200); [n] children/*[1]; [p] (pause:200);,self::fenced[@role="leftright"],./parent::children/parent::appl'.split(","),'Rule,fences-neutral,default,[p] (pause:100); [t] "absolute value of"; [n] children/*[1];[p] (pause:350);,self::fenced,self::fenced[@role="neutral"]'.split(","), +["Rule","omit-fences","default","[p] (pause:500); [n] children/*[1]; [p] (pause:200);","self::fenced"],["Rule","matrix","default",'[t] "matrix"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:100)',"self::matrix"],["Rule","matrix-row","default",'[m] children/* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)','self::row[@role="matrix"]'],["Rule","matrix-cell","default","[n] children/*[1]",'self::cell[@role="matrix"]'],["Rule","vector","default",'[t] "vector"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"element",pause:100)', +"self::vector"],["Rule","cases","default",'[t] "case statement"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"case",pause:100)',"self::cases"],["Rule","cases-row","default","[m] children/*",'self::row[@role="cases"]'],["Rule","cases-cell","default","[n] children/*[1]",'self::cell[@role="cases"]'],["Rule","row","default",'[m] ./* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)',"self::row"],'Rule{cases-end{default{[t] "case statement"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"case",pause:100);[t] "end cases"{self::cases{following-sibling::*'.split("{"), +["Rule","multiline","default",'[t] "multiline equation";[m] children/* (ctxtFunc:CTXFnodeCounter,context:"line",pause:100)',"self::multiline"],["Rule","line","default","[m] children/*","self::line"],["Rule","table","default",'[t] "multiline equation";[m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:200)',"self::table"],["Rule","table-row","default","[m] children/* (pause:100)",'self::row[@role="table"]'],["Alias","cases-cell",'self::cell[@role="table"]'],'Rule,end-punct,default,[m] children/*; [p] (pause:300),self::punctuated,@role="endpunct"'.split(","), +'Rule,start-punct,default,[n] content/*[1]; [p] (pause:200); [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule,integral-punct,default,[n] children/*[1] (rate:0.2); [n] children/*[3] (rate:0.2),self::punctuated,@role="integral"'.split(","),["Rule","punctuated","default","[m] children/* (pause:100)","self::punctuated"],["Rule","function","default","[n] text()","self::function"],["Rule","appl","default","[n] children/*[1]; [n] content/*[1]; [n] children/*[2]","self::appl"], +'Rule,sum-only,default,[n] children/*[1]; [t] "from"; [n] children/*[2]; [t] "to";[n] children/*[3],self::limboth,@role="sum" or @role="integral"'.split(","),["Rule","limboth","default",'[n] children/*[1]; [p] (pause 100); [t] "over"; [n] children/*[2];[t] "under"; [n] children/*[3]; [p] (pause 250);',"self::limboth"],["Rule","limlower","default",'[n] children/*[1]; [t] "over"; [n] children/*[2];',"self::limlower"],["Rule","limupper","default",'[n] children/*[1]; [t] "under"; [n] children/*[2];', +"self::limupper"],["Rule","largeop","default","[n] text()","self::largeop"],["Rule","bigop","default",'[n] children/*[1]; [p] (pause 100); [t] "over"; [n] children/*[2];[p] (pause 250);',"self::bigop"],["Rule","integral","default","[n] children/*[1]; [p] (pause 100); [n] children/*[2];[p] (pause 200); [n] children/*[3] (rate:0.35);","self::integral"],["Rule","sqrt","default",'[t] "Square root of"; [n] children/*[1] (rate:0.35); [p] (pause:400)',"self::sqrt"],'Rule,square,default,[n] children/*[1]; [t] "squared" (pitch:0.35); [p] (pause:200),self::superscript,children/*[2][text()=2],name(./children/*[1])!="text"'.split(","), +'Rule,cube,default,[n] children/*[1]; [t] "cubed" (pitch:0.35); [p] (pause:200),self::superscript,children/*[2][text()=3],name(./children/*[1])!="text"'.split(","),["Rule","root","default",'[t] "root of order"; [n] children/*[1];[t] "over"; [n] children/*[1] (rate:0.35); [p] (pause:400)',"self::root"],"Rule,text-no-mult,default,[n] children/*[1]; [p] (pause:200); [n] children/*[2],self::infixop,children/text".split(","),["Rule","text","default","[n] text(); [p] (pause:200)","self::text"],'Rule;unit;default;[t] text() (annotation:unit, preprocess);self::identifier;@role="unit"'.split(";"), +'Rule,unit-square,default,[t] "square"; [n] children/*[1],self::superscript,@role="unit",children/*[2][text()=2],name(children/*[1])="identifier"'.split(","),'Rule,unit-cubic,default,[t] "cubic"; [n] children/*[1],self::superscript,@role="unit",children/*[2][text()=3],name(children/*[1])="identifier"'.split(","),'Rule,reciprocal,default,[t] "reciprocal"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],count(preceding-sibling::*)=0 or preceding-sibling::*[@role!="unit"]'.split(","), +'Rule,reciprocal,default,[t] "per"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],preceding-sibling::*[@role="unit"]'.split(","),'Rule;unit-combine;default;[m] children/*;self::infixop;@role="unit"'.split(";"),'Rule,unit-divide,default,[n] children/*[1] (pitch:0.3); [t] "per"; [n] children/*[2] (pitch:-0.3),self::fraction,@role="unit"'.split(",")]};sre.MathspeakFrenchUtil={};sre.MathspeakFrenchUtil.smallRoot=function(a){if(!a.childNodes||0===a.childNodes.length||!a.childNodes[0].childNodes)return[];var b=a.childNodes[0].childNodes[0].textContent;if(!/^\d+$/.test(b))return[];b=parseInt(b,10);return 1=b?[a]:[]};sre.MathspeakFrenchUtil.baselineVerbose=function(a){return sre.MathspeakUtil.baselineVerbose(a).replace(/\-$/,"")};sre.MathspeakFrenchUtil.baselineBrief=function(a){return sre.MathspeakUtil.baselineBrief(a).replace(/\-$/,"")}; +sre.MathspeakFrenchUtil.leftSuperscriptVerbose=function(a){return sre.MathspeakUtil.superscriptVerbose(a).replace(/^exposant/,"exposant gauche")};sre.MathspeakFrenchUtil.leftSubscriptVerbose=function(a){return sre.MathspeakUtil.subscriptVerbose(a).replace(/^indice/,"indice gauche")};sre.MathspeakFrenchUtil.leftSuperscriptBrief=function(a){return sre.MathspeakUtil.superscriptBrief(a).replace(/^sup/,"sup gauche")}; +sre.MathspeakFrenchUtil.leftSubscriptBrief=function(a){return sre.MathspeakUtil.subscriptBrief(a).replace(/^sub/,"sub gauche")};sre.MathspeakFrench={locale:"fr",domain:"mathspeak",functions:[["CQF","CQFspaceoutNumber",sre.MathspeakUtil.spaceoutNumber],["CQF","CQFspaceoutIdentifier",sre.MathspeakUtil.spaceoutIdentifier],["CSF","CSFspaceoutText",sre.MathspeakUtil.spaceoutText],["CSF","CSFopenFracVerbose",sre.MathspeakUtil.openingFractionVerbose],["CSF","CSFcloseFracVerbose",sre.MathspeakUtil.closingFractionVerbose],["CSF","CSFoverFracVerbose",sre.MathspeakUtil.overFractionVerbose],["CSF","CSFopenFracBrief",sre.MathspeakUtil.openingFractionBrief], +["CSF","CSFcloseFracBrief",sre.MathspeakUtil.closingFractionBrief],["CSF","CSFopenFracSbrief",sre.MathspeakUtil.openingFractionSbrief],["CSF","CSFcloseFracSbrief",sre.MathspeakUtil.closingFractionSbrief],["CSF","CSFoverFracSbrief",sre.MathspeakUtil.overFractionSbrief],["CSF","CSFvulgarFrFraction",sre.NumbersUtil.vulgarFraction],["CQF","CQFvulgarFractionSmall",sre.MathspeakUtil.isSmallVulgarFraction],["CSF","CSFopenRadicalVerbose",sre.MathspeakUtil.openingRadicalVerbose],["CSF","CSFcloseRadicalVerbose", +sre.MathspeakUtil.closingRadicalVerbose],["CSF","CSFindexRadicalVerbose",sre.MathspeakUtil.indexRadicalVerbose],["CSF","CSFopenRadicalBrief",sre.MathspeakUtil.openingRadicalBrief],["CSF","CSFcloseRadicalBrief",sre.MathspeakUtil.closingRadicalBrief],["CSF","CSFindexRadicalBrief",sre.MathspeakUtil.indexRadicalBrief],["CSF","CSFopenRadicalSbrief",sre.MathspeakUtil.openingRadicalSbrief],["CSF","CSFindexRadicalSbrief",sre.MathspeakUtil.indexRadicalSbrief],["CQF","CQFisSmallRoot",sre.MathspeakFrenchUtil.smallRoot], +["CSF","CSFsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFbaselineVerbose",sre.MathspeakFrenchUtil.baselineVerbose],["CSF","CSFbaselineBrief",sre.MathspeakFrenchUtil.baselineBrief],["CSF","CSFleftsuperscriptVerbose",sre.MathspeakFrenchUtil.leftSuperscriptVerbose],["CSF","CSFleftsubscriptVerbose", +sre.MathspeakFrenchUtil.leftSubscriptVerbose],["CSF","CSFrightsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFrightsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFleftsuperscriptBrief",sre.MathspeakFrenchUtil.leftSuperscriptBrief],["CSF","CSFleftsubscriptBrief",sre.MathspeakFrenchUtil.leftSubscriptBrief],["CSF","CSFrightsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFrightsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFunderscript", +sre.MathspeakUtil.nestedUnderscore],["CSF","CSFoverscript",sre.MathspeakUtil.nestedOverscore],["CTXF","CTXFordinalCounter",sre.NumbersUtil.ordinalCounter],["CTXF","CTXFcontentIterator",sre.StoreUtil.contentIterator],["CQF","CQFdetIsSimple",sre.MathspeakUtil.determinantIsSimple],["CSF","CSFRemoveParens",sre.MathspeakUtil.removeParens],["CQF","CQFresetNesting",sre.MathspeakUtil.resetNestingDepth],["CQF","CQFisLogarithm",sre.ClearspeakUtil.isLogarithmWithBase]],rules:['Rule;collapsed;default;[n] . (engine:modality=summary,grammar:collapsed);self::*;@alternative;not(contains(@grammar, "collapsed"));self::*;self::*;self::*;self::*;self::*'.split(";"), +["SpecializedRule","collapsed","default","brief"],["SpecializedRule","collapsed","brief","sbrief"],"Rule;stree;default;[n] ./*[1];self::stree;CQFresetNesting".split(";"),["Rule","unknown","default","[n] text()","self::unknown"],'Rule;protected;default;[t] text();self::*;@role="protected"'.split(";"),["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule;blank-empty;default;[t] "vide";self::empty;count(../*)=1;name(../..)="cell" or name(../..)="line"'.split(";"),'Rule{font{default{[n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFont){self::*{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"), +'Rule{font-identifier-short{default{[n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFont);{self::identifier{string-length(text())=1{@font{not(contains(@grammar, "ignoreFont")){@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFont){self::identifier{string-length(text())=1{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1;@font;not(contains(@grammar, "ignoreFont"));@font="italic"'.split(";"),["Rule","number","default","[n] text()","self::number"],'Rule,mixed-number,default,[n] children/*[1]; [t] "et"; [n] children/*[2]; ,self::number,@role="mixed"'.split(","), +'Rule{number-with-chars{default{[t] "nombre"; [m] CQFspaceoutNumber{self::number{"" != translate(text(), "0123456789.,", ""){text() != translate(text(), "0123456789.,", "")'.split("{"),'Rule{number-as-upper-word{default{[t] "MotMajuscule"; [t] CSFspaceoutText{self::number{string-length(text())>1{text()=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9"){""=translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9","")'.split("{"), +'Rule{number-baseline{default{[t] "position de base"; [n] . (grammar:baseline){self::number{not(contains(@grammar, "ignoreFont")){preceding-sibling::identifier{not(contains(@grammar, "baseline")){preceding-sibling::*[1][@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline","default","brief",'[t] "base"; [n] . (grammar:baseline)'],["SpecializedRule","number-baseline","brief","sbrief"],'Rule{number-baseline-font{default{[t] "position de base"; [n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFont){self::number{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"{preceding-sibling::identifier{preceding-sibling::*[@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"), +["SpecializedRule","number-baseline-font","default","brief",'[t] "base"; [n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFont)'],["SpecializedRule","number-baseline-font","brief","sbrief"],'Rule;identifier;default;[m] CQFspaceoutIdentifier;self::identifier;string-length(text())>1;@role!="unit";@role!="protected";not(@font) or @font="normal" or contains(@grammar, "ignoreFont");text()!=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", "")'.split(";"), +["Rule","identifier","default","[n] text()","self::identifier"],'Rule,negative,default,[t] "n\u00e9gatif"; [n] children/*[1],self::prefixop,@role="negative",children/identifier'.split(","),["Aliases","negative","self::prefixop",'@role="negative"',"children/number"],["Aliases","negative","self::prefixop",'@role="negative"','children/fraction[@role="vulgar"]'],'Rule,negative,default,[t] "n\u00e9gatif"; [n] children/*[1],self::prefixop,@role="negative"'.split(","),["Rule","prefix","default","[m] content/*; [n] children/*[1]", +"self::prefixop"],["Rule","postfix","default","[n] children/*[1]; [m] content/*","self::postfixop"],["Rule","binary-operation","default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop"],'Rule;implicit;default;[m] children/*;self::infixop;@role="implicit"'.split(";"),["Aliases","implicit","self::infixop",'@role="leftsuper" or @role="leftsub" or @role="rightsuper" or @role="rightsub"'],'Rule,subtraction,default,[m] children/* (separator:"moins");,self::infixop,@role="subtraction"'.split(","), +["Rule","function-unknown","default","[n] children/*[1]; [n] children/*[2]","self::appl"],'Rule,function-prefix,default,[n] children/*[1]; [n] children/*[2],self::appl,children/*[1][@role="prefix function"]'.split(","),'Rule,fences-open-close,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="leftright"'.split(","),'Rule,fences-neutral,default,[t] "d\u00e9but valeur absolue"; [n] children/*[1]; [t] "fin valeur absolue",self::fenced,@role="neutral",content/*[1][text()]="|" or content/*[1][text()]="\u2758" or content/*[1][text()]="\uff5c"'.split(","), +["SpecializedRule","fences-neutral","default","sbrief",'[t] "valeur absolue"; [n] children/*[1]; [t] "fin valeur absolue"'],'Rule,fences-neutral,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="neutral"'.split(","),'Rule,fences-set,default,[t] "d\u00e9but ensemble"; [n] children/*[1]; [t] "fin ensemble",self::fenced,@role="set empty" or @role="set extended" or @role="set singleton" or @role="set collection",not(name(../..)="appl")'.split(","),["SpecializedRule","fences-set", +"default","sbrief",'[t] "ensemble"; [n] children/*[1]; [t] "fin ensemble"'],["Rule","text","default","[n] text()","self::text"],'Rule;factorial;default;[t] "factorielle";self::punctuation;text()="!";name(preceding-sibling::*[1])!="text"'.split(";"),'Rule;minus;default;[t] "moins";self::operator;text()="-"'.split(";"),'Rule;single-prime;default;[t] "prime";self::punctuated;@role="prime";count(children/*)=1'.split(";"),'Rule;double-prime;default;[t] "double prime";self::punctuated;@role="prime";count(children/*)=2'.split(";"), +'Rule;triple-prime;default;[t] "triple prime";self::punctuated;@role="prime";count(children/*)=3'.split(";"),'Rule;quadruple-prime;default;[t] "quadruple prime";self::punctuated;@role="prime";count(children/*)=4'.split(";"),'Rule,counted-prime,default,[t] count(children/*); [t] "prime",self::punctuated,@role="prime"'.split(","),["Rule","fraction","default","[t] CSFopenFracVerbose; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracVerbose","self::fraction"],["Rule","fraction", +"brief","[t] CSFopenFracBrief; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracBrief","self::fraction"],["Rule","fraction","sbrief","[t] CSFopenFracSbrief; [n] children/*[1]; [t] CSFoverFracSbrief; [n] children/*[2]; [t] CSFcloseFracSbrief","self::fraction"],'Rule;vulgar-fraction;default;[t] CSFvulgarFrFraction;self::fraction;@role="vulgar";CQFvulgarFractionSmall'.split(";"),["SpecializedRule","vulgar-fraction","default","brief"],["SpecializedRule","vulgar-fraction", +"default","sbrief"],'Rule,continued-fraction-outer,default,[t] "fraction continue"; [n] children/*[1];[t] "sur"; [n] children/*[2],self::fraction,not(ancestor::fraction),children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","),["SpecializedRule","continued-fraction-outer","default","brief",'[t] "frac continue"; [n] children/*[1];[t] "sur"; [n] children/*[2]'],["SpecializedRule","continued-fraction-outer","brief","sbrief"],'Rule,continued-fraction-inner,default,[t] "d\u00e9but fraction"; [n] children/*[1];[t] "sur"; [n] children/*[2],self::fraction,ancestor::fraction,children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","), +["SpecializedRule","continued-fraction-inner","default","brief",'[t] "d\u00e9but frac"; [n] children/*[1];[t] "sur"; [n] children/*[2]'],["SpecializedRule","continued-fraction-inner","brief","sbrief",'[t] "frac"; [n] children/*[1];[t] "sur"; [n] children/*[2]'],["Rule","sqrt","default","[t] CSFopenRadicalVerbose; [n] children/*[1]; [t] CSFcloseRadicalVerbose","self::sqrt"],["Rule","sqrt","brief","[t] CSFopenRadicalBrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],["Rule","sqrt","sbrief", +"[t] CSFopenRadicalSbrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],"Rule,root-small,default,[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose,self::root,CQFisSmallRoot".split(","),"Rule,root-small,brief,[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief,self::root,CQFisSmallRoot".split(","),"Rule,root-small,sbrief,[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief,self::root,CQFisSmallRoot".split(","),["Rule","root","default", +"[t] CSFindexRadicalVerbose; [n] children/*[1];[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose","self::root"],["Rule","root","brief","[t] CSFindexRadicalBrief; [n] children/*[1];[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root"],["Rule","root","sbrief","[t] CSFindexRadicalSbrief; [n] children/*[1];[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root"],'Rule,limboth,default,[n] children/*[1]; [t] "d\u00e9but"; [t] CSFunderscript; [n] children/*[2];[t] "d\u00e9but"; [t] CSFoverscript; [n] children/*[3],self::limboth,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","), +'Rule,limlower,default,[n] children/*[1]; [t] "d\u00e9but"; [t] CSFunderscript; [n] children/*[2];,self::limlower,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Rule,limupper,default,[n] children/*[1]; [t] "d\u00e9but"; [t] CSFoverscript; [n] children/*[2];,self::limupper,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Aliases;limlower;self::underscore;@role="limit function";name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"), +'Aliases;limlower;self::underscore;children/*[2][@role!="underaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),'Aliases;limupper;self::overscore;children/*[2][@role!="overaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),["Rule","limboth-end","default",'[n] children/*[1]; [t] "d\u00e9but"; [t] CSFunderscript; [n] children/*[2];[t] "d\u00e9but"; [t] CSFoverscript; [n] children/*[3]; [t] "fin scripts"', +"self::limboth"],["Rule","limlower-end","default",'[n] children/*[1]; [t] "d\u00e9but"; [t] CSFunderscript; [n] children/*[2]; [t] "fin scripts"',"self::limlower"],["Rule","limupper-end","default",'[n] children/*[1]; [t] "d\u00e9but"; [t] CSFoverscript; [n] children/*[2]; [t] "fin scripts"',"self::limupper"],["Aliases","limlower-end","self::underscore",'@role="limit function"'],["Aliases","limlower-end","self::underscore"],["Aliases","limupper-end","self::overscore"],["Rule","integral","default", +"[n] children/*[1]; [n] children/*[2]; [n] children/*[3];","self::integral"],'Rule,integral,default,[n] children/*[1]; [t] "indice inf\u00e9rieur"; [n] children/*[2];[t] "indice sup\u00e9rieur"; [n] children/*[3]; [t] "position de base";,self::limboth,@role="integral"'.split(","),["SpecializedRule","integral","default","brief",'[n] children/*[1]; [t] "inf"; [n] children/*[2];[t] "sup"; [n] children/*[3]; [t] "position de base";'],["SpecializedRule","integral","brief","sbrief"],["Rule","bigop","default", +"[n] children/*[1]; [n] children/*[2];","self::bigop"],["Rule","relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],'Rule,equality,default,[n] children/*[1]; [n] content/*[1]; [n] children/*[2],self::relseq,@role="equality",count(./children/*)=2'.split(","),'Rule;multi-equality;default;[m] children/* (sepFunc:CTXFcontentIterator);self::relseq;@role="equality";count(./children/*)>2'.split(";"),["Rule","multrel","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::multirel"], +["Rule","subscript","default","[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]","self::subscript"],["Rule","subscript","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]","self::subscript"],["SpecializedRule","subscript","brief","sbrief"],'Rule,subscript-base,default,[n] children/*[1]; [t] "base"; [n] children/*[2],self::subscript,CQFisLogarithm,self::*,self::*,self::*'.split(","),["SpecializedRule","subscript-base","default","brief"],["SpecializedRule","subscript-base", +"default","sbrief"],'Rule,subscript-simple,brief,[n] children/*[1]; [n] children/*[2],self::subscript,name(./children/*[1])="identifier",name(./children/*[2])="number",./children/*[2][@role!="mixed"],./children/*[2][@role!="othernumber"]'.split(","),["SpecializedRule","subscript-simple","brief","sbrief"],'Rule,subscript-baseline,default,[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]; [t] CSFbaselineVerbose,self::subscript,following-sibling::*,not(name(following-sibling::subscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="subscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and @role!="subsup",not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","subscript-baseline","default","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]; [t] CSFbaselineBrief"],["SpecializedRule","subscript-baseline","brief","sbrief"],'Aliases;subscript-baseline;self::subscript;not(following-sibling::*);ancestor::fenced|ancestor::root|ancestor::sqrt|ancestor::punctuated|ancestor::fraction;not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","subscript-baseline", +"self::subscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel",sre.MathspeakUtil.generateBaselineConstraint()],["Aliases","subscript-baseline","self::subscript","not(following-sibling::*)","@embellished"],'Rule,subscript-empty-sup,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="superscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","),["SpecializedRule","subscript-empty-sup", +"default","brief"],["SpecializedRule","subscript-empty-sup","brief","sbrief"],["Aliases","subscript-empty-sup","self::subscript",'name(children/*[2])="superscript"','name(children/*[2]/children/*[1])="empty"'],["Rule","superscript","default","[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2]","self::superscript"],["SpecializedRule","superscript","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2]"],["SpecializedRule","superscript","brief","sbrief"],'Rule,superscript-baseline,default,[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2];[t] CSFbaselineVerbose,self::superscript,following-sibling::*,not(name(following-sibling::superscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="superscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","superscript-baseline","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2];[t] CSFbaselineBrief"],["SpecializedRule","superscript-baseline","brief","sbrief"],'Aliases;superscript-baseline;self::superscript;not(following-sibling::*);ancestor::punctuated;ancestor::*/following-sibling::* and not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","superscript-baseline","self::superscript", +"not(following-sibling::*)","ancestor::fraction|ancestor::fenced|ancestor::root|ancestor::sqrt"],["Aliases","superscript-baseline","self::superscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel","not(@embellished)",sre.MathspeakUtil.generateBaselineConstraint()],'Aliases superscript-baseline self::superscript not(following-sibling::*) @embellished not(children/*[2][@role="prime"])'.split(" "),'Rule,superscript-empty-sub,default,[n] children/*[1]; [n] children/*[2],self::superscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="subscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","), +["SpecializedRule","superscript-empty-sub","default","brief"],["SpecializedRule","superscript-empty-sub","brief","sbrief"],["Aliases","superscript-empty-sub","self::superscript",'name(children/*[2])="subscript"','name(children/*[2]/children/*[1])="empty"'],'Rule,square,default,[n] children/*[1]; [t] "au carr\u00e9",self::superscript,children/*[2],children/*[2][text()=2],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","square","default","brief"],["SpecializedRule","square","default","sbrief"],'Aliases;square;self::superscript;children/*[2];children/*[2][text()=2];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,cube,default,[n] children/*[1]; [t] "cubique",self::superscript,children/*[2],children/*[2][text()=3],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","cube","default","brief"],["SpecializedRule","cube","default","sbrief"],'Aliases;cube;self::superscript;children/*[2];children/*[2][text()=3];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,prime,default,[n] children/*[1]; [n] children/*[2],self::superscript,children/*[2],children/*[2][@role="prime"]'.split(","),["SpecializedRule","prime","default","brief"],["SpecializedRule","prime","default","sbrief"],'Rule,prime-subscript,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",not(following-sibling::*)'.split(","), +["SpecializedRule","prime-subscript","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]"],["SpecializedRule","prime-subscript","brief","sbrief"],'Rule,prime-subscript-baseline,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2]; [t] CSFbaselineVerbose,self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",following-sibling::*'.split(","), +["SpecializedRule","prime-subscript-baseline","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]; [t] CSFbaselineBrief"],["SpecializedRule","prime-subscript-baseline","brief","sbrief"],'Aliases prime-subscript-baseline self::superscript children/*[2][@role="prime"] name(children/*[1])="subscript" not(following-sibling::*) @embellished'.split(" "),'Rule,prime-subscript-simple,brief,[n] children/*[1]/children/*[1]; [n] children/*[2];[n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",name(children/*[1]/children/*[1])="identifier",name(children/*[1]/children/*[2])="number",children/*[1]/children/*[2][@role!="mixed"],children/*[1]/children/*[2][@role!="othernumber"]'.split(","), +["SpecializedRule","prime-subscript-simple","brief","sbrief"],'Rule,overscore,default,[t] "suscrire"; [n] children/*[1]; [t] "avec"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"]'.split(","),'Rule,double-overscore,default,[t] "sus-suscrire"; [n] children/*[1]; [t] "avec"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"],name(children/*[1])="overscore",children/*[1]/children/*[2][@role="overaccent"]'.split(","),'Rule,underscore,default,[t] "souscrire"; [n] children/*[1]; [t] "avec"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"]'.split(","), +'Rule,double-underscore,default,[t] "sous-souscrire"; [n] children/*[1]; [t] "avec"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"],name(children/*[1])="underscore",children/*[1]/children/*[2][@role="underaccent"]'.split(","),'Rule,matrix-fence,default,[n] children/*[1];,self::fenced,count(children/*)=1,name(children/*[1])="matrix"'.split(","),["Rule","matrix","default",'[t] "d\u00e9but matrice"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin matrice"', +"self::matrix"],["Rule","matrix","sbrief",'[t] "matrice"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin matrice"',"self::matrix"],["Aliases","matrix","self::vector"],["Rule","matrix-row","default",'[m] children/* (ctxtFunc:CTXFordinalCounter,context:"colonne");[p] (pause: 200)',"self::row"],'Rule{row-with-label{default{[t] "avec \u00e9tiquette"; [n] content/*[1]; [t] "fin \u00e9tiquette"(pause: 200); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"colonne"){self::row{content'.split("{"), +'Rule{row-with-label{brief{[t] "\u00e9tiquette"; [n] content/*[1]; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"colonne"){self::row{content'.split("{"),["SpecializedRule","row-with-label","brief","sbrief"],'Rule{row-with-text-label{sbrief{[t] "\u00e9tiquette"; [t] CSFRemoveParens;[m] children/* (ctxtFunc:CTXFordinalCounter,context:"colonne"){self::row{content{name(content/cell/children/*[1])="text"'.split("{"),'Rule;empty-row;default;[t] "vide";self::row;count(children/*)=0'.split(";"),["Rule", +"matrix-cell","default","[n] children/*[1]; [p] (pause: 300)","self::cell"],'Rule,empty-cell,default,[t] "vide"; [p] (pause: 300),self::cell,count(children/*)=0'.split(","),'Rule{determinant{default{[t] "d\u00e9but d\u00e9terminant"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [t] ""; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin d\u00e9terminant"{self::matrix{@role="determinant"'.split("{"),["SpecializedRule","determinant","default","sbrief", +'[t] "d\u00e9terminant"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin d\u00e9terminant"'],'Rule{determinant-simple{default{[t] "d\u00e9but d\u00e9terminant"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e",grammar:simpleDet); [t] "fin d\u00e9terminant"{self::matrix{@role="determinant"{CQFdetIsSimple'.split("{"), +["SpecializedRule","determinant-simple","default","sbrief",'[t] "d\u00e9terminant"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e",grammar:simpleDet); [t] "fin d\u00e9terminant"'],'Rule{row-simple{default{[m] children/*;{self::row{@role="determinant"{contains(@grammar, "simpleDet")'.split("{"),["Rule","layout","default",'[t] "d\u00e9but tableau"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin tableau"', +"self::table"],["Rule","layout","sbrief",'[t] "tableau"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin tableau"',"self::table"],'Rule,binomial,default,[t] "d\u00e9but binomiale"; [n] children/*[2]/children/*[1]; [t] "parmi"; [n] children/*[1]/children/*[1]; [t] "fin binomiale",self::vector,@role="binomial"'.split(","),'Rule,binomial,sbrief,[t] "binomiale"; [n] children/*[1]/children/*[1]; [t] "parmi"; [n] children/*[2]/children/*[1]; [t] "fin binomiale",self::vector,@role="binomial"'.split(","), +["Rule","cases","default",'[t] "d\u00e9but tableau"; [n] content/*[1]; [t] "\u00e9largie";[m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin tableau"',"self::cases"],["Rule","cases","sbrief",'[t] "tableau"; [n] content/*[1]; [t] "\u00e9largie"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"rang\u00e9e "); [t] "fin tableau"',"self::cases"],["Aliases","layout","self::multiline"],["Rule","line","default","[m] children/*","self::line"],'Rule,line-with-label,default,[t] "avec etiquette"; [n] content/*[1]; [t] "fin etiquette" (pause: 200); [m] children/*,self::line,content'.split(","), +["SpecializedRule","line-with-label","default","brief",'[t] "etiquette"; [n] content/*[1] (pause: 200); [m] children/*'],["SpecializedRule","line-with-label","brief","sbrief"],'Rule,line-with-text-label,sbrief,[t] "etiquette"; [t] CSFRemoveParens; [m] children/*,self::line,content,name(content/cell/children/*[1])="text"'.split(","),'Rule;empty-line;default;[t] "vide";self::line;count(children/*)=0;not(content)'.split(";"),["SpecializedRule","empty-line","default","brief"],["SpecializedRule","empty-line", +"brief","sbrief"],'Rule,empty-line-with-label,default,[t] "avec etiquette"; [n] content/*[1]; [t] "fin etiquette" (pause: 200); [t] "vide",self::line,count(children/*)=0,content'.split(","),["SpecializedRule","empty-line-with-label","default","brief",'[t] "etiquette"; [n] content/*[1] (pause: 200); [t] "vide"'],["SpecializedRule","empty-line-with-label","brief","sbrief"],["Rule","enclose","default",'[t] "d\u00e9but enfermer en"; [t] @role (grammar:localEnclose); [n] children/*[1]; [t] "fin enfermer"', +"self::enclose"],'Rule,overbar,default,[t] "d\u00e9but trait suscrit"; [n] children/*[1]; [t] "fin trait suscrit",self::enclose,@role="top"'.split(","),'Rule,underbar,default,[t] "d\u00e9but trait souscrit"; [n] children/*[1]; [t] "fin trait souscrit",self::enclose,@role="bottom"'.split(","),'Rule,leftbar,default,[t] "barre verticale"; [n] children/*[1],self::enclose,@role="left"'.split(","),'Rule,rightbar,default,[n] children/*[1]; [t] "barre verticale",self::enclose,@role="right"'.split(","),'Rule,crossout,default,[t] "d\u00e9but biff\u00e9"; [n] children/*[1]; [t] "fin biff\u00e9",self::enclose,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","), +'Rule,cancel,default,[t] "d\u00e9but biff\u00e9"; [n] children/*[1]/children/*[1]; [t] "avec"; [n] children/*[2]; [t] "fin biff\u00e9",self::overscore,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","),["SpecializedRule","cancel","default","brief"],["SpecializedRule","cancel","default","sbrief"],["Aliases","cancel","self::underscore",'@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'],'Rule,cancel-reverse,default,[t] "d\u00e9but biff\u00e9"; [n] children/*[2]/children/*[1]; [t] "avec"; [n] children/*[1]; [t] "fin biff\u00e9",self::overscore,name(children/*[2])="enclose",children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'.split(","), +["SpecializedRule","cancel-reverse","default","brief"],["SpecializedRule","cancel-reverse","default","sbrief"],["Aliases","cancel-reverse","self::underscore",'name(children/*[2])="enclose"','children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'],'Rule;end-punct;default;[m] children/*;self::punctuated;@role="endpunct"'.split(";"),'Rule,start-punct,default,[n] content/*[1]; [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule,integral-punct,default,[n] children/*[1]; [n] children/*[3],self::punctuated,@role="integral"'.split(","), +["Rule","punctuated","default","[m] children/*","self::punctuated"],'Rule;unit;default;[t] text() (grammar:annotation="unit":translate);self::identifier;@role="unit"'.split(";"),'Rule,unit-square,default,[n] children/*[1]; [t] "carr\u00e9",self::superscript,@role="unit",children/*[2][text()=2],name(children/*[1])="identifier"'.split(","),'Rule,unit-cubic,default,[n] children/*[1]; [t] "cubique",self::superscript,@role="unit",children/*[2][text()=3],name(children/*[1])="identifier"'.split(","),'Rule,reciprocal,default,[t] "r\u00e9ciproque"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],count(preceding-sibling::*)=0 or preceding-sibling::*[@role!="unit"]'.split(","), +'Rule,reciprocal,default,[t] "par"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],preceding-sibling::*[@role="unit"]'.split(","),'Rule;unit-combine;default;[m] children/*;self::infixop;@role="unit"'.split(";"),'Rule,unit-divide,default,[n] children/*[1]; [t] "par"; [n] children/*[2],self::fraction,@role="unit"'.split(",")],initialize:[sre.MathspeakUtil.generateTensorRules]};sre.MathspeakGerman={locale:"de",domain:"mathspeak",functions:[["CQF","CQFspaceoutNumber",sre.MathspeakUtil.spaceoutNumber],["CQF","CQFspaceoutIdentifier",sre.MathspeakUtil.spaceoutIdentifier],["CSF","CSFspaceoutText",sre.MathspeakUtil.spaceoutText],["CSF","CSFopenFracVerbose",sre.MathspeakUtil.openingFractionVerbose],["CSF","CSFcloseFracVerbose",sre.MathspeakUtil.closingFractionVerbose],["CSF","CSFoverFracVerbose",sre.MathspeakUtil.overFractionVerbose],["CSF","CSFopenFracBrief",sre.MathspeakUtil.openingFractionBrief], +["CSF","CSFcloseFracBrief",sre.MathspeakUtil.closingFractionBrief],["CSF","CSFopenFracSbrief",sre.MathspeakUtil.openingFractionSbrief],["CSF","CSFcloseFracSbrief",sre.MathspeakUtil.closingFractionSbrief],["CSF","CSFoverFracSbrief",sre.MathspeakUtil.overFractionSbrief],["CSF","CSFvulgarFraction",sre.NumbersUtil.vulgarFraction],["CQF","CQFvulgarFractionSmall",sre.MathspeakUtil.isSmallVulgarFraction],["CSF","CSFopenRadicalVerbose",sre.MathspeakUtil.openingRadicalVerbose],["CSF","CSFcloseRadicalVerbose", +sre.MathspeakUtil.closingRadicalVerbose],["CSF","CSFindexRadicalVerbose",sre.MathspeakUtil.indexRadicalVerbose],["CSF","CSFopenRadicalBrief",sre.MathspeakUtil.openingRadicalBrief],["CSF","CSFcloseRadicalBrief",sre.MathspeakUtil.closingRadicalBrief],["CSF","CSFindexRadicalBrief",sre.MathspeakUtil.indexRadicalBrief],["CSF","CSFopenRadicalSbrief",sre.MathspeakUtil.openingRadicalSbrief],["CSF","CSFindexRadicalSbrief",sre.MathspeakUtil.indexRadicalSbrief],["CSF","CSFsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose], +["CSF","CSFsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFbaselineVerbose",sre.MathspeakUtil.baselineVerbose],["CSF","CSFbaselineBrief",sre.MathspeakUtil.baselineBrief],["CSF","CSFleftsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFleftsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFrightsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose], +["CSF","CSFrightsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFleftsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFleftsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFrightsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFrightsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFunderscript",sre.MathspeakUtil.nestedUnderscore],["CSF","CSFoverscript",sre.MathspeakUtil.nestedOverscore],["CTXF","CTXFordinalCounter",sre.NumbersUtil.ordinalCounter], +["CTXF","CTXFcontentIterator",sre.StoreUtil.contentIterator],["CQF","CQFdetIsSimple",sre.MathspeakUtil.determinantIsSimple],["CSF","CSFRemoveParens",sre.MathspeakUtil.removeParens],["CQF","CQFresetNesting",sre.MathspeakUtil.resetNestingDepth]],rules:['Rule{collapsed{default{[n] . (engine:modality=summary,grammar:collapsed); [t] "kollabiert"{self::*{@alternative{not(contains(@grammar, "collapsed")){self::*{self::*{self::*{self::*{self::*'.split("{"),["SpecializedRule","collapsed","default","brief"], +["SpecializedRule","collapsed","brief","sbrief"],"Rule;stree;default;[n] ./*[1];self::stree;CQFresetNesting".split(";"),["Rule","unknown","default","[n] text()","self::unknown"],'Rule;protected;default;[t] text();self::number;contains(@grammar, "protected")'.split(";"),["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule;blank-empty;default;[t] "leer";self::empty;count(../*)=1;name(../..)="cell" or name(../..)="line"'.split(";"),'Rule{font{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::*{name(self::*)!="number"{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"), +'Rule{font-number{default{[t] @font (grammar:localFontNumber); [n] . (grammar:ignoreFont=@font){self::number{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"),'Rule{font-identifier-short{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{not(contains(@grammar, "ignoreFont")){@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1 or string-length(text())=2{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1 or string-length(text())=2;@font;not(contains(@grammar, "ignoreFont"));@font="italic";self::*'.split(";"),'Rule{font-double-struck{default{[n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFont){self::*{name(self::*)!="number"{string-length(text())=1 or string-length(text())=2{@font{not(contains(@grammar, "ignoreFont")){@font="double-struck"'.split("{"), +'Rule{font-number-double-struck{default{[n] . (grammar:ignoreFont=@font); [t] @font (grammar:localFontNumber){self::number{string-length(text())=1 or string-length(text())=2{@font{not(contains(@grammar, "ignoreFont")){@font="double-struck"'.split("{"),["Rule","number","default","[n] text()","self::number"],'Rule,mixed-number,default,[n] children/*[1]; [n] children/*[2]; ,self::number,@role="mixed"'.split(","),'Rule{number-with-chars{default{[t] "Zahl"; [m] CQFspaceoutNumber (grammar:protected){self::number{@role="othernumber"{"" != translate(text(), "0123456789.,", ""){not(contains(@grammar, "protected"))'.split("{"), +'Rule{number-as-upper-word{default{[t] "Wort gro\u00df"; [t] CSFspaceoutText{self::number{string-length(text())>1{text()=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9"){""=translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9","")'.split("{"), +["SpecializedRule","number-as-upper-word","default","brief"],["SpecializedRule","number-as-upper-word","default","sbrief"],'Rule{number-baseline{default{[t] "Grundlinie"; [n] . (grammar:baseline){self::number{not(contains(@grammar, "ignoreFont")){preceding-sibling::identifier{not(contains(@grammar, "baseline")){preceding-sibling::*[1][@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline","default", +"brief",'[t] "Grund"; [n] . (grammar:baseline)'],["SpecializedRule","number-baseline","brief","sbrief"],'Rule{number-baseline-font{default{[t] "Grundlinie"; [t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::number{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"{preceding-sibling::identifier{preceding-sibling::*[@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline-font", +"default","brief",'[t] "Grund"; [t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font)'],["SpecializedRule","number-baseline-font","brief","sbrief"],'Rule;identifier;default;[m] CQFspaceoutIdentifier;self::identifier;string-length(text())>1;@role!="unit";not(@font) or @font="normal" or contains(@grammar, "ignoreFont");text()!=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", "")'.split(";"), +["Rule","identifier","default","[n] text()","self::identifier"],'Rule,negative,default,[t] "minus"; [n] children/*[1],self::prefixop,@role="negative",children/identifier'.split(","),["Aliases","negative","self::prefixop",'@role="negative"',"children/number"],["Aliases","negative","self::prefixop",'@role="negative"','children/fraction[@role="vulgar"]'],'Rule,negative,default,[t] "minus"; [n] children/*[1],self::prefixop,@role="negative"'.split(","),["Rule","prefix","default","[m] content/*; [n] children/*[1]", +"self::prefixop"],["Rule","postfix","default","[n] children/*[1]; [m] content/*","self::postfixop"],["Rule","binary-operation","default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop"],'Rule;implicit;default;[m] children/*;self::infixop;@role="implicit"'.split(";"),["Aliases","implicit","self::infixop",'@role="leftsuper" or @role="leftsub" or @role="rightsuper" or @role="rightsub"'],'Rule,subtraction,default,[m] children/* (separator:"minus");,self::infixop,@role="subtraction"'.split(","), +["Rule","function-unknown","default","[n] children/*[1]; [n] children/*[2]","self::appl"],'Rule,function-prefix,default,[n] children/*[1]; [n] children/*[2],self::appl,children/*[1][@role="prefix function"]'.split(","),'Rule,fences-open-close,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="leftright"'.split(","),'Rule,fences-neutral,default,[t] "Anfang Betrag"; [n] children/*[1]; [t] "Ende Betrag",self::fenced,@role="neutral",content/*[1][text()]="|" or content/*[1][text()]="\u2758" or content/*[1][text()]="\uff5c"'.split(","), +["SpecializedRule","fences-neutral","default","sbrief",'[t] "Betrag"; [n] children/*[1]; [t] "Ende Betrag"'],'Rule,fences-neutral,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="neutral"'.split(","),'Rule,fences-set,default,[t] "Anfang Menge"; [n] children/*[1]; [t] "Ende Menge",self::fenced,@role="set empty" or @role="set extended" or @role="set singleton" or @role="set collection",not(name(../..)="appl")'.split(","),["SpecializedRule","fences-set","default","sbrief", +'[t] "Menge"; [n] children/*[1]; [t] "Ende Menge"'],["Rule","text","default","[n] text()","self::text"],'Rule;factorial;default;[t] "Fakult\u00e4t";self::punctuation;text()="!";name(preceding-sibling::*[1])!="text"'.split(";"),'Rule;minus;default;[t] "minus";self::operator;text()="-"'.split(";"),'Rule;single-prime;default;[t] "Strich";self::punctuated;@role="prime";count(children/*)=1'.split(";"),'Rule;double-prime;default;[t] "zwei Strich";self::punctuated;@role="prime";count(children/*)=2'.split(";"), +'Rule;triple-prime;default;[t] "drei Strich";self::punctuated;@role="prime";count(children/*)=3'.split(";"),'Rule;quadruple-prime;default;[t] "vier Strich";self::punctuated;@role="prime";count(children/*)=4'.split(";"),'Rule,counted-prime,default,[t] count(children/*); [t] "Strich",self::punctuated,@role="prime"'.split(","),["Rule","fraction","default","[t] CSFopenFracVerbose; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracVerbose","self::fraction"],["Rule","fraction", +"brief","[t] CSFopenFracBrief; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracBrief","self::fraction"],["Rule","fraction","sbrief","[t] CSFopenFracSbrief; [n] children/*[1]; [t] CSFoverFracSbrief; [n] children/*[2]; [t] CSFcloseFracSbrief","self::fraction"],'Rule;vulgar-fraction;default;[t] CSFvulgarFraction (grammar:correctOne);self::fraction;@role="vulgar";CQFvulgarFractionSmall'.split(";"),["SpecializedRule","vulgar-fraction","default","brief"],["SpecializedRule", +"vulgar-fraction","default","sbrief"],'Rule,continued-fraction-outer,default,[t] "Kettenbruch"; [n] children/*[1];[t] "durch"; [n] children/*[2],self::fraction,not(ancestor::fraction),children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","),'Rule,continued-fraction-inner,default,[t] "Anfang Bruch"; [n] children/*[1];[t] "durch"; [n] children/*[2],self::fraction,ancestor::fraction,children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","), +["SpecializedRule","continued-fraction-inner","default","sbrief",'[t] "Bruch"; [n] children/*[1];[t] "durch"; [n] children/*[2]'],["Rule","sqrt","default","[t] CSFopenRadicalVerbose; [n] children/*[1]; [t] CSFcloseRadicalVerbose","self::sqrt"],["Rule","sqrt","brief","[t] CSFopenRadicalBrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],["Rule","sqrt","sbrief","[t] CSFopenRadicalSbrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],"Rule,root-small,default,[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose,self::root,children/*[1][text()=3 or text()=2]".split(","), +"Rule,root-small,brief,[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief,self::root,children/*[1][text()=3 or text()=2]".split(","),"Rule,root-small,sbrief,[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief,self::root,children/*[1][text()=3 or text()=2]".split(","),["Rule","root","default","[t] CSFindexRadicalVerbose; [n] children/*[1];[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose","self::root"],["Rule","root","brief","[t] CSFindexRadicalBrief; [n] children/*[1];[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief", +"self::root"],["Rule","root","sbrief","[t] CSFindexRadicalSbrief; [n] children/*[1];[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root"],'Rule,limboth,default,[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3],self::limboth,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Rule,limlower,default,[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];,self::limlower,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","), +'Rule,limupper,default,[n] children/*[1]; [t] CSFoverscript; [n] children/*[2];,self::limupper,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Aliases;limlower;self::underscore;@role="limit function";name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),'Aliases;limlower;self::underscore;children/*[2][@role!="underaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"), +'Aliases;limupper;self::overscore;children/*[2][@role!="overaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),["Rule","limboth-end","default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3]; [t] "Ende \u00dcberschrift"',"self::limboth"],["Rule","limlower-end","default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2]; [t] "Ende Unterschrift"',"self::limlower"], +["Rule","limupper-end","default",'[n] children/*[1]; [t] CSFoverscript; [n] children/*[2]; [t] "Ende \u00dcberschrift"',"self::limupper"],["Aliases","limlower-end","self::underscore",'@role="limit function"'],["Aliases","limlower-end","self::underscore"],["Aliases","limupper-end","self::overscore"],["Rule","integral","default","[n] children/*[1]; [n] children/*[2]; [n] children/*[3];","self::integral"],'Rule,integral,default,[n] children/*[1]; [t] "Index"; [n] children/*[2];[t] "Hoch"; [n] children/*[3]; [t] "Grundlinie";,self::limboth,@role="integral"'.split(","), +["SpecializedRule","integral","default","brief",'[n] children/*[1]; [t] "Index"; [n] children/*[2];[t] "Hoch"; [n] children/*[3]; [t] "Base";'],["SpecializedRule","integral","brief","sbrief"],["Rule","bigop","default","[n] children/*[1]; [n] children/*[2];","self::bigop"],["Rule","relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],'Rule,equality,default,[n] children/*[1]; [n] content/*[1]; [n] children/*[2],self::relseq,@role="equality",count(./children/*)=2'.split(","), +'Rule;multi-equality;default;[m] children/* (sepFunc:CTXFcontentIterator);self::relseq;@role="equality";count(./children/*)>2'.split(";"),["Rule","multrel","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::multirel"],["Rule","subscript","default","[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]","self::subscript"],["Rule","subscript","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]","self::subscript"],["SpecializedRule","subscript","brief","sbrief"], +'Rule,subscript-simple,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(./children/*[1])="identifier",name(./children/*[2])="number",./children/*[2][@role!="mixed"],./children/*[2][@role!="othernumber"]'.split(","),["SpecializedRule","subscript-simple","default","brief"],["SpecializedRule","subscript-simple","default","sbrief"],'Rule,subscript-baseline,default,[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]; [t] CSFbaselineVerbose,self::subscript,following-sibling::*,not(name(following-sibling::subscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="subscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and @role!="subsup",not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","subscript-baseline","default","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]; [t] CSFbaselineBrief"],["SpecializedRule","subscript-baseline","brief","sbrief"],'Aliases;subscript-baseline;self::subscript;not(following-sibling::*);ancestor::fenced|ancestor::root|ancestor::sqrt|ancestor::punctuated|ancestor::fraction;not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","subscript-baseline", +"self::subscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel",sre.MathspeakUtil.generateBaselineConstraint()],["Aliases","subscript-baseline","self::subscript","not(following-sibling::*)","@embellished"],'Rule,subscript-empty-sup,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="superscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","),["SpecializedRule","subscript-empty-sup", +"default","brief"],["SpecializedRule","subscript-empty-sup","brief","sbrief"],["Aliases","subscript-empty-sup","self::subscript",'name(children/*[2])="superscript"','name(children/*[2]/children/*[1])="empty"'],["Rule","superscript","default","[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2]","self::superscript"],["SpecializedRule","superscript","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2]"],["SpecializedRule","superscript","brief","sbrief"],'Rule,superscript-baseline,default,[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2];[t] CSFbaselineVerbose,self::superscript,following-sibling::*,not(name(following-sibling::superscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="superscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","superscript-baseline","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2];[t] CSFbaselineBrief"],["SpecializedRule","superscript-baseline","brief","sbrief"],'Aliases;superscript-baseline;self::superscript;not(following-sibling::*);ancestor::punctuated;ancestor::*/following-sibling::* and not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","superscript-baseline","self::superscript", +"not(following-sibling::*)","ancestor::fraction|ancestor::fenced|ancestor::root|ancestor::sqrt"],["Aliases","superscript-baseline","self::superscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel","not(@embellished)",sre.MathspeakUtil.generateBaselineConstraint()],'Aliases superscript-baseline self::superscript not(following-sibling::*) @embellished not(children/*[2][@role="prime"])'.split(" "),'Rule,superscript-empty-sub,default,[n] children/*[1]; [n] children/*[2],self::superscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="subscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","), +["SpecializedRule","superscript-empty-sub","default","brief"],["SpecializedRule","superscript-empty-sub","brief","sbrief"],["Aliases","superscript-empty-sub","self::superscript",'name(children/*[2])="subscript"','name(children/*[2]/children/*[1])="empty"'],'Rule,square,default,[n] children/*[1]; [t] "Quadrat",self::superscript,children/*[2],children/*[2][text()=2],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","square","default","brief"],["SpecializedRule","square","default","sbrief"],'Aliases;square;self::superscript;children/*[2];children/*[2][text()=2];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,cube,default,[n] children/*[1]; [t] "Kubik",self::superscript,children/*[2],children/*[2][text()=3],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","cube","default","brief"],["SpecializedRule","cube","default","sbrief"],'Aliases;cube;self::superscript;children/*[2];children/*[2][text()=3];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,prime,default,[n] children/*[1]; [n] children/*[2],self::superscript,children/*[2],children/*[2][@role="prime"]'.split(","),["SpecializedRule","prime","default","brief"],["SpecializedRule","prime","default","sbrief"],'Rule,prime-subscript,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",not(following-sibling::*)'.split(","), +["SpecializedRule","prime-subscript","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]"],["SpecializedRule","prime-subscript","brief","sbrief"],'Rule,prime-subscript-baseline,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2]; [t] CSFbaselineVerbose,self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",following-sibling::*'.split(","), +["SpecializedRule","prime-subscript-baseline","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]; [t] CSFbaselineBrief"],["SpecializedRule","prime-subscript-baseline","brief","sbrief"],'Aliases prime-subscript-baseline self::superscript children/*[2][@role="prime"] name(children/*[1])="subscript" not(following-sibling::*) @embellished'.split(" "),'Rule,prime-subscript-simple,default,[n] children/*[1]/children/*[1]; [n] children/*[2];[n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",name(children/*[1]/children/*[1])="identifier",name(children/*[1]/children/*[2])="number",children/*[1]/children/*[2][@role!="mixed"],children/*[1]/children/*[2][@role!="othernumber"]'.split(","), +["SpecializedRule","prime-subscript-simple","default","brief"],["SpecializedRule","prime-subscript-simple","default","sbrief"],'Rule,overscore,default,[t] "modifiziert oben"; [n] children/*[1]; [t] "mit"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"]'.split(","),["SpecializedRule","overscore","default","brief",'[t] "mod oben"; [n] children/*[1]; [t] "mit"; [n] children/*[2]'],["SpecializedRule","overscore","brief","sbrief"],'Rule,double-overscore,default,[t] "modifiziert oben oben"; [n] children/*[1]; [t] "mit"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"],name(children/*[1])="overscore",children/*[1]/children/*[2][@role="overaccent"]'.split(","), +["SpecializedRule","double-overscore","default","brief",'[t] "mod oben oben"; [n] children/*[1]; [t] "mit"; [n] children/*[2]'],["SpecializedRule","double-overscore","brief","sbrief"],'Rule,underscore,default,[t] "modifiziert unten"; [n] children/*[1]; [t] "mit"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"]'.split(","),["SpecializedRule","underscore","default","brief",'[t] "mod unten"; [n] children/*[1]; [t] "mit"; [n] children/*[2]'],["SpecializedRule","underscore","brief", +"sbrief"],'Rule,double-underscore,default,[t] "modifiziert unten unten"; [n] children/*[1]; [t] "mit"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"],name(children/*[1])="underscore",children/*[1]/children/*[2][@role="underaccent"]'.split(","),["SpecializedRule","double-underscore","default","brief",'[t] "mod unten unten"; [n] children/*[1]; [t] "mit"; [n] children/*[2]'],["SpecializedRule","double-underscore","brief","sbrief"],'Rule,overbar,default,[n] children/*[1]; [t] "\u00dcberstrich",self::overscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="overaccent"],children/*[2][text()="\u00af" or text()="\uffe3" or text()="\uff3f" or text()="_" or text()="\u203e"]'.split(","), +'Rule,underbar,default,[n] children/*[1]; [t] "Unterstrich",self::underscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="underaccent"],children/*[2][text()="\u00af" or text()="\uffe3" or text()="\uff3f" or text()="_" or text()="\u203e"]'.split(","),'Rule,overtilde,default,[n] children/*[1]; [t] "Tilde oben",self::overscore,children/*[2][@role="overaccent"],@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][text()="~" or text()="\u02dc" or text()="\u223c" or text()="\uff5e"]'.split(","), +'Rule,undertilde,default,[n] children/*[1]; [t] "Tilde unten",self::underscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="underaccent"],children/*[2][text()="~" or text()="\u02dc" or text()="\u223c" or text()="\uff5e"]'.split(","),'Rule,matrix-fence,default,[n] children/*[1];,self::fenced,count(children/*)=1,name(children/*[1])="matrix"'.split(","),["Rule","matrix","default",'[t] "Anfang"; [t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Matrize"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Matrize"', +"self::matrix"],["Rule","matrix","sbrief",'[t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Matrize"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Matrize"',"self::matrix"],["Aliases","matrix","self::vector"],["Rule","matrix-row","default",'[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Spalte");[p] (pause: 200)',"self::row"],'Rule{row-with-label{default{[t] "mit Bezeichner"; [n] content/*[1]; [t] "Ende Bezeichner"(pause: 200); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Spalte"){self::row{content'.split("{"), +'Rule{row-with-label{brief{[t] "Bezeichner"; [n] content/*[1]; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Spalte"){self::row{content'.split("{"),["SpecializedRule","row-with-label","brief","sbrief"],'Rule{row-with-text-label{sbrief{[t] "Bezeichner"; [t] CSFRemoveParens;[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Spalte"){self::row{content{name(content/cell/children/*[1])="text"'.split("{"),'Rule;empty-row;default;[t] "Blank";self::row;count(children/*)=0'.split(";"),["Rule","matrix-cell", +"default","[n] children/*[1]; [p] (pause: 300)","self::cell"],'Rule,empty-cell,default,[t] "leer"; [p] (pause: 300),self::cell,count(children/*)=0'.split(","),'Rule{determinant{default{[t] "Anfang"; [t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Determinante"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Determinante"{self::matrix{@role="determinant"'.split("{"),["SpecializedRule","determinant","default","sbrief",'[t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Determinante"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Determinante"'], +'Rule{determinant-simple{default{[t] "Anfang"; [t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Determinante"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile",grammar:simpleDet); [t] "Ende Determinante"{self::matrix{@role="determinant"{CQFdetIsSimple'.split("{"),["SpecializedRule","determinant-simple","default","sbrief",'[t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Determinante"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile",grammar:simpleDet); [t] "Ende Determinante"'], +'Rule{row-simple{default{[m] children/*;{self::row{@role="determinant"{contains(@grammar, "simpleDet")'.split("{"),["Rule","layout","default",'[t] "Anfang Anordnung"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Anordnung"',"self::table"],["Rule","layout","sbrief",'[t] "Anordnung"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Anordnung"',"self::table"],'Rule,binomial,default,[t] "Anfang Binomialkoeffizient"; [n] children/*[2]/children/*[1]; [t] "aus"; [n] children/*[1]/children/*[1]; [t] "Ende Binomialkoeffizient",self::vector,@role="binomial"'.split(","), +'Rule,binomial,brief,[t] "Anfang Binomial"; [n] children/*[2]/children/*[1]; [t] "aus"; [n] children/*[1]/children/*[1]; [t] "Ende Binomial",self::vector,@role="binomial"'.split(","),'Rule,binomial,sbrief,[t] "Binomial"; [n] children/*[2]/children/*[1]; [t] "aus"; [n] children/*[1]/children/*[1]; [t] "Ende Binomial",self::vector,@role="binomial"'.split(","),["Rule","cases","default",'[t] "Anfang Fallunterscheidung"; [t] "gro\u00dfe"; [n] content/*[1];[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende Fallunterscheidung"', +"self::cases"],["Rule","cases","brief",'[t] "Anfang F\u00e4lle"; [t] "gro\u00dfe"; [n] content/*[1];[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende F\u00e4lle"',"self::cases"],["Rule","cases","sbrief",'[t] "F\u00e4lle"; [t] "gro\u00dfe"; [n] content/*[1];[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Zeile "); [t] "Ende F\u00e4lle"',"self::cases"],["Aliases","layout","self::multiline"],["Rule","line","default","[m] children/*","self::line"],'Rule,line-with-label,default,[t] "mit Bezeichner"; [n] content/*[1]; [t] "Ende Bezeichner" (pause: 200); [m] children/*,self::line,content'.split(","), +["SpecializedRule","line-with-label","default","brief",'[t] "Bezeichner"; [n] content/*[1] (pause: 200); [m] children/*'],["SpecializedRule","line-with-label","brief","sbrief"],'Rule,line-with-text-label,sbrief,[t] "Bezeichner"; [t] CSFRemoveParens; [m] children/*,self::line,content,name(content/cell/children/*[1])="text"'.split(","),'Rule;empty-line;default;[t] "leer";self::line;count(children/*)=0;not(content)'.split(";"),["SpecializedRule","empty-line","default","brief"],["SpecializedRule","empty-line", +"brief","sbrief"],'Rule,empty-line-with-label,default,[t] "mit Bezeichner"; [n] content/*[1]; [t] "Ende Bezeichner"(pause: 200); [t] "leer",self::line,count(children/*)=0,content'.split(","),["SpecializedRule","empty-line-with-label","default","brief",'[t] "Bezeichner"; [n] content/*[1] (pause: 200); [t] "leer"'],["SpecializedRule","empty-line-with-label","brief","sbrief"],["Rule","enclose","default",'[t] "Anfang Umschlie\u00dfung"; [t] @role (grammar:localEnclose); [n] children/*[1]; [t] "Ende Umschlie\u00dfung"', +"self::enclose"],["Aliases","overbar","self::enclose",'@role="top"'],["Aliases","underbar","self::enclose",'@role="bottom"'],'Rule,leftbar,default,[t] "senkrechter Strich"; [n] children/*[1],self::enclose,@role="left"'.split(","),'Rule,rightbar,default,[n] children/*[1]; [t] "senkrechter Strich",self::enclose,@role="right"'.split(","),'Rule,crossout,default,[t] "durchgestrichen"; [n] children/*[1]; [t] "Ende duchgestrichen",self::enclose,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","), +'Rule,cancel,default,[t] "durchgestrichen"; [n] children/*[1]/children/*[1]; [t] "mit"; [n] children/*[2]; [t] "Ende duchgestrichen",self::overscore,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","),["SpecializedRule","cancel","default","brief"],["SpecializedRule","cancel","default","sbrief"],["Aliases","cancel","self::underscore",'@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'],'Rule,cancel-reverse,default,[t] "durchgestrichen"; [n] children/*[2]/children/*[1]; [t] "mit"; [n] children/*[1]; [t] "Ende duchgestrichen",self::overscore,name(children/*[2])="enclose",children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'.split(","), +["SpecializedRule","cancel-reverse","default","brief"],["SpecializedRule","cancel-reverse","default","sbrief"],["Aliases","cancel-reverse","self::underscore",'name(children/*[2])="enclose"','children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'],'Rule;end-punct;default;[m] children/*;self::punctuated;@role="endpunct"'.split(";"),'Rule,start-punct,default,[n] content/*[1]; [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule,integral-punct,default,[n] children/*[1]; [n] children/*[3],self::punctuated,@role="integral"'.split(","), +["Rule","punctuated","default","[m] children/*","self::punctuated"],'Rule;unit;default;[t] text() (grammar:annotation="unit":translate:plural);self::identifier;@role="unit"'.split(";"),'Rule,unit-square,default,[t] "Quadrat"; [n] children/*[1],self::superscript,@role="unit",children/*[2][text()=2],name(children/*[1])="identifier"'.split(","),'Rule,unit-cubic,default,[t] "Kubik"; [n] children/*[1],self::superscript,@role="unit",children/*[2][text()=3],name(children/*[1])="identifier"'.split(","),'Rule,reciprocal,default,[n] children/*[1]; [t] "invers",self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],count(preceding-sibling::*)=0 or preceding-sibling::*[@role!="unit"]'.split(","), +'Rule,reciprocal,default,[t] "pro"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],preceding-sibling::*[@role="unit"]'.split(","),'Rule;unit-combine;default;[m] children/*;self::infixop;@role="unit"'.split(";"),'Rule,unit-divide,default,[n] children/*[1]; [t] "pro"; [n] children/*[2],self::fraction,@role="unit"'.split(","),["Rule","inference","default",'[t] "Schlussregel"; [m] content/*; [t] "mit Folgerung"; [n] children/*[1]; [t] "aus"; [t] count(children/*[2]/children/*); [t] "Pr\u00e4missen"', +"self::inference"],'Rule,inference,default,[t] "Schlussregel"; ; [m] content/*; [t] "mit Folgerung"; [n] children/*[1]; [t] "aus"; [t] count(children/*[2]/children/*); [t] "Pr\u00e4misse",self::inference,count(children/*[2]/children/*)<2'.split(","),["Rule","premise","default",'[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Pr\u00e4misse ");',"self::premises"],["Rule","conclusion","default","[n] children/*[1]","self::conclusion"],["Rule","label","default",'[t] "Regel"; [n] children/*[1]',"self::rulelabel"], +'Rule,axiom,default,[t] "Axiom"; [m] children/*[1];,self::inference,@role="axiom"'.split(","),'Rule,axiom,default,[t] "leeres Axiom";,self::empty,@role="axiom"'.split(",")],initialize:[sre.MathspeakUtil.generateTensorRules]};sre.MathspeakRules={domain:"mathspeak",functions:[["CQF","CQFspaceoutNumber",sre.MathspeakUtil.spaceoutNumber],["CQF","CQFspaceoutIdentifier",sre.MathspeakUtil.spaceoutIdentifier],["CSF","CSFspaceoutText",sre.MathspeakUtil.spaceoutText],["CSF","CSFopenFracVerbose",sre.MathspeakUtil.openingFractionVerbose],["CSF","CSFcloseFracVerbose",sre.MathspeakUtil.closingFractionVerbose],["CSF","CSFoverFracVerbose",sre.MathspeakUtil.overFractionVerbose],["CSF","CSFopenFracBrief",sre.MathspeakUtil.openingFractionBrief], +["CSF","CSFcloseFracBrief",sre.MathspeakUtil.closingFractionBrief],["CSF","CSFopenFracSbrief",sre.MathspeakUtil.openingFractionSbrief],["CSF","CSFcloseFracSbrief",sre.MathspeakUtil.closingFractionSbrief],["CSF","CSFoverFracSbrief",sre.MathspeakUtil.overFractionSbrief],["CSF","CSFvulgarFraction",sre.NumbersUtil.vulgarFraction],["CQF","CQFvulgarFractionSmall",sre.MathspeakUtil.isSmallVulgarFraction],["CSF","CSFopenRadicalVerbose",sre.MathspeakUtil.openingRadicalVerbose],["CSF","CSFcloseRadicalVerbose", +sre.MathspeakUtil.closingRadicalVerbose],["CSF","CSFindexRadicalVerbose",sre.MathspeakUtil.indexRadicalVerbose],["CSF","CSFopenRadicalBrief",sre.MathspeakUtil.openingRadicalBrief],["CSF","CSFcloseRadicalBrief",sre.MathspeakUtil.closingRadicalBrief],["CSF","CSFindexRadicalBrief",sre.MathspeakUtil.indexRadicalBrief],["CSF","CSFopenRadicalSbrief",sre.MathspeakUtil.openingRadicalSbrief],["CSF","CSFindexRadicalSbrief",sre.MathspeakUtil.indexRadicalSbrief],["CSF","CSFsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose], +["CSF","CSFsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFbaselineVerbose",sre.MathspeakUtil.baselineVerbose],["CSF","CSFbaselineBrief",sre.MathspeakUtil.baselineBrief],["CSF","CSFleftsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFleftsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFrightsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose], +["CSF","CSFrightsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFleftsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFleftsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFrightsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFrightsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFunderscript",sre.MathspeakUtil.nestedUnderscore],["CSF","CSFoverscript",sre.MathspeakUtil.nestedOverscore],["CTXF","CTXFordinalCounter",sre.NumbersUtil.ordinalCounter], +["CTXF","CTXFcontentIterator",sre.StoreUtil.contentIterator],["CQF","CQFdetIsSimple",sre.MathspeakUtil.determinantIsSimple],["CSF","CSFRemoveParens",sre.MathspeakUtil.removeParens],["CQF","CQFresetNesting",sre.MathspeakUtil.resetNestingDepth]],rules:['Rule{collapsed{default{[t] "collapsed"; [n] . (engine:modality=summary,grammar:collapsed){self::*{@alternative{not(contains(@grammar, "collapsed")){self::*{self::*{self::*{self::*{self::*'.split("{"),["SpecializedRule","collapsed","default","brief"], +["SpecializedRule","collapsed","brief","sbrief"],"Rule;stree;default;[n] ./*[1];self::stree;CQFresetNesting".split(";"),["Rule","unknown","default","[n] text()","self::unknown"],'Rule;protected;default;[t] text();self::number;contains(@grammar, "protected")'.split(";"),["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule;blank-empty;default;[t] "Blank";self::empty;count(../*)=1;name(../..)="cell" or name(../..)="line"'.split(";"),'Rule{font{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"), +'Rule{font-identifier-short{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{not(contains(@grammar, "ignoreFont")){@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1;@font;not(contains(@grammar, "ignoreFont"));@font="italic"'.split(";"),'Rule{german-font{default{[t] "German"; [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font="fraktur"'.split("{"), +'Rule{german-font{default{[t] "bold German"; [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font="bold-fraktur"'.split("{"),["Rule","number","default","[n] text()","self::number"],'Rule,mixed-number,default,[n] children/*[1]; [t] "and"; [n] children/*[2]; ,self::number,@role="mixed"'.split(","),'Rule{number-with-chars{default{[t] "Number"; [m] CQFspaceoutNumber (grammar:protected){self::number{@role="othernumber"{"" != translate(text(), "0123456789.,", ""){not(contains(@grammar, "protected"))'.split("{"), +["SpecializedRule","number-with-chars","default","brief",'[t] "Num"; [m] CQFspaceoutNumber (grammar:protected)'],["SpecializedRule","number-with-chars","brief","sbrief"],'Rule{number-as-upper-word{default{[t] "UpperWord"; [t] CSFspaceoutText{self::number{string-length(text())>1{text()=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9"){""=translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9","")'.split("{"), +["SpecializedRule","number-as-upper-word","default","brief"],["SpecializedRule","number-as-upper-word","default","sbrief"],'Rule{number-baseline{default{[t] "Baseline"; [n] . (grammar:baseline){self::number{not(contains(@grammar, "ignoreFont")){preceding-sibling::identifier{not(contains(@grammar, "baseline")){preceding-sibling::*[1][@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline","default", +"brief",'[t] "Base"; [n] . (grammar:baseline)'],["SpecializedRule","number-baseline","brief","sbrief"],'Rule{number-baseline-font{default{[t] "Baseline"; [t] @font; [n] . (grammar:ignoreFont=@font){self::number{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"{preceding-sibling::identifier{preceding-sibling::*[@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline-font","default","brief", +'[t] "Base"; [t] @font; [n] . (grammar:ignoreFont=@font)'],["SpecializedRule","number-baseline-font","brief","sbrief"],'Rule;identifier;default;[m] CQFspaceoutIdentifier;self::identifier;string-length(text())>1;@role!="unit";not(@font) or @font="normal" or contains(@grammar, "ignoreFont");text()!=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", "")'.split(";"), +["Rule","identifier","default","[n] text()","self::identifier"],'Rule,negative,default,[t] "negative"; [n] children/*[1],self::prefixop,@role="negative",children/identifier'.split(","),["Aliases","negative","self::prefixop",'@role="negative"',"children/number"],["Aliases","negative","self::prefixop",'@role="negative"','children/fraction[@role="vulgar"]'],'Rule,negative,default,[t] "minus"; [n] children/*[1],self::prefixop,@role="negative"'.split(","),["Rule","prefix","default","[m] content/*; [n] children/*[1]", +"self::prefixop"],["Rule","postfix","default","[n] children/*[1]; [m] content/*","self::postfixop"],["Rule","binary-operation","default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop"],'Rule;implicit;default;[m] children/*;self::infixop;@role="implicit"'.split(";"),["Aliases","implicit","self::infixop",'@role="leftsuper" or @role="leftsub" or @role="rightsuper" or @role="rightsub"'],'Rule,subtraction,default,[m] children/* (separator:"minus");,self::infixop,@role="subtraction"'.split(","), +["Rule","function-unknown","default","[n] children/*[1]; [n] children/*[2]","self::appl"],'Rule,function-prefix,default,[n] children/*[1]; [n] children/*[2],self::appl,children/*[1][@role="prefix function"]'.split(","),'Rule,fences-open-close,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="leftright"'.split(","),'Rule,fences-neutral,default,[t] "StartAbsoluteValue"; [n] children/*[1]; [t] "EndAbsoluteValue",self::fenced,@role="neutral",content/*[1][text()]="|" or content/*[1][text()]="\u2758" or content/*[1][text()]="\uff5c"'.split(","), +["SpecializedRule","fences-neutral","default","sbrief",'[t] "AbsoluteValue"; [n] children/*[1]; [t] "EndAbsoluteValue"'],'Rule,fences-neutral,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="neutral"'.split(","),'Rule,fences-set,default,[t] "StartSet"; [n] children/*[1]; [t] "EndSet",self::fenced,@role="set empty" or @role="set extended" or @role="set singleton" or @role="set collection",not(name(../..)="appl")'.split(","),["SpecializedRule","fences-set","default", +"sbrief",'[t] "Set"; [n] children/*[1]; [t] "EndSet"'],["Rule","text","default","[n] text()","self::text"],'Rule;factorial;default;[t] "factorial";self::punctuation;text()="!";name(preceding-sibling::*[1])!="text"'.split(";"),'Rule;minus;default;[t] "minus";self::operator;text()="-"'.split(";"),'Rule;single-prime;default;[t] "prime";self::punctuated;@role="prime";count(children/*)=1'.split(";"),'Rule;double-prime;default;[t] "double prime";self::punctuated;@role="prime";count(children/*)=2'.split(";"), +'Rule;triple-prime;default;[t] "triple prime";self::punctuated;@role="prime";count(children/*)=3'.split(";"),'Rule;quadruple-prime;default;[t] "quadruple prime";self::punctuated;@role="prime";count(children/*)=4'.split(";"),'Rule,counted-prime,default,[t] count(children/*); [t] "prime",self::punctuated,@role="prime"'.split(","),["Rule","fraction","default","[t] CSFopenFracVerbose; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracVerbose","self::fraction"],["Rule","fraction", +"brief","[t] CSFopenFracBrief; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracBrief","self::fraction"],["Rule","fraction","sbrief","[t] CSFopenFracSbrief; [n] children/*[1]; [t] CSFoverFracSbrief; [n] children/*[2]; [t] CSFcloseFracSbrief","self::fraction"],'Rule;vulgar-fraction;default;[t] CSFvulgarFraction;self::fraction;@role="vulgar";CQFvulgarFractionSmall'.split(";"),["SpecializedRule","vulgar-fraction","default","brief"],["SpecializedRule","vulgar-fraction","default", +"sbrief"],'Rule,continued-fraction-outer,default,[t] "ContinuedFraction"; [n] children/*[1];[t] "Over"; [n] children/*[2],self::fraction,not(ancestor::fraction),children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","),["SpecializedRule","continued-fraction-outer","default","brief",'[t] "ContinuedFrac"; [n] children/*[1];[t] "Over"; [n] children/*[2]'],["SpecializedRule","continued-fraction-outer","brief","sbrief"],'Rule,continued-fraction-inner,default,[t] "StartFraction"; [n] children/*[1];[t] "Over"; [n] children/*[2],self::fraction,ancestor::fraction,children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","), +["SpecializedRule","continued-fraction-inner","default","brief",'[t] "StartFrac"; [n] children/*[1];[t] "Over"; [n] children/*[2]'],["SpecializedRule","continued-fraction-inner","brief","sbrief",'[t] "Frac"; [n] children/*[1];[t] "Over"; [n] children/*[2]'],["Rule","sqrt","default","[t] CSFopenRadicalVerbose; [n] children/*[1]; [t] CSFcloseRadicalVerbose","self::sqrt"],["Rule","sqrt","brief","[t] CSFopenRadicalBrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],["Rule","sqrt","sbrief", +"[t] CSFopenRadicalSbrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],["Rule","root","default","[t] CSFindexRadicalVerbose; [n] children/*[1];[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose","self::root"],["Rule","root","brief","[t] CSFindexRadicalBrief; [n] children/*[1];[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root"],["Rule","root","sbrief","[t] CSFindexRadicalSbrief; [n] children/*[1];[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief", +"self::root"],'Rule,limboth,default,[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3],self::limboth,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Rule,limlower,default,[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];,self::limlower,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","), +'Rule,limupper,default,[n] children/*[1]; [t] CSFoverscript; [n] children/*[2];,self::limupper,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Aliases;limlower;self::underscore;@role="limit function";name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),'Aliases;limlower;self::underscore;children/*[2][@role!="underaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"), +'Aliases;limupper;self::overscore;children/*[2][@role!="overaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),["Rule","limboth-end","default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3]; [t] "Endscripts"',"self::limboth"],["Rule","limlower-end","default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2]; [t] "Endscripts"',"self::limlower"],["Rule","limupper-end", +"default",'[n] children/*[1]; [t] CSFoverscript; [n] children/*[2]; [t] "Endscripts"',"self::limupper"],["Aliases","limlower-end","self::underscore",'@role="limit function"'],["Aliases","limlower-end","self::underscore"],["Aliases","limupper-end","self::overscore"],["Rule","integral","default","[n] children/*[1]; [n] children/*[2]; [n] children/*[3];","self::integral"],'Rule,integral,default,[n] children/*[1]; [t] "Subscript"; [n] children/*[2];[t] "Superscript"; [n] children/*[3]; [t] "Baseline";,self::limboth,@role="integral"'.split(","), +["SpecializedRule","integral","default","brief",'[n] children/*[1]; [t] "Sub"; [n] children/*[2];[t] "Sup"; [n] children/*[3]; [t] "Base";'],["SpecializedRule","integral","brief","sbrief"],["Rule","bigop","default","[n] children/*[1]; [n] children/*[2];","self::bigop"],["Rule","relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],'Rule,equality,default,[n] children/*[1]; [n] content/*[1]; [n] children/*[2],self::relseq,@role="equality",count(./children/*)=2'.split(","), +'Rule;multi-equality;default;[m] children/* (sepFunc:CTXFcontentIterator);self::relseq;@role="equality";count(./children/*)>2'.split(";"),["Rule","multrel","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::multirel"],["Rule","subscript","default","[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]","self::subscript"],["Rule","subscript","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]","self::subscript"],["SpecializedRule","subscript","brief","sbrief"], +'Rule,subscript-simple,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(./children/*[1])="identifier",name(./children/*[2])="number",./children/*[2][@role!="mixed"],./children/*[2][@role!="othernumber"]'.split(","),["SpecializedRule","subscript-simple","default","brief"],["SpecializedRule","subscript-simple","default","sbrief"],'Rule,subscript-baseline,default,[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]; [t] CSFbaselineVerbose,self::subscript,following-sibling::*,not(name(following-sibling::subscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="subscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and @role!="subsup",not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","subscript-baseline","default","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]; [t] CSFbaselineBrief"],["SpecializedRule","subscript-baseline","brief","sbrief"],'Aliases;subscript-baseline;self::subscript;not(following-sibling::*);ancestor::fenced|ancestor::root|ancestor::sqrt|ancestor::punctuated|ancestor::fraction;not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","subscript-baseline", +"self::subscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel",sre.MathspeakUtil.generateBaselineConstraint()],["Aliases","subscript-baseline","self::subscript","not(following-sibling::*)","@embellished"],'Rule,subscript-empty-sup,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="superscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","),["SpecializedRule","subscript-empty-sup", +"default","brief"],["SpecializedRule","subscript-empty-sup","brief","sbrief"],["Aliases","subscript-empty-sup","self::subscript",'name(children/*[2])="superscript"','name(children/*[2]/children/*[1])="empty"'],["Rule","superscript","default","[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2]","self::superscript"],["SpecializedRule","superscript","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2]"],["SpecializedRule","superscript","brief","sbrief"],'Rule,superscript-baseline,default,[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2];[t] CSFbaselineVerbose,self::superscript,following-sibling::*,not(name(following-sibling::superscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="superscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","superscript-baseline","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2];[t] CSFbaselineBrief"],["SpecializedRule","superscript-baseline","brief","sbrief"],'Aliases;superscript-baseline;self::superscript;not(following-sibling::*);ancestor::punctuated;ancestor::*/following-sibling::* and not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","superscript-baseline","self::superscript", +"not(following-sibling::*)","ancestor::fraction|ancestor::fenced|ancestor::root|ancestor::sqrt"],["Aliases","superscript-baseline","self::superscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel","not(@embellished)",sre.MathspeakUtil.generateBaselineConstraint()],'Aliases superscript-baseline self::superscript not(following-sibling::*) @embellished not(children/*[2][@role="prime"])'.split(" "),'Rule,superscript-empty-sub,default,[n] children/*[1]; [n] children/*[2],self::superscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="subscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","), +["SpecializedRule","superscript-empty-sub","default","brief"],["SpecializedRule","superscript-empty-sub","brief","sbrief"],["Aliases","superscript-empty-sub","self::superscript",'name(children/*[2])="subscript"','name(children/*[2]/children/*[1])="empty"'],'Rule,square,default,[n] children/*[1]; [t] "squared",self::superscript,children/*[2],children/*[2][text()=2],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","square","default","brief"],["SpecializedRule","square","default","sbrief"],'Aliases;square;self::superscript;children/*[2];children/*[2][text()=2];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,cube,default,[n] children/*[1]; [t] "cubed",self::superscript,children/*[2],children/*[2][text()=3],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","cube","default","brief"],["SpecializedRule","cube","default","sbrief"],'Aliases;cube;self::superscript;children/*[2];children/*[2][text()=3];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,prime,default,[n] children/*[1]; [n] children/*[2],self::superscript,children/*[2],children/*[2][@role="prime"]'.split(","),["SpecializedRule","prime","default","brief"],["SpecializedRule","prime","default","sbrief"],'Rule,prime-subscript,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",not(following-sibling::*)'.split(","), +["SpecializedRule","prime-subscript","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]"],["SpecializedRule","prime-subscript","brief","sbrief"],'Rule,prime-subscript-baseline,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2]; [t] CSFbaselineVerbose,self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",following-sibling::*'.split(","), +["SpecializedRule","prime-subscript-baseline","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]; [t] CSFbaselineBrief"],["SpecializedRule","prime-subscript-baseline","brief","sbrief"],'Aliases prime-subscript-baseline self::superscript children/*[2][@role="prime"] name(children/*[1])="subscript" not(following-sibling::*) @embellished'.split(" "),'Rule,prime-subscript-simple,default,[n] children/*[1]/children/*[1]; [n] children/*[2];[n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",name(children/*[1]/children/*[1])="identifier",name(children/*[1]/children/*[2])="number",children/*[1]/children/*[2][@role!="mixed"],children/*[1]/children/*[2][@role!="othernumber"]'.split(","), +["SpecializedRule","prime-subscript-simple","default","brief"],["SpecializedRule","prime-subscript-simple","default","sbrief"],'Rule,overscore,default,[t] "ModifyingAbove"; [n] children/*[1]; [t] "With"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"]'.split(","),["SpecializedRule","overscore","default","brief",'[t] "ModAbove"; [n] children/*[1]; [t] "With"; [n] children/*[2]'],["SpecializedRule","overscore","brief","sbrief"],'Rule,double-overscore,default,[t] "ModifyingAbove Above"; [n] children/*[1]; [t] "With"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"],name(children/*[1])="overscore",children/*[1]/children/*[2][@role="overaccent"]'.split(","), +["SpecializedRule","double-overscore","default","brief",'[t] "ModAbove Above"; [n] children/*[1]; [t] "With"; [n] children/*[2]'],["SpecializedRule","double-overscore","brief","sbrief"],'Rule,underscore,default,[t] "ModifyingBelow"; [n] children/*[1]; [t] "With"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"]'.split(","),["SpecializedRule","underscore","default","brief",'[t] "ModBelow"; [n] children/*[1]; [t] "With"; [n] children/*[2]'],["SpecializedRule","underscore","brief", +"sbrief"],'Rule,double-underscore,default,[t] "ModifyingBelow Below"; [n] children/*[1]; [t] "With"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"],name(children/*[1])="underscore",children/*[1]/children/*[2][@role="underaccent"]'.split(","),["SpecializedRule","double-underscore","default","brief",'[t] "ModBelow Below"; [n] children/*[1]; [t] "With"; [n] children/*[2]'],["SpecializedRule","double-underscore","brief","sbrief"],'Rule,overbar,default,[n] children/*[1]; [t] "overbar",self::overscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="overaccent"],children/*[2][text()="\u00af" or text()="\uffe3" or text()="\uff3f" or text()="_" or text()="\u203e"]'.split(","), +["SpecializedRule","overbar","default","brief",'[n] children/*[1]; [t] "overBar"'],["SpecializedRule","overbar","brief","sbrief"],'Rule,underbar,default,[n] children/*[1]; [t] "underbar",self::underscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="underaccent"],children/*[2][text()="\u00af" or text()="\uffe3" or text()="\uff3f" or text()="_" or text()="\u203e"]'.split(","),["SpecializedRule","underbar","default","brief",'[n] children/*[1]; [t] "underBar"'], +["SpecializedRule","underbar","brief","sbrief"],'Rule,overtilde,default,[n] children/*[1]; [t] "overTilde",self::overscore,children/*[2][@role="overaccent"],@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][text()="~" or text()="\u02dc" or text()="\u223c" or text()="\uff5e"]'.split(","),["SpecializedRule","overtilde","default","brief",'[n] children/*[1]; [t] "overtilde"'],["SpecializedRule","overtilde","brief","sbrief"],'Rule,undertilde,default,[n] children/*[1]; [t] "underTilde",self::underscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="underaccent"],children/*[2][text()="~" or text()="\u02dc" or text()="\u223c" or text()="\uff5e"]'.split(","), +["SpecializedRule","undertilde","default","brief",'[n] children/*[1]; [t] "undertilde"'],["SpecializedRule","undertilde","brief","sbrief"],'Rule,matrix-fence,default,[n] children/*[1];,self::fenced,count(children/*)=1,name(children/*[1])="matrix"'.split(","),["Rule","matrix","default",'[t] "Start"; [t] count(children/*); [t] "By";[t] count(children/*[1]/children/*); [t] "Matrix"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndMatrix"',"self::matrix"],["Rule","matrix","sbrief", +'[t] count(children/*); [t] "By";[t] count(children/*[1]/children/*); [t] "Matrix"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndMatrix"',"self::matrix"],["Aliases","matrix","self::vector"],["Rule","matrix-row","default",'[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Column");[p] (pause: 200)',"self::row"],'Rule{row-with-label{default{[t] "with Label"; [n] content/*[1]; [t] "EndLabel"(pause: 200); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Column"){self::row{content'.split("{"), +'Rule{row-with-label{brief{[t] "Label"; [n] content/*[1]; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Column"){self::row{content'.split("{"),["SpecializedRule","row-with-label","brief","sbrief"],'Rule{row-with-text-label{sbrief{[t] "Label"; [t] CSFRemoveParens;[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Column"){self::row{content{name(content/cell/children/*[1])="text"'.split("{"),'Rule;empty-row;default;[t] "Blank";self::row;count(children/*)=0'.split(";"),["Rule","matrix-cell", +"default","[n] children/*[1]; [p] (pause: 300)","self::cell"],'Rule,empty-cell,default,[t] "Blank"; [p] (pause: 300),self::cell,count(children/*)=0'.split(","),'Rule{determinant{default{[t] "Start"; [t] count(children/*); [t] "By";[t] count(children/*[1]/children/*); [t] "Determinant"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndDeterminant"{self::matrix{@role="determinant"'.split("{"),["SpecializedRule","determinant","default","sbrief",'[t] count(children/*); [t] "By";[t] count(children/*[1]/children/*); [t] "Determinant"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndDeterminant"'], +'Rule{determinant-simple{default{[t] "Start"; [t] count(children/*); [t] "By";[t] count(children/*[1]/children/*); [t] "Determinant"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row",grammar:simpleDet); [t] "EndDeterminant"{self::matrix{@role="determinant"{CQFdetIsSimple'.split("{"),["SpecializedRule","determinant-simple","default","sbrief",'[t] count(children/*); [t] "By";[t] count(children/*[1]/children/*); [t] "Determinant"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row",grammar:simpleDet); [t] "EndDeterminant"'], +'Rule{row-simple{default{[m] children/*;{self::row{@role="determinant"{contains(@grammar, "simpleDet")'.split("{"),["Rule","layout","default",'[t] "StartLayout"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndLayout"',"self::table"],["Rule","layout","sbrief",'[t] "Layout"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndLayout"',"self::table"],'Rule,binomial,default,[t] "StartBinomialOrMatrix"; [n] children/*[1]/children/*[1]; [t] "Choose"; [n] children/*[2]/children/*[1]; [t] "EndBinomialOrMatrix",self::vector,@role="binomial"'.split(","), +'Rule,binomial,sbrief,[t] "BinomialOrMatrix"; [n] children/*[1]/children/*[1]; [t] "Choose"; [n] children/*[2]/children/*[1]; [t] "EndBinomialOrMatrix",self::vector,@role="binomial"'.split(","),["Rule","cases","default",'[t] "StartLayout"; [t] "Enlarged"; [n] content/*[1];[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndLayout"',"self::cases"],["Rule","cases","sbrief",'[t] "Layout"; [t] "Enlarged"; [n] content/*[1];[m] children/* (ctxtFunc:CTXFordinalCounter,context:"Row "); [t] "EndLayout"', +"self::cases"],["Aliases","layout","self::multiline"],["Rule","line","default","[m] children/*","self::line"],'Rule,line-with-label,default,[t] "with Label"; [n] content/*[1]; [t] "EndLabel" (pause: 200); [m] children/*,self::line,content'.split(","),["SpecializedRule","line-with-label","default","brief",'[t] "Label"; [n] content/*[1] (pause: 200); [m] children/*'],["SpecializedRule","line-with-label","brief","sbrief"],'Rule,line-with-text-label,sbrief,[t] "Label"; [t] CSFRemoveParens; [m] children/*,self::line,content,name(content/cell/children/*[1])="text"'.split(","), +'Rule;empty-line;default;[t] "Blank";self::line;count(children/*)=0;not(content)'.split(";"),["SpecializedRule","empty-line","default","brief"],["SpecializedRule","empty-line","brief","sbrief"],'Rule,empty-line-with-label,default,[t] "with Label"; [n] content/*[1]; [t] "EndLabel"(pause: 200); [t] "Blank",self::line,count(children/*)=0,content'.split(","),["SpecializedRule","empty-line-with-label","default","brief",'[t] "Label"; [n] content/*[1] (pause: 200); [t] "Blank"'],["SpecializedRule","empty-line-with-label", +"brief","sbrief"],["Rule","enclose","default",'[t] "StartEnclose"; [t] @role (grammar:localEnclose); [n] children/*[1]; [t] "EndEnclose"',"self::enclose"],["Aliases","overbar","self::enclose",'@role="top"'],["Aliases","underbar","self::enclose",'@role="bottom"'],'Rule,leftbar,default,[t] "vertical bar"; [n] children/*[1],self::enclose,@role="left"'.split(","),'Rule,rightbar,default,[n] children/*[1]; [t] "vertical bar",self::enclose,@role="right"'.split(","),'Rule,crossout,default,[t] "CrossOut"; [n] children/*[1]; [t] "EndCrossOut",self::enclose,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","), +'Rule,cancel,default,[t] "CrossOut"; [n] children/*[1]/children/*[1]; [t] "With"; [n] children/*[2]; [t] "EndCrossOut",self::overscore,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","),["SpecializedRule","cancel","default","brief"],["SpecializedRule","cancel","default","sbrief"],["Aliases","cancel","self::underscore",'@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'],'Rule,cancel-reverse,default,[t] "CrossOut"; [n] children/*[2]/children/*[1]; [t] "With"; [n] children/*[1]; [t] "EndCrossOut",self::overscore,name(children/*[2])="enclose",children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'.split(","), +["SpecializedRule","cancel-reverse","default","brief"],["SpecializedRule","cancel-reverse","default","sbrief"],["Aliases","cancel-reverse","self::underscore",'name(children/*[2])="enclose"','children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'],'Rule;end-punct;default;[m] children/*;self::punctuated;@role="endpunct"'.split(";"),'Rule,start-punct,default,[n] content/*[1]; [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule,integral-punct,default,[n] children/*[1]; [n] children/*[3],self::punctuated,@role="integral"'.split(","), +["Rule","punctuated","default","[m] children/*","self::punctuated"],'Rule;unit;default;[t] text() (grammar:annotation="unit":translate:plural);self::identifier;@role="unit"'.split(";"),'Rule;unit-combine;default;[m] children/*;self::infixop;@role="unit"'.split(";"),'Rule,unit-divide,default,[n] children/*[1]; [t] "per"; [n] children/*[2],self::fraction,@role="unit"'.split(","),["Rule","inference","default",'[t] "inference rule"; [m] content/*; [t] "with conclusion"; [n] children/*[1]; [t] "and"; [t] count(children/*[2]/children/*); [t] "premises"', +"self::inference"],'Rule,inference,default,[t] "inference rule"; ; [m] content/*; [t] "with conclusion"; [n] children/*[1]; [t] "and"; [t] count(children/*[2]/children/*); [t] "premise",self::inference,count(children/*[2]/children/*)<2'.split(","),["Rule","premise","default",'[m] children/* (ctxtFunc:CTXFordinalCounter,context:"premise ");',"self::premises"],["Rule","conclusion","default","[n] children/*[1]","self::conclusion"],["Rule","label","default",'[t] "label"; [n] children/*[1]',"self::rulelabel"], +'Rule,axiom,default,[t] "axiom"; [m] children/*[1];,self::inference,@role="axiom"'.split(","),'Rule,axiom,default,[t] "empty axiom";,self::empty,@role="axiom"'.split(",")],initialize:[sre.MathspeakUtil.generateTensorRules]};sre.MathspeakSpanishUtil={};sre.MathspeakSpanishUtil.ordinalCounter=function(a,b){var c=0;return function(){return sre.Messages.NUMBERS.numberToOrdinal(++c,!1)+" "+b}};sre.MathspeakSpanishUtil.smallRoot=function(a){if(!a.childNodes||0===a.childNodes.length||!a.childNodes[0].childNodes)return[];var b=a.childNodes[0].childNodes[0].textContent;if(!/^\d+$/.test(b))return[];b=parseInt(b,10);return 1=b?[a]:[]};sre.UnitUtil={};sre.UnitUtil.unitMultipliers=function(a,b){var c=0;return function(){var d=sre.AuditoryDescription.create({text:sre.UnitUtil.rightMostUnit(a[c])&&sre.UnitUtil.leftMostUnit(a[c+1])?sre.Messages.UNIT_TIMES:""},{});c++;return[d]}};sre.UnitUtil.SCRIPT_ELEMENTS=[sre.SemanticAttr.Type.SUPERSCRIPT,sre.SemanticAttr.Type.SUBSCRIPT,sre.SemanticAttr.Type.OVERSCORE,sre.SemanticAttr.Type.UNDERSCORE]; +sre.UnitUtil.rightMostUnit=function(a){for(;a;){if("unit"===a.getAttribute("role"))return!0;var b=a.tagName;a=sre.XpathUtil.evalXPath("children/*",a);a=-1!==sre.UnitUtil.SCRIPT_ELEMENTS.indexOf(b)?a[0]:a[a.length-1]}return!1};sre.UnitUtil.leftMostUnit=function(a){for(;a;){if("unit"===a.getAttribute("role"))return!0;a=sre.XpathUtil.evalXPath("children/*",a)[0]}return!1}; +sre.UnitUtil.oneLeft=function(a){for(;a;){if("number"===a.tagName&&"1"===a.textContent)return[a];if("infixop"!==a.tagName||"multiplication"!==a.getAttribute("role")&&"implicit"!==a.getAttribute("role"))break;a=sre.XpathUtil.evalXPath("children/*",a)[0]}return[]};sre.MathspeakSpanish={locale:"es",domain:"mathspeak",functions:[["CQF","CQFspaceoutNumber",sre.MathspeakUtil.spaceoutNumber],["CQF","CQFspaceoutIdentifier",sre.MathspeakUtil.spaceoutIdentifier],["CSF","CSFspaceoutText",sre.MathspeakUtil.spaceoutText],["CSF","CSFopenFracVerbose",sre.MathspeakUtil.openingFractionVerbose],["CSF","CSFcloseFracVerbose",sre.MathspeakUtil.closingFractionVerbose],["CSF","CSFoverFracVerbose",sre.MathspeakUtil.overFractionVerbose],["CSF","CSFopenFracBrief",sre.MathspeakUtil.openingFractionBrief], +["CSF","CSFcloseFracBrief",sre.MathspeakUtil.closingFractionBrief],["CSF","CSFopenFracSbrief",sre.MathspeakUtil.openingFractionSbrief],["CSF","CSFcloseFracSbrief",sre.MathspeakUtil.closingFractionSbrief],["CSF","CSFoverFracSbrief",sre.MathspeakUtil.overFractionSbrief],["CSF","CSFopenRadicalVerbose",sre.MathspeakUtil.openingRadicalVerbose],["CSF","CSFcloseRadicalVerbose",sre.MathspeakUtil.closingRadicalVerbose],["CSF","CSFindexRadicalVerbose",sre.MathspeakUtil.indexRadicalVerbose],["CSF","CSFopenRadicalBrief", +sre.MathspeakUtil.openingRadicalBrief],["CSF","CSFcloseRadicalBrief",sre.MathspeakUtil.closingRadicalBrief],["CSF","CSFindexRadicalBrief",sre.MathspeakUtil.indexRadicalBrief],["CSF","CSFopenRadicalSbrief",sre.MathspeakUtil.openingRadicalSbrief],["CSF","CSFindexRadicalSbrief",sre.MathspeakUtil.indexRadicalSbrief],["CQF","CQFisSmallRoot",sre.MathspeakSpanishUtil.smallRoot],["CSF","CSFsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFsuperscriptBrief",sre.MathspeakUtil.superscriptBrief], +["CSF","CSFsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFbaselineVerbose",sre.MathspeakUtil.baselineVerbose],["CSF","CSFbaselineBrief",sre.MathspeakUtil.baselineBrief],["CSF","CSFleftsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFleftsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFrightsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFrightsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose], +["CSF","CSFleftsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFleftsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFrightsuperscriptBrief",sre.MathspeakUtil.superscriptBrief],["CSF","CSFrightsubscriptBrief",sre.MathspeakUtil.subscriptBrief],["CSF","CSFunderscript",sre.MathspeakUtil.nestedUnderscore],["CSF","CSFoverscript",sre.MathspeakUtil.nestedOverscore],["CTXF","CTXFordinalCounter",sre.MathspeakSpanishUtil.ordinalCounter],["CTXF","CTXFcontentIterator",sre.StoreUtil.contentIterator], +["CTXF","CTXFunitMultipliers",sre.UnitUtil.unitMultipliers],["CQF","CQFdetIsSimple",sre.MathspeakUtil.determinantIsSimple],["CSF","CSFRemoveParens",sre.MathspeakUtil.removeParens],["CQF","CQFoneLeft",sre.UnitUtil.oneLeft],["CQF","CQFresetNesting",sre.MathspeakUtil.resetNestingDepth]],rules:['Rule{collapsed{default{[n] . (engine:modality=summary,grammar:collapsed); [t] "plegado";{self::*{@alternative{not(contains(@grammar, "collapsed")){self::*{self::*{self::*{self::*{self::*'.split("{"),["SpecializedRule", +"collapsed","default","brief"],["SpecializedRule","collapsed","brief","sbrief"],"Rule;stree;default;[n] ./*[1];self::stree;CQFresetNesting".split(";"),["Rule","unknown","default","[n] text()","self::unknown"],'Rule;protected;default;[t] text();self::number;contains(@grammar, "protected")'.split(";"),["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule;blank-empty;default;[t] "espacio";self::empty;count(../*)=1;name(../..)="cell" or name(../..)="line"'.split(";"),'Rule{font{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"), +'Rule{font-identifier-short{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{not(contains(@grammar, "ignoreFont")){@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1;@font;not(contains(@grammar, "ignoreFont"));@font="italic"'.split(";"),["Rule","number","default","[n] text()","self::number"],'Rule,mixed-number,default,[n] children/*[1]; [t] "m\u00e1s"; [n] children/*[2]; ,self::number,@role="mixed"'.split(","), +'Rule{number-with-chars{default{[t] "n\u00famero"; [m] CQFspaceoutNumber (grammar:protected){self::number{@role="othernumber"{"" != translate(text(), "0123456789.,", ""){not(contains(@grammar, "protected"))'.split("{"),["SpecializedRule","number-with-chars","default","brief",'[t] "n\u00fam"; [m] CQFspaceoutNumber (grammar:protected)'],["SpecializedRule","number-with-chars","brief","sbrief"],'Rule{number-as-upper-word{default{[t] "may\u00fascula"; [t] CSFspaceoutText{self::number{string-length(text())>1{text()=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9"){""=translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9","")'.split("{"), +["SpecializedRule","number-as-upper-word","default","brief"],["SpecializedRule","number-as-upper-word","default","sbrief"],'Rule{number-baseline{default{[t] "l\u00ednea base"; [n] . (grammar:baseline){self::number{not(contains(@grammar, "ignoreFont")){preceding-sibling::identifier{not(contains(@grammar, "baseline")){preceding-sibling::*[1][@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline", +"default","brief",'[t] "base"; [n] text()'],["SpecializedRule","number-baseline","brief","sbrief"],'Rule{number-baseline-font{default{[t] "l\u00ednea base"; [t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::number{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"{preceding-sibling::identifier{preceding-sibling::*[@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),["SpecializedRule","number-baseline-font", +"default","brief",'[t] "base"; [t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font)'],["SpecializedRule","number-baseline-font","brief","sbrief"],'Rule;identifier;default;[m] CQFspaceoutIdentifier;self::identifier;string-length(text())>1;@role!="unit";not(@font) or @font="normal" or contains(@grammar, "ignoreFont");text()!=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", "")'.split(";"), +["Rule","identifier","default","[n] text()","self::identifier"],'Rule,negative,default,[t] "menos"; [n] children/*[1],self::prefixop,@role="negative",children/identifier'.split(","),["Aliases","negative","self::prefixop",'@role="negative"',"children/number"],["Aliases","negative","self::prefixop",'@role="negative"','children/fraction[@role="vulgar"]'],'Rule,negative,default,[t] "menos"; [n] children/*[1],self::prefixop,@role="negative"'.split(","),["Rule","prefix","default","[m] content/*; [n] children/*[1]", +"self::prefixop"],["Rule","postfix","default","[n] children/*[1]; [m] content/*","self::postfixop"],["Rule","binary-operation","default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop"],'Rule;implicit;default;[m] children/*;self::infixop;@role="implicit"'.split(";"),["Aliases","implicit","self::infixop",'@role="leftsuper" or @role="leftsub" or @role="rightsuper" or @role="rightsub"'],'Rule,subtraction,default,[m] children/* (separator:"menos");,self::infixop,@role="subtraction"'.split(","), +["Rule","function-unknown","default","[n] children/*[1]; [n] children/*[2]","self::appl"],'Rule,function-prefix,default,[n] children/*[1]; [n] children/*[2],self::appl,children/*[1][@role="prefix function"]'.split(","),'Rule,fences-open-close,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="leftright"'.split(","),'Rule,fences-neutral,default,[t] "empezar valor absoluto"; [n] children/*[1]; [t] "finalizar valor absoluto",self::fenced,@role="neutral",content/*[1][text()]="|" or content/*[1][text()]="\u2758" or content/*[1][text()]="\uff5c"'.split(","), +["SpecializedRule","fences-neutral","default","sbrief",'[t] "valor absoluto"; [n] children/*[1]; [t] "finalizar valor absoluto"'],'Rule,fences-neutral,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="neutral"'.split(","),'Rule,fences-set,default,[t] "empezar llave"; [n] children/*[1]; [t] "finalizar llave",self::fenced,@role="set empty" or @role="set extended" or @role="set singleton" or @role="set collection",not(name(../..)="appl")'.split(","),["SpecializedRule", +"fences-set","default","sbrief",'[t] "llave"; [n] children/*[1]; [t] "finalizar llave"'],["Rule","text","default","[n] text() (grammar:noTranslateText)","self::text"],'Rule;factorial;default;[t] "factorial";self::punctuation;text()="!";name(preceding-sibling::*[1])!="text"'.split(";"),'Rule;minus;default;[t] "menos";self::operator;text()="-"'.split(";"),'Rule;single-prime;default;[t] "prima";self::punctuated;@role="prime";count(children/*)=1'.split(";"),'Rule;double-prime;default;[t] "doble prima";self::punctuated;@role="prime";count(children/*)=2'.split(";"), +'Rule;triple-prime;default;[t] "triple prima";self::punctuated;@role="prime";count(children/*)=3'.split(";"),'Rule;quadruple-prime;default;[t] "cuadruplicar prima";self::punctuated;@role="prime";count(children/*)=4'.split(";"),'Rule,counted-prime,default,[t] count(children/*); [t] "prime",self::punctuated,@role="prime"'.split(","),["Rule","fraction","default","[t] CSFopenFracVerbose; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracVerbose","self::fraction"],["Rule","fraction", +"brief","[t] CSFopenFracBrief; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracBrief","self::fraction"],["Rule","fraction","sbrief","[t] CSFopenFracSbrief; [n] children/*[1]; [t] CSFoverFracSbrief; [n] children/*[2]; [t] CSFcloseFracSbrief","self::fraction"],'Rule,continued-fraction-outer,default,[t] "fracci\u00f3n continua"; [n] children/*[1];[t] "entre"; [n] children/*[2],self::fraction,not(ancestor::fraction),children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","), +["SpecializedRule","continued-fraction-outer","default","brief",'[t] "frac continua"; [n] children/*[1];[t] "entre"; [n] children/*[2]'],["SpecializedRule","continued-fraction-outer","brief","sbrief"],'Rule,continued-fraction-inner,default,[t] "empezar fracci\u00f3n"; [n] children/*[1];[t] "entre"; [n] children/*[2],self::fraction,ancestor::fraction,children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]'.split(","),["SpecializedRule","continued-fraction-inner","default", +"brief",'[t] "empezar frac"; [n] children/*[1];[t] "entre"; [n] children/*[2]'],["SpecializedRule","continued-fraction-inner","brief","sbrief",'[t] "frac"; [n] children/*[1];[t] "entre"; [n] children/*[2]'],["Rule","sqrt","default","[t] CSFopenRadicalVerbose; [n] children/*[1]; [t] CSFcloseRadicalVerbose","self::sqrt"],["Rule","sqrt","brief","[t] CSFopenRadicalBrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt"],["Rule","sqrt","sbrief","[t] CSFopenRadicalSbrief; [n] children/*[1]; [t] CSFcloseRadicalBrief", +"self::sqrt"],"Rule,root-small,default,[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose,self::root,CQFisSmallRoot".split(","),"Rule,root-small,brief,[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief,self::root,CQFisSmallRoot".split(","),"Rule,root-small,sbrief,[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief,self::root,CQFisSmallRoot".split(","),["Rule","root","default","[t] CSFindexRadicalVerbose; [n] children/*[1];[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose", +"self::root"],["Rule","root","brief","[t] CSFindexRadicalBrief; [n] children/*[1];[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root"],["Rule","root","sbrief","[t] CSFindexRadicalSbrief; [n] children/*[1];[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root"],'Rule,limboth,default,[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3],self::limboth,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","), +'Rule,limlower,default,[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];,self::limlower,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Rule,limupper,default,[n] children/*[1]; [t] CSFoverscript; [n] children/*[2];,self::limupper,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Aliases;limlower;self::underscore;@role="limit function";name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"), +'Aliases;limlower;self::underscore;children/*[2][@role!="underaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),'Aliases;limupper;self::overscore;children/*[2][@role!="overaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),["Rule","limboth-end","default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3]; [t] "finalizar \u00edndices"', +"self::limboth"],["Rule","limlower-end","default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2]; [t] "finalizar \u00edndices"',"self::limlower"],["Rule","limupper-end","default",'[n] children/*[1]; [t] CSFoverscript; [n] children/*[2]; [t] "finalizar \u00edndices"',"self::limupper"],["Aliases","limlower-end","self::underscore",'@role="limit function"'],["Aliases","limlower-end","self::underscore"],["Aliases","limupper-end","self::overscore"],["Rule","integral","default","[n] children/*[1]; [n] children/*[2]; [n] children/*[3];", +"self::integral"],'Rule,integral,default,[n] children/*[1]; [t] "definida"; [t] "sub\u00edndice"; [n] children/*[2];[t] "super\u00edndice"; [n] children/*[3]; [t] "l\u00ednea base";,self::limboth,@role="integral"'.split(","),["SpecializedRule","integral","default","brief",'[n] children/*[1]; [t] "Sub"; [n] children/*[2];[t] "Sup"; [n] children/*[3]; [t] "Base";'],["SpecializedRule","integral","brief","sbrief"],["Rule","bigop","default","[n] children/*[1]; [n] children/*[2];","self::bigop"],["Rule", +"relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],'Rule,equality,default,[n] children/*[1]; [n] content/*[1]; [n] children/*[2],self::relseq,@role="equality",count(./children/*)=2'.split(","),'Rule;multi-equality;default;[m] children/* (sepFunc:CTXFcontentIterator);self::relseq;@role="equality";count(./children/*)>2'.split(";"),["Rule","multrel","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::multirel"],["Rule","subscript","default","[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]", +"self::subscript"],["Rule","subscript","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]","self::subscript"],["SpecializedRule","subscript","brief","sbrief"],'Rule,subscript-baseline,default,[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]; [t] CSFbaselineVerbose,self::subscript,following-sibling::*,not(name(following-sibling::subscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="subscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and @role!="subsup",not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","subscript-baseline","default","brief","[n] children/*[1]; [t] CSFsubscriptBrief; [n] children/*[2]; [t] CSFbaselineBriefS"],["SpecializedRule","subscript-baseline","brief","sbrief"],'Aliases;subscript-baseline;self::subscript;not(following-sibling::*);ancestor::fenced|ancestor::root|ancestor::sqrt|ancestor::punctuated|ancestor::fraction;not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","subscript-baseline", +"self::subscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel",sre.MathspeakUtil.generateBaselineConstraint()],["Aliases","subscript-baseline","self::subscript","not(following-sibling::*)","@embellished"],'Rule,subscript-empty-sup,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="superscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","),["SpecializedRule","subscript-empty-sup", +"default","brief"],["SpecializedRule","subscript-empty-sup","brief","sbrief"],["Aliases","subscript-empty-sup","self::subscript",'name(children/*[2])="superscript"','name(children/*[2]/children/*[1])="empty"'],["Rule","superscript","default","[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2]","self::superscript"],["SpecializedRule","superscript","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2]"],["SpecializedRule","superscript","brief","sbrief"],'Rule,superscript-baseline,default,[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2];[t] CSFbaselineVerbose,self::superscript,following-sibling::*,not(name(following-sibling::superscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="superscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +["SpecializedRule","superscript-baseline","default","brief","[n] children/*[1]; [t] CSFsuperscriptBrief; [n] children/*[2];[t] CSFbaselineBriefS"],["SpecializedRule","superscript-baseline","brief","sbrief"],'Aliases;superscript-baseline;self::superscript;not(following-sibling::*);ancestor::punctuated;ancestor::*/following-sibling::* and not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","superscript-baseline","self::superscript", +"not(following-sibling::*)","ancestor::fraction|ancestor::fenced|ancestor::root|ancestor::sqrt"],["Aliases","superscript-baseline","self::superscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel","not(@embellished)",sre.MathspeakUtil.generateBaselineConstraint()],'Aliases superscript-baseline self::superscript not(following-sibling::*) @embellished not(children/*[2][@role="prime"])'.split(" "),'Rule,superscript-empty-sub,default,[n] children/*[1]; [n] children/*[2],self::superscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="subscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","), +["SpecializedRule","superscript-empty-sub","default","brief"],["SpecializedRule","superscript-empty-sub","brief","sbrief"],["Aliases","superscript-empty-sub","self::superscript",'name(children/*[2])="subscript"','name(children/*[2]/children/*[1])="empty"'],'Rule,square,default,[n] children/*[1]; [t] "al cuadrado",self::superscript,children/*[2],children/*[2][text()=2],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","square","default","brief"],["SpecializedRule","square","default","sbrief"],'Aliases;square;self::superscript;children/*[2];children/*[2][text()=2];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,cube,default,[n] children/*[1]; [t] "al cubo",self::superscript,children/*[2],children/*[2][text()=3],name(children/*[1])!="text" or not(name(children/*[1])="text" and (name(../../../punctuated[@role="text"]/..)="stree" or name(..)="stree")),name(children/*[1])!="subscript" or (name(children/*[1])="subscript" and name(children/*[1]/children/*[1])="identifier" and name(children/*[1]/children/*[2])="number" and children/*[1]/children/*[2][@role!="mixed"] and children/*[1]/children/*[2][@role!="othernumber"]),not(@embellished)'.split(","), +["SpecializedRule","cube","default","brief"],["SpecializedRule","cube","default","sbrief"],'Aliases;cube;self::superscript;children/*[2];children/*[2][text()=3];@embellished;children/*[1][@role="prefix operator"]'.split(";"),'Rule,prime,default,[n] children/*[1]; [n] children/*[2],self::superscript,children/*[2],children/*[2][@role="prime"]'.split(","),["SpecializedRule","prime","default","brief"],["SpecializedRule","prime","default","sbrief"],'Rule,prime-subscript,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",not(following-sibling::*)'.split(","), +["SpecializedRule","prime-subscript","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]"],["SpecializedRule","prime-subscript","brief","sbrief"],'Rule,prime-subscript-baseline,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2]; [t] CSFbaselineVerbose,self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",following-sibling::*'.split(","), +["SpecializedRule","prime-subscript-baseline","default","brief","[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptBrief; [n] children/*[1]/children/*[2]; [t] CSFbaselineBriefS"],["SpecializedRule","prime-subscript-baseline","brief","sbrief"],'Aliases prime-subscript-baseline self::superscript children/*[2][@role="prime"] name(children/*[1])="subscript" not(following-sibling::*) @embellished'.split(" "),'Rule,overscore,default,[t] "modificando superior"; [n] children/*[1]; [t] "con"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"]'.split(","), +["SpecializedRule","overscore","default","brief",'[t] "mod superior"; [n] children/*[1]; [t] "con"; [n] children/*[2]'],["SpecializedRule","overscore","brief","sbrief"],'Rule,double-overscore,default,[t] "modificando superior superior"; [n] children/*[1]; [t] "con"; [n] children/*[2],self::overscore,children/*[2][@role="overaccent"],name(children/*[1])="overscore",children/*[1]/children/*[2][@role="overaccent"]'.split(","),["SpecializedRule","double-overscore","default","brief",'[t] "mod superior superior"; [n] children/*[1]; [t] "con"; [n] children/*[2]'], +["SpecializedRule","double-overscore","brief","sbrief"],'Rule,underscore,default,[t] "modificando inferior"; [n] children/*[1]; [t] "con"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"]'.split(","),["SpecializedRule","underscore","default","brief",'[t] "mod inferior"; [n] children/*[1]; [t] "con"; [n] children/*[2]'],["SpecializedRule","underscore","brief","sbrief"],'Rule,double-underscore,default,[t] "modificando inferior inferior"; [n] children/*[1]; [t] "con"; [n] children/*[2],self::underscore,children/*[2][@role="underaccent"],name(children/*[1])="underscore",children/*[1]/children/*[2][@role="underaccent"]'.split(","), +["SpecializedRule","double-underscore","default","brief",'[t] "mod inferior inferior"; [n] children/*[1]; [t] "con"; [n] children/*[2]'],["SpecializedRule","double-underscore","brief","sbrief"],'Rule,overbar,default,[n] children/*[1]; [t] "barra",self::overscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="overaccent"],children/*[2][text()="\u00af" or text()="\uffe3" or text()="\uff3f" or text()="_" or text()="\u203e"]'.split(","),["SpecializedRule","overbar", +"default","brief",'[n] children/*[1]; [t] "barra"'],["SpecializedRule","overbar","brief","sbrief"],'Rule,underbar,default,[n] children/*[1]; [t] "subbarra",self::underscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="underaccent"],children/*[2][text()="\u00af" or text()="\uffe3" or text()="\uff3f" or text()="_" or text()="\u203e"]'.split(","),["SpecializedRule","underbar","default","brief",'[n] children/*[1]; [t] "subbarra"'],["SpecializedRule","underbar", +"brief","sbrief"],'Rule,overtilde,default,[n] children/*[1]; [t] "tilde",self::overscore,children/*[2][@role="overaccent"],@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][text()="~" or text()="\u02dc" or text()="\u223c" or text()="\uff5e"]'.split(","),["SpecializedRule","overtilde","default","brief",'[n] children/*[1]; [t] "tilde"'],["SpecializedRule","overtilde","brief","sbrief"],'Rule,undertilde,default,[n] children/*[1]; [t] "subtilde",self::underscore,@role="latinletter" or @role="greekletter" or @role="otherletter",children/*[2][@role="underaccent"],children/*[2][text()="~" or text()="\u02dc" or text()="\u223c" or text()="\uff5e"]'.split(","), +["SpecializedRule","undertilde","default","brief",'[n] children/*[1]; [t] "subtilde"'],["SpecializedRule","undertilde","brief","sbrief"],'Rule,matrix-fence,default,[n] children/*[1];,self::fenced,count(children/*)=1,name(children/*[1])="matrix"'.split(","),["Rule","matrix","default",'[t] "empezar matriz"; [t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar matriz"',"self::matrix"],["Rule","matrix","sbrief", +'[t] "matriz"; [t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:" "); [t] "finalizar matriz"',"self::matrix"],["Aliases","matrix","self::vector"],["Rule","matrix-row","default",'[m] children/* (ctxtFunc:CTXFordinalCounter,context:"columna");[p] (pause: 200)',"self::row"],'Rule{row-with-label{default{[t] "con etiqueta"; [n] content/*[1]; [t] "finalizar etiqueta" (pause: 200); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"columna"){self::row{content'.split("{"), +'Rule{row-with-label{brief{[t] "etiqueta"; [n] content/*[1]; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"columna"){self::row{content'.split("{"),["SpecializedRule","row-with-label","brief","sbrief"],'Rule{row-with-text-label{sbrief{[t] "etiqueta"; [t] CSFRemoveParens;[m] children/* (ctxtFunc:CTXFordinalCounter,context:"columna"){self::row{content{name(content/cell/children/*[1])="text"'.split("{"),'Rule;empty-row;default;[t] "espacio";self::row;count(children/*)=0'.split(";"),["Rule","matrix-cell", +"default","[n] children/*[1]; [p] (pause: 300)","self::cell"],'Rule,empty-cell,default,[t] "espacio"; [p] (pause: 300),self::cell,count(children/*)=0'.split(","),'Rule{determinant{default{[t] "empezar determinante"; [t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar determinante"{self::matrix{@role="determinant"'.split("{"),["SpecializedRule","determinant","default","sbrief",'[t] "determinante"; [t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar determinante"'], +'Rule{determinant-simple{default{[t] "empezar determinante"; [t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila",grammar:simpleDet); [t] "finalizar determinante"{self::matrix{@role="determinant"{CQFdetIsSimple'.split("{"),["SpecializedRule","determinant-simple","default","sbrief",'[t] "determinante"; [t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila",grammar:simpleDet); [t] "finalizar determinante"'], +'Rule{row-simple{default{[m] children/*;{self::row{@role="determinant"{contains(@grammar, "simpleDet")'.split("{"),["Rule","layout","default",'[t] "empezar esquema"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar esquema"',"self::table"],["Rule","layout","sbrief",'[t] "esquema"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar esquema"',"self::table"],'Rule,binomial,default,[t] "empezar binomial"; [n] children/*[1]/children/*[1]; [t] "en"; [n] children/*[2]/children/*[1]; [t] "finalizar binomial",self::vector,@role="binomial"'.split(","), +'Rule,binomial,sbrief,[t] "binomial"; [n] children/*[1]/children/*[1]; [t] "en"; [n] children/*[2]/children/*[1]; [t] "finalizar binomial",self::vector,@role="binomial"'.split(","),["Rule","cases","default",'[t] "empezar esquema"; [n] content/*[1]; [t] "alargada"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar esquema"',"self::cases"],["Rule","cases","sbrief",'[t] "esquema"; [n] content/*[1]; [t] "alargada"; [m] children/* (ctxtFunc:CTXFordinalCounter,context:"fila "); [t] "finalizar esquema"', +"self::cases"],["Aliases","layout","self::multiline"],["Rule","line","default","[m] children/*","self::line"],'Rule,line-with-label,default,[t] "con etiqueta"; [n] content/*[1]; [t] "finalizar etiqueta" (pause: 200); [m] children/*,self::line,content'.split(","),["SpecializedRule","line-with-label","default","brief",'[t] "etiqueta"; [n] content/*[1] (pause: 200); [m] children/*'],["SpecializedRule","line-with-label","brief","sbrief"],'Rule,line-with-text-label,sbrief,[t] "etiqueta"; [t] CSFRemoveParens; [m] children/*,self::line,content,name(content/cell/children/*[1])="text"'.split(","), +'Rule;empty-line;default;[t] "espacio";self::line;count(children/*)=0;not(content)'.split(";"),["SpecializedRule","empty-line","default","brief"],["SpecializedRule","empty-line","brief","sbrief"],'Rule,empty-line-with-label,default,[t] "con etiqueta"; [n] content/*[1]; [t] "finalizar etiqueta" (pause: 200); [t] "espacio",self::line,count(children/*)=0,content'.split(","),["SpecializedRule","empty-line-with-label","default","brief",'[t] "etiqueta"; [n] content/*[1] (pause: 200); [t] "espacio"'],["SpecializedRule", +"empty-line-with-label","brief","sbrief"],["Rule","enclose","default",'[t] "empezar rodear"; [t] @role (grammar:localEnclose); [n] children/*[1]; [t] "finalizar rodear"',"self::enclose"],["Aliases","overbar","self::enclose",'@role="top"'],["Aliases","underbar","self::enclose",'@role="bottom"'],'Rule,leftbar,default,[t] "barra vertical"; [n] children/*[1],self::enclose,@role="left"'.split(","),'Rule,rightbar,default,[n] children/*[1]; [t] "barra vertical",self::enclose,@role="right"'.split(","),'Rule,crossout,default,[t] "tachado"; [n] children/*[1]; [t] "finalizar tachado",self::enclose,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","), +'Rule,cancel,default,[t] "tachado"; [n] children/*[1]/children/*[1]; [t] "con"; [n] children/*[2]; [t] "finalizar tachado",self::overscore,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","),["SpecializedRule","cancel","default","brief"],["SpecializedRule","cancel","default","sbrief"],["Aliases","cancel","self::underscore",'@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'],'Rule,cancel-reverse,default,[t] "tachado"; [n] children/*[2]/children/*[1]; [t] "con"; [n] children/*[1]; [t] "finalizar tachado",self::overscore,name(children/*[2])="enclose",children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'.split(","), +["SpecializedRule","cancel-reverse","default","brief"],["SpecializedRule","cancel-reverse","default","sbrief"],["Aliases","cancel-reverse","self::underscore",'name(children/*[2])="enclose"','children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'],'Rule;end-punct;default;[m] children/*;self::punctuated;@role="endpunct"'.split(";"),'Rule,start-punct,default,[n] content/*[1]; [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule,integral-punct,default,[n] children/*[1]; [n] children/*[3],self::punctuated,@role="integral"'.split(","), +["Rule","punctuated","default","[m] children/*","self::punctuated"],'Rule;unit-singular;default;[t] text() (grammar:annotation="unit":translate);self::identifier;@role="unit"'.split(";"),'Rule;unit-plural;default;[t] text() (grammar:annotation="unit":translate:plural);self::identifier;@role="unit";not(contains(@grammar, "singularUnit"))'.split(";"),'Rule,unit-square,default,[n] children/*[1]; [t] "cuadrado",self::superscript,@role="unit",children/*[2][text()=2],name(children/*[1])="identifier"'.split(","), +'Rule,unit-cubic,default,[n] children/*[1]; [t] "c\u00fabico",self::superscript,@role="unit",children/*[2][text()=3],name(children/*[1])="identifier"'.split(","),'Rule,reciprocal,default,[t] "rec\u00edproco"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],count(preceding-sibling::*)=0 or preceding-sibling::*[@role!="unit"]'.split(","),'Rule,reciprocal,default,[t] "por"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],preceding-sibling::*[@role="unit"]'.split(","), +'Rule;unit-combine;default;[m] children/* (sepFunc:CTXFunitMultipliers);self::infixop;@role="unit"'.split(";"),'Rule,unit-combine-mult,default,[m] children/* (sepFunc:CTXFunitMultipliers);,self::infixop,@role="multiplication" or @role="implicit",children/*[@role="unit"]'.split(","),'Rule{unit-combiner-singular{default{[n] children/*[1]; [t] "por"; [m] children/*[position()>1] (grammar:!singularUnit, sepFunc:CTXFunitMultipliers){self::infixop{@role="unit"{name(children/*[1])!="number"{contains(@grammar, "singularUnit"){count(children/*)>1'.split("{"), +'Rule,unit-combine-singular-first,default,[n] children/*[1]; [n] children/*[2] (grammar:singularUnit); [t] "por"; [m] children/*[position()>2] (sepFunc:CTXFunitMultipliers),self::infixop,@role="unit",name(children/*[1])="number",children/*[1][text()=1]'.split(","),'Rule,unit-combine-singular-first,default,[n] children/*[1]; [n] children/*[2] (grammar:singularUnit); ,self::infixop,@role="unit",name(children/*[1])="number",children/*[1][text()=1],count(children/*)=2'.split(","),'Rule,unit-divide,default,[n] children/*[1]; [t] "por"; [n] children/*[2] (grammar:singularUnit),self::fraction,@role="unit"'.split(",")], +initialize:[sre.MathspeakUtil.generateTensorRules]};sre.NemethUtil={};sre.NemethUtil.openingFraction=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a).join(sre.Messages.MS.FRACTION_REPEAT)+sre.Messages.MS.FRACTION_START};sre.NemethUtil.closingFraction=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a).join(sre.Messages.MS.FRACTION_REPEAT)+sre.Messages.MS.FRACTION_END};sre.NemethUtil.overFraction=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a).join(sre.Messages.MS.FRACTION_REPEAT)+sre.Messages.MS.FRACTION_OVER}; +sre.NemethUtil.overBevelledFraction=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a).join(sre.Messages.MS.FRACTION_REPEAT)+"\u2838"+sre.Messages.MS.FRACTION_OVER};sre.NemethUtil.nestedRadical=function(a,b){a=sre.NemethUtil.radicalNestingDepth(a);return 1===a?b:Array(a).join(sre.Messages.MS.NESTED)+b};sre.NemethUtil.radicalNestingDepth=function(a,b){b=b||0;return a.parentNode?sre.NemethUtil.radicalNestingDepth(a.parentNode,"root"===a.tagName||"sqrt"===a.tagName?b+1:b):b}; +sre.NemethUtil.openingRadical=function(a){return sre.NemethUtil.nestedRadical(a,sre.Messages.MS.STARTROOT)};sre.NemethUtil.closingRadical=function(a){return sre.NemethUtil.nestedRadical(a,sre.Messages.MS.ENDROOT)};sre.NemethUtil.indexRadical=function(a){return sre.NemethUtil.nestedRadical(a,sre.Messages.MS.ROOTINDEX)}; +sre.NemethUtil.enlargeFence=function(a){if(1===a.length)return"\u2820"+a;var b=a.split("");return b.every(function(c){return"\u2833"===c})?"\u2820"+b.join("\u2820"):a.slice(0,1)+"\u2820"+a.slice(1)};sre.Grammar.getInstance().setCorrection("enlargeFence",sre.NemethUtil.enlargeFence);sre.NemethUtil.NUMBER_PROPAGATORS_=[sre.SemanticAttr.Type.MULTIREL,sre.SemanticAttr.Type.RELSEQ,sre.SemanticAttr.Type.PUNCTUATED,sre.SemanticAttr.Type.APPL]; +sre.NemethUtil.checkParent_=function(a){a=a.parent;if(!a)return!1;var b=a.type;return-1!==sre.NemethUtil.NUMBER_PROPAGATORS_.indexOf(b)||b===sre.SemanticAttr.Type.PREFIXOP&&a.role===sre.SemanticAttr.Role.NEGATIVE?!0:!1};sre.NemethUtil.propagateNumber=function(a,b){if(!a.childNodes.length)return sre.NemethUtil.checkParent_(a)&&(b.number=!0),[b.number?"number":"",{number:!1}];sre.NemethUtil.checkParent_(a)&&(b.number=!0);return["",b]}; +sre.NemethUtil.numberIndicator=function(){return new sre.SemanticVisitor("nemeth",sre.NemethUtil.propagateNumber,{number:!0})};sre.NemethUtil.addAnnotators=function(){sre.SemanticAnnotations.getInstance().register(sre.NemethUtil.numberIndicator())};sre.NemethUtil.componentString_={2:"CSFbaseline",1:"CSFsubscript",0:"CSFsuperscript"};sre.NemethUtil.childNumber_={4:2,3:3,2:1,1:4,0:5}; +sre.NemethUtil.generateTensorRuleStrings_=function(a){var b=[],c="";a=parseInt(a,2);for(var d=0;5>d;d++){var e="children/*["+sre.NemethUtil.childNumber_[d]+"]";a&1?c="[t] "+sre.NemethUtil.componentString_[d%3]+"Verbose; [n] "+e+";"+c:b.unshift("name("+e+')="empty"');a>>=1}b.push(c);return b}; +sre.NemethUtil.generateTensorRules=function(a){var b=goog.bind(a.defineRule,a);a=goog.bind(a.defineRulesAlias,a);for(var c="11111 11110 11101 11100 10111 10110 10101 10100 01111 01110 01101 01100".split(" "),d=0,e;e=c[d];d++){var f="tensor"+e;e=sre.NemethUtil.generateTensorRuleStrings_(e);var g=e.pop(),h=[f,"default.default",g,"self::tensor"].concat(e);b.apply(null,h);g+="; [t]"+sre.NemethUtil.componentString_[2]+"Verbose";f+="-baseline";h=[f,"default.default",g,"self::tensor","following-sibling::*"].concat(e); +b.apply(null,h);f=[f,"self::tensor","not(following-sibling::*)","ancestor::fraction|ancestor::punctuated|ancestor::fenced|ancestor::root|ancestor::sqrt|ancestor::relseq|ancestor::multirel|@embellished"].concat(e);a.apply(null,f)}};sre.NemethRules={locale:"nemeth",modality:"braille",domain:"default",functions:[["CQF","CQFspaceoutNumber",sre.MathspeakUtil.spaceoutNumber],["CQF","CQFspaceoutIdentifier",sre.MathspeakUtil.spaceoutIdentifier],["CSF","CSFspaceoutText",sre.MathspeakUtil.spaceoutText],["CSF","CSFopenFraction",sre.NemethUtil.openingFraction],["CSF","CSFcloseFraction",sre.NemethUtil.closingFraction],["CSF","CSFoverFraction",sre.NemethUtil.overFraction],["CSF","CSFoverBevFraction",sre.NemethUtil.overBevelledFraction], +["CSF","CSFopenRadicalVerbose",sre.NemethUtil.openingRadical],["CSF","CSFcloseRadicalVerbose",sre.NemethUtil.closingRadical],["CSF","CSFindexRadicalVerbose",sre.NemethUtil.indexRadical],["CSF","CSFsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose],["CSF","CSFsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose],["CSF","CSFbaselineVerbose",sre.MathspeakUtil.baselineVerbose],["CSF","CSFunderscript",sre.MathspeakUtil.nestedUnderscore],["CSF","CSFoverscript",sre.MathspeakUtil.nestedOverscore], +["CTXF","CTXFordinalCounter",sre.NumbersUtil.ordinalCounter],["CTXF","CTXFcontentIterator",sre.StoreUtil.contentIterator],["CQF","CQFdetIsSimple",sre.MathspeakUtil.determinantIsSimple],["CSF","CSFRemoveParens",sre.MathspeakUtil.removeParens],["CQF","CQFresetNesting",sre.MathspeakUtil.resetNestingDepth]],rules:["Rule;stree;default;[n] ./*[1];self::stree;CQFresetNesting".split(";"),["Rule","unknown","default","[n] text()","self::unknown"],'Rule;protected;default;[t] text();self::*;@role="protected"'.split(";"), +["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule;blank-empty;default;[t] "\u2800";self::empty;count(../*)=1;name(../..)="cell" or name(../..)="line"'.split(";"),'Rule{font{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"),'Rule{font-identifier-short{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{not(contains(@grammar, "ignoreFont")){@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1;@font;@role!="greekletter";not(contains(@grammar, "ignoreFont"));@font="italic"'.split(";"),'Rule{number-indicator{default{[t] "\u283c"; [n] text() (pause:10){self::number{contains(@annotation, "nemeth:number"){not(ancestor::sqrt){not(ancestor::root){not(ancestor::fraction)'.split("{"), +["Rule","number","default","[n] text()","self::number"],'Rule,mixed-number,default,[n] children/*[1]; [t] "\u2838\u2839"; [n] children/*[2]/children/*[1]; [t] "\u280c"; [n] children/*[2]/children/*[2]; [t] "\u2838\u283c",self::number,@role="mixed"'.split(","),'Rule{number-with-chars{default{[t] "\u283c"; [m] CQFspaceoutNumber{self::number{"" != translate(text(), "0123456789.,", ""){text() != translate(text(), "0123456789.,", "")'.split("{"),'Rule{number-as-upper-word{default{[t] "UpperWord"; [t] CSFspaceoutText{self::number{string-length(text())>1{text()=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9"){""=translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9","")'.split("{"), +'Rule{number-baseline{default{[t] "\u2810"; [n] text(){self::number{not(contains(@grammar, "ignoreFont")){preceding-sibling::identifier{preceding-sibling::*[1][@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"),'Rule{number-baseline-font{default{[t] "\u2810"; [t] @font; [n] . (grammar:ignoreFont=@font){self::number{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"{preceding-sibling::identifier{preceding-sibling::*[@role="latinletter" or @role="greekletter" or @role="otherletter"]{parent::*/parent::infixop[@role="implicit"]'.split("{"), +'Rule;identifier;default;[n] text();self::identifier;@role="protected"'.split(";"),'Rule,negative,default,[t] "\u2824"; [n] children/*[1],self::prefixop,@role="negative"'.split(","),["Rule","prefix","default","[n] text(); [n] children/*[1]","self::prefixop"],["Rule","postfix","default","[n] children/*[1]; [n] text()","self::postfixop"],["Rule","binary-operation","default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop"],'Rule;implicit;default;[m] children/*;self::infixop;@role="implicit"'.split(";"), +["Aliases","implicit","self::infixop",'@role="leftsuper" or @role="leftsub" or @role="rightsuper" or @role="rightsub"'],["Rule","function-named","default",'[n] children/*[1]; [t] "\u2800"; [n] children/*[2]',"self::appl"],'Rule,function-prefix,default,[n] content/*[1]; [t] "\u2800"; [n] children/*[1],self::prefixop,content/*[1][@role="infix function"]'.split(","),'Rule,function-infix,default,[n] children/*[1]; [n] content/*[1]; [t] "\u2800"; [n] children/*[2],self::infixop,@role="infix function"'.split(","), +'Rule,function-simple,default,[n] children/*[1]; [n] children/*[2],self::appl,children/*[1][@role="simple function"]'.split(","),["Rule","fences-open-close","default","[n] content/*[1]; [n] children/*[1]; [n] content/*[2]","self::fenced"],'Rule,fences-neutral,default,[n] content/*[1]; [n] children/*[1]; [n] content/*[2],self::fenced,@role="neutral"'.split(","),["Rule","text","default","[n] text()","self::text"],'Rule;factorial;default;[t] "\u282f";self::punctuation;text()="!";name(preceding-sibling::*[1])!="text"'.split(";"), +'Rule;single-prime;default;[t] "\u2804";self::punctuated;@role="prime";count(children/*)=1'.split(";"),'Rule;double-prime;default;[t] "\u2804\u2804";self::punctuated;@role="prime";count(children/*)=2'.split(";"),'Rule;triple-prime;default;[t] "\u2804\u2804\u2804";self::punctuated;@role="prime";count(children/*)=3'.split(";"),'Rule;quadruple-prime;default;[t] "\u2804\u2804\u2804\u2804";self::punctuated;@role="prime";count(children/*)=4'.split(";"),["Rule","fraction","default","[t] CSFopenFraction; [n] children/*[1]; [t] CSFoverFraction; [n] children/*[2]; [t] CSFcloseFraction", +"self::fraction"],'Rule{bevelled-fraction{default{[t] CSFopenFraction; [n] children/*[1]; [t] CSFoverBevFraction; [n] children/*[2]; [t] CSFcloseFraction{self::fraction{contains(@annotation, "general:bevelled")'.split("{"),["Rule","sqrt","default","[t] CSFopenRadicalVerbose; [n] children/*[1]; [t] CSFcloseRadicalVerbose","self::sqrt"],["Rule","root","default",'[t] CSFindexRadicalVerbose; [n] children/*[1];[t] "\u281c"; [n] children/*[2]; [t] CSFcloseRadicalVerbose',"self::root"],'Rule,limboth,default,[t] "\u2810"; [n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3],self::limboth,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","), +'Rule,limlower,default,[t] "\u2810"; [n] children/*[1]; [t] CSFunderscript; [n] children/*[2];,self::limlower,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Rule,limupper,default,[t] "\u2810"; [n] children/*[1]; [t] CSFoverscript; [n] children/*[2];,self::limupper,name(../..)="underscore" or name(../..)="overscore",following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(","),'Aliases;limlower;self::underscore;@role="limit function";name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"), +'Aliases;limlower;self::underscore;children/*[2][@role!="underaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),'Aliases;limupper;self::overscore;children/*[2][@role!="overaccent"];name(../..)="underscore" or name(../..)="overscore";following-sibling::*[@role!="underaccent" and @role!="overaccent"]'.split(";"),["Rule","limboth-end","default",'[t] "\u2810"; [n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3]; [t] "\u283b"', +"self::limboth"],["Rule","limlower-end","default",'[t] "\u2810"; [n] children/*[1]; [t] CSFunderscript; [n] children/*[2]; [t] "\u283b"',"self::limlower"],["Rule","limupper-end","default",'[t] "\u2810"; [n] children/*[1]; [t] CSFoverscript; [n] children/*[2]; [t] "\u283b"',"self::limupper"],["Aliases","limlower-end","self::underscore",'@role="limit function"'],["Aliases","limlower-end","self::underscore"],["Aliases","limupper-end","self::overscore"],["Rule","integral","default","[n] children/*[1]; [n] children/*[2]; [n] children/*[3];", +"self::integral"],'Rule,integral,default,[n] children/*[1]; [t] "\u2830"; [n] children/*[2];[t] "\u2818"; [n] children/*[3]; [t] "\u2810",self::limboth,@role="integral"'.split(","),["Rule","bigop","default","[n] children/*[1]; [n] children/*[2];","self::bigop"],["Rule","relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],'Rule,equality,default,[n] children/*[1]; [n] content/*[1]; [n] children/*[2],self::relseq,@role="equality",count(./children/*)=2'.split(","),'Rule;multi-equality;default;[m] children/* (sepFunc:CTXFcontentIterator);self::relseq;@role="equality";count(./children/*)>2'.split(";"), +["Rule","multrel","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::multirel"],["Rule","subscript","default","[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]","self::subscript"],'Rule,subscript-simple,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(./children/*[1])="identifier",name(./children/*[2])="number",./children/*[2][@role!="mixed"],./children/*[2][@role!="othernumber"],self::*'.split(","),'Rule,subscript-baseline,default,[n] children/*[1]; [t] CSFsubscriptVerbose; [n] children/*[2]; [t] CSFbaselineVerbose,self::subscript,following-sibling::*,@role!="prefix function",not(name(following-sibling::subscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="subscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and @role!="subsup",not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +'Aliases;subscript-baseline;self::subscript;not(following-sibling::*);ancestor::fenced|ancestor::root|ancestor::sqrt|ancestor::punctuated|ancestor::fraction;not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","subscript-baseline","self::subscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel",sre.MathspeakUtil.generateBaselineConstraint()],["Aliases","subscript-baseline","self::subscript","not(following-sibling::*)", +"@embellished"],'Rule,subscript-empty-sup,default,[n] children/*[1]; [n] children/*[2],self::subscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="superscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","),["Aliases","subscript-empty-sup","self::subscript",'name(children/*[2])="superscript"','name(children/*[2]/children/*[1])="empty"'],["Rule","superscript","default","[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2]","self::superscript"], +'Rule,superscript-baseline,default,[n] children/*[1]; [t] CSFsuperscriptVerbose; [n] children/*[2];[t] CSFbaselineVerbose,self::superscript,following-sibling::*,@role!="prefix function",not(name(following-sibling::superscript/children/*[1])="empty" or (name(following-sibling::infixop[@role="implicit"]/children/*[1])="superscript" and name(following-sibling::*/children/*[1]/children/*[1])="empty")) and not(following-sibling::*[@role="rightsuper" or @role="rightsub" or @role="leftsub" or @role="leftsub"])'.split(","), +'Aliases;superscript-baseline;self::superscript;not(following-sibling::*);ancestor::punctuated;ancestor::*/following-sibling::* and not(ancestor::punctuated[@role="leftsuper" or @role="rightsub" or @role="rightsuper" or @role="rightsub"])'.split(";"),["Aliases","superscript-baseline","self::superscript","not(following-sibling::*)","ancestor::fraction|ancestor::fenced|ancestor::root|ancestor::sqrt"],["Aliases","superscript-baseline","self::superscript","not(following-sibling::*)","ancestor::relseq|ancestor::multirel", +"not(@embellished)",sre.MathspeakUtil.generateBaselineConstraint()],'Aliases superscript-baseline self::superscript not(following-sibling::*) @embellished not(children/*[2][@role="prime"])'.split(" "),'Rule,superscript-empty-sub,default,[n] children/*[1]; [n] children/*[2],self::superscript,name(children/*[2])="infixop",name(children/*[2][@role="implicit"]/children/*[1])="subscript",name(children/*[2]/children/*[1]/children/*[1])="empty"'.split(","),["Aliases","superscript-empty-sub","self::superscript", +'name(children/*[2])="subscript"','name(children/*[2]/children/*[1])="empty"'],'Rule,prime,default,[n] children/*[1]; [n] children/*[2],self::superscript,children/*[2],children/*[2][@role="prime"]'.split(","),'Rule,prime-subscript,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",not(following-sibling::*)'.split(","),'Rule,prime-subscript-baseline,default,[n] children/*[1]/children/*[1]; [n] children/*[2]; [t] CSFsubscriptVerbose; [n] children/*[1]/children/*[2]; [t] CSFbaselineVerbose,self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",following-sibling::*'.split(","), +'Aliases prime-subscript-baseline self::superscript children/*[2][@role="prime"] name(children/*[1])="subscript" not(following-sibling::*) @embellished'.split(" "),'Rule,prime-subscript-simple,default,[n] children/*[1]/children/*[1]; [n] children/*[2];[n] children/*[1]/children/*[2],self::superscript,children/*[2][@role="prime"],name(children/*[1])="subscript",name(children/*[1]/children/*[1])="identifier",name(children/*[1]/children/*[2])="number",children/*[1]/children/*[2][@role!="mixed"],children/*[1]/children/*[2][@role!="othernumber"]'.split(","), +'Rule,overscore,default,[t] "\u2810"; [n] children/*[1]; [t] "\u2823"; [n] children/*[2]; [t] "\u283b",self::overscore,children/*[2][@role="overaccent"]'.split(","),'Rule{overscore{default{[n] children/*[1]; [t] "\u2823"; [n] children/*[2]{self::overscore{children/*[2][@role="overaccent"]{contains(@grammar, "modified")'.split("{"),'Rule,double-overscore,default,[t] "\u2810"; [n] children/*[1] (grammar:"modified"); [t] "\u2823"; [n] children/*[2]; [t] "\u283b",self::overscore,children/*[2][@role="overaccent"],name(children/*[1])="overscore",children/*[1]/children/*[2][@role="overaccent"]'.split(","), +'Rule,underscore,default,[t] "\u2810"; [n] children/*[1]; [t] "\u2829"; [n] children/*[2]; [t] "\u283b",self::underscore,children/*[2][@role="underaccent"]'.split(","),'Rule{underscore{default{[n] children/*[1]; [t] "\u2829"; [n] children/*[2]{self::underscore{children/*[2][@role="underaccent"]{contains(@grammar, "modified")'.split("{"),'Rule,double-underscore,default,[t] "\u2810"; [n] children/*[1] (grammar:"modified"); [t] "\u2829"; [n] children/*[2]; [t] "\u283b",self::underscore,children/*[2][@role="underaccent"],name(children/*[1])="underscore",children/*[1]/children/*[2][@role="underaccent"]'.split(","), +'Rule,matrix-fence,default,[n] children/*[1];,self::fenced,count(children/*)=1,name(children/*[1])="matrix"'.split(","),["Rule","matrix","default",'[m] children/* (separator:"\u2800", join:"");',"self::matrix"],["Aliases","matrix","self::vector"],["Rule","matrix-row","default",'[n] ../../content/*[1] (grammar:enlargeFence); [m] children/* (separator:"\u2800"); [n] ../../content/*[2] (grammar:enlargeFence); ',"self::row"],["Aliases","matrix-row","self::line",'@role="vector"'],["Aliases","matrix-row", +"self::line",'@role="binomial"'],'Rule{row-with-label{default{[t] "with Label"; [n] content/*[1]; [t] "EndLabel"(pause: 200); [m] children/* (ctxtFunc:CTXFordinalCounter,context:"Column"){self::row{content'.split("{"),'Rule;empty-row;default;[t] "\u2800" (pause:300);self::row;count(children/*)=0'.split(";"),["Rule","matrix-cell","default","[n] children/*[1]","self::cell"],'Rule;empty-cell;default;[t] "\u2800" (pause: 300);self::cell;count(children/*)=0'.split(";"),["Rule","layout","default",'[m] children/* (separator:"\u2800", join:"");', +"self::table"],["Rule","cases","default",'[n] ../../content/*[1] (grammar:enlargeFence); [m] children/* (separator:"\u2800"); [t] "\u2810"',"self::cases"],["Aliases","layout","self::multiline"],["Rule","line","default","[m] children/*","self::line"],'Rule,line-with-label,default,[t] "with Label"; [n] content/*[1]; [t] "EndLabel" (pause: 200); [m] children/*,self::line,content'.split(","),'Rule;empty-line;default;[t] "\u2800";self::line;count(children/*)=0;not(content)'.split(";"),'Rule,empty-line-with-label,default,[t] "with Label"; [n] content/*[1]; [t] "EndLabel"(pause: 200); [t] "Blank",self::line,count(children/*)=0,content'.split(","), +["Rule","enclose","default",'[t] "StartEnclose"; [t] @role (grammar:localEnclose); [n] children/*[1]; [t] "EndEnclose"',"self::enclose"],'Rule,overbar,default,[t] "\u2810"; [n] children/*[1]; [t] "\u2823\u2831\u283b",self::enclose,@role="top"'.split(","),'Rule,underbar,default,[t] "\u2810"; [n] children/*[1]; [t] "\u2829\u2831\u283b",self::enclose,@role="bottom"'.split(","),'Rule,leftbar,default,[t] "\u2833"; [n] children/*[1],self::enclose,@role="left"'.split(","),'Rule,rightbar,default,[n] children/*[1]; [t] "\u2833",self::enclose,@role="right"'.split(","), +'Rule,crossout,default,[t] "\u282a"; [n] children/*[1]; [t] "\u283b",self::enclose,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","),'Rule,cancel,default,[t] "\u282a"; [n] children/*[1]/children/*[1]; [t] "\u282a"; [n] children/*[2]; [t] "\u283b",self::overscore,@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'.split(","),["Aliases","cancel","self::underscore",'@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"'], +'Rule,cancel-reverse,default,[t] "\u282a"; [n] children/*[2]/children/*[1]; [t] "\u282a"; [n] children/*[1]; [t] "\u283b",self::overscore,name(children/*[2])="enclose",children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'.split(","),["Aliases","cancel-reverse","self::underscore",'name(children/*[2])="enclose"','children/*[2][@role="updiagonalstrike" or @role="downdiagonalstrike" or @role="horizontalstrike"]'],'Rule;end-punct;default;[m] children/*;self::punctuated;@role="endpunct"'.split(";"), +'Rule,start-punct,default,[n] content/*[1]; [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule{punctuation{default{[n] text(); [t] "\u2810"{self::punctuation{@role="fullstop"{contains(@annotation, "nemeth:number")'.split("{"),'Rule,integral-punct,default,[n] children/*[1]; [n] children/*[3],self::punctuated,@role="integral"'.split(","),["Rule","punctuated","default","[m] children/*","self::punctuated"],'Rule,punctuation-comma,default,[n] text(); [t] "\u2800",self::punctuation,parent::*/parent::punctuated,following-sibling::*,@role!="fullstop"'.split(","), +'Rule,punctuation-ellipses,default,[t] "\u2800"; [n] text(); [t] "\u2800",self::punctuation,parent::*/parent::punctuated,following-sibling::*,@role="ellipsis",name(preceding-sibling::*[1])!="punctuation"'.split(","),'Rule,punctuation-ellipses,default,[t] "\u2800"; [n] text();,self::punctuation,parent::*/parent::punctuated,@role="ellipsis",name(preceding-sibling::*[1])!="punctuation"'.split(","),'Rule,reference-sign,default,[n] children/*[1]; [n] children/*[2],self::superscript,name(children/*[1])="text" or (name(children/*[1])="punctuated" and children/*[1][@role="text"]),name(children/*[2])="operator" or name(children/*[2])="punctuation"'.split(","), +'Rule,reference-number,default,[n] children/*[1]; [t] "\u2808\u283b"; [n] children/*[2]; [t] "\u2810",self::superscript,name(children/*[1])="text" or (name(children/*[1])="punctuated" and children/*[1][@role="text"]),name(children/*[2])="number",children/*[2][@role="integer"]'.split(",")],initialize:[sre.NemethUtil.generateTensorRules,sre.NemethUtil.addAnnotators]};sre.PrefixFrench={locale:"fr",modality:"prefix",domain:"default",functions:[["CSF","CSFordinalPosition",sre.NumbersUtil.ordinalPosition]],rules:['Rule,numerator,default,[t] "num\u00e9rateur"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=0'.split(","),'Rule,denominator,default,[t] "d\u00e9nominateur"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=1'.split(","),'Rule,base,default,[t] "base"; [p] (pause:200),self::*,name(../..)="superscript" or name(../..)="subscript" or name(../..)="overscore" or name(../..)="underscore" or name(../..)="tensor" or name(../..)="limlower" or name(../..)="limupper",count(preceding-sibling::*)=0'.split(","), +'Rule,base-limit,default,[t] "base"; [p] (pause:200),self::*,name(../..)="limboth"'.split(","),'Rule,exponent,default,[t] "exposant"; [p] (pause:200),self::*,name(../..)="superscript",count(preceding-sibling::*)=1'.split(","),'Rule,subscript,default,[t] "indice"; [p] (pause:200),self::*,name(../..)="subscript",count(preceding-sibling::*)=1'.split(","),'Rule,overscript,default,[t] "indice suscrit"; [p] (pause:200),self::*,name(../..)="overscore" or name(../..)="limupper" or name(../..)="limboth",count(preceding-sibling::*)=1 or count(preceding-sibling::*)=2'.split(","), +'Rule,underscript,default,[t] "indice souscrit"; [p] (pause:200),self::*,name(../..)="underscore" or name(../..)="limlower" or name(../..)="limboth",count(preceding-sibling::*)=1'.split(","),'Rule,radicand,default,[t] "radicande"; [p] (pause:200),self::*,name(../..)="sqrt"'.split(","),'Rule,radicand,default,[t] "radicande"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=1'.split(","),'Rule,index,default,[t] "indice"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=0'.split(","), +'Rule,leftsub,default,[t] "indice inf\u00e9rieur gauche"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsub"'.split(","),'Rule,leftsub,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "indice inf\u00e9rieur gauche"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsub"'.split(","),'Rule,leftsuper,default,[t] "indice sup\u00e9rieur gauche"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsuper"'.split(","),'Rule,leftsuper,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "indice sup\u00e9rieur gauche"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsuper"'.split(","), +'Rule,rightsub,default,[t] "indice inf\u00e9rieur droite"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsub"'.split(","),'Rule,rightsub,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "indice inf\u00e9rieur droite"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsub"'.split(","),'Rule,rightsuper,default,[t] "indice sup\u00e9rieur droite"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsuper"'.split(","),'Rule,rightsuper,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "indice sup\u00e9rieur droite"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsuper"'.split(","), +'Rule,choice,default,[t] "nombre d\'\u00e9l\u00e9ments choisis"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=1'.split(","),'Rule,select,default,[t] "nombre d\'\u00e9l\u00e9ments disponibles"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=0'.split(","),["Rule","row","default",'[t] CSFordinalPosition (grammar:gender="female"); [t] "rang\u00e9e"; [p] (pause:200)',"self::row"],["Aliases","row","self::line"], +'Rule{cell{default{[n] ../..; [t] CSFordinalPosition (grammar:gender="female"); [t] "colonne"; [p] (pause:200){self::cell{contains(@grammar,"depth")'.split("{"),["Rule","cell","default",'[t] CSFordinalPosition (grammar:gender="female"); [t] "colonne"; [p] (pause:200)',"self::cell"]]};sre.PrefixGerman={modality:"prefix",locale:"de",domain:"default",functions:[["CSF","CSFordinalPosition",sre.NumbersUtil.ordinalPosition]],rules:['Rule,numerator,default,[t] "Z\u00e4hler"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=0'.split(","),'Rule,denominator,default,[t] "Nenner"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=1'.split(","),'Rule,base,default,[t] "Basis"; [p] (pause:200),self::*,name(../..)="superscript" or name(../..)="subscript" or name(../..)="overscore" or name(../..)="underscore" or name(../..)="tensor",count(preceding-sibling::*)=0'.split(","), +'Rule,exponent,default,[t] "Exponent"; [p] (pause:200),self::*,name(../..)="superscript",count(preceding-sibling::*)=1'.split(","),'Rule,subscript,default,[t] "Index"; [p] (pause:200),self::*,name(../..)="subscript",count(preceding-sibling::*)=1'.split(","),'Rule,overscript,default,[t] "Oberer Grenzwert"; [p] (pause:200),self::*,name(../..)="overscore",count(preceding-sibling::*)=1'.split(","),'Rule,underscript,default,[t] "Unterer Grenzwert"; [p] (pause:200),self::*,name(../..)="underscore",count(preceding-sibling::*)=1'.split(","), +'Rule,radicand,default,[t] "Radikand"; [p] (pause:200),self::*,name(../..)="sqrt"'.split(","),'Rule,radicand,default,[t] "Radikand"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=1'.split(","),'Rule,index,default,[t] "Wurzelexponent"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=0'.split(","),'Rule,leftsub,default,[t] "linker unterer Index"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsub"'.split(","),'Rule,leftsub,default,[t] CSFordinalPosition; [t] "linker unterer Index"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsub"'.split(","), +'Rule,leftsuper,default,[t] "linker oberer Index"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsuper"'.split(","),'Rule,leftsuper,default,[t] CSFordinalPosition; [t] "linker oberer Index"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsuper"'.split(","),'Rule,rightsub,default,[t] "rechter unterer Index"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsub"'.split(","),'Rule,rightsub,default,[t] CSFordinalPosition; [t] "rechter unterer Index"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsub"'.split(","), +'Rule,rightsuper,default,[t] "rechter oberer Index"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsuper"'.split(","),'Rule,rightsuper,default,[t] CSFordinalPosition; [t] "rechter oberer Index"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsuper"'.split(","),'Rule,choice,default,[t] "Grundgesamtheit"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=0'.split(","),'Rule,select,default,[t] "Stichprobengr\u00f6\u00dfe"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=1'.split(","), +["Rule","row","default",'[t] CSFordinalPosition; [t] "Zeile"; [p] (pause:200)',"self::row"],["Aliases","row","self::line"],'Rule{cell{default{[n] ../..; [t] CSFordinalPosition; [t] "Spalte"; [p] (pause:200){self::cell{contains(@grammar,"depth")'.split("{"),["Rule","cell","default",'[t] CSFordinalPosition; [t] "Spalte"; [p] (pause:200)',"self::cell"]]};sre.PrefixRules={modality:"prefix",domain:"default",functions:[["CSF","CSFordinalPosition",sre.NumbersUtil.ordinalPosition]],rules:['Rule,numerator,default,[t] "Numerator"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=0'.split(","),'Rule,denominator,default,[t] "Denominator"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=1'.split(","),'Rule,base,default,[t] "Base"; [p] (pause:200),self::*,name(../..)="superscript" or name(../..)="subscript" or name(../..)="overscore" or name(../..)="underscore" or name(../..)="tensor",count(preceding-sibling::*)=0'.split(","), +'Rule,exponent,default,[t] "Exponent"; [p] (pause:200),self::*,name(../..)="superscript",count(preceding-sibling::*)=1'.split(","),'Rule,subscript,default,[t] "Subscript"; [p] (pause:200),self::*,name(../..)="subscript",count(preceding-sibling::*)=1'.split(","),'Rule,overscript,default,[t] "Overscript"; [p] (pause:200),self::*,name(../..)="overscore",count(preceding-sibling::*)=1'.split(","),'Rule,underscript,default,[t] "Underscript"; [p] (pause:200),self::*,name(../..)="underscore",count(preceding-sibling::*)=1'.split(","), +'Rule,radicand,default,[t] "Radicand"; [p] (pause:200),self::*,name(../..)="sqrt"'.split(","),'Rule,radicand,default,[t] "Radicand"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=1'.split(","),'Rule,index,default,[t] "Index"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=0'.split(","),'Rule,leftsub,default,[t] "Left Subscript"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsub"'.split(","),'Rule,leftsub,default,[t] CSFordinalPosition; [t] "Left Subscript"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsub"'.split(","), +'Rule,leftsuper,default,[t] "Left Superscript"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsuper"'.split(","),'Rule,leftsuper,default,[t] CSFordinalPosition; [t] "Left Superscript"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsuper"'.split(","),'Rule,rightsub,default,[t] "Right Subscript"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsub"'.split(","),'Rule,rightsub,default,[t] CSFordinalPosition; [t] "Right Subscript"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsub"'.split(","), +'Rule,rightsuper,default,[t] "Right Superscript"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsuper"'.split(","),'Rule,rightsuper,default,[t] CSFordinalPosition; [t] "Right Superscript"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsuper"'.split(","),'Rule,choice,default,[t] "Choice Quantity"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=0'.split(","),'Rule,select,default,[t] "Selection Quantity"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=1'.split(","), +["Rule","row","default",'[t] CSFordinalPosition; [t] "Row"; [p] (pause:200)',"self::row"],["Aliases","row","self::line"],'Rule{cell{default{[n] ../..; [t] CSFordinalPosition; [t] "Column"; [p] (pause:200){self::cell{contains(@grammar,"depth")'.split("{"),["Rule","cell","default",'[t] CSFordinalPosition; [t] "Column"; [p] (pause:200)',"self::cell"]]};sre.PrefixSpanish={locale:"es",modality:"prefix",domain:"default",functions:[["CSF","CSFordinalPosition",sre.NumbersUtil.ordinalPosition]],rules:['Rule,numerator,default,[t] "numerador"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=0'.split(","),'Rule,denominator,default,[t] "denominador"; [p] (pause:200),self::*,name(../..)="fraction",count(preceding-sibling::*)=1'.split(","),'Rule,base,default,[t] "base"; [p] (pause:200),self::*,name(../..)="superscript" or name(../..)="subscript" or name(../..)="overscore" or name(../..)="underscore" or name(../..)="tensor",count(preceding-sibling::*)=0'.split(","), +'Rule,exponent,default,[t] "exponente"; [p] (pause:200),self::*,name(../..)="superscript",count(preceding-sibling::*)=1'.split(","),'Rule,subscript,default,[t] "sub\u00edndice"; [p] (pause:200),self::*,name(../..)="subscript",count(preceding-sibling::*)=1'.split(","),'Rule,overscript,default,[t] "sobre\u00edndice"; [p] (pause:200),self::*,name(../..)="overscore",count(preceding-sibling::*)=1'.split(","),'Rule,underscript,default,[t] "bajo\u00edndice"; [p] (pause:200),self::*,name(../..)="underscore",count(preceding-sibling::*)=1'.split(","), +'Rule,radicand,default,[t] "radicand"; [p] (pause:200),self::*,name(../..)="sqrt"'.split(","),'Rule,radicand,default,[t] "radicand"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=1'.split(","),'Rule,index,default,[t] "\u00edndice"; [p] (pause:200),self::*,name(../..)="root",count(preceding-sibling::*)=0'.split(","),'Rule,leftsub,default,[t] "sub\u00edndice izquierdo"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsub"'.split(","),'Rule,leftsub,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "sub\u00edndice izquierdo"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsub"'.split(","), +'Rule,leftsuper,default,[t] "super\u00edndice izquierdo"; [p] (pause:200),self::*,name(../..)="tensor",@role="leftsuper"'.split(","),'Rule,leftsuper,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "super\u00edndice izquierdo"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="leftsuper"'.split(","),'Rule,rightsub,default,[t] "sub\u00edndice derecho"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsub"'.split(","),'Rule,rightsub,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "sub\u00edndice derecho"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsub"'.split(","), +'Rule,rightsuper,default,[t] "super\u00edndice derecho"; [p] (pause:200),self::*,name(../..)="tensor",@role="rightsuper"'.split(","),'Rule,rightsuper,default,[t] CSFordinalPosition (grammar:gender="male"); [t] "super\u00edndice derecho"; [p] (pause:200),self::*,name(../..)="punctuated",name(../../../..)="tensor",../../@role="rightsuper"'.split(","),'Rule,choice,default,[t] "cantidad de elecci\u00f3n"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=0'.split(","), +'Rule,select,default,[t] "cantidad de selecci\u00f3n"; [p] (pause:200),self::line,@role="binomial",parent::*/parent::vector,count(preceding-sibling::*)=1'.split(","),["Rule","row","default",'[t] CSFordinalPosition (grammar:gender="female"); [t] "fila"; [p] (pause:200)',"self::row"],["Aliases","row","self::line"],'Rule{cell{default{[n] ../..; [t] CSFordinalPosition (grammar:gender="female"); [t] "columna"; [p] (pause:200){self::cell{contains(@grammar,"depth")'.split("{"),["Rule","cell","default",'[t] CSFordinalPosition (grammar:gender="female"); [t] "columna"; [p] (pause:200)', +"self::cell"]]};sre.SemanticTreeRules={domain:"default",functions:[["CTXF","CTXFnodeCounter",sre.StoreUtil.nodeCounter],["CTXF","CTXFcontentIterator",sre.StoreUtil.contentIterator]],rules:['Rule{collapsed{default{[t] "collapsed"; [n] . (engine:modality=summary,grammar:collapsed){self::*{@alternative{not(contains(@grammar, "collapsed")){self::*{self::*{self::*{self::*{self::*'.split("{"),["Rule","stree","default","[n] ./*[1]","self::stree"],'Rule;factorial;default;[t] "factorial";self::punctuation;text()="!";name(preceding-sibling::*[1])!="text"'.split(";"), +["Rule","multrel","default",'[t] "multirelation"; [m] children/* (sepFunc:CTXFcontentIterator)',"self::multirel"],'Rule{variable-equality{default{[t] "equation sequence"; [m] children/* (context:"part",ctxtFunc:CTXFnodeCounter,sepFunc:CTXFcontentIterator){self::relseq[@role="equality"]{count(./children/*)>2{./children/punctuation[@role="ellipsis"]'.split("{"),'Rule{multi-equality{default{[t] "equation sequence"; [m] children/* (context:"part",ctxtFunc:CTXFnodeCounter,sepFunc:CTXFcontentIterator){self::relseq[@role="equality"]{count(./children/*)>2'.split("{"), +'Rule,equality,default,[n] children/*[1]; [p] (pause:200); [n] content/*[1] (pause:200);[n] children/*[2],self::relseq[@role="equality"],count(./children/*)=2'.split(","),'Rule,simple-equality,default,[n] children/*[1]; [p] (pause:200); [n] content/*[1] (pause:200);[n] children/*[2],self::relseq[@role="equality"],count(./children/*)=2,./children/identifier or ./children/number'.split(","),'Rule,simple-equality2,default,[n] children/*[1]; [p] (pause:200); [n] content/*[1] (pause:200);[n] children/*[2],self::relseq[@role="equality"],count(./children/*)=2,./children/function or ./children/appl'.split(","), +["Rule","relseq","default","[m] children/* (sepFunc:CTXFcontentIterator)","self::relseq"],["Rule","binary-operation","default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop"],'Rule,variable-addition,default,[t] "sum with variable number of summands";[p] (pause:400); [m] children/* (sepFunc:CTXFcontentIterator),self::infixop[@role="addition"],count(children/*)>2,children/punctuation[@role="ellipsis"]'.split(","),'Rule,multi-addition,default,[t] "sum with"; [t] count(./children/*); [t] "summands";[p] (pause:400); [m] children/* (sepFunc:CTXFcontentIterator),self::infixop[@role="addition"],count(./children/*)>2'.split(","), +["Rule","prefix","default",'[t] "prefix"; [m] content/* (pause 150);[n] children/*[1]',"self::prefixop"],'Rule,negative,default,[t] "negative"; [n] children/*[1],self::prefixop,self::prefixop[@role="negative"]'.split(","),["Rule","postfix","default",'[n] children/*[1]; [t] "postfix"; [m] content/* (pause 300)',"self::postfixop"],["Rule","identifier","default","[n] text()","self::identifier"],["Rule","number","default","[n] text()","self::number"],'Rule,mixed-number,default,[n] children/*[1]; [t] "and"; [n] children/*[2]; ,self::number,@role="mixed"'.split(","), +'Rule{font{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::*{@font{not(contains(@grammar, "ignoreFont")){@font!="normal"'.split("{"),'Rule{font-identifier-short{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{not(contains(@grammar, "ignoreFont")){@font="normal"{""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", ""){@role!="unit"'.split("{"), +'Rule{font-identifier{default{[t] @font (grammar:localFont); [n] . (grammar:ignoreFont=@font){self::identifier{string-length(text())=1{@font{@font="normal"{not(contains(@grammar, "ignoreFont")){@role!="unit"'.split("{"),'Rule;omit-font;default;[n] . (grammar:ignoreFont=@font);self::identifier;string-length(text())=1;@font;not(contains(@grammar, "ignoreFont"));@font="italic"'.split(";"),["Rule","fraction","default",'[p] (pause:250); [n] children/*[1] (rate:0.35); [p] (pause:250); [t] "divided by"; [n] children/*[2] (rate:-0.35); [p] (pause:400)', +"self::fraction"],["Rule","superscript","default",'[n] children/*[1]; [t] "super"; [n] children/*[2] (pitch:0.35);[p] (pause:300)',"self::superscript"],["Rule","subscript","default",'[n] children/*[1]; [t] "sub"; [n] children/*[2] (pitch:-0.35);[p] (pause:300)',"self::subscript"],'Rule,ellipsis,default,[p] (pause:200); [t] "ellipsis"; [p] (pause:300),self::punctuation,self::punctuation[@role="ellipsis"]'.split(","),'Rule;fence-single;default;[n] text();self::punctuation;self::punctuation[@role="openfence"]'.split(";"), +["Aliases","fence-single","self::punctuation",'self::punctuation[@role="closefence"]'],["Aliases","fence-single","self::punctuation",'self::punctuation[@role="vbar"]'],["Aliases","fence-single","self::punctuation",'self::punctuation[@role="application"]'],["Rule","omit-empty","default","[p] (pause:100)","self::empty"],'Rule,fences-open-close,default,[p] (pause:100); [n] content/*[1]; [n] children/*[1]; [n] content/*[2]; [p] (pause:100),self::fenced,@role="leftright"'.split(","),'Rule,fences-open-close-in-appl,default,[p] (pause:200); [n] children/*[1]; [p] (pause:200);,self::fenced[@role="leftright"],./parent::children/parent::appl'.split(","), +'Rule,fences-neutral,default,[p] (pause:100); [t] "absolute value of"; [n] children/*[1];[p] (pause:350);,self::fenced,self::fenced[@role="neutral"]'.split(","),["Rule","omit-fences","default","[p] (pause:500); [n] children/*[1]; [p] (pause:200);","self::fenced"],["Rule","matrix","default",'[t] "matrix"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:100)',"self::matrix"],["Rule","matrix-row","default",'[m] children/* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)','self::row[@role="matrix"]'], +["Rule","matrix-cell","default","[n] children/*[1]",'self::cell[@role="matrix"]'],["Rule","vector","default",'[t] "vector"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"element",pause:100)',"self::vector"],["Rule","cases","default",'[t] "case statement"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"case",pause:100)',"self::cases"],["Rule","cases-row","default","[m] children/*",'self::row[@role="cases"]'],["Rule","cases-cell","default","[n] children/*[1]",'self::cell[@role="cases"]'],["Rule", +"row","default",'[m] ./* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)',"self::row"],'Rule{cases-end{default{[t] "case statement"; [m] children/* (ctxtFunc:CTXFnodeCounter,context:"case",pause:100);[t] "end cases"{self::cases{following-sibling::*'.split("{"),["Rule","multiline","default",'[t] "multiline equation";[m] children/* (ctxtFunc:CTXFnodeCounter,context:"line",pause:100)',"self::multiline"],'Rule{multiline-ineq{default{[t] "multiline inequality";[m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:100){self::multiline{@role="inequality"'.split("{"), +["Rule","line","default","[m] children/*","self::line"],["Rule","table","default",'[t] "multiline equation";[m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:200)',"self::table"],'Rule{table-ineq{default{[t] "multiline inequality";[m] children/* (ctxtFunc:CTXFnodeCounter,context:"row",pause:200){self::table{@role="inequality"'.split("{"),["Rule","table-row","default","[m] children/* (pause:100)",'self::row[@role="table"]'],["Aliases","cases-cell",'self::cell[@role="table"]'],'Rule;empty-cell;default;[t] "Blank";self::cell;count(children/*)=0'.split(";"), +'Rule,end-punct,default,[m] children/*; [p] (pause:300),self::punctuated,@role="endpunct"'.split(","),'Rule,start-punct,default,[n] content/*[1]; [p] (pause:200); [m] children/*[position()>1],self::punctuated,@role="startpunct"'.split(","),'Rule,integral-punct,default,[n] children/*[1] (rate:0.2); [n] children/*[3] (rate:0.2),self::punctuated,@role="integral"'.split(","),["Rule","punctuated","default","[m] children/* (pause:100)","self::punctuated"],["Rule","function","default","[n] text()","self::function"], +["Rule","appl","default","[n] children/*[1]; [n] content/*[1]; [n] children/*[2]","self::appl"],'Rule,sum-only,default,[n] children/*[1]; [t] "from"; [n] children/*[2]; [t] "to";[n] children/*[3],self::limboth,self::limboth[@role="sum"]'.split(","),["Rule","limboth","default",'[n] children/*[1]; [p] (pause 100); [t] "over"; [n] children/*[2];[t] "under"; [n] children/*[3]; [p] (pause 250);',"self::limboth"],["Rule","limlower","default",'[n] children/*[1]; [t] "over"; [n] children/*[2];',"self::limlower"], +["Rule","limupper","default",'[n] children/*[1]; [t] "under"; [n] children/*[2];',"self::limupper"],["Rule","largeop","default","[n] text()","self::largeop"],["Rule","bigop","default",'[n] children/*[1]; [p] (pause 100); [t] "over"; [n] children/*[2];[p] (pause 250);',"self::bigop"],["Rule","integral","default","[n] children/*[1]; [p] (pause 100); [n] children/*[2];[p] (pause 200); [n] children/*[3] (rate:0.35);","self::integral"],["Rule","sqrt","default",'[t] "Square root of"; [n] children/*[1] (rate:0.35); [p] (pause:400)', +"self::sqrt"],'Rule,square,default,[n] children/*[1]; [t] "squared" (pitch:0.35); [p] (pause:300),self::superscript,children/*[2][text()=2],name(./children/*[1])!="text"'.split(","),'Rule,cube,default,[n] children/*[1]; [t] "cubed" (pitch:0.35); [p] (pause:300),self::superscript,children/*[2][text()=3],name(./children/*[1])!="text"'.split(","),["Rule","root","default",'[t] "root of order"; [n] children/*[1];[t] "over"; [n] children/*[2] (rate:0.35); [p] (pause:400)',"self::root"],["Rule","text","default", +"[n] text(); [p] (pause:200)","self::text"],'Rule;unit;default;[t] text() (grammar:annotation="unit":translate:plural);self::identifier;@role="unit"'.split(";"),'Rule,unit-square,default,[t] "square"; [n] children/*[1],self::superscript,@role="unit",children/*[2][text()=2],name(children/*[1])="identifier"'.split(","),'Rule,unit-cubic,default,[t] "cubic"; [n] children/*[1],self::superscript,@role="unit",children/*[2][text()=3],name(children/*[1])="identifier"'.split(","),'Rule,reciprocal,default,[t] "reciprocal"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],count(preceding-sibling::*)=0 or preceding-sibling::*[@role!="unit"]'.split(","), +'Rule,reciprocal,default,[t] "per"; [n] children/*[1],self::superscript,@role="unit",name(children/*[1])="identifier",name(children/*[2])="prefixop",children/*[2][@role="negative"],children/*[2]/children/*[1][text()=1],preceding-sibling::*[@role="unit"]'.split(","),'Rule;unit-combine;default;[m] children/*;self::infixop;@role="unit"'.split(";"),'Rule,unit-divide,default,[n] children/*[1] (pitch:0.3); [t] "per"; [n] children/*[2] (pitch:-0.3),self::fraction,@role="unit"'.split(",")]};sre.SummaryFrench={locale:"fr",modality:"summary",rules:[["Rule","collapsed-masculine","default.masculine",'[t] "compress\u00e9"','contains(@grammar, "collapsed")'],["Rule","collapsed-feminine","default.feminine",'[t] "compress\u00e9e"','contains(@grammar, "collapsed")'],["Rule","no-collapsed","default.masculine",'[t] ""','not(contains(@grammar, "collapsed"))'],["Rule","no-collapsed","default.feminine",'[t] ""','not(contains(@grammar, "collapsed"))'],["Rule","stree","default.default","[n] ./*[1]", +"self::stree"],'Rule{abstr-identifier{default.default{[t] "identifiant long"; [n] . (engine:style=masculine){self::identifier{contains(@grammar, "collapsed")'.split("{"),["Rule","abstr-identifier","default.default",'[t] "identifiant"; [n] . (engine:style=masculine)',"self::identifier"],'Rule{abstr-number{default.default{[t] "nombre long"; [n] . (engine:style=masculine){self::number{contains(@grammar, "collapsed")'.split("{"),["Rule","abstr-number","default.default",'[t] "nombre"; [n] . (engine:style=masculine)', +"self::number"],'Rule{abstr-mixed-number{default.default{[t] "nombre fractionnaire long"; [n] . (engine:style=masculine){self::number{@role="mixed"{contains(@grammar, "collapsed")'.split("{"),'Rule,abstr-mixed-number,default.default,[t] "nombre fractionnaire"; [n] . (engine:style=masculine),self::number,@role="mixed"'.split(","),["Rule","abstr-text","default.default",'[t] "texte"; [n] . (engine:style=masculine)',"self::text"],["Rule","abstr-function","default.default",'[t] "expression fonctionnelle"; [n] . (engine:style=feminine)', +"self::function"],["Rule","abstr-function","mathspeak.brief",'[t] "fonction"; [n] . (engine:style=feminine)',"self::function"],["SpecializedRule","abstr-function","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-lim,default.default,[t] "fonction de limitation"; [n] . (engine:style=feminine),self::function,@role="limit function"'.split(","),'Rule,abstr-lim,mathspeak.brief,[t] "lim"; [n] . (engine:style=feminine),self::function,@role="limit function"'.split(","),["SpecializedRule","abstr-lim","mathspeak.brief", +"mathspeak.sbrief"],["Rule","abstr-fraction","default.default",'[t] "fraction"; [n] . (engine:style=feminine)',"self::fraction"],["Rule","abstr-fraction","mathspeak.brief",'[t] "frac"; [n] . (engine:style=feminine)',"self::fraction"],["SpecializedRule","abstr-fraction","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-continued-fraction,default.default,[t] "fraction continue"; [n] . (engine:style=feminine),self::fraction,children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(","),'Rule,abstr-continued-fraction,mathspeak.brief,[t] "frac continue"; [n] . (engine:style=feminine),self::fraction,children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(","), +["SpecializedRule","abstr-continued-fraction","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-sqrt","default.default",'[t] "racine carr\u00e9e"; [n] . (engine:style=feminine)',"self::sqrt"],'Rule,abstr-sqrt-nested,default.default,[t] "racine carr\u00e9e imbriqu\u00e9e"; [n] . (engine:style=feminine),self::sqrt,children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(","),'Rule{abstr-root{default.default{[t] "racine d\'indice"; [n] children/*[1] (engine:modality="speech"); [t] "fin indice"; [n] . (engine:style=feminine);{self::root{contains(@grammar, "collapsed"){following-sibling::* or ancestor::*/following-sibling::*'.split("{"), +["Rule","abstr-root","default.default",'[t] "racine d\'indice"; [n] children/*[1] (engine:modality=speech); [n] . (engine:style=feminine)',"self::root"],["Rule","abstr-root","mathspeak.brief",'[t] "racine"; [n] . (engine:style=feminine)',"self::root"],["SpecializedRule","abstr-root","mathspeak.brief","mathspeak.sbrief"],'Rule{abstr-root-nested{default.default{[t] "racine imbriqu\u00e9e d\'indice"; [n] children/*[1] (engine:modality=speech); [t] "fin indice"; [n] . (engine:style=feminine);{self::root{contains(@grammar, "collapsed"){children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root{following-sibling::* or ancestor::*/following-sibling::*'.split("{"), +'Rule,abstr-root-nested,default.default,[t] "racine imbriqu\u00e9e d\'indice"; [n] children/*[1] (engine:modality=speech); [n] . (engine:style=feminine),self::root,children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(","),'Rule,abstr-root-nested,mathspeak.brief,[t] "racine imbriqu\u00e9e"; [n] . (engine:style=feminine),self::root,children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(","),["SpecializedRule","abstr-root-nested","mathspeak.brief", +"mathspeak.sbrief"],["Rule","abstr-superscript","default.default",'[t] "puissance"; [n] . (engine:style=feminine)',"self::superscript"],["Rule","abstr-subscript","default.default",'[t] "indice"; [n] . (engine:style=masculine)',"self::subscript"],'Rule,abstr-subsup,default.default,[t] "puissance avec index"; [n] . (engine:style=feminine),self::superscript,name(children/*[1])="subscript"'.split(","),["Rule","abstr-infixop","default.default",'[t] @role (grammar:localRole); [t] "avec"; [t] count(./children/*); [t] "\u00e9l\u00e9ments"; [n] . (engine:style=masculine)', +"self::infixop"],'Rule,abstr-infixop,default.default,[t] @role (grammar:localRole); [t] "avec un nombre d\'\u00e9l\u00e9ments variable"; [n] . (engine:style=masculine),self::infixop,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","),["Rule","abstr-infixop","mathspeak.brief","[t] @role (grammar:localRole); [n] . (engine:style=masculine)","self::infixop"],["SpecializedRule","abstr-infixop","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-addition,default.default,[t] "somme avec"; [t] count(./children/*); [t] "op\u00e9randes"; [n] . (engine:style=feminine),self::infixop,@role="addition"'.split(","), +'Rule,abstr-addition,mathspeak.brief,[t] "somme"; [n] . (engine:style=feminine),self::infixop,@role="addition"'.split(","),["SpecializedRule","abstr-addition","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-addition,default.default,[t] "somme avec un nombre variable d\'op\u00e9randes"; [n] . (engine:style=feminine),self::infixop,@role="addition",count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","),'Rule,abstr-multiplication,default.default,[t] "produit avec"; [t] count(./children/*); [t] "facteurs"; [n] . (engine:style=masculine);,self::infixop,@role="multiplication"'.split(","), +'Rule,abstr-multiplication,mathspeak.brief,[t] "produit"; [n] . (engine:style=masculine),self::infixop,@role="multiplication"'.split(","),["SpecializedRule","abstr-multiplication","mathspeak.brief","mathspeak.sbrief"],["Aliases","abstr-multiplication","self::infixop",'@role="implicit"'],'Rule,abstr-var-multiplication,default.default,[t] "produit avec un nombre de facteurs variable"; [n] . (engine:style=masculine),self::infixop,@role="multiplication",count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","), +'Aliases abstr-var-multiplication self::infixop @role="implicit" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "),["Rule","abstr-vector","default.default",'[t] "vecteur de dimension"; [t] count(./children/*); [n] . (engine:style=masculine)',"self::vector"],["Rule","abstr-vector","mathspeak.brief",'[t] "vecteur"; [n] . (engine:style=masculine)',"self::vector"],["SpecializedRule","abstr-vector","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-vector,default.default,[t] "vecteur colonne de dimension n"; [n] . (engine:style=masculine),self::vector,./children/*/children/punctuation[@role="ellipsis"]'.split(","), +'Rule,abstr-binomial,default.default,[t] "binomial"; [n] . (engine:style=masculine),self::vector,@role="binomial"'.split(","),["SpecializedRule","abstr-binomial","default.default","mathspeak.brief"],["SpecializedRule","abstr-binomial","default.default","mathspeak.sbrief"],'Rule,abstr-determinant,default.default,[t] "d\u00e9terminant de dimension"; [t] count(./children/*); [n] . (engine:style=masculine),self::matrix,@role="determinant"'.split(","),'Rule,abstr-determinant,mathspeak.brief,[t] "d\u00e9terminant"; [n] . (engine:style=masculine),self::matrix,@role="determinant"'.split(","), +["SpecializedRule","abstr-determinant","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-determinant,default.default,[t] "d\u00e9terminant de dimension n"; [n] . (engine:style=masculine),self::matrix,@role="determinant",./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(","),'Rule,abstr-squarematrix,default.default,[t] "matrice carr\u00e9e de dimension"; [t] count(./children/*); [n] . (engine:style=feminine),self::matrix,@role="squarematrix"'.split(","),'Rule,abstr-squarematrix,mathspeak.brief,[t] "matrice carr\u00e9e"; [n] . (engine:style=feminine),self::matrix,@role="squarematrix"'.split(","), +["SpecializedRule","abstr-squarematrix","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-rowvector,default.default,[t] "vecteur ligne de dimension"; [t] count(./children/row/children/*); [n] . (engine:style=masculine),self::matrix,@role="rowvector"'.split(","),'Rule,abstr-rowvector,mathspeak.brief,[t] "vecteur ligne"; [n] . (engine:style=masculine),self::matrix,@role="rowvector"'.split(","),["SpecializedRule","abstr-rowvector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "vecteur ligne de dimension n";self::matrix;@role="rowvector";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"), +["Rule","abstr-matrix","default.default",'[t] "matrice"; [t] count(children/*); [t] "par";[t] count(children/*[1]/children/*); [n] . (engine:style=feminine)',"self::matrix"],["Rule","abstr-matrix","mathspeak.brief",'[t] "matrice"; [n] . (engine:style=feminine)',"self::matrix"],["SpecializedRule","abstr-matrix","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-matrix,default.default,[t] "matrice de dimension n par m"; [n] . (engine:style=feminine),self::matrix,./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(","), +["Rule","abstr-cases","default.default",'[t] "d\u00e9claration de cas";[t] "avec"; [t] count(children/*); [t] "cas"; [n] . (engine:style=feminine)',"self::cases"],["Rule","abstr-cases","mathspeak.brief",'[t] "d\u00e9claration de cas"; [n] . (engine:style=feminine)',"self::cases"],["SpecializedRule","abstr-cases","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-cases,default.default,[t] "d\u00e9claration de cas variable"; [n] . (engine:style=feminine),self::cases,./children/row/children/cell/children/punctuation[@role="ellipsis"]or ./children/line/children/punctuation[@role="ellipsis"]'.split(","), +["Rule","abstr-punctuated","default.default",'[t] "liste de longueur"; [t] count(children/*) - count(content/*); [t] "s\u00e9par\u00e9e par des"; [n] content/*[1] (join:""); [t] "s"; [n] . (engine:style=feminine)',"self::punctuated"],["Rule","abstr-punctuated","mathspeak.brief",'[t] "liste s\u00e9par\u00e9e par des"; [n] content/*[1] (join:""); [t] "s"; [n] . (engine:style=feminine)',"self::punctuated"],["SpecializedRule","abstr-punctuated","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-punctuated,default.default,[t] "liste de longueur variable s\u00e9par\u00e9e par des"; [n] content/*[1] (join:""); [t] "s"; [n] . (engine:style=feminine),self::punctuated,./children/punctuation[@role="ellipsis"]'.split(","), +["Rule","abstr-bigop","default.default","[n] content/*[1]; [n] . (engine:style=masculine)","self::bigop"],["Rule","abstr-integral","default.default",'[t] "int\u00e9grale"; [n] . (engine:style=feminine)','@role="integral"'],"Rule,abstr-relation,default.default,[t] @role (grammar:localRole); [n] . (engine:style=masculine);,self::relseq,count(./children/*)=2".split(","),'Rule,abstr-relation-seq,default.default,[t] @role (grammar:localRole); [t] "s\u00e9quence"; [t] "avec"; [t] count(./children/*); [t] "\u00e9l\u00e9ments"; [n] . (engine:style=feminine),self::relseq,count(./children/*)>2'.split(","), +'Rule,abstr-relation-seq,mathspeak.brief,[t] @role (grammar:localRole); [t] "s\u00e9quence"; [n] . (engine:style=feminine),self::relseq,count(./children/*)>2'.split(","),["SpecializedRule","abstr-relation-seq","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-relation,default.default,[t] @role (grammar:localRole); [t] "s\u00e9quence"; [t] "avec un nombre de \u00e9l\u00e9ments variable"; [n] . (engine:style=feminine),self::relseq,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","), +'UniqueAlias abstr-relation default.default self::multirel @role!="unknown" count(./children/*)>2'.split(" "),'Aliases abstr-var-relation self::multirel @role!="unknown" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "),'Rule,abstr-multirel,default.default,[t] "s\u00e9quence de relation"; [t] "avec"; [t] count(./children/*); [t] "\u00e9l\u00e9ments"; [n] . (engine:style=feminine),self::multirel,count(./children/*)>2'.split(","),'Rule,abstr-multirel,mathspeak.brief,[t] "s\u00e9quence de relation"; [n] . (engine:style=feminine),self::multirel,count(./children/*)>2'.split(","), +["SpecializedRule","abstr-multirel","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-multirel,default.default,[t] "s\u00e9quence de relation avec un nombre de \u00e9l\u00e9ments variable"; [n] . (engine:style=feminine),self::multirel,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","),["Rule","abstr-table","default.default",'[t] "table avec"; [t] count(children/*); [t] "lignes et";[t] count(children/*[1]/children/*); [t] "colonnes"; [n] . (engine:style=feminine);',"self::table"], +["Rule","abstr-line","default.default",'[t] "dans"; [t] @role (grammar:localRole); [n] . (engine:style=masculine)',"self::line"],["Rule","abstr-row","default.default",'[t] "dans"; [t] @role (grammar:localRole);[t] count(preceding-sibling::..); [t] "avec";[t] count(children/*); [t] "colonnes"; [n] . (engine:style=feminine)',"self::row"],["Rule","abstr-cell","default.default",'[t] "dans"; [t] @role (grammar:localRole); [n] . (engine:style=feminine);',"self::cell"]]};sre.SummaryGerman={modality:"summary",locale:"de",rules:['Rule;abstr-identifier;default.default;[t] "langer Bezeichner";self::identifier;contains(@grammar, "collapsed")'.split(";"),["Rule","abstr-identifier","default.default",'[t] "Bezeichner"',"self::identifier"],'Rule;abstr-number;default.default;[t] "lange Zahl";self::number;contains(@grammar, "collapsed")'.split(";"),["Rule","abstr-number","default.default",'[t] "Zahl"',"self::number"],'Rule;abstr-mixed-number;default.default;[t] "langer gemischter Bruch";self::number;@role="mixed";contains(@grammar, "collapsed")'.split(";"), +'Rule;abstr-mixed-number;default.default;[t] "gemischter Bruch";self::number;@role="mixed"'.split(";"),["Rule","abstr-text","default.default",'[t] "Text"',"self::text"],["Rule","abstr-function","default.default",'[t] "Funktionsausdruck"',"self::function"],["Rule","abstr-function","mathspeak.brief",'[t] "Funktion"',"self::function"],["SpecializedRule","abstr-function","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-lim;default.default;[t] "Grenzwertfunktion";self::function;@role="limit function"'.split(";"), +'Rule;abstr-lim;mathspeak.brief;[t] "Grenzwert";self::function;@role="limit function"'.split(";"),["SpecializedRule","abstr-lim","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-fraction","default.default",'[t] "Bruch"',"self::fraction"],'Rule;abstr-continued-fraction;default.default;[t] "Kettenbruch";self::fraction;children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(";"),["Rule","abstr-sqrt","default.default",'[t] "Quadratwurzel"',"self::sqrt"],'Rule;abstr-sqrt-nested;default.default;[t] "verschachtelte Quadratwurzel";self::sqrt;children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(";"), +'Rule{abstr-root{default.default{[t] "Wurzel mit Exponent"; [n] children/*[1] (engine:modality=speech); [t] "Exponentende"{self::root{contains(@grammar, "collapsed"){following-sibling::* or ancestor::*/following-sibling::*'.split("{"),["Rule","abstr-root","default.default",'[t] "Wurzel mit Exponent"; [n] children/*[1] (engine:modality=speech)',"self::root"],["Rule","abstr-root","mathspeak.brief",'[t] "Wurzel"',"self::root"],["SpecializedRule","abstr-root","mathspeak.brief","mathspeak.sbrief"],'Rule{abstr-root-nested{default.default{[t] "verschachtelte Wurzel mit Wurzelexponent"; [n] children/*[1] (engine:modality="speech"); [t] "Ende Wurzelexponent"{self::root{contains(@grammar, "collapsed"){children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root{following-sibling::* or ancestor::*/following-sibling::*'.split("{"), +'Rule,abstr-root-nested,default.default,[t] "verschachtelte Wurzel mit Exponent"; [n] children/*[1] (engine:modality="speech"),self::root,children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(","),'Rule;abstr-root-nested;mathspeak.brief;[t] "verschachtelte Wurzel";self::root;children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(";"),["SpecializedRule","abstr-root-nested","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-superscript","default.default", +'[t] "Potenz"',"self::superscript"],["Rule","abstr-subscript","default.default",'[t] "Index"',"self::subscript"],'Rule;abstr-subsup;default.default;[t] "Potenz mit Index";self::superscript;name(children/*[1])="subscript"'.split(";"),["Rule","abstr-infixop","default.default",'[t] @role (grammar:localRole); [t] "mit"; [t] count(./children/*); [t] "Elementen"',"self::infixop"],'Rule,abstr-infixop,default.default,[t] @role (grammar:localRole); [t] "mit ver\u00e4nderlicher Anzahl an Elementen",self::infixop,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","), +["Rule","abstr-infixop","mathspeak.brief","[t] @role (grammar:localRole)","self::infixop"],["SpecializedRule","abstr-infixop","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-addition,default.default,[t] "Summe mit"; [t] count(./children/*); [t] "Summanden",self::infixop,@role="addition"'.split(","),'Rule;abstr-addition;mathspeak.brief;[t] "Summe";self::infixop;@role="addition"'.split(";"),["SpecializedRule","abstr-addition","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-addition;default.default;[t] "Summe mit ver\u00e4nderlicher Anzahl an Summanden";self::infixop;@role="addition";count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +'Rule,abstr-multiplication,default.default,[t] "Produkt mit"; [t] count(./children/*); [t] "Faktoren",self::infixop,@role="multiplication"'.split(","),'Rule;abstr-multiplication;mathspeak.brief;[t] "Produkt";self::infixop;@role="multiplication"'.split(";"),["SpecializedRule","abstr-multiplication","mathspeak.brief","mathspeak.sbrief"],["Aliases","abstr-multiplication","self::infixop",'@role="implicit"'],'Rule;abstr-var-multiplication;default.default;[t] "Produkt mit ver\u00e4nderlicher Anzahl an Faktoren";self::infixop;@role="multiplication";count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +'Aliases abstr-var-multiplication self::infixop @role="implicit" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "),["Rule","abstr-vector","default.default",'[t] count(./children/*) ; [t] "dimensionaler Vektor"',"self::vector"],["Rule","abstr-vector","mathspeak.brief",'[t] "Vektor"',"self::vector"],["SpecializedRule","abstr-vector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-vector;default.default;[t] "n dimensionaler Vektor";self::vector;./children/*/children/punctuation[@role="ellipsis"]'.split(";"), +'Rule;abstr-binomial;default.default;[t] "Binomialkoeffizient";self::vector;@role="binomial"'.split(";"),["SpecializedRule","abstr-binomial","default.default","mathspeak.brief"],["SpecializedRule","abstr-binomial","default.default","mathspeak.sbrief"],'Rule,abstr-determinant,default.default,[t] count(./children/*); [t] "dimensionale Determinante",self::matrix,@role="determinant"'.split(","),'Rule;abstr-determinant;mathspeak.brief;[t] "Determinante";self::matrix;@role="determinant"'.split(";"),["SpecializedRule", +"abstr-determinant","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-determinant;default.default;[t] "n dimensionale Determinante";self::matrix;@role="determinant";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"),'Rule,abstr-squarematrix,default.default,[t] count(./children/*); [t] "dimensionale quadratische Matrize",self::matrix,@role="squarematrix"'.split(","),'Rule;abstr-squarematrix;mathspeak.brief;[t] "quadratische Matrize";self::matrix;@role="squarematrix"'.split(";"), +["SpecializedRule","abstr-squarematrix","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-rowvector,default.default,[t] count(./children/row/children/*); [t] "dimensionaler Zeilenvektor",self::matrix,@role="rowvector"'.split(","),'Rule;abstr-rowvector;mathspeak.brief;[t] "Zeilenvektor";self::matrix;@role="rowvector"'.split(";"),["SpecializedRule","abstr-rowvector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "n dimensionaler Zeilenvektor";self::matrix;@role="rowvector";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"), +["Rule","abstr-matrix","default.default",'[t] count(children/*); [t] "mal";[t] count(children/*[1]/children/*); [t] "Matrize"',"self::matrix"],["Rule","abstr-matrix","mathspeak.brief",'[t] "Matrize"',"self::matrix"],["SpecializedRule","abstr-matrix","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "n mal m dimensionale Matrize";self::matrix;./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-cases","default.default",'[t] "Fallunterscheidung";[t] "mit"; [t] count(children/*); [t] "F\u00e4llen"', +"self::cases"],["Rule","abstr-cases","mathspeak.brief",'[t] "Fallunterscheidung"',"self::cases"],["SpecializedRule","abstr-cases","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-cases;default.default;[t] "Fallunterscheidung mit ver\u00e4nderlicher Anzahl an F\u00e4llen";self::cases;./children/row/children/cell/children/punctuation[@role="ellipsis"]or ./children/line/children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-punctuated","default.default",'[t] "mit"; [n] content/*[1]; [t] "getrennte Liste der L\u00e4nge"; [t] count(children/*) - count(content/*)', +"self::punctuated"],["Rule","abstr-punctuated","mathspeak.brief",'[t] "mit"; [n] content/*[1]; [t] "getrennte Liste";',"self::punctuated"],["SpecializedRule","abstr-punctuated","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-punctuated,default.default,[t] "mit"; [n] content/*[1]; [t] "getrennte Liste";[t] "ver\u00e4nderlicher L\u00e4nge",self::punctuated,./children/punctuation[@role="ellipsis"]'.split(","),["Rule","abstr-bigop","default.default","[n] content/*[1]","self::bigop"],["Rule","abstr-integral", +"default.default",'[t] "Integral"','@role="integral"'],"Rule,abstr-relation,default.default,[t] @role (grammar:localRole);,self::relseq,count(./children/*)=2".split(","),'Rule{abstr-relation-seq{default.default{[t] @role (grammar:localRole, join:""); [t] "ssequenz"; [t] "mit"; [t] count(./children/*); [t] "Elementen"{self::relseq{count(./children/*)>2'.split("{"),'Rule{abstr-relation-seq{mathspeak.brief{[t] @role (grammar:localRole, join:""); [t] "ssequenz"{self::relseq{count(./children/*)>2'.split("{"), +["SpecializedRule","abstr-relation-seq","mathspeak.brief","mathspeak.sbrief"],'Rule{abstr-var-relation{default.default{[t] @role (grammar:localRole, join:""); [t] "ssequenz";[t] "mit ver\u00e4nderlicher Anzahl an Elementen"{self::relseq{count(./children/*)>2{./children/punctuation[@role="ellipsis"]'.split("{"),'UniqueAlias abstr-relation default.default self::multirel @role!="unknown" count(./children/*)>2'.split(" "),'Aliases abstr-var-relation self::multirel @role!="unknown" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "), +'Rule,abstr-multirel,default.default,[t] "Relationsequenz"; [t] "mit"; [t] count(./children/*); [t] "Elementen",self::multirel,count(./children/*)>2'.split(","),'Rule;abstr-multirel;mathspeak.brief;[t] "Relationsequenz";self::multirel;count(./children/*)>2'.split(";"),["SpecializedRule","abstr-multirel","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-multirel;default.default;[t] "Relationsequenz mit ver\u00e4nderlicher Anzahl an Elementen";self::multirel;count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +["Rule","abstr-table","default.default",'[t] "Tabelle mit"; [t] count(children/*); [t] "Zeilen und";[t] count(children/*[1]/children/*); [t] "Spalten"',"self::table"],["Rule","abstr-line","default.default",'[t] "in"; [t] @role (grammar:localRole);',"self::line"],["Rule","abstr-row","default.default",'[t] "in"; [t] @role (grammar:localRole);[t] count(preceding-sibling::..); [t] "mit";[t] count(children/*); [t] "Spalten"',"self::row"],["Rule","abstr-cell","default.default",'[t] "in"; [t] @role (grammar:localRole);', +"self::cell"]]};sre.SummaryRules={modality:"summary",rules:['Rule;abstr-identifier;default.default;[t] "long identifier";self::identifier;contains(@grammar, "collapsed")'.split(";"),["Rule","abstr-identifier","default.default",'[t] "identifier"',"self::identifier"],'Rule;abstr-number;default.default;[t] "long number";self::number;contains(@grammar, "collapsed")'.split(";"),["Rule","abstr-number","default.default",'[t] "number"',"self::number"],'Rule;abstr-mixed-number;default.default;[t] "long mixed number";self::number;@role="mixed";contains(@grammar, "collapsed")'.split(";"), +'Rule;abstr-mixed-number;default.default;[t] "mixed number";self::number;@role="mixed"'.split(";"),["Rule","abstr-text","default.default",'[t] "text"',"self::text"],["Rule","abstr-function","default.default",'[t] "functional expression"',"self::function"],["Rule","abstr-function","mathspeak.brief",'[t] "function"',"self::function"],["SpecializedRule","abstr-function","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-lim;default.default;[t] "limit function";self::function;@role="limit function"'.split(";"), +'Rule;abstr-lim;mathspeak.brief;[t] "lim";self::function;@role="limit function"'.split(";"),["SpecializedRule","abstr-lim","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-fraction","default.default",'[t] "fraction"',"self::fraction"],["Rule","abstr-fraction","mathspeak.brief",'[t] "frac"',"self::fraction"],["SpecializedRule","abstr-fraction","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-continued-fraction;default.default;[t] "continued fraction";self::fraction;children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(";"), +'Rule;abstr-continued-fraction;mathspeak.brief;[t] "continued frac";self::fraction;children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(";"),["SpecializedRule","abstr-continued-fraction","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-sqrt","default.default",'[t] "square root"',"self::sqrt"],'Rule;abstr-sqrt-nested;default.default;[t] "nested square root";self::sqrt;children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(";"),'Rule{abstr-root{default.default{[t] "root of index"; [n] children/*[1] (engine:modality="speech"); [t] "endindex"{self::root{contains(@grammar, "collapsed"){following-sibling::* or ancestor::*/following-sibling::*'.split("{"), +["Rule","abstr-root","default.default",'[t] "root of index"; [n] children/*[1] (engine:modality=speech)',"self::root"],["Rule","abstr-root","mathspeak.brief",'[t] "root"',"self::root"],["SpecializedRule","abstr-root","mathspeak.brief","mathspeak.sbrief"],'Rule{abstr-root-nested{default.default{[t] "nested root of index"; [n] children/*[1] (engine:modality="speech"); [t] "endindex"{self::root{contains(@grammar, "collapsed"){children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root{following-sibling::* or ancestor::*/following-sibling::*'.split("{"), +'Rule,abstr-root-nested,default.default,[t] "nested root of index"; [n] children/*[1] (engine:modality="speech"),self::root,children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(","),'Rule;abstr-root-nested;mathspeak.brief;[t] "nested root";self::root;children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(";"),["SpecializedRule","abstr-root-nested","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-superscript","default.default",'[t] "power"', +"self::superscript"],["Rule","abstr-subscript","default.default",'[t] "subscript"',"self::subscript"],'Rule;abstr-subsup;default.default;[t] "power with subscript";self::superscript;name(children/*[1])="subscript"'.split(";"),["Rule","abstr-infixop","default.default",'[t] @role (grammar:localRole); [t] "with"; [t] count(./children/*); [t] "elements"',"self::infixop"],'Rule,abstr-infixop,default.default,[t] @role (grammar:localRole); [t] "with variable number of elements",self::infixop,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","), +["Rule","abstr-infixop","mathspeak.brief","[t] @role (grammar:localRole)","self::infixop"],["SpecializedRule","abstr-infixop","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-addition,default.default,[t] "sum with"; [t] count(./children/*); [t] "summands",self::infixop,@role="addition"'.split(","),'Rule;abstr-addition;mathspeak.brief;[t] "sum";self::infixop;@role="addition"'.split(";"),["SpecializedRule","abstr-addition","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-addition;default.default;[t] "sum with variable number of summands";self::infixop;@role="addition";count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +'Rule,abstr-multiplication,default.default,[t] "product with"; [t] count(./children/*); [t] "factors",self::infixop,@role="multiplication"'.split(","),'Rule;abstr-multiplication;mathspeak.brief;[t] "product";self::infixop;@role="multiplication"'.split(";"),["SpecializedRule","abstr-multiplication","mathspeak.brief","mathspeak.sbrief"],["Aliases","abstr-multiplication","self::infixop",'@role="implicit"'],'Rule;abstr-var-multiplication;default.default;[t] "product with variable number of factors";self::infixop;@role="multiplication";count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +'Aliases abstr-var-multiplication self::infixop @role="implicit" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "),["Rule","abstr-vector","default.default",'[t] count(./children/*) ; [t] "dimensional vector"',"self::vector"],["Rule","abstr-vector","mathspeak.brief",'[t] "vector"',"self::vector"],["SpecializedRule","abstr-vector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-vector;default.default;[t] "n dimensional vector";self::vector;./children/*/children/punctuation[@role="ellipsis"]'.split(";"), +'Rule;abstr-binomial;default.default;[t] "binomial";self::vector;@role="binomial"'.split(";"),["SpecializedRule","abstr-binomial","default.default","mathspeak.brief"],["SpecializedRule","abstr-binomial","default.default","mathspeak.sbrief"],'Rule,abstr-determinant,default.default,[t] count(./children/*); [t] "dimensional determinant",self::matrix,@role="determinant"'.split(","),'Rule;abstr-determinant;mathspeak.brief;[t] "determinant";self::matrix;@role="determinant"'.split(";"),["SpecializedRule", +"abstr-determinant","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-determinant;default.default;[t] "n dimensional determinant";self::matrix;@role="determinant";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"),'Rule,abstr-squarematrix,default.default,[t] count(./children/*); [t] "dimensional square matrix",self::matrix,@role="squarematrix"'.split(","),'Rule;abstr-squarematrix;mathspeak.brief;[t] "square matrix";self::matrix;@role="squarematrix"'.split(";"),["SpecializedRule", +"abstr-squarematrix","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-rowvector,default.default,[t] count(./children/row/children/*); [t] "dimensional row vector",self::matrix,@role="rowvector"'.split(","),'Rule;abstr-rowvector;mathspeak.brief;[t] "row vector";self::matrix;@role="rowvector"'.split(";"),["SpecializedRule","abstr-rowvector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "n dimensional row vector";self::matrix;@role="rowvector";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"), +["Rule","abstr-matrix","default.default",'[t] count(children/*); [t] "by";[t] count(children/*[1]/children/*); [t] "matrix"',"self::matrix"],["Rule","abstr-matrix","mathspeak.brief",'[t] "matrix"',"self::matrix"],["SpecializedRule","abstr-matrix","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "n by m dimensional matrix";self::matrix;./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-cases","default.default",'[t] "case statement";[t] "with"; [t] count(children/*); [t] "cases"', +"self::cases"],["Rule","abstr-cases","mathspeak.brief",'[t] "case statement"',"self::cases"],["SpecializedRule","abstr-cases","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-cases;default.default;[t] "case statement with variable number of cases";self::cases;./children/row/children/cell/children/punctuation[@role="ellipsis"]or ./children/line/children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-punctuated","default.default",'[n] content/*[1]; [t] "separated list"; [t] "of length"; [t] count(children/*) - count(content/*)', +"self::punctuated"],["Rule","abstr-punctuated","mathspeak.brief",'[n] content/*[1]; [t] "separated list"',"self::punctuated"],["SpecializedRule","abstr-punctuated","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-punctuated,default.default,[n] content/*[1]; [t] "separated list";[t] "of variable length",self::punctuated,./children/punctuation[@role="ellipsis"]'.split(","),["Rule","abstr-bigop","default.default","[n] content/*[1]","self::bigop"],["Rule","abstr-integral","default.default",'[t] "integral"', +'@role="integral"'],"Rule,abstr-relation,default.default,[t] @role (grammar:localRole);,self::relseq,count(./children/*)=2".split(","),'Rule,abstr-relation-seq,default.default,[t] @role (grammar:localRole); [t] "sequence"; [t] "with"; [t] count(./children/*); [t] "elements",self::relseq,count(./children/*)>2'.split(","),'Rule,abstr-relation-seq,mathspeak.brief,[t] @role (grammar:localRole); [t] "sequence",self::relseq,count(./children/*)>2'.split(","),["SpecializedRule","abstr-relation-seq","mathspeak.brief", +"mathspeak.sbrief"],'Rule,abstr-var-relation,default.default,[t] @role (grammar:localRole); [t] "sequence"; [t] "with variable number of elements",self::relseq,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","),'UniqueAlias abstr-relation default.default self::multirel @role!="unknown" count(./children/*)>2'.split(" "),'Aliases abstr-var-relation self::multirel @role!="unknown" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "),'Rule,abstr-multirel,default.default,[t] "relation sequence"; [t] "with"; [t] count(./children/*); [t] "elements",self::multirel,count(./children/*)>2'.split(","), +'Rule;abstr-multirel;mathspeak.brief;[t] "relation sequence";self::multirel;count(./children/*)>2'.split(";"),["SpecializedRule","abstr-multirel","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-multirel;default.default;[t] "relation sequence with variable number of elements";self::multirel;count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-table","default.default",'[t] "table with"; [t] count(children/*); [t] "rows and";[t] count(children/*[1]/children/*); [t] "columns"', +"self::table"],["Rule","abstr-line","default.default",'[t] "in"; [t] @role (grammar:localRole);',"self::line"],["Rule","abstr-row","default.default",'[t] "in"; [t] @role (grammar:localRole);[t] count(preceding-sibling::..); [t] "with";[t] count(children/*); [t] "columns"',"self::row"],["Rule","abstr-cell","default.default",'[t] "in"; [t] @role (grammar:localRole);',"self::cell"]]};sre.SummarySpanish={locale:"es",modality:"summary",rules:[["Rule","stree","default.default","[n] ./*[1]","self::stree"],'Rule;abstr-identifier;default.default;[t] "identificador largo";self::identifier;contains(@grammar, "collapsed")'.split(";"),["Rule","abstr-identifier","default.default",'[t] "identificador"',"self::identifier"],'Rule;abstr-number;default.default;[t] "n\u00famero largo";self::number;contains(@grammar, "collapsed")'.split(";"),["Rule","abstr-number","default.default",'[t] "n\u00famero"', +"self::number"],'Rule;abstr-mixed-number;default.default;[t] "n\u00famero largo mixto";self::number;@role="mixed";contains(@grammar, "collapsed")'.split(";"),'Rule;abstr-mixed-number;default.default;[t] "n\u00famero mixto";self::number;@role="mixed"'.split(";"),["Rule","abstr-text","default.default",'[t] "texto"',"self::text"],["Rule","abstr-function","default.default",'[t] "expresi\u00f3n funcional"',"self::function"],["Rule","abstr-function","mathspeak.brief",'[t] "funci\u00f3n"',"self::function"], +["SpecializedRule","abstr-function","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-lim;default.default;[t] "funci\u00f3n de l\u00edmite";self::function;@role="limit function"'.split(";"),'Rule;abstr-lim;mathspeak.brief;[t] "l\u00edmite";self::function;@role="limit function"'.split(";"),["SpecializedRule","abstr-lim","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-fraction","default.default",'[t] "fracci\u00f3n"',"self::fraction"],["Rule","abstr-fraction","mathspeak.brief",'[t] "frac"',"self::fraction"], +["SpecializedRule","abstr-fraction","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-continued-fraction;default.default;[t] "fracci\u00f3n continua";self::fraction;children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(";"),'Rule;abstr-continued-fraction;mathspeak.brief;[t] "frac continua";self::fraction;children/*[2]/descendant-or-self::*[@role="ellipsis"]'.split(";"),["SpecializedRule","abstr-continued-fraction","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-sqrt","default.default", +'[t] "ra\u00edz cuadrada"',"self::sqrt"],'Rule;abstr-sqrt-nested;default.default;[t] "ra\u00edz cuadrada anidada";self::sqrt;children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(";"),'Rule{abstr-root{default.default{[t] "ra\u00edz del \u00edndice"; [n] children/*[1] (engine:modality="speech"); [t] "finalizar de \u00edndice"{self::root{contains(@grammar, "collapsed"){following-sibling::* or ancestor::*/following-sibling::*'.split("{"),["Rule","abstr-root","default.default", +'[t] "ra\u00edz del \u00edndice"; [n] children/*[1] (engine:modality=speech)',"self::root"],["Rule","abstr-root","mathspeak.brief",'[t] "ra\u00edz"',"self::root"],["SpecializedRule","abstr-root","mathspeak.brief","mathspeak.sbrief"],'Rule{abstr-root-nested{default.default{[t] "ra\u00edz anidada del \u00edndice"; [n] children/*[1] (engine:modality="speech"); [t] "finalizar de \u00edndice"{self::root{contains(@grammar, "collapsed"){children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root{following-sibling::* or ancestor::*/following-sibling::*'.split("{"), +'Rule,abstr-root-nested,default.default,[t] "ra\u00edz anidada del \u00edndice"; [n] children/*[1] (engine:modality="speech"),self::root,children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(","),'Rule;abstr-root-nested;mathspeak.brief;[t] "ra\u00edz anidada";self::root;children/*/descendant-or-self::sqrt or children/*/descendant-or-self::root'.split(";"),["SpecializedRule","abstr-root-nested","mathspeak.brief","mathspeak.sbrief"],["Rule","abstr-superscript","default.default", +'[t] "potencia"',"self::superscript"],["Rule","abstr-subscript","default.default",'[t] "sub\u00edndice"',"self::subscript"],'Rule;abstr-subsup;default.default;[t] "potencia con sub\u00edndice";self::superscript;name(children/*[1])="subscript"'.split(";"),["Rule","abstr-infixop","default.default",'[t] @role (grammar:localRole); [t] "con"; [t] count(./children/*); [t] "elementos"',"self::infixop"],'Rule,abstr-infixop,default.default,[t] @role (grammar:localRole); [t] "con una cantidad variable de elementos",self::infixop,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","), +["Rule","abstr-infixop","mathspeak.brief","[t] @role (grammar:localRole)","self::infixop"],["SpecializedRule","abstr-infixop","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-addition,default.default,[t] "suma con"; [t] count(./children/*); [t] "sumandos",self::infixop,@role="addition"'.split(","),'Rule;abstr-addition;mathspeak.brief;[t] "suma";self::infixop;@role="addition"'.split(";"),["SpecializedRule","abstr-addition","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-addition;default.default;[t] "suma con n\u00famero variable de sumandos";self::infixop;@role="addition";count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +'Rule,abstr-multiplication,default.default,[t] "producto con"; [t] count(./children/*); [t] "factores",self::infixop,@role="multiplication"'.split(","),'Rule;abstr-multiplication;mathspeak.brief;[t] "producto";self::infixop;@role="multiplication"'.split(";"),["SpecializedRule","abstr-multiplication","mathspeak.brief","mathspeak.sbrief"],["Aliases","abstr-multiplication","self::infixop",'@role="implicit"'],'Rule;abstr-var-multiplication;default.default;[t] "producto con una cantidad variable de factores";self::infixop;@role="multiplication";count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +'Aliases abstr-var-multiplication self::infixop @role="implicit" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "),["Rule","abstr-vector","default.default",'[t] "vector de dimensi\u00f3n"; [t] count(./children/*)',"self::vector"],["Rule","abstr-vector","mathspeak.brief",'[t] "vector"',"self::vector"],["SpecializedRule","abstr-vector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-vector;default.default;[t] "vector de dimensi\u00f3n n";self::vector;./children/*/children/punctuation[@role="ellipsis"]'.split(";"), +'Rule;abstr-binomial;default.default;[t] "binomio";self::vector;@role="binomial"'.split(";"),["SpecializedRule","abstr-binomial","default.default","mathspeak.brief"],["SpecializedRule","abstr-binomial","default.default","mathspeak.sbrief"],'Rule,abstr-determinant,default.default,[t] "determinante de dimensi\u00f3n"; [t] count(./children/*),self::matrix,@role="determinant"'.split(","),'Rule;abstr-determinant;mathspeak.brief;[t] "determinante";self::matrix;@role="determinant"'.split(";"),["SpecializedRule", +"abstr-determinant","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-determinant;default.default;[t] "determinante de dimensi\u00f3n n";self::matrix;@role="determinant";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"),'Rule,abstr-squarematrix,default.default,[t] "matriz cuadrada de dimensi\u00f3n"; [t] count(./children/*),self::matrix,@role="squarematrix"'.split(","),'Rule;abstr-squarematrix;mathspeak.brief;[t] "matriz cuadrada";self::matrix;@role="squarematrix"'.split(";"), +["SpecializedRule","abstr-squarematrix","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-rowvector,default.default,[t] "vector fila de dimensi\u00f3n"; [t] count(./children/row/children/*),self::matrix,@role="rowvector"'.split(","),'Rule;abstr-rowvector;mathspeak.brief;[t] "vector fila";self::matrix;@role="rowvector"'.split(";"),["SpecializedRule","abstr-rowvector","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "vector fila de dimensi\u00f3n n";self::matrix;@role="rowvector";./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"), +["Rule","abstr-matrix","default.default",'[t] count(children/*); [t] "por";[t] count(children/*[1]/children/*); [t] "matriz"',"self::matrix"],["Rule","abstr-matrix","mathspeak.brief",'[t] "matriz"',"self::matrix"],["SpecializedRule","abstr-matrix","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-matrix;default.default;[t] "matriz de dimensi\u00f3n n por m";self::matrix;./children/*/children/*/children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-cases","default.default",'[t] "declaraci\u00f3n de caso";[t] "con"; [t] count(children/*); [t] "casos"', +"self::cases"],["Rule","abstr-cases","mathspeak.brief",'[t] "declaraci\u00f3n de caso"',"self::cases"],["SpecializedRule","abstr-cases","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-cases;default.default;[t] "declaraci\u00f3n de caso con n\u00famero variable de casos";self::cases;./children/row/children/cell/children/punctuation[@role="ellipsis"]or ./children/line/children/punctuation[@role="ellipsis"]'.split(";"),["Rule","abstr-punctuated","default.default",'[t] "lista separada por"; [n] content/*[1]; [t] "de longitud"; [t] count(children/*) - count(content/*)', +"self::punctuated"],["Rule","abstr-punctuated","mathspeak.brief",'[t] "lista separada por"; [n] content/*[1]',"self::punctuated"],["SpecializedRule","abstr-punctuated","mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-punctuated,default.default,[t] "lista separada por"; [n] content/*[1],[t] "de longitud variable",self::punctuated,./children/punctuation[@role="ellipsis"]'.split(","),["Rule","abstr-bigop","default.default","[n] content/*[1]","self::bigop"],["Rule","abstr-integral","default.default", +'[t] "integral"','@role="integral"'],"Rule,abstr-relation,default.default,[t] @role (grammar:localRole);,self::relseq,count(./children/*)=2".split(","),'Rule,abstr-relation-seq,default.default,[t] "secuencia de"; [t] @role (grammar:localRole); [t] "con"; [t] count(./children/*); [t] "elementos",self::relseq,count(./children/*)>2'.split(","),'Rule,abstr-relation-seq,mathspeak.brief,[t] "secuencia de"; [t] @role (grammar:localRole),self::relseq,count(./children/*)>2'.split(","),["SpecializedRule","abstr-relation-seq", +"mathspeak.brief","mathspeak.sbrief"],'Rule,abstr-var-relation,default.default,[t] "secuencia de"; [t] @role (grammar:localRole); [t] "con una cantidad variable de elementos",self::relseq,count(./children/*)>2,./children/punctuation[@role="ellipsis"]'.split(","),'UniqueAlias abstr-relation default.default self::multirel @role!="unknown" count(./children/*)>2'.split(" "),'Aliases abstr-var-relation self::multirel @role!="unknown" count(./children/*)>2 ./children/punctuation[@role="ellipsis"]'.split(" "), +'Rule,abstr-multirel,default.default,[t] "secuencia de relaci\u00f3n"; [t] "con"; [t] count(./children/*); [t] "elementos",self::multirel,count(./children/*)>2'.split(","),'Rule;abstr-multirel;mathspeak.brief;[t] "secuencia de relaci\u00f3n";self::multirel;count(./children/*)>2'.split(";"),["SpecializedRule","abstr-multirel","mathspeak.brief","mathspeak.sbrief"],'Rule;abstr-var-multirel;default.default;[t] "secuencia de relaci\u00f3n con n\u00famero variable de elementos";self::multirel;count(./children/*)>2;./children/punctuation[@role="ellipsis"]'.split(";"), +["Rule","abstr-table","default.default",'[t] "mesa con"; [t] count(children/*); [t] "filas y";[t] count(children/*[1]/children/*); [t] "columnas"',"self::table"],["Rule","abstr-line","default.default",'[t] "en"; [t] @role (grammar:localRole);',"self::line"],["Rule","abstr-row","default.default",'[t] "en"; [t] @role (grammar:localRole);[t] count(preceding-sibling::..); [t] "con";[t] count(children/*); [t] "columnas"',"self::row"],["Rule","abstr-cell","default.default",'[t] "en"; [t] @role (grammar:localRole);', +"self::cell"]]};sre.SpeechRuleStores={}; +sre.SpeechRuleStores.RULE_SETS_={SemanticTreeRules:sre.SemanticTreeRules,MathspeakFrench:sre.MathspeakFrench,MathspeakGerman:sre.MathspeakGerman,MathspeakRules:sre.MathspeakRules,MathspeakSpanish:sre.MathspeakSpanish,NemethRules:sre.NemethRules,ClearspeakFrench:sre.ClearspeakFrench,ClearspeakGerman:sre.ClearspeakGerman,ClearspeakRules:sre.ClearspeakRules,EmacspeakRules:sre.EmacspeakRules,SummaryFrench:sre.SummaryFrench,SummaryGerman:sre.SummaryGerman,SummaryRules:sre.SummaryRules,SummarySpanish:sre.SummarySpanish, +PrefixFrench:sre.PrefixFrench,PrefixGerman:sre.PrefixGerman,PrefixRules:sre.PrefixRules,PrefixSpanish:sre.PrefixSpanish};sre.SpeechRuleStores.availableSets=function(){return Object.keys(sre.SpeechRuleStores.RULE_SETS_)};sre.SpeechRuleStores.getConstructor=function(a){return(a=sre.SpeechRuleStores.RULE_SETS_[a])?a:null};sre.SpeechRuleEngine=function(){this.activeStore_=null;this.cache_={};this.ready_=!0;this.combinedStores_={};this.evaluators_={};this.ruleSets_={};sre.Engine.registerTest(goog.bind(function(a){return this.ready_},this))};goog.addSingletonGetter(sre.SpeechRuleEngine); +sre.SpeechRuleEngine.prototype.parameterize=function(a){for(var b={},c=0,d=a.length;c=g.length&&d.push(g.shift());e=e.concat(g)}b.push(d);e.forEach(function(h){return b.push(h)})}else a.childNodes.forEach(function(h){return sre.ColorGenerator.visitStree_(h, +b,c)})}else c[a.id]||b.push(a.id)};sre.DirectSpeechGenerator=function(){sre.AbstractSpeechGenerator.call(this)};goog.inherits(sre.DirectSpeechGenerator,sre.AbstractSpeechGenerator);sre.DirectSpeechGenerator.prototype.getSpeech=function(a,b){return sre.WalkerUtil.getAttribute(a,this.modality)};sre.DummySpeechGenerator=function(){sre.AbstractSpeechGenerator.call(this)};goog.inherits(sre.DummySpeechGenerator,sre.AbstractSpeechGenerator);sre.DummySpeechGenerator.prototype.getSpeech=function(a,b){return""};sre.TreeSpeechGenerator=function(){sre.AbstractSpeechGenerator.call(this)};goog.inherits(sre.TreeSpeechGenerator,sre.AbstractSpeechGenerator); +sre.TreeSpeechGenerator.prototype.getSpeech=function(a,b){var c=this.generateSpeech(a,b);a.setAttribute(this.modality,c);var d=this.getRebuilt().nodeDict,e;for(e in d){var f=d[e],g=sre.WalkerUtil.getBySemanticId(b,e),h=sre.WalkerUtil.getBySemanticId(a,e);g&&h&&(sre.SpeechGeneratorUtil.addSpeech(h,f,this.modality),this.modality===sre.EnrichMathml.Attribute.SPEECH&&sre.SpeechGeneratorUtil.addPrefix(h,f))}return c};sre.NodeSpeechGenerator=function(){sre.TreeSpeechGenerator.call(this)};goog.inherits(sre.NodeSpeechGenerator,sre.TreeSpeechGenerator);sre.NodeSpeechGenerator.prototype.getSpeech=function(a,b){var c=sre.WalkerUtil.getAttribute(a,this.modality);return c?c:sre.NodeSpeechGenerator.superClass_.getSpeech.call(this,a,b)};sre.SummarySpeechGenerator=function(){sre.AbstractSpeechGenerator.call(this)};goog.inherits(sre.SummarySpeechGenerator,sre.AbstractSpeechGenerator);sre.SummarySpeechGenerator.prototype.getSpeech=function(a,b){sre.SpeechGeneratorUtil.connectAllMactions(b,this.getRebuilt().xml);return this.generateSpeech(a,b)};sre.SpeechGeneratorFactory={};sre.SpeechGeneratorFactory.generator=function(a){return new (sre.SpeechGeneratorFactory.generatorMapping_[a]||sre.SpeechGeneratorFactory.generatorMapping_.Direct)};sre.SpeechGeneratorFactory.generatorMapping_={Adhoc:sre.AdhocSpeechGenerator,Color:sre.ColorGenerator,Direct:sre.DirectSpeechGenerator,Dummy:sre.DummySpeechGenerator,Node:sre.NodeSpeechGenerator,Summary:sre.SummarySpeechGenerator,Tree:sre.TreeSpeechGenerator};sre.EventUtil={};sre.EventUtil.KeyCode={ENTER:13,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,TAB:9,LESS:188,GREATER:190,DASH:189,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90};sre.EventUtil.Move=function(){var a={},b;for(b in sre.EventUtil.KeyCode)a[sre.EventUtil.KeyCode[b]]=b;return a}(); +sre.EventUtil.EventType={CLICK:"click",DBLCLICK:"dblclick",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",MOUSEOVER:"mouseover",MOUSEOUT:"mouseout",MOUSEMOVE:"mousemove",SELECTSTART:"selectstart",KEYPRESS:"keypress",KEYDOWN:"keydown",KEYUP:"keyup",TOUCHSTART:"touchstart",TOUCHMOVE:"touchmove",TOUCHEND:"touchend",TOUCHCANCEL:"touchcancel"};sre.EventUtil.Event=function(a,b,c){this.src=a;this.type=b;this.callback=c};sre.EventUtil.Event.prototype.add=function(){this.src.addEventListener(this.type,this.callback)}; +sre.EventUtil.Event.prototype.remove=function(){this.src.removeEventListener(this.type,this.callback)};sre.Focus=function(a,b){this.semanticNodes_=a;this.semanticPrimary_=b;this.domNodes_=[];this.domPrimary_=null;this.allNodes_=[]};sre.Focus.prototype.getSemanticPrimary=function(){return this.semanticPrimary_};sre.Focus.prototype.getSemanticNodes=function(){return this.semanticNodes_};sre.Focus.prototype.getNodes=function(){return this.allNodes_};sre.Focus.prototype.getDomNodes=function(){return this.domNodes_};sre.Focus.prototype.getDomPrimary=function(){return this.domPrimary_}; +sre.Focus.prototype.toString=function(){return"Primary:"+this.domPrimary_+" Nodes:"+this.domNodes_};sre.Focus.prototype.clone=function(){var a=new sre.Focus(this.semanticNodes_,this.semanticPrimary_);a.domNodes_=this.domNodes_;a.domPrimary_=this.domPrimary_;a.allNodes_=this.allNodes_;return a}; +sre.Focus.factory=function(a,b,c,d){var e=function(h){return sre.WalkerUtil.getBySemanticId(d,h)},f=c.nodeDict;c=e(a);e=b.map(e);var g=b.map(function(h){return f[h]});a=new sre.Focus(g,f[a]);a.domNodes_=e;a.domPrimary_=c;a.allNodes_=sre.Focus.generateAllVisibleNodes_(b,e,f,d);return a}; +sre.Focus.generateAllVisibleNodes_=function(a,b,c,d){for(var e=function(m){return sre.WalkerUtil.getBySemanticId(d,m)},f=[],g=0,h=a.length;ga||a>=b.length?null:b[a]};sre.Levels.prototype.depth=function(){return this.level_.length};sre.Levels.prototype.clone=function(){var a=new sre.Levels;a.level_=this.level_.slice(0);return a};sre.Levels.prototype.toString=function(){for(var a="",b=0,c;c=this.level_[b];b++)a+="\n"+c.map(function(d){return d.toString()});return a};sre.Walker=function(){};sre.Walker.prototype.isActive=function(){};sre.Walker.prototype.activate=function(){};sre.Walker.prototype.deactivate=function(){};sre.Walker.prototype.speech=function(){};sre.Walker.prototype.getXml=function(){};sre.Walker.prototype.getRebuilt=function(){};sre.Walker.prototype.getFocus=function(a){};sre.Walker.prototype.setFocus=function(a){};sre.Walker.prototype.getDepth=function(){};sre.Walker.prototype.move=function(a){};sre.Walker.prototype.update=function(a){}; +sre.Walker.move={UP:"up",DOWN:"down",LEFT:"left",RIGHT:"right",REPEAT:"repeat",DEPTH:"depth",ENTER:"enter",EXPAND:"expand",HOME:"home",SUMMARY:"summary",DETAIL:"detail",ROW:"row",CELL:"cell"};sre.Walker.STATE_={};sre.Walker.resetState=function(a){delete sre.Walker.STATE_[a]};sre.Walker.setState=function(a,b){sre.Walker.STATE_[a]=b};sre.Walker.getState=function(a){return sre.Walker.STATE_[a]};sre.AbstractWalker=function(a,b,c,d){this.node=a;this.node.id?this.id=this.node.id:this.node.hasAttribute(sre.AbstractWalker.SRE_ID_ATTR)?this.id=this.node.getAttribute(sre.AbstractWalker.SRE_ID_ATTR):(this.node.setAttribute(sre.AbstractWalker.SRE_ID_ATTR,sre.AbstractWalker.ID_COUNTER),this.id=sre.AbstractWalker.ID_COUNTER++);this.generator=b;this.highlighter=c;this.rootNode=sre.WalkerUtil.getSemanticRoot(a);this.rootId=this.rootNode.getAttribute(sre.EnrichMathml.Attribute.ID);this.xmlString_=d;this.focus_= +this.rebuilt_=this.xml_=null;this.keyMapping={};this.keyMapping[sre.EventUtil.KeyCode.UP]=goog.bind(this.up,this);this.keyMapping[sre.EventUtil.KeyCode.DOWN]=goog.bind(this.down,this);this.keyMapping[sre.EventUtil.KeyCode.RIGHT]=goog.bind(this.right,this);this.keyMapping[sre.EventUtil.KeyCode.LEFT]=goog.bind(this.left,this);this.keyMapping[sre.EventUtil.KeyCode.TAB]=goog.bind(this.repeat,this);this.keyMapping[sre.EventUtil.KeyCode.DASH]=goog.bind(this.expand,this);this.keyMapping[sre.EventUtil.KeyCode.SPACE]= +goog.bind(this.depth,this);this.keyMapping[sre.EventUtil.KeyCode.HOME]=goog.bind(this.home,this);this.keyMapping[sre.EventUtil.KeyCode.X]=goog.bind(this.summary,this);this.keyMapping[sre.EventUtil.KeyCode.Z]=goog.bind(this.detail,this);this.keyMapping[sre.EventUtil.KeyCode.V]=goog.bind(this.virtualize,this);this.keyMapping[sre.EventUtil.KeyCode.P]=goog.bind(this.previous,this);this.keyMapping[sre.EventUtil.KeyCode.U]=goog.bind(this.undo,this);this.keyMapping[sre.EventUtil.KeyCode.LESS]=goog.bind(this.previousRules, +this);this.keyMapping[sre.EventUtil.KeyCode.GREATER]=goog.bind(this.nextRules,this);this.active_=!1;this.moved=sre.Walker.move.ENTER;this.cursors=[]};sre.AbstractWalker.prototype.getXml=function(){this.xml_||(this.xml_=sre.DomUtil.parseInput(this.xmlString_));return this.xml_};sre.AbstractWalker.prototype.getRebuilt=function(){this.rebuilt_||(this.rebuilt_=this.rebuildStree());return this.rebuilt_};sre.AbstractWalker.ID_COUNTER=0;sre.AbstractWalker.SRE_ID_ATTR="sre-explorer-id"; +sre.AbstractWalker.prototype.isActive=function(){return this.active_};sre.AbstractWalker.prototype.toggleActive_=function(){this.active_=!this.active_};sre.AbstractWalker.prototype.activate=function(){this.isActive()||(this.generator.start(),this.toggleActive_())};sre.AbstractWalker.prototype.deactivate=function(){this.isActive()&&(sre.Walker.setState(this.id,this.primaryId()),this.generator.end(),this.toggleActive_())}; +sre.AbstractWalker.prototype.getFocus=function(a){this.focus_||(this.focus_=sre.Focus.factory(this.rootId,[this.rootId],this.getRebuilt(),this.node));a&&this.updateFocus();return this.focus_};sre.AbstractWalker.prototype.setFocus=function(a){this.focus_=a};sre.AbstractWalker.prototype.getDepth=function(){return this.levels.depth()-1};sre.AbstractWalker.prototype.isSpeech=function(){return this.generator.modality===sre.EnrichMathml.Attribute.SPEECH}; +sre.AbstractWalker.prototype.speech=function(){var a=this.getFocus().getDomNodes();if(!a.length)return"";var b=this.specialMove();if(null!==b)return b;switch(this.moved){case sre.Walker.move.DEPTH:return this.depth_();case sre.Walker.move.SUMMARY:return this.summary_();case sre.Walker.move.DETAIL:return this.detail_();default:b=[];for(var c=this.getFocus().getSemanticNodes(),d=0,e=a.length;d=a.length-1?a[0]:a[c+1]}if("clearspeak"===a){var d=sre.ClearspeakPreferences.getLocalePreferences().en;if(!d)return"default";a=sre.ClearspeakPreferences.relevantPreferences(this.getFocus().getSemanticPrimary());c=sre.ClearspeakPreferences.findPreference(b,a);d=d[a].map(function(e){return e.split("_")[1]});c=d.indexOf(c);return-1===c?b:sre.ClearspeakPreferences.addPreference(b, +a,c>=d.length-1?d[0]:d[c+1])}return b};sre.AbstractWalker.prototype.previousRules=function(){var a=this.generator.getOptions();if("speech"!==a.modality)return this.getFocus();a.style=this.nextStyle(a.domain,a.style);this.update(a);this.moved=sre.Walker.move.REPEAT;return this.getFocus().clone()};sre.DummyWalker=function(a,b,c,d){sre.AbstractWalker.call(this,a,b,c,d)};goog.inherits(sre.DummyWalker,sre.AbstractWalker);sre.DummyWalker.prototype.up=function(){};sre.DummyWalker.prototype.down=function(){};sre.DummyWalker.prototype.left=function(){};sre.DummyWalker.prototype.right=function(){};sre.DummyWalker.prototype.repeat=function(){};sre.DummyWalker.prototype.depth=function(){};sre.DummyWalker.prototype.home=function(){};sre.DummyWalker.prototype.getDepth=function(){return 0}; +sre.DummyWalker.prototype.initLevels=function(){};sre.SemanticWalker=function(a,b,c,d){sre.AbstractWalker.call(this,a,b,c,d);this.levels=null;this.restoreState()};goog.inherits(sre.SemanticWalker,sre.AbstractWalker);sre.SemanticWalker.prototype.initLevels=function(){var a=new sre.Levels;a.push([this.getFocus()]);return a}; +sre.SemanticWalker.prototype.up=function(){sre.SemanticWalker.superClass_.up.call(this);var a=this.previousLevel();if(!a)return null;this.levels.pop();return this.levels.find(function(b){return b.getSemanticNodes().some(function(c){return c.id.toString()===a})})};sre.SemanticWalker.prototype.down=function(){sre.SemanticWalker.superClass_.down.call(this);var a=this.nextLevel();if(0===a.length)return null;this.levels.push(a);return a[0]}; +sre.SemanticWalker.prototype.combineContentChildren=function(a,b,c,d){switch(a){case sre.SemanticAttr.Type.RELSEQ:case sre.SemanticAttr.Type.INFIXOP:case sre.SemanticAttr.Type.MULTIREL:return this.makePairList(d,c);case sre.SemanticAttr.Type.PREFIXOP:return[this.focusFromId(d[0],c.concat(d))];case sre.SemanticAttr.Type.POSTFIXOP:return[this.focusFromId(d[0],d.concat(c))];case sre.SemanticAttr.Type.MATRIX:case sre.SemanticAttr.Type.VECTOR:case sre.SemanticAttr.Type.FENCED:return[this.focusFromId(d[0], +[c[0],d[0],c[1]])];case sre.SemanticAttr.Type.CASES:return[this.focusFromId(d[0],[c[0],d[0]])];case sre.SemanticAttr.Type.PUNCTUATED:return b===sre.SemanticAttr.Role.TEXT?d.map(goog.bind(this.singletonFocus,this)):d.length===c.length?c.map(goog.bind(this.singletonFocus,this)):this.combinePunctuations(d,c,[],[]);case sre.SemanticAttr.Type.APPL:return[this.focusFromId(d[0],[d[0],c[0]]),this.singletonFocus(d[1])];case sre.SemanticAttr.Type.ROOT:return[this.singletonFocus(d[1]),this.singletonFocus(d[0])]; +default:return d.map(goog.bind(this.singletonFocus,this))}};sre.SemanticWalker.prototype.combinePunctuations=function(a,b,c,d){if(0===a.length)return d;var e=a.shift(),f=b.shift();if(e===f)return c.push(f),this.combinePunctuations(a,b,c,d);b.unshift(f);c.push(e);if(a.length===b.length)return d.push(this.focusFromId(e,c.concat(b))),d;d.push(this.focusFromId(e,c));return this.combinePunctuations(a,b,[],d)}; +sre.SemanticWalker.prototype.makePairList=function(a,b){if(0===a.length)return[];if(1===a.length)return[this.singletonFocus(a[0])];for(var c=[this.singletonFocus(a.shift())],d=0,e=a.length;dthis.currentTable_.childNodes.length)return this.getFocus();this.row_=a;this.moved=sre.Walker.move.ROW;return this.getFocus().clone()}; +sre.TableWalker.prototype.jumpCell_=function(a,b){this.firstJump?this.virtualize(!1):(this.firstJump=this.getFocus(),this.virtualize(!0));var c=this.currentTable_.id.toString();do var d=this.levels.pop();while(-1===d.indexOf(c));this.levels.push(d);this.setFocus(this.singletonFocus(c));this.levels.push(this.nextLevel());a=this.currentTable_.childNodes[a-1];this.setFocus(this.singletonFocus(a.id.toString()));this.levels.push(this.nextLevel());return this.singletonFocus(a.childNodes[b-1].id.toString())}; +sre.TableWalker.prototype.isLegalJump_=function(a,b){var c=sre.DomUtil.querySelectorAllByAttrValue(this.getRebuilt().xml,"id",this.currentTable_.id.toString())[0];if(!c||c.hasAttribute("alternative"))return!1;a=this.currentTable_.childNodes[a-1];if(!a)return!1;c=sre.DomUtil.querySelectorAllByAttrValue(c,"id",a.id.toString())[0];return!c||c.hasAttribute("alternative")?!1:!(!a||!a.childNodes[b-1])}; +sre.TableWalker.prototype.isInTable_=function(){for(var a=this.getFocus().getSemanticPrimary();a;){if(-1!==sre.TableWalker.ELIGIBLE_TABLE_TYPES.indexOf(a.type))return this.currentTable_=a,!0;a=a.parent}return!1};sre.TableWalker.prototype.undo=function(){var a=sre.TableWalker.superClass_.undo.call(this);a===this.firstJump&&(this.firstJump=null);return a};sre.WalkerFactory={};sre.WalkerFactory.walker=function(a,b,c,d,e){return new (sre.WalkerFactory.walkerMapping_[a.toLowerCase()]||sre.WalkerFactory.walkerMapping_.dummy)(b,c,d,e)};sre.WalkerFactory.walkerMapping_={dummy:sre.DummyWalker,semantic:sre.SemanticWalker,syntax:sre.SyntaxWalker,table:sre.TableWalker};sre.ProcessorFactory={};sre.ProcessorFactory.PROCESSORS_={};sre.ProcessorFactory.get_=function(a){var b=sre.ProcessorFactory.PROCESSORS_[a.toLowerCase()];if(!b)throw new sre.Engine.Error("Unknown processor "+a);return b};sre.ProcessorFactory.process=function(a,b){return sre.ProcessorFactory.get_(a).processor(b)};sre.ProcessorFactory.print=function(a,b){a=sre.ProcessorFactory.get_(a);return sre.Engine.getInstance().pprint?a.pprint(b):a.print(b)}; +sre.ProcessorFactory.output=function(a,b){a=sre.ProcessorFactory.get_(a);b=a.processor(b);return sre.Engine.getInstance().pprint?a.pprint(b):a.print(b)};sre.ProcessorFactory.keypress=function(a,b){a=sre.ProcessorFactory.get_(a);b=a.key?a.key(b):b;b=a.processor(b);return sre.Engine.getInstance().pprint?a.pprint(b):a.print(b)}; +sre.Processor=function(a,b){this.name=a;this.processor=b.processor;this.print=b.print||sre.Processor.stringify_;this.pprint=b.pprint||this.print;sre.ProcessorFactory.PROCESSORS_[this.name]=this};sre.KeyProcessor=function(a,b){sre.Processor.call(this,a,b);this.key=b.key||sre.KeyProcessor.getKey_};goog.inherits(sre.KeyProcessor,sre.Processor);sre.KeyProcessor.getKey_=function(a){return"string"===typeof a?sre.EventUtil.KeyCode[a.toUpperCase()]:a}; +sre.Processor.LocalState_={walker:null,speechGenerator:null,highlighter:null};sre.Processor.stringify_=function(a){return a?a.toString():a};new sre.Processor("semantic",{processor:function(a){a=sre.DomUtil.parseInput(a);return sre.Semantic.xmlTree(a)},pprint:function(a){return sre.DomUtil.formatXml(a.toString())}}); +new sre.Processor("speech",{processor:function(a){a=sre.DomUtil.parseInput(a);a=sre.Semantic.xmlTree(a);a=sre.SpeechGeneratorUtil.computeSpeech(a);var b=sre.AuralRendering.getInstance();return b.finalize(b.markup(a))},pprint:function(a){a=a.toString();return sre.AuralRendering.ofType(sre.XmlRenderer)?sre.DomUtil.formatXml(a):a}}); +new sre.Processor("json",{processor:function(a){a=sre.DomUtil.parseInput(a,sre.Engine.Error);return sre.Semantic.getTree(a).toJson()},print:function(a){return JSON.stringify(a)},pprint:function(a){return JSON.stringify(a,null,2)}});new sre.Processor("description",{processor:function(a){a=sre.DomUtil.parseInput(a);a=sre.Semantic.xmlTree(a);return sre.SpeechGeneratorUtil.computeSpeech(a)},print:function(a){return JSON.stringify(a)},pprint:function(a){return JSON.stringify(a,null,2)}}); +new sre.Processor("enriched",{processor:function(a){a=sre.Enrich.semanticMathmlSync(a);var b=sre.WalkerUtil.getSemanticRoot(a);switch(sre.Engine.getInstance().speech){case sre.Engine.Speech.SHALLOW:var c=sre.SpeechGeneratorFactory.generator("Adhoc");c.getSpeech(b,a);break;case sre.Engine.Speech.DEEP:c=sre.SpeechGeneratorFactory.generator("Tree"),c.getSpeech(b,a)}return a},pprint:function(a){return sre.DomUtil.formatXml(a.toString())}}); +new sre.Processor("walker",{processor:function(a){var b=sre.SpeechGeneratorFactory.generator("Node");sre.Processor.LocalState_.speechGenerator=b;sre.Processor.LocalState_.highlighter=sre.HighlighterFactory.highlighter({color:"black"},{color:"white"},{renderer:"NativeMML"});a=sre.ProcessorFactory.process("enriched",a);var c=sre.ProcessorFactory.print("enriched",a);sre.Processor.LocalState_.walker=sre.WalkerFactory.walker(sre.Engine.getInstance().walker,a,b,sre.Processor.LocalState_.highlighter,c); +return sre.Processor.LocalState_.walker},print:function(a){return sre.Processor.LocalState_.walker.speech()}});new sre.KeyProcessor("move",{processor:function(a){return sre.Processor.LocalState_.walker?!1===sre.Processor.LocalState_.walker.move(a)?sre.AuralRendering.getInstance().error(a):sre.Processor.LocalState_.walker.speech():null}});sre.System=function(){this.version=sre.Variables.VERSION};goog.addSingletonGetter(sre.System); +sre.System.prototype.setupEngine=function(a){var b=sre.Engine.getInstance(),c=function(d){b[d]=a[d]||b[d]};c("mode");sre.System.prototype.configBlocks_(a);sre.Engine.BINARY_FEATURES.forEach(function(d){"undefined"!==typeof a[d]&&(b[d]=!!a[d])});sre.Engine.STRING_FEATURES.forEach(c);a.json&&(sre.SystemExternal.jsonPath=sre.BaseUtil.makePath(a.json));a.xpath&&(sre.SystemExternal.WGXpath=a.xpath);b.setupBrowsers();b.ruleSets=a.rules?a.rules:sre.SpeechRuleStores.availableSets();sre.SpeechRuleEngine.getInstance().parameterize(b.ruleSets); +b.setDynamicCstr();sre.L10n.setLocale()};sre.System.prototype.configBlocks_=function(a){if(!sre.Engine.getInstance().config&&sre.Engine.getInstance().mode===sre.Engine.Mode.HTTP){sre.Engine.getInstance().config=!0;for(var b=document.documentElement.querySelectorAll('script[type="text/x-sre-config"]'),c=0,d=b.length;c= 0; i--) { + var dependent = this.dependents[i]; + if (dependent.Disable) dependent.Disable(false,menu); + } + if (update) MathJax.Hub.Queue(["Reprocess",MathJax.Hub]); + }, + + // + // Register a dependent + // + Dependent: function (extension) { + this.dependents.push(extension); + } +}; + +(function () { + // + // Set up the a11y path,if it isn't already in place + // + var PATH = MathJax.Ajax.config.path; + if (!PATH.a11y) PATH.a11y = HUB.config.root + "/extensions/a11y"; + + // + // Load SRE and use the signal to tell MathJax when it is loaded. + // Since SRE waits for the mml element jax, load that too. + // + if (!PATH.SRE) PATH.SRE = MathJax.Ajax.fileURL(PATH.a11y); + MathJax.Ajax.Load("[SRE]/mathjax-sre.js"); + MathJax.Hub.Register.StartupHook("Sre Ready",["loadComplete",MathJax.Ajax,"[SRE]/mathjax-sre.js"]); +})(); + +// +// Make a queue so that the MathML jax and SRE are both loaded before +// we install the filter and signal that we are ready. The MathML config.js +// file must load before loading its jax.js file. +// +MathJax.Callback.Queue( + // + // Load mml jax + // + ["Require",MathJax.Ajax,"[MathJax]/jax/element/mml/jax.js"], + // + // Load MathML input jax (since we need Parse.MakeMML) + // + ["Require",MathJax.Ajax,"[MathJax]/jax/input/MathML/config.js"], + ["Require",MathJax.Ajax,"[MathJax]/jax/input/MathML/jax.js"], + // + // Load toMathML extension (if it isn't already) + // + ["Require",MathJax.Ajax,"[MathJax]/extensions/toMathML.js"], + // + // Wait for SRE (which waits for mml jax) before modifying mbase + // + MathJax.Hub.Register.StartupHook("Sre Ready",function () { + var MML = MathJax.ElementJax.mml, + ENRICH = MathJax.Extension["semantic-enrich"]; + + // + // Override toMathML's attribute function to include additional + // attributes inherited from mstyle (so SRE doesn't have to look them + // up itself). Eventually, this should be moved to toMathML.js directly. + // + MML.mbase.Augment({ + toMathMLattributes: function () { + var defaults = (this.type === "mstyle" ? MML.math.prototype.defaults : this.defaults); + var names = (this.attrNames||MML.copyAttributeNames), + skip = MML.skipAttributes, copy = MML.copyAttributes, + lookup = (ENRICH.running ? ENRICH.mstyleLookup[this.type]||[] : []); + var attr = [], ATTR = (this.attr||{}); + + if (this.type === "math" && (!this.attr || !('xmlns' in this.attr))) + attr.push('xmlns="http://www.w3.org/1998/Math/MathML"'); + if (!this.attrNames) { + 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]) this.toMathMLaddAttr(attr,id,this[id]); + } + }} + } + for (var i = 0, m = names.length; i < m; i++) { + if (copy[names[i]] === 1 && !defaults.hasOwnProperty(names[i])) continue; + value = ATTR[names[i]]; if (value == null) value = this[names[i]]; + if (value != null) this.toMathMLaddAttr(attr,names[i],value); + } + for (i = 0, m = lookup.length; i < m; i++) { + id = lookup[i]; + if (defaults.hasOwnProperty(id) && !attr["_"+id]) { + value = this.Get(id,1); + if (value != null) this.toMathMLaddAttr(attr,id,value); + } + } + this.toMathMLclass(attr); + if (attr.length) return " "+attr.join(" "); else return ""; + }, + toMathMLaddAttr: function (attr,id,value) { + attr.push(id+'="'+this.toMathMLquote(value)+'"'); + attr["_"+id] = 1; + } + }); + + // + // Adjust setTeXclass for so that added elements don't + // cause unwanted space. + // + var TEXCLASS = MML.mo.prototype.setTeXclass; + MML.mo.Augment({ + setTeXclass: function (prev) { + var values = this.getValues("form","lspace","rspace"); // sets useMMLspacing + if (this.useMMLspacing) { + this.texClass = MML.TEXCLASS.NONE; + return this; + } + if (this.attr && this.attr["data-semantic-added"]) { + this.texClass = this.prevClass = MML.TEXCLASS.NONE; + return prev; + } + return TEXCLASS.apply(this,arguments); + } + }); + }), + function () { + // + // Install enrichment filter, and signal that we are ready. + // + MathJax.Hub.postInputHooks.Add(["Filter",MathJax.Extension["semantic-enrich"]],50); + MathJax.Hub.Startup.signal.Post("Semantic Enrich Ready"); + MathJax.Ajax.loadComplete("[a11y]/semantic-enrich.js"); + } +); + + +// @license-end diff --git a/js/mathjax/extensions/a11y/wgxpath.install.js b/js/mathjax/extensions/a11y/wgxpath.install.js new file mode 100644 index 0000000..a983680 --- /dev/null +++ b/js/mathjax/extensions/a11y/wgxpath.install.js @@ -0,0 +1,77 @@ +(function(){'use strict';var k=this; +function aa(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"== +b&&"undefined"==typeof a.call)return"object";return b}function l(a){return"string"==typeof a}function ba(a,b,c){return a.call.apply(a.bind,arguments)}function ca(a,b,c){if(!a)throw Error();if(2b?1:0};var ha=Array.prototype.indexOf?function(a,b,c){return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:l(a)?a.charAt(c):a[c]}function la(a){return Array.prototype.concat.apply(Array.prototype,arguments)}function ma(a,b,c){return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};var u;a:{var na=k.navigator;if(na){var oa=na.userAgent;if(oa){u=oa;break a}}u=""};var pa=q(u,"Opera")||q(u,"OPR"),v=q(u,"Trident")||q(u,"MSIE"),qa=q(u,"Edge"),ra=q(u,"Gecko")&&!(q(u.toLowerCase(),"webkit")&&!q(u,"Edge"))&&!(q(u,"Trident")||q(u,"MSIE"))&&!q(u,"Edge"),sa=q(u.toLowerCase(),"webkit")&&!q(u,"Edge");function ta(){var a=k.document;return a?a.documentMode:void 0}var ua; +a:{var va="",wa=function(){var a=u;if(ra)return/rv\:([^\);]+)(\)|;)/.exec(a);if(qa)return/Edge\/([\d\.]+)/.exec(a);if(v)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(sa)return/WebKit\/(\S+)/.exec(a);if(pa)return/(?:Version)[ \/]?(\S+)/.exec(a)}();wa&&(va=wa?wa[1]:"");if(v){var xa=ta();if(null!=xa&&xa>parseFloat(va)){ua=String(xa);break a}}ua=va}var ya={}; +function za(a){if(!ya[a]){for(var b=0,c=fa(String(ua)).split("."),d=fa(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f",4,2,function(a,b,c){return O(function(a,b){return a>b},a,b,c)});P("<=",4,2,function(a,b,c){return O(function(a,b){return a<=b},a,b,c)});P(">=",4,2,function(a,b,c){return O(function(a,b){return a>=b},a,b,c)});var Wa=P("=",3,2,function(a,b,c){return O(function(a,b){return a==b},a,b,c,!0)});P("!=",3,2,function(a,b,c){return O(function(a,b){return a!=b},a,b,c,!0)});P("and",2,2,function(a,b,c){return M(a,c)&&M(b,c)});P("or",1,2,function(a,b,c){return M(a,c)||M(b,c)});function Q(a,b,c){this.a=a;this.b=b||1;this.f=c||1};function Za(a,b){if(b.a.length&&4!=a.i)throw Error("Primary expression must evaluate to nodeset if filter has predicate(s).");n.call(this,a.i);this.c=a;this.h=b;this.g=a.g;this.b=a.b}m(Za);Za.prototype.a=function(a){a=this.c.a(a);return $a(this.h,a)};Za.prototype.toString=function(){var a;a="Filter:"+J(this.c);return a+=J(this.h)};function ab(a,b){if(b.lengtha.v)throw Error("Function "+a.j+" expects at most "+a.v+" arguments, "+b.length+" given");a.B&&r(b,function(b,d){if(4!=b.i)throw Error("Argument "+d+" to function "+a.j+" is not of type Nodeset: "+b);});n.call(this,a.i);this.h=a;this.c=b;Ua(this,a.g||ja(b,function(a){return a.g}));Va(this,a.D&&!b.length||a.C&&!!b.length||ja(b,function(a){return a.b}))}m(ab); +ab.prototype.a=function(a){return this.h.m.apply(null,la(a,this.c))};ab.prototype.toString=function(){var a="Function: "+this.h;if(this.c.length)var b=t(this.c,function(a,b){return a+J(b)},"Arguments:"),a=a+J(b);return a};function bb(a,b,c,d,e,f,g,h,p){this.j=a;this.i=b;this.g=c;this.D=d;this.C=e;this.m=f;this.A=g;this.v=void 0!==h?h:g;this.B=!!p}bb.prototype.toString=function(){return this.j};var cb={}; +function R(a,b,c,d,e,f,g,h){if(cb.hasOwnProperty(a))throw Error("Function already created: "+a+".");cb[a]=new bb(a,b,c,d,!1,e,f,g,h)}R("boolean",2,!1,!1,function(a,b){return M(b,a)},1);R("ceiling",1,!1,!1,function(a,b){return Math.ceil(K(b,a))},1);R("concat",3,!1,!1,function(a,b){return t(ma(arguments,1),function(b,d){return b+L(d,a)},"")},2,null);R("contains",2,!1,!1,function(a,b,c){return q(L(b,a),L(c,a))},2);R("count",1,!1,!1,function(a,b){return b.a(a).l},1,1,!0); +R("false",2,!1,!1,function(){return!1},0);R("floor",1,!1,!1,function(a,b){return Math.floor(K(b,a))},1);R("id",4,!1,!1,function(a,b){function c(a){if(w){var b=e.all[a];if(b){if(b.nodeType&&a==b.id)return b;if(b.length)return ka(b,function(b){return a==b.id})}return null}return e.getElementById(a)}var d=a.a,e=9==d.nodeType?d:d.ownerDocument,d=L(b,a).split(/\s+/),f=[];r(d,function(a){a=c(a);!a||0<=ha(f,a)||f.push(a)});f.sort(La);var g=new C;r(f,function(a){F(g,a)});return g},1); +R("lang",2,!1,!1,function(){return!1},1);R("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.f},0);R("local-name",3,!1,!0,function(a,b){var c=b?Ra(b.a(a)):a.a;return c?c.localName||c.nodeName.toLowerCase():""},0,1,!0);R("name",3,!1,!0,function(a,b){var c=b?Ra(b.a(a)):a.a;return c?c.nodeName.toLowerCase():""},0,1,!0);R("namespace-uri",3,!0,!1,function(){return""},0,1,!0); +R("normalize-space",3,!1,!0,function(a,b){return(b?L(b,a):z(a.a)).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);R("not",2,!1,!1,function(a,b){return!M(b,a)},1);R("number",1,!1,!0,function(a,b){return b?K(b,a):+z(a.a)},0,1);R("position",1,!0,!1,function(a){return a.b},0);R("round",1,!1,!1,function(a,b){return Math.round(K(b,a))},1);R("starts-with",2,!1,!1,function(a,b,c){b=L(b,a);a=L(c,a);return 0==b.lastIndexOf(a,0)},2);R("string",3,!1,!0,function(a,b){return b?L(b,a):z(a.a)},0,1); +R("string-length",1,!1,!0,function(a,b){return(b?L(b,a):z(a.a)).length},0,1);R("substring",3,!1,!1,function(a,b,c,d){c=K(c,a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?K(d,a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=L(b,a);return Infinity==d?a.substring(e):a.substring(e,c+Math.round(d))},2,3);R("substring-after",3,!1,!1,function(a,b,c){b=L(b,a);a=L(c,a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2); +R("substring-before",3,!1,!1,function(a,b,c){b=L(b,a);a=L(c,a);a=b.indexOf(a);return-1==a?"":b.substring(0,a)},2);R("sum",1,!1,!1,function(a,b){for(var c=H(b.a(a)),d=0,e=I(c);e;e=I(c))d+=+z(e);return d},1,1,!0);R("translate",3,!1,!1,function(a,b,c,d){b=L(b,a);c=L(c,a);var e=L(d,a);a={};for(d=0;d]=|\s+|./g,hb=/^\s/;function S(a,b){return a.b[a.a+(b||0)]}function T(a){return a.b[a.a++]}function ib(a){return a.b.length<=a.a};function jb(a){n.call(this,3);this.c=a.substring(1,a.length-1)}m(jb);jb.prototype.a=function(){return this.c};jb.prototype.toString=function(){return"Literal: "+this.c};function E(a,b){this.j=a.toLowerCase();var c;c="*"==this.j?"*":"http://www.w3.org/1999/xhtml";this.c=b?b.toLowerCase():c}E.prototype.a=function(a){var b=a.nodeType;if(1!=b&&2!=b)return!1;b=void 0!==a.localName?a.localName:a.nodeName;return"*"!=this.j&&this.j!=b.toLowerCase()?!1:"*"==this.c?!0:this.c==(a.namespaceURI?a.namespaceURI.toLowerCase():"http://www.w3.org/1999/xhtml")};E.prototype.f=function(){return this.j}; +E.prototype.toString=function(){return"Name Test: "+("http://www.w3.org/1999/xhtml"==this.c?"":this.c+":")+this.j};function kb(a,b){n.call(this,a.i);this.h=a;this.c=b;this.g=a.g;this.b=a.b;if(1==this.c.length){var c=this.c[0];c.u||c.c!=lb||(c=c.o,"*"!=c.f()&&(this.f={name:c.f(),s:null}))}}m(kb);function mb(){n.call(this,4)}m(mb);mb.prototype.a=function(a){var b=new C;a=a.a;9==a.nodeType?F(b,a):F(b,a.ownerDocument);return b};mb.prototype.toString=function(){return"Root Helper Expression"};function nb(){n.call(this,4)}m(nb);nb.prototype.a=function(a){var b=new C;F(b,a.a);return b};nb.prototype.toString=function(){return"Context Helper Expression"}; +function ob(a){return"/"==a||"//"==a}kb.prototype.a=function(a){var b=this.h.a(a);if(!(b instanceof C))throw Error("Filter expression must evaluate to nodeset.");a=this.c;for(var c=0,d=a.length;ca.length)throw Error("Unclosed literal string");return new jb(a)} +function Hb(a){var b,c=[],d;if(ob(S(a.a))){b=T(a.a);d=S(a.a);if("/"==b&&(ib(a.a)||"."!=d&&".."!=d&&"@"!=d&&"*"!=d&&!/(?![0-9])[\w]/.test(d)))return new mb;d=new mb;W(a,"Missing next location step.");b=Ib(a,b);c.push(b)}else{a:{b=S(a.a);d=b.charAt(0);switch(d){case "$":throw Error("Variable reference not allowed in HTML XPath");case "(":T(a.a);b=Cb(a);W(a,'unclosed "("');Eb(a,")");break;case '"':case "'":b=Gb(a);break;default:if(isNaN(+b))if(!db(b)&&/(?![0-9])[\w]/.test(d)&&"("==S(a.a,1)){b=T(a.a); +b=cb[b]||null;T(a.a);for(d=[];")"!=S(a.a);){W(a,"Missing function argument list.");d.push(Cb(a));if(","!=S(a.a))break;T(a.a)}W(a,"Unclosed function argument list.");Fb(a);b=new ab(b,d)}else{b=null;break a}else b=new Ab(+T(a.a))}"["==S(a.a)&&(d=new sb(Jb(a)),b=new Za(b,d))}if(b)if(ob(S(a.a)))d=b;else return b;else b=Ib(a,"/"),d=new nb,c.push(b)}for(;ob(S(a.a));)b=T(a.a),W(a,"Missing next location step."),b=Ib(a,b),c.push(b);return new kb(d,c)} +function Ib(a,b){var c,d,e;if("/"!=b&&"//"!=b)throw Error('Step op should be "/" or "//"');if("."==S(a.a))return d=new U(yb,new G("node")),T(a.a),d;if(".."==S(a.a))return d=new U(xb,new G("node")),T(a.a),d;var f;if("@"==S(a.a))f=lb,T(a.a),W(a,"Missing attribute name");else if("::"==S(a.a,1)){if(!/(?![0-9])[\w]/.test(S(a.a).charAt(0)))throw Error("Bad token: "+T(a.a));c=T(a.a);f=wb[c]||null;if(!f)throw Error("No axis with name: "+c);T(a.a);W(a,"Missing node name")}else f=tb;c=S(a.a);if(/(?![0-9])[\w\*]/.test(c.charAt(0)))if("("== +S(a.a,1)){if(!db(c))throw Error("Invalid node type: "+c);c=T(a.a);if(!db(c))throw Error("Invalid type name: "+c);Eb(a,"(");W(a,"Bad nodetype");e=S(a.a).charAt(0);var g=null;if('"'==e||"'"==e)g=Gb(a);W(a,"Bad nodetype");Fb(a);c=new G(c,g)}else if(c=T(a.a),e=c.indexOf(":"),-1==e)c=new E(c);else{var g=c.substring(0,e),h;if("*"==g)h="*";else if(h=a.b(g),!h)throw Error("Namespace prefix not declared: "+g);c=c.substr(e+1);c=new E(c,h)}else throw Error("Bad token: "+T(a.a));e=new sb(Jb(a),f.a);return d|| +new U(f,c,e,"//"==b)}function Jb(a){for(var b=[];"["==S(a.a);){T(a.a);W(a,"Missing predicate expression.");var c=Cb(a);b.push(c);W(a,"Unclosed predicate expression.");Eb(a,"]")}return b}function Db(a){if("-"==S(a.a))return T(a.a),new zb(Db(a));var b=Hb(a);if("|"!=S(a.a))a=b;else{for(b=[b];"|"==T(a.a);)W(a,"Missing next union location path."),b.push(Hb(a));a.a.a--;a=new rb(b)}return a};function Kb(a){switch(a.nodeType){case 1:return ea(Lb,a);case 9:return Kb(a.documentElement);case 11:case 10:case 6:case 12:return Mb;default:return a.parentNode?Kb(a.parentNode):Mb}}function Mb(){return null}function Lb(a,b){if(a.prefix==b)return a.namespaceURI||"http://www.w3.org/1999/xhtml";var c=a.getAttributeNode("xmlns:"+b);return c&&c.specified?c.value||null:a.parentNode&&9!=a.parentNode.nodeType?Lb(a.parentNode,b):null};function Nb(a,b){if(!a.length)throw Error("Empty XPath expression.");var c=fb(a);if(ib(c))throw Error("Invalid XPath expression.");b?"function"==aa(b)||(b=da(b.lookupNamespaceURI,b)):b=function(){return null};var d=Cb(new Bb(c,b));if(!ib(c))throw Error("Bad token: "+T(c));this.evaluate=function(a,b){var c=d.a(new Q(a));return new Y(c,b)}} +function Y(a,b){if(0==b)if(a instanceof C)b=4;else if("string"==typeof a)b=2;else if("number"==typeof a)b=1;else if("boolean"==typeof a)b=3;else throw Error("Unexpected evaluation result.");if(2!=b&&1!=b&&3!=b&&!(a instanceof C))throw Error("value could not be converted to the specified type");this.resultType=b;var c;switch(b){case 2:this.stringValue=a instanceof C?Sa(a):""+a;break;case 1:this.numberValue=a instanceof C?+Sa(a):+a;break;case 3:this.booleanValue=a instanceof C?0=c.length?null:c[f++]};this.snapshotItem=function(a){if(6!=b&&7!=b)throw Error("snapshotItem called with wrong result type");return a>=c.length|| +0>a?null:c[a]}}Y.ANY_TYPE=0;Y.NUMBER_TYPE=1;Y.STRING_TYPE=2;Y.BOOLEAN_TYPE=3;Y.UNORDERED_NODE_ITERATOR_TYPE=4;Y.ORDERED_NODE_ITERATOR_TYPE=5;Y.UNORDERED_NODE_SNAPSHOT_TYPE=6;Y.ORDERED_NODE_SNAPSHOT_TYPE=7;Y.ANY_UNORDERED_NODE_TYPE=8;Y.FIRST_ORDERED_NODE_TYPE=9;function Ob(a){this.lookupNamespaceURI=Kb(a)} +function Pb(a,b){var c=a||k,d=c.Document&&c.Document.prototype||c.document;if(!d.evaluate||b)c.XPathResult=Y,d.evaluate=function(a,b,c,d){return(new Nb(a,c)).evaluate(b,d)},d.createExpression=function(a,b){return new Nb(a,b)},d.createNSResolver=function(a){return new Ob(a)}}var Qb=["wgxpath","install"],Z=k;Qb[0]in Z||!Z.execScript||Z.execScript("var "+Qb[0]);for(var Rb;Qb.length&&(Rb=Qb.shift());)Qb.length||void 0===Pb?Z[Rb]?Z=Z[Rb]:Z=Z[Rb]={}:Z[Rb]=Pb;}).call(this) diff --git a/js/mathjax/extensions/asciimath2jax.js b/js/mathjax/extensions/asciimath2jax.js new file mode 100644 index 0000000..48f797b --- /dev/null +++ b/js/mathjax/extensions/asciimath2jax.js @@ -0,0 +1,256 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/asciimath2jax.js + * + * Implements the AsciiMath to Jax preprocessor that locates AsciiMath + * code within the text of a document and replaces it with SCRIPT tags for + * processing by MathJax. + * + * Modified by David Lippman, based on tex2jax.js. + * Additional work by Davide P. Cervone. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2012-2020 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.asciimath2jax = { + version: "2.7.9", + config: { + delimiters: [['`','`']], // The star/stop delimiter pairs for asciimath 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 + + ignoreClass: "asciimath2jax_ignore", // the class name of elements whose contents should + // NOT be processed by asciimath2jax. Note that this + // is a regular expression, so be sure to quote any + // regexp special characters + + processClass: "asciimath2jax_process", // the class name of elements whose contents SHOULD + // be processed when they appear inside ones that + // are ignored. Note that this is a regular expression, + // so be sure to quote any regexp special characters + + preview: "AsciiMath" // set to "none" to not insert MathJax_Preview spans + // or set to an array specifying an HTML snippet + // to use the same preview for every equation. + + }, + + // + // Tags to ignore when searching for AsciiMath in the page + // + ignoreTags: { + br: (MathJax.Hub.Browser.isMSIE && document.documentMode < 9 ? "\n" : " "), + wbr: "", + "#comment": "" + }, + + PreProcess: function (element) { + if (!this.configured) { + this.config = MathJax.Hub.CombineConfig("asciimath2jax",this.config); + if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)} + this.configured = true; + } + if (typeof(element) === "string") {element = document.getElementById(element)} + if (!element) {element = document.body} + if (this.createPatterns()) {this.scanElement(element,element.nextSibling)} + }, + + createPatterns: function () { + var starts = [], i, m, config = this.config; this.match = {}; + if (config.delimiters.length === 0) {return false} + for (i = 0, m = config.delimiters.length; i < m; i++) { + starts.push(this.patternQuote(config.delimiters[i][0])); + this.match[config.delimiters[i][0]] = { + mode: "", + end: config.delimiters[i][1], + pattern: this.endPattern(config.delimiters[i][1]) + }; + } + this.start = new RegExp(starts.sort(this.sortLength).join("|"),"g"); + this.skipTags = new RegExp("^("+config.skipTags.join("|")+")$","i"); + 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; + }, + + patternQuote: function (s) {return s.replace(/([\^$(){}+*?\-|\[\]\:\\])/g,'\\$1')}, + + endPattern: function (end) { + return new RegExp(this.patternQuote(end)+"|\\\\.","g"); + }, + + sortLength: function (a,b) { + if (a.length !== b.length) {return b.length - a.length} + return (a == b ? 0 : (a < b ? -1 : 1)); + }, + + scanElement: function (element,stop,ignore) { + var cname, tname, ignoreChild, process; + while (element && element != stop) { + if (element.nodeName.toLowerCase() === '#text') { + if (!ignore) {element = this.scanText(element)} + } else { + cname = (typeof(element.className) === "undefined" ? "" : element.className); + tname = (typeof(element.tagName) === "undefined" ? "" : element.tagName); + if (typeof(cname) !== "string") {cname = String(cname)} // jsxgraph uses non-string class names! + process = this.processClass.exec(cname); + if (element.firstChild && !cname.match(/(^| )MathJax/) && + (process || !this.skipTags.exec(tname))) { + ignoreChild = (ignore || this.ignoreClass.exec(cname)) && !process; + this.scanElement(element.firstChild,stop,ignoreChild); + } + } + if (element) {element = element.nextSibling} + } + }, + + scanText: function (element) { + if (element.nodeValue.replace(/\s+/,'') == '') {return element} + var match, prev, pos = 0, rescan; + this.search = {start: true}; + this.pattern = this.start; + while (element) { + rescan = null; + this.pattern.lastIndex = pos || 0; pos = 0; + while (element && element.nodeName.toLowerCase() === '#text' && + (match = this.pattern.exec(element.nodeValue))) { + if (this.search.start) {element = this.startMatch(match,element)} + else {element = this.endMatch(match,element)} + } + if (this.search.matched) element = this.encloseMath(element); + else if (!this.search.start) rescan = this.search; + if (element) { + do {prev = element; element = element.nextSibling} + while (element && this.ignoreTags[element.nodeName.toLowerCase()] != null); + if (!element || element.nodeName !== '#text') { + if (!rescan) return prev; + element = rescan.open; + pos = rescan.opos + rescan.olen; + this.search = {start: true}; + this.pattern = this.start; + } + } + } + return element; + }, + + startMatch: function (match,element) { + var delim = this.match[match[0]]; + if (delim != null) { + this.search = { + end: delim.end, mode: delim.mode, + open: element, olen: match[0].length, + opos: this.pattern.lastIndex - match[0].length + }; + this.switchPattern(delim.pattern); + } + return element; + }, + + endMatch: function (match,element) { + if (match[0] == this.search.end) { + this.search.close = element; + this.search.cpos = this.pattern.lastIndex; + this.search.clen = (this.search.isBeginEnd ? 0 : match[0].length); + this.search.matched = true; + element = this.encloseMath(element); + this.switchPattern(this.start); + } + return element; + }, + + switchPattern: function (pattern) { + pattern.lastIndex = this.pattern.lastIndex; + this.pattern = pattern; + this.search.start = (pattern === this.start); + }, + + encloseMath: function (element) { + var search = this.search, close = search.close, CLOSE, math, next; + if (search.cpos === close.length) {close = close.nextSibling} + else {close = close.splitText(search.cpos)} + if (!close) {CLOSE = close = MathJax.HTML.addText(search.close.parentNode,"")} + search.close = close; + math = (search.opos ? search.open.splitText(search.opos) : search.open); + while ((next = math.nextSibling) && next !== close) { + if (next.nodeValue !== null) { + if (next.nodeName === "#comment") { + math.nodeValue += next.nodeValue.replace(/^\[CDATA\[((.|\n|\r)*)\]\]$/,"$1"); + } else { + math.nodeValue += math.nextSibling.nodeValue; + } + } else { + var ignore = this.ignoreTags[next.nodeName.toLowerCase()]; + math.nodeValue += (ignore == null ? " " : ignore); + } + math.parentNode.removeChild(next); + } + var AM = math.nodeValue.substr(search.olen,math.nodeValue.length-search.olen-search.clen); + math.parentNode.removeChild(math); + if (this.config.preview !== "none") {this.createPreview(search.mode,AM)} + math = this.createMathTag(search.mode,AM); + this.search = {}; this.pattern.lastIndex = 0; + if (CLOSE) {CLOSE.parentNode.removeChild(CLOSE)} + return math; + }, + + insertNode: function (node) { + var search = this.search; + search.close.parentNode.insertBefore(node,search.close); + }, + + createPreview: function (mode,asciimath) { + var previewClass = MathJax.Hub.config.preRemoveClass; + var preview = this.config.preview; + if (preview === "none") return; + if ((this.search.close.previousSibling||{}).className === previewClass) return; + if (preview === "AsciiMath") {preview = [this.filterPreview(asciimath)]} + if (preview) { + preview = MathJax.HTML.Element("span",{className:previewClass},preview); + this.insertNode(preview); + } + }, + + createMathTag: function (mode,asciimath) { + var script = document.createElement("script"); + script.type = "math/asciimath" + mode; + MathJax.HTML.setScript(script,asciimath); + this.insertNode(script); + return script; + }, + + filterPreview: function (asciimath) {return asciimath} + +}; + +// 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"); +// @license-end diff --git a/js/mathjax/extensions/fast-preview.js b/js/mathjax/extensions/fast-preview.js new file mode 100644 index 0000000..34da2c3 --- /dev/null +++ b/js/mathjax/extensions/fast-preview.js @@ -0,0 +1,157 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- 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-2020 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.7.9", + 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() || !data.script.parentNode) 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"); + +// @license-end diff --git a/js/mathjax/extensions/jsMath2jax.js b/js/mathjax/extensions/jsMath2jax.js new file mode 100644 index 0000000..2c75d4f --- /dev/null +++ b/js/mathjax/extensions/jsMath2jax.js @@ -0,0 +1,107 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/jsMath2jax.js + * + * Implements a jsMath to Jax preprocessor that locates jsMath-style + * ... and
...
tags + * and replaces them with SCRIPT tags for processing by MathJax. + * (Note: use the tex2jax preprocessor to convert TeX delimiters or + * custom delimiters to MathJax SCRIPT tags. This preprocessor is + * only for the SPAN and DIV form of jsMath delimiters). + * + * To use this preprocessor, include "jsMath2jax.js" in the extensions + * array in your config/MathJax.js file, or the MathJax.Hub.Config() call + * in your HTML document. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 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.jsMath2jax = { + version: "2.7.9", + + config: { + preview: "TeX" // Set to "none" to prevent preview strings from being inserted + // or to an array that specifies an HTML snippet to use for + // the preview. + }, + + PreProcess: function (element) { + if (!this.configured) { + this.config = MathJax.Hub.CombineConfig("jsMath2jax",this.config); + if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)} + if (typeof(this.config.previewTeX) !== "undefined" && !this.config.previewTeX) + {this.config.preview = "none"} // backward compatibility for previewTeX parameter + this.previewClass = MathJax.Hub.config.preRemoveClass; + this.configured = true; + } + if (typeof(element) === "string") {element = document.getElementById(element)} + if (!element) {element = document.body} + var span = element.getElementsByTagName("span"), i; + for (i = span.length-1; i >= 0; i--) + {if (String(span[i].className).match(/(^| )math( |$)/)) {this.ConvertMath(span[i],"")}} + var div = element.getElementsByTagName("div"); + for (i = div.length-1; i >= 0; i--) + {if (String(div[i].className).match(/(^| )math( |$)/)) {this.ConvertMath(div[i],"; mode=display")}} + }, + + ConvertMath: function (node,mode) { + if (node.getElementsByTagName("script").length === 0) { + var parent = node.parentNode, + script = this.createMathTag(mode,node.innerHTML); + if (node.nextSibling) {parent.insertBefore(script,node.nextSibling)} + else {parent.appendChild(script)} + if (this.config.preview !== "none") {this.createPreview(node)} + parent.removeChild(node); + } + }, + + createPreview: function (node) { + var previewClass = MathJax.Hub.config.preRemoveClass; + var preview = this.config.preview; + if (preview === "none") return; + if ((node.previousSibling||{}).className === previewClass) return; + if (preview === "TeX") {preview = [this.filterPreview(node.innerHTML)]} + if (preview) { + preview = MathJax.HTML.Element("span",{className:previewClass},preview); + node.parentNode.insertBefore(preview,node); + } + }, + + createMathTag: function (mode,tex) { + tex = tex.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"); + var script = document.createElement("script"); + script.type = "math/tex" + mode; + MathJax.HTML.setScript(script,tex); + return script; + }, + + filterPreview: function (tex) {return tex} + +}; + +// 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"); +// @license-end diff --git a/js/mathjax/extensions/mml2jax.js b/js/mathjax/extensions/mml2jax.js new file mode 100644 index 0000000..cb23f0d --- /dev/null +++ b/js/mathjax/extensions/mml2jax.js @@ -0,0 +1,265 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/mml2jax.js + * + * Implements the MathML to Jax preprocessor that locates nodes + * within the text of a document and replaces them with SCRIPT tags + * for processing by MathJax. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +MathJax.Extension.mml2jax = { + version: "2.7.9", + config: { + 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 + + }, + MMLnamespace: "http://www.w3.org/1998/Math/MathML", + + PreProcess: function (element) { + if (!this.configured) { + this.config = MathJax.Hub.CombineConfig("mml2jax",this.config); + if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)} + this.InitBrowser(); + this.configured = true; + } + if (typeof(element) === "string") {element = document.getElementById(element)} + if (!element) {element = document.body} + var mathArray = []; + // + // Handle all math tags with no namespaces + // + this.PushMathElements(mathArray,element,"math"); + // + // Handle math with namespaces in XHTML + // + this.PushMathElements(mathArray,element,"math",this.MMLnamespace); + // + // Handle math with namespaces in HTML + // + var i, m; + if (typeof(document.namespaces) !== "undefined") { + // + // IE namespaces are listed in document.namespaces + // + try { + for (i = 0, m = document.namespaces.length; i < m; i++) { + var ns = document.namespaces[i]; + if (ns.urn === this.MMLnamespace) + {this.PushMathElements(mathArray,element,ns.name+":math")} + } + } catch (err) {} + } else { + // + // Everybody else + // + var html = document.getElementsByTagName("html")[0]; + if (html) { + for (i = 0, m = html.attributes.length; i < m; i++) { + var attr = html.attributes[i]; + if (attr.nodeName.substr(0,6) === "xmlns:" && attr.nodeValue === this.MMLnamespace) + {this.PushMathElements(mathArray,element,attr.nodeName.substr(6)+":math")} + } + } + } + this.ProcessMathArray(mathArray); + }, + + PushMathElements: function (array,element,name,namespace) { + var math, preview = MathJax.Hub.config.preRemoveClass; + if (namespace) { + if (!element.getElementsByTagNameNS) return; + math = element.getElementsByTagNameNS(namespace,name); + } else { + math = element.getElementsByTagName(name); + } + for (var i = 0, m = math.length; i < m; i++) { + var parent = math[i].parentNode; + if (parent && parent.className !== preview && + !parent.isMathJax && !math[i].prefix === !namespace) array.push(math[i]); + } + }, + + ProcessMathArray: function (math) { + var i, m = math.length; + if (m) { + if (this.MathTagBug) { + for (i = 0; i < m; i++) { + if (math[i].nodeName === "MATH") {this.ProcessMathFlattened(math[i])} + else {this.ProcessMath(math[i])} + } + } else { + for (i = 0; i < m; i++) {this.ProcessMath(math[i])} + } + } + }, + + ProcessMath: function (math) { + var parent = math.parentNode; + if (!parent || parent.className === MathJax.Hub.config.preRemoveClass) return; + var script = document.createElement("script"); + script.type = "math/mml"; + parent.insertBefore(script,math); + if (this.AttributeBug) { + var html = this.OuterHTML(math); + if (this.CleanupHTML) { + html = html.replace(/<\?import .*?>/i,"").replace(/<\?xml:namespace .*?\/>/i,""); + html = html.replace(/ /g," "); + } + MathJax.HTML.setScript(script,html); parent.removeChild(math); + } else { + var span = MathJax.HTML.Element("span"); span.appendChild(math); + MathJax.HTML.setScript(script,span.innerHTML); + } + if (this.config.preview !== "none") {this.createPreview(math,script)} + }, + + ProcessMathFlattened: function (math) { + var parent = math.parentNode; + if (!parent || parent.className === MathJax.Hub.config.preRemoveClass) return; + var script = document.createElement("script"); + script.type = "math/mml"; + parent.insertBefore(script,math); + var mml = "", node, MATH = math; + while (math && math.nodeName !== "/MATH") { + node = math; math = math.nextSibling; + mml += this.NodeHTML(node); + node.parentNode.removeChild(node); + } + if (math && math.nodeName === "/MATH") {math.parentNode.removeChild(math)} + script.text = mml + ""; + if (this.config.preview !== "none") {this.createPreview(MATH,script)} + }, + + NodeHTML: function (node) { + var html, i, m; + if (node.nodeName === "#text") { + html = this.quoteHTML(node.nodeValue); + } else if (node.nodeName === "#comment") { + html = "" + } else { + // In IE, outerHTML doesn't properly quote attributes, so quote them by hand + // In Opera, HTML special characters aren't quoted in attributes, so quote them + html = "<"+node.nodeName.toLowerCase(); + for (i = 0, m = node.attributes.length; i < m; i++) { + var attribute = node.attributes[i]; + if (attribute.specified && attribute.nodeName.substr(0,10) !== "_moz-math-") { + // Opera 11.5 beta turns xmlns into xmlns:xmlns, so put it back (*** check after 11.5 is out ***) + html += " "+attribute.nodeName.toLowerCase().replace(/xmlns:xmlns/,"xmlns")+"="; + var value = attribute.nodeValue; // IE < 8 doesn't properly set style by setAttributes + if (value == null && attribute.nodeName === "style" && node.style) {value = node.style.cssText} + html += '"'+this.quoteHTML(value)+'"'; + } + } + html += ">"; + // Handle internal HTML (possibly due to annotation or missing ) + if (node.outerHTML != null && node.outerHTML.match(/(.<\/[A-Z]+>|\/>)$/)) { + for (i = 0, m = node.childNodes.length; i < m; i++) + {html += this.OuterHTML(node.childNodes[i])} + html += ""; + } + } + return html; + }, + OuterHTML: function (node) { + if (node.nodeName.charAt(0) === "#") {return this.NodeHTML(node)} + if (!this.AttributeBug) {return node.outerHTML} + var html = this.NodeHTML(node); + for (var i = 0, m = node.childNodes.length; i < m; i++) + {html += this.OuterHTML(node.childNodes[i]);} + html += ""; + return html; + }, + quoteHTML: function (string) { + if (string == null) {string = ""} + return string.replace(/&/g,"&").replace(//g,">").replace(/\"/g,"""); + }, + + createPreview: function (math,script) { + var preview = this.config.preview; + if (preview === "none") return; + var isNodePreview = false; + var previewClass = MathJax.Hub.config.preRemoveClass; + if ((script.previousSibling||{}).className === previewClass) return; + if (preview === "mathml") { + isNodePreview = true; + // mathml preview does not work with IE < 9, so fallback to alttext. + if (this.MathTagBug) {preview = "alttext"} else {preview = math.cloneNode(true)} + } + if (preview === "alttext" || preview === "altimg") { + isNodePreview = true; + var alttext = this.filterPreview(math.getAttribute("alttext")); + if (preview === "alttext") { + if (alttext != null) {preview = MathJax.HTML.TextNode(alttext)} else {preview = null} + } else { + var src = math.getAttribute("altimg"); + if (src != null) { + // FIXME: use altimg-valign when display="inline"? + var style = {width: math.getAttribute("altimg-width"), height: math.getAttribute("altimg-height")}; + preview = MathJax.HTML.Element("img",{src:src,alt:alttext,style:style}); + } else {preview = null} + } + } + if (preview) { + var span; + if (isNodePreview) { + span = MathJax.HTML.Element("span",{className:previewClass}); + span.appendChild(preview); + } else { + span = MathJax.HTML.Element("span",{className:previewClass},preview); + } + script.parentNode.insertBefore(span,script); + } + }, + + filterPreview: function (text) {return text}, + + InitBrowser: function () { + var test = MathJax.HTML.Element("span",{id:"<", className: "mathjax", innerHTML: "x"}); + var html = test.outerHTML || ""; + this.AttributeBug = html !== "" && !( + html.match(/id="<"/) && // "<" should convert to "<" + html.match(/class="mathjax"/) && // IE leaves out quotes + html.match(/<\/math>/) // Opera 9 drops tags after self-closing tags + ); + this.MathTagBug = test.childNodes.length > 1; // IE < 9 flattens unknown tags + this.CleanupHTML = MathJax.Hub.Browser.isMSIE; // remove namespace and other added tags + } + +}; + +// +// We register the preprocessors with the following priorities: +// - mml2jax.js: 5 +// - jsMath2jax.js: 8 +// - asciimath2jax.js, tex2jax.js: 10 (default) +// See issues 18 and 484 and the other *2jax.js files. +// +MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.mml2jax],5); +MathJax.Ajax.loadComplete("[MathJax]/extensions/mml2jax.js"); +// @license-end diff --git a/js/mathjax/extensions/tex2jax.js b/js/mathjax/extensions/tex2jax.js new file mode 100644 index 0000000..cfc3c0b --- /dev/null +++ b/js/mathjax/extensions/tex2jax.js @@ -0,0 +1,321 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/tex2jax.js + * + * Implements the TeX to Jax preprocessor that locates TeX code + * within the text of a document and replaces it with SCRIPT tags + * for processing by MathJax. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2009-2020 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.tex2jax = { + version: "2.7.9", + config: { + inlineMath: [ // The start/stop pairs for in-line math +// ['$','$'], // (comment out any you don't want, or add your own, but + ['\\(','\\)'] // be sure that you don't have an extra comma at the end) + ], + + displayMath: [ // The start/stop pairs for display math + ['$$','$$'], // (comment out any you don't want, or add your own, but + ['\\[','\\]'] // be sure that you don't have an extra comma at the end) + ], + + skipTags: ["script","noscript","style","textarea","pre","code","annotation","annotation-xml"], + // The names of the tags whose contents will not be + // scanned for math delimiters + + ignoreClass: "tex2jax_ignore", // the class name of elements whose contents should + // NOT be processed by tex2jax. Note that this + // is a regular expression, so be sure to quote any + // regexp special characters + + processClass: "tex2jax_process", // the class name of elements whose contents SHOULD + // be processed when they appear inside ones that + // are ignored. Note that this is a regular expression, + // so be sure to quote any regexp special characters + + processEscapes: false, // set to true to allow \$ to produce a dollar without + // starting in-line math mode + + processEnvironments: true, // set to true to process \begin{xxx}...\end{xxx} outside + // of math mode, false to prevent that + + processRefs: true, // set to true to process \ref{...} outside of math mode + + + preview: "TeX" // set to "none" to not insert MathJax_Preview spans + // or set to an array specifying an HTML snippet + // to use the same preview for every equation. + + }, + + // + // Tags to ignore when searching for TeX in the page + // + ignoreTags: { + br: (MathJax.Hub.Browser.isMSIE && document.documentMode < 9 ? "\n" : " "), + wbr: "", + "#comment": "" + }, + + PreProcess: function (element) { + if (!this.configured) { + this.config = MathJax.Hub.CombineConfig("tex2jax",this.config); + if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)} + if (typeof(this.config.previewTeX) !== "undefined" && !this.config.previewTeX) + {this.config.preview = "none"} // backward compatibility for previewTeX parameter + this.configured = true; + } + if (typeof(element) === "string") {element = document.getElementById(element)} + if (!element) {element = document.body} + if (this.createPatterns()) {this.scanElement(element,element.nextSibling)} + }, + + createPatterns: function () { + var starts = [], parts = [], i, m, config = this.config; + this.match = {}; + for (i = 0, m = config.inlineMath.length; i < m; i++) { + starts.push(this.patternQuote(config.inlineMath[i][0])); + this.match[config.inlineMath[i][0]] = { + mode: "", + end: config.inlineMath[i][1], + pattern: this.endPattern(config.inlineMath[i][1]) + }; + } + for (i = 0, m = config.displayMath.length; i < m; i++) { + starts.push(this.patternQuote(config.displayMath[i][0])); + this.match[config.displayMath[i][0]] = { + mode: "; mode=display", + end: config.displayMath[i][1], + pattern: this.endPattern(config.displayMath[i][1]) + }; + } + if (starts.length) {parts.push(starts.sort(this.sortLength).join("|"))} + if (config.processEnvironments) {parts.push("\\\\begin\\{([^}]*)\\}")} + if (config.processEscapes) {parts.push("\\\\*\\\\\\\$")} + if (config.processRefs) {parts.push("\\\\(eq)?ref\\{[^}]*\\}")} + this.start = new RegExp(parts.join("|"),"g"); + this.skipTags = new RegExp("^("+config.skipTags.join("|")+")$","i"); + 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); + }, + + patternQuote: function (s) {return s.replace(/([\^$(){}+*?\-|\[\]\:\\])/g,'\\$1')}, + + endPattern: function (end) { + return new RegExp(this.patternQuote(end)+"|\\\\.|[{}]","g"); + }, + + sortLength: function (a,b) { + if (a.length !== b.length) {return b.length - a.length} + return (a == b ? 0 : (a < b ? -1 : 1)); + }, + + scanElement: function (element,stop,ignore) { + var cname, tname, ignoreChild, process; + while (element && element != stop) { + if (element.nodeName.toLowerCase() === '#text') { + if (!ignore) {element = this.scanText(element)} + } else { + cname = (typeof(element.className) === "undefined" ? "" : element.className); + tname = (typeof(element.tagName) === "undefined" ? "" : element.tagName); + if (typeof(cname) !== "string") {cname = String(cname)} // jsxgraph uses non-string class names! + process = this.processClass.exec(cname); + if (element.firstChild && !cname.match(/(^| )MathJax/) && + (process || !this.skipTags.exec(tname))) { + ignoreChild = (ignore || this.ignoreClass.exec(cname)) && !process; + this.scanElement(element.firstChild,stop,ignoreChild); + } + } + if (element) {element = element.nextSibling} + } + }, + + scanText: function (element) { + if (element.nodeValue.replace(/\s+/,'') == '') {return element} + var match, prev, pos = 0, rescan; + this.search = {start: true}; + this.pattern = this.start; + while (element) { + rescan = null; + this.pattern.lastIndex = pos; pos = 0; + while (element && element.nodeName.toLowerCase() === '#text' && + (match = this.pattern.exec(element.nodeValue))) { + if (this.search.start) {element = this.startMatch(match,element)} + else {element = this.endMatch(match,element)} + } + if (this.search.matched) element = this.encloseMath(element); + else if (!this.search.start && !this.search.close) rescan = this.search; + if (element) { + do {prev = element; element = element.nextSibling} + while (element && this.ignoreTags[element.nodeName.toLowerCase()] != null); + if (!element || element.nodeName !== '#text') { + if (!rescan) return (this.search.close ? this.prevEndMatch() : prev); + element = rescan.open; + pos = rescan.opos + rescan.olen + (rescan.blen || 0); + this.search = {start: true}; + this.pattern = this.start; + } + } + } + return element; + }, + + startMatch: function (match,element) { + var delim = this.match[match[0]]; + if (delim != null) { // a start delimiter + this.search = { + end: delim.end, mode: delim.mode, pcount: 0, + open: element, olen: match[0].length, opos: this.pattern.lastIndex - match[0].length + }; + this.switchPattern(delim.pattern); + } else if (match[0].substr(0,6) === "\\begin") { // \begin{...} + this.search = { + end: "\\end{"+match[1]+"}", mode: "; mode=display", pcount: 0, + open: element, olen: 0, opos: this.pattern.lastIndex - match[0].length, + blen: match[1].length + 3, isBeginEnd: true + }; + this.switchPattern(this.endPattern(this.search.end)); + } else if (match[0].substr(0,4) === "\\ref" || match[0].substr(0,6) === "\\eqref") { + this.search = { + mode: "", end: "", open: element, pcount: 0, + olen: 0, opos: this.pattern.lastIndex - match[0].length + } + return this.endMatch([""],element); + } else { // escaped dollar signs + // put $ in a span so it doesn't get processed again + // split off backslashes so they don't get removed later + var slashes = match[0].substr(0,match[0].length-1), n, span; + if (slashes.length % 2 === 0) {span = [slashes.replace(/\\\\/g,"\\")]; n = 1} + else {span = [slashes.substr(1).replace(/\\\\/g,"\\"),"$"]; n = 0} + span = MathJax.HTML.Element("span",null,span); + var text = MathJax.HTML.TextNode(element.nodeValue.substr(0,match.index)); + element.nodeValue = element.nodeValue.substr(match.index + match[0].length - n); + element.parentNode.insertBefore(span,element); + element.parentNode.insertBefore(text,span); + this.pattern.lastIndex = n; + } + return element; + }, + + endMatch: function (match,element) { + var search = this.search; + if (match[0] == search.end) { + if (!search.close || search.pcount === 0) { + search.close = element; + search.cpos = this.pattern.lastIndex; + search.clen = (search.isBeginEnd ? 0 : match[0].length); + } + if (search.pcount === 0) { + search.matched = true; + element = this.encloseMath(element); + this.switchPattern(this.start); + } + } + if (match[0] === "{") {search.pcount++} + else if (match[0] === "}" && search.pcount) {search.pcount--} + return element; + }, + prevEndMatch: function () { + this.search.matched = true; + var element = this.encloseMath(this.search.close); + this.switchPattern(this.start); + return element; + }, + + switchPattern: function (pattern) { + pattern.lastIndex = this.pattern.lastIndex; + this.pattern = pattern; + this.search.start = (pattern === this.start); + }, + + encloseMath: function (element) { + var search = this.search, close = search.close, CLOSE, math, next; + if (search.cpos === close.length) {close = close.nextSibling} + else {close = close.splitText(search.cpos)} + if (!close) {CLOSE = close = MathJax.HTML.addText(search.close.parentNode,"")} + search.close = close; + math = (search.opos ? search.open.splitText(search.opos) : search.open); + while ((next = math.nextSibling) && next !== close) { + if (next.nodeValue !== null) { + if (next.nodeName === "#comment") { + math.nodeValue += next.nodeValue.replace(/^\[CDATA\[((.|\n|\r)*)\]\]$/,"$1"); + } else { + math.nodeValue += next.nodeValue; + } + } else { + var ignore = this.ignoreTags[next.nodeName.toLowerCase()]; + math.nodeValue += (ignore == null ? " " : ignore); + } + math.parentNode.removeChild(next); + } + var TeX = math.nodeValue.substr(search.olen,math.nodeValue.length-search.olen-search.clen); + math.parentNode.removeChild(math); + if (this.config.preview !== "none") {this.createPreview(search.mode,TeX)} + math = this.createMathTag(search.mode,TeX); + this.search = {}; this.pattern.lastIndex = 0; + if (CLOSE) {CLOSE.parentNode.removeChild(CLOSE)} + return math; + }, + + insertNode: function (node) { + var search = this.search; + search.close.parentNode.insertBefore(node,search.close); + }, + + createPreview: function (mode,tex) { + var previewClass = MathJax.Hub.config.preRemoveClass; + var preview = this.config.preview; + if (preview === "none") return; + if ((this.search.close.previousSibling||{}).className === previewClass) return; + if (preview === "TeX") {preview = [this.filterPreview(tex)]} + if (preview) { + preview = MathJax.HTML.Element("span",{className:previewClass},preview); + this.insertNode(preview); + } + }, + + createMathTag: function (mode,tex) { + var script = document.createElement("script"); + script.type = "math/tex" + mode; + MathJax.HTML.setScript(script,tex); + this.insertNode(script); + return script; + }, + + filterPreview: function (tex) {return tex} + +}; + +// 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"); +// @license-end diff --git a/js/mathjax/extensions/toMathML.js b/js/mathjax/extensions/toMathML.js new file mode 100644 index 0000000..cb95c08 --- /dev/null +++ b/js/mathjax/extensions/toMathML.js @@ -0,0 +1,243 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/toMathML.js + * + * Implements a toMathML() method for the mml Element Jax that returns + * a MathML string from a given math expression. + * + * --------------------------------------------------------------------- + * + * Copyright (c) 2010-2020 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.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () { + var VERSION = "2.7.9"; + + var MML = MathJax.ElementJax.mml, + SETTINGS = MathJax.Hub.config.menuSettings; + + MML.mbase.Augment({ + + toMathML: function (space) { + var inferred = (this.inferred && this.parent.inferRow); + if (space == null) {space = ""} + var tag = this.type, attr = this.toMathMLattributes(); + if (tag === "mspace") {return space + "<"+tag+attr+" />"} + 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 && !this.isChars) {data.push(SPACE+"")} + } + 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+" />"} + return space + "<"+tag+attr+">\n"+data.join("\n")+"\n"+ space +""; + }, + + toMathMLattributes: function () { + 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" && (!this.attr || !('xmlns' in this.attr))) + {attr.push('xmlns="http://www.w3.org/1998/Math/MathML"')} + if (!this.attrNames) { + 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 = 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 ""} + }, + toMathMLclass: function (attr) { + var CLASS = []; if (this["class"]) {CLASS.push(this["class"])} + if (this.isa(MML.TeXAtom) && SETTINGS.texHints) { + var TEXCLASS = ["ORD","OP","BIN","REL","OPEN","CLOSE","PUNCT","INNER","VCENTER"][this.texClass]; + if (TEXCLASS) { + CLASS.push("MJX-TeXAtom-"+TEXCLASS) + if (TEXCLASS === "OP" && !this.movablelimits) CLASS.push("MJX-fixedlimits"); + } + } + if (this.mathvariant && this.toMathMLvariants[this.mathvariant]) + {CLASS.push("MJX"+this.mathvariant)} + if (this.variantForm) {CLASS.push("MJX-variant")} + if (CLASS.length) {attr.unshift('class="'+this.toMathMLquote(CLASS.join(" "))+'"')} + }, + toMathMLattribute: function (value) { + if (typeof(value) === "string" && + value.replace(/ /g,"").match(/^(([-+])?(\d+(\.\d*)?|\.\d+))mu$/)) { + // FIXME: should take scriptlevel into account + 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); + }, + toMathMLvariants: { + "-tex-caligraphic": MML.VARIANT.SCRIPT, + "-tex-caligraphic-bold": MML.VARIANT.BOLDSCRIPT, + "-tex-oldstyle": MML.VARIANT.NORMAL, + "-tex-oldstyle-bold": MML.VARIANT.BOLD, + "-tex-mathit": MML.VARIANT.ITALIC + }, + + toMathMLquote: function (string) { + string = String(string).split(""); + for (var i = 0, m = string.length; i < m; i++) { + var n = string[i].charCodeAt(0); + 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 { + // 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; + if (this.data[this.sup] == null) {tag = "msub"} + if (this.data[this.sub] == null) {tag = "msup"} + var attr = this.toMathMLattributes(); + delete this.data[0].inferred; + var data = []; + for (var i = 0, m = this.data.length; i < m; i++) + {if (this.data[i]) {data.push(this.data[i].toMathML(space+" "))}} + return space + "<"+tag+attr+">\n" + data.join("\n") + "\n" + space + ""; + } + }); + + MML.munderover.Augment({ + toMathML: function (space) { + var tag = this.type; + var base = this.data[this.base]; + if (base && base.isa(MML.TeXAtom) && base.movablelimits && !base.Get("displaystyle")) { + type = "msubsup"; + if (this.data[this.under] == null) {tag = "msup"} + if (this.data[this.over] == null) {tag = "msub"} + } else { + if (this.data[this.under] == null) {tag = "mover"} + if (this.data[this.over] == null) {tag = "munder"} + } + var attr = this.toMathMLattributes(); + delete this.data[0].inferred; + var data = []; + for (var i = 0, m = this.data.length; i < m; i++) + {if (this.data[i]) {data.push(this.data[i].toMathML(space+" "))}} + return space + "<"+tag+attr+">\n" + data.join("\n") + "\n" + space + ""; + } + }); + + MML.TeXAtom.Augment({ + toMathML: function (space) { + // FIXME: Handle spacing using mpadded? + var attr = this.toMathMLattributes(); + if (!attr && this.data[0].data.length === 1) {return space.substr(2) + this.data[0].toMathML(space)} + return space+"\n" + this.data[0].toMathML(space+" ")+"\n"+space+""; + } + }); + + MML.chars.Augment({ + toMathML: function (space) {return (space||"") + this.toMathMLquote(this.toString())} + }); + + MML.entity.Augment({ + toMathML: function (space) {return (space||"") + "&"+this.toMathMLquote(this.data[0])+";"} + }); + + MML.xml.Augment({ + toMathML: function (space) {return (space||"") + this.toString()} + }); + + MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function () { + MML.TeXmathchoice.Augment({ + toMathML: function (space) {return this.Core().toMathML(space)} + }); + }); + + MathJax.Hub.Startup.signal.Post("toMathML Ready"); + +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/toMathML.js"); +// @license-end -- cgit v1.2.3