tex2typst 0.3.10 → 0.3.12

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/README.md CHANGED
@@ -32,7 +32,7 @@ Replace `0.3.0` with the latest version number in case this README is outdated.
32
32
  ```javascript
33
33
  import { tex2typst, typst2tex } from 'tex2typst';
34
34
 
35
- let tex = "e \overset{\text{def}}{=} \lim_{{n \to \infty}} \left(1 + \frac{1}{n}\right)^n";
35
+ let tex = "e \\overset{\\text{def}}{=} \\lim_{{n \\to \\infty}} \left(1 + \\frac{1}{n}\\right)^n";
36
36
  let typst = tex2typst(tex);
37
37
  console.log(typst);
38
38
  // e eq.def lim_(n -> infinity)(1 + 1/n)^n
package/dist/index.js CHANGED
@@ -1292,16 +1292,18 @@ var TypstToken = class {
1292
1292
  }
1293
1293
  toNode() {
1294
1294
  switch (this.type) {
1295
- case 2 /* TEXT */:
1295
+ case 0 /* NONE */:
1296
+ return new TypstNode("none", "#none");
1297
+ case 3 /* TEXT */:
1296
1298
  return new TypstNode("text", this.value);
1297
- case 3 /* COMMENT */:
1299
+ case 4 /* COMMENT */:
1298
1300
  return new TypstNode("comment", this.value);
1299
- case 4 /* SPACE */:
1301
+ case 5 /* SPACE */:
1300
1302
  case 7 /* NEWLINE */:
1301
1303
  return new TypstNode("whitespace", this.value);
1302
- case 1 /* ELEMENT */:
1304
+ case 2 /* ELEMENT */:
1303
1305
  return new TypstNode("atom", this.value);
1304
- case 0 /* SYMBOL */:
1306
+ case 1 /* SYMBOL */:
1305
1307
  return new TypstNode("symbol", this.value);
1306
1308
  case 6 /* CONTROL */: {
1307
1309
  const controlChar = this.value;
@@ -1309,7 +1311,7 @@ var TypstToken = class {
1309
1311
  case "":
1310
1312
  case "_":
1311
1313
  case "^":
1312
- return new TypstNode("empty", "");
1314
+ throw new Error(`Should not convert ${controlChar} to a node`);
1313
1315
  case "&":
1314
1316
  return new TypstNode("control", "&");
1315
1317
  case "\\":
@@ -1324,17 +1326,15 @@ var TypstToken = class {
1324
1326
  }
1325
1327
  toString() {
1326
1328
  switch (this.type) {
1327
- case 2 /* TEXT */:
1329
+ case 3 /* TEXT */:
1328
1330
  return `"${this.value}"`;
1329
- case 3 /* COMMENT */:
1331
+ case 4 /* COMMENT */:
1330
1332
  return `//${this.value}`;
1331
1333
  default:
1332
1334
  return this.value;
1333
1335
  }
1334
1336
  }
1335
1337
  };
1336
- var TYPST_NULL = null;
1337
- var TYPST_TRUE = true;
1338
1338
  var TypstNode = class {
1339
1339
  constructor(type, content, args, data) {
1340
1340
  this.type = type;
@@ -1374,6 +1374,8 @@ var TypstNode = class {
1374
1374
  }
1375
1375
  }
1376
1376
  };
1377
+ var TYPST_NONE = new TypstNode("none", "#none");
1378
+ var TYPST_TRUE = true;
1377
1379
 
1378
1380
  // src/util.ts
