tex2typst 0.3.9 → 0.3.11

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
@@ -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_NONE = 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,7 +1809,8 @@ 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())],
1813
1816
  [String.raw`.`, (s) => new TexToken(7 /* UNKNOWN */, s.text())]
@@ -1856,9 +1859,7 @@ var LatexParser = class {
1856
1859
  results.push(res);
1857
1860
  }
1858
1861
  let node;
1859
- if (results.length === 0) {
1860
- node = EMPTY_NODE;
1861
- } else if (results.length === 1) {
1862
+ if (results.length === 1) {
1862
1863
  node = results[0];
1863
1864
  } else {
1864
1865
  node = new TexNode("ordgroup", "", results);
@@ -2232,10 +2233,10 @@ for (const [key, value] of shorthandMap.entries()) {
2232
2233
  function is_delimiter(c) {
2233
2234
  return c.type === "atom" && ["(", ")", "[", "]", "{", "}", "|", "\u230A", "\u230B", "\u2308", "\u2309"].includes(c.content);
2234
2235
  }
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");
2236
+ var TYPST_LEFT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, "(");
2237
+ var TYPST_RIGHT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, ")");
2238
+ var TYPST_COMMA = new TypstToken(2 /* ELEMENT */, ",");
2239
+ var TYPST_NEWLINE = new TypstToken(1 /* SYMBOL */, "\n");
2239
2240
  function typst_primitive_to_string(value) {
2240
2241
  switch (typeof value) {
2241
2242
  case "string":
@@ -2245,12 +2246,8 @@ function typst_primitive_to_string(value) {
2245
2246
  case "boolean":
2246
2247
  return value ? "#true" : "#false";
2247
2248
  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);
2249
+ assert(value instanceof TypstNode, "Not a valid primitive value");
2250
+ return value.content;
2254
2251
  }
2255
2252
  }
2256
2253
  var TypstWriterError = class extends Error {
@@ -2296,13 +2293,14 @@ var TypstWriter = class {
2296
2293
  // Serialize a tree of TypstNode into a list of TypstToken
2297
2294
  serialize(node) {
2298
2295
  switch (node.type) {
2299
- case "empty":
2296
+ case "none":
2297
+ this.queue.push(new TypstToken(0 /* NONE */, "#none"));
2300
2298
  break;
2301
2299
  case "atom": {
2302
2300
  if (node.content === "," && this.insideFunctionDepth > 0) {
2303
- this.queue.push(new TypstToken(0 /* SYMBOL */, "comma"));
2301
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "comma"));
2304
2302
  } else {
2305
- this.queue.push(new TypstToken(1 /* ELEMENT */, node.content));
2303
+ this.queue.push(new TypstToken(2 /* ELEMENT */, node.content));
2306
2304
  }
2307
2305
  break;
2308
2306
  }
@@ -2316,23 +2314,23 @@ var TypstWriter = class {
2316
2314
  if (this.inftyToOo && content === "infinity") {
2317
2315
  content = "oo";
2318
2316
  }
2319
- this.queue.push(new TypstToken(0 /* SYMBOL */, content));
2317
+ this.queue.push(new TypstToken(1 /* SYMBOL */, content));
2320
2318
  break;
2321
2319
  }
2322
2320
  case "text":
2323
- this.queue.push(new TypstToken(2 /* TEXT */, node.content));
2321
+ this.queue.push(new TypstToken(3 /* TEXT */, node.content));
2324
2322
  break;
2325
2323
  case "comment":
2326
- this.queue.push(new TypstToken(3 /* COMMENT */, node.content));
2324
+ this.queue.push(new TypstToken(4 /* COMMENT */, node.content));
2327
2325
  break;
2328
2326
  case "whitespace":
2329
2327
  for (const c of node.content) {
2330
2328
  if (c === " ") {
2331
2329
  if (this.keepSpaces) {
2332
- this.queue.push(new TypstToken(4 /* SPACE */, c));
2330
+ this.queue.push(new TypstToken(5 /* SPACE */, c));
2333
2331
  }
2334
2332
  } else if (c === "\n") {
2335
- this.queue.push(new TypstToken(0 /* SYMBOL */, c));
2333
+ this.queue.push(new TypstToken(1 /* SYMBOL */, c));
2336
2334
  } else {
2337
2335
  throw new TypstWriterError(`Unexpected whitespace character: ${c}`, node);
2338
2336
  }
@@ -2349,15 +2347,15 @@ var TypstWriter = class {
2349
2347
  let trailing_space_needed = false;
2350
2348
  const has_prime = sup && sup.type === "atom" && sup.content === "'";
2351
2349
  if (has_prime) {
2352
- this.queue.push(new TypstToken(1 /* ELEMENT */, "'"));
2350
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "'"));
2353
2351
  trailing_space_needed = false;
2354
2352
  }
2355
2353
  if (sub) {
2356
- this.queue.push(new TypstToken(1 /* ELEMENT */, "_"));
2354
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "_"));
2357
2355
  trailing_space_needed = this.appendWithBracketsIfNeeded(sub);
2358
2356
  }
2359
2357
  if (sup && !has_prime) {
2360
- this.queue.push(new TypstToken(1 /* ELEMENT */, "^"));
2358
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "^"));
2361
2359
  trailing_space_needed = this.appendWithBracketsIfNeeded(sup);
