tex2typst 0.2.3 → 0.2.7
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 +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +81 -54
- package/dist/parser.d.ts +2 -1
- package/dist/tex2typst.min.js +1 -1
- package/package.json +1 -1
- package/src/parser.ts +43 -43
- package/src/writer.ts +2 -0
package/README.md
CHANGED
|
@@ -16,12 +16,12 @@ npm install tex2typst
|
|
|
16
16
|
## Or just loading it in a web page
|
|
17
17
|
|
|
18
18
|
```html
|
|
19
|
-
<script src="https://cdn.jsdelivr.net/npm/tex2typst@0.
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/npm/tex2typst@0.2.7/dist/tex2typst.min.js"></script>
|
|
20
20
|
<!-- or -->
|
|
21
|
-
<script src="https://unpkg.com/tex2typst@0.
|
|
21
|
+
<script src="https://unpkg.com/tex2typst@0.2.7/dist/tex2typst.min.js"></script>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Replace `0.
|
|
24
|
+
Replace `0.2.7` with the latest version number in case this README is outdated.
|
|
25
25
|
|
|
26
26
|
The size of minimized library `tex2typst.min.js` is about 23 KB.
|
|
27
27
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -189,17 +189,15 @@ function tokenize(latex) {
|
|
|
189
189
|
throw new LatexParserError("Expecting command name after \\");
|
|
190
190
|
}
|
|
191
191
|
const firstTwoChars = latex.slice(pos, pos + 2);
|
|
192
|
-
if (
|
|
193
|
-
token = { type: "control", value:
|
|
194
|
-
pos += 2;
|
|
192
|
+
if (["\\\\", "\\,"].includes(firstTwoChars)) {
|
|
193
|
+
token = { type: "control", value: firstTwoChars };
|
|
195
194
|
} else if (["\\{", "\\}", "\\%", "\\$", "\\&", "\\#", "\\_"].includes(firstTwoChars)) {
|
|
196
195
|
token = { type: "element", value: firstTwoChars };
|
|
197
|
-
pos += 2;
|
|
198
196
|
} else {
|
|
199
197
|
const command = eat_command_name(latex, pos + 1);
|
|
200
198
|
token = { type: "command", value: "\\" + command };
|
|
201
|
-
pos += 1 + command.length;
|
|
202
199
|
}
|
|
200
|
+
pos += token.value.length;
|
|
203
201
|
break;
|
|
204
202
|
}
|
|
205
203
|
default: {
|
|
@@ -242,53 +240,61 @@ function tokenize(latex) {
|
|
|
242
240
|
function token_eq(token1, token2) {
|
|
243
241
|
return token1.type == token2.type && token1.value == token2.value;
|
|
244
242
|
}
|
|
245
|
-
function
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
let
|
|
249
|
-
|
|
243
|
+
function passIgnoreWhitespaceBeforeScriptMark(tokens) {
|
|
244
|
+
const is_script_mark = (token) => token_eq(token, SUB_SYMBOL) || token_eq(token, SUP_SYMBOL);
|
|
245
|
+
let out_tokens = [];
|
|
246
|
+
for (let i = 0;i < tokens.length; i++) {
|
|
247
|
+
if (tokens[i].type === "whitespace" && i + 1 < tokens.length && is_script_mark(tokens[i + 1])) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (tokens[i].type === "whitespace" && i - 1 >= 0 && is_script_mark(tokens[i - 1])) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
out_tokens.push(tokens[i]);
|
|
254
|
+
}
|
|
255
|
+
return out_tokens;
|
|
256
|
+
}
|
|
257
|
+
function passExpandCustomTexMacros(tokens, customTexMacros) {
|
|
258
|
+
let out_tokens = [];
|
|
259
|
+
for (const token of tokens) {
|
|
250
260
|
if (token.type === "command" && customTexMacros[token.value]) {
|
|
251
261
|
const expanded_tokens = tokenize(customTexMacros[token.value]);
|
|
252
|
-
|
|
262
|
+
out_tokens = out_tokens.concat(expanded_tokens);
|
|
253
263
|
} else {
|
|
254
|
-
|
|
264
|
+
out_tokens.push(token);
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
|
-
return
|
|
267
|
+
return out_tokens;
|
|
268
|
+
}
|
|
269
|
+
function parseTex(tex, customTexMacros) {
|
|
270
|
+
const parser = new LatexParser;
|
|
271
|
+
let tokens = tokenize(tex);
|
|
272
|
+
tokens = passIgnoreWhitespaceBeforeScriptMark(tokens);
|
|
273
|
+
tokens = passExpandCustomTexMacros(tokens, customTexMacros);
|
|
274
|
+
return parser.parse(tokens);
|
|
258
275
|
}
|
|
259
276
|
var UNARY_COMMANDS = [
|
|
260
277
|
"sqrt",
|
|
261
278
|
"text",
|
|
262
|
-
"arccos",
|
|
263
|
-
"arcsin",
|
|
264
|
-
"arctan",
|
|
265
|
-
"arg",
|
|
266
279
|
"bar",
|
|
267
280
|
"bold",
|
|
268
281
|
"boldsymbol",
|
|
269
282
|
"ddot",
|
|
270
|
-
"det",
|
|
271
|
-
"dim",
|
|
272
283
|
"dot",
|
|
273
|
-
"exp",
|
|
274
|
-
"gcd",
|
|
275
284
|
"hat",
|
|
276
|
-
"ker",
|
|
277
285
|
"mathbb",
|
|
278
286
|
"mathbf",
|
|
279
287
|
"mathcal",
|
|
288
|
+
"mathfrak",
|
|
289
|
+
"mathit",
|
|
290
|
+
"mathrm",
|
|
280
291
|
"mathscr",
|
|
281
292
|
"mathsf",
|
|
282
293
|
"mathtt",
|
|
283
|
-
"mathrm",
|
|
284
|
-
"max",
|
|
285
|
-
"min",
|
|
286
|
-
"mod",
|
|
287
294
|
"operatorname",
|
|
288
295
|
"overbrace",
|
|
289
296
|
"overline",
|
|
290
297
|
"pmb",
|
|
291
|
-
"sup",
|
|
292
298
|
"rm",
|
|
293
299
|
"tilde",
|
|
294
300
|
"underbrace",
|
|
@@ -449,23 +455,13 @@ class LatexParser {
|
|
|
449
455
|
throw new LatexParserError("Unmatched '}'");
|
|
450
456
|
case "\\\\":
|
|
451
457
|
return [{ type: "control", content: "\\\\" }, start + 1];
|
|
458
|
+
case "\\,":
|
|
459
|
+
return [{ type: "control", content: "\\," }, start + 1];
|
|
452
460
|
case "_": {
|
|
453
|
-
|
|
454
|
-
let sup = undefined;
|
|
455
|
-
if (pos < tokens.length && token_eq(tokens[pos], SUP_SYMBOL)) {
|
|
456
|
-
[sup, pos] = this.parseNextExpr(tokens, pos + 1);
|
|
457
|
-
}
|
|
458
|
-
const subData = { base: EMPTY_NODE, sub, sup };
|
|
459
|
-
return [{ type: "supsub", content: "", data: subData }, pos];
|
|
461
|
+
return [EMPTY_NODE, start];
|
|
460
462
|
}
|
|
461
463
|
case "^": {
|
|
462
|
-
|
|
463
|
-
let sub = undefined;
|
|
464
|
-
if (pos < tokens.length && token_eq(tokens[pos], SUB_SYMBOL)) {
|
|
465
|
-
[sub, pos] = this.parseNextExpr(tokens, pos + 1);
|
|
466
|
-
}
|
|
467
|
-
const supData = { base: EMPTY_NODE, sub, sup };
|
|
468
|
-
return [{ type: "supsub", content: "", data: supData }, pos];
|
|
464
|
+
return [EMPTY_NODE, start];
|
|
469
465
|
}
|
|
470
466
|
case "&":
|
|
471
467
|
return [{ type: "control", content: "&" }, start + 1];
|
|
@@ -615,7 +611,6 @@ class LatexParser {
|
|
|
615
611
|
|
|
616
612
|
// src/map.ts
|
|
617
613
|
var symbolMap = new Map([
|
|
618
|
-
["gets", "arrow.l"],
|
|
619
614
|
["nonumber", ""],
|
|
620
615
|
["vec", "arrow"],
|
|
621
616
|
["neq", "eq.not"],
|
|
@@ -640,13 +635,14 @@ var symbolMap = new Map([
|
|
|
640
635
|
["dfrac", "frac"],
|
|
641
636
|
["tfrac", "frac"],
|
|
642
637
|
["boldsymbol", "bold"],
|
|
643
|
-
["mathbf", "bold"],
|
|
644
638
|
["mathbb", "bb"],
|
|
639
|
+
["mathbf", "bold"],
|
|
645
640
|
["mathcal", "cal"],
|
|
641
|
+
["mathit", "italic"],
|
|
646
642
|
["mathfrak", "frak"],
|
|
643
|
+
["mathrm", "upright"],
|
|
647
644
|
["mathsf", "sans"],
|
|
648
645
|
["mathtt", "mono"],
|
|
649
|
-
["mathrm", "upright"],
|
|
650
646
|
["rm", "upright"],
|
|
651
647
|
["pmb", "bold"],
|
|
652
648
|
["pm", "plus.minus"],
|
|
@@ -662,29 +658,56 @@ var symbolMap = new Map([
|
|
|
662
658
|
["asymp", "\u224D"],
|
|
663
659
|
["equiv", "equiv"],
|
|
664
660
|
["propto", "prop"],
|
|
665
|
-
["implies", "arrow.r.double.long"],
|
|
666
|
-
["Longrightarrow", "arrow.r.double.long"],
|
|
667
|
-
["iff", "arrow.l.r.double.long"],
|
|
668
|
-
["Longleftrightarrow", "arrow.l.r.double.long"],
|
|
669
|
-
["leftrightarrow", "arrow.l.r"],
|
|
670
|
-
["longleftrightarrow", "arrow.l.r.long"],
|
|
671
|
-
["rightrightarrows", "arrows.rr"],
|
|
672
661
|
["lfloor", "\u230A"],
|
|
673
662
|
["rfloor", "\u230B"],
|
|
674
663
|
["lceil", "\u2308"],
|
|
675
664
|
["rceil", "\u2309"],
|
|
665
|
+
["gets", "arrow.l"],
|
|
666
|
+
["hookleftarrow", "arrow.l.hook"],
|
|
667
|
+
["leftharpoonup", "harpoon.lt"],
|
|
668
|
+
["leftharpoondown", "harpoon.lb"],
|
|
669
|
+
["rightleftharpoons", "harpoons.rtlb"],
|
|
670
|
+
["longleftarrow", "arrow.l.long"],
|
|
671
|
+
["longrightarrow", "arrow.r.long"],
|
|
672
|
+
["longleftrightarrow", "arrow.l.r.long"],
|
|
673
|
+
["Longleftarrow", "arrow.l.double.long"],
|
|
674
|
+
["Longrightarrow", "arrow.r.double.long"],
|
|
675
|
+
["Longleftrightarrow", "arrow.l.r.double.long"],
|
|
676
|
+
["longmapsto", "arrow.r.bar"],
|
|
677
|
+
["hookrightarrow", "arrow.r.hook"],
|
|
678
|
+
["rightharpoonup", "harpoon.rt"],
|
|
679
|
+
["rightharpoondown", "harpoon.rb"],
|
|
680
|
+
["iff", "arrow.l.r.double.long"],
|
|
681
|
+
["implies", "arrow.r.double.long"],
|
|
682
|
+
["uparrow", "arrow.t"],
|
|
683
|
+
["downarrow", "arrow.b"],
|
|
684
|
+
["updownarrow", "arrow.t.b"],
|
|
685
|
+
["Uparrow", "arrow.t.double"],
|
|
686
|
+
["Downarrow", "arrow.b.double"],
|
|
687
|
+
["Updownarrow", "arrow.t.b.double"],
|
|
688
|
+
["nearrow", "arrow.tr"],
|
|
689
|
+
["searrow", "arrow.br"],
|
|
690
|
+
["swarrow", "arrow.bl"],
|
|
691
|
+
["nwarrow", "arrow.tl"],
|
|
692
|
+
["leadsto", "arrow.squiggly"],
|
|
693
|
+
["leftleftarrows", "arrows.ll"],
|
|
694
|
+
["rightrightarrows", "arrows.rr"],
|
|
676
695
|
["Cap", "sect.double"],
|
|
677
696
|
["Cup", "union.double"],
|
|
678
697
|
["Delta", "Delta"],
|
|
679
698
|
["Gamma", "Gamma"],
|
|
680
699
|
["Join", "join"],
|
|
681
700
|
["Lambda", "Lambda"],
|
|
701
|
+
["Leftarrow", "arrow.l.double"],
|
|
702
|
+
["Leftrightarrow", "arrow.l.r.double"],
|
|
682
703
|
["Longrightarrow", "arrow.r.double.long"],
|
|
683
704
|
["Omega", "Omega"],
|
|
705
|
+
["P", "pilcrow"],
|
|
684
706
|
["Phi", "Phi"],
|
|
685
707
|
["Pi", "Pi"],
|
|
686
708
|
["Psi", "Psi"],
|
|
687
|
-
["Rightarrow", "arrow.double"],
|
|
709
|
+
["Rightarrow", "arrow.r.double"],
|
|
710
|
+
["S", "section"],
|
|
688
711
|
["Sigma", "Sigma"],
|
|
689
712
|
["Theta", "Theta"],
|
|
690
713
|
["aleph", "alef"],
|
|
@@ -716,6 +739,7 @@ var symbolMap = new Map([
|
|
|
716
739
|
["colon", "colon"],
|
|
717
740
|
["cong", "tilde.equiv"],
|
|
718
741
|
["coprod", "product.co"],
|
|
742
|
+
["copyright", "copyright"],
|
|
719
743
|
["cup", "union"],
|
|
720
744
|
["curlyvee", "or.curly"],
|
|
721
745
|
["curlywedge", "and.curly"],
|
|
@@ -768,7 +792,7 @@ var symbolMap = new Map([
|
|
|
768
792
|
["leqslant", "lt.eq.slant"],
|
|
769
793
|
["lhd", "triangle.l"],
|
|
770
794
|
["ll", "lt.double"],
|
|
771
|
-
["longmapsto", "arrow.long
|
|
795
|
+
["longmapsto", "arrow.bar.long"],
|
|
772
796
|
["longrightarrow", "arrow.long"],
|
|
773
797
|
["lor", "or"],
|
|
774
798
|
["ltimes", "times.l"],
|
|
@@ -1141,6 +1165,8 @@ class TypstWriter {
|
|
|
1141
1165
|
} else if (node.type === "control") {
|
|
1142
1166
|
if (node.content === "\\\\") {
|
|
1143
1167
|
this.queue.push({ type: "symbol", content: node.content });
|
|
1168
|
+
} else if (node.content === "\\,") {
|
|
1169
|
+
this.queue.push({ type: "symbol", content: "thin" });
|
|
1144
1170
|
} else {
|
|
1145
1171
|
throw new TypstWriterError(`Unknown control sequence: ${node.content}`, node);
|
|
1146
1172
|
}
|
|
@@ -1241,5 +1267,6 @@ function tex2typst(tex, options) {
|
|
|
1241
1267
|
return writer2.finalize();
|
|
1242
1268
|
}
|
|
1243
1269
|
export {
|
|
1244
|
-
tex2typst
|
|
1270
|
+
tex2typst,
|
|
1271
|
+
symbolMap
|
|
1245
1272
|
};
|
package/dist/parser.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { TexNode } from "./types";
|
|
2
|
-
interface Token {
|
|
2
|
+
export interface Token {
|
|
3
3
|
type: 'element' | 'command' | 'text' | 'comment' | 'whitespace' | 'newline' | 'control' | 'unknown';
|
|
4
4
|
value: string;
|
|
5
5
|
}
|
|
6
|
+
export declare function tokenize(latex: string): Token[];
|
|
6
7
|
export declare class LatexParserError extends Error {
|
|
7
8
|
constructor(message: string);
|
|
8
9
|
}
|
package/dist/tex2typst.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function G(J,Z=""){if(!J)throw new v(Z)}function c(J){if(E.includes(J))return 1;else if(m.includes(J))return 2;else return 0}function x(J,Z){G(H(J[Z],D));let V=1,$=Z+1;while(V>0){if($>=J.length)throw new v("Unmatched curly brackets");if(H(J[$],D))V+=1;else if(H(J[$],S))V-=1;$+=1}return $-1}function l(J,Z){G(H(J[Z],I));let V=1,$=Z+1;while(V>0){if($>=J.length)throw new v("Unmatched square brackets");if(H(J[$],I))V+=1;else if(H(J[$],i))V-=1;$+=1}return $-1}function C(J){return"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(J)}function w(J){return"0123456789".includes(J)}function N(J,Z){let V=Z;while(V<J.length&&["whitespace","newline"].includes(J[V].type))V++;return J.slice(Z,V)}function R(J,Z){const V=J[Z];if(V.type==="element"&&["(",")","[","]","|","\\{","\\}"].includes(V.value))return V;else if(V.type==="command"&&["lfloor","rfloor","lceil","rceil","langle","rangle"].includes(V.value.slice(1)))return V;else return null}function K(J,Z){let V=Z;while(V<J.length&&H(J[V],{type:"element",value:"'"}))V+=1;return V-Z}function _(J,Z){let V=Z;while(V<J.length&&C(J[V]))V+=1;return J.substring(Z,V)}function p(J,Z){let V=1,$=Z;while(V>0){if($>=J.length)return-1;if(H(J[$],q))V+=1;else if(H(J[$],d))V-=1;$+=1}return $-1}function a(J,Z){let V=1,$=Z;while(V>0){if($>=J.length)return-1;if(H(J[$],M))V+=1;else if(H(J[$],k))V-=1;$+=1}return $-1}function r(J,Z){G(J[Z]==="{");let V=1,$=Z+1;while(V>0){if($>=J.length)throw new v("Unmatched curly brackets");if($+1<J.length&&["\\{","\\}"].includes(J.substring($,$+2))){$+=2;continue}if(J[$]==="{")V+=1;else if(J[$]==="}")V-=1;$+=1}return $-1}function g(J){const Z=[];let V=0;while(V<J.length){const $=J[V];let X;switch($){case"%":{let z=V+1;while(z<J.length&&J[z]!=="\n")z+=1;X={type:"comment",value:J.slice(V+1,z)},V=z;break}case"{":case"}":case"_":case"^":case"&":X={type:"control",value:$},V++;break;case"\n":X={type:"newline",value:$},V++;break;case"\r":{if(V+1<J.length&&J[V+1]==="\n")X={type:"newline",value:"\n"},V+=2;else X={type:"newline",value:"\n"},V++;break}case" ":{let z=V;while(z<J.length&&J[z]===" ")z+=1;X={type:"whitespace",value:J.slice(V,z)},V=z;break}case"\\":{if(V+1>=J.length)throw new v("Expecting command name after \\");const z=J.slice(V,V+2);if(z==="\\\\")X={type:"control",value:"\\\\"},V+=2;else if(["\\{","\\}","\\%","\\$","\\&","\\#","\\_"].includes(z))X={type:"element",value:z},V+=2;else{const j=_(J,V+1);X={type:"command",value:"\\"+j},V+=1+j.length}break}default:{if(w($)){let z=V;while(z<J.length&&w(J[z]))z+=1;X={type:"element",value:J.slice(V,z)}}else if(C($))X={type:"element",value:$};else if("+-*/=\'<>!.,;?()[]|".includes($))X={type:"element",value:$};else X={type:"unknown",value:$};V+=X.value.length}}if(Z.push(X),X.type==="command"&&["\\text","\\begin","\\end"].includes(X.value)){if(V>=J.length||J[V]!=="{")throw new v(`No content for ${X.value} command`);Z.push({type:"control",value:"{"});const z=r(J,V);V++;let j=J.slice(V,z);const Q=["{","}","\\","$","&","#","_","%"];for(let W of Q)j=j.replaceAll("\\"+W,W);Z.push({type:"text",value:j}),Z.push({type:"control",value:"}"}),V=z+1}}return Z}function H(J,Z){return J.type==Z.type&&J.value==Z.value}function b(J,Z){const V=new T,$=g(J);let X=[];for(let z of $)if(z.type==="command"&&Z[z.value]){const j=g(Z[z.value]);X=X.concat(j)}else X.push(z);return V.parse(X)}var E=["sqrt","text","arccos","arcsin","arctan","arg","bar","bold","boldsymbol","ddot","det","dim","dot","exp","gcd","hat","ker","mathbb","mathbf","mathcal","mathscr","mathsf","mathtt","mathrm","max","min","mod","operatorname","overbrace","overline","pmb","sup","rm","tilde","underbrace","underline","vec","widehat","widetilde"],m=["frac","tfrac","binom","dbinom","dfrac","tbinom"],Y={type:"empty",content:""},D={type:"control",value:"{"},S={type:"control",value:"}"},I={type:"element",value:"["},i={type:"element",value:"]"},q={type:"command",value:"\\left"},d={type:"command",value:"\\right"},M={type:"command",value:"\\begin"},k={type:"command",value:"\\end"};class v extends Error{constructor(J){super(J);this.name="LatexParserError"}}var y={type:"control",value:"_"},A={type:"control",value:"^"};class T{space_sensitive;newline_sensitive;constructor(J=!1,Z=!0){this.space_sensitive=J,this.newline_sensitive=Z}parse(J){const Z=[];let V=0;while(V<J.length){const $=[];let X=0;while(X<J.length){const[z,j]=this.parseNextExpr(J,X);if(X=j,!this.space_sensitive&&z.type==="whitespace")continue;if(!this.newline_sensitive&&z.type==="newline")continue;if(z.type==="control"&&z.content==="&")throw new v("Unexpected & outside of an alignment");$.push(z)}if($.length===0)return Y;else if($.length===1)return $[0];else return{type:"ordgroup",content:"",args:$}}if(Z.length===0)return Y;else if(Z.length===1)return Z[0];else return{type:"ordgroup",content:"",args:Z}}parseNextExpr(J,Z){let[V,$]=this.parseNextExprWithoutSupSub(J,Z),X=null,z=null,j=0;if(j+=K(J,$),$+=j,$<J.length&&H(J[$],y)){if([X,$]=this.parseNextExprWithoutSupSub(J,$+1),j+=K(J,$),$+=j,$<J.length&&H(J[$],A)){if([z,$]=this.parseNextExprWithoutSupSub(J,$+1),K(J,$)>0)throw new v("Double superscript")}}else if($<J.length&&H(J[$],A)){if([z,$]=this.parseNextExprWithoutSupSub(J,$+1),K(J,$)>0)throw new v("Double superscript");if($<J.length&&H(J[$],y)){if([X,$]=this.parseNextExprWithoutSupSub(J,$+1),K(J,$)>0)throw new v("Double superscript")}}if(X!==null||z!==null||j>0){const Q={base:V};if(X)Q.sub=X;if(j>0){Q.sup={type:"ordgroup",content:"",args:[]};for(let W=0;W<j;W++)Q.sup.args.push({type:"symbol",content:"\\prime"});if(z)Q.sup.args.push(z);if(Q.sup.args.length===1)Q.sup=Q.sup.args[0]}else if(z)Q.sup=z;return[{type:"supsub",content:"",data:Q},$]}else return[V,$]}parseNextExprWithoutSupSub(J,Z){const V=J[Z],$=V.type;switch($){case"element":case"text":case"comment":case"whitespace":case"newline":return[{type:$,content:V.value},Z+1];case"command":if(H(V,M))return this.parseBeginEndExpr(J,Z);else if(H(V,q))return this.parseLeftRightExpr(J,Z);else return this.parseCommandExpr(J,Z);case"control":switch(V.value){case"{":const z=x(J,Z),j=J.slice(Z+1,z);return[this.parse(j),z+1];case"}":throw new v("Unmatched '}'");case"\\\\":return[{type:"control",content:"\\\\"},Z+1];case"_":{let[Q,W]=this.parseNextExpr(J,Z+1),F=void 0;if(W<J.length&&H(J[W],A))[F,W]=this.parseNextExpr(J,W+1);return[{type:"supsub",content:"",data:{base:Y,sub:Q,sup:F}},W]}case"^":{let[Q,W]=this.parseNextExpr(J,Z+1),F=void 0;if(W<J.length&&H(J[W],y))[F,W]=this.parseNextExpr(J,W+1);return[{type:"supsub",content:"",data:{base:Y,sub:F,sup:Q}},W]}case"&":return[{type:"control",content:"&"},Z+1];default:throw new v("Unknown control sequence")}default:throw new v("Unknown token type")}}parseCommandExpr(J,Z){G(J[Z].type==="command");const V=J[Z].value;let $=Z+1;if(["left","right","begin","end"].includes(V.slice(1)))throw new v("Unexpected command: "+V);const X=c(V.slice(1));if(X===0)return[{type:"symbol",content:V},$];else if(X===1){if(V==="\\sqrt"&&$<J.length&&H(J[$],I)){const Q=$,W=l(J,$),F=J.slice(Q+1,W),U=this.parse(F),[f,u]=this.parseNextExprWithoutSupSub(J,W+1);return[{type:"unaryFunc",content:V,args:[f],data:U},u]}else if(V==="\\text"){if($+2>=J.length)throw new v("Expecting content for \\text command");return G(H(J[$],D)),G(J[$+1].type==="text"),G(H(J[$+2],S)),[{type:"text",content:J[$+1].value},$+3]}let[z,j]=this.parseNextExprWithoutSupSub(J,$);return[{type:"unaryFunc",content:V,args:[z]},j]}else if(X===2){const[z,j]=this.parseNextExprWithoutSupSub(J,$),[Q,W]=this.parseNextExprWithoutSupSub(J,j);return[{type:"binaryFunc",content:V,args:[z,Q]},W]}else throw new Error("Invalid number of parameters")}parseLeftRightExpr(J,Z){G(H(J[Z],q));let V=Z+1;if(V+=N(J,V).length,V>=J.length)throw new v("Expecting delimiter after \\left");const $=R(J,V);if($===null)throw new v("Invalid delimiter after \\left");V++;const X=V,z=p(J,V);if(z===-1)throw new v("No matching \\right");const j=z;if(V=z+1,V+=N(J,V).length,V>=J.length)throw new v("Expecting \\right after \\left");const Q=R(J,V);if(Q===null)throw new v("Invalid delimiter after \\right");V++;const W=J.slice(X,j),F=this.parse(W);return[{type:"leftright",content:"",args:[{type:"element",content:$.value},F,{type:"element",content:Q.value}]},V]}parseBeginEndExpr(J,Z){G(H(J[Z],M));let V=Z+1;G(H(J[V],D)),G(J[V+1].type==="text"),G(H(J[V+2],S));const $=J[V+1].value;V+=3,V+=N(J,V).length;const X=V,z=a(J,V);if(z===-1)throw new v("No matching \\end");const j=z;if(V=z+1,G(H(J[V],D)),G(J[V+1].type==="text"),G(H(J[V+2],S)),J[V+1].value!==$)throw new v("Mismatched \\begin and \\end environments");V+=3;const Q=J.slice(X,j);while(Q.length>0&&["whitespace","newline"].includes(Q[Q.length-1].type))Q.pop();const W=this.parseAligned(Q);return[{type:"beginend",content:$,data:W},V]}parseAligned(J){let Z=0;const V=[];let $=[];V.push($);let X={type:"ordgroup",content:"",args:[]};$.push(X);while(Z<J.length){const[z,j]=this.parseNextExpr(J,Z);if(Z=j,z.type==="whitespace")continue;else if(z.type==="newline"&&!this.newline_sensitive)continue;else if(z.type==="control"&&z.content==="\\\\")$=[],X={type:"ordgroup",content:"",args:[]},$.push(X),V.push($);else if(z.type==="control"&&z.content==="&")X={type:"ordgroup",content:"",args:[]},$.push(X);else X.args.push(z)}return V}}var B=new Map([["gets","arrow.l"],["nonumber",""],["vec","arrow"],["neq","eq.not"],["dot","dot"],["ddot","dot.double"],["doteq","dot(eq)"],["dots","dots.h"],["ldots","dots.h"],["vdots","dots.v"],["ddots","dots.down"],["widehat","hat"],["widetilde","tilde"],["quad","quad"],["qquad","wide"],["overbrace","overbrace"],["underbrace","underbrace"],["overline","overline"],["underline","underline"],["bar","macron"],["dbinom","binom"],["tbinom","binom"],["dfrac","frac"],["tfrac","frac"],["boldsymbol","bold"],["mathbf","bold"],["mathbb","bb"],["mathcal","cal"],["mathfrak","frak"],["mathsf","sans"],["mathtt","mono"],["mathrm","upright"],["rm","upright"],["pmb","bold"],["pm","plus.minus"],["mp","minus.plus"],["oplus","xor"],["boxplus","plus.square"],["otimes","times.circle"],["boxtimes","times.square"],["sim","tilde"],["approx","approx"],["cong","tilde.equiv"],["simeq","tilde.eq"],["asymp","\u224D"],["equiv","equiv"],["propto","prop"],["implies","arrow.r.double.long"],["Longrightarrow","arrow.r.double.long"],["iff","arrow.l.r.double.long"],["Longleftrightarrow","arrow.l.r.double.long"],["leftrightarrow","arrow.l.r"],["longleftrightarrow","arrow.l.r.long"],["rightrightarrows","arrows.rr"],["lfloor","\u230A"],["rfloor","\u230B"],["lceil","\u2308"],["rceil","\u2309"],["Cap","sect.double"],["Cup","union.double"],["Delta","Delta"],["Gamma","Gamma"],["Join","join"],["Lambda","Lambda"],["Longrightarrow","arrow.r.double.long"],["Omega","Omega"],["Phi","Phi"],["Pi","Pi"],["Psi","Psi"],["Rightarrow","arrow.double"],["Sigma","Sigma"],["Theta","Theta"],["aleph","alef"],["alpha","alpha"],["angle","angle"],["approx","approx"],["approxeq","approx.eq"],["ast","ast"],["beta","beta"],["bigcap","sect.big"],["bigcirc","circle.big"],["bigcup","union.big"],["bigodot","dot.circle.big"],["bigoplus","xor.big"],["bigotimes","times.circle.big"],["bigsqcup","union.sq.big"],["bigtriangledown","triangle.b"],["bigtriangleup","triangle.t"],["biguplus","union.plus.big"],["bigvee","or.big"],["bigwedge","and.big"],["bullet","bullet"],["cap","sect"],["cdot","dot.op"],["cdots","dots.c"],["checkmark","checkmark"],["chi","chi"],["circ","circle.small"],["colon","colon"],["cong","tilde.equiv"],["coprod","product.co"],["cup","union"],["curlyvee","or.curly"],["curlywedge","and.curly"],["dagger","dagger"],["dashv","tack.l"],["ddagger","dagger.double"],["delta","delta"],["ddots","dots.down"],["diamond","diamond"],["div","div"],["divideontimes","times.div"],["dotplus","plus.dot"],["downarrow","arrow.b"],["ell","ell"],["emptyset","nothing"],["epsilon","epsilon.alt"],["equiv","equiv"],["eta","eta"],["exists","exists"],["forall","forall"],["gamma","gamma"],["ge","gt.eq"],["geq","gt.eq"],["geqslant","gt.eq.slant"],["gg","gt.double"],["hbar","planck.reduce"],["imath","dotless.i"],["iiiint","intgral.quad"],["iiint","integral.triple"],["iint","integral.double"],["in","in"],["infty","infinity"],["int","integral"],["intercal","top"],["iota","iota"],["jmath","dotless.j"],["kappa","kappa"],["lambda","lambda"],["land","and"],["langle","angle.l"],["lbrace","brace.l"],["lbrack","bracket.l"],["ldots","dots.l"],["le","lt.eq"],["leadsto","arrow.squiggly"],["leftarrow","arrow.l"],["leftthreetimes","times.three.l"],["leftrightarrow","arrow.l.r"],["leq","lt.eq"],["leqslant","lt.eq.slant"],["lhd","triangle.l"],["ll","lt.double"],["longmapsto","arrow.long.bar"],["longrightarrow","arrow.long"],["lor","or"],["ltimes","times.l"],["mapsto","arrow.bar"],["measuredangle","angle.arc"],["mid","divides"],["models","models"],["mp","minus.plus"],["mu","mu"],["nRightarrow","arrow.double.not"],["nabla","nabla"],["ncong","tilde.nequiv"],["ne","eq.not"],["neg","not"],["neq","eq.not"],["nexists","exists.not"],["ni","in.rev"],["nleftarrow","arrow.l.not"],["nleq","lt.eq.not"],["nparallel","parallel.not"],["ngeq","gt.eq.not"],["nmid","divides.not"],["notin","in.not"],["nrightarrow","arrow.not"],["nsim","tilde.not"],["nsubseteq","subset.eq.not"],["nu","nu"],["ntriangleleft","lt.tri.not"],["ntriangleright","gt.tri.not"],["nwarrow","arrow.tl"],["odot","dot.circle"],["oint","integral.cont"],["oiint","integral.surf"],["oiiint","integral.vol"],["omega","omega"],["ominus","minus.circle"],["oplus","xor"],["otimes","times.circle"],["parallel","parallel"],["partial","diff"],["perp","perp"],["phi","phi.alt"],["pi","pi"],["pm","plus.minus"],["pounds","pound"],["prec","prec"],["preceq","prec.eq"],["prime","prime"],["prod","product"],["propto","prop"],["psi","psi"],["rangle","angle.r"],["rbrace","brace.r"],["rbrack","bracket.r"],["rhd","triangle"],["rho","rho"],["rightarrow","arrow.r"],["rightthreetimes","times.three.r"],["rtimes","times.r"],["setminus","without"],["sigma","sigma"],["sim","tilde"],["simeq","tilde.eq"],["slash","slash"],["smallsetminus","without"],["spadesuit","suit.spade"],["sqcap","sect.sq"],["sqcup","union.sq"],["sqsubseteq","subset.eq.sq"],["sqsupseteq","supset.eq.sq"],["star","star"],["subset","subset"],["subseteq","subset.eq"],["subsetneq","subset.neq"],["succ","succ"],["succeq","succ.eq"],["sum","sum"],["supset","supset"],["supseteq","supset.eq"],["supsetneq","supset.neq"],["swarrow","arrow.bl"],["tau","tau"],["theta","theta"],["times","times"],["to","arrow.r"],["top","top"],["triangle","triangle.t"],["triangledown","triangle.b.small"],["triangleleft","triangle.l.small"],["triangleright","triangle.r.small"],["twoheadrightarrow","arrow.r.twohead"],["uparrow","arrow.t"],["updownarrow","arrow.t.b"],["upharpoonright","harpoon.tr"],["uplus","union.plus"],["upsilon","upsilon"],["varepsilon","epsilon"],["varnothing","diameter"],["varphi","phi"],["varpi","pi.alt"],["varrho","rho.alt"],["varsigma","sigma.alt"],["vartheta","theta.alt"],["vdash","tack.r"],["vdots","dots.v"],["vee","or"],["wedge","and"],["wr","wreath"],["xi","xi"],["yen","yen"],["zeta","zeta"],["mathscr","scr"],["LaTeX","#LaTeX"],["TeX","#TeX"]]);function L(J){if(/^[a-zA-Z0-9]$/.test(J))return J;else if(J==="\\\\")return"\\";else if(J=="/")return"\\/";else if(["\\$","\\#","\\&","\\_"].includes(J))return J;else if(J.startsWith("\\")){const Z=J.slice(1);if(B.has(Z))return B.get(Z);else return Z}return J}var n=["dim","id","im","mod","Pr","sech","csch"];class O extends Error{node;constructor(J,Z){super(J);this.name="TypstWriterError",this.node=Z}}class h{nonStrict;preferTypstIntrinsic;buffer="";queue=[];needSpaceAfterSingleItemScript=!1;insideFunctionDepth=0;constructor(J,Z){this.nonStrict=J,this.preferTypstIntrinsic=Z}writeBuffer(J){if(this.needSpaceAfterSingleItemScript&&/^[0-9a-zA-Z\(]/.test(J))this.buffer+=" ";else{let Z=!1;if(Z||=/[\(\|]$/.test(this.buffer)&&/^\w/.test(J),Z||=/^[}()_^,;!\|]$/.test(J),Z||=J==="'",Z||=/[0-9]$/.test(this.buffer)&&/^[0-9]/.test(J),Z||=/[\(\[{]\s*(-|\+)$/.test(this.buffer)||this.buffer==="-"||this.buffer==="+",Z||=J.startsWith("\n"),Z||=this.buffer==="",Z||=/[\s"_^{\(]$/.test(this.buffer),!Z)this.buffer+=" "}if(this.needSpaceAfterSingleItemScript)this.needSpaceAfterSingleItemScript=!1;this.buffer+=J}append(J){if(J.type==="empty"||J.type==="whitespace")return;else if(J.type==="ordgroup")J.args.forEach((Z)=>this.append(Z));else if(J.type==="element"){let Z=J.content;if(J.content===","&&this.insideFunctionDepth>0)Z="comma";this.queue.push({type:"symbol",content:Z})}else if(J.type==="symbol")this.queue.push({type:"symbol",content:J.content});else if(J.type==="text")this.queue.push(J);else if(J.type==="supsub"){let{base:Z,sup:V,sub:$}=J.data;if(Z&&Z.type==="unaryFunc"&&Z.content==="\\overbrace"&&V){this.append({type:"binaryFunc",content:"\\overbrace",args:[Z.args[0],V]});return}else if(Z&&Z.type==="unaryFunc"&&Z.content==="\\underbrace"&&$){this.append({type:"binaryFunc",content:"\\underbrace",args:[Z.args[0],$]});return}if(Z.type==="empty")this.queue.push({type:"text",content:""});else this.appendWithBracketsIfNeeded(Z);let X=!1;const z=V&&V.type==="symbol"&&V.content==="\\prime";if(z)this.queue.push({type:"atom",content:"\'"}),X=!1;if($)this.queue.push({type:"atom",content:"_"}),X=this.appendWithBracketsIfNeeded($);if(V&&!z)this.queue.push({type:"atom",content:"^"}),X=this.appendWithBracketsIfNeeded(V);if(X)this.queue.push({type:"softSpace",content:""})}else if(J.type==="leftright"){const[Z,V,$]=J.args;if(["[]","()","\\{\\}","\\lfloor\\rfloor","\\lceil\\rceil"].includes(Z.content+$.content)){this.append(Z),this.append(V),this.append($);return}const X={type:"symbol",content:"lr"};this.queue.push(X),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(Z),this.append(V),this.append($),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(J.type==="binaryFunc"){const Z={type:"symbol",content:J.content},[V,$]=J.args;this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(V),this.queue.push({type:"atom",content:","}),this.append($),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(J.type==="unaryFunc"){const Z={type:"symbol",content:J.content},V=J.args[0];if(J.content==="\\sqrt"&&J.data){Z.content="root",this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J.data),this.queue.push({type:"atom",content:","}),this.append(V),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--;return}else if(J.content==="\\mathbf"){this.append({type:"symbol",content:"upright"}),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(V),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--,this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--;return}else if(J.content==="\\mathbb"){const $=J.args[0];if($.type==="element"&&/^[A-Z]$/.test($.content)){this.queue.push({type:"symbol",content:$.content+$.content});return}}else if(J.content==="\\operatorname"){let $=J.args;if($.length===1&&$[0].type=="ordgroup")$=$[0].args;const X=$.reduce((z,j)=>{return z+=L(j.content),z},"");if(this.preferTypstIntrinsic&&n.includes(X))this.queue.push({type:"symbol",content:X});else this.queue.push({type:"symbol",content:"op"}),this.queue.push({type:"atom",content:"("}),this.queue.push({type:"text",content:X}),this.queue.push({type:"atom",content:")"});return}this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(V),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(J.type==="newline"){this.queue.push({type:"newline",content:"\n"});return}else if(J.type==="beginend")if(J.content.startsWith("align")){const Z=J.data;Z.forEach((V,$)=>{if(V.forEach((X,z)=>{if(z>0)this.queue.push({type:"atom",content:"&"});this.append(X)}),$<Z.length-1)this.queue.push({type:"symbol",content:"\\\\"})})}else{const Z=J.data;this.queue.push({type:"symbol",content:"mat"}),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.queue.push({type:"symbol",content:"delim: #none, "}),Z.forEach((V,$)=>{V.forEach((X,z)=>{if(X.type==="ordgroup"&&X.args.length===0){this.queue.push({type:"atom",content:","});return}if(this.append(X),z<V.length-1)this.queue.push({type:"atom",content:","});else if($<Z.length-1)this.queue.push({type:"atom",content:";"})})}),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(J.type==="matrix");else if(J.type==="unknownMacro")if(this.nonStrict)this.queue.push({type:"symbol",content:J.content});else throw new O(`Unknown macro: ${J.content}`,J);else if(J.type==="control")if(J.content==="\\\\")this.queue.push({type:"symbol",content:J.content});else throw new O(`Unknown control sequence: ${J.content}`,J);else if(J.type==="comment")this.queue.push({type:"comment",content:J.content});else throw new O(`Unimplemented node type to append: ${J.type}`,J)}flushQueue(){this.queue.forEach((J)=>{let Z="";switch(J.type){case"atom":Z=J.content;break;case"symbol":Z=L(J.content);break;case"text":Z=`"${J.content}"`;break;case"softSpace":this.needSpaceAfterSingleItemScript=!0,Z="";break;case"comment":Z=`//${J.content}`;break;case"newline":Z="\n";break;default:throw new O(`Unexpected node type to stringify: ${J.type}`,J)}if(Z!=="")this.writeBuffer(Z)}),this.queue=[]}appendWithBracketsIfNeeded(J){const Z=["symbol","element","unaryFunc","binaryFunc","leftright"].includes(J.type);if(Z)this.append(J);else this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:")"});return Z}finalize(){this.flushQueue();const J=function(V){let $=V.replace(/⌊\s*(.*?)\s*⌋/g,"floor($1)");return $=$.replace(/floor\(\)/g,'floor("")'),$},Z=function(V){let $=V.replace(/⌈\s*(.*?)\s*⌉/g,"ceil($1)");return $=$.replace(/ceil\(\)/g,'ceil("")'),$};return this.buffer=J(this.buffer),this.buffer=Z(this.buffer),this.buffer}}function P(J,Z){const V={nonStrict:!1,preferTypstIntrinsic:!0,customTexMacros:{}};if(Z){if(Z.nonStrict)V.nonStrict=Z.nonStrict;if(Z.preferTypstIntrinsic)V.preferTypstIntrinsic=Z.preferTypstIntrinsic;if(Z.customTexMacros)V.customTexMacros=Z.customTexMacros}const $=b(J,V.customTexMacros),X=new h(V.nonStrict,V.preferTypstIntrinsic);return X.append($),X.finalize()}if(typeof window!=="undefined")window.tex2typst=P;
|
|
1
|
+
function v(z,Z=""){if(!z)throw new H(Z)}function c(z){if(u.includes(z))return 1;else if(m.includes(z))return 2;else return 0}function x(z,Z){v(q(z[Z],F));let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched curly brackets");if(q(z[V],F))J+=1;else if(q(z[V],D))J-=1;V+=1}return V-1}function l(z,Z){v(q(z[Z],y));let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched square brackets");if(q(z[V],y))J+=1;else if(q(z[V],_))J-=1;V+=1}return V-1}function g(z){return"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(z)}function R(z){return"0123456789".includes(z)}function S(z,Z){let J=Z;while(J<z.length&&["whitespace","newline"].includes(z[J].type))J++;return z.slice(Z,J)}function w(z,Z){const J=z[Z];if(J.type==="element"&&["(",")","[","]","|","\\{","\\}"].includes(J.value))return J;else if(J.type==="command"&&["lfloor","rfloor","lceil","rceil","langle","rangle"].includes(J.value.slice(1)))return J;else return null}function G(z,Z){let J=Z;while(J<z.length&&q(z[J],{type:"element",value:"'"}))J+=1;return J-Z}function i(z,Z){let J=Z;while(J<z.length&&g(z[J]))J+=1;return z.substring(Z,J)}function p(z,Z){let J=1,V=Z;while(J>0){if(V>=z.length)return-1;if(q(z[V],N))J+=1;else if(q(z[V],d))J-=1;V+=1}return V-1}function a(z,Z){let J=1,V=Z;while(J>0){if(V>=z.length)return-1;if(q(z[V],A))J+=1;else if(q(z[V],k))J-=1;V+=1}return V-1}function n(z,Z){v(z[Z]==="{");let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched curly brackets");if(V+1<z.length&&["\\{","\\}"].includes(z.substring(V,V+2))){V+=2;continue}if(z[V]==="{")J+=1;else if(z[V]==="}")J-=1;V+=1}return V-1}function C(z){const Z=[];let J=0;while(J<z.length){const V=z[J];let X;switch(V){case"%":{let $=J+1;while($<z.length&&z[$]!=="\n")$+=1;X={type:"comment",value:z.slice(J+1,$)},J=$;break}case"{":case"}":case"_":case"^":case"&":X={type:"control",value:V},J++;break;case"\n":X={type:"newline",value:V},J++;break;case"\r":{if(J+1<z.length&&z[J+1]==="\n")X={type:"newline",value:"\n"},J+=2;else X={type:"newline",value:"\n"},J++;break}case" ":{let $=J;while($<z.length&&z[$]===" ")$+=1;X={type:"whitespace",value:z.slice(J,$)},J=$;break}case"\\":{if(J+1>=z.length)throw new H("Expecting command name after \\");const $=z.slice(J,J+2);if(["\\\\","\\,"].includes($))X={type:"control",value:$};else if(["\\{","\\}","\\%","\\$","\\&","\\#","\\_"].includes($))X={type:"element",value:$};else X={type:"command",value:"\\"+i(z,J+1)};J+=X.value.length;break}default:{if(R(V)){let $=J;while($<z.length&&R(z[$]))$+=1;X={type:"element",value:z.slice(J,$)}}else if(g(V))X={type:"element",value:V};else if("+-*/=\'<>!.,;?()[]|".includes(V))X={type:"element",value:V};else X={type:"unknown",value:V};J+=X.value.length}}if(Z.push(X),X.type==="command"&&["\\text","\\begin","\\end"].includes(X.value)){if(J>=z.length||z[J]!=="{")throw new H(`No content for ${X.value} command`);Z.push({type:"control",value:"{"});const $=n(z,J);J++;let j=z.slice(J,$);const Q=["{","}","\\","$","&","#","_","%"];for(let W of Q)j=j.replaceAll("\\"+W,W);Z.push({type:"text",value:j}),Z.push({type:"control",value:"}"}),J=$+1}}return Z}function q(z,Z){return z.type==Z.type&&z.value==Z.value}function r(z){const Z=(V)=>q(V,I)||q(V,B);let J=[];for(let V=0;V<z.length;V++){if(z[V].type==="whitespace"&&V+1<z.length&&Z(z[V+1]))continue;if(z[V].type==="whitespace"&&V-1>=0&&Z(z[V-1]))continue;J.push(z[V])}return J}function t(z,Z){let J=[];for(let V of z)if(V.type==="command"&&Z[V.value]){const X=C(Z[V.value]);J=J.concat(X)}else J.push(V);return J}function T(z,Z){const J=new b;let V=C(z);return V=r(V),V=t(V,Z),J.parse(V)}var u=["sqrt","text","bar","bold","boldsymbol","ddot","dot","hat","mathbb","mathbf","mathcal","mathfrak","mathit","mathrm","mathscr","mathsf","mathtt","operatorname","overbrace","overline","pmb","rm","tilde","underbrace","underline","vec","widehat","widetilde"],m=["frac","tfrac","binom","dbinom","dfrac","tbinom"],U={type:"empty",content:""},F={type:"control",value:"{"},D={type:"control",value:"}"},y={type:"element",value:"["},_={type:"element",value:"]"},N={type:"command",value:"\\left"},d={type:"command",value:"\\right"},A={type:"command",value:"\\begin"},k={type:"command",value:"\\end"};class H extends Error{constructor(z){super(z);this.name="LatexParserError"}}var I={type:"control",value:"_"},B={type:"control",value:"^"};class b{space_sensitive;newline_sensitive;constructor(z=!1,Z=!0){this.space_sensitive=z,this.newline_sensitive=Z}parse(z){const Z=[];let J=0;while(J<z.length){const V=[];let X=0;while(X<z.length){const[$,j]=this.parseNextExpr(z,X);if(X=j,!this.space_sensitive&&$.type==="whitespace")continue;if(!this.newline_sensitive&&$.type==="newline")continue;if($.type==="control"&&$.content==="&")throw new H("Unexpected & outside of an alignment");V.push($)}if(V.length===0)return U;else if(V.length===1)return V[0];else return{type:"ordgroup",content:"",args:V}}if(Z.length===0)return U;else if(Z.length===1)return Z[0];else return{type:"ordgroup",content:"",args:Z}}parseNextExpr(z,Z){let[J,V]=this.parseNextExprWithoutSupSub(z,Z),X=null,$=null,j=0;if(j+=G(z,V),V+=j,V<z.length&&q(z[V],I)){if([X,V]=this.parseNextExprWithoutSupSub(z,V+1),j+=G(z,V),V+=j,V<z.length&&q(z[V],B)){if([$,V]=this.parseNextExprWithoutSupSub(z,V+1),G(z,V)>0)throw new H("Double superscript")}}else if(V<z.length&&q(z[V],B)){if([$,V]=this.parseNextExprWithoutSupSub(z,V+1),G(z,V)>0)throw new H("Double superscript");if(V<z.length&&q(z[V],I)){if([X,V]=this.parseNextExprWithoutSupSub(z,V+1),G(z,V)>0)throw new H("Double superscript")}}if(X!==null||$!==null||j>0){const Q={base:J};if(X)Q.sub=X;if(j>0){Q.sup={type:"ordgroup",content:"",args:[]};for(let W=0;W<j;W++)Q.sup.args.push({type:"symbol",content:"\\prime"});if($)Q.sup.args.push($);if(Q.sup.args.length===1)Q.sup=Q.sup.args[0]}else if($)Q.sup=$;return[{type:"supsub",content:"",data:Q},V]}else return[J,V]}parseNextExprWithoutSupSub(z,Z){const J=z[Z],V=J.type;switch(V){case"element":case"text":case"comment":case"whitespace":case"newline":return[{type:V,content:J.value},Z+1];case"command":if(q(J,A))return this.parseBeginEndExpr(z,Z);else if(q(J,N))return this.parseLeftRightExpr(z,Z);else return this.parseCommandExpr(z,Z);case"control":switch(J.value){case"{":const $=x(z,Z),j=z.slice(Z+1,$);return[this.parse(j),$+1];case"}":throw new H("Unmatched '}'");case"\\\\":return[{type:"control",content:"\\\\"},Z+1];case"\\,":return[{type:"control",content:"\\,"},Z+1];case"_":return[U,Z];case"^":return[U,Z];case"&":return[{type:"control",content:"&"},Z+1];default:throw new H("Unknown control sequence")}default:throw new H("Unknown token type")}}parseCommandExpr(z,Z){v(z[Z].type==="command");const J=z[Z].value;let V=Z+1;if(["left","right","begin","end"].includes(J.slice(1)))throw new H("Unexpected command: "+J);const X=c(J.slice(1));if(X===0)return[{type:"symbol",content:J},V];else if(X===1){if(J==="\\sqrt"&&V<z.length&&q(z[V],y)){const Q=V,W=l(z,V),O=z.slice(Q+1,W),h=this.parse(O),[f,E]=this.parseNextExprWithoutSupSub(z,W+1);return[{type:"unaryFunc",content:J,args:[f],data:h},E]}else if(J==="\\text"){if(V+2>=z.length)throw new H("Expecting content for \\text command");return v(q(z[V],F)),v(z[V+1].type==="text"),v(q(z[V+2],D)),[{type:"text",content:z[V+1].value},V+3]}let[$,j]=this.parseNextExprWithoutSupSub(z,V);return[{type:"unaryFunc",content:J,args:[$]},j]}else if(X===2){const[$,j]=this.parseNextExprWithoutSupSub(z,V),[Q,W]=this.parseNextExprWithoutSupSub(z,j);return[{type:"binaryFunc",content:J,args:[$,Q]},W]}else throw new Error("Invalid number of parameters")}parseLeftRightExpr(z,Z){v(q(z[Z],N));let J=Z+1;if(J+=S(z,J).length,J>=z.length)throw new H("Expecting delimiter after \\left");const V=w(z,J);if(V===null)throw new H("Invalid delimiter after \\left");J++;const X=J,$=p(z,J);if($===-1)throw new H("No matching \\right");const j=$;if(J=$+1,J+=S(z,J).length,J>=z.length)throw new H("Expecting \\right after \\left");const Q=w(z,J);if(Q===null)throw new H("Invalid delimiter after \\right");J++;const W=z.slice(X,j),O=this.parse(W);return[{type:"leftright",content:"",args:[{type:"element",content:V.value},O,{type:"element",content:Q.value}]},J]}parseBeginEndExpr(z,Z){v(q(z[Z],A));let J=Z+1;v(q(z[J],F)),v(z[J+1].type==="text"),v(q(z[J+2],D));const V=z[J+1].value;J+=3,J+=S(z,J).length;const X=J,$=a(z,J);if($===-1)throw new H("No matching \\end");const j=$;if(J=$+1,v(q(z[J],F)),v(z[J+1].type==="text"),v(q(z[J+2],D)),z[J+1].value!==V)throw new H("Mismatched \\begin and \\end environments");J+=3;const Q=z.slice(X,j);while(Q.length>0&&["whitespace","newline"].includes(Q[Q.length-1].type))Q.pop();const W=this.parseAligned(Q);return[{type:"beginend",content:V,data:W},J]}parseAligned(z){let Z=0;const J=[];let V=[];J.push(V);let X={type:"ordgroup",content:"",args:[]};V.push(X);while(Z<z.length){const[$,j]=this.parseNextExpr(z,Z);if(Z=j,$.type==="whitespace")continue;else if($.type==="newline"&&!this.newline_sensitive)continue;else if($.type==="control"&&$.content==="\\\\")V=[],X={type:"ordgroup",content:"",args:[]},V.push(X),J.push(V);else if($.type==="control"&&$.content==="&")X={type:"ordgroup",content:"",args:[]},V.push(X);else X.args.push($)}return J}}var Y=new Map([["nonumber",""],["vec","arrow"],["neq","eq.not"],["dot","dot"],["ddot","dot.double"],["doteq","dot(eq)"],["dots","dots.h"],["ldots","dots.h"],["vdots","dots.v"],["ddots","dots.down"],["widehat","hat"],["widetilde","tilde"],["quad","quad"],["qquad","wide"],["overbrace","overbrace"],["underbrace","underbrace"],["overline","overline"],["underline","underline"],["bar","macron"],["dbinom","binom"],["tbinom","binom"],["dfrac","frac"],["tfrac","frac"],["boldsymbol","bold"],["mathbb","bb"],["mathbf","bold"],["mathcal","cal"],["mathit","italic"],["mathfrak","frak"],["mathrm","upright"],["mathsf","sans"],["mathtt","mono"],["rm","upright"],["pmb","bold"],["pm","plus.minus"],["mp","minus.plus"],["oplus","xor"],["boxplus","plus.square"],["otimes","times.circle"],["boxtimes","times.square"],["sim","tilde"],["approx","approx"],["cong","tilde.equiv"],["simeq","tilde.eq"],["asymp","\u224D"],["equiv","equiv"],["propto","prop"],["lfloor","\u230A"],["rfloor","\u230B"],["lceil","\u2308"],["rceil","\u2309"],["gets","arrow.l"],["hookleftarrow","arrow.l.hook"],["leftharpoonup","harpoon.lt"],["leftharpoondown","harpoon.lb"],["rightleftharpoons","harpoons.rtlb"],["longleftarrow","arrow.l.long"],["longrightarrow","arrow.r.long"],["longleftrightarrow","arrow.l.r.long"],["Longleftarrow","arrow.l.double.long"],["Longrightarrow","arrow.r.double.long"],["Longleftrightarrow","arrow.l.r.double.long"],["longmapsto","arrow.r.bar"],["hookrightarrow","arrow.r.hook"],["rightharpoonup","harpoon.rt"],["rightharpoondown","harpoon.rb"],["iff","arrow.l.r.double.long"],["implies","arrow.r.double.long"],["uparrow","arrow.t"],["downarrow","arrow.b"],["updownarrow","arrow.t.b"],["Uparrow","arrow.t.double"],["Downarrow","arrow.b.double"],["Updownarrow","arrow.t.b.double"],["nearrow","arrow.tr"],["searrow","arrow.br"],["swarrow","arrow.bl"],["nwarrow","arrow.tl"],["leadsto","arrow.squiggly"],["leftleftarrows","arrows.ll"],["rightrightarrows","arrows.rr"],["Cap","sect.double"],["Cup","union.double"],["Delta","Delta"],["Gamma","Gamma"],["Join","join"],["Lambda","Lambda"],["Leftarrow","arrow.l.double"],["Leftrightarrow","arrow.l.r.double"],["Longrightarrow","arrow.r.double.long"],["Omega","Omega"],["P","pilcrow"],["Phi","Phi"],["Pi","Pi"],["Psi","Psi"],["Rightarrow","arrow.r.double"],["S","section"],["Sigma","Sigma"],["Theta","Theta"],["aleph","alef"],["alpha","alpha"],["angle","angle"],["approx","approx"],["approxeq","approx.eq"],["ast","ast"],["beta","beta"],["bigcap","sect.big"],["bigcirc","circle.big"],["bigcup","union.big"],["bigodot","dot.circle.big"],["bigoplus","xor.big"],["bigotimes","times.circle.big"],["bigsqcup","union.sq.big"],["bigtriangledown","triangle.b"],["bigtriangleup","triangle.t"],["biguplus","union.plus.big"],["bigvee","or.big"],["bigwedge","and.big"],["bullet","bullet"],["cap","sect"],["cdot","dot.op"],["cdots","dots.c"],["checkmark","checkmark"],["chi","chi"],["circ","circle.small"],["colon","colon"],["cong","tilde.equiv"],["coprod","product.co"],["copyright","copyright"],["cup","union"],["curlyvee","or.curly"],["curlywedge","and.curly"],["dagger","dagger"],["dashv","tack.l"],["ddagger","dagger.double"],["delta","delta"],["ddots","dots.down"],["diamond","diamond"],["div","div"],["divideontimes","times.div"],["dotplus","plus.dot"],["downarrow","arrow.b"],["ell","ell"],["emptyset","nothing"],["epsilon","epsilon.alt"],["equiv","equiv"],["eta","eta"],["exists","exists"],["forall","forall"],["gamma","gamma"],["ge","gt.eq"],["geq","gt.eq"],["geqslant","gt.eq.slant"],["gg","gt.double"],["hbar","planck.reduce"],["imath","dotless.i"],["iiiint","intgral.quad"],["iiint","integral.triple"],["iint","integral.double"],["in","in"],["infty","infinity"],["int","integral"],["intercal","top"],["iota","iota"],["jmath","dotless.j"],["kappa","kappa"],["lambda","lambda"],["land","and"],["langle","angle.l"],["lbrace","brace.l"],["lbrack","bracket.l"],["ldots","dots.l"],["le","lt.eq"],["leadsto","arrow.squiggly"],["leftarrow","arrow.l"],["leftthreetimes","times.three.l"],["leftrightarrow","arrow.l.r"],["leq","lt.eq"],["leqslant","lt.eq.slant"],["lhd","triangle.l"],["ll","lt.double"],["longmapsto","arrow.bar.long"],["longrightarrow","arrow.long"],["lor","or"],["ltimes","times.l"],["mapsto","arrow.bar"],["measuredangle","angle.arc"],["mid","divides"],["models","models"],["mp","minus.plus"],["mu","mu"],["nRightarrow","arrow.double.not"],["nabla","nabla"],["ncong","tilde.nequiv"],["ne","eq.not"],["neg","not"],["neq","eq.not"],["nexists","exists.not"],["ni","in.rev"],["nleftarrow","arrow.l.not"],["nleq","lt.eq.not"],["nparallel","parallel.not"],["ngeq","gt.eq.not"],["nmid","divides.not"],["notin","in.not"],["nrightarrow","arrow.not"],["nsim","tilde.not"],["nsubseteq","subset.eq.not"],["nu","nu"],["ntriangleleft","lt.tri.not"],["ntriangleright","gt.tri.not"],["nwarrow","arrow.tl"],["odot","dot.circle"],["oint","integral.cont"],["oiint","integral.surf"],["oiiint","integral.vol"],["omega","omega"],["ominus","minus.circle"],["oplus","xor"],["otimes","times.circle"],["parallel","parallel"],["partial","diff"],["perp","perp"],["phi","phi.alt"],["pi","pi"],["pm","plus.minus"],["pounds","pound"],["prec","prec"],["preceq","prec.eq"],["prime","prime"],["prod","product"],["propto","prop"],["psi","psi"],["rangle","angle.r"],["rbrace","brace.r"],["rbrack","bracket.r"],["rhd","triangle"],["rho","rho"],["rightarrow","arrow.r"],["rightthreetimes","times.three.r"],["rtimes","times.r"],["setminus","without"],["sigma","sigma"],["sim","tilde"],["simeq","tilde.eq"],["slash","slash"],["smallsetminus","without"],["spadesuit","suit.spade"],["sqcap","sect.sq"],["sqcup","union.sq"],["sqsubseteq","subset.eq.sq"],["sqsupseteq","supset.eq.sq"],["star","star"],["subset","subset"],["subseteq","subset.eq"],["subsetneq","subset.neq"],["succ","succ"],["succeq","succ.eq"],["sum","sum"],["supset","supset"],["supseteq","supset.eq"],["supsetneq","supset.neq"],["swarrow","arrow.bl"],["tau","tau"],["theta","theta"],["times","times"],["to","arrow.r"],["top","top"],["triangle","triangle.t"],["triangledown","triangle.b.small"],["triangleleft","triangle.l.small"],["triangleright","triangle.r.small"],["twoheadrightarrow","arrow.r.twohead"],["uparrow","arrow.t"],["updownarrow","arrow.t.b"],["upharpoonright","harpoon.tr"],["uplus","union.plus"],["upsilon","upsilon"],["varepsilon","epsilon"],["varnothing","diameter"],["varphi","phi"],["varpi","pi.alt"],["varrho","rho.alt"],["varsigma","sigma.alt"],["vartheta","theta.alt"],["vdash","tack.r"],["vdots","dots.v"],["vee","or"],["wedge","and"],["wr","wreath"],["xi","xi"],["yen","yen"],["zeta","zeta"],["mathscr","scr"],["LaTeX","#LaTeX"],["TeX","#TeX"]]);function L(z){if(/^[a-zA-Z0-9]$/.test(z))return z;else if(z==="\\\\")return"\\";else if(z=="/")return"\\/";else if(["\\$","\\#","\\&","\\_"].includes(z))return z;else if(z.startsWith("\\")){const Z=z.slice(1);if(Y.has(Z))return Y.get(Z);else return Z}return z}var o=["dim","id","im","mod","Pr","sech","csch"];class K extends Error{node;constructor(z,Z){super(z);this.name="TypstWriterError",this.node=Z}}class M{nonStrict;preferTypstIntrinsic;buffer="";queue=[];needSpaceAfterSingleItemScript=!1;insideFunctionDepth=0;constructor(z,Z){this.nonStrict=z,this.preferTypstIntrinsic=Z}writeBuffer(z){if(this.needSpaceAfterSingleItemScript&&/^[0-9a-zA-Z\(]/.test(z))this.buffer+=" ";else{let Z=!1;if(Z||=/[\(\|]$/.test(this.buffer)&&/^\w/.test(z),Z||=/^[}()_^,;!\|]$/.test(z),Z||=z==="'",Z||=/[0-9]$/.test(this.buffer)&&/^[0-9]/.test(z),Z||=/[\(\[{]\s*(-|\+)$/.test(this.buffer)||this.buffer==="-"||this.buffer==="+",Z||=z.startsWith("\n"),Z||=this.buffer==="",Z||=/[\s"_^{\(]$/.test(this.buffer),!Z)this.buffer+=" "}if(this.needSpaceAfterSingleItemScript)this.needSpaceAfterSingleItemScript=!1;this.buffer+=z}append(z){if(z.type==="empty"||z.type==="whitespace")return;else if(z.type==="ordgroup")z.args.forEach((Z)=>this.append(Z));else if(z.type==="element"){let Z=z.content;if(z.content===","&&this.insideFunctionDepth>0)Z="comma";this.queue.push({type:"symbol",content:Z})}else if(z.type==="symbol")this.queue.push({type:"symbol",content:z.content});else if(z.type==="text")this.queue.push(z);else if(z.type==="supsub"){let{base:Z,sup:J,sub:V}=z.data;if(Z&&Z.type==="unaryFunc"&&Z.content==="\\overbrace"&&J){this.append({type:"binaryFunc",content:"\\overbrace",args:[Z.args[0],J]});return}else if(Z&&Z.type==="unaryFunc"&&Z.content==="\\underbrace"&&V){this.append({type:"binaryFunc",content:"\\underbrace",args:[Z.args[0],V]});return}if(Z.type==="empty")this.queue.push({type:"text",content:""});else this.appendWithBracketsIfNeeded(Z);let X=!1;const $=J&&J.type==="symbol"&&J.content==="\\prime";if($)this.queue.push({type:"atom",content:"\'"}),X=!1;if(V)this.queue.push({type:"atom",content:"_"}),X=this.appendWithBracketsIfNeeded(V);if(J&&!$)this.queue.push({type:"atom",content:"^"}),X=this.appendWithBracketsIfNeeded(J);if(X)this.queue.push({type:"softSpace",content:""})}else if(z.type==="leftright"){const[Z,J,V]=z.args;if(["[]","()","\\{\\}","\\lfloor\\rfloor","\\lceil\\rceil"].includes(Z.content+V.content)){this.append(Z),this.append(J),this.append(V);return}const X={type:"symbol",content:"lr"};this.queue.push(X),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(Z),this.append(J),this.append(V),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="binaryFunc"){const Z={type:"symbol",content:z.content},[J,V]=z.args;this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:","}),this.append(V),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="unaryFunc"){const Z={type:"symbol",content:z.content},J=z.args[0];if(z.content==="\\sqrt"&&z.data){Z.content="root",this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(z.data),this.queue.push({type:"atom",content:","}),this.append(J),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--;return}else if(z.content==="\\mathbf"){this.append({type:"symbol",content:"upright"}),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--,this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--;return}else if(z.content==="\\mathbb"){const V=z.args[0];if(V.type==="element"&&/^[A-Z]$/.test(V.content)){this.queue.push({type:"symbol",content:V.content+V.content});return}}else if(z.content==="\\operatorname"){let V=z.args;if(V.length===1&&V[0].type=="ordgroup")V=V[0].args;const X=V.reduce(($,j)=>{return $+=L(j.content),$},"");if(this.preferTypstIntrinsic&&o.includes(X))this.queue.push({type:"symbol",content:X});else this.queue.push({type:"symbol",content:"op"}),this.queue.push({type:"atom",content:"("}),this.queue.push({type:"text",content:X}),this.queue.push({type:"atom",content:")"});return}this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="newline"){this.queue.push({type:"newline",content:"\n"});return}else if(z.type==="beginend")if(z.content.startsWith("align")){const Z=z.data;Z.forEach((J,V)=>{if(J.forEach((X,$)=>{if($>0)this.queue.push({type:"atom",content:"&"});this.append(X)}),V<Z.length-1)this.queue.push({type:"symbol",content:"\\\\"})})}else{const Z=z.data;this.queue.push({type:"symbol",content:"mat"}),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.queue.push({type:"symbol",content:"delim: #none, "}),Z.forEach((J,V)=>{J.forEach((X,$)=>{if(X.type==="ordgroup"&&X.args.length===0){this.queue.push({type:"atom",content:","});return}if(this.append(X),$<J.length-1)this.queue.push({type:"atom",content:","});else if(V<Z.length-1)this.queue.push({type:"atom",content:";"})})}),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="matrix");else if(z.type==="unknownMacro")if(this.nonStrict)this.queue.push({type:"symbol",content:z.content});else throw new K(`Unknown macro: ${z.content}`,z);else if(z.type==="control")if(z.content==="\\\\")this.queue.push({type:"symbol",content:z.content});else if(z.content==="\\,")this.queue.push({type:"symbol",content:"thin"});else throw new K(`Unknown control sequence: ${z.content}`,z);else if(z.type==="comment")this.queue.push({type:"comment",content:z.content});else throw new K(`Unimplemented node type to append: ${z.type}`,z)}flushQueue(){this.queue.forEach((z)=>{let Z="";switch(z.type){case"atom":Z=z.content;break;case"symbol":Z=L(z.content);break;case"text":Z=`"${z.content}"`;break;case"softSpace":this.needSpaceAfterSingleItemScript=!0,Z="";break;case"comment":Z=`//${z.content}`;break;case"newline":Z="\n";break;default:throw new K(`Unexpected node type to stringify: ${z.type}`,z)}if(Z!=="")this.writeBuffer(Z)}),this.queue=[]}appendWithBracketsIfNeeded(z){const Z=["symbol","element","unaryFunc","binaryFunc","leftright"].includes(z.type);if(Z)this.append(z);else this.queue.push({type:"atom",content:"("}),this.append(z),this.queue.push({type:"atom",content:")"});return Z}finalize(){this.flushQueue();const z=function(J){let V=J.replace(/⌊\s*(.*?)\s*⌋/g,"floor($1)");return V=V.replace(/floor\(\)/g,'floor("")'),V},Z=function(J){let V=J.replace(/⌈\s*(.*?)\s*⌉/g,"ceil($1)");return V=V.replace(/ceil\(\)/g,'ceil("")'),V};return this.buffer=z(this.buffer),this.buffer=Z(this.buffer),this.buffer}}function P(z,Z){const J={nonStrict:!1,preferTypstIntrinsic:!0,customTexMacros:{}};if(Z){if(Z.nonStrict)J.nonStrict=Z.nonStrict;if(Z.preferTypstIntrinsic)J.preferTypstIntrinsic=Z.preferTypstIntrinsic;if(Z.customTexMacros)J.customTexMacros=Z.customTexMacros}const V=T(z,J.customTexMacros),X=new M(J.nonStrict,J.preferTypstIntrinsic);return X.append(V),X.finalize()}if(typeof window!=="undefined")window.tex2typst=P;
|
package/package.json
CHANGED
package/src/parser.ts
CHANGED
|
@@ -5,36 +5,25 @@ const UNARY_COMMANDS = [
|
|
|
5
5
|
'sqrt',
|
|
6
6
|
'text',
|
|
7
7
|
|
|
8
|
-
'arccos',
|
|
9
|
-
'arcsin',
|
|
10
|
-
'arctan',
|
|
11
|
-
'arg',
|
|
12
8
|
'bar',
|
|
13
9
|
'bold',
|
|
14
10
|
'boldsymbol',
|
|
15
11
|
'ddot',
|
|
16
|
-
'det',
|
|
17
|
-
'dim',
|
|
18
12
|
'dot',
|
|
19
|
-
'exp',
|
|
20
|
-
'gcd',
|
|
21
13
|
'hat',
|
|
22
|
-
'ker',
|
|
23
14
|
'mathbb',
|
|
24
15
|
'mathbf',
|
|
25
16
|
'mathcal',
|
|
17
|
+
'mathfrak',
|
|
18
|
+
'mathit',
|
|
19
|
+
'mathrm',
|
|
26
20
|
'mathscr',
|
|
27
21
|
'mathsf',
|
|
28
22
|
'mathtt',
|
|
29
|
-
'mathrm',
|
|
30
|
-
'max',
|
|
31
|
-
'min',
|
|
32
|
-
'mod',
|
|
33
23
|
'operatorname',
|
|
34
24
|
'overbrace',
|
|
35
25
|
'overline',
|
|
36
26
|
'pmb',
|
|
37
|
-
'sup',
|
|
38
27
|
'rm',
|
|
39
28
|
'tilde',
|
|
40
29
|
'underbrace',
|
|
@@ -237,12 +226,12 @@ function find_closing_curly_bracket_char(latex: string, start: number): number {
|
|
|
237
226
|
}
|
|
238
227
|
|
|
239
228
|
|
|
240
|
-
interface Token {
|
|
229
|
+
export interface Token {
|
|
241
230
|
type: 'element' | 'command' | 'text' | 'comment' | 'whitespace' | 'newline' | 'control' | 'unknown';
|
|
242
231
|
value: string;
|
|
243
232
|
}
|
|
244
233
|
|
|
245
|
-
function tokenize(latex: string): Token[] {
|
|
234
|
+
export function tokenize(latex: string): Token[] {
|
|
246
235
|
const tokens: Token[] = [];
|
|
247
236
|
let pos = 0;
|
|
248
237
|
|
|
@@ -295,17 +284,15 @@ function tokenize(latex: string): Token[] {
|
|
|
295
284
|
throw new LatexParserError('Expecting command name after \\');
|
|
296
285
|
}
|
|
297
286
|
const firstTwoChars = latex.slice(pos, pos + 2);
|
|
298
|
-
if (
|
|
299
|
-
token = { type: 'control', value:
|
|
300
|
-
pos += 2;
|
|
287
|
+
if (['\\\\', '\\,'].includes(firstTwoChars)) {
|
|
288
|
+
token = { type: 'control', value: firstTwoChars };
|
|
301
289
|
} else if (['\\{','\\}', '\\%', '\\$', '\\&', '\\#', '\\_'].includes(firstTwoChars)) {
|
|
302
290
|
token = { type: 'element', value: firstTwoChars };
|
|
303
|
-
pos += 2;
|
|
304
291
|
} else {
|
|
305
292
|
const command = eat_command_name(latex, pos + 1);
|
|
306
293
|
token = { type: 'command', value: '\\' + command};
|
|
307
|
-
pos += 1 + command.length;
|
|
308
294
|
}
|
|
295
|
+
pos += token.value.length;
|
|
309
296
|
break;
|
|
310
297
|
}
|
|
311
298
|
default: {
|
|
@@ -502,23 +489,13 @@ export class LatexParser {
|
|
|
502
489
|
throw new LatexParserError("Unmatched '}'");
|
|
503
490
|
case '\\\\':
|
|
504
491
|
return [{ type: 'control', content: '\\\\' }, start + 1];
|
|
492
|
+
case '\\,':
|
|
493
|
+
return [{ type: 'control', content: '\\,' }, start + 1];
|
|
505
494
|
case '_': {
|
|
506
|
-
|
|
507
|
-
let sup: TexNode | undefined = undefined;
|
|
508
|
-
if (pos < tokens.length && token_eq(tokens[pos], SUP_SYMBOL)) {
|
|
509
|
-
[sup, pos] = this.parseNextExpr(tokens, pos + 1);
|
|
510
|
-
}
|
|
511
|
-
const subData = { base: EMPTY_NODE, sub, sup };
|
|
512
|
-
return [{ type: 'supsub', content: '', data: subData }, pos];
|
|
495
|
+
return [ EMPTY_NODE, start];
|
|
513
496
|
}
|
|
514
497
|
case '^': {
|
|
515
|
-
|
|
516
|
-
let sub: TexNode | undefined = undefined;
|
|
517
|
-
if (pos < tokens.length && token_eq(tokens[pos], SUB_SYMBOL)) {
|
|
518
|
-
[sub, pos] = this.parseNextExpr(tokens, pos + 1);
|
|
519
|
-
}
|
|
520
|
-
const supData = { base: EMPTY_NODE, sub, sup };
|
|
521
|
-
return [{ type: 'supsub', content: '', data: supData }, pos];
|
|
498
|
+
return [ EMPTY_NODE, start];
|
|
522
499
|
}
|
|
523
500
|
case '&':
|
|
524
501
|
return [{ type: 'control', content: '&' }, start + 1];
|
|
@@ -688,17 +665,40 @@ export class LatexParser {
|
|
|
688
665
|
}
|
|
689
666
|
}
|
|
690
667
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
const
|
|
694
|
-
let
|
|
695
|
-
for (
|
|
668
|
+
// Remove all whitespace before and after _ or ^
|
|
669
|
+
function passIgnoreWhitespaceBeforeScriptMark(tokens: Token[]): Token[] {
|
|
670
|
+
const is_script_mark = (token: Token) => token_eq(token, SUB_SYMBOL) || token_eq(token, SUP_SYMBOL);
|
|
671
|
+
let out_tokens: Token[] = [];
|
|
672
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
673
|
+
if (tokens[i].type === 'whitespace' && i + 1 < tokens.length && is_script_mark(tokens[i + 1])) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
if (tokens[i].type === 'whitespace' && i - 1 >= 0 && is_script_mark(tokens[i - 1])) {
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
out_tokens.push(tokens[i]);
|
|
680
|
+
}
|
|
681
|
+
return out_tokens;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// expand custom tex macros
|
|
685
|
+
function passExpandCustomTexMacros(tokens: Token[], customTexMacros: {[key: string]: string}): Token[] {
|
|
686
|
+
let out_tokens: Token[] = [];
|
|
687
|
+
for (const token of tokens) {
|
|
696
688
|
if (token.type === 'command' && customTexMacros[token.value]) {
|
|
697
689
|
const expanded_tokens = tokenize(customTexMacros[token.value]);
|
|
698
|
-
|
|
690
|
+
out_tokens = out_tokens.concat(expanded_tokens);
|
|
699
691
|
} else {
|
|
700
|
-
|
|
692
|
+
out_tokens.push(token);
|
|
701
693
|
}
|
|
702
694
|
}
|
|
703
|
-
return
|
|
695
|
+
return out_tokens;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
export function parseTex(tex: string, customTexMacros: {[key: string]: string}): TexNode {
|
|
699
|
+
const parser = new LatexParser();
|
|
700
|
+
let tokens = tokenize(tex);
|
|
701
|
+
tokens = passIgnoreWhitespaceBeforeScriptMark(tokens);
|
|
702
|
+
tokens = passExpandCustomTexMacros(tokens, customTexMacros);
|
|
703
|
+
return parser.parse(tokens);
|
|
704
704
|
}
|
package/src/writer.ts
CHANGED
|
@@ -283,6 +283,8 @@ export class TypstWriter {
|
|
|
283
283
|
} else if (node.type === 'control') {
|
|
284
284
|
if (node.content === '\\\\') {
|
|
285
285
|
this.queue.push({ type: 'symbol', content: node.content });
|
|
286
|
+
} else if (node.content === '\\,') {
|
|
287
|
+
this.queue.push({ type: 'symbol', content: 'thin' });
|
|
286
288
|
} else {
|
|
287
289
|
throw new TypstWriterError(`Unknown control sequence: ${node.content}`, node);
|
|
288
290
|
}
|