tex2typst 0.3.0 → 0.3.1

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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/map.ts
2
- var symbolMap = new Map([
2
+ var symbolMap = /* @__PURE__ */ new Map([
3
3
  ["nonumber", ""],
4
4
  ["vec", "arrow"],
5
5
  ["neq", "eq.not"],
@@ -10,13 +10,19 @@ var symbolMap = new Map([
10
10
  ["vdots", "dots.v"],
11
11
  ["ddots", "dots.down"],
12
12
  ["widehat", "hat"],
13
+ // Ideally, the result of \widehat should be longer than \hat. But it is not implemented now.
13
14
  ["widetilde", "tilde"],
15
+ // Ideally, the result of \widetilde should be longer than \tilde. But it is not implemented now.
14
16
  ["quad", "quad"],
15
17
  ["qquad", "wide"],
16
18
  ["overbrace", "overbrace"],
19
+ // same
17
20
  ["underbrace", "underbrace"],
21
+ // same
18
22
  ["overline", "overline"],
23
+ // same
19
24
  ["underline", "underline"],
25
+ // same
20
26
  ["bar", "macron"],
21
27
  ["dbinom", "binom"],
22
28
  ["tbinom", "binom"],
@@ -33,18 +39,25 @@ var symbolMap = new Map([
33
39
  ["mathsf", "sans"],
34
40
  ["mathtt", "mono"],
35
41
  ["rm", "upright"],
42
+ // TODO: \pmb need special logic to handle but it is not implemented now. See the commented test case.
36
43
  ["pmb", "bold"],
44
+ /* variants of plus,minus,times,divide */
37
45
  ["pm", "plus.minus"],
38
46
  ["mp", "minus.plus"],
39
47
  ["boxplus", "plus.square"],
40
48
  ["otimes", "times.circle"],
41
49
  ["boxtimes", "times.square"],
50
+ /* wave */
51
+ // tex: \sim \approx \cong \simeq \asymp \equiv \propto
52
+ // typst: tilde.op approx tilde.equiv tilde.eq ≍ equiv prop
42
53
  ["approx", "approx"],
43
54
  ["cong", "tilde.equiv"],
44
55
  ["simeq", "tilde.eq"],
45
- ["asymp", ""],
56
+ ["asymp", "\u224D"],
57
+ // just use the unicode character :-)
46
58
  ["equiv", "equiv"],
47
59
  ["propto", "prop"],
60
+ /* arrows */
48
61
  ["gets", "arrow.l"],
49
62
  ["hookleftarrow", "arrow.l.hook"],
50
63
  ["leftharpoonup", "harpoon.lt"],
@@ -56,6 +69,7 @@ var symbolMap = new Map([
56
69
  ["Longleftarrow", "arrow.l.double.long"],
57
70
  ["Longrightarrow", "arrow.r.double.long"],
58
71
  ["Longleftrightarrow", "arrow.l.r.double.long"],
72
+ // ['longmapsto', 'arrow.r.bar'],
59
73
  ["hookrightarrow", "arrow.r.hook"],
60
74
  ["rightharpoonup", "harpoon.rt"],
61
75
  ["rightharpoondown", "harpoon.rb"],
@@ -94,26 +108,34 @@ var symbolMap = new Map([
94
108
  ["Theta", "Theta"],
95
109
  ["aleph", "alef"],
96
110
  ["alpha", "alpha"],
111
+ // ['amalg', 'product.co'],
97
112
  ["angle", "angle"],
98
113
  ["approx", "approx"],
99
114
  ["approxeq", "approx.eq"],
115
+ // ['ast', 'ast'],
100
116
  ["beta", "beta"],
101
117
  ["bigcap", "sect.big"],
102
118
  ["bigcirc", "circle.big"],
103
119
  ["bigcup", "union.big"],
104
120
  ["bigodot", "dot.circle.big"],
121
+ // ['bigoplus', 'xor.big'], // or "plus.circle.big"
105
122
  ["bigotimes", "times.circle.big"],
106
123
  ["bigsqcup", "union.sq.big"],
124
+ // ['bigtriangledown', 'triangle.b'],
125
+ // ['bigtriangleup', 'triangle.t'],
107
126
  ["biguplus", "union.plus.big"],
108
127
  ["bigvee", "or.big"],
109
128
  ["bigwedge", "and.big"],
129
+ // ['bowtie', 'join'],
110
130
  ["bullet", "bullet"],
111
131
  ["cap", "sect"],
112
132
  ["cdot", "dot.op"],
133
+ // 'dot.op' or 'dot.c'
113
134
  ["cdots", "dots.c"],
114
135
  ["checkmark", "checkmark"],
115
136
  ["chi", "chi"],
116
137
  ["circ", "circle.small"],
138
+ // 'circle.small' or 'compose'
117
139
  ["colon", "colon"],
118
140
  ["cong", "tilde.equiv"],
119
141
  ["coprod", "product.co"],
@@ -138,6 +160,7 @@ var symbolMap = new Map([
138
160
  ["eta", "eta"],
139
161
  ["exists", "exists"],
140
162
  ["forall", "forall"],
163
+ // ['frown', 'paren.t'],
141
164
  ["gamma", "gamma"],
142
165
  ["ge", "gt.eq"],
143
166
  ["geq", "gt.eq"],
@@ -152,6 +175,7 @@ var symbolMap = new Map([
152
175
  ["infty", "infinity"],
153
176
  ["int", "integral"],
154
177
  ["intercal", "top"],
178
+ // 'top' or 'tack.b'
155
179
  ["iota", "iota"],
156
180
  ["jmath", "dotless.j"],
157
181
  ["kappa", "kappa"],
@@ -170,13 +194,17 @@ var symbolMap = new Map([
170
194
  ["leqslant", "lt.eq.slant"],
171
195
  ["lhd", "triangle.l"],
172
196
  ["ll", "lt.double"],
197
+ // ['longmapsto', 'arrow.bar.long'],
198
+ // ['longrightarrow', 'arrow.long'],
173
199
  ["lor", "or"],
174
200
  ["ltimes", "times.l"],
201
+ // ['mapsto', 'arrow.bar'],
175
202
  ["measuredangle", "angle.arc"],
176
203
  ["mid", "divides"],
177
204
  ["models", "models"],
178
205
  ["mp", "minus.plus"],
179
206
  ["mu", "mu"],
207
+ // ['nRightarrow', 'arrow.double.not'],
180
208
  ["nabla", "nabla"],
181
209
  ["ncong", "tilde.equiv.not"],
182
210
  ["ne", "eq.not"],
@@ -190,6 +218,7 @@ var symbolMap = new Map([
190
218
  ["ngeq", "gt.eq.not"],
191
219
  ["nmid", "divides.not"],
192
220
  ["notin", "in.not"],
221
+ // ['nrightarrow', 'arrow.not'],
193
222
  ["nsim", "tilde.not"],
194
223
  ["nsubseteq", "subset.eq.not"],
195
224
  ["nu", "nu"],
@@ -201,7 +230,9 @@ var symbolMap = new Map([
201
230
  ["oiint", "integral.surf"],
202
231
  ["oiiint", "integral.vol"],
203
232
  ["omega", "omega"],
233
+ // ['omicron', 'omicron'],
204
234
  ["ominus", "minus.circle"],
235
+ // ['oplus', 'xor'], // or 'plus.circle'
205
236
  ["otimes", "times.circle"],
206
237
  ["parallel", "parallel"],
207
238
  ["partial", "diff"],
@@ -230,11 +261,13 @@ var symbolMap = new Map([
230
261
  ["simeq", "tilde.eq"],
231
262
  ["slash", "slash"],
232
263
  ["smallsetminus", "without"],
264
+ // ['smile', 'paren.b'],
233
265
  ["spadesuit", "suit.spade"],
234
266
  ["sqcap", "sect.sq"],
235
267
  ["sqcup", "union.sq"],
236
268
  ["sqsubseteq", "subset.eq.sq"],
237
269
  ["sqsupseteq", "supset.eq.sq"],
270
+ // ['star', 'star'],
238
271
  ["subset", "subset"],
239
272
  ["subseteq", "subset.eq"],
240
273
  ["subsetneq", "subset.neq"],
@@ -251,6 +284,9 @@ var symbolMap = new Map([
251
284
  ["to", "arrow.r"],
252
285
  ["top", "top"],
253
286
  ["triangle", "triangle.t"],
287
+ // ['triangledown', 'triangle.b.small'],
288
+ // ['triangleleft', 'triangle.l.small'],
289
+ // ['triangleright', 'triangle.r.small'],
254
290
  ["twoheadrightarrow", "arrow.r.twohead"],
255
291
  ["uparrow", "arrow.t"],
256
292
  ["updownarrow", "arrow.t.b"],
@@ -259,6 +295,7 @@ var symbolMap = new Map([
259
295
  ["upsilon", "upsilon"],
260
296
  ["varepsilon", "epsilon"],
261
297
  ["varnothing", "diameter"],
298
+ // empty set
262
299
  ["varphi", "phi"],
263
300
  ["varpi", "pi.alt"],
264
301
  ["varrho", "rho.alt"],
@@ -272,11 +309,12 @@ var symbolMap = new Map([
272
309
  ["xi", "xi"],
273
310
  ["yen", "yen"],
274
311
  ["zeta", "zeta"],
312
+ // extended
275
313
  ["mathscr", "scr"],
276
314
  ["LaTeX", "#LaTeX"],
277
315
  ["TeX", "#TeX"]
278
316
  ]);
279
- var map_from_official_docs = new Map([
317
+ var map_from_official_docs = /* @__PURE__ */ new Map([
280
318
  ["lparen", "paren.l"],
281
319
  ["lParen", "paren.l.double"],
282
320
  ["rparen", "paren.r"],
@@ -287,6 +325,7 @@ var map_from_official_docs = new Map([
287
325
  ["lBrace", "brace.l.double"],
288
326
  ["rbrace", "brace.r"],
289
327
  ["rBrace", "brace.r.double"],
328
+ // ['overbrace', 'brace.t'],
290
329
  ["underbrace", "brace.b"],
291
330
  ["lbrack", "bracket.l"],
292
331
  ["lBrack", "bracket.l.double"],
@@ -367,6 +406,7 @@ var map_from_official_docs = new Map([
367
406
  ["mathquestion", "quest"],
368
407
  ["Question", "quest.double"],
369
408
  ["mathoctothorpe", "hash"],
409
+ // ['mathhyphen', 'hyph'],
370
410
  ["mathpercent", "percent"],
371
411
  ["mathparagraph", "pilcrow"],
372
412
  ["mathsection", "section"],
@@ -435,6 +475,8 @@ var map_from_official_docs = new Map([
435
475
  ["stareq", "eq.star"],
436
476
  ["circledequal", "eq.circle"],
437
477
  ["eqcolon", "eq.colon"],
478
+ // \usepackage{mathtools} defines \eqdef
479
+ // https://tex.stackexchange.com/questions/28836/typesetting-the-define-equals-symbol
438
480
  ["eqdef", "eq.def"],
439
481
  ["triangleq", "eq.delta"],
440
482
  ["veeeq", "eq.equi"],
@@ -936,6 +978,64 @@ var map_from_official_docs = new Map([
936
978
  ["barV", "tack.b.double"],
937
979
  ["shortdowntack", "tack.b.short"],
938
980
  ["dashVdash", "tack.l.r"],
981
+ /*
982
+ ['mupalpha', 'alpha'],
983
+ ['mupbeta', 'beta'],
984
+ ['mupchi', 'chi'],
985
+ ['mupdelta', 'delta'],
986
+ ['mupvarepsilon', 'epsilon'],
987
+ ['mupepsilon', 'epsilon.alt'],
988
+ ['mupeta', 'eta'],
989
+ ['mupgamma', 'gamma'],
990
+ ['mupiota', 'iota'],
991
+ ['mupkappa', 'kappa'],
992
+ ['mupvarkappa', 'kappa.alt'],
993
+ ['muplambda', 'lambda'],
994
+ ['mupmu', 'mu'],
995
+ ['mupnu', 'nu'],
996
+ ['mho', 'ohm.inv'],
997
+ ['mupomega', 'omega'],
998
+ ['mupomicron', 'omicron'],
999
+ ['mupvarphi', 'phi'],
1000
+ ['mupphi', 'phi.alt'],
1001
+ ['muppi', 'pi'],
1002
+ ['mupvarpi', 'pi.alt'],
1003
+ ['muppsi', 'psi'],
1004
+ ['muprho', 'rho'],
1005
+ ['mupvarrho', 'rho.alt'],
1006
+ ['mupsigma', 'sigma'],
1007
+ ['mupvarsigma', 'sigma.alt'],
1008
+ ['muptau', 'tau'],
1009
+ ['muptheta', 'theta'],
1010
+ ['mupvartheta', 'theta.alt'],
1011
+ ['mupupsilon', 'upsilon'],
1012
+ ['mupxi', 'xi'],
1013
+ ['mupzeta', 'zeta'],
1014
+ ['mupAlpha', 'Alpha'],
1015
+ ['mupBeta', 'Beta'],
1016
+ ['mupChi', 'Chi'],
1017
+ ['mupDelta', 'Delta'],
1018
+ ['mupEpsilon', 'Epsilon'],
1019
+ ['mupEta', 'Eta'],
1020
+ ['mupGamma', 'Gamma'],
1021
+ ['mupIota', 'Iota'],
1022
+ ['mupKappa', 'Kappa'],
1023
+ ['mupLambda', 'Lambda'],
1024
+ ['mupMu', 'Mu'],
1025
+ ['mupNu', 'Nu'],
1026
+ ['mupOmega', 'Omega'],
1027
+ ['mupOmicron', 'Omicron'],
1028
+ ['mupPhi', 'Phi'],
1029
+ ['mupPi', 'Pi'],
1030
+ ['mupPsi', 'Psi'],
1031
+ ['mupRho', 'Rho'],
1032
+ ['mupSigma', 'Sigma'],
1033
+ ['mupTau', 'Tau'],
1034
+ ['mupTheta', 'Theta'],
1035
+ ['mupUpsilon', 'Upsilon'],
1036
+ ['mupXi', 'Xi'],
1037
+ ['mupZeta', 'Zeta'],
1038
+ */
939
1039
  ["BbbA", "AA"],
940
1040
  ["BbbB", "BB"],
941
1041
  ["BbbC", "CC"],
@@ -976,12 +1076,12 @@ for (const [key, value] of map_from_official_docs) {
976
1076
  symbolMap.set(key, value);
977
1077
  }
978
1078
  }
979
- var reverseSymbolMap = new Map;
1079
+ var reverseSymbolMap = /* @__PURE__ */ new Map();
980
1080
  for (const [key, value] of Array.from(symbolMap.entries()).reverse()) {
981
1081
  reverseSymbolMap.set(value, key);
982
1082
  }
983
1083
  reverseSymbolMap.set("dif", "mathrm{d}");
984
- var typst_to_tex_map = new Map([
1084
+ var typst_to_tex_map = /* @__PURE__ */ new Map([
985
1085
  ["top", "top"],
986
1086
  ["frac", "frac"],
987
1087
  ["tilde", "tilde"],
@@ -996,7 +1096,7 @@ for (const [key, value] of typst_to_tex_map) {
996
1096
 
997
1097
  // src/generic.ts
998
1098
  function array_find(array, item, start = 0) {
999
- for (let i = start;i < array.length; i++) {
1099
+ for (let i = start; i < array.length; i++) {
1000
1100
  if (array[i].eq(item)) {
1001
1101
  return i;
1002
1102
  }
@@ -1027,9 +1127,7 @@ function array_split(array, sep) {
1027
1127
  }
1028
1128
 
1029
1129
  // src/types.ts
1030
- class TexToken {
1031
- type;
1032
- value;
1130
+ var TexToken = class {
1033
1131
  constructor(type, value) {
1034
1132
  this.type = type;
1035
1133
  this.value = value;
@@ -1047,25 +1145,21 @@ class TexToken {
1047
1145
  return this.value;
1048
1146
  }
1049
1147
  }
1050
- }
1148
+ };
1051
1149
  function apply_escape_if_needed(c) {
1052
1150
  if (["{", "}", "%"].includes(c)) {
1053
1151
  return "\\" + c;
1054
1152
  }
1055
1153
  return c;
1056
1154
  }
1057
-
1058
- class TexNode {
1059
- type;
1060
- content;
1061
- args;
1062
- data;
1155
+ var TexNode = class {
1063
1156
  constructor(type, content, args, data) {
1064
1157
  this.type = type;
1065
1158
  this.content = content;
1066
1159
  this.args = args;
1067
1160
  this.data = data;
1068
1161
  }
1162
+ // Note that this is only shallow equality.
1069
1163
  eq(other) {
1070
1164
  return this.type === other.type && this.content === other.content;
1071
1165
  }
@@ -1143,7 +1237,7 @@ class TexNode {
1143
1237
  return tokens;
1144
1238
  }
1145
1239
  case "supsub": {
1146
- let should_wrap_in_braces = function(node) {
1240
+ let should_wrap_in_braces2 = function(node) {
1147
1241
  if (node.type === "ordgroup" || node.type === "supsub" || node.type === "empty") {
1148
1242
  return true;
1149
1243
  } else if (node.type === "element" && /\d+(\.\d+)?/.test(node.content) && node.content.length > 1) {
@@ -1152,12 +1246,13 @@ class TexNode {
1152
1246
  return false;
1153
1247
  }
1154
1248
  };
1249
+ var should_wrap_in_braces = should_wrap_in_braces2;
1155
1250
  let tokens = [];
1156
1251
  const { base, sup, sub } = this.data;
1157
1252
  tokens = tokens.concat(base.serialize());
1158
1253
  if (sub) {
1159
1254
  tokens.push(new TexToken(6 /* CONTROL */, "_"));
1160
- if (should_wrap_in_braces(sub)) {
1255
+ if (should_wrap_in_braces2(sub)) {
1161
1256
  tokens.push(new TexToken(0 /* ELEMENT */, "{"));
1162
1257
  tokens = tokens.concat(sub.serialize());
1163
1258
  tokens.push(new TexToken(0 /* ELEMENT */, "}"));
@@ -1167,7 +1262,7 @@ class TexNode {
1167
1262
  }
1168
1263
  if (sup) {
1169
1264
  tokens.push(new TexToken(6 /* CONTROL */, "^"));
1170
- if (should_wrap_in_braces(sup)) {
1265
+ if (should_wrap_in_braces2(sup)) {
1171
1266
  tokens.push(new TexToken(0 /* ELEMENT */, "{"));
1172
1267
  tokens = tokens.concat(sup.serialize());
1173
1268
  tokens.push(new TexToken(0 /* ELEMENT */, "}"));
@@ -1184,11 +1279,10 @@ class TexNode {
1184
1279
  let tokens = [];
1185
1280
  const matrix = this.data;
1186
1281
  tokens.push(new TexToken(1 /* COMMAND */, `\\begin{${this.content}}`));
1187
- tokens.push(new TexToken(5 /* NEWLINE */, `
1188
- `));
1189
- for (let i = 0;i < matrix.length; i++) {
1282
+ tokens.push(new TexToken(5 /* NEWLINE */, "\n"));
1283
+ for (let i = 0; i < matrix.length; i++) {
1190
1284
  const row = matrix[i];
1191
- for (let j = 0;j < row.length; j++) {
1285
+ for (let j = 0; j < row.length; j++) {
1192
1286
  const cell = row[j];
1193
1287
  tokens = tokens.concat(cell.serialize());
1194
1288
  if (j !== row.length - 1) {
@@ -1199,8 +1293,7 @@ class TexNode {
1199
1293
  tokens.push(new TexToken(6 /* CONTROL */, "\\\\"));
1200
1294
  }
1201
1295
  }
1202
- tokens.push(new TexToken(5 /* NEWLINE */, `
1203
- `));
1296
+ tokens.push(new TexToken(5 /* NEWLINE */, "\n"));
1204
1297
  tokens.push(new TexToken(1 /* COMMAND */, `\\end{${this.content}}`));
1205
1298
  return tokens;
1206
1299
  }
@@ -1208,6 +1301,8 @@ class TexNode {
1208
1301
  throw new Error("[TexNode.serialize] Unimplemented type: " + this.type);
1209
1302
  }
1210
1303
  }
1304
+ // whether the node is over high so that if it's wrapped in braces, \left and \right should be used.
1305
+ // e.g. \frac{1}{2} is over high, "2" is not.
1211
1306
  isOverHigh() {
1212
1307
  switch (this.type) {
1213
1308
  case "element":
@@ -1220,6 +1315,7 @@ class TexNode {
1220
1315
  if (this.content === "\\frac") {
1221
1316
  return true;
1222
1317
  }
1318
+ // fall through
1223
1319
  case "unaryFunc":
1224
1320
  case "ordgroup":
1225
1321
  return this.args.some((n) => n.isOverHigh());
@@ -1232,10 +1328,8 @@ class TexNode {
1232
1328
  return false;
1233
1329
  }
1234
1330
  }
1235
- }
1236
- class TypstToken {
1237
- type;
1238
- value;
1331
+ };
1332
+ var TypstToken = class {
1239
1333
  constructor(type, content) {
1240
1334
  this.type = type;
1241
1335
  this.value = content;
@@ -1288,14 +1382,10 @@ class TypstToken {
1288
1382
  return this.value;
1289
1383
  }
1290
1384
  }
1291
- }
1292
-
1293
- class TypstNode {
1294
- type;
1295
- content;
1296
- args;
1297
- data;
1298
- options;
1385
+ };
1386
+ var TYPST_NONE = null;
1387
+ var TYPST_TRUE = true;
1388
+ var TypstNode = class {
1299
1389
  constructor(type, content, args, data) {
1300
1390
  this.type = type;
1301
1391
  this.content = content;
@@ -1305,10 +1395,11 @@ class TypstNode {
1305
1395
  setOptions(options) {
1306
1396
  this.options = options;
1307
1397
  }
1398
+ // Note that this is only shallow equality.
1308
1399
  eq(other) {
1309
1400
  return this.type === other.type && this.content === other.content;
1310
1401
  }
1311
- }
1402
+ };
1312
1403
 
1313
1404
  // src/util.ts
1314
1405
  function isalpha(char) {
@@ -1465,8 +1556,7 @@ function tokenize(latex) {
1465
1556
  switch (firstChar) {
1466
1557
  case "%": {
1467
1558
  let newPos = pos + 1;
1468
- while (newPos < latex.length && latex[newPos] !== `
1469
- `) {
1559
+ while (newPos < latex.length && latex[newPos] !== "\n") {
1470
1560
  newPos += 1;
1471
1561
  }
1472
1562
  token = new TexToken(3 /* COMMENT */, latex.slice(pos + 1, newPos));
@@ -1481,20 +1571,16 @@ function tokenize(latex) {
1481
1571
  token = new TexToken(6 /* CONTROL */, firstChar);
1482
1572
  pos++;
1483
1573
  break;
1484
- case `
1485
- `:
1574
+ case "\n":
1486
1575
  token = new TexToken(5 /* NEWLINE */, firstChar);
1487
1576
  pos++;
1488
1577
  break;
1489
1578
  case "\r": {
1490
- if (pos + 1 < latex.length && latex[pos + 1] === `
1491
- `) {
1492
- token = new TexToken(5 /* NEWLINE */, `
1493
- `);
1579
+ if (pos + 1 < latex.length && latex[pos + 1] === "\n") {
1580
+ token = new TexToken(5 /* NEWLINE */, "\n");
1494
1581
  pos += 2;
1495
1582
  } else {
1496
- token = new TexToken(5 /* NEWLINE */, `
1497
- `);
1583
+ token = new TexToken(5 /* NEWLINE */, "\n");
1498
1584
  pos++;
1499
1585
  }
1500
1586
  break;
@@ -1561,61 +1647,51 @@ function tokenize(latex) {
1561
1647
  }
1562
1648
  return tokens;
1563
1649
  }
1564
-
1565
- class LatexParserError extends Error {
1650
+ var LatexParserError = class extends Error {
1566
1651
  constructor(message) {
1567
1652
  super(message);
1568
1653
  this.name = "LatexParserError";
1569
1654
  }
1570
- }
1655
+ };
1571
1656
  var SUB_SYMBOL = new TexToken(6 /* CONTROL */, "_");
1572
1657
  var SUP_SYMBOL = new TexToken(6 /* CONTROL */, "^");
1573
-
1574
- class LatexParser {
1575
- space_sensitive;
1576
- newline_sensitive;
1658
+ var LatexParser = class {
1577
1659
  constructor(space_sensitive = false, newline_sensitive = true) {
1578
1660
  this.space_sensitive = space_sensitive;
1579
1661
  this.newline_sensitive = newline_sensitive;
1580
1662
  }
1581
1663
  parse(tokens) {
1664
+ const [tree, _] = this.parseGroup(tokens, 0, tokens.length);
1665
+ return tree;
1666
+ }
1667
+ parseGroup(tokens, start, end) {
1582
1668
  const results = [];
1583
- let pos = 0;
1584
- while (pos < tokens.length) {
1585
- const results2 = [];
1586
- let pos2 = 0;
1587
- while (pos2 < tokens.length) {
1588
- const [res, newPos] = this.parseNextExpr(tokens, pos2);
1589
- pos2 = newPos;
1590
- if (res.type === "whitespace") {
1591
- if (!this.space_sensitive && res.content.replace(/ /g, "").length === 0) {
1592
- continue;
1593
- }
1594
- if (!this.newline_sensitive && res.content === `
1595
- `) {
1596
- continue;
1597
- }
1669
+ let pos = start;
1670
+ while (pos < end) {
1671
+ const [res, newPos] = this.parseNextExpr(tokens, pos);
1672
+ pos = newPos;
1673
+ if (res.type === "whitespace") {
1674
+ if (!this.space_sensitive && res.content.replace(/ /g, "").length === 0) {
1675
+ continue;
1598
1676
  }
1599
- if (res.type === "control" && res.content === "&") {
1600
- throw new LatexParserError("Unexpected & outside of an alignment");
1677
+ if (!this.newline_sensitive && res.content === "\n") {
1678
+ continue;
1601
1679
  }
1602
- results2.push(res);
1603
1680
  }
1604
- if (results2.length === 0) {
1605
- return EMPTY_NODE;
1606
- } else if (results2.length === 1) {
1607
- return results2[0];
1608
- } else {
1609
- return new TexNode("ordgroup", "", results2);
1681
+ if (res.type === "control" && res.content === "&") {
1682
+ throw new LatexParserError("Unexpected & outside of an alignment");
1610
1683
  }
1684
+ results.push(res);
1611
1685
  }
1686
+ let node;
1612
1687
  if (results.length === 0) {
1613
- return EMPTY_NODE;
1688
+ node = EMPTY_NODE;
1614
1689
  } else if (results.length === 1) {
1615
- return results[0];
1690
+ node = results[0];
1616
1691
  } else {
1617
- return new TexNode("ordgroup", "", results);
1692
+ node = new TexNode("ordgroup", "", results);
1618
1693
  }
1694
+ return [node, end + 1];
1619
1695
  }
1620
1696
  parseNextExpr(tokens, start) {
1621
1697
  let [base, pos] = this.parseNextExprWithoutSupSub(tokens, start);
@@ -1653,7 +1729,7 @@ class LatexParser {
1653
1729
  }
1654
1730
  if (num_prime > 0) {
1655
1731
  res.sup = new TexNode("ordgroup", "", []);
1656
- for (let i = 0;i < num_prime; i++) {
1732
+ for (let i = 0; i < num_prime; i++) {
1657
1733
  res.sup.args.push(new TexNode("element", "'"));
1658
1734
  }
1659
1735
  if (sup) {
@@ -1672,8 +1748,7 @@ class LatexParser {
1672
1748
  }
1673
1749
  parseNextExprWithoutSupSub(tokens, start) {
1674
1750
  const firstToken = tokens[start];
1675
- const tokenType = firstToken.type;
1676
- switch (tokenType) {
1751
+ switch (firstToken.type) {
1677
1752
  case 0 /* ELEMENT */:
1678
1753
  return [new TexNode("element", firstToken.value), start + 1];
1679
1754
  case 2 /* TEXT */:
@@ -1699,8 +1774,7 @@ class LatexParser {
1699
1774
  if (posClosingBracket === -1) {
1700
1775
  throw new LatexParserError("Unmatched '{'");
1701
1776
  }
1702
- const exprInside = tokens.slice(start + 1, posClosingBracket);
1703
- return [this.parse(exprInside), posClosingBracket + 1];
1777
+ return this.parseGroup(tokens, start + 1, posClosingBracket);
1704
1778
  case "}":
1705
1779
  throw new LatexParserError("Unmatched '}'");
1706
1780
  case "\\\\":
@@ -1743,8 +1817,7 @@ class LatexParser {
1743
1817
  if (posRightSquareBracket === -1) {
1744
1818
  throw new LatexParserError("No matching right square bracket for [");
1745
1819
  }
1746
- const exprInside = tokens.slice(posLeftSquareBracket + 1, posRightSquareBracket);
1747
- const exponent = this.parse(exprInside);
1820
+ const [exponent, _] = this.parseGroup(tokens, posLeftSquareBracket + 1, posRightSquareBracket);
1748
1821
  const [arg12, newPos2] = this.parseNextExprWithoutSupSub(tokens, posRightSquareBracket + 1);
1749
1822
  return [new TexNode("unaryFunc", command, [arg12], exponent), newPos2];
1750
1823
  } else if (command === "\\text") {
@@ -1797,8 +1870,7 @@ class LatexParser {
1797
1870
  throw new LatexParserError("Invalid delimiter after \\right");
1798
1871
  }
1799
1872
  pos++;
1800
- const exprInside = tokens.slice(exprInsideStart, exprInsideEnd);
1801
- const body = this.parse(exprInside);
1873
+ const [body, _] = this.parseGroup(tokens, exprInsideStart, exprInsideEnd);
1802
1874
  const args = [
1803
1875
  new TexNode("element", leftDelimiter.value),
1804
1876
  body,
@@ -1852,8 +1924,7 @@ class LatexParser {
1852
1924
  if (!this.space_sensitive && res.content.replace(/ /g, "").length === 0) {
1853
1925
  continue;
1854
1926
  }
1855
- if (!this.newline_sensitive && res.content === `
1856
- `) {
1927
+ if (!this.newline_sensitive && res.content === "\n") {
1857
1928
  continue;
1858
1929
  }
1859
1930
  }
@@ -1871,11 +1942,11 @@ class LatexParser {
1871
1942
  }
1872
1943
  return allRows;
1873
1944
  }
1874
- }
1945
+ };
1875
1946
  function passIgnoreWhitespaceBeforeScriptMark(tokens) {
1876
1947
  const is_script_mark = (token) => token.eq(SUB_SYMBOL) || token.eq(SUP_SYMBOL);
1877
1948
  let out_tokens = [];
1878
- for (let i = 0;i < tokens.length; i++) {
1949
+ for (let i = 0; i < tokens.length; i++) {
1879
1950
  if (tokens[i].type === 4 /* SPACE */ && i + 1 < tokens.length && is_script_mark(tokens[i + 1])) {
1880
1951
  continue;
1881
1952
  }
@@ -1899,7 +1970,7 @@ function passExpandCustomTexMacros(tokens, customTexMacros) {
1899
1970
  return out_tokens;
1900
1971
  }
1901
1972
  function parseTex(tex, customTexMacros) {
1902
- const parser = new LatexParser;
1973
+ const parser = new LatexParser();
1903
1974
  let tokens = tokenize(tex);
1904
1975
  tokens = passIgnoreWhitespaceBeforeScriptMark(tokens);
1905
1976
  tokens = passExpandCustomTexMacros(tokens, customTexMacros);
@@ -1915,33 +1986,42 @@ var TYPST_INTRINSIC_SYMBOLS = [
1915
1986
  "Pr",
1916
1987
  "sech",
1917
1988
  "csch"
1989
+ // 'sgn
1918
1990
  ];
1919
1991
  function is_delimiter(c) {
1920
- return c.type === "atom" && ["(", ")", "[", "]", "{", "}", "|", "", "", "", ""].includes(c.content);
1992
+ return c.type === "atom" && ["(", ")", "[", "]", "{", "}", "|", "\u230A", "\u230B", "\u2308", "\u2309"].includes(c.content);
1921
1993
  }
1922
1994
  var TYPST_LEFT_PARENTHESIS = new TypstToken(1 /* ELEMENT */, "(");
1923
1995
  var TYPST_RIGHT_PARENTHESIS = new TypstToken(1 /* ELEMENT */, ")");
1924
1996
  var TYPST_COMMA = new TypstToken(1 /* ELEMENT */, ",");
1925
- var TYPST_NEWLINE = new TypstToken(0 /* SYMBOL */, `
1926
- `);
1927
-
1928
- class TypstWriterError extends Error {
1929
- node;
1997
+ var TYPST_NEWLINE = new TypstToken(0 /* SYMBOL */, "\n");
1998
+ function typst_primitive_to_string(value) {
1999
+ switch (typeof value) {
2000
+ case "string":
2001
+ return `"${value}"`;
2002
+ case "number":
2003
+ return value.toString();
2004
+ case "boolean":
2005
+ return value ? "#true" : "#false";
2006
+ default:
2007
+ if (value === null) {
2008
+ return "#none";
2009
+ }
2010
+ throw new TypstWriterError(`Invalid primitive value: ${value}`, value);
2011
+ }
2012
+ }
2013
+ var TypstWriterError = class extends Error {
1930
2014
  constructor(message, node) {
1931
2015
  super(message);
1932
2016
  this.name = "TypstWriterError";
1933
2017
  this.node = node;
1934
2018
  }
1935
- }
1936
-
1937
- class TypstWriter {
1938
- nonStrict;
1939
- preferTypstIntrinsic;
1940
- keepSpaces;
1941
- buffer = "";
1942
- queue = [];
1943
- insideFunctionDepth = 0;
2019
+ };
2020
+ var TypstWriter = class {
1944
2021
  constructor(nonStrict, preferTypstIntrinsic, keepSpaces) {
2022
+ this.buffer = "";
2023
+ this.queue = [];
2024
+ this.insideFunctionDepth = 0;
1945
2025
  this.nonStrict = nonStrict;
1946
2026
  this.preferTypstIntrinsic = preferTypstIntrinsic;
1947
2027
  this.keepSpaces = keepSpaces;
@@ -1959,8 +2039,7 @@ class TypstWriter {
1959
2039
  no_need_space ||= str === "'";
1960
2040
  no_need_space ||= /[0-9]$/.test(this.buffer) && /^[0-9]/.test(str);
1961
2041
  no_need_space ||= /[\(\[{]\s*(-|\+)$/.test(this.buffer) || this.buffer === "-" || this.buffer === "+";
1962
- no_need_space ||= str.startsWith(`
1963
- `);
2042
+ no_need_space ||= str.startsWith("\n");
1964
2043
  no_need_space ||= this.buffer === "";
1965
2044
  no_need_space ||= /^\s/.test(str);
1966
2045
  no_need_space ||= this.buffer.endsWith("&") && str === "=";
@@ -1971,6 +2050,7 @@ class TypstWriter {
1971
2050
  }
1972
2051
  this.buffer += str;
1973
2052
  }
2053
+ // Serialize a tree of TypstNode into a list of TypstToken
1974
2054
  serialize(node) {
1975
2055
  switch (node.type) {
1976
2056
  case "empty":
@@ -1998,8 +2078,7 @@ class TypstWriter {
1998
2078
  if (this.keepSpaces) {
1999
2079
  this.queue.push(new TypstToken(4 /* SPACE */, c));
2000
2080
  }
2001
- } else if (c === `
2002
- `) {
2081
+ } else if (c === "\n") {
2003
2082
  this.queue.push(new TypstToken(0 /* SYMBOL */, c));
2004
2083
  } else {
2005
2084
  throw new TypstWriterError(`Unexpected whitespace character: ${c}`, node);
@@ -2038,7 +2117,7 @@ class TypstWriter {
2038
2117
  this.queue.push(func_symbol);
2039
2118
  this.insideFunctionDepth++;
2040
2119
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2041
- for (let i = 0;i < node.args.length; i++) {
2120
+ for (let i = 0; i < node.args.length; i++) {
2042
2121
  this.serialize(node.args[i]);
2043
2122
  if (i < node.args.length - 1) {
2044
2123
  this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
@@ -2046,7 +2125,8 @@ class TypstWriter {
2046
2125
  }
2047
2126
  if (node.options) {
2048
2127
  for (const [key, value] of Object.entries(node.options)) {
2049
- this.queue.push(new TypstToken(0 /* SYMBOL */, `, ${key}: ${value}`));
2128
+ const value_str = typst_primitive_to_string(value);
2129
+ this.queue.push(new TypstToken(0 /* SYMBOL */, `, ${key}: ${value_str}`));
2050
2130
  }
2051
2131
  }
2052
2132
  this.queue.push(TYPST_RIGHT_PARENTHESIS);
@@ -2094,7 +2174,8 @@ class TypstWriter {
2094
2174
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2095
2175
  if (node.options) {
2096
2176
  for (const [key, value] of Object.entries(node.options)) {
2097
- this.queue.push(new TypstToken(0 /* SYMBOL */, `${key}: ${value}, `));
2177
+ const value_str = typst_primitive_to_string(value);
2178
+ this.queue.push(new TypstToken(0 /* SYMBOL */, `${key}: ${value_str}, `));
2098
2179
  }
2099
2180
  }
2100
2181
  matrix.forEach((row, i) => {
@@ -2145,7 +2226,7 @@ class TypstWriter {
2145
2226
  }
2146
2227
  flushQueue() {
2147
2228
  const SOFT_SPACE = new TypstToken(6 /* CONTROL */, " ");
2148
- for (let i = 0;i < this.queue.length; i++) {
2229
+ for (let i = 0; i < this.queue.length; i++) {
2149
2230
  let token = this.queue[i];
2150
2231
  if (token.eq(SOFT_SPACE)) {
2151
2232
  if (i === this.queue.length - 1) {
@@ -2183,7 +2264,7 @@ class TypstWriter {
2183
2264
  }
2184
2265
  return this.buffer;
2185
2266
  }
2186
- }
2267
+ };
2187
2268
 
2188
2269
  // src/convert.ts
2189
2270
  function tex_token_to_typst(token) {
@@ -2228,12 +2309,21 @@ function convert_overset(node, options) {
2228
2309
  if (is_def(sup) && is_eq(base)) {
2229
2310
  return new TypstNode("symbol", "eq.def");
2230
2311
  }
2231
- const op_call = new TypstNode("funcCall", "op", [convert_tex_node_to_typst(base, options)]);
2232
- op_call.setOptions({ limits: "#true" });
2233
- return new TypstNode("supsub", "", [], {
2234
- base: op_call,
2235
- sup: convert_tex_node_to_typst(sup, options)
2236
- });
2312
+ const op_call = new TypstNode(
2313
+ "funcCall",
2314
+ "op",
2315
+ [convert_tex_node_to_typst(base, options)]
2316
+ );
2317
+ op_call.setOptions({ limits: TYPST_TRUE });
2318
+ return new TypstNode(
2319
+ "supsub",
2320
+ "",
2321
+ [],
2322
+ {
2323
+ base: op_call,
2324
+ sup: convert_tex_node_to_typst(sup, options)
2325
+ }
2326
+ );
2237
2327
  }
2238
2328
  function convert_tex_node_to_typst(node, options = {}) {
2239
2329
  switch (node.type) {
@@ -2242,7 +2332,11 @@ function convert_tex_node_to_typst(node, options = {}) {
2242
2332
  case "whitespace":
2243
2333
  return new TypstNode("whitespace", node.content);
2244
2334
  case "ordgroup":
2245
- return new TypstNode("group", "", node.args.map((n) => convert_tex_node_to_typst(n, options)));
2335
+ return new TypstNode(
2336
+ "group",
2337
+ "",
2338
+ node.args.map((n) => convert_tex_node_to_typst(n, options))
2339
+ );
2246
2340
  case "element":
2247
2341
  return new TypstNode("atom", tex_token_to_typst(node.content));
2248
2342
  case "symbol":
@@ -2254,9 +2348,17 @@ function convert_tex_node_to_typst(node, options = {}) {
2254
2348
  case "supsub": {
2255
2349
  let { base, sup, sub } = node.data;
2256
2350
  if (base && base.type === "unaryFunc" && base.content === "\\overbrace" && sup) {
2257
- return new TypstNode("funcCall", "overbrace", [convert_tex_node_to_typst(base.args[0], options), convert_tex_node_to_typst(sup, options)]);
2351
+ return new TypstNode(
2352
+ "funcCall",
2353
+ "overbrace",
2354
+ [convert_tex_node_to_typst(base.args[0], options), convert_tex_node_to_typst(sup, options)]
2355
+ );
2258
2356
  } else if (base && base.type === "unaryFunc" && base.content === "\\underbrace" && sub) {
2259
- return new TypstNode("funcCall", "underbrace", [convert_tex_node_to_typst(base.args[0], options), convert_tex_node_to_typst(sub, options)]);
2357
+ return new TypstNode(
2358
+ "funcCall",
2359
+ "underbrace",
2360
+ [convert_tex_node_to_typst(base.args[0], options), convert_tex_node_to_typst(sub, options)]
2361
+ );
2260
2362
  }
2261
2363
  const data = {
2262
2364
  base: convert_tex_node_to_typst(base, options)
@@ -2274,7 +2376,11 @@ function convert_tex_node_to_typst(node, options = {}) {
2274
2376
  }
2275
2377
  case "leftright": {
2276
2378
  const [left, body, right] = node.args;
2277
- const group = new TypstNode("group", "", node.args.map((n) => convert_tex_node_to_typst(n, options)));
2379
+ const group = new TypstNode(
2380
+ "group",
2381
+ "",
2382
+ node.args.map((n) => convert_tex_node_to_typst(n, options))
2383
+ );
2278
2384
  if ([
2279
2385
  "[]",
2280
2386
  "()",
@@ -2292,7 +2398,11 @@ function convert_tex_node_to_typst(node, options = {}) {
2292
2398
  group.args.shift();
2293
2399
  return new TypstNode("funcCall", "lr", [group]);
2294
2400
  }
2295
- return new TypstNode("funcCall", "lr", [group]);
2401
+ return new TypstNode(
2402
+ "funcCall",
2403
+ "lr",
2404
+ [group]
2405
+ );
2296
2406
  }
2297
2407
  case "binaryFunc": {
2298
2408
  if (node.content === "\\overset") {
@@ -2300,20 +2410,40 @@ function convert_tex_node_to_typst(node, options = {}) {
2300
2410
  }
2301
2411
  if (node.content === "\\frac") {
2302
2412
  if (options.fracToSlash) {
2303
- return new TypstNode("fraction", "", node.args.map((n) => convert_tex_node_to_typst(n, options)));
2413
+ return new TypstNode(
2414
+ "fraction",
2415
+ "",
2416
+ node.args.map((n) => convert_tex_node_to_typst(n, options))
2417
+ );
2304
2418
  }
2305
2419
  }
2306
- return new TypstNode("funcCall", tex_token_to_typst(node.content), node.args.map((n) => convert_tex_node_to_typst(n, options)));
2420
+ return new TypstNode(
2421
+ "funcCall",
2422
+ tex_token_to_typst(node.content),
2423
+ node.args.map((n) => convert_tex_node_to_typst(n, options))
2424
+ );
2307
2425
  }
2308
2426
  case "unaryFunc": {
2309
2427
  const arg0 = convert_tex_node_to_typst(node.args[0], options);
2310
2428
  if (node.content === "\\sqrt" && node.data) {
2311
2429
  const data = convert_tex_node_to_typst(node.data, options);
2312
- return new TypstNode("funcCall", "root", [data, arg0]);
2430
+ return new TypstNode(
2431
+ "funcCall",
2432
+ "root",
2433
+ [data, arg0]
2434
+ );
2313
2435
  }
2314
2436
  if (node.content === "\\mathbf") {
2315
- const inner = new TypstNode("funcCall", "bold", [arg0]);
2316
- return new TypstNode("funcCall", "upright", [inner]);
2437
+ const inner = new TypstNode(
2438
+ "funcCall",
2439
+ "bold",
2440
+ [arg0]
2441
+ );
2442
+ return new TypstNode(
2443
+ "funcCall",
2444
+ "upright",
2445
+ [inner]
2446
+ );
2317
2447
  }
2318
2448
  if (node.content === "\\mathbb" && arg0.type === "atom" && /^[A-Z]$/.test(arg0.content)) {
2319
2449
  return new TypstNode("symbol", arg0.content + arg0.content);
@@ -2327,21 +2457,61 @@ function convert_tex_node_to_typst(node, options = {}) {
2327
2457
  if (TYPST_INTRINSIC_SYMBOLS.includes(text)) {
2328
2458
  return new TypstNode("symbol", text);
2329
2459
  } else {
2330
- return new TypstNode("funcCall", "op", [new TypstNode("text", text)]);
2460
+ return new TypstNode(
2461
+ "funcCall",
2462
+ "op",
2463
+ [new TypstNode("text", text)]
2464
+ );
2331
2465
  }
2332
2466
  }
2333
- return new TypstNode("funcCall", tex_token_to_typst(node.content), node.args.map((n) => convert_tex_node_to_typst(n, options)));
2467
+ return new TypstNode(
2468
+ "funcCall",
2469
+ tex_token_to_typst(node.content),
2470
+ node.args.map((n) => convert_tex_node_to_typst(n, options))
2471
+ );
2334
2472
  }
2335
2473
  case "beginend": {
2336
2474
  const matrix = node.data;
2337
2475
  const data = matrix.map((row) => row.map((n) => convert_tex_node_to_typst(n, options)));
2338
2476
  if (node.content.startsWith("align")) {
2339
2477
  return new TypstNode("align", "", [], data);
2340
- } else {
2478
+ }
2479
+ if (node.content.endsWith("matrix")) {
2480
+ let delim = null;
2481
+ switch (node.content) {
2482
+ case "matrix":
2483
+ delim = TYPST_NONE;
2484
+ break;
2485
+ case "pmatrix":
2486
+ delim = "(";
2487
+ break;
2488
+ case "bmatrix":
2489
+ delim = "[";
2490
+ break;
2491
+ case "Bmatrix":
2492
+ delim = "{";
2493
+ break;
2494
+ case "vmatrix":
2495
+ delim = "|";
2496
+ break;
2497
+ case "Vmatrix": {
2498
+ const matrix2 = new TypstNode("matrix", "", [], data);
2499
+ matrix2.setOptions({ "delim": TYPST_NONE });
2500
+ const group = new TypstNode("group", "", [
2501
+ new TypstNode("symbol", "||"),
2502
+ matrix2,
2503
+ new TypstNode("symbol", "||")
2504
+ ]);
2505
+ return new TypstNode("funcCall", "lr", [group]);
2506
+ }
2507
+ default:
2508
+ throw new TypstWriterError(`Unimplemented beginend: ${node.content}`, node);
2509
+ }
2341
2510
  const res = new TypstNode("matrix", "", [], data);
2342
- res.setOptions({ delim: "#none" });
2511
+ res.setOptions({ "delim": delim });
2343
2512
  return res;
2344
2513
  }
2514
+ throw new TypstWriterError(`Unimplemented beginend: ${node.content}`, node);
2345
2515
  }
2346
2516
  case "unknownMacro":
2347
2517
  return new TypstNode("unknown", tex_token_to_typst(node.content));
@@ -2413,8 +2583,10 @@ function convert_typst_node_to_tex(node) {
2413
2583
  return new TexNode("element", node.content);
2414
2584
  case "symbol":
2415
2585
  switch (node.content) {
2586
+ // special hook for comma
2416
2587
  case "comma":
2417
2588
  return new TexNode("element", ",");
2589
+ // special hook for hyph and hyph.minus
2418
2590
  case "hyph":
2419
2591
  case "hyph.minus":
2420
2592
  return new TexNode("text", "-");
@@ -2498,7 +2670,7 @@ function convert_typst_node_to_tex(node) {
2498
2670
  if (node.options) {
2499
2671
  if ("delim" in node.options) {
2500
2672
  switch (node.options.delim) {
2501
- case "#none":
2673
+ case TYPST_NONE:
2502
2674
  return matrix;
2503
2675
  case "[":
2504
2676
  left_delim = "\\left[";
@@ -2587,20 +2759,16 @@ function tokenize_typst(typst) {
2587
2759
  token = new TypstToken(6 /* CONTROL */, firstChar);
2588
2760
  pos++;
2589
2761
  break;
2590
- case `
2591
- `:
2762
+ case "\n":
2592
2763
  token = new TypstToken(7 /* NEWLINE */, firstChar);
2593
2764
  pos++;
2594
2765
  break;
2595
2766
  case "\r": {
2596
- if (pos + 1 < typst.length && typst[pos + 1] === `
2597
- `) {
2598
- token = new TypstToken(7 /* NEWLINE */, `
2599
- `);
2767
+ if (pos + 1 < typst.length && typst[pos + 1] === "\n") {
2768
+ token = new TypstToken(7 /* NEWLINE */, "\n");
2600
2769
  pos += 2;
2601
2770
  } else {
2602
- token = new TypstToken(7 /* NEWLINE */, `
2603
- `);
2771
+ token = new TypstToken(7 /* NEWLINE */, "\n");
2604
2772
  pos++;
2605
2773
  }
2606
2774
  break;
@@ -2617,8 +2785,7 @@ function tokenize_typst(typst) {
2617
2785
  case "/": {
2618
2786
  if (pos < typst.length && typst[pos + 1] === "/") {
2619
2787
  let newPos = pos + 2;
2620
- while (newPos < typst.length && typst[newPos] !== `
2621
- `) {
2788
+ while (newPos < typst.length && typst[newPos] !== "\n") {
2622
2789
  newPos++;
2623
2790
  }
2624
2791
  token = new TypstToken(3 /* COMMENT */, typst.slice(pos + 2, newPos));
@@ -2730,7 +2897,7 @@ function find_closing_parenthesis(nodes, start) {
2730
2897
  }
2731
2898
  function primes(num) {
2732
2899
  const res = [];
2733
- for (let i = 0;i < num; i++) {
2900
+ for (let i = 0; i < num; i++) {
2734
2901
  res.push(new TypstNode("atom", "'"));
2735
2902
  }
2736
2903
  return res;
@@ -2746,7 +2913,7 @@ function next_non_whitespace(nodes, start) {
2746
2913
  function trim_whitespace_around_operators(nodes) {
2747
2914
  let after_operator = false;
2748
2915
  const res = [];
2749
- for (let i = 0;i < nodes.length; i++) {
2916
+ for (let i = 0; i < nodes.length; i++) {
2750
2917
  const current = nodes[i];
2751
2918
  if (current.type === "whitespace") {
2752
2919
  if (after_operator) {
@@ -2820,13 +2987,12 @@ function process_operators(nodes, parenthesis = false) {
2820
2987
  }
2821
2988
  }
2822
2989
  }
2823
-
2824
- class TypstParserError extends Error {
2990
+ var TypstParserError = class extends Error {
2825
2991
  constructor(message) {
2826
2992
  super(message);
2827
2993
  this.name = "TypstParserError";
2828
2994
  }
2829
- }
2995
+ };
2830
2996
  var SUB_SYMBOL2 = new TypstToken(6 /* CONTROL */, "_");
2831
2997
  var SUP_SYMBOL2 = new TypstToken(6 /* CONTROL */, "^");
2832
2998
  var LEFT_PARENTHESES = new TypstToken(1 /* ELEMENT */, "(");
@@ -2838,10 +3004,7 @@ var RIGHT_CURLY_BRACKET2 = new TypstToken(1 /* ELEMENT */, "}");
2838
3004
  var COMMA = new TypstToken(1 /* ELEMENT */, ",");
2839
3005
  var SEMICOLON = new TypstToken(1 /* ELEMENT */, ";");
2840
3006
  var SINGLE_SPACE = new TypstToken(4 /* SPACE */, " ");
2841
-
2842
- class TypstParser {
2843
- space_sensitive;
2844
- newline_sensitive;
3007
+ var TypstParser = class {
2845
3008
  constructor(space_sensitive = true, newline_sensitive = true) {
2846
3009
  this.space_sensitive = space_sensitive;
2847
3010
  this.newline_sensitive = newline_sensitive;
@@ -2860,8 +3023,7 @@ class TypstParser {
2860
3023
  if (!this.space_sensitive && res.content.replace(/ /g, "").length === 0) {
2861
3024
  continue;
2862
3025
  }
2863
- if (!this.newline_sensitive && res.content === `
2864
- `) {
3026
+ if (!this.newline_sensitive && res.content === "\n") {
2865
3027
  continue;
2866
3028
  }
2867
3029
  }
@@ -2956,10 +3118,12 @@ class TypstParser {
2956
3118
  }
2957
3119
  return [node, start + 1];
2958
3120
  }
3121
+ // start: the position of the left parentheses
2959
3122
  parseArguments(tokens, start) {
2960
3123
  const end = find_closing_match2(tokens, start);
2961
3124
  return [this.parseCommaSeparatedArguments(tokens, start + 1, end), end + 1];
2962
3125
  }
3126
+ // start: the position of the left parentheses
2963
3127
  parseGroupsOfArguments(tokens, start) {
2964
3128
  const end = find_closing_match2(tokens, start);
2965
3129
  tokens = tokens.slice(0, end);
@@ -2968,11 +3132,11 @@ class TypstParser {
2968
3132
  let pos = start + 1;
2969
3133
  while (pos < end) {
2970
3134
  while (pos < end) {
2971
- let extract_named_params = function(arr) {
3135
+ let extract_named_params2 = function(arr) {
2972
3136
  const COLON = new TypstNode("atom", ":");
2973
3137
  const np2 = {};
2974
3138
  const to_delete = [];
2975
- for (let i = 0;i < arr.length; i++) {
3139
+ for (let i = 0; i < arr.length; i++) {
2976
3140
  if (arr[i].type !== "group") {
2977
3141
  continue;
2978
3142
  }
@@ -2993,7 +3157,7 @@ class TypstParser {
2993
3157
  if (g.args.length !== 4 || !g.args[pos_colon + 2].eq(new TypstNode("symbol", "none"))) {
2994
3158
  throw new TypstParserError("Invalid number of arguments for delim");
2995
3159
  }
2996
- np2["delim"] = "#none";
3160
+ np2["delim"] = TYPST_NONE;
2997
3161
  } else {
2998
3162
  throw new TypstParserError("Not implemented for other types of delim");
2999
3163
  }
@@ -3001,18 +3165,19 @@ class TypstParser {
3001
3165
  throw new TypstParserError("Not implemented for other named parameters");
3002
3166
  }
3003
3167
  }
3004
- for (let i = to_delete.length - 1;i >= 0; i--) {
3168
+ for (let i = to_delete.length - 1; i >= 0; i--) {
3005
3169
  arr.splice(to_delete[i], 1);
3006
3170
  }
3007
3171
  return [arr, np2];
3008
3172
  };
3173
+ var extract_named_params = extract_named_params2;
3009
3174
  let next_stop = array_find(tokens, SEMICOLON, pos);
3010
3175
  if (next_stop === -1) {
3011
3176
  next_stop = end;
3012
3177
  }
3013
3178
  let row = this.parseCommaSeparatedArguments(tokens, pos, next_stop);
3014
3179
  let np = {};
3015
- [row, np] = extract_named_params(row);
3180
+ [row, np] = extract_named_params2(row);
3016
3181
  matrix.push(row);
3017
3182
  Object.assign(named_params, np);
3018
3183
  pos = next_stop + 1;
@@ -3020,6 +3185,7 @@ class TypstParser {
3020
3185
  }
3021
3186
  return [matrix, named_params, end + 1];
3022
3187
  }
3188
+ // start: the position of the first token of arguments
3023
3189
  parseCommaSeparatedArguments(tokens, start, end) {
3024
3190
  const args = [];
3025
3191
  let pos = start;
@@ -3046,17 +3212,19 @@ class TypstParser {
3046
3212
  }
3047
3213
  return args;
3048
3214
  }
3049
- }
3215
+ };
3050
3216
  function parseTypst(typst) {
3051
- const parser = new TypstParser;
3217
+ const parser = new TypstParser();
3052
3218
  let tokens = tokenize_typst(typst);
3053
3219
  return parser.parse(tokens);
3054
3220
  }
3055
3221
 
3056
3222
  // src/tex-writer.ts
3057
- class TexWriter {
3058
- buffer = "";
3059
- queue = [];
3223
+ var TexWriter = class {
3224
+ constructor() {
3225
+ this.buffer = "";
3226
+ this.queue = [];
3227
+ }
3060
3228
  writeBuffer(token) {
3061
3229
  const str = token.toString();
3062
3230
  let no_need_space = false;
@@ -3095,7 +3263,7 @@ class TexWriter {
3095
3263
  this.queue = this.queue.concat(node.serialize());
3096
3264
  }
3097
3265
  flushQueue() {
3098
- for (let i = 0;i < this.queue.length; i++) {
3266
+ for (let i = 0; i < this.queue.length; i++) {
3099
3267
  this.writeBuffer(this.queue[i]);
3100
3268
  }
3101
3269
  this.queue = [];
@@ -3104,7 +3272,7 @@ class TexWriter {
3104
3272
  this.flushQueue();
3105
3273
  return this.buffer;
3106
3274
  }
3107
- }
3275
+ };
3108
3276
 
3109
3277
  // src/index.ts
3110
3278
  function tex2typst(tex, options) {
@@ -3125,7 +3293,7 @@ function tex2typst(tex, options) {
3125
3293
  if (options.customTexMacros) {
3126
3294
  opt.customTexMacros = options.customTexMacros;
3127
3295
  }
3128
- if (options.fracToSlash !== undefined) {
3296
+ if (options.fracToSlash !== void 0) {
3129
3297
  opt.fracToSlash = options.fracToSlash;
3130
3298
  }
3131
3299
  }
@@ -3138,12 +3306,12 @@ function tex2typst(tex, options) {
3138
3306
  function typst2tex(typst) {
3139
3307
  const typstTree = parseTypst(typst);
3140
3308
  const texTree = convert_typst_node_to_tex(typstTree);
3141
- const writer = new TexWriter;
3309
+ const writer = new TexWriter();
3142
3310
  writer.append(texTree);
3143
3311
  return writer.finalize();
3144
3312
  }
3145
3313
  export {
3146
- typst2tex,
3314
+ symbolMap,
3147
3315
  tex2typst,
3148
- symbolMap
3316
+ typst2tex
3149
3317
  };