latex.js (11163B)
1 /* eslint no-template-curly-in-string: "off" */ 2 import escapeLatexLib from 'escape-latex'; 3 import { hasOwnProperty } from './object.js'; 4 export var latexSymbols = { 5 // GREEK LETTERS 6 Alpha: 'A', 7 alpha: '\\alpha', 8 Beta: 'B', 9 beta: '\\beta', 10 Gamma: '\\Gamma', 11 gamma: '\\gamma', 12 Delta: '\\Delta', 13 delta: '\\delta', 14 Epsilon: 'E', 15 epsilon: '\\epsilon', 16 varepsilon: '\\varepsilon', 17 Zeta: 'Z', 18 zeta: '\\zeta', 19 Eta: 'H', 20 eta: '\\eta', 21 Theta: '\\Theta', 22 theta: '\\theta', 23 vartheta: '\\vartheta', 24 Iota: 'I', 25 iota: '\\iota', 26 Kappa: 'K', 27 kappa: '\\kappa', 28 varkappa: '\\varkappa', 29 Lambda: '\\Lambda', 30 lambda: '\\lambda', 31 Mu: 'M', 32 mu: '\\mu', 33 Nu: 'N', 34 nu: '\\nu', 35 Xi: '\\Xi', 36 xi: '\\xi', 37 Omicron: 'O', 38 omicron: 'o', 39 Pi: '\\Pi', 40 pi: '\\pi', 41 varpi: '\\varpi', 42 Rho: 'P', 43 rho: '\\rho', 44 varrho: '\\varrho', 45 Sigma: '\\Sigma', 46 sigma: '\\sigma', 47 varsigma: '\\varsigma', 48 Tau: 'T', 49 tau: '\\tau', 50 Upsilon: '\\Upsilon', 51 upsilon: '\\upsilon', 52 Phi: '\\Phi', 53 phi: '\\phi', 54 varphi: '\\varphi', 55 Chi: 'X', 56 chi: '\\chi', 57 Psi: '\\Psi', 58 psi: '\\psi', 59 Omega: '\\Omega', 60 omega: '\\omega', 61 // logic 62 true: '\\mathrm{True}', 63 false: '\\mathrm{False}', 64 // other 65 i: 'i', 66 // TODO use \i ?? 67 inf: '\\infty', 68 Inf: '\\infty', 69 infinity: '\\infty', 70 Infinity: '\\infty', 71 oo: '\\infty', 72 lim: '\\lim', 73 undefined: '\\mathbf{?}' 74 }; 75 export var latexOperators = { 76 transpose: '^\\top', 77 ctranspose: '^H', 78 factorial: '!', 79 pow: '^', 80 dotPow: '.^\\wedge', 81 // TODO find ideal solution 82 unaryPlus: '+', 83 unaryMinus: '-', 84 bitNot: '\\~', 85 // TODO find ideal solution 86 not: '\\neg', 87 multiply: '\\cdot', 88 divide: '\\frac', 89 // TODO how to handle that properly? 90 dotMultiply: '.\\cdot', 91 // TODO find ideal solution 92 dotDivide: '.:', 93 // TODO find ideal solution 94 mod: '\\mod', 95 add: '+', 96 subtract: '-', 97 to: '\\rightarrow', 98 leftShift: '<<', 99 rightArithShift: '>>', 100 rightLogShift: '>>>', 101 equal: '=', 102 unequal: '\\neq', 103 smaller: '<', 104 larger: '>', 105 smallerEq: '\\leq', 106 largerEq: '\\geq', 107 bitAnd: '\\&', 108 bitXor: '\\underline{|}', 109 bitOr: '|', 110 and: '\\wedge', 111 xor: '\\veebar', 112 or: '\\vee' 113 }; 114 export var latexFunctions = { 115 // arithmetic 116 abs: { 117 1: '\\left|${args[0]}\\right|' 118 }, 119 add: { 120 2: "\\left(${args[0]}".concat(latexOperators.add, "${args[1]}\\right)") 121 }, 122 cbrt: { 123 1: '\\sqrt[3]{${args[0]}}' 124 }, 125 ceil: { 126 1: '\\left\\lceil${args[0]}\\right\\rceil' 127 }, 128 cube: { 129 1: '\\left(${args[0]}\\right)^3' 130 }, 131 divide: { 132 2: '\\frac{${args[0]}}{${args[1]}}' 133 }, 134 dotDivide: { 135 2: "\\left(${args[0]}".concat(latexOperators.dotDivide, "${args[1]}\\right)") 136 }, 137 dotMultiply: { 138 2: "\\left(${args[0]}".concat(latexOperators.dotMultiply, "${args[1]}\\right)") 139 }, 140 dotPow: { 141 2: "\\left(${args[0]}".concat(latexOperators.dotPow, "${args[1]}\\right)") 142 }, 143 exp: { 144 1: '\\exp\\left(${args[0]}\\right)' 145 }, 146 expm1: "\\left(e".concat(latexOperators.pow, "{${args[0]}}-1\\right)"), 147 fix: { 148 1: '\\mathrm{${name}}\\left(${args[0]}\\right)' 149 }, 150 floor: { 151 1: '\\left\\lfloor${args[0]}\\right\\rfloor' 152 }, 153 gcd: '\\gcd\\left(${args}\\right)', 154 hypot: '\\hypot\\left(${args}\\right)', 155 log: { 156 1: '\\ln\\left(${args[0]}\\right)', 157 2: '\\log_{${args[1]}}\\left(${args[0]}\\right)' 158 }, 159 log10: { 160 1: '\\log_{10}\\left(${args[0]}\\right)' 161 }, 162 log1p: { 163 1: '\\ln\\left(${args[0]}+1\\right)', 164 2: '\\log_{${args[1]}}\\left(${args[0]}+1\\right)' 165 }, 166 log2: '\\log_{2}\\left(${args[0]}\\right)', 167 mod: { 168 2: "\\left(${args[0]}".concat(latexOperators.mod, "${args[1]}\\right)") 169 }, 170 multiply: { 171 2: "\\left(${args[0]}".concat(latexOperators.multiply, "${args[1]}\\right)") 172 }, 173 norm: { 174 1: '\\left\\|${args[0]}\\right\\|', 175 2: undefined // use default template 176 177 }, 178 nthRoot: { 179 2: '\\sqrt[${args[1]}]{${args[0]}}' 180 }, 181 nthRoots: { 182 2: '\\{y : $y^{args[1]} = {${args[0]}}\\}' 183 }, 184 pow: { 185 2: "\\left(${args[0]}\\right)".concat(latexOperators.pow, "{${args[1]}}") 186 }, 187 round: { 188 1: '\\left\\lfloor${args[0]}\\right\\rceil', 189 2: undefined // use default template 190 191 }, 192 sign: { 193 1: '\\mathrm{${name}}\\left(${args[0]}\\right)' 194 }, 195 sqrt: { 196 1: '\\sqrt{${args[0]}}' 197 }, 198 square: { 199 1: '\\left(${args[0]}\\right)^2' 200 }, 201 subtract: { 202 2: "\\left(${args[0]}".concat(latexOperators.subtract, "${args[1]}\\right)") 203 }, 204 unaryMinus: { 205 1: "".concat(latexOperators.unaryMinus, "\\left(${args[0]}\\right)") 206 }, 207 unaryPlus: { 208 1: "".concat(latexOperators.unaryPlus, "\\left(${args[0]}\\right)") 209 }, 210 // bitwise 211 bitAnd: { 212 2: "\\left(${args[0]}".concat(latexOperators.bitAnd, "${args[1]}\\right)") 213 }, 214 bitNot: { 215 1: latexOperators.bitNot + '\\left(${args[0]}\\right)' 216 }, 217 bitOr: { 218 2: "\\left(${args[0]}".concat(latexOperators.bitOr, "${args[1]}\\right)") 219 }, 220 bitXor: { 221 2: "\\left(${args[0]}".concat(latexOperators.bitXor, "${args[1]}\\right)") 222 }, 223 leftShift: { 224 2: "\\left(${args[0]}".concat(latexOperators.leftShift, "${args[1]}\\right)") 225 }, 226 rightArithShift: { 227 2: "\\left(${args[0]}".concat(latexOperators.rightArithShift, "${args[1]}\\right)") 228 }, 229 rightLogShift: { 230 2: "\\left(${args[0]}".concat(latexOperators.rightLogShift, "${args[1]}\\right)") 231 }, 232 // combinatorics 233 bellNumbers: { 234 1: '\\mathrm{B}_{${args[0]}}' 235 }, 236 catalan: { 237 1: '\\mathrm{C}_{${args[0]}}' 238 }, 239 stirlingS2: { 240 2: '\\mathrm{S}\\left(${args}\\right)' 241 }, 242 // complex 243 arg: { 244 1: '\\arg\\left(${args[0]}\\right)' 245 }, 246 conj: { 247 1: '\\left(${args[0]}\\right)^*' 248 }, 249 im: { 250 1: '\\Im\\left\\lbrace${args[0]}\\right\\rbrace' 251 }, 252 re: { 253 1: '\\Re\\left\\lbrace${args[0]}\\right\\rbrace' 254 }, 255 // logical 256 and: { 257 2: "\\left(${args[0]}".concat(latexOperators.and, "${args[1]}\\right)") 258 }, 259 not: { 260 1: latexOperators.not + '\\left(${args[0]}\\right)' 261 }, 262 or: { 263 2: "\\left(${args[0]}".concat(latexOperators.or, "${args[1]}\\right)") 264 }, 265 xor: { 266 2: "\\left(${args[0]}".concat(latexOperators.xor, "${args[1]}\\right)") 267 }, 268 // matrix 269 cross: { 270 2: '\\left(${args[0]}\\right)\\times\\left(${args[1]}\\right)' 271 }, 272 ctranspose: { 273 1: "\\left(${args[0]}\\right)".concat(latexOperators.ctranspose) 274 }, 275 det: { 276 1: '\\det\\left(${args[0]}\\right)' 277 }, 278 dot: { 279 2: '\\left(${args[0]}\\cdot${args[1]}\\right)' 280 }, 281 expm: { 282 1: '\\exp\\left(${args[0]}\\right)' 283 }, 284 inv: { 285 1: '\\left(${args[0]}\\right)^{-1}' 286 }, 287 sqrtm: { 288 1: "{${args[0]}}".concat(latexOperators.pow, "{\\frac{1}{2}}") 289 }, 290 trace: { 291 1: '\\mathrm{tr}\\left(${args[0]}\\right)' 292 }, 293 transpose: { 294 1: "\\left(${args[0]}\\right)".concat(latexOperators.transpose) 295 }, 296 // probability 297 combinations: { 298 2: '\\binom{${args[0]}}{${args[1]}}' 299 }, 300 combinationsWithRep: { 301 2: '\\left(\\!\\!{\\binom{${args[0]}}{${args[1]}}}\\!\\!\\right)' 302 }, 303 factorial: { 304 1: "\\left(${args[0]}\\right)".concat(latexOperators.factorial) 305 }, 306 gamma: { 307 1: '\\Gamma\\left(${args[0]}\\right)' 308 }, 309 // relational 310 equal: { 311 2: "\\left(${args[0]}".concat(latexOperators.equal, "${args[1]}\\right)") 312 }, 313 larger: { 314 2: "\\left(${args[0]}".concat(latexOperators.larger, "${args[1]}\\right)") 315 }, 316 largerEq: { 317 2: "\\left(${args[0]}".concat(latexOperators.largerEq, "${args[1]}\\right)") 318 }, 319 smaller: { 320 2: "\\left(${args[0]}".concat(latexOperators.smaller, "${args[1]}\\right)") 321 }, 322 smallerEq: { 323 2: "\\left(${args[0]}".concat(latexOperators.smallerEq, "${args[1]}\\right)") 324 }, 325 unequal: { 326 2: "\\left(${args[0]}".concat(latexOperators.unequal, "${args[1]}\\right)") 327 }, 328 // special 329 erf: { 330 1: 'erf\\left(${args[0]}\\right)' 331 }, 332 // statistics 333 max: '\\max\\left(${args}\\right)', 334 min: '\\min\\left(${args}\\right)', 335 variance: '\\mathrm{Var}\\left(${args}\\right)', 336 // trigonometry 337 acos: { 338 1: '\\cos^{-1}\\left(${args[0]}\\right)' 339 }, 340 acosh: { 341 1: '\\cosh^{-1}\\left(${args[0]}\\right)' 342 }, 343 acot: { 344 1: '\\cot^{-1}\\left(${args[0]}\\right)' 345 }, 346 acoth: { 347 1: '\\coth^{-1}\\left(${args[0]}\\right)' 348 }, 349 acsc: { 350 1: '\\csc^{-1}\\left(${args[0]}\\right)' 351 }, 352 acsch: { 353 1: '\\mathrm{csch}^{-1}\\left(${args[0]}\\right)' 354 }, 355 asec: { 356 1: '\\sec^{-1}\\left(${args[0]}\\right)' 357 }, 358 asech: { 359 1: '\\mathrm{sech}^{-1}\\left(${args[0]}\\right)' 360 }, 361 asin: { 362 1: '\\sin^{-1}\\left(${args[0]}\\right)' 363 }, 364 asinh: { 365 1: '\\sinh^{-1}\\left(${args[0]}\\right)' 366 }, 367 atan: { 368 1: '\\tan^{-1}\\left(${args[0]}\\right)' 369 }, 370 atan2: { 371 2: '\\mathrm{atan2}\\left(${args}\\right)' 372 }, 373 atanh: { 374 1: '\\tanh^{-1}\\left(${args[0]}\\right)' 375 }, 376 cos: { 377 1: '\\cos\\left(${args[0]}\\right)' 378 }, 379 cosh: { 380 1: '\\cosh\\left(${args[0]}\\right)' 381 }, 382 cot: { 383 1: '\\cot\\left(${args[0]}\\right)' 384 }, 385 coth: { 386 1: '\\coth\\left(${args[0]}\\right)' 387 }, 388 csc: { 389 1: '\\csc\\left(${args[0]}\\right)' 390 }, 391 csch: { 392 1: '\\mathrm{csch}\\left(${args[0]}\\right)' 393 }, 394 sec: { 395 1: '\\sec\\left(${args[0]}\\right)' 396 }, 397 sech: { 398 1: '\\mathrm{sech}\\left(${args[0]}\\right)' 399 }, 400 sin: { 401 1: '\\sin\\left(${args[0]}\\right)' 402 }, 403 sinh: { 404 1: '\\sinh\\left(${args[0]}\\right)' 405 }, 406 tan: { 407 1: '\\tan\\left(${args[0]}\\right)' 408 }, 409 tanh: { 410 1: '\\tanh\\left(${args[0]}\\right)' 411 }, 412 // unit 413 to: { 414 2: "\\left(${args[0]}".concat(latexOperators.to, "${args[1]}\\right)") 415 }, 416 // utils 417 numeric: function numeric(node, options) { 418 // Not sure if this is strictly right but should work correctly for the vast majority of use cases. 419 return node.args[0].toTex(); 420 }, 421 // type 422 number: { 423 0: '0', 424 1: '\\left(${args[0]}\\right)', 425 2: '\\left(\\left(${args[0]}\\right)${args[1]}\\right)' 426 }, 427 string: { 428 0: '\\mathtt{""}', 429 1: '\\mathrm{string}\\left(${args[0]}\\right)' 430 }, 431 bignumber: { 432 0: '0', 433 1: '\\left(${args[0]}\\right)' 434 }, 435 complex: { 436 0: '0', 437 1: '\\left(${args[0]}\\right)', 438 2: "\\left(\\left(${args[0]}\\right)+".concat(latexSymbols.i, "\\cdot\\left(${args[1]}\\right)\\right)") 439 }, 440 matrix: { 441 0: '\\begin{bmatrix}\\end{bmatrix}', 442 1: '\\left(${args[0]}\\right)', 443 2: '\\left(${args[0]}\\right)' 444 }, 445 sparse: { 446 0: '\\begin{bsparse}\\end{bsparse}', 447 1: '\\left(${args[0]}\\right)' 448 }, 449 unit: { 450 1: '\\left(${args[0]}\\right)', 451 2: '\\left(\\left(${args[0]}\\right)${args[1]}\\right)' 452 } 453 }; 454 export var defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)'; 455 var latexUnits = { 456 deg: '^\\circ' 457 }; 458 export function escapeLatex(string) { 459 return escapeLatexLib(string, { 460 preserveFormatting: true 461 }); 462 } // @param {string} name 463 // @param {boolean} isUnit 464 465 export function toSymbol(name, isUnit) { 466 isUnit = typeof isUnit === 'undefined' ? false : isUnit; 467 468 if (isUnit) { 469 if (hasOwnProperty(latexUnits, name)) { 470 return latexUnits[name]; 471 } 472 473 return '\\mathrm{' + escapeLatex(name) + '}'; 474 } 475 476 if (hasOwnProperty(latexSymbols, name)) { 477 return latexSymbols[name]; 478 } 479 480 return escapeLatex(name); 481 }