tex2typst 0.3.27-beta.1 → 0.3.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,463 @@
1
+ # Some test cases are from https://github.com/curvenote/tex-to-typst/blob/1d0b121d162911f1c99b47171939e30656f49270/tests/math.yml (MIT License)
2
+ title: struct-tex2typst
3
+ cases:
4
+ - title: redundant spaces should be ignored
5
+ tex: 'p ( x ) = \frac{e^{-\lambda}\lambda^{x}}{ x ! }'
6
+ typst: p(x) = (e^(-lambda) lambda^x)/(x!)
7
+ - title: Simplified brackets
8
+ tex: 'e_f(x)'
9
+ typst: e_f (x)
10
+ - title: Comma inside function
11
+ tex: '\boldsymbol{j_x, j_y}'
12
+ typst: 'bold(j_x comma j_y)'
13
+
14
+ - title: Nested functions
15
+ tex: '\boldsymbol{m}_\text{ref}'
16
+ typst: 'bold(m)_"ref"'
17
+ - title: left and right brackets, not overHigh
18
+ tex: '\left[\boldsymbol{A} \right) \left\{b \right)'
19
+ typst: 'lr([bold(A))) lr({b))'
20
+ - title: dot as right bracket
21
+ tex: '\left\{ \frac{a}{b} \right.'
22
+ typst: 'lr(\{ a/b)'
23
+ - title: dot as left bracket
24
+ tex: '\left. \frac{a}{b} \right\}'
25
+ typst: 'lr(a/b })'
26
+ - title: left. and right.
27
+ tex: '\left. \frac{a}{b} \right.'
28
+ typst: 'lr(a/b)'
29
+ - title: lr
30
+ tex: \left|a + \frac{1}{3} \right|^2
31
+ typst: lr(|a + 1/3|)^2
32
+ - title: biglr
33
+ tex: \bigl|a + \frac{1}{3} \bigr|^2
34
+ typst: "|a + 1/3 |^2"
35
+ - title: bigm
36
+ tex: \dfrac{d}{dx}x^2\bigm{|}_{x=2}
37
+ typst: frac(d, d x) x^2 |_(x = 2)
38
+ - title: intop
39
+ tex: \intop_0^\infty x \text{d} x
40
+ typst: limits(integral)_0^infinity x "d" x
41
+ - title: bigglr
42
+ tex: \biggl|a + \frac{1}{3} \biggr|^2
43
+ typst: "|a + 1/3 |^2"
44
+ - title: symmetry left right
45
+ tex: \left\{ a \right\} \left( b \right) \left[ c \right]
46
+ typst: '{a}(b) [c]'
47
+ - title: symmetry bigl bigr
48
+ tex: \bigl\{ a \bigr\} \bigl( b \bigr) \bigl[ c \bigr]
49
+ typst: '{a}(b) [c]'
50
+ - title: symmetry biggl biggr
51
+ tex: \biggl\{ a \biggr\} \biggl( b \biggr) \biggl[ c \biggr]
52
+ typst: '{a}(b) [c]'
53
+ - title: symmetry Biggl Biggr
54
+ tex: \Biggl\{ a \Biggr\} \Biggl( b \Biggr) \Biggl[ c \Biggr]
55
+ typst: '{a}(b) [c]'
56
+ - title: paired delimiter commands
57
+ tex: \left(\bigl[\biggl\{a\biggr\}\bigr]\right)
58
+ typst: '([ {a}])'
59
+ - title: lparen rparen
60
+ tex: \left\lparen \frac{1}{3} \right\rparen
61
+ typst: lr(paren.l 1/3 paren.r)
62
+ - title: lbrace rbrace
63
+ tex: \left\lbrace \frac{1}{3} \right\rbrace
64
+ typst: lr(brace.l 1/3 brace.r)
65
+ - title: operatorname
66
+ tex: '\operatorname{diag} \text{diag}'
67
+ typst: 'op("diag") "diag"'
68
+ - title: operatorname1
69
+ tex: '\operatorname{a}'
70
+ typst: op("a")
71
+ - title: scripts
72
+ tex: '\boldsymbol{k}_{Av} \boldsymbol{k}^{Av}'
73
+ typst: 'bold(k)_(A v) bold(k)^(A v)'
74
+ - title: scripts
75
+ tex: |-
76
+ \boldsymbol{D}
77
+ \\
78
+ \boldsymbol{G}_{z}
79
+ typst: |-
80
+ bold(D)
81
+ \
82
+ bold(G)_z
83
+ - title: Complex equations with nested over/under braces
84
+ tex: |-
85
+ \begin{align*}
86
+ \overbrace{
87
+ \left[
88
+ \frac{1}{\Delta t}
89
+ \frac{\partial \boldsymbol{\theta}^{n+1}}{\partial\boldsymbol{\psi}^{n+1}}
90
+ -\boldsymbol{D}
91
+ \text{diag}\left( \boldsymbol{G} \boldsymbol{\psi}^{n+1} \right)
92
+ \frac{\partial \boldsymbol{k}_{Av}}{\partial\boldsymbol{\psi}^{n+1}}
93
+ -\boldsymbol{D}
94
+ \text{diag}\left( \boldsymbol{k}_{Av}(\boldsymbol{\psi}^{n+1},\boldsymbol{m}) \right)
95
+ \boldsymbol{G}
96
+ - \boldsymbol{G}_{z}
97
+ \frac{\partial \boldsymbol{k}_{Av}}{\partial\boldsymbol{\psi}^{n+1}}
98
+ \right]
99
+ }^{\boldsymbol{A}_0(\boldsymbol{\psi}^{n+1})}
100
+ \frac{\partial \boldsymbol{\psi}^{n+1}}{\partial\boldsymbol{m}}
101
+ \nonumber\\
102
+ +
103
+ \underbrace{
104
+ \left[
105
+ -\frac{1}{\Delta t}
106
+ \frac{\partial \boldsymbol{\theta}^n}{\partial\boldsymbol{\psi}^n}
107
+ \right]
108
+ }_{\boldsymbol{A}_{-1}(\boldsymbol{\psi}^n)}
109
+ \frac{\partial \boldsymbol{\psi}^n}{\partial\boldsymbol{m}}
110
+ =
111
+ \underbrace{
112
+ \left[
113
+ -\boldsymbol{D}
114
+ \text{diag}\left( \boldsymbol{G} \boldsymbol{\psi}^{n+1} \right)
115
+ \frac{\partial \boldsymbol{k}_{Av}}{\partial\boldsymbol{m}}
116
+ -\boldsymbol{G}_{z}
117
+ \frac{\partial \boldsymbol{k}_{Av}}{\partial\boldsymbol{m}}
118
+ \right]
119
+ }_{\boldsymbol{B}(\psi^{n+1})}&
120
+ \end{align*}
121
+ typst: |-
122
+ overbrace(
123
+ [
124
+ 1/(Delta t)
125
+ (diff bold(theta)^(n + 1))/(diff bold(psi)^(n + 1))
126
+ - bold(D)
127
+ "diag"(bold(G) bold(psi)^(n + 1))
128
+ (diff bold(k)_(A v))/(diff bold(psi)^(n + 1))
129
+ - bold(D)
130
+ "diag"(bold(k)_(A v) (bold(psi)^(n + 1) comma bold(m)))
131
+ bold(G)
132
+ - bold(G)_z
133
+ (diff bold(k)_(A v))/(diff bold(psi)^(n + 1))
134
+ ]
135
+ , bold(A)_0 (bold(psi)^(n + 1)))
136
+ (diff bold(psi)^(n + 1))/(diff bold(m))
137
+ \
138
+ +
139
+ underbrace(
140
+ [
141
+ - 1/(Delta t)
142
+ (diff bold(theta)^n)/(diff bold(psi)^n)
143
+ ]
144
+ , bold(A)_(-1) (bold(psi)^n))
145
+ (diff bold(psi)^n)/(diff bold(m))
146
+ =
147
+ underbrace(
148
+ [
149
+ -bold(D)
150
+ "diag"(bold(G) bold(psi)^(n + 1))
151
+ (diff bold(k)_(A v))/(diff bold(m))
152
+ - bold(G)_z
153
+ (diff bold(k)_(A v))/(diff bold(m))
154
+ ]
155
+ , bold(B)(psi^(n + 1))) &
156
+ - title: leading underscore
157
+ tex: _2
158
+ typst: '#none_2'
159
+ - title: leading power
160
+ tex: '^{\text{st}}'
161
+ typst: '#none^"st"'
162
+ - title: greater than
163
+ tex: 'a \ge b'
164
+ typst: a >= b
165
+ - title: greater than (preferShorthands=false)
166
+ tex: 'a \ge b'
167
+ typst: a gt.eq b
168
+ preferShorthands: false
169
+ - title: ddot
170
+ tex: 'q, \dot{q}, \ddot{q}'
171
+ typst: q, dot(q), dot.double(q)
172
+ - title: mat
173
+ tex: 'x(t) = \left[ \begin{array}{c} q(t) & x \\ \dot{q}(t) & x \end{array}\right]'
174
+ typst: 'x(t) = [mat(delim: #none, align: #center, q(t), x; dot(q)(t), x)]'
175
+ - title: brackets
176
+ tex: '\frac{1}{\tau(X_2)}'
177
+ typst: '1/(tau(X_2))'
178
+ - title: bar and nested bb
179
+ tex: '\mathbb{\bar{R}}'
180
+ typst: 'bb(macron(R))'
181
+ - title: Underscore with no content
182
+ tex: 'P_{}^{1}'
183
+ typst: 'P_()^1'
184
+ - title: Simple overbrace
185
+ tex: '\overbrace{a}^{b}'
186
+ typst: 'overbrace(a, b)'
187
+ - title: underbrace
188
+ tex: '\underbrace{a}_{b}'
189
+ typst: underbrace(a, b)
190
+ - title: Test
191
+ tex: a^{b^{n+1}}
192
+ typst: a^(b^(n + 1))
193
+ - title: Test2
194
+ tex: a+b^1 + \frac{2}{3} + \overbrace{123}^{b}
195
+ typst: a + b^1 + 2/3 + overbrace(123, b)
196
+ - title: Symbols
197
+ tex: '\alpha \nabla \partial'
198
+ typst: alpha nabla diff
199
+ - title: Align
200
+ tex: |-
201
+ \begin{align*}
202
+ a &= b \\
203
+ c &= d
204
+ \end{align*}
205
+ typst: |-
206
+ a &= b \
207
+ c &= d
208
+ - title: Matrix cells are groups
209
+ tex: |-
210
+ m = \begin{matrix}
211
+ a &= b \\
212
+ c &= d
213
+ \end{matrix}
214
+ typst: |-
215
+ m = mat(delim: #none, a, = b;
216
+ c, = d)
217
+ - title: An align mark & is at the beginning of a line
218
+ tex: |-
219
+ \begin{matrix}
220
+ &a &= b \\
221
+ &c &= d
222
+ \end{matrix}
223
+ typst: |-
224
+ mat(delim: #none, , a, = b;
225
+ , c, = d)
226
+ - title: Array
227
+ tex: |-
228
+ \begin{array}{cc}
229
+ a & b \\
230
+ c & d
231
+ \end{array}
232
+ typst: |-
233
+ mat(delim: #none, align: #center, a, b;
234
+ c, d)
235
+ - title: Array with vertical line
236
+ tex: |-
237
+ \begin{array}{c|c|c}
238
+ a & b & c \\
239
+ c & d & e
240
+ \end{array}
241
+ typst: |-
242
+ mat(delim: #none, augment: #(vline: (1, 2)), align: #center, a, b, c;
243
+ c, d, e)
244
+ - title: Array with single vertical line
245
+ tex: |-
246
+ \begin{array}{c|cc}
247
+ a & b & c \\
248
+ c & d & e
249
+ \end{array}
250
+ typst: |-
251
+ mat(delim: #none, augment: #1, align: #center, a, b, c;
252
+ c, d, e)
253
+ # should not mistakenly ignore `{x}` in `\begin{matrix} {x} ... \end{matrix}`
254
+ - title: should not parse arg if envName is not one of array, subarray
255
+ tex: \begin{matrix} {x} & {y} \\ {z} & {w} \end{matrix}
256
+ typst: "mat(delim: #none, x, y; z, w)"
257
+ - title: Test3
258
+ tex: \boldsymbol{x}
259
+ typst: bold(x)
260
+ - title: Test4
261
+ tex: a^2 + b^2 = c^2
262
+ typst: a^2 + b^2 = c^2
263
+ - title: Euler Complex Exponential
264
+ tex: e^{i\theta} = \cos \theta + i \sin \theta
265
+ typst: e^(i theta) = cos theta + i sin theta
266
+ - title: Euler Product
267
+ tex: \prod_{p} \frac{1}{1-p^{-s}}= \sum_{n=1}^{\infty} \frac{1}{n^s}
268
+ typst: product_p 1/(1 - p^(-s)) = sum_(n = 1)^infinity 1/(n^s)
269
+ - title: Test5
270
+ tex: "{a+b}^2"
271
+ typst: (a + b)^2
272
+ - title: Test6
273
+ tex: 1 + {a + b} + c
274
+ typst: 1 + a + b + c
275
+ - title: Test7
276
+ tex: (a + b)^2
277
+ typst: (a + b)^2
278
+ - title: leading minus sign
279
+ tex: a^{-s}
280
+ typst: a^(-s)
281
+ - title: Test8
282
+ tex: \sqrt{\frac{1}{x^2 + y^2}}
283
+ typst: sqrt(1/(x^2 + y^2))
284
+ - title: basic prime case
285
+ tex: y'
286
+ typst: y'
287
+ - title: has both prime and subscript
288
+ tex: y_1' + y'_2 + y_{a_1}' + {\theta}_1'
289
+ typst: y'_1 + y'_2 + y'_(a_1) + theta'_1
290
+
291
+ - title: space before or after script
292
+ tex: \lim _{x \to 0} \sum_{i=1} ^ n
293
+ typst: lim_(x -> 0) sum_(i = 1)^n
294
+ - title: spaces around text
295
+ tex: i_D = \mu_n C_\text{ox} \frac{W}{L} \left[ (v_\text{GS} - V_t)v_\text{DS} - \frac{1}{2} v_\text{DS}^2 \right]
296
+ typst: i_D = mu_n C_"ox" W/L [(v_"GS" - V_t) v_"DS" - 1/2 v_"DS"^2]
297
+ - title: base is group wrapped in brackets
298
+ tex: e = \lim_{{n \to \infty}} \left(1 + \frac{1}{n}\right)^n
299
+ typst: e = lim_(n -> infinity) (1 + 1/n)^n
300
+
301
+ - title: oo
302
+ tex: \infty
303
+ typst: oo
304
+ inftyToOo: true
305
+ - title: overrightarrow
306
+ tex: \overrightarrow{AB}
307
+ typst: arrow(A B)
308
+ - title: overleftarrow
309
+ tex: \overleftarrow{AB}
310
+ typst: accent(A B, <-)
311
+ - title: Horizontal space symbols
312
+ tex: "\\, \\: \\; \\quad \\!"
313
+ typst: "thin med thick quad #h(-math.thin.amount)"
314
+ - title: cases1
315
+ tex: |-
316
+ \begin{cases}
317
+ x^2, & \text{if } x \geq 0 \\
318
+ -x, & \text{if } x < 0
319
+ \end{cases}
320
+ typst: |-
321
+ cases(x^2 comma & "if " x >= 0,
322
+ - x comma & "if " x < 0)
323
+ - title: cases2
324
+ tex: |-
325
+ A_{ij} =
326
+ \begin{cases}
327
+ 1, & \text{if } i = j \\
328
+ 0, & \text{otherwise}
329
+ \end{cases}
330
+ typst: |-
331
+ A_(i j) =
332
+ cases(1 comma & "if " i = j,
333
+ 0 comma & "otherwise")
334
+ - title: cases3
335
+ tex: |-
336
+ P(X = x) =
337
+ \begin{cases}
338
+ \frac{1}{n}, & x \in \{1,2,\dots,n\} \\
339
+ 0, & \text{otherwise}
340
+ \end{cases}
341
+ typst: |-
342
+ P(X = x) =
343
+ cases(1/n comma & x in {1 comma 2 comma ... comma n},
344
+ 0 comma & "otherwise")
345
+ - title: cases4
346
+ tex: |-
347
+ f(x) =
348
+ \begin{cases}
349
+ x^2 + 1, & \text{if } x < -1 \\
350
+ \sin x + x^2, & \text{if } -1 \leq x \leq 1 \\
351
+ \sqrt{x}, & \text{if } x > 1
352
+ \end{cases}
353
+ typst: |-
354
+ f(x) =
355
+ cases(x^2 + 1 comma & "if " x < - 1,
356
+ sin x + x^2 comma & "if " - 1 <= x <= 1,
357
+ sqrt(x) comma & "if " x > 1)
358
+ - title: cases5
359
+ tex: |-
360
+ \begin{align*}
361
+ f(x) &=
362
+ \begin{cases}
363
+ x^2, & x \geq 0 \\
364
+ -x, & x < 0
365
+ \end{cases} \\
366
+ g(x) &=
367
+ \begin{cases}
368
+ \sin x, & x < \pi \\
369
+ 0, & x \geq \pi
370
+ \end{cases}
371
+ \end{align*}
372
+
373
+ typst: |-
374
+ f(x) &=
375
+ cases(x^2 comma & x >= 0,
376
+ - x comma & x < 0) \
377
+ g(x) &=
378
+ cases(sin x comma & x < pi,
379
+ 0 comma & x >= pi)
380
+ - title: frac1
381
+ tex: \frac ab
382
+ typst: a/b
383
+ - title: frac2
384
+ tex: \frac 12
385
+ typst: 1/2
386
+ - title: frac3
387
+ tex: \frac 12
388
+ typst: 1/2
389
+ - title: frac4
390
+ tex: \frac12
391
+ typst: 1/2
392
+ - title: frac5
393
+ tex: \frac{12}{34}
394
+ typst: 12/34
395
+ - title: frac6
396
+ tex: \frac123
397
+ typst: 1/2 3
398
+ - title: frac7
399
+ tex: \frac {12}3
400
+ typst: 12/3
401
+ # this test the lexer's regex. Old bad implementation translated it to "yen 2 0 00 \$ 3000"
402
+ - title: yen
403
+ tex: \yen 2000 > \$ 3000
404
+ typst: yen 2000 > \$ 3000
405
+ # this test the typst writer. Old bad implementation translated it to "X/Y/2"
406
+ - title: frac of frac
407
+ tex: \frac{X}{\frac{Y}{2}}
408
+ typst: X/(Y/2)
409
+ - title: Don't escape commas inside a lr()
410
+ tex: \left| f(a, b) \right|
411
+ typst: lr(|f(a, b)|)
412
+ - title: Backslash space
413
+ tex: a \ b
414
+ typst: a med b
415
+ - title: display style
416
+ tex: \displaystyle \lim_{x \to -\infty} F(x) = 0, \lim_{x \to +\infty} F(x) = 1
417
+ typst: display(lim_(x -> - infinity) F(x) = 0 comma lim_(x -> + infinity) F(x) = 1)
418
+ - title: display style 2
419
+ tex: \lim_{x \to -\infty} F(x) = 0, \displaystyle \lim_{x \to +\infty} F(x) = 1
420
+ typst: lim_(x -> - infinity) F(x) = 0, display(lim_(x -> + infinity) F(x) = 1)
421
+ # this test the typst formatter. Old bad implementation translated it to "C(x y)/z"
422
+ - title: parenthesis in fraction
423
+ tex: C \frac{xy}{z}
424
+ typst: C (x y)/z
425
+ # this test the typst formatter. Old bad implementation translated it to "1/3(x + y)"
426
+ - title: parenthesis after fraction
427
+ tex: \frac{1}{3} (x + y)
428
+ typst: 1/3 (x + y)
429
+ - title: substack
430
+ tex: \sum_{\substack{0 \leq i \leq m \\ 0 < j < n}} P(i, j)
431
+ typst: sum_(0 <= i <= m \ 0 < j < n) P(i, j)
432
+ - title: subarray-l
433
+ tex: \sum_{\begin{subarray}{l} 0 \leq i \leq m \\ 0 < j < n \end{subarray}} P(i, j)
434
+ typst: sum_(& 0 <= i <= m \ & 0 < j < n) P(i, j)
435
+ - title: subarray
436
+ tex: \sum_{\begin{subarray}{c} 0 \leq i \leq m \\ 0 < j < n \end{subarray}} P(i, j)
437
+ typst: sum_(0 <= i <= m \ 0 < j < n) P(i, j)
438
+ - title: subarray-r
439
+ tex: \sum_{\begin{subarray}{r} 0 \leq i \leq m \\ 0 < j < n \end{subarray}} P(i, j)
440
+ typst: sum_(0 <= i <= m & \ 0 < j < n &) P(i, j)
441
+ - title: subarray-with-rr &
442
+ tex: \sum_{\begin{subarray}{rr} a & b \\ c & d \end{subarray}} P(i, j)
443
+ typst: sum_(a & b \ c & d) P(i, j)
444
+ - title: command set
445
+ tex: \set{a, b, c}
446
+ typst: "{a, b, c}"
447
+ - title: command set, empty
448
+ tex: \set{}
449
+ typst: "{}"
450
+ - title: command displaylines is ignored
451
+ tex: |-
452
+ \displaylines{
453
+ E = mc^2 \\
454
+ F = ma \\
455
+ P = IV
456
+ }
457
+ typst: |-
458
+ E = m c^2 \
459
+ F = m a \
460
+ P = I V
461
+ - title: command mathinner is ignored
462
+ tex: ab\mathinner{\text{inside}}cd
463
+ typst: a b "inside" c d