UNPKG

10.4 kBJavaScriptView Raw
1/* eslint no-template-curly-in-string: "off" */
2
3import escapeLatexLib from 'escape-latex'
4import { hasOwnProperty } from './object'
5
6export const latexSymbols = {
7 // GREEK LETTERS
8 Alpha: 'A',
9 alpha: '\\alpha',
10 Beta: 'B',
11 beta: '\\beta',
12 Gamma: '\\Gamma',
13 gamma: '\\gamma',
14 Delta: '\\Delta',
15 delta: '\\delta',
16 Epsilon: 'E',
17 epsilon: '\\epsilon',
18 varepsilon: '\\varepsilon',
19 Zeta: 'Z',
20 zeta: '\\zeta',
21 Eta: 'H',
22 eta: '\\eta',
23 Theta: '\\Theta',
24 theta: '\\theta',
25 vartheta: '\\vartheta',
26 Iota: 'I',
27 iota: '\\iota',
28 Kappa: 'K',
29 kappa: '\\kappa',
30 varkappa: '\\varkappa',
31 Lambda: '\\Lambda',
32 lambda: '\\lambda',
33 Mu: 'M',
34 mu: '\\mu',
35 Nu: 'N',
36 nu: '\\nu',
37 Xi: '\\Xi',
38 xi: '\\xi',
39 Omicron: 'O',
40 omicron: 'o',
41 Pi: '\\Pi',
42 pi: '\\pi',
43 varpi: '\\varpi',
44 Rho: 'P',
45 rho: '\\rho',
46 varrho: '\\varrho',
47 Sigma: '\\Sigma',
48 sigma: '\\sigma',
49 varsigma: '\\varsigma',
50 Tau: 'T',
51 tau: '\\tau',
52 Upsilon: '\\Upsilon',
53 upsilon: '\\upsilon',
54 Phi: '\\Phi',
55 phi: '\\phi',
56 varphi: '\\varphi',
57 Chi: 'X',
58 chi: '\\chi',
59 Psi: '\\Psi',
60 psi: '\\psi',
61 Omega: '\\Omega',
62 omega: '\\omega',
63 // logic
64 true: '\\mathrm{True}',
65 false: '\\mathrm{False}',
66 // other
67 i: 'i', // TODO use \i ??
68 inf: '\\infty',
69 Inf: '\\infty',
70 infinity: '\\infty',
71 Infinity: '\\infty',
72 oo: '\\infty',
73 lim: '\\lim',
74 undefined: '\\mathbf{?}'
75}
76
77export const latexOperators = {
78 transpose: '^\\top',
79 ctranspose: '^H',
80 factorial: '!',
81 pow: '^',
82 dotPow: '.^\\wedge', // TODO find ideal solution
83 unaryPlus: '+',
84 unaryMinus: '-',
85 bitNot: '\\~', // TODO find ideal solution
86 not: '\\neg',
87 multiply: '\\cdot',
88 divide: '\\frac', // TODO how to handle that properly?
89 dotMultiply: '.\\cdot', // TODO find ideal solution
90 dotDivide: '.:', // TODO find ideal solution
91 mod: '\\mod',
92 add: '+',
93 subtract: '-',
94 to: '\\rightarrow',
95 leftShift: '<<',
96 rightArithShift: '>>',
97 rightLogShift: '>>>',
98 equal: '=',
99 unequal: '\\neq',
100 smaller: '<',
101 larger: '>',
102 smallerEq: '\\leq',
103 largerEq: '\\geq',
104 bitAnd: '\\&',
105 bitXor: '\\underline{|}',
106 bitOr: '|',
107 and: '\\wedge',
108 xor: '\\veebar',
109 or: '\\vee'
110}
111
112export const latexFunctions = {
113 // arithmetic
114 abs: { 1: '\\left|${args[0]}\\right|' },
115 add: { 2: `\\left(\${args[0]}${latexOperators.add}\${args[1]}\\right)` },
116 cbrt: { 1: '\\sqrt[3]{${args[0]}}' },
117 ceil: { 1: '\\left\\lceil${args[0]}\\right\\rceil' },
118 cube: { 1: '\\left(${args[0]}\\right)^3' },
119 divide: { 2: '\\frac{${args[0]}}{${args[1]}}' },
120 dotDivide: { 2: `\\left(\${args[0]}${latexOperators.dotDivide}\${args[1]}\\right)` },
121 dotMultiply: { 2: `\\left(\${args[0]}${latexOperators.dotMultiply}\${args[1]}\\right)` },
122 dotPow: { 2: `\\left(\${args[0]}${latexOperators.dotPow}\${args[1]}\\right)` },
123 exp: { 1: '\\exp\\left(${args[0]}\\right)' },
124 expm1: `\\left(e${latexOperators.pow}{\${args[0]}}-1\\right)`,
125 fix: { 1: '\\mathrm{${name}}\\left(${args[0]}\\right)' },
126 floor: { 1: '\\left\\lfloor${args[0]}\\right\\rfloor' },
127 gcd: '\\gcd\\left(${args}\\right)',
128 hypot: '\\hypot\\left(${args}\\right)',
129 log: {
130 1: '\\ln\\left(${args[0]}\\right)',
131 2: '\\log_{${args[1]}}\\left(${args[0]}\\right)'
132 },
133 log10: { 1: '\\log_{10}\\left(${args[0]}\\right)' },
134 log1p: {
135 1: '\\ln\\left(${args[0]}+1\\right)',
136 2: '\\log_{${args[1]}}\\left(${args[0]}+1\\right)'
137 },
138 log2: '\\log_{2}\\left(${args[0]}\\right)',
139 mod: { 2: `\\left(\${args[0]}${latexOperators.mod}\${args[1]}\\right)` },
140 multiply: { 2: `\\left(\${args[0]}${latexOperators.multiply}\${args[1]}\\right)` },
141 norm: {
142 1: '\\left\\|${args[0]}\\right\\|',
143 2: undefined // use default template
144 },
145 nthRoot: { 2: '\\sqrt[${args[1]}]{${args[0]}}' },
146 nthRoots: { 2: '\\{y : $y^{args[1]} = {${args[0]}}\\}' },
147 pow: { 2: `\\left(\${args[0]}\\right)${latexOperators.pow}{\${args[1]}}` },
148 round: {
149 1: '\\left\\lfloor${args[0]}\\right\\rceil',
150 2: undefined // use default template
151 },
152 sign: { 1: '\\mathrm{${name}}\\left(${args[0]}\\right)' },
153 sqrt: { 1: '\\sqrt{${args[0]}}' },
154 square: { 1: '\\left(${args[0]}\\right)^2' },
155 subtract: { 2: `\\left(\${args[0]}${latexOperators.subtract}\${args[1]}\\right)` },
156 unaryMinus: { 1: `${latexOperators.unaryMinus}\\left(\${args[0]}\\right)` },
157 unaryPlus: { 1: `${latexOperators.unaryPlus}\\left(\${args[0]}\\right)` },
158
159 // bitwise
160 bitAnd: { 2: `\\left(\${args[0]}${latexOperators.bitAnd}\${args[1]}\\right)` },
161 bitNot: { 1: latexOperators.bitNot + '\\left(${args[0]}\\right)' },
162 bitOr: { 2: `\\left(\${args[0]}${latexOperators.bitOr}\${args[1]}\\right)` },
163 bitXor: { 2: `\\left(\${args[0]}${latexOperators.bitXor}\${args[1]}\\right)` },
164 leftShift: { 2: `\\left(\${args[0]}${latexOperators.leftShift}\${args[1]}\\right)` },
165 rightArithShift: { 2: `\\left(\${args[0]}${latexOperators.rightArithShift}\${args[1]}\\right)` },
166 rightLogShift: { 2: `\\left(\${args[0]}${latexOperators.rightLogShift}\${args[1]}\\right)` },
167
168 // combinatorics
169 bellNumbers: { 1: '\\mathrm{B}_{${args[0]}}' },
170 catalan: { 1: '\\mathrm{C}_{${args[0]}}' },
171 stirlingS2: { 2: '\\mathrm{S}\\left(${args}\\right)' },
172
173 // complex
174 arg: { 1: '\\arg\\left(${args[0]}\\right)' },
175 conj: { 1: '\\left(${args[0]}\\right)^*' },
176 im: { 1: '\\Im\\left\\lbrace${args[0]}\\right\\rbrace' },
177 re: { 1: '\\Re\\left\\lbrace${args[0]}\\right\\rbrace' },
178
179 // logical
180 and: { 2: `\\left(\${args[0]}${latexOperators.and}\${args[1]}\\right)` },
181 not: { 1: latexOperators.not + '\\left(${args[0]}\\right)' },
182 or: { 2: `\\left(\${args[0]}${latexOperators.or}\${args[1]}\\right)` },
183 xor: { 2: `\\left(\${args[0]}${latexOperators.xor}\${args[1]}\\right)` },
184
185 // matrix
186 cross: { 2: '\\left(${args[0]}\\right)\\times\\left(${args[1]}\\right)' },
187 ctranspose: { 1: `\\left(\${args[0]}\\right)${latexOperators.ctranspose}` },
188 det: { 1: '\\det\\left(${args[0]}\\right)' },
189 dot: { 2: '\\left(${args[0]}\\cdot${args[1]}\\right)' },
190 expm: { 1: '\\exp\\left(${args[0]}\\right)' },
191 inv: { 1: '\\left(${args[0]}\\right)^{-1}' },
192 sqrtm: { 1: `{\${args[0]}}${latexOperators.pow}{\\frac{1}{2}}` },
193 trace: { 1: '\\mathrm{tr}\\left(${args[0]}\\right)' },
194 transpose: { 1: `\\left(\${args[0]}\\right)${latexOperators.transpose}` },
195
196 // probability
197 combinations: { 2: '\\binom{${args[0]}}{${args[1]}}' },
198 combinationsWithRep: { 2: '\\left(\\!\\!{\\binom{${args[0]}}{${args[1]}}}\\!\\!\\right)' },
199 factorial: { 1: `\\left(\${args[0]}\\right)${latexOperators.factorial}` },
200 gamma: { 1: '\\Gamma\\left(${args[0]}\\right)' },
201
202 // relational
203 equal: { 2: `\\left(\${args[0]}${latexOperators.equal}\${args[1]}\\right)` },
204 larger: { 2: `\\left(\${args[0]}${latexOperators.larger}\${args[1]}\\right)` },
205 largerEq: { 2: `\\left(\${args[0]}${latexOperators.largerEq}\${args[1]}\\right)` },
206 smaller: { 2: `\\left(\${args[0]}${latexOperators.smaller}\${args[1]}\\right)` },
207 smallerEq: { 2: `\\left(\${args[0]}${latexOperators.smallerEq}\${args[1]}\\right)` },
208 unequal: { 2: `\\left(\${args[0]}${latexOperators.unequal}\${args[1]}\\right)` },
209
210 // special
211 erf: { 1: 'erf\\left(${args[0]}\\right)' },
212
213 // statistics
214 max: '\\max\\left(${args}\\right)',
215 min: '\\min\\left(${args}\\right)',
216 variance: '\\mathrm{Var}\\left(${args}\\right)',
217
218 // trigonometry
219 acos: { 1: '\\cos^{-1}\\left(${args[0]}\\right)' },
220 acosh: { 1: '\\cosh^{-1}\\left(${args[0]}\\right)' },
221 acot: { 1: '\\cot^{-1}\\left(${args[0]}\\right)' },
222 acoth: { 1: '\\coth^{-1}\\left(${args[0]}\\right)' },
223 acsc: { 1: '\\csc^{-1}\\left(${args[0]}\\right)' },
224 acsch: { 1: '\\mathrm{csch}^{-1}\\left(${args[0]}\\right)' },
225 asec: { 1: '\\sec^{-1}\\left(${args[0]}\\right)' },
226 asech: { 1: '\\mathrm{sech}^{-1}\\left(${args[0]}\\right)' },
227 asin: { 1: '\\sin^{-1}\\left(${args[0]}\\right)' },
228 asinh: { 1: '\\sinh^{-1}\\left(${args[0]}\\right)' },
229 atan: { 1: '\\tan^{-1}\\left(${args[0]}\\right)' },
230 atan2: { 2: '\\mathrm{atan2}\\left(${args}\\right)' },
231 atanh: { 1: '\\tanh^{-1}\\left(${args[0]}\\right)' },
232 cos: { 1: '\\cos\\left(${args[0]}\\right)' },
233 cosh: { 1: '\\cosh\\left(${args[0]}\\right)' },
234 cot: { 1: '\\cot\\left(${args[0]}\\right)' },
235 coth: { 1: '\\coth\\left(${args[0]}\\right)' },
236 csc: { 1: '\\csc\\left(${args[0]}\\right)' },
237 csch: { 1: '\\mathrm{csch}\\left(${args[0]}\\right)' },
238 sec: { 1: '\\sec\\left(${args[0]}\\right)' },
239 sech: { 1: '\\mathrm{sech}\\left(${args[0]}\\right)' },
240 sin: { 1: '\\sin\\left(${args[0]}\\right)' },
241 sinh: { 1: '\\sinh\\left(${args[0]}\\right)' },
242 tan: { 1: '\\tan\\left(${args[0]}\\right)' },
243 tanh: { 1: '\\tanh\\left(${args[0]}\\right)' },
244
245 // unit
246 to: { 2: `\\left(\${args[0]}${latexOperators.to}\${args[1]}\\right)` },
247
248 // utils
249 numeric: function (node, options) {
250 // Not sure if this is strictly right but should work correctly for the vast majority of use cases.
251 return node.args[0].toTex()
252 },
253
254 // type
255 number: {
256 0: '0',
257 1: '\\left(${args[0]}\\right)',
258 2: '\\left(\\left(${args[0]}\\right)${args[1]}\\right)'
259 },
260 string: {
261 0: '\\mathtt{""}',
262 1: '\\mathrm{string}\\left(${args[0]}\\right)'
263 },
264 bignumber: {
265 0: '0',
266 1: '\\left(${args[0]}\\right)'
267 },
268 complex: {
269 0: '0',
270 1: '\\left(${args[0]}\\right)',
271 2: `\\left(\\left(\${args[0]}\\right)+${latexSymbols.i}\\cdot\\left(\${args[1]}\\right)\\right)`
272 },
273 matrix: {
274 0: '\\begin{bmatrix}\\end{bmatrix}',
275 1: '\\left(${args[0]}\\right)',
276 2: '\\left(${args[0]}\\right)'
277 },
278 sparse: {
279 0: '\\begin{bsparse}\\end{bsparse}',
280 1: '\\left(${args[0]}\\right)'
281 },
282 unit: {
283 1: '\\left(${args[0]}\\right)',
284 2: '\\left(\\left(${args[0]}\\right)${args[1]}\\right)'
285 }
286
287}
288
289export const defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)'
290
291const latexUnits = {
292 deg: '^\\circ'
293}
294
295export function escapeLatex (string) {
296 return escapeLatexLib(string, { preserveFormatting: true })
297}
298
299// @param {string} name
300// @param {boolean} isUnit
301export function toSymbol (name, isUnit) {
302 isUnit = typeof isUnit === 'undefined' ? false : isUnit
303 if (isUnit) {
304 if (hasOwnProperty(latexUnits, name)) {
305 return latexUnits[name]
306 }
307
308 return '\\mathrm{' + escapeLatex(name) + '}'
309 }
310
311 if (hasOwnProperty(latexSymbols, name)) {
312 return latexSymbols[name]
313 }
314
315 return escapeLatex(name)
316}