simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

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 }