2021-02-28 15:34:43 -05:00
import katex from '../katex.mjs' ;
/* eslint-disable */
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* KaTeX mhchem . js
*
* This file implements a KaTeX version of mhchem version 3.3 . 0.
* It is adapted from MathJax / extensions / TeX / mhchem . js
* It differs from the MathJax version as follows :
* 1. The interface is changed so that it can be called from KaTeX , not MathJax .
* 2. \ rlap and \ llap are replaced with \ mathrlap and \ mathllap .
* 3. Four lines of code are edited in order to use \ raisebox instead of \ raise .
* 4. The reaction arrow code is simplified . All reaction arrows are rendered
* using KaTeX extensible arrows instead of building non - extensible arrows .
* 5. \ tripledash vertical alignment is slightly adjusted .
*
* This code , as other KaTeX code , is released under the MIT license .
*
* / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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 - 2018 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
// version: "3.3.0" for MathJax and KaTeX
// Add \ce, \pu, and \tripledash to the KaTeX macros.
katex . _ _defineMacro ( "\\ce" , function ( context ) {
return chemParse ( context . consumeArgs ( 1 ) [ 0 ] , "ce" ) ;
} ) ;
katex . _ _defineMacro ( "\\pu" , function ( context ) {
return chemParse ( context . consumeArgs ( 1 ) [ 0 ] , "pu" ) ;
} ) ; // Needed for \bond for the ~ forms
// Raise by 2.56mu, not 2mu. We're raising a hyphen-minus, U+002D, not
// a mathematical minus, U+2212. So we need that extra 0.56.
katex . _ _defineMacro ( "\\tripledash" , "{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu" + "\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}" ) ;
// This is the main function for handing the \ce and \pu commands.
// It takes the argument to \ce or \pu and returns the corresponding TeX string.
//
var chemParse = function chemParse ( tokens , stateMachine ) {
// Recreate the argument string from KaTeX's array of tokens.
var str = "" ;
var expectedLoc = tokens [ tokens . length - 1 ] . loc . start ;
for ( var i = tokens . length - 1 ; i >= 0 ; i -- ) {
if ( tokens [ i ] . loc . start > expectedLoc ) {
// context.consumeArgs has eaten a space.
str += " " ;
expectedLoc = tokens [ i ] . loc . start ;
}
str += tokens [ i ] . text ;
expectedLoc += tokens [ i ] . text . length ;
}
var tex = texify . go ( mhchemParser . go ( str , stateMachine ) ) ;
return tex ;
} ; //
// Core parser for mhchem syntax (recursive)
//
/** @type {MhchemParser} */
var mhchemParser = {
//
// Parses mchem \ce syntax
//
// Call like
// go("H2O");
//
go : function go ( 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 < t . length ; i ++ ) {
var matches = mhchemParser . patterns . match _ ( t [ i ] . pattern , input ) ;
if ( matches ) {
//
// Execute actions
//
var task = t [ i ] . task ;
for ( var iA = 0 ; iA < task . action _ . length ; iA ++ ) {
var o ; //
// Find and execute action
//
if ( machine . actions [ task . action _ [ iA ] . type _ ] ) {
o = machine . actions [ task . action _ [ iA ] . type _ ] ( buffer , matches . match _ , task . action _ [ iA ] . option ) ;
} else if ( mhchemParser . actions [ task . action _ [ iA ] . type _ ] ) {
o = mhchemParser . actions [ task . action _ [ iA ] . type _ ] ( buffer , matches . match _ , task . action _ [ iA ] . option ) ;
} else {
throw [ "MhchemBugA" , "mhchem bug A. Please report. (" + task . action _ [ iA ] . type _ + ")" ] ; // Trying to use non-existing action
} //
// Add output
//
mhchemParser . concatArray ( output , o ) ;
} //
// Set next state,
// Shorten input,
// Continue with next character
// (= apply only one transition per position)
//
state = task . nextState || state ;
if ( input . length > 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 concatArray ( a , b ) {
if ( b ) {
if ( Array . isArray ( b ) ) {
for ( var iB = 0 ; iB < b . length ; iB ++ ) {
a . push ( b [ iB ] ) ;
}
} else {
a . push ( b ) ;
}
}
} ,
patterns : {
//
// Matching patterns
// either regexps or function that return null or {match_:"a", remainder:"bc"}
//
patterns : {
// property names must not look like integers ("2") for correct property traversal order, later on
'empty' : /^$/ ,
'else' : /^./ ,
'else2' : /^./ ,
'space' : /^\s/ ,
'space A' : /^\s(?=[A-Z\\$])/ ,
'space$' : /^\s$/ ,
'a-z' : /^[a-z]/ ,
'x' : /^x/ ,
'x$' : /^x$/ ,
'i$' : /^i$/ ,
'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]))))+/ ,
'\\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]))/ ,
'one lowercase latin letter $' : /^(?:([a-z])(?:$|[^a-zA-Z]))$/ ,
'$one lowercase latin letter$ $' : /^\$(?:([a-z])(?:$|[^a-zA-Z]))\$$/ ,
'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]))$/ ,
'digits' : /^[0-9]+/ ,
'-9.,9' : /^[+\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))/ ,
'-9.,9 no missing 0' : /^[+\-]?[0-9]+(?:[.,][0-9]+)?/ ,
'(-)(9.,9)(e)(99)' : function e99 ( input ) {
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]+\}))?/ ) ;
if ( m && m [ 0 ] ) {
return {
match _ : m . splice ( 1 ) ,
remainder : input . substr ( m [ 0 ] . length )
} ;
}
return null ;
} ,
'(-)(9)^(-9)' : function _ ( input ) {
var m = input . match ( /^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+)?)\^([+\-]?[0-9]+|\{[+\-]?[0-9]+\})/ ) ;
if ( m && m [ 0 ] ) {
return {
match _ : m . splice ( 1 ) ,
remainder : input . substr ( m [ 0 ] . length )
} ;
}
return null ;
} ,
'state of aggregation $' : function stateOfAggregation$ ( input ) {
// ... or crystal system
var a = mhchemParser . patterns . findObserveGroups ( input , "" , /^\([a-z]{1,3}(?=[\),])/ , ")" , "" ) ; // (aq), (aq,$\infty$), (aq, sat)
if ( a && a . remainder . match ( /^($|[\s,;\)\]\}])/ ) ) {
return a ;
} // AND end of 'phrase'
var m = input . match ( /^(?:\((?:\\ca\s?)?\$[amothc]\$\))/ ) ; // OR crystal system ($o$) (\ca$c$)
if ( m ) {
return {
match _ : m [ 0 ] ,
remainder : input . substr ( m [ 0 ] . length )
} ;
}
return null ;
} ,
'_{(state of aggregation)}$' : /^_\{(\([a-z]{1,3}\))\}/ ,
'{[(' : /^(?:\\\{|\[|\()/ ,
')]}' : /^(?:\)|\]|\\\})/ ,
', ' : /^[,;]\s*/ ,
',' : /^[,;]/ ,
'.' : /^[.]/ ,
'. ' : /^([.\u22C5\u00B7\u2022])\s*/ ,
'...' : /^\.\.\.(?=$|[^.])/ ,
'* ' : /^([*])\s*/ ,
'^{(...)}' : function _ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "^{" , "" , "" , "}" ) ;
} ,
'^($...$)' : function $$ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "^" , "$" , "$" , "" ) ;
} ,
'^a' : /^\^([0-9]+|[^\\_])/ ,
'^\\x{}{}' : function x ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "^" , /^\\[a-zA-Z]+\{/ , "}" , "" , "" , "{" , "}" , "" , true ) ;
} ,
'^\\x{}' : function x ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "^" , /^\\[a-zA-Z]+\{/ , "}" , "" ) ;
} ,
'^\\x' : /^\^(\\[a-zA-Z]+)\s*/ ,
'^(-1)' : /^\^(-?\d+)/ ,
'\'' : /^'/ ,
'_{(...)}' : function _ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "_{" , "" , "" , "}" ) ;
} ,
'_($...$)' : function _$$ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "_" , "$" , "$" , "" ) ;
} ,
'_9' : /^_([+\-]?[0-9]+|[^\\])/ ,
'_\\x{}{}' : function _X ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "_" , /^\\[a-zA-Z]+\{/ , "}" , "" , "" , "{" , "}" , "" , true ) ;
} ,
'_\\x{}' : function _X ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "_" , /^\\[a-zA-Z]+\{/ , "}" , "" ) ;
} ,
'_\\x' : /^_(\\[a-zA-Z]+)\s*/ ,
'^_' : /^(?:\^(?=_)|\_(?=\^)|[\^_]$)/ ,
'{}' : /^\{\}/ ,
'{...}' : function _ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "" , "{" , "}" , "" ) ;
} ,
'{(...)}' : function _ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "{" , "" , "" , "}" ) ;
} ,
'$...$' : function $$ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "" , "$" , "$" , "" ) ;
} ,
'${(...)}$' : function $$ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "${" , "" , "" , "}$" ) ;
} ,
'$(...)$' : function $$ ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "$" , "" , "" , "$" ) ;
} ,
'=<>' : /^[=<>]/ ,
'#' : /^[#\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 bond ( 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 x ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "" , /^\\[a-zA-Z]+\{/ , "}" , "" , "" , "{" , "}" , "" , true ) ;
} ,
'\\x{}' : function x ( 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 frac ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\frac{" , "" , "" , "}" , "{" , "" , "" , "}" ) ;
} ,
'\\overset{(...)}' : function overset ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\overset{" , "" , "" , "}" , "{" , "" , "" , "}" ) ;
} ,
'\\underset{(...)}' : function underset ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\underset{" , "" , "" , "}" , "{" , "" , "" , "}" ) ;
} ,
'\\underbrace{(...)}' : function underbrace ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\underbrace{" , "" , "" , "}_" , "{" , "" , "" , "}" ) ;
} ,
'\\color{(...)}0' : function color0 ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\color{" , "" , "" , "}" ) ;
} ,
'\\color{(...)}{(...)}1' : function color1 ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\color{" , "" , "" , "}" , "{" , "" , "" , "}" ) ;
} ,
'\\color(...){(...)}2' : function color2 ( input ) {
return mhchemParser . patterns . findObserveGroups ( input , "\\color" , "\\" , "" , /^(?=\{)/ , "{" , "" , "" , "}" ) ;
} ,
'\\ce{(...)}' : function ce ( 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 amount ( 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 amount2 ( input ) {
return this [ 'amount' ] ( input ) ;
} ,
'(KV letters),' : /^(?:[A-Z][a-z]{0,2}|i)(?=,)/ ,
'formula$' : function formula$ ( 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 findObserveGroups ( input , begExcl , begIncl , endIncl , endExcl , beg2Excl , beg2Incl , end2Incl , end2Excl , combine ) {
/** @type {{(input: string, pattern: string | RegExp): string | string[] | null;}} */
var _match = function _match ( 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 _findObserveGroups ( 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 match _ ( 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 a ( buffer , m ) {
buffer . a = ( buffer . a || "" ) + m ;
} ,
'b=' : function b ( buffer , m ) {
buffer . b = ( buffer . b || "" ) + m ;
} ,
'p=' : function p ( buffer , m ) {
buffer . p = ( buffer . p || "" ) + m ;
} ,
'o=' : function o ( buffer , m ) {
buffer . o = ( buffer . o || "" ) + m ;
} ,
'q=' : function q ( buffer , m ) {
buffer . q = ( buffer . q || "" ) + m ;
} ,
'd=' : function d ( buffer , m ) {
buffer . d = ( buffer . d || "" ) + m ;
} ,
'rm=' : function rm ( buffer , m ) {
buffer . rm = ( buffer . rm || "" ) + m ;
} ,
'text=' : function text ( buffer , m ) {
buffer . text _ = ( buffer . text _ || "" ) + m ;
} ,
'insert' : function insert ( buffer , m , a ) {
return {
type _ : a
} ;
} ,
'insert+p1' : function insertP1 ( buffer , m , a ) {
return {
type _ : a ,
p1 : m
} ;
} ,
'insert+p1+p2' : function insertP1P2 ( buffer , m , a ) {
return {
type _ : a ,
p1 : m [ 0 ] ,
p2 : m [ 1 ]
} ;
} ,
'copy' : function copy ( buffer , m ) {
return m ;
} ,
'rm' : function rm ( buffer , m ) {
return {
type _ : 'rm' ,
p1 : m || ""
} ;
} ,
'text' : function text ( buffer , m ) {
return mhchemParser . go ( m , 'text' ) ;
} ,
'{text}' : function text ( buffer , m ) {
var ret = [ "{" ] ;
mhchemParser . concatArray ( ret , mhchemParser . go ( m , 'text' ) ) ;
ret . push ( "}" ) ;
return ret ;
} ,
'tex-math' : function texMath ( buffer , m ) {
return mhchemParser . go ( m , 'tex-math' ) ;
} ,
'tex-math tight' : function texMathTight ( buffer , m ) {
return mhchemParser . go ( m , 'tex-math tight' ) ;
} ,
'bond' : function bond ( buffer , m , k ) {
return {
type _ : 'bond' ,
kind _ : k || m
} ;
} ,
'color0-output' : function color0Output ( buffer , m ) {
return {
type _ : 'color0' ,
color : m [ 0 ]
} ;
} ,
'ce' : function ce ( 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 createTransitions ( 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 < stateArray . length ; i ++ ) {
transitions [ stateArray [ i ] ] = [ ] ;
}
}
} //
// 2. Fill states
//
for ( pattern in o ) {
for ( state in o [ pattern ] ) {
stateArray = o [ pattern ] [ state ] . stateArray || [ ] ;
for ( i = 0 ; i < stateArray . length ; i ++ ) {
//
// 2a. Normalize actions into array: 'text=' ==> [{type_:'text='}]
// (Note to myself: Resolving the function here would be problematic. It would need .bind (for *this*) and currying (for *option*).)
//
/** @type {any} */
var p = o [ pattern ] [ state ] ;
if ( p . action _ ) {
p . action _ = [ ] . concat ( p . action _ ) ;
for ( var k = 0 ; k < p . action _ . length ; k ++ ) {
if ( typeof p . action _ [ k ] === "string" ) {
p . action _ [ k ] = {
type _ : p . action _ [ k ]
} ;
}
}
} else {
p . action _ = [ ] ;
} //
// 2.b Multi-insert
//
var patternArray = pattern . split ( "|" ) ;
for ( var j = 0 ; j < patternArray . length ; j ++ ) {
if ( stateArray [ i ] === '*' ) {
// insert into all
for ( var t in transitions ) {
transitions [ t ] . push ( {
pattern : patternArray [ j ] ,
task : p
} ) ;
}
} else {
transitions [ stateArray [ i ] ] . push ( {
pattern : patternArray [ j ] ,
task : p
} ) ;
}
}
}
}
}
return transitions ;
} ,
stateMachines : { }
} ; //
// Definition of state machines
//
mhchemParser . stateMachines = {
//
// \ce state machines
//
//#region ce
'ce' : {
// main parser
transitions : mhchemParser . createTransitions ( {
'empty' : {
'*' : {
action _ : 'output'
}
} ,
'else' : {
'0|1|2' : {
action _ : 'beginsWithBond=false' ,
revisit : true ,
toContinue : true
}
} ,
'oxidation$' : {
'0' : {
action _ : 'oxidation-output'
}
} ,
'CMT' : {
'r' : {
action _ : 'rdt=' ,
nextState : 'rt'
} ,
'rd' : {
action _ : 'rqt=' ,
nextState : 'rdt'
}
} ,
'arrowUpDown' : {
'0|1|2|as' : {
action _ : [ 'sb=false' , 'output' , 'operator' ] ,
nextState : '1'
}
} ,
'uprightEntities' : {
'0|1|2' : {
action _ : [ 'o=' , 'output' ] ,
nextState : '1'
}
} ,
'orbital' : {
'0|1|2|3' : {
action _ : 'o=' ,
nextState : 'o'
}
} ,
'->' : {
'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 oAfterD ( 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 dKv ( buffer , m ) {
buffer . d = m ;
buffer . dType = 'kv' ;
} ,
'charge or bond' : function chargeOrBond ( 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 afterOD ( 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 aToO ( buffer ) {
buffer . o = buffer . a ;
buffer . a = undefined ;
} ,
'sb=true' : function sbTrue ( buffer ) {
buffer . sb = true ;
} ,
'sb=false' : function sbFalse ( buffer ) {
buffer . sb = false ;
} ,
'beginsWithBond=true' : function beginsWithBondTrue ( buffer ) {
buffer [ 'beginsWithBond' ] = true ;
} ,
'beginsWithBond=false' : function beginsWithBondFalse ( buffer ) {
buffer [ 'beginsWithBond' ] = false ;
} ,
'parenthesisLevel++' : function parenthesisLevel ( buffer ) {
buffer [ 'parenthesisLevel' ] ++ ;
} ,
'parenthesisLevel--' : function parenthesisLevel ( buffer ) {
buffer [ 'parenthesisLevel' ] -- ;
} ,
'state of aggregation' : function stateOfAggregation ( buffer , m ) {
return {
type _ : 'state of aggregation' ,
p1 : mhchemParser . go ( m , 'o' )
} ;
} ,
'comma' : function comma ( 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 output ( 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 ) ; 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 oxidationOutput ( buffer , m ) {
var ret = [ "{" ] ;
mhchemParser . concatArray ( ret , mhchemParser . go ( m , 'oxidation' ) ) ;
ret . push ( "}" ) ;
return ret ;
} ,
'frac-output' : function fracOutput ( buffer , m ) {
return {
type _ : 'frac-ce' ,
p1 : mhchemParser . go ( m [ 0 ] ) ,
p2 : mhchemParser . go ( m [ 1 ] )
} ;
} ,
'overset-output' : function oversetOutput ( buffer , m ) {
return {
type _ : 'overset' ,
p1 : mhchemParser . go ( m [ 0 ] ) ,
p2 : mhchemParser . go ( m [ 1 ] )
} ;
} ,
'underset-output' : function undersetOutput ( buffer , m ) {
return {
type _ : 'underset' ,
p1 : mhchemParser . go ( m [ 0 ] ) ,
p2 : mhchemParser . go ( m [ 1 ] )
} ;
} ,
'underbrace-output' : function underbraceOutput ( buffer , m ) {
return {
type _ : 'underbrace' ,
p1 : mhchemParser . go ( m [ 0 ] ) ,
p2 : mhchemParser . go ( m [ 1 ] )
} ;
} ,
'color-output' : function colorOutput ( buffer , m ) {
return {
type _ : 'color' ,
color1 : m [ 0 ] ,
color2 : mhchemParser . go ( m [ 1 ] )
} ;
} ,
'r=' : function r ( buffer , m ) {
buffer . r = m ;
} ,
'rdt=' : function rdt ( buffer , m ) {
buffer . rdt = m ;
} ,
'rd=' : function rd ( buffer , m ) {
buffer . rd = m ;
} ,
'rqt=' : function rqt ( buffer , m ) {
buffer . rqt = m ;
} ,
'rq=' : function rq ( buffer , m ) {
buffer . rq = m ;
} ,
'operator' : function operator ( 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 output ( 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 stateOfAggregation ( buffer , m ) {
return {
type _ : 'state of aggregation subscript' ,
p1 : mhchemParser . go ( m , 'o' )
} ;
} ,
'color-output' : function colorOutput ( 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 colorOutput ( 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 romanNumeral ( 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 output ( 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 tightOperator ( buffer , m ) {
buffer . o = ( buffer . o || "" ) + "{" + m + "}" ;
} ,
'output' : function output ( 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 comma ( ) {
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 enumber ( 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 ] ) {
mhchemParser . concatArray ( ret , mhchemParser . go ( m [ 1 ] , 'pu-9,9' ) ) ;
if ( m [ 2 ] ) {
if ( m [ 2 ] . match ( /[,.]/ ) ) {
mhchemParser . concatArray ( ret , mhchemParser . go ( m [ 2 ] , 'pu-9,9' ) ) ;
} else {
ret . push ( m [ 2 ] ) ;
}
}
m [ 3 ] = m [ 4 ] || m [ 3 ] ;
if ( m [ 3 ] ) {
m [ 3 ] = m [ 3 ] . trim ( ) ;
if ( m [ 3 ] === "e" || m [ 3 ] . substr ( 0 , 1 ) === "*" ) {
ret . push ( {
type _ : 'cdot'
} ) ;
} else {
ret . push ( {
type _ : 'times'
} ) ;
}
}
}
if ( m [ 3 ] ) {
ret . push ( "10^{" + m [ 5 ] + "}" ) ;
}
return ret ;
} ,
'number^' : function number ( 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 operator ( buffer , m , p1 ) {
return {
type _ : 'operator' ,
kind _ : p1 || m
} ;
} ,
'space' : function space ( ) {
return {
type _ : 'pu-space-1'
} ;
} ,
'output' : function output ( 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 cdot ( ) {
return {
type _ : 'tight cdot'
} ;
} ,
'^(-1)' : function _ ( buffer , m ) {
buffer . rm += "^{" + m + "}" ;
} ,
'space' : function space ( ) {
return {
type _ : 'pu-space-2'
} ;
} ,
'output' : function output ( 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 comma ( ) {
return {
type _ : 'commaDecimal'
} ;
} ,
'output-0' : function output0 ( 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 outputO ( 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 < a ; i += 3 ) {
ret . push ( buffer . text _ . substr ( i , 3 ) ) ;
ret . push ( {
type _ : '1000 separator'
} ) ;
}
ret . push ( buffer . text _ . substr ( i ) ) ;
} else {
ret . push ( buffer . text _ ) ;
}
for ( var p in buffer ) {
delete buffer [ p ] ;
}
return ret ;
}
2021-03-11 15:55:04 -05:00
}
} //#endregion
2021-02-28 15:34:43 -05:00
} ; //
// texify: Take MhchemParser output and convert it to TeX
//
/** @type {Texify} */
var texify = {
go : function go ( input , isInner ) {
// (recursive, max 4 levels)
if ( ! input ) {
return "" ;
}
var res = "" ;
var cee = false ;
for ( var i = 0 ; i < input . length ; i ++ ) {
var inputi = input [ i ] ;
if ( typeof inputi === "string" ) {
res += inputi ;
} else {
res += texify . _go2 ( inputi ) ;
if ( inputi . type _ === '1st-level escape' ) {
cee = true ;
}
}
}
if ( ! isInner && ! cee && res ) {
res = "{" + res + "}" ;
}
return res ;
} ,
_goInner : function _goInner ( input ) {
if ( ! input ) {
return input ;
}
return texify . go ( input , true ) ;
} ,
_go2 : function _go2 ( buf ) {
/** @type {undefined | string} */
var res ;
switch ( buf . type _ ) {
case 'chemfive' :
res = "" ;
var b5 = {
a : texify . _goInner ( buf . a ) ,
b : texify . _goInner ( buf . b ) ,
p : texify . _goInner ( buf . p ) ,
o : texify . _goInner ( buf . o ) ,
q : texify . _goInner ( buf . q ) ,
d : texify . _goInner ( buf . d )
} ; //
// a
//
if ( b5 . a ) {
if ( b5 . a . match ( /^[+\-]/ ) ) {
b5 . a = "{" + b5 . a + "}" ;
}
res += b5 . a + "\\," ;
} //
// b and p
//
if ( b5 . b || b5 . p ) {
res += "{\\vphantom{X}}" ;
res += "^{\\hphantom{" + ( b5 . b || "" ) + "}}_{\\hphantom{" + ( b5 . p || "" ) + "}}" ;
res += "{\\vphantom{X}}" ;
res += "^{\\smash[t]{\\vphantom{2}}\\mathllap{" + ( b5 . b || "" ) + "}}" ;
res += "_{\\vphantom{2}\\mathllap{\\smash[t]{" + ( b5 . p || "" ) + "}}}" ;
} //
// o
//
if ( b5 . o ) {
if ( b5 . o . match ( /^[+\-]/ ) ) {
b5 . o = "{" + b5 . o + "}" ;
}
res += b5 . o ;
} //
// q and d
//
if ( buf . dType === 'kv' ) {
if ( b5 . d || b5 . q ) {
res += "{\\vphantom{X}}" ;
}
if ( b5 . d ) {
res += "^{" + b5 . d + "}" ;
}
if ( b5 . q ) {
res += "_{\\smash[t]{" + b5 . q + "}}" ;
}
} else if ( buf . dType === 'oxidation' ) {
if ( b5 . d ) {
res += "{\\vphantom{X}}" ;
res += "^{" + b5 . d + "}" ;
}
if ( b5 . q ) {
res += "{\\vphantom{X}}" ;
res += "_{\\smash[t]{" + b5 . q + "}}" ;
}
} else {
if ( b5 . q ) {
res += "{\\vphantom{X}}" ;
res += "_{\\smash[t]{" + b5 . q + "}}" ;
}
if ( b5 . d ) {
res += "{\\vphantom{X}}" ;
res += "^{" + b5 . d + "}" ;
}
}
break ;
case 'rm' :
res = "\\mathrm{" + buf . p1 + "}" ;
break ;
case 'text' :
if ( buf . p1 . match ( /[\^_]/ ) ) {
buf . p1 = buf . p1 . replace ( " " , "~" ) . replace ( "-" , "\\text{-}" ) ;
res = "\\mathrm{" + buf . p1 + "}" ;
} else {
res = "\\text{" + buf . p1 + "}" ;
}
break ;
case 'roman numeral' :
res = "\\mathrm{" + buf . p1 + "}" ;
break ;
case 'state of aggregation' :
res = "\\mskip2mu " + texify . _goInner ( buf . p1 ) ;
break ;
case 'state of aggregation subscript' :
res = "\\mskip1mu " + texify . _goInner ( buf . p1 ) ;
break ;
case 'bond' :
res = texify . _getBond ( buf . kind _ ) ;
if ( ! res ) {
throw [ "MhchemErrorBond" , "mhchem Error. Unknown bond type (" + buf . kind _ + ")" ] ;
}
break ;
case 'frac' :
var c = "\\frac{" + buf . p1 + "}{" + buf . p2 + "}" ;
res = "\\mathchoice{\\textstyle" + c + "}{" + c + "}{" + c + "}{" + c + "}" ;
break ;
case 'pu-frac' :
var d = "\\frac{" + texify . _goInner ( buf . p1 ) + "}{" + texify . _goInner ( buf . p2 ) + "}" ;
res = "\\mathchoice{\\textstyle" + d + "}{" + d + "}{" + d + "}{" + d + "}" ;
break ;
case 'tex-math' :
res = buf . p1 + " " ;
break ;
case 'frac-ce' :
res = "\\frac{" + texify . _goInner ( buf . p1 ) + "}{" + texify . _goInner ( buf . p2 ) + "}" ;
break ;
case 'overset' :
res = "\\overset{" + texify . _goInner ( buf . p1 ) + "}{" + texify . _goInner ( buf . p2 ) + "}" ;
break ;
case 'underset' :
res = "\\underset{" + texify . _goInner ( buf . p1 ) + "}{" + texify . _goInner ( buf . p2 ) + "}" ;
break ;
case 'underbrace' :
res = "\\underbrace{" + texify . _goInner ( buf . p1 ) + "}_{" + texify . _goInner ( buf . p2 ) + "}" ;
break ;
case 'color' :
res = "{\\color{" + buf . color1 + "}{" + texify . _goInner ( buf . color2 ) + "}}" ;
break ;
case 'color0' :
res = "\\color{" + buf . color + "}" ;
break ;
case 'arrow' :
var b6 = {
rd : texify . _goInner ( buf . rd ) ,
rq : texify . _goInner ( buf . rq )
} ;
var arrow = "\\x" + texify . _getArrow ( buf . r ) ;
if ( b6 . rq ) {
arrow += "[{" + b6 . rq + "}]" ;
}
if ( b6 . rd ) {
arrow += "{" + b6 . rd + "}" ;
} else {
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 :
throw [ "MhchemBugT" , "mhchem bug T. Please report." ] ;
// Missing texify rule or unknown MhchemParser output
}
return res ;
} ,
_getArrow : function _getArrow ( a ) {
switch ( a ) {
case "->" :
return "rightarrow" ;
case "\u2192" :
return "rightarrow" ;
case "\u27F6" :
return "rightarrow" ;
case "<-" :
return "leftarrow" ;
case "<->" :
return "leftrightarrow" ;
case "<-->" :
return "rightleftarrows" ;
case "<=>" :
return "rightleftharpoons" ;
case "\u21CC" :
return "rightleftharpoons" ;
case "<=>>" :
return "rightequilibrium" ;
case "<<=>" :
return "leftequilibrium" ;
default :
throw [ "MhchemBugT" , "mhchem bug T. Please report." ] ;
}
} ,
_getBond : function _getBond ( 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 "{\\mathrlap{\\raisebox{-.1em}{$-$}}\\raisebox{.1em}{$\\tripledash$}}" ;
case "~=" :
return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}" ;
case "~--" :
return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}" ;
case "-~-" :
return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$-$}}\\tripledash}" ;
case "..." :
return "{{\\cdot}{\\cdot}{\\cdot}}" ;
case "...." :
return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}" ;
case "->" :
return "{\\rightarrow}" ;
case "<-" :
return "{\\leftarrow}" ;
case "<" :
return "{<}" ;
case ">" :
return "{>}" ;
default :
throw [ "MhchemBugT" , "mhchem bug T. Please report." ] ;
}
} ,
_getOperator : function _getOperator ( 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 :
throw [ "MhchemBugT" , "mhchem bug T. Please report." ] ;
}
}
} ; //