1379
1381
  function isalpha(char) {
@@ -1807,9 +1809,12 @@ var rules_map = /* @__PURE__ */ new Map([
1807
1809
  const command = s.text();
1808
1810
  return [new TexToken(1 /* COMMAND */, command)];
1809
1811
  }],
1810
- [String.raw`[0-9]+`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1812
+ // Numbers like "123", "3.14"
1813
+ [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1811
1814
  [String.raw`[a-zA-Z]`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1812
1815
  [String.raw`[+\-*/='<>!.,;:?()\[\]|]`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1816
+ // non-ASCII characters
1817
+ [String.raw`[^\x00-\x7F]`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1813
1818
  [String.raw`.`, (s) => new TexToken(7 /* UNKNOWN */, s.text())]
1814
1819
  ]);
1815
1820
  var spec = {
@@ -1856,9 +1861,7 @@ var LatexParser = class {
1856
1861
  results.push(res);
1857
1862
  }
1858
1863
  let node;
1859
- if (results.length === 0) {
1860
- node = EMPTY_NODE;
1861
- } else if (results.length === 1) {
1864
+ if (results.length === 1) {
1862
1865
  node = results[0];
1863
1866
  } else {
1864
1867
  node = new TexNode("ordgroup", "", results);
@@ -2232,10 +2235,10 @@ for (const [key, value] of shorthandMap.entries()) {
2232
2235
  function is_delimiter(c) {
2233
2236
  return c.type === "atom" && ["(", ")", "[", "]", "{", "}", "|", "\u230A", "\u230B", "\u2308", "\u2309"].includes(c.content);
2234
2237
  }
2235
- var TYPST_LEFT_PARENTHESIS = new TypstToken(1 /* ELEMENT */, "(");
2236
- var TYPST_RIGHT_PARENTHESIS = new TypstToken(1 /* ELEMENT */, ")");
2237
- var TYPST_COMMA = new TypstToken(1 /* ELEMENT */, ",");
2238
- var TYPST_NEWLINE = new TypstToken(0 /* SYMBOL */, "\n");
2238
+ var TYPST_LEFT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, "(");
2239
+ var TYPST_RIGHT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, ")");
2240
+ var TYPST_COMMA = new TypstToken(2 /* ELEMENT */, ",");
2241
+ var TYPST_NEWLINE = new TypstToken(1 /* SYMBOL */, "\n");
2239
2242
  function typst_primitive_to_string(value) {
2240
2243
  switch (typeof value) {
2241
2244
  case "string":
@@ -2245,12 +2248,8 @@ function typst_primitive_to_string(value) {
2245
2248
  case "boolean":
2246
2249
  return value ? "#true" : "#false";
2247
2250
  default:
2248
- if (value === null) {
2249
- return "#none";
2250
- } else if (value instanceof TypstToken) {
2251
- return value.toString();
2252
- }
2253
- throw new TypstWriterError(`Invalid primitive value: ${value}`, value);
2251
+ assert(value instanceof TypstNode, "Not a valid primitive value");
2252
+ return value.content;
2254
2253
  }
2255
2254
  }
2256
2255
  var TypstWriterError = class extends Error {
@@ -2296,13 +2295,14 @@ var TypstWriter = class {
2296
2295
  // Serialize a tree of TypstNode into a list of TypstToken
2297
2296
  serialize(node) {
2298
2297
  switch (node.type) {
2299
- case "empty":
2298
+ case "none":
2299
+ this.queue.push(new TypstToken(0 /* NONE */, "#none"));
2300
2300
  break;
2301
2301
  case "atom": {
2302
2302
  if (node.content === "," && this.insideFunctionDepth > 0) {
2303
- this.queue.push(new TypstToken(0 /* SYMBOL */, "comma"));
2303
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "comma"));
2304
2304
  } else {
2305
- this.queue.push(new TypstToken(1 /* ELEMENT */, node.content));
2305
+ this.queue.push(new TypstToken(2 /* ELEMENT */, node.content));
2306
2306
  }
2307
2307
  break;
2308
2308
  }
@@ -2316,23 +2316,23 @@ var TypstWriter = class {
2316
2316
  if (this.inftyToOo && content === "infinity") {
2317
2317
  content = "oo";
2318
2318
  }
2319
- this.queue.push(new TypstToken(0 /* SYMBOL */, content));
2319
+ this.queue.push(new TypstToken(1 /* SYMBOL */, content));
2320
2320
  break;
2321
2321
  }
2322
2322
  case "text":
2323
- this.queue.push(new TypstToken(2 /* TEXT */, node.content));
2323
+ this.queue.push(new TypstToken(3 /* TEXT */, node.content));
2324
2324
  break;
2325
2325
  case "comment":
2326
- this.queue.push(new TypstToken(3 /* COMMENT */, node.content));
2326
+ this.queue.push(new TypstToken(4 /* COMMENT */, node.content));
2327
2327
  break;
2328
2328
  case "whitespace":
2329
2329
  for (const c of node.content) {
2330
2330
  if (c === " ") {
2331
2331
  if (this.keepSpaces) {
2332
- this.queue.push(new TypstToken(4 /* SPACE */, c));
2332
+ this.queue.push(new TypstToken(5 /* SPACE */, c));
2333
2333
  }
2334
2334
  } else if (c === "\n") {
2335
- this.queue.push(new TypstToken(0 /* SYMBOL */, c));
2335
+ this.queue.push(new TypstToken(1 /* SYMBOL */, c));
2336
2336
  } else {
2337
2337
  throw new TypstWriterError(`Unexpected whitespace character: ${c}`, node);
2338
2338
  }
@@ -2349,15 +2349,15 @@ var TypstWriter = class {
2349
2349
  let trailing_space_needed = false;
2350
2350
  const has_prime = sup && sup.type === "atom" && sup.content === "'";
2351
2351
  if (has_prime) {
2352
- this.queue.push(new TypstToken(1 /* ELEMENT */, "'"));
2352
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "'"));
2353
2353
  trailing_space_needed = false;
2354
2354
  }
2355
2355
  if (sub) {
2356
- this.queue.push(new TypstToken(1 /* ELEMENT */, "_"));
2356
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "_"));
2357
2357
  trailing_space_needed = this.appendWithBracketsIfNeeded(sub);
2358
2358
  }
2359
2359
  if (sup && !has_prime) {
2360
- this.queue.push(new TypstToken(1 /* ELEMENT */, "^"));
2360
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "^"));
2361
2361
  trailing_space_needed = this.appendWithBracketsIfNeeded(sup);
2362
2362
  }
2363
2363
  if (trailing_space_needed) {
@@ -2366,24 +2366,28 @@ var TypstWriter = class {
2366
2366
  break;
2367
2367
  }
2368
2368
  case "funcCall": {
2369
- const func_symbol = new TypstToken(0 /* SYMBOL */, node.content);
2369
+ const func_symbol = new TypstToken(1 /* SYMBOL */, node.content);
2370
2370
  this.queue.push(func_symbol);
2371
- this.insideFunctionDepth++;
2371
+ if (node.content !== "lr") {
2372
+ this.insideFunctionDepth++;
2373
+ }
2372
2374
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2373
2375
  for (let i = 0; i < node.args.length; i++) {
2374
2376
  this.serialize(node.args[i]);
2375
2377
  if (i < node.args.length - 1) {
2376
- this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
2378
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
2377
2379
  }
2378
2380
  }
2379
2381
  if (node.options) {
2380
2382
  for (const [key, value] of Object.entries(node.options)) {
2381
2383
  const value_str = typst_primitive_to_string(value);
2382
- this.queue.push(new TypstToken(0 /* SYMBOL */, `, ${key}: ${value_str}`));
2384
+ this.queue.push(new TypstToken(1 /* SYMBOL */, `, ${key}: ${value_str}`));
2383
2385
  }
2384
2386
  }
2385
2387
  this.queue.push(TYPST_RIGHT_PARENTHESIS);
2386
- this.insideFunctionDepth--;
2388
+ if (node.content !== "lr") {
2389
+ this.insideFunctionDepth--;
2390
+ }
2387
2391
  break;
2388
2392
  }
2389
2393
  case "fraction": {
@@ -2395,7 +2399,7 @@ var TypstWriter = class {
2395
2399
  } else {
2396
2400
  this.serialize(numerator);
2397
2401
  }
2398
- this.queue.push(new TypstToken(1 /* ELEMENT */, "/"));
2402
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "/"));
2399
2403
  if (denominator.type === "group") {
2400
2404
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2401
2405
  this.serialize(denominator);
@@ -2410,35 +2414,35 @@ var TypstWriter = class {
2410
2414
  matrix.forEach((row, i) => {
2411
2415
  row.forEach((cell, j) => {
2412
2416
  if (j > 0) {
2413
- this.queue.push(new TypstToken(1 /* ELEMENT */, "&"));
2417
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "&"));
2414
2418
  }
2415
2419
  this.serialize(cell);
2416
2420
  });
2417
2421
  if (i < matrix.length - 1) {
2418
- this.queue.push(new TypstToken(0 /* SYMBOL */, "\\"));
2422
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "\\"));
2419
2423
  }
2420
2424
  });
2421
2425
  break;
2422
2426
  }
2423
2427
  case "matrix": {
2424
2428
  const matrix = node.data;
2425
- this.queue.push(new TypstToken(0 /* SYMBOL */, "mat"));
2429
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "mat"));
2426
2430
  this.insideFunctionDepth++;
2427
2431
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2428
2432
  if (node.options) {
2429
2433
  for (const [key, value] of Object.entries(node.options)) {
2430
2434
  const value_str = typst_primitive_to_string(value);
2431
- this.queue.push(new TypstToken(0 /* SYMBOL */, `${key}: ${value_str}, `));
2435
+ this.queue.push(new TypstToken(1 /* SYMBOL */, `${key}: ${value_str}, `));
2432
2436
  }
2433
2437
  }
2434
2438
  matrix.forEach((row, i) => {
2435
2439
  row.forEach((cell, j) => {
2436
2440
  this.serialize(cell);
2437
2441
  if (j < row.length - 1) {
2438
- this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
2442
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
2439
2443
  } else {
2440
2444
  if (i < matrix.length - 1) {
2441
- this.queue.push(new TypstToken(1 /* ELEMENT */, ";"));
2445
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ";"));
2442
2446
  }
2443
2447
  }
2444
2448
  });
@@ -2449,23 +2453,23 @@ var TypstWriter = class {
2449
2453
  }
2450
2454
  case "cases": {
2451
2455
  const cases = node.data;
2452
- this.queue.push(new TypstToken(0 /* SYMBOL */, "cases"));
2456
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "cases"));
2453
2457
  this.insideFunctionDepth++;
