tex2typst 0.3.24 → 0.3.26
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 +270 -212
- package/dist/map.d.ts +1 -1
- package/dist/tex-types.d.ts +11 -7
- package/dist/tex2typst.min.js +13 -13
- package/dist/typst-types.d.ts +19 -16
- package/package.json +1 -1
- package/src/convert.ts +131 -101
- package/src/map.ts +4 -2
- package/src/tex-parser.ts +13 -18
- package/src/tex-tokenizer.ts +3 -2
- package/src/tex-types.ts +28 -17
- package/src/typst-parser.ts +39 -19
- package/src/typst-tokenizer.ts +2 -2
- package/src/typst-types.ts +46 -37
- package/src/typst-writer.ts +73 -73
package/dist/index.js
CHANGED
|
@@ -33,10 +33,9 @@ var TexToken = class _TexToken {
|
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
var TexNode = class {
|
|
36
|
-
constructor(type, head
|
|
36
|
+
constructor(type, head) {
|
|
37
37
|
this.type = type;
|
|
38
38
|
this.head = head ? head : TexToken.EMPTY;
|
|
39
|
-
this.args = args;
|
|
40
39
|
}
|
|
41
40
|
// Note that this is only shallow equality.
|
|
42
41
|
eq(other) {
|
|
@@ -91,16 +90,17 @@ var TexText = class extends TexNode {
|
|
|
91
90
|
}
|
|
92
91
|
};
|
|
93
92
|
var TexGroup = class extends TexNode {
|
|
94
|
-
constructor(
|
|
95
|
-
super("ordgroup", TexToken.EMPTY
|
|
93
|
+
constructor(items) {
|
|
94
|
+
super("ordgroup", TexToken.EMPTY);
|
|
95
|
+
this.items = items;
|
|
96
96
|
}
|
|
97
97
|
serialize() {
|
|
98
|
-
return this.
|
|
98
|
+
return this.items.map((n) => n.serialize()).flat();
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
101
|
var TexSupSub = class extends TexNode {
|
|
102
102
|
constructor(data) {
|
|
103
|
-
super("supsub", TexToken.EMPTY
|
|
103
|
+
super("supsub", TexToken.EMPTY);
|
|
104
104
|
this.base = data.base;
|
|
105
105
|
this.sup = data.sup;
|
|
106
106
|
this.sub = data.sub;
|
|
@@ -143,7 +143,8 @@ var TexSupSub = class extends TexNode {
|
|
|
143
143
|
};
|
|
144
144
|
var TexFuncCall = class extends TexNode {
|
|
145
145
|
constructor(head, args, data = null) {
|
|
146
|
-
super("funcCall", head
|
|
146
|
+
super("funcCall", head);
|
|
147
|
+
this.args = args;
|
|
147
148
|
this.data = data;
|
|
148
149
|
}
|
|
149
150
|
serialize() {
|
|
@@ -163,8 +164,9 @@ var TexFuncCall = class extends TexNode {
|
|
|
163
164
|
}
|
|
164
165
|
};
|
|
165
166
|
var TexLeftRight = class extends TexNode {
|
|
166
|
-
constructor(
|
|
167
|
-
super("leftright", TexToken.EMPTY
|
|
167
|
+
constructor(data) {
|
|
168
|
+
super("leftright", TexToken.EMPTY);
|
|
169
|
+
this.body = data.body;
|
|
168
170
|
this.left = data.left;
|
|
169
171
|
this.right = data.right;
|
|
170
172
|
}
|
|
@@ -172,17 +174,18 @@ var TexLeftRight = class extends TexNode {
|
|
|
172
174
|
let tokens = [];
|
|
173
175
|
tokens.push(new TexToken(2 /* COMMAND */, "\\left"));
|
|
174
176
|
tokens.push(new TexToken(1 /* ELEMENT */, this.left ? this.left.value : "."));
|
|
175
|
-
tokens = tokens.concat(this.
|
|
177
|
+
tokens = tokens.concat(this.body.serialize());
|
|
176
178
|
tokens.push(new TexToken(2 /* COMMAND */, "\\right"));
|
|
177
179
|
tokens.push(new TexToken(1 /* ELEMENT */, this.right ? this.right.value : "."));
|
|
178
180
|
return tokens;
|
|
179
181
|
}
|
|
180
182
|
};
|
|
181
183
|
var TexBeginEnd = class extends TexNode {
|
|
182
|
-
constructor(head,
|
|
184
|
+
constructor(head, matrix, data = null) {
|
|
183
185
|
assert(head.type === 3 /* LITERAL */);
|
|
184
|
-
super("beginend", head
|
|
185
|
-
this.matrix =
|
|
186
|
+
super("beginend", head);
|
|
187
|
+
this.matrix = matrix;
|
|
188
|
+
this.data = data;
|
|
186
189
|
}
|
|
187
190
|
serialize() {
|
|
188
191
|
let tokens = [];
|
|
@@ -230,6 +233,7 @@ function writeTexTokenBuffer(buffer, token) {
|
|
|
230
233
|
no_need_space ||= buffer === "";
|
|
231
234
|
no_need_space ||= /[\(\[{]\s*(-|\+)$/.test(buffer) || buffer === "-" || buffer === "+";
|
|
232
235
|
no_need_space ||= buffer.endsWith("&") && str === "=";
|
|
236
|
+
no_need_space ||= /\d$/.test(buffer) && /^[a-zA-Z]$/.test(str);
|
|
233
237
|
}
|
|
234
238
|
if (!no_need_space) {
|
|
235
239
|
buffer += " ";
|
|
@@ -549,7 +553,8 @@ var TEX_BINARY_COMMANDS = [
|
|
|
549
553
|
"dfrac",
|
|
550
554
|
"tbinom",
|
|
551
555
|
"overset",
|
|
552
|
-
"underset"
|
|
556
|
+
"underset",
|
|
557
|
+
"textcolor"
|
|
553
558
|
];
|
|
554
559
|
function unescape(str) {
|
|
555
560
|
const chars = ["{", "}", "\\", "$", "&", "#", "_", "%"];
|
|
@@ -559,7 +564,7 @@ function unescape(str) {
|
|
|
559
564
|
return str;
|
|
560
565
|
}
|
|
561
566
|
var rules_map = /* @__PURE__ */ new Map([
|
|
562
|
-
//
|
|
567
|
+
// match `\begin{array}{cc}`
|
|
563
568
|
[
|
|
564
569
|
String.raw`\\begin{(array|subarry)}{(.+?)}`,
|
|
565
570
|
(s) => {
|
|
@@ -576,7 +581,7 @@ var rules_map = /* @__PURE__ */ new Map([
|
|
|
576
581
|
}
|
|
577
582
|
],
|
|
578
583
|
[
|
|
579
|
-
String.raw`\\(text|operatorname|begin|end|hspace|array){(.+?)}`,
|
|
584
|
+
String.raw`\\(text|operatorname|textcolor|begin|end|hspace|array){(.+?)}`,
|
|
580
585
|
(s) => {
|
|
581
586
|
const match = s.reMatchArray();
|
|
582
587
|
return [
|
|
@@ -646,12 +651,16 @@ function tokenize_tex(input) {
|
|
|
646
651
|
var IGNORED_COMMANDS = [
|
|
647
652
|
"bigl",
|
|
648
653
|
"bigr",
|
|
654
|
+
"bigm",
|
|
649
655
|
"biggl",
|
|
650
656
|
"biggr",
|
|
657
|
+
"biggm",
|
|
651
658
|
"Bigl",
|
|
652
659
|
"Bigr",
|
|
660
|
+
"Bigm",
|
|
653
661
|
"Biggl",
|
|
654
|
-
"Biggr"
|
|
662
|
+
"Biggr",
|
|
663
|
+
"Biggm"
|
|
655
664
|
];
|
|
656
665
|
var EMPTY_NODE = TexToken.EMPTY.toNode();
|
|
657
666
|
function get_command_param_num(command) {
|
|
@@ -809,16 +818,14 @@ var LatexParser = class {
|
|
|
809
818
|
res.sub = sub;
|
|
810
819
|
}
|
|
811
820
|
if (num_prime > 0) {
|
|
812
|
-
|
|
821
|
+
const items = [];
|
|
813
822
|
for (let i = 0; i < num_prime; i++) {
|
|
814
|
-
|
|
823
|
+
items.push(new TexToken(1 /* ELEMENT */, "'").toNode());
|
|
815
824
|
}
|
|
816
825
|
if (sup) {
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
if (res.sup.args.length === 1) {
|
|
820
|
-
res.sup = res.sup.args[0];
|
|
826
|
+
items.push(sup);
|
|
821
827
|
}
|
|
828
|
+
res.sup = items.length === 1 ? items[0] : new TexGroup(items);
|
|
822
829
|
} else if (sup) {
|
|
823
830
|
res.sup = sup;
|
|
824
831
|
}
|
|
@@ -981,10 +988,9 @@ var LatexParser = class {
|
|
|
981
988
|
}
|
|
982
989
|
pos++;
|
|
983
990
|
const [body, _] = this.parseGroup(tokens, exprInsideStart, exprInsideEnd);
|
|
984
|
-
const args = [body];
|
|
985
991
|
const left = leftDelimiter.value === "." ? null : leftDelimiter;
|
|
986
992
|
const right = rightDelimiter.value === "." ? null : rightDelimiter;
|
|
987
|
-
const res = new TexLeftRight(
|
|
993
|
+
const res = new TexLeftRight({ body, left, right });
|
|
988
994
|
return [res, pos];
|
|
989
995
|
}
|
|
990
996
|
parseBeginEndExpr(tokens, start) {
|
|
@@ -995,12 +1001,10 @@ var LatexParser = class {
|
|
|
995
1001
|
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
|
|
996
1002
|
const envName = tokens[pos + 1].value;
|
|
997
1003
|
pos += 3;
|
|
998
|
-
|
|
1004
|
+
let data = null;
|
|
999
1005
|
if (["array", "subarray"].includes(envName)) {
|
|
1000
1006
|
pos += eat_whitespaces(tokens, pos).length;
|
|
1001
|
-
|
|
1002
|
-
args.push(arg);
|
|
1003
|
-
pos = newPos;
|
|
1007
|
+
[data, pos] = this.parseNextArg(tokens, pos);
|
|
1004
1008
|
}
|
|
1005
1009
|
pos += eat_whitespaces(tokens, pos).length;
|
|
1006
1010
|
const exprInsideStart = pos;
|
|
@@ -1022,7 +1026,7 @@ var LatexParser = class {
|
|
|
1022
1026
|
exprInside.pop();
|
|
1023
1027
|
}
|
|
1024
1028
|
const body = this.parseAligned(exprInside);
|
|
1025
|
-
const res = new TexBeginEnd(new TexToken(3 /* LITERAL */, envName),
|
|
1029
|
+
const res = new TexBeginEnd(new TexToken(3 /* LITERAL */, envName), body, data);
|
|
1026
1030
|
return [res, pos];
|
|
1027
1031
|
}
|
|
1028
1032
|
parseAligned(tokens) {
|
|
@@ -1052,7 +1056,7 @@ var LatexParser = class {
|
|
|
1052
1056
|
group = new TexGroup([]);
|
|
1053
1057
|
row.push(group);
|
|
1054
1058
|
} else {
|
|
1055
|
-
group.
|
|
1059
|
+
group.items.push(res);
|
|
1056
1060
|
}
|
|
1057
1061
|
}
|
|
1058
1062
|
return allRows;
|
|
@@ -1120,12 +1124,14 @@ var TypstToken = class _TypstToken {
|
|
|
1120
1124
|
static {
|
|
1121
1125
|
this.NONE = new _TypstToken(0 /* NONE */, "#none");
|
|
1122
1126
|
}
|
|
1127
|
+
static {
|
|
1128
|
+
this.EMPTY = new _TypstToken(2 /* ELEMENT */, "");
|
|
1129
|
+
}
|
|
1123
1130
|
};
|
|
1124
1131
|
var TypstNode = class {
|
|
1125
|
-
constructor(type, head
|
|
1132
|
+
constructor(type, head) {
|
|
1126
1133
|
this.type = type;
|
|
1127
1134
|
this.head = head ? head : TypstToken.NONE;
|
|
1128
|
-
this.args = args;
|
|
1129
1135
|
}
|
|
1130
1136
|
setOptions(options) {
|
|
1131
1137
|
this.options = options;
|
|
@@ -1150,16 +1156,17 @@ var TypstTerminal = class extends TypstNode {
|
|
|
1150
1156
|
}
|
|
1151
1157
|
};
|
|
1152
1158
|
var TypstGroup = class extends TypstNode {
|
|
1153
|
-
constructor(
|
|
1154
|
-
super("group", TypstToken.NONE
|
|
1159
|
+
constructor(items) {
|
|
1160
|
+
super("group", TypstToken.NONE);
|
|
1161
|
+
this.items = items;
|
|
1155
1162
|
}
|
|
1156
1163
|
isOverHigh() {
|
|
1157
|
-
return this.
|
|
1164
|
+
return this.items.some((n) => n.isOverHigh());
|
|
1158
1165
|
}
|
|
1159
1166
|
};
|
|
1160
1167
|
var TypstSupsub = class extends TypstNode {
|
|
1161
1168
|
constructor(data) {
|
|
1162
|
-
super("supsub", TypstToken.NONE
|
|
1169
|
+
super("supsub", TypstToken.NONE);
|
|
1163
1170
|
this.base = data.base;
|
|
1164
1171
|
this.sup = data.sup;
|
|
1165
1172
|
this.sub = data.sub;
|
|
@@ -1170,7 +1177,8 @@ var TypstSupsub = class extends TypstNode {
|
|
|
1170
1177
|
};
|
|
1171
1178
|
var TypstFuncCall = class extends TypstNode {
|
|
1172
1179
|
constructor(head, args) {
|
|
1173
|
-
super("funcCall", head
|
|
1180
|
+
super("funcCall", head);
|
|
1181
|
+
this.args = args;
|
|
1174
1182
|
}
|
|
1175
1183
|
isOverHigh() {
|
|
1176
1184
|
if (this.head.value === "frac") {
|
|
@@ -1181,47 +1189,48 @@ var TypstFuncCall = class extends TypstNode {
|
|
|
1181
1189
|
};
|
|
1182
1190
|
var TypstFraction = class extends TypstNode {
|
|
1183
1191
|
constructor(args) {
|
|
1184
|
-
super("fraction", TypstToken.NONE
|
|
1192
|
+
super("fraction", TypstToken.NONE);
|
|
1193
|
+
this.args = args;
|
|
1185
1194
|
}
|
|
1186
1195
|
isOverHigh() {
|
|
1187
1196
|
return true;
|
|
1188
1197
|
}
|
|
1189
1198
|
};
|
|
1190
1199
|
var TypstLeftright = class extends TypstNode {
|
|
1191
|
-
|
|
1192
|
-
|
|
1200
|
+
// head is either null or 'lr'
|
|
1201
|
+
constructor(head, data) {
|
|
1202
|
+
super("leftright", head);
|
|
1203
|
+
this.body = data.body;
|
|
1193
1204
|
this.left = data.left;
|
|
1194
1205
|
this.right = data.right;
|
|
1195
1206
|
}
|
|
1196
1207
|
isOverHigh() {
|
|
1197
|
-
return this.
|
|
1208
|
+
return this.body.isOverHigh();
|
|
1198
1209
|
}
|
|
1199
1210
|
};
|
|
1200
|
-
var
|
|
1201
|
-
|
|
1202
|
-
|
|
1211
|
+
var TypstMatrixLike = class extends TypstNode {
|
|
1212
|
+
// head is 'mat', 'cases' or null
|
|
1213
|
+
constructor(head, data) {
|
|
1214
|
+
super("matrixLike", head);
|
|
1203
1215
|
this.matrix = data;
|
|
1204
1216
|
}
|
|
1205
1217
|
isOverHigh() {
|
|
1206
1218
|
return true;
|
|
1207
1219
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
constructor(data) {
|
|
1211
|
-
super("matrix", TypstToken.NONE, []);
|
|
1212
|
-
this.matrix = data;
|
|
1220
|
+
static {
|
|
1221
|
+
this.MAT = new TypstToken(1 /* SYMBOL */, "mat");
|
|
1213
1222
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1223
|
+
static {
|
|
1224
|
+
this.CASES = new TypstToken(1 /* SYMBOL */, "cases");
|
|
1216
1225
|
}
|
|
1217
1226
|
};
|
|
1218
|
-
var
|
|
1219
|
-
constructor(
|
|
1220
|
-
super("
|
|
1221
|
-
this.
|
|
1227
|
+
var TypstMarkupFunc = class extends TypstNode {
|
|
1228
|
+
constructor(head, fragments) {
|
|
1229
|
+
super("markupFunc", head);
|
|
1230
|
+
this.fragments = fragments;
|
|
1222
1231
|
}
|
|
1223
1232
|
isOverHigh() {
|
|
1224
|
-
return
|
|
1233
|
+
return this.fragments.some((n) => n.isOverHigh());
|
|
1225
1234
|
}
|
|
1226
1235
|
};
|
|
1227
1236
|
|
|
@@ -1300,7 +1309,7 @@ var TypstWriter = class {
|
|
|
1300
1309
|
this.inftyToOo = options.inftyToOo;
|
|
1301
1310
|
this.optimize = options.optimize;
|
|
1302
1311
|
}
|
|
1303
|
-
writeBuffer(token) {
|
|
1312
|
+
writeBuffer(previousToken, token) {
|
|
1304
1313
|
const str = token.toString();
|
|
1305
1314
|
if (str === "") {
|
|
1306
1315
|
return;
|
|
@@ -1317,7 +1326,11 @@ var TypstWriter = class {
|
|
|
1317
1326
|
no_need_space ||= /^\s/.test(str);
|
|
1318
1327
|
no_need_space ||= this.buffer.endsWith("&") && str === "=";
|
|
1319
1328
|
no_need_space ||= this.buffer.endsWith("/") || str === "/";
|
|
1329
|
+
no_need_space ||= token.type === 3 /* LITERAL */;
|
|
1320
1330
|
no_need_space ||= /[\s_^{\(]$/.test(this.buffer);
|
|
1331
|
+
if (previousToken !== null) {
|
|
1332
|
+
no_need_space ||= previousToken.type === 3 /* LITERAL */;
|
|
1333
|
+
}
|
|
1321
1334
|
if (!no_need_space) {
|
|
1322
1335
|
this.buffer += " ";
|
|
1323
1336
|
}
|
|
@@ -1367,7 +1380,7 @@ var TypstWriter = class {
|
|
|
1367
1380
|
}
|
|
1368
1381
|
case "group": {
|
|
1369
1382
|
const node = abstractNode;
|
|
1370
|
-
for (const item of node.
|
|
1383
|
+
for (const item of node.items) {
|
|
1371
1384
|
this.serialize(item);
|
|
1372
1385
|
}
|
|
1373
1386
|
break;
|
|
@@ -1383,9 +1396,7 @@ var TypstWriter = class {
|
|
|
1383
1396
|
if (left) {
|
|
1384
1397
|
this.queue.push(left);
|
|
1385
1398
|
}
|
|
1386
|
-
|
|
1387
|
-
this.serialize(item);
|
|
1388
|
-
}
|
|
1399
|
+
this.serialize(node.body);
|
|
1389
1400
|
if (right) {
|
|
1390
1401
|
this.queue.push(right);
|
|
1391
1402
|
}
|
|
@@ -1451,74 +1462,71 @@ var TypstWriter = class {
|
|
|
1451
1462
|
this.appendWithBracketsIfNeeded(denominator);
|
|
1452
1463
|
break;
|
|
1453
1464
|
}
|
|
1454
|
-
case "
|
|
1465
|
+
case "matrixLike": {
|
|
1455
1466
|
const node = abstractNode;
|
|
1456
1467
|
const matrix = node.matrix;
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1468
|
+
let cell_sep;
|
|
1469
|
+
let row_sep;
|
|
1470
|
+
if (node.head.eq(TypstMatrixLike.MAT)) {
|
|
1471
|
+
cell_sep = new TypstToken(2 /* ELEMENT */, ",");
|
|
1472
|
+
row_sep = new TypstToken(2 /* ELEMENT */, ";");
|
|
1473
|
+
} else if (node.head.eq(TypstMatrixLike.CASES)) {
|
|
1474
|
+
cell_sep = new TypstToken(2 /* ELEMENT */, "&");
|
|
1475
|
+
row_sep = new TypstToken(2 /* ELEMENT */, ",");
|
|
1476
|
+
} else if (node.head.eq(TypstToken.NONE)) {
|
|
1477
|
+
cell_sep = new TypstToken(2 /* ELEMENT */, "&");
|
|
1478
|
+
row_sep = new TypstToken(1 /* SYMBOL */, "\\");
|
|
1479
|
+
}
|
|
1480
|
+
if (!node.head.eq(TypstToken.NONE)) {
|
|
1481
|
+
this.queue.push(node.head);
|
|
1482
|
+
this.insideFunctionDepth++;
|
|
1483
|
+
this.queue.push(TYPST_LEFT_PARENTHESIS);
|
|
1484
|
+
if (node.options) {
|
|
1485
|
+
for (const [key, value] of Object.entries(node.options)) {
|
|
1486
|
+
this.queue.push(new TypstToken(3 /* LITERAL */, `${key}: ${value.toString()}, `));
|
|
1461
1487
|
}
|
|
1462
|
-
this.serialize(cell);
|
|
1463
|
-
});
|
|
1464
|
-
if (i < matrix.length - 1) {
|
|
1465
|
-
this.queue.push(new TypstToken(1 /* SYMBOL */, "\\"));
|
|
1466
|
-
}
|
|
1467
|
-
});
|
|
1468
|
-
break;
|
|
1469
|
-
}
|
|
1470
|
-
case "matrix": {
|
|
1471
|
-
const node = abstractNode;
|
|
1472
|
-
const matrix = node.matrix;
|
|
1473
|
-
this.queue.push(new TypstToken(1 /* SYMBOL */, "mat"));
|
|
1474
|
-
this.insideFunctionDepth++;
|
|
1475
|
-
this.queue.push(TYPST_LEFT_PARENTHESIS);
|
|
1476
|
-
if (node.options) {
|
|
1477
|
-
for (const [key, value] of Object.entries(node.options)) {
|
|
1478
|
-
this.queue.push(new TypstToken(3 /* LITERAL */, `${key}: ${value.toString()}, `));
|
|
1479
1488
|
}
|
|
1480
1489
|
}
|
|
1481
1490
|
matrix.forEach((row, i) => {
|
|
1482
1491
|
row.forEach((cell, j) => {
|
|
1483
1492
|
this.serialize(cell);
|
|
1484
1493
|
if (j < row.length - 1) {
|
|
1485
|
-
this.queue.push(
|
|
1494
|
+
this.queue.push(cell_sep);
|
|
1486
1495
|
} else {
|
|
1487
1496
|
if (i < matrix.length - 1) {
|
|
1488
|
-
this.queue.push(
|
|
1497
|
+
this.queue.push(row_sep);
|
|
1489
1498
|
}
|
|
1490
1499
|
}
|
|
1491
1500
|
});
|
|
1492
1501
|
});
|
|
1493
|
-
|
|
1494
|
-
|
|
1502
|
+
if (!node.head.eq(TypstToken.NONE)) {
|
|
1503
|
+
this.queue.push(TYPST_RIGHT_PARENTHESIS);
|
|
1504
|
+
this.insideFunctionDepth--;
|
|
1505
|
+
}
|
|
1495
1506
|
break;
|
|
1496
1507
|
}
|
|
1497
|
-
case "
|
|
1508
|
+
case "markupFunc": {
|
|
1498
1509
|
const node = abstractNode;
|
|
1499
|
-
|
|
1500
|
-
this.queue.push(new TypstToken(1 /* SYMBOL */, "cases"));
|
|
1501
|
-
this.insideFunctionDepth++;
|
|
1510
|
+
this.queue.push(node.head);
|
|
1502
1511
|
this.queue.push(TYPST_LEFT_PARENTHESIS);
|
|
1503
1512
|
if (node.options) {
|
|
1504
|
-
|
|
1505
|
-
|
|
1513
|
+
const entries = Object.entries(node.options);
|
|
1514
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1515
|
+
const [key, value] = entries[i];
|
|
1516
|
+
this.queue.push(new TypstToken(3 /* LITERAL */, `${key}: ${value.toString()}`));
|
|
1517
|
+
if (i < entries.length - 1) {
|
|
1518
|
+
this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
|
|
1519
|
+
}
|
|
1506
1520
|
}
|
|
1507
1521
|
}
|
|
1508
|
-
cases.forEach((row, i) => {
|
|
1509
|
-
row.forEach((cell, j) => {
|
|
1510
|
-
this.serialize(cell);
|
|
1511
|
-
if (j < row.length - 1) {
|
|
1512
|
-
this.queue.push(new TypstToken(2 /* ELEMENT */, "&"));
|
|
1513
|
-
} else {
|
|
1514
|
-
if (i < cases.length - 1) {
|
|
1515
|
-
this.queue.push(new TypstToken(2 /* ELEMENT */, ","));
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
});
|
|
1519
|
-
});
|
|
1520
1522
|
this.queue.push(TYPST_RIGHT_PARENTHESIS);
|
|
1521
|
-
this.
|
|
1523
|
+
this.queue.push(new TypstToken(3 /* LITERAL */, "["));
|
|
1524
|
+
for (const frag of node.fragments) {
|
|
1525
|
+
this.queue.push(new TypstToken(3 /* LITERAL */, "$"));
|
|
1526
|
+
this.serialize(frag);
|
|
1527
|
+
this.queue.push(new TypstToken(3 /* LITERAL */, "$"));
|
|
1528
|
+
}
|
|
1529
|
+
this.queue.push(new TypstToken(3 /* LITERAL */, "]"));
|
|
1522
1530
|
break;
|
|
1523
1531
|
}
|
|
1524
1532
|
default:
|
|
@@ -1526,13 +1534,14 @@ var TypstWriter = class {
|
|
|
1526
1534
|
}
|
|
1527
1535
|
}
|
|
1528
1536
|
appendWithBracketsIfNeeded(node) {
|
|
1529
|
-
let need_to_wrap = ["group", "supsub", "
|
|
1537
|
+
let need_to_wrap = ["group", "supsub", "matrixLike", "fraction", "empty"].includes(node.type);
|
|
1530
1538
|
if (node.type === "group") {
|
|
1531
|
-
|
|
1539
|
+
const group = node;
|
|
1540
|
+
if (group.items.length === 0) {
|
|
1532
1541
|
need_to_wrap = true;
|
|
1533
1542
|
} else {
|
|
1534
|
-
const first =
|
|
1535
|
-
const last =
|
|
1543
|
+
const first = group.items[0];
|
|
1544
|
+
const last = group.items[group.items.length - 1];
|
|
1536
1545
|
if (is_delimiter(first) && is_delimiter(last)) {
|
|
1537
1546
|
need_to_wrap = false;
|
|
1538
1547
|
}
|
|
@@ -1559,9 +1568,11 @@ var TypstWriter = class {
|
|
|
1559
1568
|
}
|
|
1560
1569
|
}
|
|
1561
1570
|
this.queue = this.queue.filter((token) => !token.eq(dummy_token));
|
|
1562
|
-
this.queue.
|
|
1563
|
-
this.
|
|
1564
|
-
|
|
1571
|
+
for (let i = 0; i < this.queue.length; i++) {
|
|
1572
|
+
let token = this.queue[i];
|
|
1573
|
+
let previous_token = i === 0 ? null : this.queue[i - 1];
|
|
1574
|
+
this.writeBuffer(previous_token, token);
|
|
1575
|
+
}
|
|
1565
1576
|
this.queue = [];
|
|
1566
1577
|
}
|
|
1567
1578
|
finalize() {
|
|
@@ -1849,6 +1860,7 @@ var symbolMap = /* @__PURE__ */ new Map([
|
|
|
1849
1860
|
["xi", "xi"],
|
|
1850
1861
|
["yen", "yen"],
|
|
1851
1862
|
["zeta", "zeta"],
|
|
1863
|
+
["intop", "limits(integral)"],
|
|
1852
1864
|
// extended
|
|
1853
1865
|
["mathscr", "scr"],
|
|
1854
1866
|
["LaTeX", "#LaTeX"],
|
|
@@ -2836,7 +2848,7 @@ function convert_tex_node_to_typst(abstractNode, options = {}) {
|
|
|
2836
2848
|
case "ordgroup":
|
|
2837
2849
|
const node = abstractNode;
|
|
2838
2850
|
return new TypstGroup(
|
|
2839
|
-
node.
|
|
2851
|
+
node.items.map((n) => convert_tex_node_to_typst(n, options))
|
|
2840
2852
|
);
|
|
2841
2853
|
case "supsub": {
|
|
2842
2854
|
const node2 = abstractNode;
|
|
@@ -2862,8 +2874,7 @@ function convert_tex_node_to_typst(abstractNode, options = {}) {
|
|
|
2862
2874
|
case "leftright": {
|
|
2863
2875
|
const node2 = abstractNode;
|
|
2864
2876
|
const { left, right } = node2;
|
|
2865
|
-
const
|
|
2866
|
-
const typ_body = convert_tex_node_to_typst(_body, options);
|
|
2877
|
+
const typ_body = convert_tex_node_to_typst(node2.body, options);
|
|
2867
2878
|
if (options.optimize) {
|
|
2868
2879
|
if (left !== null && right !== null) {
|
|
2869
2880
|
const typ_left2 = tex_token_to_typst(left, options);
|
|
@@ -2900,8 +2911,7 @@ function convert_tex_node_to_typst(abstractNode, options = {}) {
|
|
|
2900
2911
|
}
|
|
2901
2912
|
return new TypstLeftright(
|
|
2902
2913
|
new TypstToken(1 /* SYMBOL */, "lr"),
|
|
2903
|
-
|
|
2904
|
-
{ left: typ_left, right: typ_right }
|
|
2914
|
+
{ body: typ_body, left: typ_left, right: typ_right }
|
|
2905
2915
|
);
|
|
2906
2916
|
}
|
|
2907
2917
|
case "funcCall": {
|
|
@@ -2944,6 +2954,14 @@ function convert_tex_node_to_typst(abstractNode, options = {}) {
|
|
|
2944
2954
|
}
|
|
2945
2955
|
return new TypstFuncCall(new TypstToken(1 /* SYMBOL */, "op"), [new TypstToken(4 /* TEXT */, arg0.head.value).toNode()]);
|
|
2946
2956
|
}
|
|
2957
|
+
if (node2.head.value === "\\textcolor") {
|
|
2958
|
+
const res = new TypstMarkupFunc(
|
|
2959
|
+
new TypstToken(1 /* SYMBOL */, `#text`),
|
|
2960
|
+
[convert_tex_node_to_typst(node2.args[1], options)]
|
|
2961
|
+
);
|
|
2962
|
+
res.setOptions({ fill: arg0 });
|
|
2963
|
+
return res;
|
|
2964
|
+
}
|
|
2947
2965
|
if (node2.head.value === "\\substack") {
|
|
2948
2966
|
return arg0;
|
|
2949
2967
|
}
|
|
@@ -2973,38 +2991,40 @@ function convert_tex_node_to_typst(abstractNode, options = {}) {
|
|
|
2973
2991
|
}
|
|
2974
2992
|
case "beginend": {
|
|
2975
2993
|
const node2 = abstractNode;
|
|
2976
|
-
const
|
|
2994
|
+
const matrix = node2.matrix.map((row) => row.map((n) => convert_tex_node_to_typst(n, options)));
|
|
2977
2995
|
if (node2.head.value.startsWith("align")) {
|
|
2978
|
-
return new
|
|
2996
|
+
return new TypstMatrixLike(null, matrix);
|
|
2979
2997
|
}
|
|
2980
2998
|
if (node2.head.value === "cases") {
|
|
2981
|
-
return new
|
|
2999
|
+
return new TypstMatrixLike(TypstMatrixLike.CASES, matrix);
|
|
2982
3000
|
}
|
|
2983
3001
|
if (node2.head.value === "subarray") {
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
3002
|
+
if (node2.data) {
|
|
3003
|
+
const align_node = node2.data;
|
|
3004
|
+
switch (align_node.head.value) {
|
|
3005
|
+
case "r":
|
|
3006
|
+
matrix.forEach((row) => row.push(TypstToken.EMPTY.toNode()));
|
|
3007
|
+
break;
|
|
3008
|
+
case "l":
|
|
3009
|
+
matrix.forEach((row) => row.unshift(TypstToken.EMPTY.toNode()));
|
|
3010
|
+
break;
|
|
3011
|
+
default:
|
|
3012
|
+
break;
|
|
3013
|
+
}
|
|
2994
3014
|
}
|
|
2995
|
-
return new
|
|
3015
|
+
return new TypstMatrixLike(null, matrix);
|
|
2996
3016
|
}
|
|
2997
3017
|
if (node2.head.value === "array") {
|
|
2998
3018
|
const np = { "delim": TYPST_NONE };
|
|
2999
|
-
assert(node2.
|
|
3000
|
-
const np_new = convert_tex_array_align_literal(node2.
|
|
3019
|
+
assert(node2.data !== null && node2.head.type === 3 /* LITERAL */);
|
|
3020
|
+
const np_new = convert_tex_array_align_literal(node2.data.head.value);
|
|
3001
3021
|
Object.assign(np, np_new);
|
|
3002
|
-
const res = new
|
|
3022
|
+
const res = new TypstMatrixLike(TypstMatrixLike.MAT, matrix);
|
|
3003
3023
|
res.setOptions(np);
|
|
3004
3024
|
return res;
|
|
3005
3025
|
}
|
|
3006
3026
|
if (node2.head.value.endsWith("matrix")) {
|
|
3007
|
-
const res = new
|
|
3027
|
+
const res = new TypstMatrixLike(TypstMatrixLike.MAT, matrix);
|
|
3008
3028
|
let delim;
|
|
3009
3029
|
switch (node2.head.value) {
|
|
3010
3030
|
case "matrix":
|
|
@@ -3123,32 +3143,30 @@ function convert_typst_node_to_tex(abstractNode) {
|
|
|
3123
3143
|
}
|
|
3124
3144
|
case "group": {
|
|
3125
3145
|
const node = abstractNode;
|
|
3126
|
-
const args = node.
|
|
3146
|
+
const args = node.items.map(convert_typst_node_to_tex);
|
|
3127
3147
|
const alignment_char = new TexToken(7 /* CONTROL */, "&").toNode();
|
|
3128
3148
|
const newline_char = new TexToken(7 /* CONTROL */, "\\\\").toNode();
|
|
3129
3149
|
if (array_includes(args, alignment_char)) {
|
|
3130
3150
|
const rows = array_split(args, newline_char);
|
|
3131
|
-
const
|
|
3151
|
+
const matrix = [];
|
|
3132
3152
|
for (const row of rows) {
|
|
3133
3153
|
const cells = array_split(row, alignment_char);
|
|
3134
|
-
|
|
3154
|
+
matrix.push(cells.map((cell) => new TexGroup(cell)));
|
|
3135
3155
|
}
|
|
3136
|
-
return new TexBeginEnd(new TexToken(3 /* LITERAL */, "aligned"),
|
|
3156
|
+
return new TexBeginEnd(new TexToken(3 /* LITERAL */, "aligned"), matrix);
|
|
3137
3157
|
}
|
|
3138
3158
|
return new TexGroup(args);
|
|
3139
3159
|
}
|
|
3140
3160
|
case "leftright": {
|
|
3141
3161
|
const node = abstractNode;
|
|
3142
|
-
const
|
|
3162
|
+
const body = convert_typst_node_to_tex(node.body);
|
|
3143
3163
|
let left = node.left ? typst_token_to_tex(node.left) : new TexToken(1 /* ELEMENT */, ".");
|
|
3144
3164
|
let right = node.right ? typst_token_to_tex(node.right) : new TexToken(1 /* ELEMENT */, ".");
|
|
3145
3165
|
if (node.isOverHigh()) {
|
|
3146
3166
|
left.value = "\\left" + left.value;
|
|
3147
3167
|
right.value = "\\right" + right.value;
|
|
3148
3168
|
}
|
|
3149
|
-
|
|
3150
|
-
args.push(right.toNode());
|
|
3151
|
-
return new TexGroup(args);
|
|
3169
|
+
return new TexGroup([left.toNode(), body, right.toNode()]);
|
|
3152
3170
|
}
|
|
3153
3171
|
case "funcCall": {
|
|
3154
3172
|
const node = abstractNode;
|
|
@@ -3158,14 +3176,15 @@ function convert_typst_node_to_tex(abstractNode) {
|
|
|
3158
3176
|
// `\left\| a + \frac{1}{3} \right\|` <- `norm(a + 1/3)`
|
|
3159
3177
|
case "norm": {
|
|
3160
3178
|
const arg0 = node.args[0];
|
|
3161
|
-
const
|
|
3179
|
+
const body = convert_typst_node_to_tex(arg0);
|
|
3162
3180
|
if (node.isOverHigh()) {
|
|
3163
|
-
return new TexLeftRight(
|
|
3181
|
+
return new TexLeftRight({
|
|
3182
|
+
body,
|
|
3164
3183
|
left: new TexToken(2 /* COMMAND */, "\\|"),
|
|
3165
3184
|
right: new TexToken(2 /* COMMAND */, "\\|")
|
|
3166
3185
|
});
|
|
3167
3186
|
} else {
|
|
3168
|
-
return
|
|
3187
|
+
return body;
|
|
3169
3188
|
}
|
|
3170
3189
|
}
|
|
3171
3190
|
// special hook for floor, ceil
|
|
@@ -3178,16 +3197,17 @@ function convert_typst_node_to_tex(abstractNode) {
|
|
|
3178
3197
|
const left = "\\l" + node.head.value;
|
|
3179
3198
|
const right = "\\r" + node.head.value;
|
|
3180
3199
|
const arg0 = node.args[0];
|
|
3181
|
-
const
|
|
3200
|
+
const body = convert_typst_node_to_tex(arg0);
|
|
3182
3201
|
const left_node = new TexToken(2 /* COMMAND */, left);
|
|
3183
3202
|
const right_node = new TexToken(2 /* COMMAND */, right);
|
|
3184
3203
|
if (node.isOverHigh()) {
|
|
3185
|
-
return new TexLeftRight(
|
|
3204
|
+
return new TexLeftRight({
|
|
3205
|
+
body,
|
|
3186
3206
|
left: left_node,
|
|
3187
3207
|
right: right_node
|
|
3188
3208
|
});
|
|
3189
3209
|
} else {
|
|
3190
|
-
return new TexGroup([left_node.toNode(),
|
|
3210
|
+
return new TexGroup([left_node.toNode(), body, right_node.toNode()]);
|
|
3191
3211
|
}
|
|
3192
3212
|
}
|
|
3193
3213
|
// special hook for root
|
|
@@ -3208,8 +3228,8 @@ function convert_typst_node_to_tex(abstractNode) {
|
|
|
3208
3228
|
// special hook for vec
|
|
3209
3229
|
// "vec(a, b, c)" -> "\begin{pmatrix}a\\ b\\ c\end{pmatrix}"
|
|
3210
3230
|
case "vec": {
|
|
3211
|
-
const
|
|
3212
|
-
return new TexBeginEnd(new TexToken(3 /* LITERAL */, "pmatrix"),
|
|
3231
|
+
const tex_matrix = node.args.map(convert_typst_node_to_tex).map((n) => [n]);
|
|
3232
|
+
return new TexBeginEnd(new TexToken(3 /* LITERAL */, "pmatrix"), tex_matrix);
|
|
3213
3233
|
}
|
|
3214
3234
|
// special hook for op
|
|
3215
3235
|
case "op": {
|
|
@@ -3234,13 +3254,31 @@ function convert_typst_node_to_tex(abstractNode) {
|
|
|
3234
3254
|
}
|
|
3235
3255
|
}
|
|
3236
3256
|
}
|
|
3257
|
+
case "markupFunc": {
|
|
3258
|
+
const node = abstractNode;
|
|
3259
|
+
switch (node.head.value) {
|
|
3260
|
+
case "#text": {
|
|
3261
|
+
if (node.options && node.options["fill"]) {
|
|
3262
|
+
const color = node.options["fill"];
|
|
3263
|
+
return new TexFuncCall(
|
|
3264
|
+
new TexToken(2 /* COMMAND */, "\\textcolor"),
|
|
3265
|
+
[convert_typst_node_to_tex(color), convert_typst_node_to_tex(node.fragments[0])]
|
|
3266
|
+
);
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
case "#heading":
|
|
3270
|
+
default:
|
|
3271
|
+
throw new Error(`Unimplemented markup function: ${node.head.value}`);
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3237
3274
|
case "supsub": {
|
|
3238
3275
|
const node = abstractNode;
|
|
3239
3276
|
const { base, sup, sub } = node;
|
|
3240
3277
|
const sup_tex = sup ? convert_typst_node_to_tex(sup) : null;
|
|
3241
3278
|
const sub_tex = sub ? convert_typst_node_to_tex(sub) : null;
|
|
3242
3279
|
if (base.head.eq(new TypstToken(1 /* SYMBOL */, "limits"))) {
|
|
3243
|
-
const
|
|
3280
|
+
const limits = base;
|
|
3281
|
+
const body_in_limits = convert_typst_node_to_tex(limits.args[0]);
|
|
3244
3282
|
if (sup_tex !== null && sub_tex === null) {
|
|
3245
3283
|
return new TexFuncCall(new TexToken(2 /* COMMAND */, "\\overset"), [sup_tex, body_in_limits]);
|
|
3246
3284
|
} else if (sup_tex === null && sub_tex !== null) {
|
|
@@ -3258,50 +3296,51 @@ function convert_typst_node_to_tex(abstractNode) {
|
|
|
3258
3296
|
});
|
|
3259
3297
|
return res;
|
|
3260
3298
|
}
|
|
3261
|
-
case "
|
|
3299
|
+
case "matrixLike": {
|
|
3262
3300
|
const node = abstractNode;
|
|
3263
|
-
const
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
if (
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3301
|
+
const tex_matrix = node.matrix.map((row) => row.map(convert_typst_node_to_tex));
|
|
3302
|
+
if (node.head.eq(TypstMatrixLike.MAT)) {
|
|
3303
|
+
let env_type = "pmatrix";
|
|
3304
|
+
if (node.options) {
|
|
3305
|
+
if ("delim" in node.options) {
|
|
3306
|
+
const delim = node.options.delim;
|
|
3307
|
+
switch (delim.head.value) {
|
|
3308
|
+
case "#none":
|
|
3309
|
+
env_type = "matrix";
|
|
3310
|
+
break;
|
|
3311
|
+
case "[":
|
|
3312
|
+
case "]":
|
|
3313
|
+
env_type = "bmatrix";
|
|
3314
|
+
break;
|
|
3315
|
+
case "(":
|
|
3316
|
+
case ")":
|
|
3317
|
+
env_type = "pmatrix";
|
|
3318
|
+
break;
|
|
3319
|
+
case "{":
|
|
3320
|
+
case "}":
|
|
3321
|
+
env_type = "Bmatrix";
|
|
3322
|
+
break;
|
|
3323
|
+
case "|":
|
|
3324
|
+
env_type = "vmatrix";
|
|
3325
|
+
break;
|
|
3326
|
+
case "bar":
|
|
3327
|
+
case "bar.v":
|
|
3328
|
+
env_type = "vmatrix";
|
|
3329
|
+
break;
|
|
3330
|
+
case "bar.v.double":
|
|
3331
|
+
env_type = "Vmatrix";
|
|
3332
|
+
break;
|
|
3333
|
+
default:
|
|
3334
|
+
throw new Error(`Unexpected delimiter ${delim.head}`);
|
|
3335
|
+
}
|
|
3296
3336
|
}
|
|
3297
3337
|
}
|
|
3338
|
+
return new TexBeginEnd(new TexToken(3 /* LITERAL */, env_type), tex_matrix);
|
|
3339
|
+
} else if (node.head.eq(TypstMatrixLike.CASES)) {
|
|
3340
|
+
return new TexBeginEnd(new TexToken(3 /* LITERAL */, "cases"), tex_matrix);
|
|
3341
|
+
} else {
|
|
3342
|
+
throw new Error(`Unexpected matrix type ${node.head}`);
|
|
3298
3343
|
}
|
|
3299
|
-
return new TexBeginEnd(new TexToken(3 /* LITERAL */, env_type), [], tex_data);
|
|
3300
|
-
}
|
|
3301
|
-
case "cases": {
|
|
3302
|
-
const node = abstractNode;
|
|
3303
|
-
const tex_data = node.matrix.map((row) => row.map(convert_typst_node_to_tex));
|
|
3304
|
-
return new TexBeginEnd(new TexToken(3 /* LITERAL */, "cases"), [], tex_data);
|
|
3305
3344
|
}
|
|
3306
3345
|
case "fraction": {
|
|
3307
3346
|
const node = abstractNode;
|
|
@@ -3376,10 +3415,10 @@ var rules_map2 = /* @__PURE__ */ new Map([
|
|
|
3376
3415
|
new TypstToken(2 /* ELEMENT */, ")")
|
|
3377
3416
|
];
|
|
3378
3417
|
}],
|
|
3379
|
-
[String.raw
|
|
3418
|
+
[String.raw`#none`, (s) => new TypstToken(0 /* NONE */, s.text())],
|
|
3419
|
+
[String.raw`#?[a-zA-Z\.]+`, (s) => {
|
|
3380
3420
|
return new TypstToken(s.text().length === 1 ? 2 /* ELEMENT */ : 1 /* SYMBOL */, s.text());
|
|
3381
3421
|
}],
|
|
3382
|
-
[String.raw`#none`, (s) => new TypstToken(0 /* NONE */, s.text())],
|
|
3383
3422
|
[String.raw`.`, (s) => new TypstToken(2 /* ELEMENT */, s.text())]
|
|
3384
3423
|
]);
|
|
3385
3424
|
var spec2 = {
|
|
@@ -3518,10 +3557,10 @@ function process_operators(nodes, parenthesis = false) {
|
|
|
3518
3557
|
}
|
|
3519
3558
|
let numerator = args.pop();
|
|
3520
3559
|
if (denominator.type === "leftright") {
|
|
3521
|
-
denominator =
|
|
3560
|
+
denominator = denominator.body;
|
|
3522
3561
|
}
|
|
3523
3562
|
if (numerator.type === "leftright") {
|
|
3524
|
-
numerator =
|
|
3563
|
+
numerator = numerator.body;
|
|
3525
3564
|
}
|
|
3526
3565
|
args.push(new TypstFraction([numerator, denominator]));
|
|
3527
3566
|
stack.pop();
|
|
@@ -3530,16 +3569,23 @@ function process_operators(nodes, parenthesis = false) {
|
|
|
3530
3569
|
}
|
|
3531
3570
|
}
|
|
3532
3571
|
}
|
|
3572
|
+
const body = args.length === 1 ? args[0] : new TypstGroup(args);
|
|
3533
3573
|
if (parenthesis) {
|
|
3534
|
-
return new TypstLeftright(null,
|
|
3574
|
+
return new TypstLeftright(null, { body, left: LEFT_PARENTHESES, right: RIGHT_PARENTHESES });
|
|
3535
3575
|
} else {
|
|
3536
|
-
|
|
3537
|
-
return args[0];
|
|
3538
|
-
} else {
|
|
3539
|
-
return new TypstGroup(args);
|
|
3540
|
-
}
|
|
3576
|
+
return body;
|
|
3541
3577
|
}
|
|
3542
3578
|
}
|
|
3579
|
+
function parse_named_params(groups) {
|
|
3580
|
+
const COLON = new TypstToken(2 /* ELEMENT */, ":").toNode();
|
|
3581
|
+
const np = {};
|
|
3582
|
+
for (const group of groups) {
|
|
3583
|
+
assert(group.items.length == 3);
|
|
3584
|
+
assert(group.items[1].eq(COLON));
|
|
3585
|
+
np[group.items[0].toString()] = new TypstTerminal(new TypstToken(3 /* LITERAL */, group.items[2].toString()));
|
|
3586
|
+
}
|
|
3587
|
+
return np;
|
|
3588
|
+
}
|
|
3543
3589
|
var TypstParserError = class extends Error {
|
|
3544
3590
|
constructor(message) {
|
|
3545
3591
|
super(message);
|
|
@@ -3653,19 +3699,31 @@ var TypstParser = class {
|
|
|
3653
3699
|
if (start + 1 < tokens.length && tokens[start + 1].eq(LEFT_PARENTHESES)) {
|
|
3654
3700
|
if (firstToken.value === "mat") {
|
|
3655
3701
|
const [matrix, named_params, newPos2] = this.parseMatrix(tokens, start + 1, SEMICOLON, COMMA);
|
|
3656
|
-
const mat = new
|
|
3702
|
+
const mat = new TypstMatrixLike(firstToken, matrix);
|
|
3657
3703
|
mat.setOptions(named_params);
|
|
3658
3704
|
return [mat, newPos2];
|
|
3659
3705
|
}
|
|
3660
3706
|
if (firstToken.value === "cases") {
|
|
3661
3707
|
const [cases, named_params, newPos2] = this.parseMatrix(tokens, start + 1, COMMA, CONTROL_AND);
|
|
3662
|
-
const casesNode = new
|
|
3708
|
+
const casesNode = new TypstMatrixLike(firstToken, cases);
|
|
3663
3709
|
casesNode.setOptions(named_params);
|
|
3664
3710
|
return [casesNode, newPos2];
|
|
3665
3711
|
}
|
|
3666
3712
|
if (firstToken.value === "lr") {
|
|
3667
3713
|
return this.parseLrArguments(tokens, start + 1);
|
|
3668
3714
|
}
|
|
3715
|
+
if (["#heading", "#text"].includes(firstToken.value)) {
|
|
3716
|
+
const [args2, newPos2] = this.parseArguments(tokens, start + 1);
|
|
3717
|
+
const named_params = parse_named_params(args2);
|
|
3718
|
+
assert(tokens[newPos2].eq(LEFT_BRACKET));
|
|
3719
|
+
const DOLLAR = new TypstToken(2 /* ELEMENT */, "$");
|
|
3720
|
+
const end = _find_closing_match(tokens, newPos2 + 1, [DOLLAR], [DOLLAR]);
|
|
3721
|
+
const [group, _] = this.parseGroup(tokens, newPos2 + 2, end);
|
|
3722
|
+
assert(tokens[end + 1].eq(RIGHT_BRACKET));
|
|
3723
|
+
const markup_func = new TypstMarkupFunc(firstToken, [group]);
|
|
3724
|
+
markup_func.setOptions(named_params);
|
|
3725
|
+
return [markup_func, end + 2];
|
|
3726
|
+
}
|
|
3669
3727
|
const [args, newPos] = this.parseArguments(tokens, start + 1);
|
|
3670
3728
|
const func_call = new TypstFuncCall(firstToken, args);
|
|
3671
3729
|
return [func_call, newPos];
|
|
@@ -3687,13 +3745,13 @@ var TypstParser = class {
|
|
|
3687
3745
|
const inner_end = find_closing_delim(tokens, inner_start);
|
|
3688
3746
|
const inner_args = this.parseArgumentsWithSeparator(tokens, inner_start + 1, inner_end, COMMA);
|
|
3689
3747
|
return [
|
|
3690
|
-
new TypstLeftright(lr_token, inner_args,
|
|
3748
|
+
new TypstLeftright(lr_token, { body: new TypstGroup(inner_args), left: tokens[inner_start], right: tokens[inner_end] }),
|
|
3691
3749
|
end + 1
|
|
3692
3750
|
];
|
|
3693
3751
|
} else {
|
|
3694
3752
|
const [args, end] = this.parseArguments(tokens, start);
|
|
3695
3753
|
return [
|
|
3696
|
-
new TypstLeftright(lr_token, args,
|
|
3754
|
+
new TypstLeftright(lr_token, { body: new TypstGroup(args), left: null, right: null }),
|
|
3697
3755
|
end
|
|
3698
3756
|
];
|
|
3699
3757
|
}
|
|
@@ -3716,17 +3774,17 @@ var TypstParser = class {
|
|
|
3716
3774
|
continue;
|
|
3717
3775
|
}
|
|
3718
3776
|
const g = arr[i];
|
|
3719
|
-
const pos_colon = array_find(g.
|
|
3777
|
+
const pos_colon = array_find(g.items, COLON);
|
|
3720
3778
|
if (pos_colon === -1 || pos_colon === 0) {
|
|
3721
3779
|
continue;
|
|
3722
3780
|
}
|
|
3723
3781
|
to_delete.push(i);
|
|
3724
|
-
const param_name = g.
|
|
3782
|
+
const param_name = g.items[pos_colon - 1];
|
|
3725
3783
|
if (param_name.eq(new TypstToken(1 /* SYMBOL */, "delim").toNode())) {
|
|
3726
|
-
if (g.
|
|
3784
|
+
if (g.items.length !== 3) {
|
|
3727
3785
|
throw new TypstParserError("Invalid number of arguments for delim");
|
|
3728
3786
|
}
|
|
3729
|
-
np2["delim"] = g.
|
|
3787
|
+
np2["delim"] = g.items[pos_colon + 1];
|
|
3730
3788
|
} else {
|
|
3731
3789
|
throw new TypstParserError("Not implemented for other named parameters");
|
|
3732
3790
|
}
|