tex2typst 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +401 -424
- package/dist/parser.d.ts +16 -13
- package/dist/tex2typst.min.js +1 -1
- package/dist/types.d.ts +1 -13
- package/package.json +2 -4
- package/src/index.ts +2 -1
- package/src/map.ts +43 -17
- package/src/parser.ts +413 -480
- package/src/types.ts +1 -15
- package/src/writer.ts +57 -50
package/dist/parser.d.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import { TexNode
|
|
2
|
-
|
|
1
|
+
import { TexNode } from "./types";
|
|
2
|
+
interface Token {
|
|
3
|
+
type: 'element' | 'command' | 'text' | 'comment' | 'whitespace' | 'newline' | 'control' | 'unknown';
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class LatexParserError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
type ParseResult = [TexNode, number];
|
|
3
10
|
export declare class LatexParser {
|
|
4
11
|
space_sensitive: boolean;
|
|
5
12
|
newline_sensitive: boolean;
|
|
6
13
|
constructor(space_sensitive?: boolean, newline_sensitive?: boolean);
|
|
7
|
-
parse(
|
|
8
|
-
parseNextExpr(
|
|
9
|
-
parseNextExprWithoutSupSub(
|
|
10
|
-
parseCommandExpr(
|
|
11
|
-
parseLeftRightExpr(
|
|
12
|
-
parseBeginEndExpr(
|
|
13
|
-
parseAligned(
|
|
14
|
-
}
|
|
15
|
-
export declare class LatexNodeToTexNodeError extends Error {
|
|
16
|
-
node: LatexParseNode;
|
|
17
|
-
constructor(message: string, node: LatexParseNode);
|
|
14
|
+
parse(tokens: Token[]): TexNode;
|
|
15
|
+
parseNextExpr(tokens: Token[], start: number): ParseResult;
|
|
16
|
+
parseNextExprWithoutSupSub(tokens: Token[], start: number): ParseResult;
|
|
17
|
+
parseCommandExpr(tokens: Token[], start: number): ParseResult;
|
|
18
|
+
parseLeftRightExpr(tokens: Token[], start: number): ParseResult;
|
|
19
|
+
parseBeginEndExpr(tokens: Token[], start: number): ParseResult;
|
|
20
|
+
parseAligned(tokens: Token[]): TexNode[][];
|
|
18
21
|
}
|
|
19
22
|
export declare function parseTex(tex: string, customTexMacros: {
|
|
20
23
|
[key: string]: string;
|
package/dist/tex2typst.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function j(z,G=""){if(!z)throw new K(G)}function w(z){if(P.includes(z))return 1;else if(N.includes(z))return 2;else return 0}function O(z,G){j(z[G]==="{");let J=1,H=G+1;while(J>0){if(H>=z.length)throw new K("Unmatched curly brackets");if(H+1<z.length&&["\\{","\\}"].includes(z.substring(H,H+2))){H+=2;continue}if(z[H]==="{")J+=1;else if(z[H]==="}")J-=1;H+=1}return H-1}function E(z,G){j(z[G]==="[");let J=1,H=G+1;while(J>0){if(H>=z.length)throw new K("Unmatched square brackets");if(z[H]==="[")J+=1;else if(z[H]==="]")J-=1;H+=1}return H-1}function M(z){return"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(z)}function I(z){return"0123456789".includes(z)}function Y(z,G,J){const H=1+J.length;let Q=G;while(Q<z.length){if(Q=z.indexOf("\\"+J,Q),Q===-1)return-1;if(Q+H>=z.length||!M(z[Q+H]))return Q;else Q+=H}return-1}function f(z,G){let J=1,H=G;while(J>0){if(H>=z.length)return-1;const Q=Y(z,H,"left"),V=Y(z,H,"right");if(V===-1)return-1;if(Q===-1||Q>V)J-=1,H=V+"\\right".length;else J+=1,H=Q+"\\left".length}return H-"\\right".length}function h(z,G){let J=1,H=G;while(J>0){if(H>=z.length)return-1;const Q=Y(z,H,"begin"),V=Y(z,H,"end");if(V===-1)return-1;if(Q===-1||Q>V)J-=1,H=V+"\\end".length;else J+=1,H=Q+"\\begin".length}return H-"\\end".length}function B(z,G){let J=G;while(J<z.length&&[" ","\t","\n"].includes(z[J]))J+=1;return z.substring(G,J)}function b(z,G){let J=G;while(J<z.length&&M(z[J]))J+=1;return z.substring(G,J)}function y(z,G){if("()[]|".includes(z[G]))return z[G];else if(G+1<z.length&&["\\{","\\}"].includes(z.substring(G,G+2)))return z.substring(G,G+2);else if(G+6<z.length&&["\\lfloor","\\rfloor"].includes(z.substring(G,G+7)))return z.substring(G,G+7);else if(G+5<z.length&&["\\lceil","\\rceil"].includes(z.substring(G,G+6)))return z.substring(G,G+6);else if(G+6<z.length&&["\\langle","\\rangle"].includes(z.substring(G,G+7)))return z.substring(G,G+7);else return null}function q(z,G){let J=G;while(J<z.length&&z[J]==="'")J+=1;return J-G}function X(z){try{let G={};switch(z.type){case"ordgroup":if(G.type="ordgroup",G.args=z.args.map(($)=>X($)),G.args.length===1)G=G.args[0];break;case"empty":G.type="empty",G.content="";break;case"atom":G.type="atom",G.content=z.content;break;case"token":case"token-letter-var":case"token-number":case"token-operator":case"token-parenthesis":G.type="symbol",G.content=z.content;break;case"supsub":if(G.type="supsub",G.irregularData={},z.base)G.irregularData.base=X(z.base);if(z.sup)G.irregularData.sup=X(z.sup);if(z.sub)G.irregularData.sub=X(z.sub);break;case"leftright":G.type="leftright";const J=X(z.body);let H=z.left;if(H==="\\{")H="{";let Q=z.right;if(Q==="\\}")Q="}";const V=($)=>["(",")","[","]","{","}"].includes($);G.args=[{type:V(H)?"atom":"symbol",content:H},J,{type:V(Q)?"atom":"symbol",content:Q}];break;case"beginend":if(z.content?.startsWith("align"))G.type="align";else G.type="matrix";G.content=z.content,G.irregularData=z.body.map(($)=>{return $.map((U)=>X(U))});break;case"command":const Z=w(z.content);if(G.content="\\"+z.content,Z===0)G.type="symbol";else if(Z===1){if(G.type="unaryFunc",G.args=[X(z.arg1)],z.content==="sqrt"){if(z.exponent)G.irregularData=X(z.exponent)}}else if(Z===2)G.type="binaryFunc",G.args=[X(z.arg1),X(z.arg2)];else throw new W("Invalid number of arguments",z);break;case"text":G.type="text",G.content=z.content;break;case"comment":G.type="comment",G.content=z.content;break;case"whitespace":G.type="empty";break;case"newline":G.type="newline",G.content="\n";break;case"control":if(z.content==="\\\\"){G.type="symbol",G.content=z.content;break}else throw new W(`Unknown control sequence: ${z.content}`,z);break;default:throw new W(`Unknown node type: ${z.type}`,z)}return G}catch(G){throw G}}function k(z,G){const J=new C;for(let[Q,V]of Object.entries(G))z=z.replaceAll(Q,V);const H=J.parse(z);return X(H)}var P=["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"],N=["frac","tfrac","binom","dbinom","dfrac","tbinom"],R={type:"empty",content:""};class K extends Error{constructor(z){super(z);this.name="LatexParserError"}}class C{space_sensitive;newline_sensitive;constructor(z=!1,G=!0){this.space_sensitive=z,this.newline_sensitive=G}parse(z){const G=[];let J=0;while(J<z.length){const[H,Q]=this.parseNextExpr(z,J);if(J=Q,!this.space_sensitive&&H.type==="whitespace")continue;if(!this.newline_sensitive&&H.type==="newline")continue;if(H.type==="control"&&H.content==="&")throw new K("Unexpected & outside of an alignment");G.push(H)}if(G.length===0)return R;else if(G.length===1)return G[0];else return{type:"ordgroup",args:G}}parseNextExpr(z,G){let[J,H]=this.parseNextExprWithoutSupSub(z,G),Q=null,V=null,Z=0;if(Z+=q(z,H),H+=Z,H<z.length&&z[H]==="_"){if([Q,H]=this.parseNextExprWithoutSupSub(z,H+1),Z+=q(z,H),H+=Z,H<z.length&&z[H]==="^"){if([V,H]=this.parseNextExprWithoutSupSub(z,H+1),q(z,H)>0)throw new K("Double superscript")}}else if(H<z.length&&z[H]==="^"){if([V,H]=this.parseNextExprWithoutSupSub(z,H+1),q(z,H)>0)throw new K("Double superscript");if(H<z.length&&z[H]==="_"){if([Q,H]=this.parseNextExprWithoutSupSub(z,H+1),q(z,H)>0)throw new K("Double superscript")}}if(Q!==null||V!==null||Z>0){const $={type:"supsub",base:J};if(Q)$.sub=Q;if(Z>0){$.sup={type:"ordgroup",args:[]};for(let U=0;U<Z;U++)$.sup.args.push({type:"command",content:"prime"});if(V)$.sup.args.push(V);if($.sup.args.length===1)$.sup=$.sup.args[0]}else if(V)$.sup=V;return[$,H]}else return[J,H]}parseNextExprWithoutSupSub(z,G){const J=z[G];if(J==="{"){const H=O(z,G),Q=z.slice(G+1,H);return[this.parse(Q),H+1]}else if(J==="\\"){if(G+1>=z.length)throw new K("Expecting command name after \\");const H=z.slice(G,G+2);if(H==="\\\\")return[{type:"control",content:"\\\\"},G+2];else if(H==="\\{"||H==="\\}")return[{type:"token-parenthesis",content:H},G+2];else if(["\\%","\\$","\\&","\\#","\\_"].includes(H))return[{type:"token",content:H},G+2];else if(z.slice(G).startsWith("\\begin{"))return this.parseBeginEndExpr(z,G);else if(z.slice(G).startsWith("\\left")&&(G+5>=z.length||!M(z[G+5])))return this.parseLeftRightExpr(z,G);else return this.parseCommandExpr(z,G)}else if(J==="%"){let H=G+1;while(H<z.length&&z[H]!=="\n")H+=1;return[{type:"comment",content:z.slice(G+1,H)},H]}else if(I(J)){let H=G;while(H<z.length&&I(z[H]))H+=1;return[{type:"token-number",content:z.slice(G,H)},H]}else if(M(J))return[{type:"token-letter-var",content:J},G+1];else if("+-*/=<>!".includes(J))return[{type:"token-operator",content:J},G+1];else if(".,;?".includes(J))return[{type:"atom",content:J},G+1];else if("()[]".includes(J))return[{type:"token-parenthesis",content:J},G+1];else if(J==="_"){let[H,Q]=this.parseNextExpr(z,G+1),V=void 0;if(Q<z.length&&z[Q]==="^")[V,Q]=this.parseNextExpr(z,Q+1);return[{type:"supsub",base:R,sub:H,sup:V},Q]}else if(J==="^"){let[H,Q]=this.parseNextExpr(z,G+1),V=void 0;if(Q<z.length&&z[Q]==="_")[V,Q]=this.parseNextExpr(z,Q+1);return[{type:"supsub",base:R,sub:V,sup:H},Q]}else if(J===" "){let H=G;while(H<z.length&&z[H]===" ")H+=1;return[{type:"whitespace",content:z.slice(G,H)},H]}else if(J==="\n")return[{type:"newline",content:"\n"},G+1];else if(J==="\r")if(G+1<z.length&&z[G+1]==="\n")return[{type:"newline",content:"\n"},G+2];else return[{type:"newline",content:"\n"},G+1];else if(J==="&")return[{type:"control",content:"&"},G+1];else return[{type:"unknown",content:J},G+1]}parseCommandExpr(z,G){j(z[G]==="\\");let J=G+1;const H=b(z,J);J+=H.length;const Q=w(H);if(Q===0)return[{type:"command",content:H},J];else if(Q===1)if(H==="sqrt"&&J<z.length&&z[J]==="["){const V=J,Z=E(z,J),$=z.slice(V+1,Z),U=this.parse($),[F,A]=this.parseNextExprWithoutSupSub(z,Z+1);return[{type:"command",content:H,arg1:F,exponent:U},A]}else if(H==="text"){j(z[J]==="{");const V=O(z,J);return[{type:"text",content:z.slice(J+1,V)},V+1]}else{let[V,Z]=this.parseNextExprWithoutSupSub(z,J);return[{type:"command",content:H,arg1:V},Z]}else if(Q===2){const[V,Z]=this.parseNextExprWithoutSupSub(z,J),[$,U]=this.parseNextExprWithoutSupSub(z,Z);return[{type:"command",content:H,arg1:V,arg2:$},U]}else throw new Error("Invalid number of parameters")}parseLeftRightExpr(z,G){j(z.slice(G,G+5)==="\\left");let J=G+"\\left".length;if(J+=B(z,J).length,J>=z.length)throw new K("Expecting delimiter after \\left");const H=y(z,J);if(H===null)throw new K("Invalid delimiter after \\left");J+=H.length;const Q=J,V=f(z,J);if(V===-1)throw new K("No matching \\right");const Z=V;if(J=V+"\\right".length,J+=B(z,J).length,J>=z.length)throw new K("Expecting delimiter after \\right");const $=y(z,J);if($===null)throw new K("Invalid delimiter after \\right");J+=$.length;const U=z.slice(Q,Z),F=this.parse(U);return[{type:"leftright",left:H,right:$,body:F},J]}parseBeginEndExpr(z,G){j(z.slice(G,G+7)==="\\begin{");let J=G+"\\begin".length;const H=O(z,J);if(H===-1)throw new K("No matching } after \\begin{");const Q=z.slice(J+1,H);J=H+1,J+=B(z,J).length;const V=J,Z=h(z,J);if(Z===-1)throw new K("No matching \\end");const $=Z;J=Z+"\\end".length;const U=O(z,J);if(U===-1)throw new K("No matching } after \\end{");if(z.slice(J+1,U)!==Q)throw new K("Mismatched \\begin and \\end environments");let F=z.slice(V,$);F=F.trimEnd();const A=this.parseAligned(F);return[{type:"beginend",content:Q,body:A},U+1]}parseAligned(z){let G=0;const J=[];let H=[];J.push(H);let Q={type:"ordgroup",args:[]};H.push(Q);while(G<z.length){const[V,Z]=this.parseNextExpr(z,G);if(G=Z,V.type==="whitespace")continue;else if(V.type==="newline"&&!this.newline_sensitive)continue;else if(V.type==="control"&&V.content==="\\\\")H=[],Q={type:"ordgroup",args:[]},H.push(Q),J.push(H);else if(V.type==="control"&&V.content==="&")Q={type:"ordgroup",args:[]},H.push(Q);else Q.args.push(V)}return J}}class W extends Error{node;constructor(z,G){super(z);this.name="LatexNodeToTexNodeError",this.node=G}}var S=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 T(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 G=z.slice(1);if(S.has(G))return S.get(G);else return G}return z}var g=["dim","id","im","mod","Pr","sech","csch"];class v extends Error{node;constructor(z,G){super(z);this.name="TypstWriterError",this.node=G}}class D{nonStrict;preferTypstIntrinsic;buffer="";queue=[];needSpaceAfterSingleItemScript=!1;insideFunctionDepth=0;constructor(z,G){this.nonStrict=z,this.preferTypstIntrinsic=G}writeBuffer(z){if(this.needSpaceAfterSingleItemScript&&/^[0-9a-zA-Z\(]/.test(z))this.buffer+=" ";else{let G=!1;if(G||=/[\(\|]$/.test(this.buffer)&&/^\w/.test(z),G||=/^[}()_^,;!\|]$/.test(z),G||=z==="'",G||=/[0-9]$/.test(this.buffer)&&/^[0-9]/.test(z),G||=/[\(\[{]\s*(-|\+)$/.test(this.buffer)||this.buffer==="-"||this.buffer==="+",G||=z.startsWith("\n"),G||=this.buffer==="",G||=/[\s"_^{\(]$/.test(this.buffer),!G)this.buffer+=" "}if(this.needSpaceAfterSingleItemScript)this.needSpaceAfterSingleItemScript=!1;this.buffer+=z}append(z){if(z.type==="empty")return;else if(z.type==="ordgroup")z.args.forEach((G)=>this.append(G));else if(z.type==="atom"){let G=z.content;if(z.content===","&&this.insideFunctionDepth>0)G="comma";this.queue.push({type:"atom",content:G})}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:G,sup:J,sub:H}=z.irregularData;if(G&&G.type==="unaryFunc"&&G.content==="\\overbrace"&&J){this.append({type:"binaryFunc",content:"\\overbrace",args:[G.args[0],J]});return}else if(G&&G.type==="unaryFunc"&&G.content==="\\underbrace"&&H){this.append({type:"binaryFunc",content:"\\underbrace",args:[G.args[0],H]});return}if(G.type==="empty")this.queue.push({type:"text",content:""});else this.appendWithBracketsIfNeeded(G);let Q=!1;const V=J&&J.type==="symbol"&&J.content==="\\prime";if(V)this.queue.push({type:"atom",content:"\'"}),Q=!1;if(H)this.queue.push({type:"atom",content:"_"}),Q=this.appendWithBracketsIfNeeded(H);if(J&&!V)this.queue.push({type:"atom",content:"^"}),Q=this.appendWithBracketsIfNeeded(J);if(Q)this.queue.push({type:"softSpace",content:""})}else if(z.type==="leftright"){const[G,J,H]=z.args;if(["[]","()","{}","\\lfloor\\rfloor","\\lceil\\rceil"].includes(G.content+H.content)){this.append(G),this.append(J),this.append(H);return}const Q={type:"symbol",content:"lr"};this.queue.push(Q),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(G),this.append(J),this.append(H),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="binaryFunc"){const G={type:"symbol",content:z.content},[J,H]=z.args;this.queue.push(G),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:","}),this.append(H),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="unaryFunc"){const G={type:"symbol",content:z.content},J=z.args[0];if(z.content==="\\sqrt"&&z.irregularData){G.content="root",this.queue.push(G),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(z.irregularData),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(G),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 H=z.args[0];if(H.type==="symbol"&&/^[A-Z]$/.test(H.content)){this.queue.push({type:"symbol",content:H.content+H.content});return}}else if(z.content==="\\operatorname"){let H=z.args;if(H.length===1&&H[0].type=="ordgroup")H=H[0].args;const Q=H.reduce((V,Z)=>{return V+=T(Z.content),V},"");if(this.preferTypstIntrinsic&&g.includes(Q))this.queue.push({type:"symbol",content:Q});else this.queue.push({type:"symbol",content:"op"}),this.queue.push({type:"atom",content:"("}),this.queue.push({type:"text",content:Q}),this.queue.push({type:"atom",content:")"});return}this.queue.push(G),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==="align"){const G=z.irregularData;G.forEach((J,H)=>{if(J.forEach((Q,V)=>{if(V>0)this.queue.push({type:"atom",content:"&"});this.append(Q)}),H<G.length-1)this.queue.push({type:"symbol",content:"\\\\"})})}else if(z.type==="matrix"){const G=z.irregularData;this.queue.push({type:"symbol",content:"mat"}),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.queue.push({type:"symbol",content:"delim: #none, "}),G.forEach((J,H)=>{J.forEach((Q,V)=>{if(Q.type==="ordgroup"&&Q.args.length===0){this.queue.push({type:"atom",content:","});return}if(this.append(Q),V<J.length-1)this.queue.push({type:"atom",content:","});else if(H<G.length-1)this.queue.push({type:"atom",content:";"})})}),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--}else if(z.type==="unknownMacro")if(this.nonStrict)this.queue.push({type:"symbol",content:z.content});else throw new v(`Unknown macro: ${z.content}`,z);else if(z.type==="comment")this.queue.push({type:"comment",content:z.content});else throw new v(`Unimplemented node type to append: ${z.type}`,z)}flushQueue(){this.queue.forEach((z)=>{let G="";switch(z.type){case"atom":G=z.content;break;case"symbol":G=T(z.content);break;case"text":G=`"${z.content}"`;break;case"softSpace":this.needSpaceAfterSingleItemScript=!0,G="";break;case"comment":G=`//${z.content}`;break;case"newline":G="\n";break;default:throw new v(`Unexpected node type to stringify: ${z.type}`,z)}if(G!=="")this.writeBuffer(G)}),this.queue=[]}appendWithBracketsIfNeeded(z){const G=z.type==="atom",J=z.type==="unaryFunc"||z.type==="binaryFunc"||z.type==="leftright",H=["atom","symbol","unaryFunc","binaryFunc","leftright"].includes(z.type);if(H)this.append(z);else this.queue.push({type:"atom",content:"("}),this.append(z),this.queue.push({type:"atom",content:")"});return H}finalize(){this.flushQueue();const z=function(J){let H=J.replace(/⌊\s*(.*?)\s*⌋/g,"floor($1)");return H=H.replace(/floor\(\)/g,'floor("")'),H},G=function(J){let H=J.replace(/⌈\s*(.*?)\s*⌉/g,"ceil($1)");return H=H.replace(/ceil\(\)/g,'ceil("")'),H};return this.buffer=z(this.buffer),this.buffer=G(this.buffer),this.buffer}}function L(z,G){const J={nonStrict:!1,preferTypstIntrinsic:!0,customTexMacros:{}};if(G){if(G.nonStrict)J.nonStrict=G.nonStrict;if(G.preferTypstIntrinsic)J.preferTypstIntrinsic=G.preferTypstIntrinsic;if(G.customTexMacros)J.customTexMacros=G.customTexMacros}const H=k(z,J.customTexMacros),Q=new D(J.nonStrict,J.preferTypstIntrinsic);return Q.append(H),Q.finalize()}if(typeof window!=="undefined")window.tex2typst=L;
|
|
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;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
export interface LatexParseNode {
|
|
2
|
-
type: string;
|
|
3
|
-
content?: string;
|
|
4
|
-
arg1?: LatexParseNode;
|
|
5
|
-
arg2?: LatexParseNode;
|
|
6
|
-
args?: LatexParseNode[];
|
|
7
|
-
base?: LatexParseNode;
|
|
8
|
-
sub?: LatexParseNode;
|
|
9
|
-
sup?: LatexParseNode;
|
|
10
|
-
exponent?: LatexParseNode;
|
|
11
|
-
body?: LatexParseNode | LatexParseNode[] | LatexParseNode[][];
|
|
12
|
-
}
|
|
13
1
|
export interface TexSupsubData {
|
|
14
2
|
base: TexNode;
|
|
15
3
|
sup?: TexNode;
|
|
@@ -21,7 +9,7 @@ export interface TexNode {
|
|
|
21
9
|
type: string;
|
|
22
10
|
content: string;
|
|
23
11
|
args?: TexNode[];
|
|
24
|
-
|
|
12
|
+
data?: TexSqrtData | TexSupsubData | TexArrayData;
|
|
25
13
|
}
|
|
26
14
|
export interface TypstNode {
|
|
27
15
|
type: 'atom' | 'symbol' | 'text' | 'softSpace' | 'comment' | 'newline';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tex2typst",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "JavaScript library for converting TeX code to Typst",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,7 +30,5 @@
|
|
|
30
30
|
"typescript": "^5.5.3",
|
|
31
31
|
"vitest": "^2.0.2"
|
|
32
32
|
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"katex": "^0.16.11"
|
|
35
|
-
}
|
|
33
|
+
"dependencies": {}
|
|
36
34
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parseTex } from "./parser";
|
|
2
2
|
import { Tex2TypstOptions } from "./types";
|
|
3
3
|
import { TypstWriter } from "./writer";
|
|
4
|
+
import { symbolMap } from "./map";
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export function tex2typst(tex: string, options?: Tex2TypstOptions): string {
|
|
@@ -26,4 +27,4 @@ export function tex2typst(tex: string, options?: Tex2TypstOptions): string {
|
|
|
26
27
|
return writer.finalize();
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
export { Tex2TypstOptions };
|
|
30
|
+
export { symbolMap, Tex2TypstOptions };
|
package/src/map.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export const symbolMap = new Map<string, string>([
|
|
2
|
-
['gets', 'arrow.l'],
|
|
3
2
|
['nonumber', ''],
|
|
4
3
|
['vec', 'arrow'],
|
|
5
4
|
['neq', 'eq.not'],
|
|
@@ -25,14 +24,15 @@ export const symbolMap = new Map<string, string>([
|
|
|
25
24
|
['tfrac', 'frac'],
|
|
26
25
|
|
|
27
26
|
['boldsymbol', 'bold'],
|
|
28
|
-
['mathbf', 'bold'],
|
|
29
27
|
['mathbb', 'bb'],
|
|
28
|
+
['mathbf', 'bold'],
|
|
30
29
|
['mathcal', 'cal'],
|
|
30
|
+
['mathit', 'italic'],
|
|
31
31
|
['mathfrak', 'frak'],
|
|
32
|
+
['mathrm', 'upright'],
|
|
32
33
|
['mathsf', 'sans'],
|
|
33
34
|
['mathtt', 'mono'],
|
|
34
35
|
|
|
35
|
-
['mathrm', 'upright'],
|
|
36
36
|
['rm', 'upright'],
|
|
37
37
|
|
|
38
38
|
// TODO: \pmb need special logic to handle but it is not implemented now. See the commented test case.
|
|
@@ -58,18 +58,6 @@ export const symbolMap = new Map<string, string>([
|
|
|
58
58
|
['equiv', 'equiv'],
|
|
59
59
|
['propto', 'prop'],
|
|
60
60
|
|
|
61
|
-
/* arrows used in proofs */
|
|
62
|
-
// tex: \implies \iff \leftrightarrow \longleftrightarrow \rightrightarrows
|
|
63
|
-
// typst: arrow.r.double.long arrow.l.r.double.long arrow.l.r arrow.l.r.long arrows.rr
|
|
64
|
-
['implies', 'arrow.r.double.long'],
|
|
65
|
-
['Longrightarrow', 'arrow.r.double.long'], // Note: This macro is not supported by KaTeX
|
|
66
|
-
['iff', 'arrow.l.r.double.long'],
|
|
67
|
-
['Longleftrightarrow', 'arrow.l.r.double.long'], // Note: This macro is not supported by KaTeX
|
|
68
|
-
['leftrightarrow', 'arrow.l.r'],
|
|
69
|
-
['longleftrightarrow', 'arrow.l.r.long'],
|
|
70
|
-
['rightrightarrows', 'arrows.rr'],
|
|
71
|
-
|
|
72
|
-
|
|
73
61
|
/* left and right floor,ceil */
|
|
74
62
|
// tex: \lfloor \rfloor \lceil \rceil
|
|
75
63
|
// typst: ⌊ ⌋ ⌈ ⌉
|
|
@@ -80,6 +68,39 @@ export const symbolMap = new Map<string, string>([
|
|
|
80
68
|
['lceil', '⌈'],
|
|
81
69
|
['rceil', '⌉'],
|
|
82
70
|
|
|
71
|
+
/* arrows */
|
|
72
|
+
['gets', 'arrow.l'],
|
|
73
|
+
['hookleftarrow', 'arrow.l.hook'],
|
|
74
|
+
['leftharpoonup', 'harpoon.lt'],
|
|
75
|
+
['leftharpoondown', 'harpoon.lb'],
|
|
76
|
+
['rightleftharpoons', 'harpoons.rtlb'],
|
|
77
|
+
['longleftarrow', 'arrow.l.long'],
|
|
78
|
+
['longrightarrow', 'arrow.r.long'],
|
|
79
|
+
['longleftrightarrow', 'arrow.l.r.long'],
|
|
80
|
+
['Longleftarrow', 'arrow.l.double.long'],
|
|
81
|
+
['Longrightarrow', 'arrow.r.double.long'],
|
|
82
|
+
['Longleftrightarrow', 'arrow.l.r.double.long'],
|
|
83
|
+
['longmapsto', 'arrow.r.bar'],
|
|
84
|
+
['hookrightarrow', 'arrow.r.hook'],
|
|
85
|
+
['rightharpoonup', 'harpoon.rt'],
|
|
86
|
+
['rightharpoondown', 'harpoon.rb'],
|
|
87
|
+
['iff', 'arrow.l.r.double.long'],
|
|
88
|
+
['implies', 'arrow.r.double.long'],
|
|
89
|
+
['uparrow', 'arrow.t'],
|
|
90
|
+
['downarrow', 'arrow.b'],
|
|
91
|
+
['updownarrow', 'arrow.t.b'],
|
|
92
|
+
['Uparrow', 'arrow.t.double'],
|
|
93
|
+
['Downarrow', 'arrow.b.double'],
|
|
94
|
+
['Updownarrow', 'arrow.t.b.double'],
|
|
95
|
+
['nearrow', 'arrow.tr'],
|
|
96
|
+
['searrow', 'arrow.br'],
|
|
97
|
+
['swarrow', 'arrow.bl'],
|
|
98
|
+
['nwarrow', 'arrow.tl'],
|
|
99
|
+
['leadsto', 'arrow.squiggly'],
|
|
100
|
+
|
|
101
|
+
['leftleftarrows', 'arrows.ll'],
|
|
102
|
+
['rightrightarrows', 'arrows.rr'],
|
|
103
|
+
|
|
83
104
|
|
|
84
105
|
['Cap', 'sect.double'],
|
|
85
106
|
['Cup', 'union.double'],
|
|
@@ -87,12 +108,16 @@ export const symbolMap = new Map<string, string>([
|
|
|
87
108
|
['Gamma', 'Gamma'],
|
|
88
109
|
['Join', 'join'],
|
|
89
110
|
['Lambda', 'Lambda'],
|
|
111
|
+
['Leftarrow', 'arrow.l.double'],
|
|
112
|
+
['Leftrightarrow', 'arrow.l.r.double'],
|
|
90
113
|
['Longrightarrow', 'arrow.r.double.long'],
|
|
91
114
|
['Omega', 'Omega'],
|
|
115
|
+
['P', 'pilcrow'],
|
|
92
116
|
['Phi', 'Phi'],
|
|
93
117
|
['Pi', 'Pi'],
|
|
94
118
|
['Psi', 'Psi'],
|
|
95
|
-
['Rightarrow', 'arrow.double'],
|
|
119
|
+
['Rightarrow', 'arrow.r.double'],
|
|
120
|
+
['S', 'section'],
|
|
96
121
|
['Sigma', 'Sigma'],
|
|
97
122
|
['Theta', 'Theta'],
|
|
98
123
|
['aleph', 'alef'],
|
|
@@ -126,6 +151,7 @@ export const symbolMap = new Map<string, string>([
|
|
|
126
151
|
['colon', 'colon'],
|
|
127
152
|
['cong', 'tilde.equiv'],
|
|
128
153
|
['coprod', 'product.co'],
|
|
154
|
+
['copyright', 'copyright'],
|
|
129
155
|
['cup', 'union'],
|
|
130
156
|
['curlyvee', 'or.curly'],
|
|
131
157
|
['curlywedge', 'and.curly'],
|
|
@@ -179,7 +205,7 @@ export const symbolMap = new Map<string, string>([
|
|
|
179
205
|
['leqslant', 'lt.eq.slant'],
|
|
180
206
|
['lhd', 'triangle.l'],
|
|
181
207
|
['ll', 'lt.double'],
|
|
182
|
-
['longmapsto', 'arrow.long
|
|
208
|
+
['longmapsto', 'arrow.bar.long'],
|
|
183
209
|
['longrightarrow', 'arrow.long'],
|
|
184
210
|
['lor', 'or'],
|
|
185
211
|
['ltimes', 'times.l'],
|