mhchem.js (79514B)
1 (function webpackUniversalModuleDefinition(root, factory) { 2 if(typeof exports === 'object' && typeof module === 'object') 3 module.exports = factory(require("katex")); 4 else if(typeof define === 'function' && define.amd) 5 define(["katex"], factory); 6 else { 7 var a = typeof exports === 'object' ? factory(require("katex")) : factory(root["katex"]); 8 for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; 9 } 10 })((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__974__) { 11 return /******/ (function() { // webpackBootstrap 12 /******/ "use strict"; 13 /******/ var __webpack_modules__ = ({ 14 15 /***/ 974: 16 /***/ (function(module) { 17 18 module.exports = __WEBPACK_EXTERNAL_MODULE__974__; 19 20 /***/ }) 21 22 /******/ }); 23 /************************************************************************/ 24 /******/ // The module cache 25 /******/ var __webpack_module_cache__ = {}; 26 /******/ 27 /******/ // The require function 28 /******/ function __webpack_require__(moduleId) { 29 /******/ // Check if module is in cache 30 /******/ if(__webpack_module_cache__[moduleId]) { 31 /******/ return __webpack_module_cache__[moduleId].exports; 32 /******/ } 33 /******/ // Create a new module (and put it into the cache) 34 /******/ var module = __webpack_module_cache__[moduleId] = { 35 /******/ // no module.id needed 36 /******/ // no module.loaded needed 37 /******/ exports: {} 38 /******/ }; 39 /******/ 40 /******/ // Execute the module function 41 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 42 /******/ 43 /******/ // Return the exports of the module 44 /******/ return module.exports; 45 /******/ } 46 /******/ 47 /************************************************************************/ 48 /******/ /* webpack/runtime/compat get default export */ 49 /******/ !function() { 50 /******/ // getDefaultExport function for compatibility with non-harmony modules 51 /******/ __webpack_require__.n = function(module) { 52 /******/ var getter = module && module.__esModule ? 53 /******/ function() { return module['default']; } : 54 /******/ function() { return module; }; 55 /******/ __webpack_require__.d(getter, { a: getter }); 56 /******/ return getter; 57 /******/ }; 58 /******/ }(); 59 /******/ 60 /******/ /* webpack/runtime/define property getters */ 61 /******/ !function() { 62 /******/ // define getter functions for harmony exports 63 /******/ __webpack_require__.d = function(exports, definition) { 64 /******/ for(var key in definition) { 65 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 66 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 67 /******/ } 68 /******/ } 69 /******/ }; 70 /******/ }(); 71 /******/ 72 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 73 /******/ !function() { 74 /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } 75 /******/ }(); 76 /******/ 77 /************************************************************************/ 78 var __webpack_exports__ = {}; 79 // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 80 !function() { 81 /* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(974); 82 /* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__); 83 /* eslint-disable */ 84 85 /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ 86 87 /* vim: set ts=2 et sw=2 tw=80: */ 88 89 /************************************************************* 90 * 91 * KaTeX mhchem.js 92 * 93 * This file implements a KaTeX version of mhchem version 3.3.0. 94 * It is adapted from MathJax/extensions/TeX/mhchem.js 95 * It differs from the MathJax version as follows: 96 * 1. The interface is changed so that it can be called from KaTeX, not MathJax. 97 * 2. \rlap and \llap are replaced with \mathrlap and \mathllap. 98 * 3. Four lines of code are edited in order to use \raisebox instead of \raise. 99 * 4. The reaction arrow code is simplified. All reaction arrows are rendered 100 * using KaTeX extensible arrows instead of building non-extensible arrows. 101 * 5. \tripledash vertical alignment is slightly adjusted. 102 * 103 * This code, as other KaTeX code, is released under the MIT license. 104 * 105 * /************************************************************* 106 * 107 * MathJax/extensions/TeX/mhchem.js 108 * 109 * Implements the \ce command for handling chemical formulas 110 * from the mhchem LaTeX package. 111 * 112 * --------------------------------------------------------------------- 113 * 114 * Copyright (c) 2011-2015 The MathJax Consortium 115 * Copyright (c) 2015-2018 Martin Hensel 116 * 117 * Licensed under the Apache License, Version 2.0 (the "License"); 118 * you may not use this file except in compliance with the License. 119 * You may obtain a copy of the License at 120 * 121 * http://www.apache.org/licenses/LICENSE-2.0 122 * 123 * Unless required by applicable law or agreed to in writing, software 124 * distributed under the License is distributed on an "AS IS" BASIS, 125 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 126 * See the License for the specific language governing permissions and 127 * limitations under the License. 128 */ 129 // 130 // Coding Style 131 // - use '' for identifiers that can by minified/uglified 132 // - use "" for strings that need to stay untouched 133 // version: "3.3.0" for MathJax and KaTeX 134 // Add \ce, \pu, and \tripledash to the KaTeX macros. 135 katex__WEBPACK_IMPORTED_MODULE_0___default().__defineMacro("\\ce", function (context) { 136 return chemParse(context.consumeArgs(1)[0], "ce"); 137 }); 138 139 katex__WEBPACK_IMPORTED_MODULE_0___default().__defineMacro("\\pu", function (context) { 140 return chemParse(context.consumeArgs(1)[0], "pu"); 141 }); // Needed for \bond for the ~ forms 142 // Raise by 2.56mu, not 2mu. We're raising a hyphen-minus, U+002D, not 143 // a mathematical minus, U+2212. So we need that extra 0.56. 144 145 146 katex__WEBPACK_IMPORTED_MODULE_0___default().__defineMacro("\\tripledash", "{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu" + "\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}"); 147 148 // 149 // This is the main function for handing the \ce and \pu commands. 150 // It takes the argument to \ce or \pu and returns the corresponding TeX string. 151 // 152 153 var chemParse = function chemParse(tokens, stateMachine) { 154 // Recreate the argument string from KaTeX's array of tokens. 155 var str = ""; 156 var expectedLoc = tokens[tokens.length - 1].loc.start; 157 158 for (var i = tokens.length - 1; i >= 0; i--) { 159 if (tokens[i].loc.start > expectedLoc) { 160 // context.consumeArgs has eaten a space. 161 str += " "; 162 expectedLoc = tokens[i].loc.start; 163 } 164 165 str += tokens[i].text; 166 expectedLoc += tokens[i].text.length; 167 } 168 169 var tex = texify.go(mhchemParser.go(str, stateMachine)); 170 return tex; 171 }; // 172 // Core parser for mhchem syntax (recursive) 173 // 174 175 /** @type {MhchemParser} */ 176 177 178 var mhchemParser = { 179 // 180 // Parses mchem \ce syntax 181 // 182 // Call like 183 // go("H2O"); 184 // 185 go: function go(input, stateMachine) { 186 if (!input) { 187 return []; 188 } 189 190 if (stateMachine === undefined) { 191 stateMachine = 'ce'; 192 } 193 194 var state = '0'; // 195 // String buffers for parsing: 196 // 197 // buffer.a == amount 198 // buffer.o == element 199 // buffer.b == left-side superscript 200 // buffer.p == left-side subscript 201 // buffer.q == right-side subscript 202 // buffer.d == right-side superscript 203 // 204 // buffer.r == arrow 205 // buffer.rdt == arrow, script above, type 206 // buffer.rd == arrow, script above, content 207 // buffer.rqt == arrow, script below, type 208 // buffer.rq == arrow, script below, content 209 // 210 // buffer.text_ 211 // buffer.rm 212 // etc. 213 // 214 // buffer.parenthesisLevel == int, starting at 0 215 // buffer.sb == bool, space before 216 // buffer.beginsWithBond == bool 217 // 218 // These letters are also used as state names. 219 // 220 // Other states: 221 // 0 == begin of main part (arrow/operator unlikely) 222 // 1 == next entity 223 // 2 == next entity (arrow/operator unlikely) 224 // 3 == next atom 225 // c == macro 226 // 227 228 /** @type {Buffer} */ 229 230 var buffer = {}; 231 buffer['parenthesisLevel'] = 0; 232 input = input.replace(/\n/g, " "); 233 input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-"); 234 input = input.replace(/[\u2026]/g, "..."); // 235 // Looks through mhchemParser.transitions, to execute a matching action 236 // (recursive) 237 // 238 239 var lastInput; 240 var watchdog = 10; 241 /** @type {ParserOutput[]} */ 242 243 var output = []; 244 245 while (true) { 246 if (lastInput !== input) { 247 watchdog = 10; 248 lastInput = input; 249 } else { 250 watchdog--; 251 } // 252 // Find actions in transition table 253 // 254 255 256 var machine = mhchemParser.stateMachines[stateMachine]; 257 var t = machine.transitions[state] || machine.transitions['*']; 258 259 iterateTransitions: for (var i = 0; i < t.length; i++) { 260 var matches = mhchemParser.patterns.match_(t[i].pattern, input); 261 262 if (matches) { 263 // 264 // Execute actions 265 // 266 var task = t[i].task; 267 268 for (var iA = 0; iA < task.action_.length; iA++) { 269 var o; // 270 // Find and execute action 271 // 272 273 if (machine.actions[task.action_[iA].type_]) { 274 o = machine.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option); 275 } else if (mhchemParser.actions[task.action_[iA].type_]) { 276 o = mhchemParser.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option); 277 } else { 278 throw ["MhchemBugA", "mhchem bug A. Please report. (" + task.action_[iA].type_ + ")"]; // Trying to use non-existing action 279 } // 280 // Add output 281 // 282 283 284 mhchemParser.concatArray(output, o); 285 } // 286 // Set next state, 287 // Shorten input, 288 // Continue with next character 289 // (= apply only one transition per position) 290 // 291 292 293 state = task.nextState || state; 294 295 if (input.length > 0) { 296 if (!task.revisit) { 297 input = matches.remainder; 298 } 299 300 if (!task.toContinue) { 301 break iterateTransitions; 302 } 303 } else { 304 return output; 305 } 306 } 307 } // 308 // Prevent infinite loop 309 // 310 311 312 if (watchdog <= 0) { 313 throw ["MhchemBugU", "mhchem bug U. Please report."]; // Unexpected character 314 } 315 } 316 }, 317 concatArray: function concatArray(a, b) { 318 if (b) { 319 if (Array.isArray(b)) { 320 for (var iB = 0; iB < b.length; iB++) { 321 a.push(b[iB]); 322 } 323 } else { 324 a.push(b); 325 } 326 } 327 }, 328 patterns: { 329 // 330 // Matching patterns 331 // either regexps or function that return null or {match_:"a", remainder:"bc"} 332 // 333 patterns: { 334 // property names must not look like integers ("2") for correct property traversal order, later on 335 'empty': /^$/, 336 'else': /^./, 337 'else2': /^./, 338 'space': /^\s/, 339 'space A': /^\s(?=[A-Z\\$])/, 340 'space$': /^\s$/, 341 'a-z': /^[a-z]/, 342 'x': /^x/, 343 'x$': /^x$/, 344 'i$': /^i$/, 345 'letters': /^(?:[a-zA-Z\u03B1-\u03C9\u0391-\u03A9?@]|(?:\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))))+/, 346 '\\greek': /^\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))/, 347 'one lowercase latin letter $': /^(?:([a-z])(?:$|[^a-zA-Z]))$/, 348 '$one lowercase latin letter$ $': /^\$(?:([a-z])(?:$|[^a-zA-Z]))\$$/, 349 'one lowercase greek letter $': /^(?:\$?[\u03B1-\u03C9]\$?|\$?\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\s*\$?)(?:\s+|\{\}|(?![a-zA-Z]))$/, 350 'digits': /^[0-9]+/, 351 '-9.,9': /^[+\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))/, 352 '-9.,9 no missing 0': /^[+\-]?[0-9]+(?:[.,][0-9]+)?/, 353 '(-)(9.,9)(e)(99)': function e99(input) { 354 var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))?(\((?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))\))?(?:([eE]|\s*(\*|x|\\times|\u00D7)\s*10\^)([+\-]?[0-9]+|\{[+\-]?[0-9]+\}))?/); 355 356 if (m && m[0]) { 357 return { 358 match_: m.splice(1), 359 remainder: input.substr(m[0].length) 360 }; 361 } 362 363 return null; 364 }, 365 '(-)(9)^(-9)': function _(input) { 366 var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+)?)\^([+\-]?[0-9]+|\{[+\-]?[0-9]+\})/); 367 368 if (m && m[0]) { 369 return { 370 match_: m.splice(1), 371 remainder: input.substr(m[0].length) 372 }; 373 } 374 375 return null; 376 }, 377 'state of aggregation $': function stateOfAggregation$(input) { 378 // ... or crystal system 379 var a = mhchemParser.patterns.findObserveGroups(input, "", /^\([a-z]{1,3}(?=[\),])/, ")", ""); // (aq), (aq,$\infty$), (aq, sat) 380 381 if (a && a.remainder.match(/^($|[\s,;\)\]\}])/)) { 382 return a; 383 } // AND end of 'phrase' 384 385 386 var m = input.match(/^(?:\((?:\\ca\s?)?\$[amothc]\$\))/); // OR crystal system ($o$) (\ca$c$) 387 388 if (m) { 389 return { 390 match_: m[0], 391 remainder: input.substr(m[0].length) 392 }; 393 } 394 395 return null; 396 }, 397 '_{(state of aggregation)}$': /^_\{(\([a-z]{1,3}\))\}/, 398 '{[(': /^(?:\\\{|\[|\()/, 399 ')]}': /^(?:\)|\]|\\\})/, 400 ', ': /^[,;]\s*/, 401 ',': /^[,;]/, 402 '.': /^[.]/, 403 '. ': /^([.\u22C5\u00B7\u2022])\s*/, 404 '...': /^\.\.\.(?=$|[^.])/, 405 '* ': /^([*])\s*/, 406 '^{(...)}': function _(input) { 407 return mhchemParser.patterns.findObserveGroups(input, "^{", "", "", "}"); 408 }, 409 '^($...$)': function $$(input) { 410 return mhchemParser.patterns.findObserveGroups(input, "^", "$", "$", ""); 411 }, 412 '^a': /^\^([0-9]+|[^\\_])/, 413 '^\\x{}{}': function x(input) { 414 return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); 415 }, 416 '^\\x{}': function x(input) { 417 return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", ""); 418 }, 419 '^\\x': /^\^(\\[a-zA-Z]+)\s*/, 420 '^(-1)': /^\^(-?\d+)/, 421 '\'': /^'/, 422 '_{(...)}': function _(input) { 423 return mhchemParser.patterns.findObserveGroups(input, "_{", "", "", "}"); 424 }, 425 '_($...$)': function _$$(input) { 426 return mhchemParser.patterns.findObserveGroups(input, "_", "$", "$", ""); 427 }, 428 '_9': /^_([+\-]?[0-9]+|[^\\])/, 429 '_\\x{}{}': function _X(input) { 430 return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); 431 }, 432 '_\\x{}': function _X(input) { 433 return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", ""); 434 }, 435 '_\\x': /^_(\\[a-zA-Z]+)\s*/, 436 '^_': /^(?:\^(?=_)|\_(?=\^)|[\^_]$)/, 437 '{}': /^\{\}/, 438 '{...}': function _(input) { 439 return mhchemParser.patterns.findObserveGroups(input, "", "{", "}", ""); 440 }, 441 '{(...)}': function _(input) { 442 return mhchemParser.patterns.findObserveGroups(input, "{", "", "", "}"); 443 }, 444 '$...$': function $$(input) { 445 return mhchemParser.patterns.findObserveGroups(input, "", "$", "$", ""); 446 }, 447 '${(...)}$': function $$(input) { 448 return mhchemParser.patterns.findObserveGroups(input, "${", "", "", "}$"); 449 }, 450 '$(...)$': function $$(input) { 451 return mhchemParser.patterns.findObserveGroups(input, "$", "", "", "$"); 452 }, 453 '=<>': /^[=<>]/, 454 '#': /^[#\u2261]/, 455 '+': /^\+/, 456 '-$': /^-(?=[\s_},;\]/]|$|\([a-z]+\))/, 457 // -space -, -; -] -/ -$ -state-of-aggregation 458 '-9': /^-(?=[0-9])/, 459 '- orbital overlap': /^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/, 460 '-': /^-/, 461 'pm-operator': /^(?:\\pm|\$\\pm\$|\+-|\+\/-)/, 462 'operator': /^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/, 463 'arrowUpDown': /^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/, 464 '\\bond{(...)}': function bond(input) { 465 return mhchemParser.patterns.findObserveGroups(input, "\\bond{", "", "", "}"); 466 }, 467 '->': /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/, 468 'CMT': /^[CMT](?=\[)/, 469 '[(...)]': function _(input) { 470 return mhchemParser.patterns.findObserveGroups(input, "[", "", "", "]"); 471 }, 472 '1st-level escape': /^(&|\\\\|\\hline)\s*/, 473 '\\,': /^(?:\\[,\ ;:])/, 474 // \\x - but output no space before 475 '\\x{}{}': function x(input) { 476 return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); 477 }, 478 '\\x{}': function x(input) { 479 return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", ""); 480 }, 481 '\\ca': /^\\ca(?:\s+|(?![a-zA-Z]))/, 482 '\\x': /^(?:\\[a-zA-Z]+\s*|\\[_&{}%])/, 483 'orbital': /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/, 484 // only those with numbers in front, because the others will be formatted correctly anyway 485 'others': /^[\/~|]/, 486 '\\frac{(...)}': function frac(input) { 487 return mhchemParser.patterns.findObserveGroups(input, "\\frac{", "", "", "}", "{", "", "", "}"); 488 }, 489 '\\overset{(...)}': function overset(input) { 490 return mhchemParser.patterns.findObserveGroups(input, "\\overset{", "", "", "}", "{", "", "", "}"); 491 }, 492 "\\underset{(...)}": function underset(input) { 493 return mhchemParser.patterns.findObserveGroups(input, "\\underset{", "", "", "}", "{", "", "", "}"); 494 }, 495 "\\underbrace{(...)}": function underbrace(input) { 496 return mhchemParser.patterns.findObserveGroups(input, "\\underbrace{", "", "", "}_", "{", "", "", "}"); 497 }, 498 '\\color{(...)}0': function color0(input) { 499 return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}"); 500 }, 501 '\\color{(...)}{(...)}1': function color1(input) { 502 return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}", "{", "", "", "}"); 503 }, 504 '\\color(...){(...)}2': function color2(input) { 505 return mhchemParser.patterns.findObserveGroups(input, "\\color", "\\", "", /^(?=\{)/, "{", "", "", "}"); 506 }, 507 '\\ce{(...)}': function ce(input) { 508 return mhchemParser.patterns.findObserveGroups(input, "\\ce{", "", "", "}"); 509 }, 510 'oxidation$': /^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, 511 'd-oxidation$': /^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, 512 // 0 could be oxidation or charge 513 'roman numeral': /^[IVX]+/, 514 '1/2$': /^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/, 515 'amount': function amount(input) { 516 var match; // e.g. 2, 0.5, 1/2, -2, n/2, +; $a$ could be added later in parsing 517 518 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))/); 519 520 if (match) { 521 return { 522 match_: match[0], 523 remainder: input.substr(match[0].length) 524 }; 525 } 526 527 var a = mhchemParser.patterns.findObserveGroups(input, "", "$", "$", ""); 528 529 if (a) { 530 // e.g. $2n-1$, $-$ 531 match = a.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/); 532 533 if (match) { 534 return { 535 match_: match[0], 536 remainder: input.substr(match[0].length) 537 }; 538 } 539 } 540 541 return null; 542 }, 543 'amount2': function amount2(input) { 544 return this['amount'](input); 545 }, 546 '(KV letters),': /^(?:[A-Z][a-z]{0,2}|i)(?=,)/, 547 'formula$': function formula$(input) { 548 if (input.match(/^\([a-z]+\)$/)) { 549 return null; 550 } // state of aggregation = no formula 551 552 553 var match = input.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/); 554 555 if (match) { 556 return { 557 match_: match[0], 558 remainder: input.substr(match[0].length) 559 }; 560 } 561 562 return null; 563 }, 564 'uprightEntities': /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/, 565 '/': /^\s*(\/)\s*/, 566 '//': /^\s*(\/\/)\s*/, 567 '*': /^\s*[*.]\s*/ 568 }, 569 findObserveGroups: function findObserveGroups(input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) { 570 /** @type {{(input: string, pattern: string | RegExp): string | string[] | null;}} */ 571 var _match = function _match(input, pattern) { 572 if (typeof pattern === "string") { 573 if (input.indexOf(pattern) !== 0) { 574 return null; 575 } 576 577 return pattern; 578 } else { 579 var match = input.match(pattern); 580 581 if (!match) { 582 return null; 583 } 584 585 return match[0]; 586 } 587 }; 588 /** @type {{(input: string, i: number, endChars: string | RegExp): {endMatchBegin: number, endMatchEnd: number} | null;}} */ 589 590 591 var _findObserveGroups = function _findObserveGroups(input, i, endChars) { 592 var braces = 0; 593 594 while (i < input.length) { 595 var a = input.charAt(i); 596 597 var match = _match(input.substr(i), endChars); 598 599 if (match !== null && braces === 0) { 600 return { 601 endMatchBegin: i, 602 endMatchEnd: i + match.length 603 }; 604 } else if (a === "{") { 605 braces++; 606 } else if (a === "}") { 607 if (braces === 0) { 608 throw ["ExtraCloseMissingOpen", "Extra close brace or missing open brace"]; 609 } else { 610 braces--; 611 } 612 } 613 614 i++; 615 } 616 617 if (braces > 0) { 618 return null; 619 } 620 621 return null; 622 }; 623 624 var match = _match(input, begExcl); 625 626 if (match === null) { 627 return null; 628 } 629 630 input = input.substr(match.length); 631 match = _match(input, begIncl); 632 633 if (match === null) { 634 return null; 635 } 636 637 var e = _findObserveGroups(input, match.length, endIncl || endExcl); 638 639 if (e === null) { 640 return null; 641 } 642 643 var match1 = input.substring(0, endIncl ? e.endMatchEnd : e.endMatchBegin); 644 645 if (!(beg2Excl || beg2Incl)) { 646 return { 647 match_: match1, 648 remainder: input.substr(e.endMatchEnd) 649 }; 650 } else { 651 var group2 = this.findObserveGroups(input.substr(e.endMatchEnd), beg2Excl, beg2Incl, end2Incl, end2Excl); 652 653 if (group2 === null) { 654 return null; 655 } 656 /** @type {string[]} */ 657 658 659 var matchRet = [match1, group2.match_]; 660 return { 661 match_: combine ? matchRet.join("") : matchRet, 662 remainder: group2.remainder 663 }; 664 } 665 }, 666 // 667 // Matching function 668 // e.g. match("a", input) will look for the regexp called "a" and see if it matches 669 // returns null or {match_:"a", remainder:"bc"} 670 // 671 match_: function match_(m, input) { 672 var pattern = mhchemParser.patterns.patterns[m]; 673 674 if (pattern === undefined) { 675 throw ["MhchemBugP", "mhchem bug P. Please report. (" + m + ")"]; // Trying to use non-existing pattern 676 } else if (typeof pattern === "function") { 677 return mhchemParser.patterns.patterns[m](input); // cannot use cached var pattern here, because some pattern functions need this===mhchemParser 678 } else { 679 // RegExp 680 var match = input.match(pattern); 681 682 if (match) { 683 var mm; 684 685 if (match[2]) { 686 mm = [match[1], match[2]]; 687 } else if (match[1]) { 688 mm = match[1]; 689 } else { 690 mm = match[0]; 691 } 692 693 return { 694 match_: mm, 695 remainder: input.substr(match[0].length) 696 }; 697 } 698 699 return null; 700 } 701 } 702 }, 703 // 704 // Generic state machine actions 705 // 706 actions: { 707 'a=': function a(buffer, m) { 708 buffer.a = (buffer.a || "") + m; 709 }, 710 'b=': function b(buffer, m) { 711 buffer.b = (buffer.b || "") + m; 712 }, 713 'p=': function p(buffer, m) { 714 buffer.p = (buffer.p || "") + m; 715 }, 716 'o=': function o(buffer, m) { 717 buffer.o = (buffer.o || "") + m; 718 }, 719 'q=': function q(buffer, m) { 720 buffer.q = (buffer.q || "") + m; 721 }, 722 'd=': function d(buffer, m) { 723 buffer.d = (buffer.d || "") + m; 724 }, 725 'rm=': function rm(buffer, m) { 726 buffer.rm = (buffer.rm || "") + m; 727 }, 728 'text=': function text(buffer, m) { 729 buffer.text_ = (buffer.text_ || "") + m; 730 }, 731 'insert': function insert(buffer, m, a) { 732 return { 733 type_: a 734 }; 735 }, 736 'insert+p1': function insertP1(buffer, m, a) { 737 return { 738 type_: a, 739 p1: m 740 }; 741 }, 742 'insert+p1+p2': function insertP1P2(buffer, m, a) { 743 return { 744 type_: a, 745 p1: m[0], 746 p2: m[1] 747 }; 748 }, 749 'copy': function copy(buffer, m) { 750 return m; 751 }, 752 'rm': function rm(buffer, m) { 753 return { 754 type_: 'rm', 755 p1: m || "" 756 }; 757 }, 758 'text': function text(buffer, m) { 759 return mhchemParser.go(m, 'text'); 760 }, 761 '{text}': function text(buffer, m) { 762 var ret = ["{"]; 763 mhchemParser.concatArray(ret, mhchemParser.go(m, 'text')); 764 ret.push("}"); 765 return ret; 766 }, 767 'tex-math': function texMath(buffer, m) { 768 return mhchemParser.go(m, 'tex-math'); 769 }, 770 'tex-math tight': function texMathTight(buffer, m) { 771 return mhchemParser.go(m, 'tex-math tight'); 772 }, 773 'bond': function bond(buffer, m, k) { 774 return { 775 type_: 'bond', 776 kind_: k || m 777 }; 778 }, 779 'color0-output': function color0Output(buffer, m) { 780 return { 781 type_: 'color0', 782 color: m[0] 783 }; 784 }, 785 'ce': function ce(buffer, m) { 786 return mhchemParser.go(m); 787 }, 788 '1/2': function _(buffer, m) { 789 /** @type {ParserOutput[]} */ 790 var ret = []; 791 792 if (m.match(/^[+\-]/)) { 793 ret.push(m.substr(0, 1)); 794 m = m.substr(1); 795 } 796 797 var n = m.match(/^([0-9]+|\$[a-z]\$|[a-z])\/([0-9]+)(\$[a-z]\$|[a-z])?$/); 798 n[1] = n[1].replace(/\$/g, ""); 799 ret.push({ 800 type_: 'frac', 801 p1: n[1], 802 p2: n[2] 803 }); 804 805 if (n[3]) { 806 n[3] = n[3].replace(/\$/g, ""); 807 ret.push({ 808 type_: 'tex-math', 809 p1: n[3] 810 }); 811 } 812 813 return ret; 814 }, 815 '9,9': function _(buffer, m) { 816 return mhchemParser.go(m, '9,9'); 817 } 818 }, 819 // 820 // createTransitions 821 // convert { 'letter': { 'state': { action_: 'output' } } } to { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] } 822 // with expansion of 'a|b' to 'a' and 'b' (at 2 places) 823 // 824 createTransitions: function createTransitions(o) { 825 var pattern, state; 826 /** @type {string[]} */ 827 828 var stateArray; 829 var i; // 830 // 1. Collect all states 831 // 832 833 /** @type {Transitions} */ 834 835 var transitions = {}; 836 837 for (pattern in o) { 838 for (state in o[pattern]) { 839 stateArray = state.split("|"); 840 o[pattern][state].stateArray = stateArray; 841 842 for (i = 0; i < stateArray.length; i++) { 843 transitions[stateArray[i]] = []; 844 } 845 } 846 } // 847 // 2. Fill states 848 // 849 850 851 for (pattern in o) { 852 for (state in o[pattern]) { 853 stateArray = o[pattern][state].stateArray || []; 854 855 for (i = 0; i < stateArray.length; i++) { 856 // 857 // 2a. Normalize actions into array: 'text=' ==> [{type_:'text='}] 858 // (Note to myself: Resolving the function here would be problematic. It would need .bind (for *this*) and currying (for *option*).) 859 // 860 861 /** @type {any} */ 862 var p = o[pattern][state]; 863 864 if (p.action_) { 865 p.action_ = [].concat(p.action_); 866 867 for (var k = 0; k < p.action_.length; k++) { 868 if (typeof p.action_[k] === "string") { 869 p.action_[k] = { 870 type_: p.action_[k] 871 }; 872 } 873 } 874 } else { 875 p.action_ = []; 876 } // 877 // 2.b Multi-insert 878 // 879 880 881 var patternArray = pattern.split("|"); 882 883 for (var j = 0; j < patternArray.length; j++) { 884 if (stateArray[i] === '*') { 885 // insert into all 886 for (var t in transitions) { 887 transitions[t].push({ 888 pattern: patternArray[j], 889 task: p 890 }); 891 } 892 } else { 893 transitions[stateArray[i]].push({ 894 pattern: patternArray[j], 895 task: p 896 }); 897 } 898 } 899 } 900 } 901 } 902 903 return transitions; 904 }, 905 stateMachines: {} 906 }; // 907 // Definition of state machines 908 // 909 910 mhchemParser.stateMachines = { 911 // 912 // \ce state machines 913 // 914 //#region ce 915 'ce': { 916 // main parser 917 transitions: mhchemParser.createTransitions({ 918 'empty': { 919 '*': { 920 action_: 'output' 921 } 922 }, 923 'else': { 924 '0|1|2': { 925 action_: 'beginsWithBond=false', 926 revisit: true, 927 toContinue: true 928 } 929 }, 930 'oxidation$': { 931 '0': { 932 action_: 'oxidation-output' 933 } 934 }, 935 'CMT': { 936 'r': { 937 action_: 'rdt=', 938 nextState: 'rt' 939 }, 940 'rd': { 941 action_: 'rqt=', 942 nextState: 'rdt' 943 } 944 }, 945 'arrowUpDown': { 946 '0|1|2|as': { 947 action_: ['sb=false', 'output', 'operator'], 948 nextState: '1' 949 } 950 }, 951 'uprightEntities': { 952 '0|1|2': { 953 action_: ['o=', 'output'], 954 nextState: '1' 955 } 956 }, 957 'orbital': { 958 '0|1|2|3': { 959 action_: 'o=', 960 nextState: 'o' 961 } 962 }, 963 '->': { 964 '0|1|2|3': { 965 action_: 'r=', 966 nextState: 'r' 967 }, 968 'a|as': { 969 action_: ['output', 'r='], 970 nextState: 'r' 971 }, 972 '*': { 973 action_: ['output', 'r='], 974 nextState: 'r' 975 } 976 }, 977 '+': { 978 'o': { 979 action_: 'd= kv', 980 nextState: 'd' 981 }, 982 'd|D': { 983 action_: 'd=', 984 nextState: 'd' 985 }, 986 'q': { 987 action_: 'd=', 988 nextState: 'qd' 989 }, 990 'qd|qD': { 991 action_: 'd=', 992 nextState: 'qd' 993 }, 994 'dq': { 995 action_: ['output', 'd='], 996 nextState: 'd' 997 }, 998 '3': { 999 action_: ['sb=false', 'output', 'operator'], 1000 nextState: '0' 1001 } 1002 }, 1003 'amount': { 1004 '0|2': { 1005 action_: 'a=', 1006 nextState: 'a' 1007 } 1008 }, 1009 'pm-operator': { 1010 '0|1|2|a|as': { 1011 action_: ['sb=false', 'output', { 1012 type_: 'operator', 1013 option: '\\pm' 1014 }], 1015 nextState: '0' 1016 } 1017 }, 1018 'operator': { 1019 '0|1|2|a|as': { 1020 action_: ['sb=false', 'output', 'operator'], 1021 nextState: '0' 1022 } 1023 }, 1024 '-$': { 1025 'o|q': { 1026 action_: ['charge or bond', 'output'], 1027 nextState: 'qd' 1028 }, 1029 'd': { 1030 action_: 'd=', 1031 nextState: 'd' 1032 }, 1033 'D': { 1034 action_: ['output', { 1035 type_: 'bond', 1036 option: "-" 1037 }], 1038 nextState: '3' 1039 }, 1040 'q': { 1041 action_: 'd=', 1042 nextState: 'qd' 1043 }, 1044 'qd': { 1045 action_: 'd=', 1046 nextState: 'qd' 1047 }, 1048 'qD|dq': { 1049 action_: ['output', { 1050 type_: 'bond', 1051 option: "-" 1052 }], 1053 nextState: '3' 1054 } 1055 }, 1056 '-9': { 1057 '3|o': { 1058 action_: ['output', { 1059 type_: 'insert', 1060 option: 'hyphen' 1061 }], 1062 nextState: '3' 1063 } 1064 }, 1065 '- orbital overlap': { 1066 'o': { 1067 action_: ['output', { 1068 type_: 'insert', 1069 option: 'hyphen' 1070 }], 1071 nextState: '2' 1072 }, 1073 'd': { 1074 action_: ['output', { 1075 type_: 'insert', 1076 option: 'hyphen' 1077 }], 1078 nextState: '2' 1079 } 1080 }, 1081 '-': { 1082 '0|1|2': { 1083 action_: [{ 1084 type_: 'output', 1085 option: 1 1086 }, 'beginsWithBond=true', { 1087 type_: 'bond', 1088 option: "-" 1089 }], 1090 nextState: '3' 1091 }, 1092 '3': { 1093 action_: { 1094 type_: 'bond', 1095 option: "-" 1096 } 1097 }, 1098 'a': { 1099 action_: ['output', { 1100 type_: 'insert', 1101 option: 'hyphen' 1102 }], 1103 nextState: '2' 1104 }, 1105 'as': { 1106 action_: [{ 1107 type_: 'output', 1108 option: 2 1109 }, { 1110 type_: 'bond', 1111 option: "-" 1112 }], 1113 nextState: '3' 1114 }, 1115 'b': { 1116 action_: 'b=' 1117 }, 1118 'o': { 1119 action_: { 1120 type_: '- after o/d', 1121 option: false 1122 }, 1123 nextState: '2' 1124 }, 1125 'q': { 1126 action_: { 1127 type_: '- after o/d', 1128 option: false 1129 }, 1130 nextState: '2' 1131 }, 1132 'd|qd|dq': { 1133 action_: { 1134 type_: '- after o/d', 1135 option: true 1136 }, 1137 nextState: '2' 1138 }, 1139 'D|qD|p': { 1140 action_: ['output', { 1141 type_: 'bond', 1142 option: "-" 1143 }], 1144 nextState: '3' 1145 } 1146 }, 1147 'amount2': { 1148 '1|3': { 1149 action_: 'a=', 1150 nextState: 'a' 1151 } 1152 }, 1153 'letters': { 1154 '0|1|2|3|a|as|b|p|bp|o': { 1155 action_: 'o=', 1156 nextState: 'o' 1157 }, 1158 'q|dq': { 1159 action_: ['output', 'o='], 1160 nextState: 'o' 1161 }, 1162 'd|D|qd|qD': { 1163 action_: 'o after d', 1164 nextState: 'o' 1165 } 1166 }, 1167 'digits': { 1168 'o': { 1169 action_: 'q=', 1170 nextState: 'q' 1171 }, 1172 'd|D': { 1173 action_: 'q=', 1174 nextState: 'dq' 1175 }, 1176 'q': { 1177 action_: ['output', 'o='], 1178 nextState: 'o' 1179 }, 1180 'a': { 1181 action_: 'o=', 1182 nextState: 'o' 1183 } 1184 }, 1185 'space A': { 1186 'b|p|bp': {} 1187 }, 1188 'space': { 1189 'a': { 1190 nextState: 'as' 1191 }, 1192 '0': { 1193 action_: 'sb=false' 1194 }, 1195 '1|2': { 1196 action_: 'sb=true' 1197 }, 1198 'r|rt|rd|rdt|rdq': { 1199 action_: 'output', 1200 nextState: '0' 1201 }, 1202 '*': { 1203 action_: ['output', 'sb=true'], 1204 nextState: '1' 1205 } 1206 }, 1207 '1st-level escape': { 1208 '1|2': { 1209 action_: ['output', { 1210 type_: 'insert+p1', 1211 option: '1st-level escape' 1212 }] 1213 }, 1214 '*': { 1215 action_: ['output', { 1216 type_: 'insert+p1', 1217 option: '1st-level escape' 1218 }], 1219 nextState: '0' 1220 } 1221 }, 1222 '[(...)]': { 1223 'r|rt': { 1224 action_: 'rd=', 1225 nextState: 'rd' 1226 }, 1227 'rd|rdt': { 1228 action_: 'rq=', 1229 nextState: 'rdq' 1230 } 1231 }, 1232 '...': { 1233 'o|d|D|dq|qd|qD': { 1234 action_: ['output', { 1235 type_: 'bond', 1236 option: "..." 1237 }], 1238 nextState: '3' 1239 }, 1240 '*': { 1241 action_: [{ 1242 type_: 'output', 1243 option: 1 1244 }, { 1245 type_: 'insert', 1246 option: 'ellipsis' 1247 }], 1248 nextState: '1' 1249 } 1250 }, 1251 '. |* ': { 1252 '*': { 1253 action_: ['output', { 1254 type_: 'insert', 1255 option: 'addition compound' 1256 }], 1257 nextState: '1' 1258 } 1259 }, 1260 'state of aggregation $': { 1261 '*': { 1262 action_: ['output', 'state of aggregation'], 1263 nextState: '1' 1264 } 1265 }, 1266 '{[(': { 1267 'a|as|o': { 1268 action_: ['o=', 'output', 'parenthesisLevel++'], 1269 nextState: '2' 1270 }, 1271 '0|1|2|3': { 1272 action_: ['o=', 'output', 'parenthesisLevel++'], 1273 nextState: '2' 1274 }, 1275 '*': { 1276 action_: ['output', 'o=', 'output', 'parenthesisLevel++'], 1277 nextState: '2' 1278 } 1279 }, 1280 ')]}': { 1281 '0|1|2|3|b|p|bp|o': { 1282 action_: ['o=', 'parenthesisLevel--'], 1283 nextState: 'o' 1284 }, 1285 'a|as|d|D|q|qd|qD|dq': { 1286 action_: ['output', 'o=', 'parenthesisLevel--'], 1287 nextState: 'o' 1288 } 1289 }, 1290 ', ': { 1291 '*': { 1292 action_: ['output', 'comma'], 1293 nextState: '0' 1294 } 1295 }, 1296 '^_': { 1297 // ^ and _ without a sensible argument 1298 '*': {} 1299 }, 1300 '^{(...)}|^($...$)': { 1301 '0|1|2|as': { 1302 action_: 'b=', 1303 nextState: 'b' 1304 }, 1305 'p': { 1306 action_: 'b=', 1307 nextState: 'bp' 1308 }, 1309 '3|o': { 1310 action_: 'd= kv', 1311 nextState: 'D' 1312 }, 1313 'q': { 1314 action_: 'd=', 1315 nextState: 'qD' 1316 }, 1317 'd|D|qd|qD|dq': { 1318 action_: ['output', 'd='], 1319 nextState: 'D' 1320 } 1321 }, 1322 '^a|^\\x{}{}|^\\x{}|^\\x|\'': { 1323 '0|1|2|as': { 1324 action_: 'b=', 1325 nextState: 'b' 1326 }, 1327 'p': { 1328 action_: 'b=', 1329 nextState: 'bp' 1330 }, 1331 '3|o': { 1332 action_: 'd= kv', 1333 nextState: 'd' 1334 }, 1335 'q': { 1336 action_: 'd=', 1337 nextState: 'qd' 1338 }, 1339 'd|qd|D|qD': { 1340 action_: 'd=' 1341 }, 1342 'dq': { 1343 action_: ['output', 'd='], 1344 nextState: 'd' 1345 } 1346 }, 1347 '_{(state of aggregation)}$': { 1348 'd|D|q|qd|qD|dq': { 1349 action_: ['output', 'q='], 1350 nextState: 'q' 1351 } 1352 }, 1353 '_{(...)}|_($...$)|_9|_\\x{}{}|_\\x{}|_\\x': { 1354 '0|1|2|as': { 1355 action_: 'p=', 1356 nextState: 'p' 1357 }, 1358 'b': { 1359 action_: 'p=', 1360 nextState: 'bp' 1361 }, 1362 '3|o': { 1363 action_: 'q=', 1364 nextState: 'q' 1365 }, 1366 'd|D': { 1367 action_: 'q=', 1368 nextState: 'dq' 1369 }, 1370 'q|qd|qD|dq': { 1371 action_: ['output', 'q='], 1372 nextState: 'q' 1373 } 1374 }, 1375 '=<>': { 1376 '0|1|2|3|a|as|o|q|d|D|qd|qD|dq': { 1377 action_: [{ 1378 type_: 'output', 1379 option: 2 1380 }, 'bond'], 1381 nextState: '3' 1382 } 1383 }, 1384 '#': { 1385 '0|1|2|3|a|as|o': { 1386 action_: [{ 1387 type_: 'output', 1388 option: 2 1389 }, { 1390 type_: 'bond', 1391 option: "#" 1392 }], 1393 nextState: '3' 1394 } 1395 }, 1396 '{}': { 1397 '*': { 1398 action_: { 1399 type_: 'output', 1400 option: 1 1401 }, 1402 nextState: '1' 1403 } 1404 }, 1405 '{...}': { 1406 '0|1|2|3|a|as|b|p|bp': { 1407 action_: 'o=', 1408 nextState: 'o' 1409 }, 1410 'o|d|D|q|qd|qD|dq': { 1411 action_: ['output', 'o='], 1412 nextState: 'o' 1413 } 1414 }, 1415 '$...$': { 1416 'a': { 1417 action_: 'a=' 1418 }, 1419 // 2$n$ 1420 '0|1|2|3|as|b|p|bp|o': { 1421 action_: 'o=', 1422 nextState: 'o' 1423 }, 1424 // not 'amount' 1425 'as|o': { 1426 action_: 'o=' 1427 }, 1428 'q|d|D|qd|qD|dq': { 1429 action_: ['output', 'o='], 1430 nextState: 'o' 1431 } 1432 }, 1433 '\\bond{(...)}': { 1434 '*': { 1435 action_: [{ 1436 type_: 'output', 1437 option: 2 1438 }, 'bond'], 1439 nextState: "3" 1440 } 1441 }, 1442 '\\frac{(...)}': { 1443 '*': { 1444 action_: [{ 1445 type_: 'output', 1446 option: 1 1447 }, 'frac-output'], 1448 nextState: '3' 1449 } 1450 }, 1451 '\\overset{(...)}': { 1452 '*': { 1453 action_: [{ 1454 type_: 'output', 1455 option: 2 1456 }, 'overset-output'], 1457 nextState: '3' 1458 } 1459 }, 1460 "\\underset{(...)}": { 1461 '*': { 1462 action_: [{ 1463 type_: 'output', 1464 option: 2 1465 }, 'underset-output'], 1466 nextState: '3' 1467 } 1468 }, 1469 "\\underbrace{(...)}": { 1470 '*': { 1471 action_: [{ 1472 type_: 'output', 1473 option: 2 1474 }, 'underbrace-output'], 1475 nextState: '3' 1476 } 1477 }, 1478 '\\color{(...)}{(...)}1|\\color(...){(...)}2': { 1479 '*': { 1480 action_: [{ 1481 type_: 'output', 1482 option: 2 1483 }, 'color-output'], 1484 nextState: '3' 1485 } 1486 }, 1487 '\\color{(...)}0': { 1488 '*': { 1489 action_: [{ 1490 type_: 'output', 1491 option: 2 1492 }, 'color0-output'] 1493 } 1494 }, 1495 '\\ce{(...)}': { 1496 '*': { 1497 action_: [{ 1498 type_: 'output', 1499 option: 2 1500 }, 'ce'], 1501 nextState: '3' 1502 } 1503 }, 1504 '\\,': { 1505 '*': { 1506 action_: [{ 1507 type_: 'output', 1508 option: 1 1509 }, 'copy'], 1510 nextState: '1' 1511 } 1512 }, 1513 '\\x{}{}|\\x{}|\\x': { 1514 '0|1|2|3|a|as|b|p|bp|o|c0': { 1515 action_: ['o=', 'output'], 1516 nextState: '3' 1517 }, 1518 '*': { 1519 action_: ['output', 'o=', 'output'], 1520 nextState: '3' 1521 } 1522 }, 1523 'others': { 1524 '*': { 1525 action_: [{ 1526 type_: 'output', 1527 option: 1 1528 }, 'copy'], 1529 nextState: '3' 1530 } 1531 }, 1532 'else2': { 1533 'a': { 1534 action_: 'a to o', 1535 nextState: 'o', 1536 revisit: true 1537 }, 1538 'as': { 1539 action_: ['output', 'sb=true'], 1540 nextState: '1', 1541 revisit: true 1542 }, 1543 'r|rt|rd|rdt|rdq': { 1544 action_: ['output'], 1545 nextState: '0', 1546 revisit: true 1547 }, 1548 '*': { 1549 action_: ['output', 'copy'], 1550 nextState: '3' 1551 } 1552 } 1553 }), 1554 actions: { 1555 'o after d': function oAfterD(buffer, m) { 1556 var ret; 1557 1558 if ((buffer.d || "").match(/^[0-9]+$/)) { 1559 var tmp = buffer.d; 1560 buffer.d = undefined; 1561 ret = this['output'](buffer); 1562 buffer.b = tmp; 1563 } else { 1564 ret = this['output'](buffer); 1565 } 1566 1567 mhchemParser.actions['o='](buffer, m); 1568 return ret; 1569 }, 1570 'd= kv': function dKv(buffer, m) { 1571 buffer.d = m; 1572 buffer.dType = 'kv'; 1573 }, 1574 'charge or bond': function chargeOrBond(buffer, m) { 1575 if (buffer['beginsWithBond']) { 1576 /** @type {ParserOutput[]} */ 1577 var ret = []; 1578 mhchemParser.concatArray(ret, this['output'](buffer)); 1579 mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-")); 1580 return ret; 1581 } else { 1582 buffer.d = m; 1583 } 1584 }, 1585 '- after o/d': function afterOD(buffer, m, isAfterD) { 1586 var c1 = mhchemParser.patterns.match_('orbital', buffer.o || ""); 1587 var c2 = mhchemParser.patterns.match_('one lowercase greek letter $', buffer.o || ""); 1588 var c3 = mhchemParser.patterns.match_('one lowercase latin letter $', buffer.o || ""); 1589 var c4 = mhchemParser.patterns.match_('$one lowercase latin letter$ $', buffer.o || ""); 1590 var hyphenFollows = m === "-" && (c1 && c1.remainder === "" || c2 || c3 || c4); 1591 1592 if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) { 1593 buffer.o = '$' + buffer.o + '$'; 1594 } 1595 /** @type {ParserOutput[]} */ 1596 1597 1598 var ret = []; 1599 1600 if (hyphenFollows) { 1601 mhchemParser.concatArray(ret, this['output'](buffer)); 1602 ret.push({ 1603 type_: 'hyphen' 1604 }); 1605 } else { 1606 c1 = mhchemParser.patterns.match_('digits', buffer.d || ""); 1607 1608 if (isAfterD && c1 && c1.remainder === '') { 1609 mhchemParser.concatArray(ret, mhchemParser.actions['d='](buffer, m)); 1610 mhchemParser.concatArray(ret, this['output'](buffer)); 1611 } else { 1612 mhchemParser.concatArray(ret, this['output'](buffer)); 1613 mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-")); 1614 } 1615 } 1616 1617 return ret; 1618 }, 1619 'a to o': function aToO(buffer) { 1620 buffer.o = buffer.a; 1621 buffer.a = undefined; 1622 }, 1623 'sb=true': function sbTrue(buffer) { 1624 buffer.sb = true; 1625 }, 1626 'sb=false': function sbFalse(buffer) { 1627 buffer.sb = false; 1628 }, 1629 'beginsWithBond=true': function beginsWithBondTrue(buffer) { 1630 buffer['beginsWithBond'] = true; 1631 }, 1632 'beginsWithBond=false': function beginsWithBondFalse(buffer) { 1633 buffer['beginsWithBond'] = false; 1634 }, 1635 'parenthesisLevel++': function parenthesisLevel(buffer) { 1636 buffer['parenthesisLevel']++; 1637 }, 1638 'parenthesisLevel--': function parenthesisLevel(buffer) { 1639 buffer['parenthesisLevel']--; 1640 }, 1641 'state of aggregation': function stateOfAggregation(buffer, m) { 1642 return { 1643 type_: 'state of aggregation', 1644 p1: mhchemParser.go(m, 'o') 1645 }; 1646 }, 1647 'comma': function comma(buffer, m) { 1648 var a = m.replace(/\s*$/, ''); 1649 var withSpace = a !== m; 1650 1651 if (withSpace && buffer['parenthesisLevel'] === 0) { 1652 return { 1653 type_: 'comma enumeration L', 1654 p1: a 1655 }; 1656 } else { 1657 return { 1658 type_: 'comma enumeration M', 1659 p1: a 1660 }; 1661 } 1662 }, 1663 'output': function output(buffer, m, entityFollows) { 1664 // entityFollows: 1665 // undefined = if we have nothing else to output, also ignore the just read space (buffer.sb) 1666 // 1 = an entity follows, never omit the space if there was one just read before (can only apply to state 1) 1667 // 2 = 1 + the entity can have an amount, so output a\, instead of converting it to o (can only apply to states a|as) 1668 1669 /** @type {ParserOutput | ParserOutput[]} */ 1670 var ret; 1671 1672 if (!buffer.r) { 1673 ret = []; 1674 1675 if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) {//ret = []; 1676 } else { 1677 if (buffer.sb) { 1678 ret.push({ 1679 type_: 'entitySkip' 1680 }); 1681 } 1682 1683 if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows !== 2) { 1684 buffer.o = buffer.a; 1685 buffer.a = undefined; 1686 } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) { 1687 buffer.o = buffer.a; 1688 buffer.d = buffer.b; 1689 buffer.q = buffer.p; 1690 buffer.a = buffer.b = buffer.p = undefined; 1691 } else { 1692 if (buffer.o && buffer.dType === 'kv' && mhchemParser.patterns.match_('d-oxidation$', buffer.d || "")) { 1693 buffer.dType = 'oxidation'; 1694 } else if (buffer.o && buffer.dType === 'kv' && !buffer.q) { 1695 buffer.dType = undefined; 1696 } 1697 } 1698 1699 ret.push({ 1700 type_: 'chemfive', 1701 a: mhchemParser.go(buffer.a, 'a'), 1702 b: mhchemParser.go(buffer.b, 'bd'), 1703 p: mhchemParser.go(buffer.p, 'pq'), 1704 o: mhchemParser.go(buffer.o, 'o'), 1705 q: mhchemParser.go(buffer.q, 'pq'), 1706 d: mhchemParser.go(buffer.d, buffer.dType === 'oxidation' ? 'oxidation' : 'bd'), 1707 dType: buffer.dType 1708 }); 1709 } 1710 } else { 1711 // r 1712 1713 /** @type {ParserOutput[]} */ 1714 var rd; 1715 1716 if (buffer.rdt === 'M') { 1717 rd = mhchemParser.go(buffer.rd, 'tex-math'); 1718 } else if (buffer.rdt === 'T') { 1719 rd = [{ 1720 type_: 'text', 1721 p1: buffer.rd || "" 1722 }]; 1723 } else { 1724 rd = mhchemParser.go(buffer.rd); 1725 } 1726 /** @type {ParserOutput[]} */ 1727 1728 1729 var rq; 1730 1731 if (buffer.rqt === 'M') { 1732 rq = mhchemParser.go(buffer.rq, 'tex-math'); 1733 } else if (buffer.rqt === 'T') { 1734 rq = [{ 1735 type_: 'text', 1736 p1: buffer.rq || "" 1737 }]; 1738 } else { 1739 rq = mhchemParser.go(buffer.rq); 1740 } 1741 1742 ret = { 1743 type_: 'arrow', 1744 r: buffer.r, 1745 rd: rd, 1746 rq: rq 1747 }; 1748 } 1749 1750 for (var p in buffer) { 1751 if (p !== 'parenthesisLevel' && p !== 'beginsWithBond') { 1752 delete buffer[p]; 1753 } 1754 } 1755 1756 return ret; 1757 }, 1758 'oxidation-output': function oxidationOutput(buffer, m) { 1759 var ret = ["{"]; 1760 mhchemParser.concatArray(ret, mhchemParser.go(m, 'oxidation')); 1761 ret.push("}"); 1762 return ret; 1763 }, 1764 'frac-output': function fracOutput(buffer, m) { 1765 return { 1766 type_: 'frac-ce', 1767 p1: mhchemParser.go(m[0]), 1768 p2: mhchemParser.go(m[1]) 1769 }; 1770 }, 1771 'overset-output': function oversetOutput(buffer, m) { 1772 return { 1773 type_: 'overset', 1774 p1: mhchemParser.go(m[0]), 1775 p2: mhchemParser.go(m[1]) 1776 }; 1777 }, 1778 'underset-output': function undersetOutput(buffer, m) { 1779 return { 1780 type_: 'underset', 1781 p1: mhchemParser.go(m[0]), 1782 p2: mhchemParser.go(m[1]) 1783 }; 1784 }, 1785 'underbrace-output': function underbraceOutput(buffer, m) { 1786 return { 1787 type_: 'underbrace', 1788 p1: mhchemParser.go(m[0]), 1789 p2: mhchemParser.go(m[1]) 1790 }; 1791 }, 1792 'color-output': function colorOutput(buffer, m) { 1793 return { 1794 type_: 'color', 1795 color1: m[0], 1796 color2: mhchemParser.go(m[1]) 1797 }; 1798 }, 1799 'r=': function r(buffer, m) { 1800 buffer.r = m; 1801 }, 1802 'rdt=': function rdt(buffer, m) { 1803 buffer.rdt = m; 1804 }, 1805 'rd=': function rd(buffer, m) { 1806 buffer.rd = m; 1807 }, 1808 'rqt=': function rqt(buffer, m) { 1809 buffer.rqt = m; 1810 }, 1811 'rq=': function rq(buffer, m) { 1812 buffer.rq = m; 1813 }, 1814 'operator': function operator(buffer, m, p1) { 1815 return { 1816 type_: 'operator', 1817 kind_: p1 || m 1818 }; 1819 } 1820 } 1821 }, 1822 'a': { 1823 transitions: mhchemParser.createTransitions({ 1824 'empty': { 1825 '*': {} 1826 }, 1827 '1/2$': { 1828 '0': { 1829 action_: '1/2' 1830 } 1831 }, 1832 'else': { 1833 '0': { 1834 nextState: '1', 1835 revisit: true 1836 } 1837 }, 1838 '$(...)$': { 1839 '*': { 1840 action_: 'tex-math tight', 1841 nextState: '1' 1842 } 1843 }, 1844 ',': { 1845 '*': { 1846 action_: { 1847 type_: 'insert', 1848 option: 'commaDecimal' 1849 } 1850 } 1851 }, 1852 'else2': { 1853 '*': { 1854 action_: 'copy' 1855 } 1856 } 1857 }), 1858 actions: {} 1859 }, 1860 'o': { 1861 transitions: mhchemParser.createTransitions({ 1862 'empty': { 1863 '*': {} 1864 }, 1865 '1/2$': { 1866 '0': { 1867 action_: '1/2' 1868 } 1869 }, 1870 'else': { 1871 '0': { 1872 nextState: '1', 1873 revisit: true 1874 } 1875 }, 1876 'letters': { 1877 '*': { 1878 action_: 'rm' 1879 } 1880 }, 1881 '\\ca': { 1882 '*': { 1883 action_: { 1884 type_: 'insert', 1885 option: 'circa' 1886 } 1887 } 1888 }, 1889 '\\x{}{}|\\x{}|\\x': { 1890 '*': { 1891 action_: 'copy' 1892 } 1893 }, 1894 '${(...)}$|$(...)$': { 1895 '*': { 1896 action_: 'tex-math' 1897 } 1898 }, 1899 '{(...)}': { 1900 '*': { 1901 action_: '{text}' 1902 } 1903 }, 1904 'else2': { 1905 '*': { 1906 action_: 'copy' 1907 } 1908 } 1909 }), 1910 actions: {} 1911 }, 1912 'text': { 1913 transitions: mhchemParser.createTransitions({ 1914 'empty': { 1915 '*': { 1916 action_: 'output' 1917 } 1918 }, 1919 '{...}': { 1920 '*': { 1921 action_: 'text=' 1922 } 1923 }, 1924 '${(...)}$|$(...)$': { 1925 '*': { 1926 action_: 'tex-math' 1927 } 1928 }, 1929 '\\greek': { 1930 '*': { 1931 action_: ['output', 'rm'] 1932 } 1933 }, 1934 '\\,|\\x{}{}|\\x{}|\\x': { 1935 '*': { 1936 action_: ['output', 'copy'] 1937 } 1938 }, 1939 'else': { 1940 '*': { 1941 action_: 'text=' 1942 } 1943 } 1944 }), 1945 actions: { 1946 'output': function output(buffer) { 1947 if (buffer.text_) { 1948 /** @type {ParserOutput} */ 1949 var ret = { 1950 type_: 'text', 1951 p1: buffer.text_ 1952 }; 1953 1954 for (var p in buffer) { 1955 delete buffer[p]; 1956 } 1957 1958 return ret; 1959 } 1960 } 1961 } 1962 }, 1963 'pq': { 1964 transitions: mhchemParser.createTransitions({ 1965 'empty': { 1966 '*': {} 1967 }, 1968 'state of aggregation $': { 1969 '*': { 1970 action_: 'state of aggregation' 1971 } 1972 }, 1973 'i$': { 1974 '0': { 1975 nextState: '!f', 1976 revisit: true 1977 } 1978 }, 1979 '(KV letters),': { 1980 '0': { 1981 action_: 'rm', 1982 nextState: '0' 1983 } 1984 }, 1985 'formula$': { 1986 '0': { 1987 nextState: 'f', 1988 revisit: true 1989 } 1990 }, 1991 '1/2$': { 1992 '0': { 1993 action_: '1/2' 1994 } 1995 }, 1996 'else': { 1997 '0': { 1998 nextState: '!f', 1999 revisit: true 2000 } 2001 }, 2002 '${(...)}$|$(...)$': { 2003 '*': { 2004 action_: 'tex-math' 2005 } 2006 }, 2007 '{(...)}': { 2008 '*': { 2009 action_: 'text' 2010 } 2011 }, 2012 'a-z': { 2013 'f': { 2014 action_: 'tex-math' 2015 } 2016 }, 2017 'letters': { 2018 '*': { 2019 action_: 'rm' 2020 } 2021 }, 2022 '-9.,9': { 2023 '*': { 2024 action_: '9,9' 2025 } 2026 }, 2027 ',': { 2028 '*': { 2029 action_: { 2030 type_: 'insert+p1', 2031 option: 'comma enumeration S' 2032 } 2033 } 2034 }, 2035 '\\color{(...)}{(...)}1|\\color(...){(...)}2': { 2036 '*': { 2037 action_: 'color-output' 2038 } 2039 }, 2040 '\\color{(...)}0': { 2041 '*': { 2042 action_: 'color0-output' 2043 } 2044 }, 2045 '\\ce{(...)}': { 2046 '*': { 2047 action_: 'ce' 2048 } 2049 }, 2050 '\\,|\\x{}{}|\\x{}|\\x': { 2051 '*': { 2052 action_: 'copy' 2053 } 2054 }, 2055 'else2': { 2056 '*': { 2057 action_: 'copy' 2058 } 2059 } 2060 }), 2061 actions: { 2062 'state of aggregation': function stateOfAggregation(buffer, m) { 2063 return { 2064 type_: 'state of aggregation subscript', 2065 p1: mhchemParser.go(m, 'o') 2066 }; 2067 }, 2068 'color-output': function colorOutput(buffer, m) { 2069 return { 2070 type_: 'color', 2071 color1: m[0], 2072 color2: mhchemParser.go(m[1], 'pq') 2073 }; 2074 } 2075 } 2076 }, 2077 'bd': { 2078 transitions: mhchemParser.createTransitions({ 2079 'empty': { 2080 '*': {} 2081 }, 2082 'x$': { 2083 '0': { 2084 nextState: '!f', 2085 revisit: true 2086 } 2087 }, 2088 'formula$': { 2089 '0': { 2090 nextState: 'f', 2091 revisit: true 2092 } 2093 }, 2094 'else': { 2095 '0': { 2096 nextState: '!f', 2097 revisit: true 2098 } 2099 }, 2100 '-9.,9 no missing 0': { 2101 '*': { 2102 action_: '9,9' 2103 } 2104 }, 2105 '.': { 2106 '*': { 2107 action_: { 2108 type_: 'insert', 2109 option: 'electron dot' 2110 } 2111 } 2112 }, 2113 'a-z': { 2114 'f': { 2115 action_: 'tex-math' 2116 } 2117 }, 2118 'x': { 2119 '*': { 2120 action_: { 2121 type_: 'insert', 2122 option: 'KV x' 2123 } 2124 } 2125 }, 2126 'letters': { 2127 '*': { 2128 action_: 'rm' 2129 } 2130 }, 2131 '\'': { 2132 '*': { 2133 action_: { 2134 type_: 'insert', 2135 option: 'prime' 2136 } 2137 } 2138 }, 2139 '${(...)}$|$(...)$': { 2140 '*': { 2141 action_: 'tex-math' 2142 } 2143 }, 2144 '{(...)}': { 2145 '*': { 2146 action_: 'text' 2147 } 2148 }, 2149 '\\color{(...)}{(...)}1|\\color(...){(...)}2': { 2150 '*': { 2151 action_: 'color-output' 2152 } 2153 }, 2154 '\\color{(...)}0': { 2155 '*': { 2156 action_: 'color0-output' 2157 } 2158 }, 2159 '\\ce{(...)}': { 2160 '*': { 2161 action_: 'ce' 2162 } 2163 }, 2164 '\\,|\\x{}{}|\\x{}|\\x': { 2165 '*': { 2166 action_: 'copy' 2167 } 2168 }, 2169 'else2': { 2170 '*': { 2171 action_: 'copy' 2172 } 2173 } 2174 }), 2175 actions: { 2176 'color-output': function colorOutput(buffer, m) { 2177 return { 2178 type_: 'color', 2179 color1: m[0], 2180 color2: mhchemParser.go(m[1], 'bd') 2181 }; 2182 } 2183 } 2184 }, 2185 'oxidation': { 2186 transitions: mhchemParser.createTransitions({ 2187 'empty': { 2188 '*': {} 2189 }, 2190 'roman numeral': { 2191 '*': { 2192 action_: 'roman-numeral' 2193 } 2194 }, 2195 '${(...)}$|$(...)$': { 2196 '*': { 2197 action_: 'tex-math' 2198 } 2199 }, 2200 'else': { 2201 '*': { 2202 action_: 'copy' 2203 } 2204 } 2205 }), 2206 actions: { 2207 'roman-numeral': function romanNumeral(buffer, m) { 2208 return { 2209 type_: 'roman numeral', 2210 p1: m || "" 2211 }; 2212 } 2213 } 2214 }, 2215 'tex-math': { 2216 transitions: mhchemParser.createTransitions({ 2217 'empty': { 2218 '*': { 2219 action_: 'output' 2220 } 2221 }, 2222 '\\ce{(...)}': { 2223 '*': { 2224 action_: ['output', 'ce'] 2225 } 2226 }, 2227 '{...}|\\,|\\x{}{}|\\x{}|\\x': { 2228 '*': { 2229 action_: 'o=' 2230 } 2231 }, 2232 'else': { 2233 '*': { 2234 action_: 'o=' 2235 } 2236 } 2237 }), 2238 actions: { 2239 'output': function output(buffer) { 2240 if (buffer.o) { 2241 /** @type {ParserOutput} */ 2242 var ret = { 2243 type_: 'tex-math', 2244 p1: buffer.o 2245 }; 2246 2247 for (var p in buffer) { 2248 delete buffer[p]; 2249 } 2250 2251 return ret; 2252 } 2253 } 2254 } 2255 }, 2256 'tex-math tight': { 2257 transitions: mhchemParser.createTransitions({ 2258 'empty': { 2259 '*': { 2260 action_: 'output' 2261 } 2262 }, 2263 '\\ce{(...)}': { 2264 '*': { 2265 action_: ['output', 'ce'] 2266 } 2267 }, 2268 '{...}|\\,|\\x{}{}|\\x{}|\\x': { 2269 '*': { 2270 action_: 'o=' 2271 } 2272 }, 2273 '-|+': { 2274 '*': { 2275 action_: 'tight operator' 2276 } 2277 }, 2278 'else': { 2279 '*': { 2280 action_: 'o=' 2281 } 2282 } 2283 }), 2284 actions: { 2285 'tight operator': function tightOperator(buffer, m) { 2286 buffer.o = (buffer.o || "") + "{" + m + "}"; 2287 }, 2288 'output': function output(buffer) { 2289 if (buffer.o) { 2290 /** @type {ParserOutput} */ 2291 var ret = { 2292 type_: 'tex-math', 2293 p1: buffer.o 2294 }; 2295 2296 for (var p in buffer) { 2297 delete buffer[p]; 2298 } 2299 2300 return ret; 2301 } 2302 } 2303 } 2304 }, 2305 '9,9': { 2306 transitions: mhchemParser.createTransitions({ 2307 'empty': { 2308 '*': {} 2309 }, 2310 ',': { 2311 '*': { 2312 action_: 'comma' 2313 } 2314 }, 2315 'else': { 2316 '*': { 2317 action_: 'copy' 2318 } 2319 } 2320 }), 2321 actions: { 2322 'comma': function comma() { 2323 return { 2324 type_: 'commaDecimal' 2325 }; 2326 } 2327 } 2328 }, 2329 //#endregion 2330 // 2331 // \pu state machines 2332 // 2333 //#region pu 2334 'pu': { 2335 transitions: mhchemParser.createTransitions({ 2336 'empty': { 2337 '*': { 2338 action_: 'output' 2339 } 2340 }, 2341 'space$': { 2342 '*': { 2343 action_: ['output', 'space'] 2344 } 2345 }, 2346 '{[(|)]}': { 2347 '0|a': { 2348 action_: 'copy' 2349 } 2350 }, 2351 '(-)(9)^(-9)': { 2352 '0': { 2353 action_: 'number^', 2354 nextState: 'a' 2355 } 2356 }, 2357 '(-)(9.,9)(e)(99)': { 2358 '0': { 2359 action_: 'enumber', 2360 nextState: 'a' 2361 } 2362 }, 2363 'space': { 2364 '0|a': {} 2365 }, 2366 'pm-operator': { 2367 '0|a': { 2368 action_: { 2369 type_: 'operator', 2370 option: '\\pm' 2371 }, 2372 nextState: '0' 2373 } 2374 }, 2375 'operator': { 2376 '0|a': { 2377 action_: 'copy', 2378 nextState: '0' 2379 } 2380 }, 2381 '//': { 2382 'd': { 2383 action_: 'o=', 2384 nextState: '/' 2385 } 2386 }, 2387 '/': { 2388 'd': { 2389 action_: 'o=', 2390 nextState: '/' 2391 } 2392 }, 2393 '{...}|else': { 2394 '0|d': { 2395 action_: 'd=', 2396 nextState: 'd' 2397 }, 2398 'a': { 2399 action_: ['space', 'd='], 2400 nextState: 'd' 2401 }, 2402 '/|q': { 2403 action_: 'q=', 2404 nextState: 'q' 2405 } 2406 } 2407 }), 2408 actions: { 2409 'enumber': function enumber(buffer, m) { 2410 /** @type {ParserOutput[]} */ 2411 var ret = []; 2412 2413 if (m[0] === "+-" || m[0] === "+/-") { 2414 ret.push("\\pm "); 2415 } else if (m[0]) { 2416 ret.push(m[0]); 2417 } 2418 2419 if (m[1]) { 2420 mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9')); 2421 2422 if (m[2]) { 2423 if (m[2].match(/[,.]/)) { 2424 mhchemParser.concatArray(ret, mhchemParser.go(m[2], 'pu-9,9')); 2425 } else { 2426 ret.push(m[2]); 2427 } 2428 } 2429 2430 m[3] = m[4] || m[3]; 2431 2432 if (m[3]) { 2433 m[3] = m[3].trim(); 2434 2435 if (m[3] === "e" || m[3].substr(0, 1) === "*") { 2436 ret.push({ 2437 type_: 'cdot' 2438 }); 2439 } else { 2440 ret.push({ 2441 type_: 'times' 2442 }); 2443 } 2444 } 2445 } 2446 2447 if (m[3]) { 2448 ret.push("10^{" + m[5] + "}"); 2449 } 2450 2451 return ret; 2452 }, 2453 'number^': function number(buffer, m) { 2454 /** @type {ParserOutput[]} */ 2455 var ret = []; 2456 2457 if (m[0] === "+-" || m[0] === "+/-") { 2458 ret.push("\\pm "); 2459 } else if (m[0]) { 2460 ret.push(m[0]); 2461 } 2462 2463 mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9')); 2464 ret.push("^{" + m[2] + "}"); 2465 return ret; 2466 }, 2467 'operator': function operator(buffer, m, p1) { 2468 return { 2469 type_: 'operator', 2470 kind_: p1 || m 2471 }; 2472 }, 2473 'space': function space() { 2474 return { 2475 type_: 'pu-space-1' 2476 }; 2477 }, 2478 'output': function output(buffer) { 2479 /** @type {ParserOutput | ParserOutput[]} */ 2480 var ret; 2481 var md = mhchemParser.patterns.match_('{(...)}', buffer.d || ""); 2482 2483 if (md && md.remainder === '') { 2484 buffer.d = md.match_; 2485 } 2486 2487 var mq = mhchemParser.patterns.match_('{(...)}', buffer.q || ""); 2488 2489 if (mq && mq.remainder === '') { 2490 buffer.q = mq.match_; 2491 } 2492 2493 if (buffer.d) { 2494 buffer.d = buffer.d.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C"); 2495 buffer.d = buffer.d.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F"); 2496 } 2497 2498 if (buffer.q) { 2499 // fraction 2500 buffer.q = buffer.q.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C"); 2501 buffer.q = buffer.q.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F"); 2502 var b5 = { 2503 d: mhchemParser.go(buffer.d, 'pu'), 2504 q: mhchemParser.go(buffer.q, 'pu') 2505 }; 2506 2507 if (buffer.o === '//') { 2508 ret = { 2509 type_: 'pu-frac', 2510 p1: b5.d, 2511 p2: b5.q 2512 }; 2513 } else { 2514 ret = b5.d; 2515 2516 if (b5.d.length > 1 || b5.q.length > 1) { 2517 ret.push({ 2518 type_: ' / ' 2519 }); 2520 } else { 2521 ret.push({ 2522 type_: '/' 2523 }); 2524 } 2525 2526 mhchemParser.concatArray(ret, b5.q); 2527 } 2528 } else { 2529 // no fraction 2530 ret = mhchemParser.go(buffer.d, 'pu-2'); 2531 } 2532 2533 for (var p in buffer) { 2534 delete buffer[p]; 2535 } 2536 2537 return ret; 2538 } 2539 } 2540 }, 2541 'pu-2': { 2542 transitions: mhchemParser.createTransitions({ 2543 'empty': { 2544 '*': { 2545 action_: 'output' 2546 } 2547 }, 2548 '*': { 2549 '*': { 2550 action_: ['output', 'cdot'], 2551 nextState: '0' 2552 } 2553 }, 2554 '\\x': { 2555 '*': { 2556 action_: 'rm=' 2557 } 2558 }, 2559 'space': { 2560 '*': { 2561 action_: ['output', 'space'], 2562 nextState: '0' 2563 } 2564 }, 2565 '^{(...)}|^(-1)': { 2566 '1': { 2567 action_: '^(-1)' 2568 } 2569 }, 2570 '-9.,9': { 2571 '0': { 2572 action_: 'rm=', 2573 nextState: '0' 2574 }, 2575 '1': { 2576 action_: '^(-1)', 2577 nextState: '0' 2578 } 2579 }, 2580 '{...}|else': { 2581 '*': { 2582 action_: 'rm=', 2583 nextState: '1' 2584 } 2585 } 2586 }), 2587 actions: { 2588 'cdot': function cdot() { 2589 return { 2590 type_: 'tight cdot' 2591 }; 2592 }, 2593 '^(-1)': function _(buffer, m) { 2594 buffer.rm += "^{" + m + "}"; 2595 }, 2596 'space': function space() { 2597 return { 2598 type_: 'pu-space-2' 2599 }; 2600 }, 2601 'output': function output(buffer) { 2602 /** @type {ParserOutput | ParserOutput[]} */ 2603 var ret = []; 2604 2605 if (buffer.rm) { 2606 var mrm = mhchemParser.patterns.match_('{(...)}', buffer.rm || ""); 2607 2608 if (mrm && mrm.remainder === '') { 2609 ret = mhchemParser.go(mrm.match_, 'pu'); 2610 } else { 2611 ret = { 2612 type_: 'rm', 2613 p1: buffer.rm 2614 }; 2615 } 2616 } 2617 2618 for (var p in buffer) { 2619 delete buffer[p]; 2620 } 2621 2622 return ret; 2623 } 2624 } 2625 }, 2626 'pu-9,9': { 2627 transitions: mhchemParser.createTransitions({ 2628 'empty': { 2629 '0': { 2630 action_: 'output-0' 2631 }, 2632 'o': { 2633 action_: 'output-o' 2634 } 2635 }, 2636 ',': { 2637 '0': { 2638 action_: ['output-0', 'comma'], 2639 nextState: 'o' 2640 } 2641 }, 2642 '.': { 2643 '0': { 2644 action_: ['output-0', 'copy'], 2645 nextState: 'o' 2646 } 2647 }, 2648 'else': { 2649 '*': { 2650 action_: 'text=' 2651 } 2652 } 2653 }), 2654 actions: { 2655 'comma': function comma() { 2656 return { 2657 type_: 'commaDecimal' 2658 }; 2659 }, 2660 'output-0': function output0(buffer) { 2661 /** @type {ParserOutput[]} */ 2662 var ret = []; 2663 buffer.text_ = buffer.text_ || ""; 2664 2665 if (buffer.text_.length > 4) { 2666 var a = buffer.text_.length % 3; 2667 2668 if (a === 0) { 2669 a = 3; 2670 } 2671 2672 for (var i = buffer.text_.length - 3; i > 0; i -= 3) { 2673 ret.push(buffer.text_.substr(i, 3)); 2674 ret.push({ 2675 type_: '1000 separator' 2676 }); 2677 } 2678 2679 ret.push(buffer.text_.substr(0, a)); 2680 ret.reverse(); 2681 } else { 2682 ret.push(buffer.text_); 2683 } 2684 2685 for (var p in buffer) { 2686 delete buffer[p]; 2687 } 2688 2689 return ret; 2690 }, 2691 'output-o': function outputO(buffer) { 2692 /** @type {ParserOutput[]} */ 2693 var ret = []; 2694 buffer.text_ = buffer.text_ || ""; 2695 2696 if (buffer.text_.length > 4) { 2697 var a = buffer.text_.length - 3; 2698 2699 for (var i = 0; i < a; i += 3) { 2700 ret.push(buffer.text_.substr(i, 3)); 2701 ret.push({ 2702 type_: '1000 separator' 2703 }); 2704 } 2705 2706 ret.push(buffer.text_.substr(i)); 2707 } else { 2708 ret.push(buffer.text_); 2709 } 2710 2711 for (var p in buffer) { 2712 delete buffer[p]; 2713 } 2714 2715 return ret; 2716 } 2717 } 2718 } //#endregion 2719 2720 }; // 2721 // texify: Take MhchemParser output and convert it to TeX 2722 // 2723 2724 /** @type {Texify} */ 2725 2726 var texify = { 2727 go: function go(input, isInner) { 2728 // (recursive, max 4 levels) 2729 if (!input) { 2730 return ""; 2731 } 2732 2733 var res = ""; 2734 var cee = false; 2735 2736 for (var i = 0; i < input.length; i++) { 2737 var inputi = input[i]; 2738 2739 if (typeof inputi === "string") { 2740 res += inputi; 2741 } else { 2742 res += texify._go2(inputi); 2743 2744 if (inputi.type_ === '1st-level escape') { 2745 cee = true; 2746 } 2747 } 2748 } 2749 2750 if (!isInner && !cee && res) { 2751 res = "{" + res + "}"; 2752 } 2753 2754 return res; 2755 }, 2756 _goInner: function _goInner(input) { 2757 if (!input) { 2758 return input; 2759 } 2760 2761 return texify.go(input, true); 2762 }, 2763 _go2: function _go2(buf) { 2764 /** @type {undefined | string} */ 2765 var res; 2766 2767 switch (buf.type_) { 2768 case 'chemfive': 2769 res = ""; 2770 var b5 = { 2771 a: texify._goInner(buf.a), 2772 b: texify._goInner(buf.b), 2773 p: texify._goInner(buf.p), 2774 o: texify._goInner(buf.o), 2775 q: texify._goInner(buf.q), 2776 d: texify._goInner(buf.d) 2777 }; // 2778 // a 2779 // 2780 2781 if (b5.a) { 2782 if (b5.a.match(/^[+\-]/)) { 2783 b5.a = "{" + b5.a + "}"; 2784 } 2785 2786 res += b5.a + "\\,"; 2787 } // 2788 // b and p 2789 // 2790 2791 2792 if (b5.b || b5.p) { 2793 res += "{\\vphantom{X}}"; 2794 res += "^{\\hphantom{" + (b5.b || "") + "}}_{\\hphantom{" + (b5.p || "") + "}}"; 2795 res += "{\\vphantom{X}}"; 2796 res += "^{\\smash[t]{\\vphantom{2}}\\mathllap{" + (b5.b || "") + "}}"; 2797 res += "_{\\vphantom{2}\\mathllap{\\smash[t]{" + (b5.p || "") + "}}}"; 2798 } // 2799 // o 2800 // 2801 2802 2803 if (b5.o) { 2804 if (b5.o.match(/^[+\-]/)) { 2805 b5.o = "{" + b5.o + "}"; 2806 } 2807 2808 res += b5.o; 2809 } // 2810 // q and d 2811 // 2812 2813 2814 if (buf.dType === 'kv') { 2815 if (b5.d || b5.q) { 2816 res += "{\\vphantom{X}}"; 2817 } 2818 2819 if (b5.d) { 2820 res += "^{" + b5.d + "}"; 2821 } 2822 2823 if (b5.q) { 2824 res += "_{\\smash[t]{" + b5.q + "}}"; 2825 } 2826 } else if (buf.dType === 'oxidation') { 2827 if (b5.d) { 2828 res += "{\\vphantom{X}}"; 2829 res += "^{" + b5.d + "}"; 2830 } 2831 2832 if (b5.q) { 2833 res += "{\\vphantom{X}}"; 2834 res += "_{\\smash[t]{" + b5.q + "}}"; 2835 } 2836 } else { 2837 if (b5.q) { 2838 res += "{\\vphantom{X}}"; 2839 res += "_{\\smash[t]{" + b5.q + "}}"; 2840 } 2841 2842 if (b5.d) { 2843 res += "{\\vphantom{X}}"; 2844 res += "^{" + b5.d + "}"; 2845 } 2846 } 2847 2848 break; 2849 2850 case 'rm': 2851 res = "\\mathrm{" + buf.p1 + "}"; 2852 break; 2853 2854 case 'text': 2855 if (buf.p1.match(/[\^_]/)) { 2856 buf.p1 = buf.p1.replace(" ", "~").replace("-", "\\text{-}"); 2857 res = "\\mathrm{" + buf.p1 + "}"; 2858 } else { 2859 res = "\\text{" + buf.p1 + "}"; 2860 } 2861 2862 break; 2863 2864 case 'roman numeral': 2865 res = "\\mathrm{" + buf.p1 + "}"; 2866 break; 2867 2868 case 'state of aggregation': 2869 res = "\\mskip2mu " + texify._goInner(buf.p1); 2870 break; 2871 2872 case 'state of aggregation subscript': 2873 res = "\\mskip1mu " + texify._goInner(buf.p1); 2874 break; 2875 2876 case 'bond': 2877 res = texify._getBond(buf.kind_); 2878 2879 if (!res) { 2880 throw ["MhchemErrorBond", "mhchem Error. Unknown bond type (" + buf.kind_ + ")"]; 2881 } 2882 2883 break; 2884 2885 case 'frac': 2886 var c = "\\frac{" + buf.p1 + "}{" + buf.p2 + "}"; 2887 res = "\\mathchoice{\\textstyle" + c + "}{" + c + "}{" + c + "}{" + c + "}"; 2888 break; 2889 2890 case 'pu-frac': 2891 var d = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; 2892 res = "\\mathchoice{\\textstyle" + d + "}{" + d + "}{" + d + "}{" + d + "}"; 2893 break; 2894 2895 case 'tex-math': 2896 res = buf.p1 + " "; 2897 break; 2898 2899 case 'frac-ce': 2900 res = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; 2901 break; 2902 2903 case 'overset': 2904 res = "\\overset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; 2905 break; 2906 2907 case 'underset': 2908 res = "\\underset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; 2909 break; 2910 2911 case 'underbrace': 2912 res = "\\underbrace{" + texify._goInner(buf.p1) + "}_{" + texify._goInner(buf.p2) + "}"; 2913 break; 2914 2915 case 'color': 2916 res = "{\\color{" + buf.color1 + "}{" + texify._goInner(buf.color2) + "}}"; 2917 break; 2918 2919 case 'color0': 2920 res = "\\color{" + buf.color + "}"; 2921 break; 2922 2923 case 'arrow': 2924 var b6 = { 2925 rd: texify._goInner(buf.rd), 2926 rq: texify._goInner(buf.rq) 2927 }; 2928 2929 var arrow = "\\x" + texify._getArrow(buf.r); 2930 2931 if (b6.rq) { 2932 arrow += "[{" + b6.rq + "}]"; 2933 } 2934 2935 if (b6.rd) { 2936 arrow += "{" + b6.rd + "}"; 2937 } else { 2938 arrow += "{}"; 2939 } 2940 2941 res = arrow; 2942 break; 2943 2944 case 'operator': 2945 res = texify._getOperator(buf.kind_); 2946 break; 2947 2948 case '1st-level escape': 2949 res = buf.p1 + " "; // &, \\\\, \\hlin 2950 2951 break; 2952 2953 case 'space': 2954 res = " "; 2955 break; 2956 2957 case 'entitySkip': 2958 res = "~"; 2959 break; 2960 2961 case 'pu-space-1': 2962 res = "~"; 2963 break; 2964 2965 case 'pu-space-2': 2966 res = "\\mkern3mu "; 2967 break; 2968 2969 case '1000 separator': 2970 res = "\\mkern2mu "; 2971 break; 2972 2973 case 'commaDecimal': 2974 res = "{,}"; 2975 break; 2976 2977 case 'comma enumeration L': 2978 res = "{" + buf.p1 + "}\\mkern6mu "; 2979 break; 2980 2981 case 'comma enumeration M': 2982 res = "{" + buf.p1 + "}\\mkern3mu "; 2983 break; 2984 2985 case 'comma enumeration S': 2986 res = "{" + buf.p1 + "}\\mkern1mu "; 2987 break; 2988 2989 case 'hyphen': 2990 res = "\\text{-}"; 2991 break; 2992 2993 case 'addition compound': 2994 res = "\\,{\\cdot}\\,"; 2995 break; 2996 2997 case 'electron dot': 2998 res = "\\mkern1mu \\bullet\\mkern1mu "; 2999 break; 3000 3001 case 'KV x': 3002 res = "{\\times}"; 3003 break; 3004 3005 case 'prime': 3006 res = "\\prime "; 3007 break; 3008 3009 case 'cdot': 3010 res = "\\cdot "; 3011 break; 3012 3013 case 'tight cdot': 3014 res = "\\mkern1mu{\\cdot}\\mkern1mu "; 3015 break; 3016 3017 case 'times': 3018 res = "\\times "; 3019 break; 3020 3021 case 'circa': 3022 res = "{\\sim}"; 3023 break; 3024 3025 case '^': 3026 res = "uparrow"; 3027 break; 3028 3029 case 'v': 3030 res = "downarrow"; 3031 break; 3032 3033 case 'ellipsis': 3034 res = "\\ldots "; 3035 break; 3036 3037 case '/': 3038 res = "/"; 3039 break; 3040 3041 case ' / ': 3042 res = "\\,/\\,"; 3043 break; 3044 3045 default: 3046 assertNever(buf); 3047 throw ["MhchemBugT", "mhchem bug T. Please report."]; 3048 // Missing texify rule or unknown MhchemParser output 3049 } 3050 3051 assertString(res); 3052 return res; 3053 }, 3054 _getArrow: function _getArrow(a) { 3055 switch (a) { 3056 case "->": 3057 return "rightarrow"; 3058 3059 case "\u2192": 3060 return "rightarrow"; 3061 3062 case "\u27F6": 3063 return "rightarrow"; 3064 3065 case "<-": 3066 return "leftarrow"; 3067 3068 case "<->": 3069 return "leftrightarrow"; 3070 3071 case "<-->": 3072 return "rightleftarrows"; 3073 3074 case "<=>": 3075 return "rightleftharpoons"; 3076 3077 case "\u21CC": 3078 return "rightleftharpoons"; 3079 3080 case "<=>>": 3081 return "rightequilibrium"; 3082 3083 case "<<=>": 3084 return "leftequilibrium"; 3085 3086 default: 3087 assertNever(a); 3088 throw ["MhchemBugT", "mhchem bug T. Please report."]; 3089 } 3090 }, 3091 _getBond: function _getBond(a) { 3092 switch (a) { 3093 case "-": 3094 return "{-}"; 3095 3096 case "1": 3097 return "{-}"; 3098 3099 case "=": 3100 return "{=}"; 3101 3102 case "2": 3103 return "{=}"; 3104 3105 case "#": 3106 return "{\\equiv}"; 3107 3108 case "3": 3109 return "{\\equiv}"; 3110 3111 case "~": 3112 return "{\\tripledash}"; 3113 3114 case "~-": 3115 return "{\\mathrlap{\\raisebox{-.1em}{$-$}}\\raisebox{.1em}{$\\tripledash$}}"; 3116 3117 case "~=": 3118 return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}"; 3119 3120 case "~--": 3121 return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}"; 3122 3123 case "-~-": 3124 return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$-$}}\\tripledash}"; 3125 3126 case "...": 3127 return "{{\\cdot}{\\cdot}{\\cdot}}"; 3128 3129 case "....": 3130 return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}"; 3131 3132 case "->": 3133 return "{\\rightarrow}"; 3134 3135 case "<-": 3136 return "{\\leftarrow}"; 3137 3138 case "<": 3139 return "{<}"; 3140 3141 case ">": 3142 return "{>}"; 3143 3144 default: 3145 assertNever(a); 3146 throw ["MhchemBugT", "mhchem bug T. Please report."]; 3147 } 3148 }, 3149 _getOperator: function _getOperator(a) { 3150 switch (a) { 3151 case "+": 3152 return " {}+{} "; 3153 3154 case "-": 3155 return " {}-{} "; 3156 3157 case "=": 3158 return " {}={} "; 3159 3160 case "<": 3161 return " {}<{} "; 3162 3163 case ">": 3164 return " {}>{} "; 3165 3166 case "<<": 3167 return " {}\\ll{} "; 3168 3169 case ">>": 3170 return " {}\\gg{} "; 3171 3172 case "\\pm": 3173 return " {}\\pm{} "; 3174 3175 case "\\approx": 3176 return " {}\\approx{} "; 3177 3178 case "$\\approx$": 3179 return " {}\\approx{} "; 3180 3181 case "v": 3182 return " \\downarrow{} "; 3183 3184 case "(v)": 3185 return " \\downarrow{} "; 3186 3187 case "^": 3188 return " \\uparrow{} "; 3189 3190 case "(^)": 3191 return " \\uparrow{} "; 3192 3193 default: 3194 assertNever(a); 3195 throw ["MhchemBugT", "mhchem bug T. Please report."]; 3196 } 3197 } 3198 }; // 3199 // Helpers for code anaylsis 3200 // Will show type error at calling position 3201 // 3202 3203 /** @param {number} a */ 3204 3205 function assertNever(a) {} 3206 /** @param {string} a */ 3207 3208 3209 function assertString(a) {} 3210 }(); 3211 __webpack_exports__ = __webpack_exports__.default; 3212 /******/ return __webpack_exports__; 3213 /******/ })() 3214 ; 3215 });