tex2typst 0.3.21 → 0.3.23

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,8 +1,8 @@
1
1
  // src/map.ts
2
2
  var symbolMap = /* @__PURE__ */ new Map([
3
3
  ["displaystyle", "display"],
4
+ ["hspace", "#h"],
4
5
  ["|", "bar.v.double"],
5
- ["!", "#h(-math.thin.amount)"],
6
6
  [",", "thin"],
7
7
  [":", "med"],
8
8
  [";", "thick"],
@@ -1056,7 +1056,6 @@ var reverseSymbolMap = /* @__PURE__ */ new Map();
1056
1056
  for (const [key, value] of Array.from(symbolMap.entries()).reverse()) {
1057
1057
  reverseSymbolMap.set(value, key);
1058
1058
  }
1059
- reverseSymbolMap.set("dif", "mathrm{d}");
1060
1059
  reverseSymbolMap.set("oo", "infty");
1061
1060
  var typst_to_tex_map = /* @__PURE__ */ new Map([
1062
1061
  ["top", "top"],
@@ -1065,8 +1064,7 @@ var typst_to_tex_map = /* @__PURE__ */ new Map([
1065
1064
  ["hat", "hat"],
1066
1065
  ["upright", "mathrm"],
1067
1066
  ["bold", "boldsymbol"],
1068
- ["infinity", "infty"],
1069
- ["hyph.minus", "\\text{-}"]
1067
+ ["infinity", "infty"]
1070
1068
  ]);
1071
1069
  for (const [key, value] of typst_to_tex_map) {
1072
1070
  reverseSymbolMap.set(key, value);
@@ -1108,7 +1106,7 @@ function array_split(array, sep) {
1108
1106
  res.push(current_slice);
1109
1107
  return res;
1110
1108
  }
1111
- function array_join(array, sep) {
1109
+ function array_intersperse(array, sep) {
1112
1110
  const res = [];
1113
1111
  for (let i = 0; i < array.length; i++) {
1114
1112
  res.push(array[i]);
@@ -1130,10 +1128,8 @@ var TexToken = class {
1130
1128
  }
1131
1129
  toString() {
1132
1130
  switch (this.type) {
1133
- case 2 /* TEXT */:
1134
- return `\\text{${this.value}}`;
1135
1131
  case 3 /* COMMENT */:
1136
- return `%${this.value}`;
1132
+ return "%" + this.value;
1137
1133
  default:
1138
1134
  return this.value;
1139
1135
  }
@@ -1156,14 +1152,6 @@ var TexNode = class {
1156
1152
  eq(other) {
1157
1153
  return this.type === other.type && this.content === other.content;
1158
1154
  }
1159
- toString() {
1160
- switch (this.type) {
1161
- case "text":
1162
- return `\\text{${this.content}}`;
1163
- default:
1164
- throw new Error(`toString() is not implemented for type ${this.type}`);
1165
- }
1166
- }
1167
1155
  serialize() {
1168
1156
  switch (this.type) {
1169
1157
  case "empty":
@@ -1175,8 +1163,15 @@ var TexNode = class {
1175
1163
  }
1176
1164
  case "symbol":
1177
1165
  return [new TexToken(1 /* COMMAND */, this.content)];
1166
+ case "literal":
1167
+ return [new TexToken(2 /* LITERAL */, this.content)];
1178
1168
  case "text":
1179
- return [new TexToken(2 /* TEXT */, this.content)];
1169
+ return [
1170
+ new TexToken(1 /* COMMAND */, "\\text"),
1171
+ new TexToken(0 /* ELEMENT */, "{"),
1172
+ new TexToken(2 /* LITERAL */, this.content),
1173
+ new TexToken(0 /* ELEMENT */, "}")
1174
+ ];
1180
1175
  case "comment":
1181
1176
  return [new TexToken(3 /* COMMENT */, this.content)];
1182
1177
  case "whitespace": {
@@ -1308,18 +1303,20 @@ var TypstToken = class {
1308
1303
  switch (this.type) {
1309
1304
  case 0 /* NONE */:
1310
1305
  return new TypstNode("none", "#none");
1311
- case 3 /* TEXT */:
1306
+ case 3 /* LITERAL */:
1307
+ return new TypstNode("literal", this.value);
1308
+ case 4 /* TEXT */:
1312
1309
  return new TypstNode("text", this.value);
1313
- case 4 /* COMMENT */:
1310
+ case 5 /* COMMENT */:
1314
1311
  return new TypstNode("comment", this.value);
1315
- case 5 /* SPACE */:
1316
- case 7 /* NEWLINE */:
1312
+ case 6 /* SPACE */:
1313
+ case 8 /* NEWLINE */:
1317
1314
  return new TypstNode("whitespace", this.value);
1318
1315
  case 2 /* ELEMENT */:
1319
1316
  return new TypstNode("atom", this.value);
1320
1317
  case 1 /* SYMBOL */:
1321
1318
  return new TypstNode("symbol", this.value);
1322
- case 6 /* CONTROL */: {
1319
+ case 7 /* CONTROL */: {
1323
1320
  const controlChar = this.value;
1324
1321
  switch (controlChar) {
1325
1322
  case "":
@@ -1340,9 +1337,9 @@ var TypstToken = class {
1340
1337
  }
1341
1338
  toString() {
1342
1339
  switch (this.type) {
1343
- case 3 /* TEXT */:
1340
+ case 4 /* TEXT */:
1344
1341
  return `"${this.value}"`;
1345
- case 4 /* COMMENT */:
1342
+ case 5 /* COMMENT */:
1346
1343
  return `//${this.value}`;
1347
1344
  default:
1348
1345
  return this.value;
@@ -1387,6 +1384,16 @@ var TypstNode = class {
1387
1384
  return false;
1388
1385
  }
1389
1386
  }
1387
+ toString() {
1388
+ switch (this.type) {
1389
+ case "text":
1390
+ return `"${this.content}"`;
1391
+ case "comment":
1392
+ return `//${this.content}`;
1393
+ default:
1394
+ return this.content;
1395
+ }
1396
+ }
1390
1397
  };
1391
1398
  var TYPST_NONE = new TypstNode("none", "#none");
1392
1399
 
@@ -1403,8 +1410,10 @@ function assert(condition, message = "") {
1403
1410
  // src/jslex.ts
1404
1411
  var EOF = {};
1405
1412
  function matchcompare(m1, m2) {
1406
- if (m2.len !== m1.len) {
1407
- return m2.len - m1.len;
1413
+ const m1_len = m1.reMatchArray[0].length;
1414
+ const m2_len = m2.reMatchArray[0].length;
1415
+ if (m2_len !== m1_len) {
1416
+ return m2_len - m1_len;
1408
1417
  } else {
1409
1418
  return m1.index - m2.index;
1410
1419
  }
@@ -1423,6 +1432,7 @@ var Scanner = class {
1423
1432
  this._newstate = null;
1424
1433
  this._text = null;
1425
1434
  this._leng = null;
1435
+ this._reMatchArray = null;
1426
1436
  this._input = input;
1427
1437
  this._lexer = lexer;
1428
1438
  this._state = lexer.states[0];
@@ -1436,6 +1446,9 @@ var Scanner = class {
1436
1446
  leng() {
1437
1447
  return this._leng;
1438
1448
  }
1449
+ reMatchArray() {
1450
+ return this._reMatchArray;
1451
+ }
1439
1452
  /**
1440
1453
  * Position of in stream, line number and column number of match.
1441
1454
  */
@@ -1528,9 +1541,8 @@ var Scanner = class {
1528
1541
  if (mt !== null && mt[0].length > 0) {
1529
1542
  matches.push({
1530
1543
  index: i,
1531
- text: mt[0],
1532
- len: mt[0].length,
1533
- rule
1544
+ rule,
1545
+ reMatchArray: mt
1534
1546
  });
1535
1547
  }
1536
1548
  }
@@ -1540,22 +1552,24 @@ var Scanner = class {
1540
1552
  matches.sort(matchcompare);
1541
1553
  this._go = true;
1542
1554
  let result;
1543
- let m;
1555
+ let matched_text;
1544
1556
  for (let j = 0, n = matches.length; j < n && this._go; j++) {
1545
1557
  this._offset = 0;
1546
1558
  this._less = null;
1547
1559
  this._go = false;
1548
1560
  this._newstate = null;
1549
- m = matches[j];
1550
- this._text = m.text;
1551
- this._leng = m.len;
1561
+ const m = matches[j];
1562
+ matched_text = m.reMatchArray[0];
1563
+ this._text = matched_text;
1564
+ this._leng = matched_text.length;
1565
+ this._reMatchArray = m.reMatchArray;
1552
1566
  result = m.rule.action(this);
1553
1567
  if (this._newstate && this._newstate != this._state) {
1554
1568
  this._state = this._newstate;
1555
1569
  break;
1556
1570
  }
1557
1571
  }
1558
- const text = this._less === null ? m.text : m.text.substring(0, this._less);
1572
+ const text = this._less === null ? matched_text : matched_text.substring(0, this._less);
1559
1573
  const len = text.length;
1560
1574
  this._pos += len + this._offset;
1561
1575
  const nlm = text.match(/\n/g);
@@ -1689,16 +1703,30 @@ function unescape(str) {
1689
1703
  return str;
1690
1704
  }
1691
1705
  var rules_map = /* @__PURE__ */ new Map([
1706
+ // math `\begin{array}{cc}`
1692
1707
  [
1693
- String.raw`\\(text|operatorname|begin|end|hspace){.+?}`,
1708
+ String.raw`\\begin{(array|subarry)}{(.+?)}`,
1694
1709
  (s) => {
1695
- const text = s.text();
1696
- const command = text.substring(0, text.indexOf("{"));
1697
- const text_inside = text.substring(text.indexOf("{") + 1, text.lastIndexOf("}"));
1710
+ const match = s.reMatchArray();
1698
1711
  return [
1699
- new TexToken(1 /* COMMAND */, command),
1712
+ new TexToken(1 /* COMMAND */, "\\begin"),
1700
1713
  new TexToken(6 /* CONTROL */, "{"),
1701
- new TexToken(2 /* TEXT */, unescape(text_inside)),
1714
+ new TexToken(2 /* LITERAL */, match[1]),
1715
+ new TexToken(6 /* CONTROL */, "}"),
1716
+ new TexToken(6 /* CONTROL */, "{"),
1717
+ new TexToken(2 /* LITERAL */, match[2]),
1718
+ new TexToken(6 /* CONTROL */, "}")
1719
+ ];
1720
+ }
1721
+ ],
1722
+ [
1723
+ String.raw`\\(text|operatorname|begin|end|hspace|array){(.+?)}`,
1724
+ (s) => {
1725
+ const match = s.reMatchArray();
1726
+ return [
1727
+ new TexToken(1 /* COMMAND */, "\\" + match[1]),
1728
+ new TexToken(6 /* CONTROL */, "{"),
1729
+ new TexToken(2 /* LITERAL */, unescape(match[2])),
1702
1730
  new TexToken(6 /* CONTROL */, "}")
1703
1731
  ];
1704
1732
  }
@@ -1711,10 +1739,7 @@ var rules_map = /* @__PURE__ */ new Map([
1711
1739
  [String.raw`\\[{}%$&#_|]`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1712
1740
  // e.g. match `\frac13`, `\frac1 b`, `\frac a b`
1713
1741
  [String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`, (s) => {
1714
- const text = s.text();
1715
- const regex = RegExp(String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`);
1716
- const match = text.match(regex);
1717
- assert(match !== null);
1742
+ const match = s.reMatchArray();
1718
1743
  const command = match[1];
1719
1744
  if (TEX_BINARY_COMMANDS.includes(command.substring(1))) {
1720
1745
  const arg1 = match[2].trimStart();
@@ -1731,10 +1756,7 @@ var rules_map = /* @__PURE__ */ new Map([
1731
1756
  }],
1732
1757
  // e.g. match `\sqrt3`, `\sqrt a`
1733
1758
  [String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])`, (s) => {
1734
- const text = s.text();
1735
- const regex = RegExp(String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])`);
1736
- const match = text.match(regex);
1737
- assert(match !== null);
1759
+ const match = s.reMatchArray();
1738
1760
  const command = match[1];
1739
1761
  if (TEX_UNARY_COMMANDS.includes(command.substring(1))) {
1740
1762
  const arg1 = match[2].trimStart();
@@ -1747,10 +1769,7 @@ var rules_map = /* @__PURE__ */ new Map([
1747
1769
  return [];
1748
1770
  }
1749
1771
  }],
1750
- [String.raw`\\[a-zA-Z]+`, (s) => {
1751
- const command = s.text();
1752
- return [new TexToken(1 /* COMMAND */, command)];
1753
- }],
1772
+ [String.raw`\\[a-zA-Z]+`, (s) => new TexToken(1 /* COMMAND */, s.text())],
1754
1773
  // Numbers like "123", "3.14"
1755
1774
  [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
1756
1775
  [String.raw`[a-zA-Z]`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
@@ -1959,8 +1978,8 @@ var LatexParser = class {
1959
1978
  switch (firstToken.type) {
1960
1979
  case 0 /* ELEMENT */:
1961
1980
  return [new TexNode("element", firstToken.value), start + 1];
1962
- case 2 /* TEXT */:
1963
- return [new TexNode("text", firstToken.value), start + 1];
1981
+ case 2 /* LITERAL */:
1982
+ return [new TexNode("literal", firstToken.value), start + 1];
1964
1983
  case 3 /* COMMENT */:
1965
1984
  return [new TexNode("comment", firstToken.value), start + 1];
1966
1985
  case 4 /* SPACE */:
@@ -2041,7 +2060,7 @@ var LatexParser = class {
2041
2060
  throw new LatexParserError("Expecting content for \\text command");
2042
2061
  }
2043
2062
  assert(tokens[pos].eq(LEFT_CURLY_BRACKET));
2044
- assert(tokens[pos + 1].type === 2 /* TEXT */);
2063
+ assert(tokens[pos + 1].type === 2 /* LITERAL */);
2045
2064
  assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
2046
2065
  const text = tokens[pos + 1].value;
2047
2066
  return [new TexNode("text", text), pos + 3];
@@ -2122,21 +2141,20 @@ var LatexParser = class {
2122
2141
  assert(tokens[start].eq(BEGIN_COMMAND));
2123
2142
  let pos = start + 1;
2124
2143
  assert(tokens[pos].eq(LEFT_CURLY_BRACKET));
2125
- assert(tokens[pos + 1].type === 2 /* TEXT */);
2144
+ assert(tokens[pos + 1].type === 2 /* LITERAL */);
2126
2145
  assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
2127
2146
  const envName = tokens[pos + 1].value;
2128
2147
  pos += 3;
2129
2148
  const args = [];
2130
- while (pos < tokens.length) {
2131
- const whitespaceCount = eat_whitespaces(tokens, pos).length;
2132
- pos += whitespaceCount;
2149
+ if (["array", "subarray"].includes(envName)) {
2133
2150
  if (pos >= tokens.length || !tokens[pos].eq(LEFT_CURLY_BRACKET)) {
2134
- break;
2151
+ throw new LatexParserError(`Missing arg for \\begin{${envName}}`);
2135
2152
  }
2136
2153
  const [arg, newPos] = this.parseNextArg(tokens, pos);
2137
2154
  args.push(arg);
2138
2155
  pos = newPos;
2139
2156
  }
2157
+ pos += eat_whitespaces(tokens, pos).length;
2140
2158
  const exprInsideStart = pos;
2141
2159
  const endIdx = find_closing_end_command(tokens, start);
2142
2160
  if (endIdx === -1) {
@@ -2145,7 +2163,7 @@ var LatexParser = class {
2145
2163
  const exprInsideEnd = endIdx;
2146
2164
  pos = endIdx + 1;
2147
2165
  assert(tokens[pos].eq(LEFT_CURLY_BRACKET));
2148
- assert(tokens[pos + 1].type === 2 /* TEXT */);
2166
+ assert(tokens[pos + 1].type === 2 /* LITERAL */);
2149
2167
  assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
2150
2168
  if (tokens[pos + 1].value !== envName) {
2151
2169
  throw new LatexParserError("Mismatched \\begin and \\end environments");
@@ -2282,20 +2300,7 @@ var TYPST_LEFT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, "(");
2282
2300
  var TYPST_RIGHT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, ")");
2283
2301
  var TYPST_COMMA = new TypstToken(2 /* ELEMENT */, ",");
2284
2302
  var TYPST_NEWLINE = new TypstToken(1 /* SYMBOL */, "\n");
2285
- var SOFT_SPACE = new TypstToken(6 /* CONTROL */, " ");
2286
- function typst_primitive_to_string(value) {
2287
- switch (typeof value) {
2288
- case "string":
2289
- return `"${value}"`;
2290
- case "number":
2291
- return value.toString();
2292
- case "boolean":
2293
- return value ? "#true" : "#false";
2294
- default:
2295
- assert(value instanceof TypstNode, "Not a valid primitive value");
2296
- return value.content;
2297
- }
2298
- }
2303
+ var SOFT_SPACE = new TypstToken(7 /* CONTROL */, " ");
2299
2304
  var TypstWriterError = class extends Error {
2300
2305
  constructor(message, node) {
2301
2306
  super(message);
@@ -2364,17 +2369,20 @@ var TypstWriter = class {
2364
2369
  this.queue.push(new TypstToken(1 /* SYMBOL */, content));
2365
2370
  break;
2366
2371
  }
2372
+ case "literal":
2373
+ this.queue.push(new TypstToken(3 /* LITERAL */, node.content));
2374
+ break;
2367
2375
  case "text":
2368
- this.queue.push(new TypstToken(3 /* TEXT */, node.content));
2376
+ this.queue.push(new TypstToken(4 /* TEXT */, node.content));
2369
2377
  break;
2370
2378
  case "comment":
2371
- this.queue.push(new TypstToken(4 /* COMMENT */, node.content));
2379
+ this.queue.push(new TypstToken(5 /* COMMENT */, node.content));
2372
2380
  break;
2373
2381
  case "whitespace":
2374
2382
  for (const c of node.content) {
2375
2383
  if (c === " ") {
2376
2384
  if (this.keepSpaces) {
2377
- this.queue.push(new TypstToken(5 /* SPACE */, c));
2385
+ this.queue.push(new TypstToken(6 /* SPACE */, c));
2378
2386
  }
2379
2387
  } else if (c === "\n") {
2380
2388
  this.queue.push(new TypstToken(1 /* SYMBOL */, c));
@@ -2425,8 +2433,7 @@ var TypstWriter = class {
2425
2433
  }
2426
2434
  if (node.options) {
2427
2435
  for (const [key, value] of Object.entries(node.options)) {
2428
- const value_str = typst_primitive_to_string(value);
2429
- this.queue.push(new TypstToken(1 /* SYMBOL */, `, ${key}: ${value_str}`));
2436
+ this.queue.push(new TypstToken(3 /* LITERAL */, `, ${key}: ${value.toString()}`));
2430
2437
  }
2431
2438
  }
2432
2439
  this.queue.push(TYPST_RIGHT_PARENTHESIS);
@@ -2469,8 +2476,7 @@ var TypstWriter = class {
2469
2476
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2470
2477
  if (node.options) {
2471
2478
  for (const [key, value] of Object.entries(node.options)) {
2472
- const value_str = typst_primitive_to_string(value);
2473
- this.queue.push(new TypstToken(1 /* SYMBOL */, `${key}: ${value_str}, `));
2479
+ this.queue.push(new TypstToken(3 /* LITERAL */, `${key}: ${value.toString()}, `));
2474
2480
  }
2475
2481
  }
2476
2482
  matrix.forEach((row, i) => {
@@ -2496,8 +2502,7 @@ var TypstWriter = class {
2496
2502
  this.queue.push(TYPST_LEFT_PARENTHESIS);
2497
2503
  if (node.options) {
2498
2504
  for (const [key, value] of Object.entries(node.options)) {
2499
- const value_str = typst_primitive_to_string(value);
2500
- this.queue.push(new TypstToken(1 /* SYMBOL */, `${key}: ${value_str}, `));
2505
+ this.queue.push(new TypstToken(3 /* LITERAL */, `${key}: ${value.toString()}, `));
2501
2506
  }
2502
2507
  }
2503
2508
  cases.forEach((row, i) => {
@@ -2529,7 +2534,7 @@ var TypstWriter = class {
2529
2534
  }
2530
2535
  }
2531
2536
  appendWithBracketsIfNeeded(node) {
2532
- let need_to_wrap = ["group", "supsub", "fraction", "empty"].includes(node.type);
2537
+ let need_to_wrap = ["group", "supsub", "align", "fraction", "empty"].includes(node.type);
2533
2538
  if (node.type === "group") {
2534
2539
  if (node.args.length === 0) {
2535
2540
  need_to_wrap = true;
@@ -2555,7 +2560,7 @@ var TypstWriter = class {
2555
2560
  for (let i = 0; i < this.queue.length; i++) {
2556
2561
  let token = this.queue[i];
2557
2562
  if (token.eq(SOFT_SPACE)) {
2558
- const to_delete = i === 0 || i === this.queue.length - 1 || this.queue[i - 1].type === 5 /* SPACE */ || this.queue[i - 1].isOneOf([TYPST_LEFT_PARENTHESIS, TYPST_NEWLINE]) || this.queue[i + 1].isOneOf([TYPST_RIGHT_PARENTHESIS, TYPST_COMMA, TYPST_NEWLINE]);
2563
+ const to_delete = i === 0 || i === this.queue.length - 1 || this.queue[i - 1].type === 6 /* SPACE */ || this.queue[i - 1].isOneOf([TYPST_LEFT_PARENTHESIS, TYPST_NEWLINE]) || this.queue[i + 1].isOneOf([TYPST_RIGHT_PARENTHESIS, TYPST_COMMA, TYPST_NEWLINE]);
2559
2564
  if (to_delete) {
2560
2565
  this.queue[i] = dummy_token;
2561
2566
  }
@@ -2669,6 +2674,35 @@ function convert_underset(node, options) {
2669
2674
  sub: convert_tex_node_to_typst(sub, options)
2670
2675
  });
2671
2676
  }
2677
+ function convert_tex_array_align_literal(alignLiteral) {
2678
+ const np = {};
2679
+ const alignMap = { l: "#left", c: "#center", r: "#right" };
2680
+ const chars = Array.from(alignLiteral);
2681
+ const vlinePositions = [];
2682
+ let columnIndex = 0;
2683
+ for (const c of chars) {
2684
+ if (c === "|") {
2685
+ vlinePositions.push(columnIndex);
2686
+ } else if (c === "l" || c === "c" || c === "r") {
2687
+ columnIndex++;
2688
+ }
2689
+ }
2690
+ if (vlinePositions.length > 0) {
2691
+ let augment_str;
2692
+ if (vlinePositions.length === 1) {
2693
+ augment_str = `#${vlinePositions[0]}`;
2694
+ } else {
2695
+ augment_str = `#(vline: (${vlinePositions.join(", ")}))`;
2696
+ }
2697
+ np["augment"] = new TypstNode("literal", augment_str);
2698
+ }
2699
+ const alignments = chars.map((c) => alignMap[c]).filter((x) => x !== void 0).map((s) => new TypstNode("literal", s));
2700
+ if (alignments.length > 0) {
2701
+ const all_same = alignments.every((item) => item.eq(alignments[0]));
2702
+ np["align"] = all_same ? alignments[0] : new TypstNode("literal", "#center");
2703
+ }
2704
+ return np;
2705
+ }
2672
2706
  function convert_tex_node_to_typst(node, options = {}) {
2673
2707
  switch (node.type) {
2674
2708
  case "empty":
@@ -2695,6 +2729,8 @@ function convert_tex_node_to_typst(node, options = {}) {
2695
2729
  }
2696
2730
  return new TypstNode("text", node.content);
2697
2731
  }
2732
+ case "literal":
2733
+ return new TypstNode("literal", node.content);
2698
2734
  case "comment":
2699
2735
  return new TypstNode("comment", node.content);
2700
2736
  case "supsub": {
@@ -2829,22 +2865,10 @@ function convert_tex_node_to_typst(node, options = {}) {
2829
2865
  return new TypstNode("symbol", arg0.content);
2830
2866
  }
2831
2867
  }
2832
- return new TypstNode("funcCall", "op", [arg0]);
2833
- }
2834
- if (node.content === "\\hspace") {
2835
- const text = arg0.content;
2836
- return new TypstNode(
2837
- "funcCall",
2838
- "#h",
2839
- [new TypstNode("symbol", text)]
2840
- );
2868
+ return new TypstNode("funcCall", "op", [new TypstNode("text", arg0.content)]);
2841
2869
  }
2842
2870
  if (node.content === "\\substack") {
2843
- return new TypstNode(
2844
- "group",
2845
- "",
2846
- [arg0]
2847
- );
2871
+ return arg0;
2848
2872
  }
2849
2873
  if (options.optimize) {
2850
2874
  if (node.content === "\\mathbb" && arg0.type === "atom" && /^[A-Z]$/.test(arg0.content)) {
@@ -2871,78 +2895,45 @@ function convert_tex_node_to_typst(node, options = {}) {
2871
2895
  }
2872
2896
  if (node.content === "subarray") {
2873
2897
  const align_node = node.args[0];
2874
- if (align_node.content == "r") {
2875
- data.forEach((row) => row[0].args.push(new TypstNode("symbol", "&")));
2876
- }
2877
- if (align_node.content == "l") {
2878
- data.forEach((row) => row[0].args.unshift(new TypstNode("symbol", "&")));
2898
+ switch (align_node.content) {
2899
+ case "r":
2900
+ data.forEach((row) => row[0].args.push(new TypstNode("symbol", "&")));
2901
+ break;
2902
+ case "l":
2903
+ data.forEach((row) => row[0].args.unshift(new TypstNode("symbol", "&")));
2904
+ break;
2905
+ default:
2906
+ break;
2879
2907
  }
2880
- return new TypstNode(
2881
- "group",
2882
- "",
2883
- [new TypstNode("align", "", [], data)]
2884
- );
2908
+ return new TypstNode("align", "", [], data);
2885
2909
  }
2886
2910
  if (node.content === "array") {
2911
+ const np = { "delim": TYPST_NONE };
2912
+ assert(node.args.length > 0 && node.args[0].type === "literal");
2913
+ const np_new = convert_tex_array_align_literal(node.args[0].content);
2914
+ Object.assign(np, np_new);
2887
2915
  const res = new TypstNode("matrix", "", [], data);
2888
- const options2 = { "delim": TYPST_NONE };
2889
- const align_args = node.args;
2890
- if (align_args.length > 0) {
2891
- const align_node = align_args[0];
2892
- const align_str = (() => {
2893
- if (align_node.type === "element") return align_node.content;
2894
- if (align_node.type === "ordgroup") {
2895
- return align_node.args.map((n) => n.type === "element" ? n.content : "").join("");
2896
- }
2897
- return "";
2898
- })();
2899
- if (align_str) {
2900
- const alignMap = { l: "#left", c: "#center", r: "#right" };
2901
- const chars = Array.from(align_str);
2902
- const alignments = chars.map((c) => alignMap[c]).filter(Boolean).map((s) => new TypstNode("symbol", s));
2903
- const vlinePositions = [];
2904
- let columnIndex = 0;
2905
- for (const c of chars) {
2906
- if (c === "|") {
2907
- vlinePositions.push(columnIndex);
2908
- } else if (c === "l" || c === "c" || c === "r") {
2909
- columnIndex++;
2910
- }
2911
- }
2912
- if (vlinePositions.length > 0) {
2913
- if (vlinePositions.length === 1) {
2914
- options2["augment"] = new TypstNode("symbol", `#${vlinePositions[0]}`);
2915
- } else {
2916
- options2["augment"] = new TypstNode("symbol", `#(vline: (${vlinePositions.join(", ")}))`);
2917
- }
2918
- }
2919
- if (alignments.length > 0) {
2920
- const first_align = alignments[0].content;
2921
- const all_same = alignments.every((item) => item.content === first_align);
2922
- options2["align"] = all_same ? alignments[0] : new TypstNode("symbol", "#center");
2923
- }
2924
- }
2925
- }
2926
- res.setOptions(options2);
2916
+ res.setOptions(np);
2927
2917
  return res;
2928
2918
  }
2929
2919
  if (node.content.endsWith("matrix")) {
2920
+ const res = new TypstNode("matrix", "", [], data);
2930
2921
  let delim;
2931
2922
  switch (node.content) {
2932
2923
  case "matrix":
2933
2924
  delim = TYPST_NONE;
2934
2925
  break;
2935
2926
  case "pmatrix":
2936
- delim = "(";
2937
- break;
2927
+ return res;
2928
+ // typst mat use delim:"(" by default
2938
2929
  case "bmatrix":
2939
- delim = "[";
2930
+ delim = new TypstNode("text", "[");
2940
2931
  break;
2941
2932
  case "Bmatrix":
2942
- delim = "{";
2933
+ delim = new TypstNode("text", "{");
2943
2934
  break;
2944
2935
  case "vmatrix":
2945
- delim = "|";
2936
+ delim = new TypstNode("text", "|");
2946
2937
  break;
2947
2938
  case "Vmatrix": {
2948
2939
  delim = new TypstNode("symbol", "bar.v.double");
@@ -2951,7 +2942,6 @@ function convert_tex_node_to_typst(node, options = {}) {
2951
2942
  default:
2952
2943
  throw new TypstWriterError(`Unimplemented beginend: ${node.content}`, node);
2953
2944
  }
2954
- const res = new TypstNode("matrix", "", [], data);
2955
2945
  res.setOptions({ "delim": delim });
2956
2946
  return res;
2957
2947
  }
@@ -2962,6 +2952,10 @@ function convert_tex_node_to_typst(node, options = {}) {
2962
2952
  case "control":
2963
2953
  if (node.content === "\\\\") {
2964
2954
  return new TypstNode("symbol", "\\");
2955
+ } else if (node.content === "\\!") {
2956
+ return new TypstNode("funcCall", "#h", [
2957
+ new TypstNode("literal", "-math.thin.amount")
2958
+ ]);
2965
2959
  } else if (symbolMap.has(node.content.substring(1))) {
2966
2960
  const typst_symbol = symbolMap.get(node.content.substring(1));
2967
2961
  return new TypstNode("symbol", typst_symbol);
@@ -2972,34 +2966,6 @@ function convert_tex_node_to_typst(node, options = {}) {
2972
2966
  throw new TypstWriterError(`Unimplemented node type: ${node.type}`, node);
2973
2967
  }
2974
2968
  }
2975
- var TYPST_UNARY_FUNCTIONS = [
2976
- "sqrt",
2977
- "bold",
2978
- "arrow",
2979
- "upright",
2980
- "lr",
2981
- "op",
2982
- "macron",
2983
- "dot",
2984
- "dot.double",
2985
- "hat",
2986
- "tilde",
2987
- "overline",
2988
- "underline",
2989
- "bb",
2990
- "cal",
2991
- "frak",
2992
- "floor",
2993
- "ceil",
2994
- "norm",
2995
- "limits"
2996
- ];
2997
- var TYPST_BINARY_FUNCTIONS = [
2998
- "frac",
2999
- "root",
3000
- "overbrace",
3001
- "underbrace"
3002
- ];
3003
2969
  function apply_escape_if_needed2(c) {
3004
2970
  if (["{", "}", "%"].includes(c)) {
3005
2971
  return "\\" + c;
@@ -3029,18 +2995,25 @@ function convert_typst_node_to_tex(node) {
3029
2995
  return new TexNode("whitespace", node.content);
3030
2996
  case "atom":
3031
2997
  return new TexNode("element", node.content);
3032
- case "symbol":
3033
- switch (node.content) {
3034
- // special hook for comma
3035
- case "comma":
3036
- return new TexNode("element", ",");
3037
- // special hook for hyph and hyph.minus
3038
- case "hyph":
3039
- case "hyph.minus":
3040
- return new TexNode("text", "-");
3041
- default:
3042
- return new TexNode("symbol", typst_token_to_tex(node.content));
2998
+ case "symbol": {
2999
+ if (node.content === "comma") {
3000
+ return new TexNode("element", ",");
3001
+ }
3002
+ if (node.content === "dif") {
3003
+ return new TexNode("unaryFunc", "\\mathrm", [new TexNode("element", "d")]);
3043
3004
  }
3005
+ if (node.content === "hyph" || node.content === "hyph.minus") {
3006
+ return new TexNode("text", "-");
3007
+ }
3008
+ if (/^([A-Z])\1$/.test(node.content)) {
3009
+ return new TexNode("unaryFunc", "\\mathbb", [
3010
+ new TexNode("element", node.content[0])
3011
+ ]);
3012
+ }
3013
+ return new TexNode("symbol", typst_token_to_tex(node.content));
3014
+ }
3015
+ case "literal":
3016
+ return new TexNode("literal", node.content);
3044
3017
  case "text":
3045
3018
  return new TexNode("text", node.content);
3046
3019
  case "comment":
@@ -3057,68 +3030,67 @@ function convert_typst_node_to_tex(node) {
3057
3030
  return new TexNode("ordgroup", node.content, args);
3058
3031
  }
3059
3032
  case "funcCall": {
3060
- if (TYPST_UNARY_FUNCTIONS.includes(node.content)) {
3061
- if (node.content === "lr") {
3062
- const data = node.data;
3063
- if (data.leftDelim !== null) {
3064
- let left_delim = apply_escape_if_needed2(data.leftDelim);
3065
- assert(data.rightDelim !== null, "leftDelim has value but rightDelim not");
3066
- let right_delim = apply_escape_if_needed2(data.rightDelim);
3067
- return new TexNode("ordgroup", "", [
3068
- new TexNode("element", "\\left" + left_delim),
3069
- ...node.args.map(convert_typst_node_to_tex),
3070
- new TexNode("element", "\\right" + right_delim)
3071
- ]);
3072
- } else {
3073
- return new TexNode("ordgroup", "", node.args.map(convert_typst_node_to_tex));
3074
- }
3075
- }
3076
- if (node.content === "norm") {
3077
- const arg0 = node.args[0];
3078
- const tex_node_type = node.isOverHigh() ? "leftright" : "ordgroup";
3079
- return new TexNode(tex_node_type, "", [
3080
- new TexNode("symbol", "\\|"),
3081
- convert_typst_node_to_tex(arg0),
3082
- new TexNode("symbol", "\\|")
3083
- ]);
3084
- }
3085
- if (node.content === "floor" || node.content === "ceil") {
3086
- const left = "\\l" + node.content;
3087
- const right = "\\r" + node.content;
3088
- const arg0 = node.args[0];
3089
- const tex_node_type = node.isOverHigh() ? "leftright" : "ordgroup";
3090
- return new TexNode(tex_node_type, "", [
3091
- new TexNode("symbol", left),
3092
- convert_typst_node_to_tex(arg0),
3093
- new TexNode("symbol", right)
3033
+ if (node.content === "lr") {
3034
+ const data = node.data;
3035
+ if (data.leftDelim !== null) {
3036
+ let left_delim = apply_escape_if_needed2(data.leftDelim);
3037
+ assert(data.rightDelim !== null, "leftDelim has value but rightDelim not");
3038
+ let right_delim = apply_escape_if_needed2(data.rightDelim);
3039
+ return new TexNode("ordgroup", "", [
3040
+ new TexNode("element", "\\left" + left_delim),
3041
+ ...node.args.map(convert_typst_node_to_tex),
3042
+ new TexNode("element", "\\right" + right_delim)
3094
3043
  ]);
3044
+ } else {
3045
+ return new TexNode("ordgroup", "", node.args.map(convert_typst_node_to_tex));
3095
3046
  }
3096
- const command = typst_token_to_tex(node.content);
3097
- return new TexNode("unaryFunc", command, node.args.map(convert_typst_node_to_tex));
3098
- } else if (TYPST_BINARY_FUNCTIONS.includes(node.content)) {
3099
- if (node.content === "root") {
3100
- const [degree, radicand] = node.args;
3101
- const data = convert_typst_node_to_tex(degree);
3102
- return new TexNode("unaryFunc", "\\sqrt", [convert_typst_node_to_tex(radicand)], data);
3103
- }
3104
- if (node.content === "overbrace" || node.content === "underbrace") {
3105
- const [body, label] = node.args;
3106
- const base = new TexNode("unaryFunc", "\\" + node.content, [convert_typst_node_to_tex(body)]);
3107
- const script = convert_typst_node_to_tex(label);
3108
- const data = node.content === "overbrace" ? { base, sup: script } : { base, sub: script };
3109
- return new TexNode("supsub", "", [], data);
3110
- }
3111
- const command = typst_token_to_tex(node.content);
3112
- return new TexNode("binaryFunc", command, node.args.map(convert_typst_node_to_tex));
3047
+ }
3048
+ if (node.content === "norm") {
3049
+ const arg0 = node.args[0];
3050
+ const tex_node_type = node.isOverHigh() ? "leftright" : "ordgroup";
3051
+ return new TexNode(tex_node_type, "", [
3052
+ new TexNode("symbol", "\\|"),
3053
+ convert_typst_node_to_tex(arg0),
3054
+ new TexNode("symbol", "\\|")
3055
+ ]);
3056
+ }
3057
+ if (node.content === "floor" || node.content === "ceil") {
3058
+ const left = "\\l" + node.content;
3059
+ const right = "\\r" + node.content;
3060
+ const arg0 = node.args[0];
3061
+ const tex_node_type = node.isOverHigh() ? "leftright" : "ordgroup";
3062
+ return new TexNode(tex_node_type, "", [
3063
+ new TexNode("symbol", left),
3064
+ convert_typst_node_to_tex(arg0),
3065
+ new TexNode("symbol", right)
3066
+ ]);
3067
+ }
3068
+ if (node.content === "root") {
3069
+ const [degree, radicand] = node.args;
3070
+ const data = convert_typst_node_to_tex(degree);
3071
+ return new TexNode("unaryFunc", "\\sqrt", [convert_typst_node_to_tex(radicand)], data);
3072
+ }
3073
+ if (node.content === "overbrace" || node.content === "underbrace") {
3074
+ const [body, label] = node.args;
3075
+ const base = new TexNode("unaryFunc", "\\" + node.content, [convert_typst_node_to_tex(body)]);
3076
+ const script = convert_typst_node_to_tex(label);
3077
+ const data = node.content === "overbrace" ? { base, sup: script } : { base, sub: script };
3078
+ return new TexNode("supsub", "", [], data);
3079
+ }
3080
+ if (node.content === "vec") {
3081
+ const tex_data = node.args.map(convert_typst_node_to_tex).map((n) => [n]);
3082
+ return new TexNode("beginend", "pmatrix", [], tex_data);
3083
+ }
3084
+ const func_name_tex = typst_token_to_tex(node.content);
3085
+ if (func_name_tex.length > 0 && TEX_UNARY_COMMANDS.includes(func_name_tex.substring(1))) {
3086
+ return new TexNode("unaryFunc", func_name_tex, node.args.map(convert_typst_node_to_tex));
3087
+ } else if (func_name_tex.length > 0 && TEX_BINARY_COMMANDS.includes(func_name_tex.substring(1))) {
3088
+ return new TexNode("binaryFunc", func_name_tex, node.args.map(convert_typst_node_to_tex));
3113
3089
  } else {
3114
- if (node.content === "vec") {
3115
- const tex_data = node.args.map(convert_typst_node_to_tex).map((n) => [n]);
3116
- return new TexNode("beginend", "pmatrix", [], tex_data);
3117
- }
3118
3090
  return new TexNode("ordgroup", "", [
3119
3091
  new TexNode("symbol", typst_token_to_tex(node.content)),
3120
3092
  new TexNode("element", "("),
3121
- ...array_join(node.args.map(convert_typst_node_to_tex), TEX_NODE_COMMA),
3093
+ ...array_intersperse(node.args.map(convert_typst_node_to_tex), TEX_NODE_COMMA),
3122
3094
  new TexNode("element", ")")
3123
3095
  ]);
3124
3096
  }
@@ -3159,43 +3131,34 @@ function convert_typst_node_to_tex(node) {
3159
3131
  if (node.options) {
3160
3132
  if ("delim" in node.options) {
3161
3133
  const delim = node.options.delim;
3162
- if (delim instanceof TypstNode) {
3163
- switch (delim.content) {
3164
- case "#none":
3165
- env_type = "matrix";
3166
- break;
3167
- case "bar.v.double":
3168
- env_type = "Vmatrix";
3169
- break;
3170
- case "bar":
3171
- case "bar.v":
3172
- env_type = "vmatrix";
3173
- break;
3174
- default:
3175
- throw new Error(`Unexpected delimiter ${delim.content}`);
3176
- }
3177
- } else {
3178
- switch (delim) {
3179
- case "[":
3180
- env_type = "bmatrix";
3181
- break;
3182
- case "]":
3183
- env_type = "bmatrix";
3184
- break;
3185
- case "{":
3186
- env_type = "Bmatrix";
3187
- break;
3188
- case "}":
3189
- env_type = "Bmatrix";
3190
- break;
3191
- case "|":
3192
- env_type = "vmatrix";
3193
- break;
3194
- case ")":
3195
- case "(":
3196
- default:
3197
- env_type = "pmatrix";
3198
- }
3134
+ switch (delim.content) {
3135
+ case "#none":
3136
+ env_type = "matrix";
3137
+ break;
3138
+ case "[":
3139
+ case "]":
3140
+ env_type = "bmatrix";
3141
+ break;
3142
+ case "(":
3143
+ case ")":
3144
+ env_type = "pmatrix";
3145
+ break;
3146
+ case "{":
3147
+ case "}":
3148
+ env_type = "Bmatrix";
3149
+ break;
3150
+ case "|":
3151
+ env_type = "vmatrix";
3152
+ break;
3153
+ case "bar":
3154
+ case "bar.v":
3155
+ env_type = "vmatrix";
3156
+ break;
3157
+ case "bar.v.double":
3158
+ env_type = "Vmatrix";
3159
+ break;
3160
+ default:
3161
+ throw new Error(`Unexpected delimiter ${delim.content}`);
3199
3162
  }
3200
3163
  }
3201
3164
  }
@@ -3241,32 +3204,32 @@ function generate_regex_for_shorthands() {
3241
3204
  }
3242
3205
  var REGEX_SHORTHANDS = generate_regex_for_shorthands();
3243
3206
  var rules_map2 = /* @__PURE__ */ new Map([
3244
- [String.raw`//[^\n]*`, (s) => new TypstToken(4 /* COMMENT */, s.text().substring(2))],
3207
+ [String.raw`//[^\n]*`, (s) => new TypstToken(5 /* COMMENT */, s.text().substring(2))],
3245
3208
  [String.raw`/`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3246
- [String.raw`[_^&]`, (s) => new TypstToken(6 /* CONTROL */, s.text())],
3247
- [String.raw`\r?\n`, (_s) => new TypstToken(7 /* NEWLINE */, "\n")],
3248
- [String.raw`\s+`, (s) => new TypstToken(5 /* SPACE */, s.text())],
3209
+ [String.raw`[_^&]`, (s) => new TypstToken(7 /* CONTROL */, s.text())],
3210
+ [String.raw`\r?\n`, (_s) => new TypstToken(8 /* NEWLINE */, "\n")],
3211
+ [String.raw`\s+`, (s) => new TypstToken(6 /* SPACE */, s.text())],
3249
3212
  [String.raw`\\[$&#_]`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3250
3213
  [String.raw`\\\n`, (s) => {
3251
3214
  return [
3252
- new TypstToken(6 /* CONTROL */, "\\"),
3253
- new TypstToken(7 /* NEWLINE */, "\n")
3215
+ new TypstToken(7 /* CONTROL */, "\\"),
3216
+ new TypstToken(8 /* NEWLINE */, "\n")
3254
3217
  ];
3255
3218
  }],
3256
3219
  [String.raw`\\\s`, (s) => {
3257
3220
  return [
3258
- new TypstToken(6 /* CONTROL */, "\\"),
3259
- new TypstToken(5 /* SPACE */, " ")
3221
+ new TypstToken(7 /* CONTROL */, "\\"),
3222
+ new TypstToken(6 /* SPACE */, " ")
3260
3223
  ];
3261
3224
  }],
3262
3225
  // this backslash is dummy and will be ignored in later stages
3263
- [String.raw`\\\S`, (_s) => new TypstToken(6 /* CONTROL */, "")],
3226
+ [String.raw`\\\S`, (_s) => new TypstToken(7 /* CONTROL */, "")],
3264
3227
  [
3265
3228
  String.raw`"([^"]|(\\"))*"`,
3266
3229
  (s) => {
3267
3230
  const text = s.text().substring(1, s.text().length - 1);
3268
3231
  text.replaceAll('\\"', '"');
3269
- return new TypstToken(3 /* TEXT */, text);
3232
+ return new TypstToken(4 /* TEXT */, text);
3270
3233
  }
3271
3234
  ],
3272
3235
  [
@@ -3279,6 +3242,15 @@ var rules_map2 = /* @__PURE__ */ new Map([
3279
3242
  ],
3280
3243
  [String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3281
3244
  [String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(2 /* ELEMENT */, s.text())],
3245
+ [String.raw`#h\((.+?)\)`, (s) => {
3246
+ const match = s.reMatchArray();
3247
+ return [
3248
+ new TypstToken(1 /* SYMBOL */, "#h"),
3249
+ new TypstToken(2 /* ELEMENT */, "("),
3250
+ new TypstToken(3 /* LITERAL */, match[1]),
3251
+ new TypstToken(2 /* ELEMENT */, ")")
3252
+ ];
3253
+ }],
3282
3254
  [String.raw`[a-zA-Z\.]+`, (s) => {
3283
3255
  return new TypstToken(s.text().length === 1 ? 2 /* ELEMENT */ : 1 /* SYMBOL */, s.text());
3284
3256
  }],
@@ -3449,8 +3421,8 @@ var TypstParserError = class extends Error {
3449
3421
  this.name = "TypstParserError";
3450
3422
  }
3451
3423
  };
3452
- var SUB_SYMBOL2 = new TypstToken(6 /* CONTROL */, "_");
3453
- var SUP_SYMBOL2 = new TypstToken(6 /* CONTROL */, "^");
3424
+ var SUB_SYMBOL2 = new TypstToken(7 /* CONTROL */, "_");
3425
+ var SUP_SYMBOL2 = new TypstToken(7 /* CONTROL */, "^");
3454
3426
  var LEFT_PARENTHESES = new TypstToken(2 /* ELEMENT */, "(");
3455
3427
  var RIGHT_PARENTHESES = new TypstToken(2 /* ELEMENT */, ")");
3456
3428
  var LEFT_BRACKET = new TypstToken(2 /* ELEMENT */, "[");
@@ -3460,7 +3432,7 @@ var RIGHT_CURLY_BRACKET2 = new TypstToken(2 /* ELEMENT */, "}");
3460
3432
  var VERTICAL_BAR = new TypstToken(2 /* ELEMENT */, "|");
3461
3433
  var COMMA = new TypstToken(2 /* ELEMENT */, ",");
3462
3434
  var SEMICOLON = new TypstToken(2 /* ELEMENT */, ";");
3463
- var SINGLE_SPACE = new TypstToken(5 /* SPACE */, " ");
3435
+ var SINGLE_SPACE = new TypstToken(6 /* SPACE */, " ");
3464
3436
  var TypstParser = class {
3465
3437
  constructor(space_sensitive = true, newline_sensitive = true) {
3466
3438
  this.space_sensitive = space_sensitive;
@@ -3637,22 +3609,7 @@ var TypstParser = class {
3637
3609
  if (g.args.length !== 3) {
3638
3610
  throw new TypstParserError("Invalid number of arguments for delim");
3639
3611
  }
3640
- switch (g.args[pos_colon + 1].type) {
3641
- case "text": {
3642
- np2["delim"] = g.args[pos_colon + 1].content;
3643
- break;
3644
- }
3645
- case "none": {
3646
- np2["delim"] = TYPST_NONE;
3647
- break;
3648
- }
3649
- case "symbol": {
3650
- np2["delim"] = g.args[pos_colon + 1];
3651
- break;
3652
- }
3653
- default:
3654
- throw new TypstParserError("Not implemented for other types of delim");
3655
- }
3612
+ np2["delim"] = g.args[pos_colon + 1];
3656
3613
  } else {
3657
3614
  throw new TypstParserError("Not implemented for other named parameters");
3658
3615
  }