tex2typst 0.5.3 → 0.5.5

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
@@ -570,13 +570,22 @@ var TEX_UNARY_COMMANDS = [
570
570
  "overrightarrow",
571
571
  "hspace",
572
572
  "substack",
573
- "set",
574
573
  "displaylines",
575
574
  "mathinner",
576
575
  "mathrel",
577
576
  "mathbin",
578
577
  "mathop",
579
- "not"
578
+ "not",
579
+ // the braket package
580
+ "bra",
581
+ "ket",
582
+ "braket",
583
+ "set",
584
+ "Bra",
585
+ "Ket",
586
+ "Braket",
587
+ "Set",
588
+ "pmod"
580
589
  ];
581
590
  var TEX_BINARY_COMMANDS = [
582
591
  "frac",
@@ -719,7 +728,7 @@ function eat_whitespaces(tokens, start) {
719
728
  }
720
729
  function eat_parenthesis(tokens, start) {
721
730
  const firstToken = tokens[start];
722
- if (firstToken.type === 1 /* ELEMENT */ && ["(", ")", "[", "]", "|", "\\{", "\\}", ".", "\\|"].includes(firstToken.value)) {
731
+ if (firstToken.type === 1 /* ELEMENT */ && ["(", ")", "[", "]", "|", "\\{", "\\}", ".", "\\|", "<", ">"].includes(firstToken.value)) {
723
732
  return firstToken;
724
733
  } else if (firstToken.type === 2 /* COMMAND */ && ["lfloor", "rfloor", "lceil", "rceil", "langle", "rangle", "lparen", "rparen", "lbrace", "rbrace"].includes(firstToken.value.slice(1))) {
725
734
  return firstToken;
@@ -734,6 +743,29 @@ function eat_primes(tokens, start) {
734
743
  }
735
744
  return pos - start;
736
745
  }
746
+ function process_styled_parts(nodes) {
747
+ let style_token = null;
748
+ let bucket = [];
749
+ let res = [];
750
+ let i = 0;
751
+ while (true) {
752
+ if (i === nodes.length || nodes[i].head.eq(TexToken.COMMAND_DISPLAYSTYLE) || nodes[i].head.eq(TexToken.COMMAND_TEXTSTYLE)) {
753
+ if (bucket.length > 0) {
754
+ const g = bucket.length === 1 ? bucket[0] : new TexGroup(bucket);
755
+ res.push(style_token ? new TexFuncCall(style_token, [g]) : g);
756
+ }
757
+ if (i === nodes.length) {
758
+ break;
759
+ }
760
+ bucket = [];
761
+ style_token = nodes[i].head;
762
+ } else {
763
+ bucket.push(nodes[i]);
764
+ }
765
+ i++;
766
+ }
767
+ return res;
768
+ }
737
769
  var LEFT_COMMAND = new TexToken(2 /* COMMAND */, "\\left");
738
770
  var RIGHT_COMMAND = new TexToken(2 /* COMMAND */, "\\right");
739
771
  var BEGIN_COMMAND = new TexToken(2 /* COMMAND */, "\\begin");
@@ -795,7 +827,7 @@ var LatexParser = class {
795
827
  if (pos >= tokens.length && closingToken !== null) {
796
828
  return [EMPTY_NODE, -1];
797
829
  }
798
- const styledResults = this.applyStyleCommands(results);
830
+ const styledResults = process_styled_parts(results);
799
831
  let node;
800
832
  if (styledResults.length === 1) {
801
833
  node = styledResults[0];
@@ -1081,34 +1113,6 @@ var LatexParser = class {
1081
1113
  this.alignmentDepth--;
1082
1114
  return [allRows, pos];
1083
1115
  }
1084
- applyStyleCommands(nodes) {
1085
- for (let i = 0; i < nodes.length; i++) {
1086
- const styleToken = this.getStyleToken(nodes[i]);
1087
- if (styleToken) {
1088
- const before = this.applyStyleCommands(nodes.slice(0, i));
1089
- const after = this.applyStyleCommands(nodes.slice(i + 1));
1090
- let body;
1091
- if (after.length === 0) {
1092
- body = EMPTY_NODE;
1093
- } else if (after.length === 1) {
1094
- body = after[0];
1095
- } else {
1096
- body = new TexGroup(after);
1097
- }
1098
- const funcCall = new TexFuncCall(styleToken, [body]);
1099
- return before.concat(funcCall);
1100
- }
1101
- }
1102
- return nodes;
1103
- }
1104
- getStyleToken(node) {
1105
- if (node.type === "terminal") {
1106
- if (node.head.eq(TexToken.COMMAND_DISPLAYSTYLE) || node.head.eq(TexToken.COMMAND_TEXTSTYLE)) {
1107
- return node.head;
1108
- }
1109
- }
1110
- return null;
1111
- }
1112
1116
  };
1113
1117
  function passIgnoreWhitespaceBeforeScriptMark(tokens) {
1114
1118
  const is_script_mark = (token) => token.eq(SUB_SYMBOL) || token.eq(SUP_SYMBOL);
@@ -1225,23 +1229,29 @@ var TypstToken = class _TypstToken {
1225
1229
  static EMPTY = new _TypstToken(2 /* ELEMENT */, "");
1226
1230
  static LEFT_BRACE = new _TypstToken(2 /* ELEMENT */, "{");
1227
1231
  static RIGHT_BRACE = new _TypstToken(2 /* ELEMENT */, "}");
1232
+ static LEFT_PAREN = new _TypstToken(2 /* ELEMENT */, "(");
1233
+ static RIGHT_PAREN = new _TypstToken(2 /* ELEMENT */, ")");
1234
+ static LEFT_ANGLE = new _TypstToken(1 /* SYMBOL */, "chevron.l");
1235
+ static RIGHT_ANGLE = new _TypstToken(1 /* SYMBOL */, "chevron.r");
1236
+ static VERTICAL_BAR = new _TypstToken(2 /* ELEMENT */, "|");
1228
1237
  static PLUS = new _TypstToken(2 /* ELEMENT */, "+");
1229
1238
  static MINUS = new _TypstToken(2 /* ELEMENT */, "-");
1239
+ static LR = new _TypstToken(1 /* SYMBOL */, "lr");
1230
1240
  static LEFT_DELIMITERS = [
1231
- new _TypstToken(2 /* ELEMENT */, "("),
1241
+ _TypstToken.LEFT_PAREN,
1232
1242
  new _TypstToken(2 /* ELEMENT */, "["),
1233
- new _TypstToken(2 /* ELEMENT */, "{"),
1234
- new _TypstToken(2 /* ELEMENT */, "|"),
1235
- new _TypstToken(1 /* SYMBOL */, "chevron.l"),
1243
+ _TypstToken.LEFT_BRACE,
1244
+ _TypstToken.VERTICAL_BAR,
1245
+ _TypstToken.LEFT_ANGLE,
1236
1246
  new _TypstToken(1 /* SYMBOL */, "paren.l"),
1237
1247
  new _TypstToken(1 /* SYMBOL */, "brace.l")
1238
1248
  ];
1239
1249
  static RIGHT_DELIMITERS = [
1240
- new _TypstToken(2 /* ELEMENT */, ")"),
1250
+ _TypstToken.RIGHT_PAREN,
1241
1251
  new _TypstToken(2 /* ELEMENT */, "]"),
1242
- new _TypstToken(2 /* ELEMENT */, "}"),
1243
- new _TypstToken(2 /* ELEMENT */, "|"),
1244
- new _TypstToken(1 /* SYMBOL */, "chevron.r"),
1252
+ _TypstToken.RIGHT_BRACE,
1253
+ _TypstToken.VERTICAL_BAR,
1254
+ _TypstToken.RIGHT_ANGLE,
1245
1255
  new _TypstToken(1 /* SYMBOL */, "paren.r"),
1246
1256
  new _TypstToken(1 /* SYMBOL */, "brace.r")
1247
1257
  ];
@@ -1291,7 +1301,7 @@ var TypstTerminal = class extends TypstNode {
1291
1301
  return true;
1292
1302
  case 1 /* SYMBOL */:
1293
1303
  case 2 /* ELEMENT */: {
1294
- if (["(", "!", "}", "]"].includes(this.head.value)) {
1304
+ if (["(", "!", ",", ")", "}", "]"].includes(this.head.value)) {
1295
1305
  return false;
1296
1306
  }
1297
1307
  return true;
@@ -1321,7 +1331,7 @@ var TypstTerminal = class extends TypstNode {
1321
1331
  serialize(env, options) {
1322
1332
  if (this.head.type === 2 /* ELEMENT */) {
1323
1333
  if (this.head.value === "," && env.insideFunctionDepth > 0) {
1324
- return [new TypstToken(1 /* SYMBOL */, "comma")];
1334
+ return [SOFT_SPACE, new TypstToken(1 /* SYMBOL */, "comma")];
1325
1335
  }
1326
1336
  } else if (this.head.type === 1 /* SYMBOL */) {
1327
1337
  let symbol_name = this.head.value;
@@ -1352,6 +1362,40 @@ var TypstTerminal = class extends TypstNode {
1352
1362
  return [this.head];
1353
1363
  }
1354
1364
  };
1365
+ var TypstTokenQueue = class {
1366
+ queue = [];
1367
+ pushSoftSpace() {
1368
+ if (this.queue.length === 0) {
1369
+ return;
1370
+ } else if (this.queue.at(-1).eq(SOFT_SPACE)) {
1371
+ return;
1372
+ } else if (["(", "{", "["].includes(this.queue.at(-1).value)) {
1373
+ return;
1374
+ }
1375
+ this.queue.push(SOFT_SPACE);
1376
+ }
1377
+ pushAll(tokens) {
1378
+ if (tokens.length == 0) {
1379
+ return;
1380
+ } else if (tokens[0].eq(SOFT_SPACE) && this.queue.length === 0) {
1381
+ this.queue.push(...tokens.slice(1));
1382
+ } else {
1383
+ if ([")", "}", "]"].includes(tokens[0].value)) {
1384
+ while (this.queue.at(-1)?.eq(SOFT_SPACE)) {
1385
+ this.queue.pop();
1386
+ }
1387
+ }
1388
+ this.queue.push(...tokens);
1389
+ }
1390
+ }
1391
+ getQueue() {
1392
+ const res = Array.from(this.queue);
1393
+ while (res.at(-1)?.eq(SOFT_SPACE)) {
1394
+ res.pop();
1395
+ }
1396
+ return res;
1397
+ }
1398
+ };
1355
1399
  var TypstGroup = class extends TypstNode {
1356
1400
  items;
1357
1401
  constructor(items) {
@@ -1377,28 +1421,19 @@ var TypstGroup = class extends TypstNode {
1377
1421
  if (this.items.length === 0) {
1378
1422
  return [];
1379
1423
  }
1380
- const queue = [];
1424
+ const q = new TypstTokenQueue();
1381
1425
  for (let i = 0; i < this.items.length; i++) {
1382
1426
  const n = this.items[i];
1383
1427
  const tokens = n.serialize(env, options);
1384
- if (n.isLeftSpaceful() && i > 0) {
1385
- if (queue.length > 0) {
1386
- const top = queue.at(-1);
1387
- let no_need_space = false;
1388
- no_need_space ||= top.eq(SOFT_SPACE);
1389
- no_need_space ||= ["{", "["].includes(top.value);
1390
- if (!no_need_space) {
1391
- queue.push(SOFT_SPACE);
1392
- }
1393
- }
1428
+ if (n.isLeftSpaceful()) {
1429
+ q.pushSoftSpace();
1394
1430
  }
1395
- queue.push(...tokens);
1396
- if (n.isRightSpaceful() && i < this.items.length - 1) {
1397
- if (!queue.at(-1)?.eq(SOFT_SPACE)) {
1398
- queue.push(SOFT_SPACE);
1399
- }
1431
+ q.pushAll(tokens);
1432
+ if (n.isRightSpaceful()) {
1433
+ q.pushSoftSpace();
1400
1434
  }
1401
1435
  }
1436
+ const queue = q.getQueue();
1402
1437
  if (queue.length > 0 && (queue[0].eq(TypstToken.MINUS) || queue[0].eq(TypstToken.PLUS))) {
1403
1438
  while (queue.length > 1 && queue[1].eq(SOFT_SPACE)) {
1404
1439
  queue.splice(1, 1);
@@ -1603,7 +1638,9 @@ var TypstMatrixLike = class _TypstMatrixLike extends TypstNode {
1603
1638
  row.forEach((cell, j) => {
1604
1639
  queue.push(...cell.serialize(env, options));
1605
1640
  if (j < row.length - 1) {
1606
- queue.push(SOFT_SPACE);
1641
+ if (cell_sep.value === "&") {
1642
+ queue.push(SOFT_SPACE);
1643
+ }
1607
1644
  queue.push(cell_sep);
1608
1645
  queue.push(SOFT_SPACE);
1609
1646
  } else {
@@ -1676,9 +1713,6 @@ var TypstMarkupFunc = class extends TypstNode {
1676
1713
  };
1677
1714
 
1678
1715
  // src/typst-writer.ts
1679
- var TYPST_LEFT_PARENTHESIS2 = new TypstToken(2 /* ELEMENT */, "(");
1680
- var TYPST_RIGHT_PARENTHESIS2 = new TypstToken(2 /* ELEMENT */, ")");
1681
- var TYPST_COMMA = new TypstToken(2 /* ELEMENT */, ",");
1682
1716
  var TYPST_NEWLINE = new TypstToken(1 /* SYMBOL */, "\n");
1683
1717
  var SOFT_SPACE2 = new TypstToken(7 /* CONTROL */, " ");
1684
1718
  var TypstWriter = class {
@@ -1706,15 +1740,13 @@ var TypstWriter = class {
1706
1740
  for (let i = 0; i < qu.length; i++) {
1707
1741
  let token = qu[i];
1708
1742
  if (token.eq(SOFT_SPACE2)) {
1709
- const to_delete = i === 0 || i === qu.length - 1 || qu[i - 1].type === 6 /* SPACE */ || qu[i - 1].isOneOf([TYPST_LEFT_PARENTHESIS2, TYPST_NEWLINE]) || qu[i + 1].isOneOf([TYPST_RIGHT_PARENTHESIS2, TYPST_COMMA, TYPST_NEWLINE]);
1743
+ const to_delete = i === 0 || i === qu.length - 1 || qu[i - 1].type === 6 /* SPACE */ || qu[i - 1].eq(TYPST_NEWLINE) || qu[i + 1].eq(TYPST_NEWLINE);
1710
1744
  if (to_delete) {
1711
1745
  qu[i] = dummy_token;
1712
1746
  }
1713
1747
  }
1714
1748
  }
1715
- qu = qu.filter((token) => !token.eq(dummy_token));
1716
- for (let i = 0; i < qu.length; i++) {
1717
- let token = qu[i];
1749
+ for (const token of qu) {
1718
1750
  this.buffer += token.toString();
1719
1751
  }
1720
1752
  this.queue = [];
@@ -1791,6 +1823,7 @@ var symbolMap = /* @__PURE__ */ new Map([
1791
1823
  ["tilde", "tilde"],
1792
1824
  ["hat", "hat"],
1793
1825
  ["sqrt", "sqrt"],
1826
+ ["bmod", "mod"],
1794
1827
  ["nonumber", ""],
1795
1828
  ["vec", "arrow"],
1796
1829
  ["neq", "eq.not"],
@@ -3036,14 +3069,14 @@ function convert_tex_array_align_literal(alignLiteral) {
3036
3069
  }
3037
3070
  return np;
3038
3071
  }
3039
- var TYPST_LEFT_PARENTHESIS3 = new TypstToken(2 /* ELEMENT */, "(");
3040
- var TYPST_RIGHT_PARENTHESIS3 = new TypstToken(2 /* ELEMENT */, ")");
3072
+ var TYPST_LEFT_PARENTHESIS2 = new TypstToken(2 /* ELEMENT */, "(");
3073
+ var TYPST_RIGHT_PARENTHESIS2 = new TypstToken(2 /* ELEMENT */, ")");
3041
3074
  function appendWithBracketsIfNeeded(node) {
3042
3075
  let need_to_wrap = ["group", "supsub", "matrixLike", "fraction", "empty"].includes(node.type);
3043
3076
  if (need_to_wrap) {
3044
3077
  return new TypstLeftright(null, {
3045
- left: TYPST_LEFT_PARENTHESIS3,
3046
- right: TYPST_RIGHT_PARENTHESIS3,
3078
+ left: TYPST_LEFT_PARENTHESIS2,
3079
+ right: TYPST_RIGHT_PARENTHESIS2,
3047
3080
  body: node
3048
3081
  });
3049
3082
  } else {
@@ -3124,6 +3157,12 @@ function convert_tex_node_to_typst(abstractNode, options) {
3124
3157
  };
3125
3158
  let typ_left = left ? tex_token_to_typst(left, options) : null;
3126
3159
  let typ_right = right ? tex_token_to_typst(right, options) : null;
3160
+ if (typ_left && typ_left.value === "<") {
3161
+ typ_left = new TypstToken(1 /* SYMBOL */, "chevron.l");
3162
+ }
3163
+ if (typ_right && typ_right.value === ">") {
3164
+ typ_right = new TypstToken(1 /* SYMBOL */, "chevron.r");
3165
+ }
3127
3166
  if (typ_left === null && typ_right !== null) {
3128
3167
  typ_right = escape_curly_or_paren(typ_right);
3129
3168
  }
@@ -3131,7 +3170,7 @@ function convert_tex_node_to_typst(abstractNode, options) {
3131
3170
  typ_left = escape_curly_or_paren(typ_left);
3132
3171
  }
3133
3172
  return new TypstLeftright(
3134
- new TypstToken(1 /* SYMBOL */, "lr"),
3173
+ TypstToken.LR,
3135
3174
  { body: typ_body, left: typ_left, right: typ_right }
3136
3175
  );
3137
3176
  }
@@ -3214,12 +3253,6 @@ function convert_tex_node_to_typst(abstractNode, options) {
3214
3253
  [new TypstToken(4 /* TEXT */, "large").toNode(), arg0]
3215
3254
  );
3216
3255
  }
3217
- if (node2.head.value === "\\set") {
3218
- return new TypstLeftright(
3219
- null,
3220
- { body: arg0, left: TypstToken.LEFT_BRACE, right: TypstToken.RIGHT_BRACE }
3221
- );
3222
- }
3223
3256
  if (node2.head.value === "\\not") {
3224
3257
  const sym = convert_tex_node_to_typst(node2.args[0], options);
3225
3258
  assert(sym.type === "terminal");
@@ -3234,12 +3267,87 @@ function convert_tex_node_to_typst(abstractNode, options) {
3234
3267
  }
3235
3268
  }
3236
3269
  }
3270
+ if (node2.head.value === "\\pmod") {
3271
+ const g = new TypstGroup([new TypstToken(1 /* SYMBOL */, "mod").toNode(), arg0]);
3272
+ return new TypstLeftright(
3273
+ null,
3274
+ { body: g, left: TypstToken.LEFT_PAREN, right: TypstToken.RIGHT_PAREN }
3275
+ );
3276
+ }
3237
3277
  if (node2.head.value === "\\overset") {
3238
3278
  return convert_overset(node2, options);
3239
3279
  }
3240
3280
  if (node2.head.value === "\\underset") {
3241
3281
  return convert_underset(node2, options);
3242
3282
  }
3283
+ if (["\\bra", "\\ket", "\\braket", "\\set", "\\Bra", "\\Ket", "\\Braket", "\\Set"].includes(node2.head.value)) {
3284
+ let process_vertical_bar2 = function(n, once) {
3285
+ const mid_bar = new TypstFuncCall(
3286
+ new TypstToken(1 /* SYMBOL */, "mid"),
3287
+ [TypstToken.VERTICAL_BAR.toNode()]
3288
+ );
3289
+ if (n.type === "terminal" && n.head.eq(TypstToken.VERTICAL_BAR)) {
3290
+ return mid_bar;
3291
+ } else if (n.type === "group") {
3292
+ const group = n;
3293
+ for (let i = 0; i < group.items.length; i++) {
3294
+ if (group.items[i].type === "terminal" && group.items[i].head.eq(TypstToken.VERTICAL_BAR)) {
3295
+ group.items[i] = mid_bar;
3296
+ if (once) {
3297
+ break;
3298
+ }
3299
+ }
3300
+ }
3301
+ return group;
3302
+ } else {
3303
+ return n;
3304
+ }
3305
+ };
3306
+ var process_vertical_bar = process_vertical_bar2;
3307
+ switch (node2.head.value) {
3308
+ case "\\bra":
3309
+ return new TypstLeftright(
3310
+ null,
3311
+ { body: arg0, left: TypstToken.LEFT_ANGLE, right: TypstToken.VERTICAL_BAR }
3312
+ );
3313
+ case "\\ket":
3314
+ return new TypstLeftright(
3315
+ null,
3316
+ { body: arg0, left: TypstToken.VERTICAL_BAR, right: TypstToken.RIGHT_ANGLE }
3317
+ );
3318
+ case "\\braket":
3319
+ return new TypstLeftright(
3320
+ null,
3321
+ { body: arg0, left: TypstToken.LEFT_ANGLE, right: TypstToken.RIGHT_ANGLE }
3322
+ );
3323
+ case "\\set":
3324
+ return new TypstLeftright(
3325
+ null,
3326
+ { body: arg0, left: TypstToken.LEFT_BRACE, right: TypstToken.RIGHT_BRACE }
3327
+ );
3328
+ case "\\Bra":
3329
+ return new TypstLeftright(
3330
+ TypstToken.LR,
3331
+ { body: arg0, left: TypstToken.LEFT_ANGLE, right: TypstToken.VERTICAL_BAR }
3332
+ );
3333
+ case "\\Ket":
3334
+ return new TypstLeftright(
3335
+ TypstToken.LR,
3336
+ { body: arg0, left: TypstToken.VERTICAL_BAR, right: TypstToken.RIGHT_ANGLE }
3337
+ );
3338
+ case "\\Braket":
3339
+ return new TypstLeftright(
3340
+ TypstToken.LR,
3341
+ { body: process_vertical_bar2(arg0, false), left: TypstToken.LEFT_ANGLE, right: TypstToken.RIGHT_ANGLE }
3342
+ );
3343
+ case "\\Set":
3344
+ return new TypstLeftright(
3345
+ TypstToken.LR,
3346
+ { body: process_vertical_bar2(arg0, true), left: TypstToken.LEFT_BRACE, right: TypstToken.RIGHT_BRACE }
3347
+ );
3348
+ default:
3349
+ }
3350
+ }
3243
3351
  if (node2.head.value === "\\frac") {
3244
3352
  if (options.fracToSlash) {
3245
3353
  return new TypstFraction(node2.args.map((n) => convert_tex_node_to_typst(n, options)).map(appendWithBracketsIfNeeded));
@@ -4147,14 +4255,6 @@ var TexWriter = class {
4147
4255
  this.queue = this.queue.concat(node.serialize());
4148
4256
  }
4149
4257
  flushQueue() {
4150
- while (this.queue.length > 0) {
4151
- const last_token = this.queue[this.queue.length - 1];
4152
- if (last_token.eq(TexToken.COMMAND_DISPLAYSTYLE) || last_token.eq(TexToken.COMMAND_TEXTSTYLE)) {
4153
- this.queue.pop();
4154
- } else {
4155
- break;
4156
- }
4157
- }
4158
4258
  for (let i = 0; i < this.queue.length; i++) {
4159
4259
  this.buffer = writeTexTokenBuffer(this.buffer, this.queue[i]);
4160
4260
  }
@@ -4162,6 +4262,10 @@ var TexWriter = class {
4162
4262
  }
4163
4263
  finalize() {
4164
4264
  this.flushQueue();
4265
+ this.buffer = this.buffer.replace(/\\displaystyle \\displaystyle/g, "\\displaystyle");
4266
+ this.buffer = this.buffer.replace(/\\textstyle \\textstyle/g, "\\textstyle");
4267
+ this.buffer = this.buffer.replace(/\s?\\textstyle\s?$/, "");
4268
+ this.buffer = this.buffer.replace(/\s?\\displaystyle\s?$/, "");
4165
4269
  return this.buffer;
4166
4270
  }
4167
4271
  };