2362
2360
  }
2363
2361
  if (trailing_space_needed) {
@@ -2366,24 +2364,28 @@ var TypstWriter = class {
2366
2364
  break;
2367
2365
  }
2368
2366
  case "funcCall": {
2369
- const func_symbol = new TypstToken(0 /* SYMBOL */, node.content);
2367
+ const func_symbol = new TypstToken(1 /* SYMBOL */, node.content);
2370
2368
  this.queue.push(func_symbol);
2371
- this.insideFunctionDepth++;
2369
+ if (node.content !== "lr") {
2370
+ this.insideFunctionDepth++;
2371
+ }
2372
2372
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2373
2373
  for (let i = 0; i < node.args.length; i++) {
2374
2374
  this.serialize(node.args[i]);
2375
2375
  if (i < node.args.length - 1) {
2376
- this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
2376
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
2377
2377
  }
2378
2378
  }
2379
2379
  if (node.options) {
2380
2380
  for (const [key, value] of Object.entries(node.options)) {
2381
2381
  const value_str = typst_primitive_to_string(value);
2382
- this.queue.push(new TypstToken(0 /* SYMBOL */, `, ${key}: ${value_str}`));
2382
+ this.queue.push(new TypstToken(1 /* SYMBOL */, `, ${key}: ${value_str}`));
2383
2383
  }
2384
2384
  }
2385
2385
  this.queue.push(TYPST_RIGHT_PARENTHESIS);
2386
- this.insideFunctionDepth--;
2386
+ if (node.content !== "lr") {
2387
+ this.insideFunctionDepth--;
2388
+ }
2387
2389
  break;
2388
2390
  }
2389
2391
  case "fraction": {
@@ -2395,7 +2397,7 @@ var TypstWriter = class {
2395
2397
  } else {
2396
2398
  this.serialize(numerator);
2397
2399
  }
2398
- this.queue.push(new TypstToken(1 /* ELEMENT */, "/"));
2400
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "/"));
2399
2401
  if (denominator.type === "group") {
2400
2402
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2401
2403
  this.serialize(denominator);
@@ -2410,35 +2412,35 @@ var TypstWriter = class {
2410
2412
  matrix.forEach((row, i) => {
2411
2413
  row.forEach((cell, j) => {
2412
2414
  if (j > 0) {
2413
- this.queue.push(new TypstToken(1 /* ELEMENT */, "&"));
2415
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "&"));
2414
2416
  }
2415
2417
  this.serialize(cell);
2416
2418
  });
2417
2419
  if (i < matrix.length - 1) {
2418
- this.queue.push(new TypstToken(0 /* SYMBOL */, "\\"));
2420
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "\\"));
2419
2421
  }
2420
2422
  });
2421
2423
  break;
2422
2424
  }
2423
2425
  case "matrix": {
2424
2426
  const matrix = node.data;
2425
- this.queue.push(new TypstToken(0 /* SYMBOL */, "mat"));
2427
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "mat"));
2426
2428
  this.insideFunctionDepth++;
2427
2429
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2428
2430
  if (node.options) {
2429
2431
  for (const [key, value] of Object.entries(node.options)) {
2430
2432
  const value_str = typst_primitive_to_string(value);
2431
- this.queue.push(new TypstToken(0 /* SYMBOL */, `${key}: ${value_str}, `));
2433
+ this.queue.push(new TypstToken(1 /* SYMBOL */, `${key}: ${value_str}, `));
2432
2434
  }
2433
2435
  }