2454
2458
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2455
2459
  if (node.options) {
2456
2460
  for (const [key, value] of Object.entries(node.options)) {
2457
2461
  const value_str = typst_primitive_to_string(value);
2458
- this.queue.push(new TypstToken(0 /* SYMBOL */, `${key}: ${value_str}, `));
2462
+ this.queue.push(new TypstToken(1 /* SYMBOL */, `${key}: ${value_str}, `));
2459
2463
  }
2460
2464
  }
2461
2465
  cases.forEach((row, i) => {
2462
2466
  row.forEach((cell, j) => {
2463
2467
  this.serialize(cell);
2464
2468
  if (j < row.length - 1) {
2465
- this.queue.push(new TypstToken(1 /* ELEMENT */, "&"));
2469
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "&"));
2466
2470
  } else {
2467
2471
  if (i < cases.length - 1) {
2468
- this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
2472
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
2469
2473
  }
2470
2474
  }
2471
2475
  });
@@ -2476,7 +2480,7 @@ var TypstWriter = class {
2476
2480
  }
2477
2481
  case "unknown": {
2478
2482
  if (this.nonStrict) {
2479
- this.queue.push(new TypstToken(0 /* SYMBOL */, node.content));
2483
+ this.queue.push(new TypstToken(1 /* SYMBOL */, node.content));
2480
2484
  } else {
2481
2485
  throw new TypstWriterError(`Unknown macro: ${node.content}`, node);
2482
2486
  }
@@ -2489,10 +2493,14 @@ var TypstWriter = class {
2489
2493
  appendWithBracketsIfNeeded(node) {
2490
2494
  let need_to_wrap = ["group", "supsub", "empty"].includes(node.type);
2491
2495
  if (node.type === "group") {
2492
- const first = node.args[0];
2493
- const last = node.args[node.args.length - 1];
2494
- if (is_delimiter(first) && is_delimiter(last)) {
2495
- need_to_wrap = false;
2496
+ if (node.args.length === 0) {
2497
+ need_to_wrap = true;
2498
+ } else {
2499
+ const first = node.args[0];
2500
+ const last = node.args[node.args.length - 1];
2501
+ if (is_delimiter(first) && is_delimiter(last)) {
2502
+ need_to_wrap = false;
2503
+ }
2496
2504
  }
2497
2505
  }
2498
2506
  if (need_to_wrap) {
@@ -2618,7 +2626,7 @@ function convert_overset(node, options) {
2618
2626
  function convert_tex_node_to_typst(node, options = {}) {
2619
2627
  switch (node.type) {
2620
2628
  case "empty":
2621
- return new TypstNode("empty", "");
2629
+ return TYPST_NONE;
2622
2630
  case "whitespace":
2623
2631
  return new TypstNode("whitespace", node.content);
2624
2632
  case "ordgroup":
@@ -2631,8 +2639,16 @@ function convert_tex_node_to_typst(node, options = {}) {
2631
2639
  return new TypstNode("atom", tex_token_to_typst(node.content));
2632
2640
  case "symbol":
2633
2641
  return new TypstNode("symbol", tex_token_to_typst(node.content));
2634
- case "text":
2642
+ case "text": {
2643
+ if (/[^\x00-\x7F]+/.test(node.content) && options.nonAsciiWrapper !== "") {
2644
+ return new TypstNode(
2645
+ "funcCall",
2646
+ options.nonAsciiWrapper,
2647
+ [new TypstNode("text", node.content)]
2648
+ );
2649
+ }
2635
2650
  return new TypstNode("text", node.content);
2651
+ }
2636
2652
  case "comment":
2637
2653
  return new TypstNode("comment", node.content);
2638
2654
  case "supsub": {
@@ -2653,8 +2669,8 @@ function convert_tex_node_to_typst(node, options = {}) {
2653
2669
  const data = {
2654
2670
  base: convert_tex_node_to_typst(base, options)
2655
2671
  };
2656
- if (data.base.type === "empty") {
2657
- data.base = new TypstNode("text", "");
2672
+ if (data.base.type === "none") {
2673
+ data.base = new TypstNode("none", "");
2658
2674
  }
2659
2675
  if (sup) {
2660
2676
  data.sup = convert_tex_node_to_typst(sup, options);
@@ -2788,10 +2804,10 @@ function convert_tex_node_to_typst(node, options = {}) {
2788
2804
  return new TypstNode("cases", "", [], data);
2789
2805
  }
2790
2806
  if (node.content.endsWith("matrix")) {
2791
- let delim = null;
2807
+ let delim;
2792
2808
  switch (node.content) {
2793
2809
  case "matrix":
2794
- delim = TYPST_NULL;
2810
+ delim = TYPST_NONE;
2795
2811
  break;
2796
2812
  case "pmatrix":
2797
2813
  delim = "(";
@@ -2806,7 +2822,7 @@ function convert_tex_node_to_typst(node, options = {}) {
2806
2822
  delim = "|";
2807
2823
  break;
2808
2824
  case "Vmatrix": {
2809
- delim = new TypstToken(0 /* SYMBOL */, "bar.v.double");
2825
+ delim = new TypstNode("symbol", "bar.v.double");
2810
2826
  break;
2811
2827
  }
2812
2828
  default:
@@ -2884,7 +2900,7 @@ function convert_typst_node_to_tex(node) {
2884
2900
  ]);
2885
2901
  }
2886
2902
  switch (node.type) {
2887
- case "empty":
2903
+ case "none":
2888
2904
  return new TexNode("empty", "");
2889
2905
  case "whitespace":
2890
2906
  return new TexNode("whitespace", node.content);
@@ -3002,29 +3018,44 @@ function convert_typst_node_to_tex(node) {
3002
3018
  let env_type = "pmatrix";
3003
3019
  if (node.options) {
3004
3020
  if ("delim" in node.options) {
3005
- switch (node.options.delim) {
3006
- case TYPST_NULL:
3007
- env_type = "matrix";
3008
- break;
3009
- case "[":
3010
- env_type = "bmatrix";
3011
- break;
3012
- case "]":
3013
- env_type = "bmatrix";
3014
- break;
3015
- case "{":
3016
- env_type = "Bmatrix";
3017
- break;
3018
- case "}":
3019
- env_type = "Bmatrix";
3020
- break;
3021
- case "|":
3022
- env_type = "vmatrix";
3023
- break;
3024
- case ")":
3025
- case "(":
3026
- default:
3027
- env_type = "pmatrix";
3021
+ const delim = node.options.delim;
3022
+ if (delim instanceof TypstNode) {
3023
+ switch (delim.content) {
3024
+ case "#none":
3025
+ env_type = "matrix";
3026
+ break;
3027
+ case "bar.v.double":
3028
+ env_type = "Vmatrix";
3029
+ break;
3030
+ case "bar":
3031
+ case "bar.v":
3032
+ env_type = "vmatrix";
3033
+ break;
3034
+ default:
3035
+ throw new Error(`Unexpected delimiter ${delim.content}`);
3036
+ }
3037
+ } else {
3038
+ switch (delim) {
3039
+ case "[":
3040
+ env_type = "bmatrix";
3041
+ break;
3042
+ case "]":
3043
+ env_type = "bmatrix";
3044
+ break;
3045
+ case "{":
3046
+ env_type = "Bmatrix";
3047
+ break;
3048
+ case "}":
3049
+ env_type = "Bmatrix";
3050
+ break;
3051
+ case "|":
3052
+ env_type = "vmatrix";
3053
+ break;
3054
+ case ")":
3055
+ case "(":
3056
+ default:
3057
+ env_type = "pmatrix";
3058
+ }
3028
3059
  }
3029
3060
  }
3030
3061
  }
@@ -3057,11 +3088,10 @@ function convert_typst_node_to_tex(node) {
3057
3088
  }
3058
3089
 
3059
3090
  // src/typst-parser.ts
3060
- var TYPST_EMPTY_NODE = new TypstNode("empty", "");
3061
3091
  var TYPST_SHORTHANDS = Array.from(reverseShorthandMap.keys());
3062
3092
  function eat_primes2(tokens, start) {
3063
3093
  let pos = start;
3064
- while (pos < tokens.length && tokens[pos].eq(new TypstToken(1 /* ELEMENT */, "'"))) {
3094
+ while (pos < tokens.length && tokens[pos].eq(new TypstToken(2 /* ELEMENT */, "'"))) {
3065
3095
  pos += 1;
3066
3096
  }
3067
3097
  return pos - start;
@@ -3078,12 +3108,12 @@ function generate_regex_for_shorthands() {
3078
3108
  }
3079
3109
  var REGEX_SHORTHANDS = generate_regex_for_shorthands();
3080
3110
  var rules_map2 = /* @__PURE__ */ new Map([
3081
- [String.raw`//[^\n]*`, (s) => new TypstToken(3 /* COMMENT */, s.text().substring(2))],
3082
- [String.raw`/`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3111
+ [String.raw`//[^\n]*`, (s) => new TypstToken(4 /* COMMENT */, s.text().substring(2))],
3112
+ [String.raw`/`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3083
3113
  [String.raw`[_^&]`, (s) => new TypstToken(6 /* CONTROL */, s.text())],
3084
3114
  [String.raw`\r?\n`, (_s) => new TypstToken(7 /* NEWLINE */, "\n")],
3085
- [String.raw`\s+`, (s) => new TypstToken(4 /* SPACE */, s.text())],
3086
- [String.raw`\\[$&#_]`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3115
+ [String.raw`\s+`, (s) => new TypstToken(5 /* SPACE */, s.text())],
3116
+ [String.raw`\\[$&#_]`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3087
3117
  [String.raw`\\\n`, (s) => {
3088
3118
  return [
3089
3119
  new TypstToken(6 /* CONTROL */, "\\"),
@@ -3093,7 +3123,7 @@ var rules_map2 = /* @__PURE__ */ new Map([
3093
3123
  [String.raw`\\\s`, (s) => {
3094
3124
  return [
3095
3125
  new TypstToken(6 /* CONTROL */, "\\"),
3096
- new TypstToken(4 /* SPACE */, " ")
3126
+ new TypstToken(5 /* SPACE */, " ")
3097
3127
  ];
3098
3128
  }],
3099
3129
  // this backslash is dummy and will be ignored in later stages
@@ -3103,7 +3133,7 @@ var rules_map2 = /* @__PURE__ */ new Map([
3103
3133
  (s) => {
3104
3134
  const text = s.text().substring(1, s.text().length - 1);
3105
3135
  text.replaceAll('\\"', '"');
3106
- return new TypstToken(2 /* TEXT */, text);
3136
+ return new TypstToken(3 /* TEXT */, text);
3107
3137
  }
3108
3138
  ],
3109
3139
  [
@@ -3111,15 +3141,16 @@ var rules_map2 = /* @__PURE__ */ new Map([
3111
3141
  (s) => {
3112
3142
  const shorthand = s.text();
3113
3143
  const symbol = reverseShorthandMap.get(shorthand);
3114
- return new TypstToken(0 /* SYMBOL */, symbol);
3144
+ return new TypstToken(1 /* SYMBOL */, symbol);
3115
3145
  }
3116
3146
  ],
3117
- [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3118
- [String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3147
+ [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3148
+ [String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3119
3149
  [String.raw`[a-zA-Z\.]+`, (s) => {
3120
- return new TypstToken(s.text().length === 1 ? 1 /* ELEMENT */ : 0 /* SYMBOL */, s.text());
3150
+ return new TypstToken(s.text().length === 1 ? 2 /* ELEMENT */ : 1 /* SYMBOL */, s.text());
3121
3151
  }],
3122
- [String.raw`.`, (s) => new TypstToken(1 /* ELEMENT */, s.text())]
3152
+ [String.raw`#none`, (s) => new TypstToken(0 /* NONE */, s.text())],
3153
+ [String.raw`.`, (s) => new TypstToken(2 /* ELEMENT */, s.text())]
3123
3154
  ]);
3124
3155
  var spec2 = {
3125
3156
  "start": rules_map2
@@ -3193,7 +3224,7 @@ function next_non_whitespace(nodes, start) {
3193
3224
  while (pos < nodes.length && nodes[pos].type === "whitespace") {
3194
3225
  pos++;
3195
3226
  }
3196
- return pos === nodes.length ? TYPST_EMPTY_NODE : nodes[pos];
3227
+ return pos === nodes.length ? null : nodes[pos];
3197
3228
  }
3198
3229
  function trim_whitespace_around_operators(nodes) {
3199
3230
  let after_operator = false;
@@ -3204,7 +3235,7 @@ function trim_whitespace_around_operators(nodes) {
3204
3235
  if (after_operator) {
3205
3236
  continue;
3206
3237
  }
3207
- if (next_non_whitespace(nodes, i + 1).eq(DIV)) {
3238
+ if (next_non_whitespace(nodes, i + 1)?.eq(DIV)) {
3208
3239
  continue;
3209
3240
  }
3210
3241
  }
@@ -3263,9 +3294,7 @@ function process_operators(nodes, parenthesis = false) {
3263
3294
  if (parenthesis) {
3264
3295
  return new TypstNode("group", "parenthesis", args);
3265
3296
  } else {
3266
- if (args.length === 0) {
3267
- return TYPST_EMPTY_NODE;
3268
- } else if (args.length === 1) {
3297
+ if (args.length === 1) {
3269
3298
  return args[0];
3270
3299
  } else {
3271
3300
  return new TypstNode("group", "", args);
@@ -3280,16 +3309,16 @@ var TypstParserError = class extends Error {
3280
3309
  };
3281
3310
  var SUB_SYMBOL2 = new TypstToken(6 /* CONTROL */, "_");
3282
3311
  var SUP_SYMBOL2 = new TypstToken(6 /* CONTROL */, "^");
3283
- var LEFT_PARENTHESES = new TypstToken(1 /* ELEMENT */, "(");
3284
- var RIGHT_PARENTHESES = new TypstToken(1 /* ELEMENT */, ")");
3285
- var LEFT_BRACKET = new TypstToken(1 /* ELEMENT */, "[");
3286
- var RIGHT_BRACKET = new TypstToken(1 /* ELEMENT */, "]");
3287
- var LEFT_CURLY_BRACKET2 = new TypstToken(1 /* ELEMENT */, "{");
3288
- var RIGHT_CURLY_BRACKET2 = new TypstToken(1 /* ELEMENT */, "}");
3289
- var VERTICAL_BAR = new TypstToken(1 /* ELEMENT */, "|");
3290
- var COMMA = new TypstToken(1 /* ELEMENT */, ",");
3291
- var SEMICOLON = new TypstToken(1 /* ELEMENT */, ";");
3292
- var SINGLE_SPACE = new TypstToken(4 /* SPACE */, " ");
3312
+ var LEFT_PARENTHESES = new TypstToken(2 /* ELEMENT */, "(");
3313
+ var RIGHT_PARENTHESES = new TypstToken(2 /* ELEMENT */, ")");
3314
+ var LEFT_BRACKET = new TypstToken(2 /* ELEMENT */, "[");
3315
+ var RIGHT_BRACKET = new TypstToken(2 /* ELEMENT */, "]");
3316
+ var LEFT_CURLY_BRACKET2 = new TypstToken(2 /* ELEMENT */, "{");
3317
+ var RIGHT_CURLY_BRACKET2 = new TypstToken(2 /* ELEMENT */, "}");
3318
+ var VERTICAL_BAR = new TypstToken(2 /* ELEMENT */, "|");
3319
+ var COMMA = new TypstToken(2 /* ELEMENT */, ",");
3320
+ var SEMICOLON = new TypstToken(2 /* ELEMENT */, ";");
3321
+ var SINGLE_SPACE = new TypstToken(5 /* SPACE */, " ");
3293
3322
  var TypstParser = class {
3294
3323
  constructor(space_sensitive = true, newline_sensitive = true) {
3295
3324
  this.space_sensitive = space_sensitive;
@@ -3319,9 +3348,7 @@ var TypstParser = class {
3319
3348
  if (parentheses) {
3320
3349
  node = process_operators(results, true);
3321
3350
  } else {
3322
- if (results.length === 0) {
3323
- node = TYPST_EMPTY_NODE;
3324
- } else if (results.length === 1) {
3351
+ if (results.length === 1) {
3325
3352
  node = results[0];
3326
3353
  } else {
3327
3354
  node = process_operators(results);
@@ -3385,10 +3412,10 @@ var TypstParser = class {
3385
3412
  const pos_closing = find_closing_match2(tokens, start);
3386
3413
  return this.parseGroup(tokens, start + 1, pos_closing, true);
3387
3414
  }
3388
- if (firstToken.type === 1 /* ELEMENT */ && !isalpha(firstToken.value[0])) {
3415
+ if (firstToken.type === 2 /* ELEMENT */ && !isalpha(firstToken.value[0])) {
3389
3416
  return [node, start + 1];
3390
3417
  }
3391
- if ([1 /* ELEMENT */, 0 /* SYMBOL */].includes(firstToken.type)) {
3418
+ if ([2 /* ELEMENT */, 1 /* SYMBOL */].includes(firstToken.type)) {
3392
3419
  if (start + 1 < tokens.length && tokens[start + 1].eq(LEFT_PARENTHESES)) {
3393
3420
  if (firstToken.value === "mat") {
3394
3421
  const [matrix, named_params, newPos2] = this.parseGroupsOfArguments(tokens, start + 1);
@@ -3465,18 +3492,24 @@ var TypstParser = class {
3465
3492
  to_delete.push(i);
3466
3493
  const param_name = g.args[pos_colon - 1];
3467
3494
  if (param_name.eq(new TypstNode("symbol", "delim"))) {
3468
- if (g.args[pos_colon + 1].type === "text") {
3469
- np2["delim"] = g.args[pos_colon + 1].content;
3470
- if (g.args.length !== 3) {
3471
- throw new TypstParserError("Invalid number of arguments for delim");
3495
+ if (g.args.length !== 3) {
3496
+ throw new TypstParserError("Invalid number of arguments for delim");
3497
+ }
3498
+ switch (g.args[pos_colon + 1].type) {
3499
+ case "text": {
3500
+ np2["delim"] = g.args[pos_colon + 1].content;
3501
+ break;
3502
+ }
3503
+ case "none": {
3504
+ np2["delim"] = TYPST_NONE;
3505
+ break;
3472
3506
  }
3473
- } else if (g.args[pos_colon + 1].eq(new TypstNode("atom", "#"))) {
3474
- if (g.args.length !== 4 || !g.args[pos_colon + 2].eq(new TypstNode("symbol", "none"))) {
3475
- throw new TypstParserError("Invalid number of arguments for delim");
3507
+ case "symbol": {
3508
+ np2["delim"] = g.args[pos_colon + 1];
3509
+ break;
3476
3510
  }
3477
- np2["delim"] = TYPST_NULL;
3478
- } else {
3479
- throw new TypstParserError("Not implemented for other types of delim");
3511
+ default:
3512
+ throw new TypstParserError("Not implemented for other types of delim");
3480
3513
  }
3481
3514
  } else {
3482
3515
  throw new TypstParserError("Not implemented for other named parameters");
@@ -3521,9 +3554,7 @@ var TypstParser = class {
3521
3554
  nodes.push(argItem);
3522
3555
  }
3523
3556
  let arg;
3524
- if (nodes.length === 0) {
3525
- arg = TYPST_EMPTY_NODE;
3526
- } else if (nodes.length === 1) {
3557
+ if (nodes.length === 1) {
3527
3558
  arg = nodes[0];
3528
3559
  } else {
3529
3560
  arg = process_operators(nodes);
@@ -3603,6 +3634,7 @@ function tex2typst(tex, options) {
3603
3634
  keepSpaces: false,
3604
3635
  fracToSlash: true,
3605
3636
  inftyToOo: false,
3637
+ nonAsciiWrapper: "",
3606
3638
  customTexMacros: {}
3607
3639
  };
3608
3640
  if (options !== void 0) {