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