2434
2436
  matrix.forEach((row, i) => {
2435
2437
  row.forEach((cell, j) => {
2436
2438
  this.serialize(cell);
2437
2439
  if (j < row.length - 1) {
2438
- this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
2440
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
2439
2441
  } else {
2440
2442
  if (i < matrix.length - 1) {
2441
- this.queue.push(new TypstToken(1 /* ELEMENT */, ";"));
2443
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ";"));
2442
2444
  }
2443
2445
  }
2444
2446
  });
@@ -2449,23 +2451,23 @@ var TypstWriter = class {
2449
2451
  }
2450
2452
  case "cases": {
2451
2453
  const cases = node.data;
2452
- this.queue.push(new TypstToken(0 /* SYMBOL */, "cases"));
2454
+ this.queue.push(new TypstToken(1 /* SYMBOL */, "cases"));
2453
2455
  this.insideFunctionDepth++;
2454
2456
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2455
2457
  if (node.options) {
2456
2458
  for (const [key, value] of Object.entries(node.options)) {
2457
2459
  const value_str = typst_primitive_to_string(value);
2458
- this.queue.push(new TypstToken(0 /* SYMBOL */, `${key}: ${value_str}, `));
2460
+ this.queue.push(new TypstToken(1 /* SYMBOL */, `${key}: ${value_str}, `));
2459
2461
  }
2460
2462
  }
2461
2463
  cases.forEach((row, i) => {
2462
2464
  row.forEach((cell, j) => {
2463
2465
  this.serialize(cell);
2464
2466
  if (j < row.length - 1) {
2465
- this.queue.push(new TypstToken(1 /* ELEMENT */, "&"));
2467
+ this.queue.push(new TypstToken(2 /* ELEMENT */, "&"));
2466
2468
  } else {
2467
2469
  if (i < cases.length - 1) {
2468
- this.queue.push(new TypstToken(1 /* ELEMENT */, ","));
2470
+ this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
2469
2471
  }
2470
2472
  }
2471
2473
  });
@@ -2476,7 +2478,7 @@ var TypstWriter = class {
2476
2478
  }
2477
2479
  case "unknown": {
2478
2480
  if (this.nonStrict) {
2479
- this.queue.push(new TypstToken(0 /* SYMBOL */, node.content));
2481
+ this.queue.push(new TypstToken(1 /* SYMBOL */, node.content));
2480
2482
  } else {
2481
2483
  throw new TypstWriterError(`Unknown macro: ${node.content}`, node);
2482
2484
  }
@@ -2489,10 +2491,14 @@ var TypstWriter = class {
2489
2491
  appendWithBracketsIfNeeded(node) {
2490
2492
  let need_to_wrap = ["group", "supsub", "empty"].includes(node.type);
2491
2493
  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;
2494
+ if (node.args.length === 0) {
2495
+ need_to_wrap = true;
2496
+ } else {
2497
+ const first = node.args[0];
2498
+ const last = node.args[node.args.length - 1];
2499
+ if (is_delimiter(first) && is_delimiter(last)) {
2500
+ need_to_wrap = false;
2501
+ }
2496
2502
  }
2497
2503
  }
2498
2504
  if (need_to_wrap) {
@@ -2618,7 +2624,7 @@ function convert_overset(node, options) {
2618
2624
  function convert_tex_node_to_typst(node, options = {}) {
2619
2625
  switch (node.type) {
2620
2626
  case "empty":
2621
- return new TypstNode("empty", "");
2627
+ return TYPST_NONE;
2622
2628
  case "whitespace":
2623
2629
  return new TypstNode("whitespace", node.content);
2624
2630
  case "ordgroup":
@@ -2653,8 +2659,8 @@ function convert_tex_node_to_typst(node, options = {}) {
2653
2659
  const data = {
2654
2660
  base: convert_tex_node_to_typst(base, options)
2655
2661
  };
2656
- if (data.base.type === "empty") {
2657
- data.base = new TypstNode("text", "");
2662
+ if (data.base.type === "none") {
2663
+ data.base = new TypstNode("none", "");
2658
2664
  }
2659
2665
  if (sup) {
2660
2666
  data.sup = convert_tex_node_to_typst(sup, options);
@@ -2788,7 +2794,7 @@ function convert_tex_node_to_typst(node, options = {}) {
2788
2794
  return new TypstNode("cases", "", [], data);
2789
2795
  }
2790
2796
  if (node.content.endsWith("matrix")) {
2791
- let delim = null;
2797
+ let delim;
2792
2798
  switch (node.content) {
2793
2799
  case "matrix":
2794
2800
  delim = TYPST_NONE;
@@ -2806,7 +2812,7 @@ function convert_tex_node_to_typst(node, options = {}) {
2806
2812
  delim = "|";
2807
2813
  break;
2808
2814
  case "Vmatrix": {
2809
- delim = new TypstToken(0 /* SYMBOL */, "bar.v.double");
2815
+ delim = new TypstNode("symbol", "bar.v.double");
2810
2816
  break;
2811
2817
  }
2812
2818
  default:
@@ -2884,7 +2890,7 @@ function convert_typst_node_to_tex(node) {
2884
2890
  ]);
2885
2891
  }
2886
2892
  switch (node.type) {
2887
- case "empty":
2893
+ case "none":
2888
2894
  return new TexNode("empty", "");
2889
2895
  case "whitespace":
2890
2896
  return new TexNode("whitespace", node.content);
@@ -2966,6 +2972,10 @@ function convert_typst_node_to_tex(node) {
2966
2972
  const command = typst_token_to_tex(node.content);
2967
2973
  return new TexNode("binaryFunc", command, node.args.map(convert_typst_node_to_tex));
2968
2974
  } else {
2975
+ if (node.content === "vec") {
2976
+ const tex_data = node.args.map(convert_typst_node_to_tex).map((n) => [n]);
2977
+ return new TexNode("beginend", "pmatrix", [], tex_data);
2978
+ }
2969
2979
  return new TexNode("ordgroup", "", [
2970
2980
  new TexNode("symbol", typst_token_to_tex(node.content)),
2971
2981
  new TexNode("element", "("),
@@ -2995,50 +3005,51 @@ function convert_typst_node_to_tex(node) {
2995
3005
  case "matrix": {
2996
3006
  const typst_data = node.data;
2997
3007
  const tex_data = typst_data.map((row) => row.map(convert_typst_node_to_tex));
2998
- const matrix = new TexNode("beginend", "matrix", [], tex_data);
2999
- let left_delim = "\\left(";
3000
- let right_delim = "\\right)";
3008
+ let env_type = "pmatrix";
3001
3009
  if (node.options) {
3002
3010
  if ("delim" in node.options) {
3003
- switch (node.options.delim) {
3004
- case TYPST_NONE:
3005
- return matrix;
3006
- case "[":
3007
- left_delim = "\\left[";
3008
- right_delim = "\\right]";
3009
- break;
3010
- case "]":
3011
- left_delim = "\\left]";
3012
- right_delim = "\\right[";
3013
- break;
3014
- case "{":
3015
- left_delim = "\\left\\{";
3016
- right_delim = "\\right\\}";
3017
- break;
3018
- case "}":
3019
- left_delim = "\\left\\}";
3020
- right_delim = "\\right\\{";
3021
- break;
3022
- case "|":
3023
- left_delim = "\\left|";
3024
- right_delim = "\\right|";
3025
- break;
3026
- case ")":
3027
- left_delim = "\\left)";
3028
- right_delim = "\\right(";
3029
- case "(":
3030
- default:
3031
- left_delim = "\\left(";
3032
- right_delim = "\\right)";
3033
- break;
3011
+ const delim = node.options.delim;
3012
+ if (delim instanceof TypstNode) {
3013
+ switch (delim.content) {
3014
+ case "#none":
3015
+ env_type = "matrix";
3016
+ break;
3017
+ case "bar.v.double":
3018
+ env_type = "Vmatrix";
3019
+ break;
3020
+ case "bar":
3021
+ case "bar.v":
3022
+ env_type = "vmatrix";
3023
+ break;
3024
+ default:
3025
+ throw new Error(`Unexpected delimiter ${delim.content}`);
3026
+ }
3027
+ } else {
3028
+ switch (delim) {
3029
+ case "[":
3030
+ env_type = "bmatrix";
3031
+ break;
3032
+ case "]":
3033
+ env_type = "bmatrix";
3034
+ break;
3035
+ case "{":
3036
+ env_type = "Bmatrix";
3037
+ break;
3038
+ case "}":
3039
+ env_type = "Bmatrix";
3040
+ break;
3041
+ case "|":
3042
+ env_type = "vmatrix";
3043
+ break;
3044
+ case ")":
3045
+ case "(":
3046
+ default:
3047
+ env_type = "pmatrix";
3048
+ }
3034
3049
  }
3035
3050
  }
3036
3051
  }
3037
- return new TexNode("ordgroup", "", [
3038
- new TexNode("element", left_delim),
3039
- matrix,
3040
- new TexNode("element", right_delim)
3041
- ]);
3052
+ return new TexNode("beginend", env_type, [], tex_data);
3042
3053
  }
3043
3054
  case "cases": {
3044
3055
  const typst_data = node.data;
@@ -3067,11 +3078,10 @@ function convert_typst_node_to_tex(node) {
3067
3078
  }
3068
3079
 
3069
3080
  // src/typst-parser.ts
3070
- var TYPST_EMPTY_NODE = new TypstNode("empty", "");
3071
3081
  var TYPST_SHORTHANDS = Array.from(reverseShorthandMap.keys());
3072
3082
  function eat_primes2(tokens, start) {
3073
3083
  let pos = start;
3074
- while (pos < tokens.length && tokens[pos].eq(new TypstToken(1 /* ELEMENT */, "'"))) {
3084
+ while (pos < tokens.length && tokens[pos].eq(new TypstToken(2 /* ELEMENT */, "'"))) {
3075
3085
  pos += 1;
3076
3086
  }
3077
3087
  return pos - start;
@@ -3088,12 +3098,12 @@ function generate_regex_for_shorthands() {
3088
3098
  }
3089
3099
  var REGEX_SHORTHANDS = generate_regex_for_shorthands();
3090
3100
  var rules_map2 = /* @__PURE__ */ new Map([
3091
- [String.raw`//[^\n]*`, (s) => new TypstToken(3 /* COMMENT */, s.text().substring(2))],
3092
- [String.raw`/`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3101
+ [String.raw`//[^\n]*`, (s) => new TypstToken(4 /* COMMENT */, s.text().substring(2))],
3102
+ [String.raw`/`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3093
3103
  [String.raw`[_^&]`, (s) => new TypstToken(6 /* CONTROL */, s.text())],
3094
3104
  [String.raw`\r?\n`, (_s) => new TypstToken(7 /* NEWLINE */, "\n")],
3095
- [String.raw`\s+`, (s) => new TypstToken(4 /* SPACE */, s.text())],
3096
- [String.raw`\\[$&#_]`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3105
+ [String.raw`\s+`, (s) => new TypstToken(5 /* SPACE */, s.text())],
3106
+ [String.raw`\\[$&#_]`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3097
3107
  [String.raw`\\\n`, (s) => {
3098
3108
  return [
3099
3109
  new TypstToken(6 /* CONTROL */, "\\"),
@@ -3103,7 +3113,7 @@ var rules_map2 = /* @__PURE__ */ new Map([
3103
3113
  [String.raw`\\\s`, (s) => {
3104
3114
  return [
3105
3115
  new TypstToken(6 /* CONTROL */, "\\"),
3106
- new TypstToken(4 /* SPACE */, " ")
3116
+ new TypstToken(5 /* SPACE */, " ")
3107
3117
  ];
3108
3118
  }],
3109
3119
  // this backslash is dummy and will be ignored in later stages
@@ -3113,7 +3123,7 @@ var rules_map2 = /* @__PURE__ */ new Map([
3113
3123
  (s) => {
3114
3124
  const text = s.text().substring(1, s.text().length - 1);
3115
3125
  text.replaceAll('\\"', '"');
3116
- return new TypstToken(2 /* TEXT */, text);
3126
+ return new TypstToken(3 /* TEXT */, text);
3117
3127
  }
3118
3128
  ],
3119
3129
  [
@@ -3121,15 +3131,16 @@ var rules_map2 = /* @__PURE__ */ new Map([
3121
3131
  (s) => {
3122
3132
  const shorthand = s.text();
3123
3133
  const symbol = reverseShorthandMap.get(shorthand);
3124
- return new TypstToken(0 /* SYMBOL */, symbol);
3134
+ return new TypstToken(1 /* SYMBOL */, symbol);
3125
3135
  }
3126
3136
  ],
3127
- [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3128
- [String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(1 /* ELEMENT */, s.text())],
3137
+ [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3138
+ [String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3129
3139
  [String.raw`[a-zA-Z\.]+`, (s) => {
3130
- return new TypstToken(s.text().length === 1 ? 1 /* ELEMENT */ : 0 /* SYMBOL */, s.text());
3140
+ return new TypstToken(s.text().length === 1 ? 2 /* ELEMENT */ : 1 /* SYMBOL */, s.text());
3131
3141
  }],
3132
- [String.raw`.`, (s) => new TypstToken(1 /* ELEMENT */, s.text())]
3142
+ [String.raw`#none`, (s) => new TypstToken(0 /* NONE */, s.text())],
3143
+ [String.raw`.`, (s) => new TypstToken(2 /* ELEMENT */, s.text())]
3133
3144
  ]);
3134
3145
  var spec2 = {
3135
3146
  "start": rules_map2
@@ -3203,7 +3214,7 @@ function next_non_whitespace(nodes, start) {
3203
3214
  while (pos < nodes.length && nodes[pos].type === "whitespace") {
3204
3215
  pos++;
3205
3216
  }
3206
- return pos === nodes.length ? TYPST_EMPTY_NODE : nodes[pos];
3217
+ return pos === nodes.length ? null : nodes[pos];
3207
3218
  }
3208
3219
  function trim_whitespace_around_operators(nodes) {
3209
3220
  let after_operator = false;
@@ -3214,7 +3225,7 @@ function trim_whitespace_around_operators(nodes) {
3214
3225
  if (after_operator) {
3215
3226
  continue;
3216
3227
  }
3217
- if (next_non_whitespace(nodes, i + 1).eq(DIV)) {
3228
+ if (next_non_whitespace(nodes, i + 1)?.eq(DIV)) {
3218
3229
  continue;
3219
3230
  }
3220
3231
  }
@@ -3273,9 +3284,7 @@ function process_operators(nodes, parenthesis = false) {
3273
3284
  if (parenthesis) {
3274
3285
  return new TypstNode("group", "parenthesis", args);
3275
3286
  } else {
3276
- if (args.length === 0) {
3277
- return TYPST_EMPTY_NODE;
3278
- } else if (args.length === 1) {
3287
+ if (args.length === 1) {
3279
3288
  return args[0];
3280
3289
  } else {
3281
3290
  return new TypstNode("group", "", args);
@@ -3290,16 +3299,16 @@ var TypstParserError = class extends Error {
3290
3299
  };
3291
3300
  var SUB_SYMBOL2 = new TypstToken(6 /* CONTROL */, "_");
3292
3301
  var SUP_SYMBOL2 = new TypstToken(6 /* CONTROL */, "^");
3293
- var LEFT_PARENTHESES = new TypstToken(1 /* ELEMENT */, "(");
3294
- var RIGHT_PARENTHESES = new TypstToken(1 /* ELEMENT */, ")");
3295
- var LEFT_BRACKET = new TypstToken(1 /* ELEMENT */, "[");
3296
- var RIGHT_BRACKET = new TypstToken(1 /* ELEMENT */, "]");
3297
- var LEFT_CURLY_BRACKET2 = new TypstToken(1 /* ELEMENT */, "{");
3298
- var RIGHT_CURLY_BRACKET2 = new TypstToken(1 /* ELEMENT */, "}");
3299
- var VERTICAL_BAR = new TypstToken(1 /* ELEMENT */, "|");
3300
- var COMMA = new TypstToken(1 /* ELEMENT */, ",");
3301
- var SEMICOLON = new TypstToken(1 /* ELEMENT */, ";");
3302
- var SINGLE_SPACE = new TypstToken(4 /* SPACE */, " ");
3302
+ var LEFT_PARENTHESES = new TypstToken(2 /* ELEMENT */, "(");
3303
+ var RIGHT_PARENTHESES = new TypstToken(2 /* ELEMENT */, ")");
3304
+ var LEFT_BRACKET = new TypstToken(2 /* ELEMENT */, "[");
3305
+ var RIGHT_BRACKET = new TypstToken(2 /* ELEMENT */, "]");
3306
+ var LEFT_CURLY_BRACKET2 = new TypstToken(2 /* ELEMENT */, "{");
3307
+ var RIGHT_CURLY_BRACKET2 = new TypstToken(2 /* ELEMENT */, "}");
3308
+ var VERTICAL_BAR = new TypstToken(2 /* ELEMENT */, "|");
3309
+ var COMMA = new TypstToken(2 /* ELEMENT */, ",");
3310
+ var SEMICOLON = new TypstToken(2 /* ELEMENT */, ";");
3311
+ var SINGLE_SPACE = new TypstToken(5 /* SPACE */, " ");
3303
3312
  var TypstParser = class {
3304
3313
  constructor(space_sensitive = true, newline_sensitive = true) {
3305
3314
  this.space_sensitive = space_sensitive;
@@ -3329,9 +3338,7 @@ var TypstParser = class {
3329
3338
  if (parentheses) {
3330
3339
  node = process_operators(results, true);
3331
3340
  } else {
3332
- if (results.length === 0) {
3333
- node = TYPST_EMPTY_NODE;
3334
- } else if (results.length === 1) {
3341
+ if (results.length === 1) {
3335
3342
  node = results[0];
3336
3343
  } else {
3337
3344
  node = process_operators(results);
@@ -3395,10 +3402,10 @@ var TypstParser = class {
3395
3402
  const pos_closing = find_closing_match2(tokens, start);
3396
3403
  return this.parseGroup(tokens, start + 1, pos_closing, true);
3397
3404
  }
3398
- if (firstToken.type === 1 /* ELEMENT */ && !isalpha(firstToken.value[0])) {
3405
+ if (firstToken.type === 2 /* ELEMENT */ && !isalpha(firstToken.value[0])) {
3399
3406
  return [node, start + 1];
3400
3407
  }
3401
- if ([1 /* ELEMENT */, 0 /* SYMBOL */].includes(firstToken.type)) {
3408
+ if ([2 /* ELEMENT */, 1 /* SYMBOL */].includes(firstToken.type)) {
3402
3409
  if (start + 1 < tokens.length && tokens[start + 1].eq(LEFT_PARENTHESES)) {
3403
3410
  if (firstToken.value === "mat") {
3404
3411
  const [matrix, named_params, newPos2] = this.parseGroupsOfArguments(tokens, start + 1);
@@ -3475,18 +3482,24 @@ var TypstParser = class {
3475
3482
  to_delete.push(i);
3476
3483
  const param_name = g.args[pos_colon - 1];
3477
3484
  if (param_name.eq(new TypstNode("symbol", "delim"))) {
3478
- if (g.args[pos_colon + 1].type === "text") {
3479
- np2["delim"] = g.args[pos_colon + 1].content;
3480
- if (g.args.length !== 3) {
3481
- throw new TypstParserError("Invalid number of arguments for delim");
3485
+ if (g.args.length !== 3) {
3486
+ throw new TypstParserError("Invalid number of arguments for delim");
3487
+ }
3488
+ switch (g.args[pos_colon + 1].type) {
3489
+ case "text": {
3490
+ np2["delim"] = g.args[pos_colon + 1].content;
3491
+ break;
3492
+ }
3493
+ case "none": {
3494
+ np2["delim"] = TYPST_NONE;
3495
+ break;
3482
3496
  }
3483
- } else if (g.args[pos_colon + 1].eq(new TypstNode("atom", "#"))) {
3484
- if (g.args.length !== 4 || !g.args[pos_colon + 2].eq(new TypstNode("symbol", "none"))) {
3485
- throw new TypstParserError("Invalid number of arguments for delim");
3497
+ case "symbol": {
3498
+ np2["delim"] = g.args[pos_colon + 1];
3499
+ break;
3486
3500
  }
3487
- np2["delim"] = TYPST_NONE;
3488
- } else {
3489
- throw new TypstParserError("Not implemented for other types of delim");
3501
+ default:
3502
+ throw new TypstParserError("Not implemented for other types of delim");
3490
3503
  }
3491
3504
  } else {
3492
3505
  throw new TypstParserError("Not implemented for other named parameters");
@@ -3531,9 +3544,7 @@ var TypstParser = class {
3531
3544
  nodes.push(argItem);
3532
3545
  }
3533
3546
  let arg;
3534
- if (nodes.length === 0) {
3535
- arg = TYPST_EMPTY_NODE;
3536
- } else if (nodes.length === 1) {
3547
+ if (nodes.length === 1) {
3537
3548
  arg = nodes[0];
3538
3549
  } else {
3539
3550
  arg = process_operators(nodes);