Comparing version 0.2.9 to 0.2.10
@@ -317,3 +317,3 @@ // src/map.ts | ||
function find_closing_curly_bracket(tokens, start) { | ||
assert(token_eq(tokens[start], LEFT_CURLY_BRACKET)); | ||
assert(tokens[start].eq(LEFT_CURLY_BRACKET)); | ||
let count = 1; | ||
@@ -325,5 +325,5 @@ let pos = start + 1; | ||
} | ||
if (token_eq(tokens[pos], LEFT_CURLY_BRACKET)) { | ||
if (tokens[pos].eq(LEFT_CURLY_BRACKET)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], RIGHT_CURLY_BRACKET)) { | ||
} else if (tokens[pos].eq(RIGHT_CURLY_BRACKET)) { | ||
count -= 1; | ||
@@ -336,3 +336,3 @@ } | ||
function find_closing_square_bracket(tokens, start) { | ||
assert(token_eq(tokens[start], LEFT_SQUARE_BRACKET)); | ||
assert(tokens[start].eq(LEFT_SQUARE_BRACKET)); | ||
let count = 1; | ||
@@ -344,5 +344,5 @@ let pos = start + 1; | ||
} | ||
if (token_eq(tokens[pos], LEFT_SQUARE_BRACKET)) { | ||
if (tokens[pos].eq(LEFT_SQUARE_BRACKET)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], RIGHT_SQUARE_BRACKET)) { | ||
} else if (tokens[pos].eq(RIGHT_SQUARE_BRACKET)) { | ||
count -= 1; | ||
@@ -379,3 +379,3 @@ } | ||
let pos = start; | ||
while (pos < tokens.length && token_eq(tokens[pos], { type: 0 /* ELEMENT */, value: "'" })) { | ||
while (pos < tokens.length && tokens[pos].eq(new Token(0 /* ELEMENT */, "'"))) { | ||
pos += 1; | ||
@@ -399,5 +399,5 @@ } | ||
} | ||
if (token_eq(tokens[pos], LEFT_COMMAND)) { | ||
if (tokens[pos].eq(LEFT_COMMAND)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], RIGHT_COMMAND)) { | ||
} else if (tokens[pos].eq(RIGHT_COMMAND)) { | ||
count -= 1; | ||
@@ -416,5 +416,5 @@ } | ||
} | ||
if (token_eq(tokens[pos], BEGIN_COMMAND)) { | ||
if (tokens[pos].eq(BEGIN_COMMAND)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], END_COMMAND)) { | ||
} else if (tokens[pos].eq(END_COMMAND)) { | ||
count -= 1; | ||
@@ -459,3 +459,3 @@ } | ||
} | ||
token = { type: 3 /* COMMENT */, value: latex.slice(pos + 1, newPos) }; | ||
token = new Token(3 /* COMMENT */, latex.slice(pos + 1, newPos)); | ||
pos = newPos; | ||
@@ -469,7 +469,7 @@ break; | ||
case "&": | ||
token = { type: 6 /* CONTROL */, value: firstChar }; | ||
token = new Token(6 /* CONTROL */, firstChar); | ||
pos++; | ||
break; | ||
case "\n": | ||
token = { type: 5 /* NEWLINE */, value: firstChar }; | ||
token = new Token(5 /* NEWLINE */, firstChar); | ||
pos++; | ||
@@ -479,6 +479,6 @@ break; | ||
if (pos + 1 < latex.length && latex[pos + 1] === "\n") { | ||
token = { type: 5 /* NEWLINE */, value: "\n" }; | ||
token = new Token(5 /* NEWLINE */, "\n"); | ||
pos += 2; | ||
} else { | ||
token = { type: 5 /* NEWLINE */, value: "\n" }; | ||
token = new Token(5 /* NEWLINE */, "\n"); | ||
pos++; | ||
@@ -493,3 +493,3 @@ } | ||
} | ||
token = { type: 4 /* WHITESPACE */, value: latex.slice(pos, newPos) }; | ||
token = new Token(4 /* WHITESPACE */, latex.slice(pos, newPos)); | ||
pos = newPos; | ||
@@ -504,8 +504,8 @@ break; | ||
if (["\\\\", "\\,"].includes(firstTwoChars)) { | ||
token = { type: 6 /* CONTROL */, value: firstTwoChars }; | ||
token = new Token(6 /* CONTROL */, firstTwoChars); | ||
} else if (["\\{", "\\}", "\\%", "\\$", "\\&", "\\#", "\\_"].includes(firstTwoChars)) { | ||
token = { type: 0 /* ELEMENT */, value: firstTwoChars }; | ||
token = new Token(0 /* ELEMENT */, firstTwoChars); | ||
} else { | ||
const command = eat_command_name(latex, pos + 1); | ||
token = { type: 1 /* COMMAND */, value: "\\" + command }; | ||
token = new Token(1 /* COMMAND */, "\\" + command); | ||
} | ||
@@ -521,9 +521,9 @@ pos += token.value.length; | ||
} | ||
token = { type: 0 /* ELEMENT */, value: latex.slice(pos, newPos) }; | ||
token = new Token(0 /* ELEMENT */, latex.slice(pos, newPos)); | ||
} else if (isalpha(firstChar)) { | ||
token = { type: 0 /* ELEMENT */, value: firstChar }; | ||
token = new Token(0 /* ELEMENT */, firstChar); | ||
} else if ("+-*/=\'<>!.,;?()[]|".includes(firstChar)) { | ||
token = { type: 0 /* ELEMENT */, value: firstChar }; | ||
token = new Token(0 /* ELEMENT */, firstChar); | ||
} else { | ||
token = { type: 7 /* UNKNOWN */, value: firstChar }; | ||
token = new Token(7 /* UNKNOWN */, firstChar); | ||
} | ||
@@ -538,3 +538,3 @@ pos += token.value.length; | ||
} | ||
tokens.push({ type: 6 /* CONTROL */, value: "{" }); | ||
tokens.push(new Token(6 /* CONTROL */, "{")); | ||
const posClosingBracket = find_closing_curly_bracket_char(latex, pos); | ||
@@ -547,4 +547,4 @@ pos++; | ||
} | ||
tokens.push({ type: 2 /* TEXT */, value: textInside }); | ||
tokens.push({ type: 6 /* CONTROL */, value: "}" }); | ||
tokens.push(new Token(2 /* TEXT */, textInside)); | ||
tokens.push(new Token(6 /* CONTROL */, "}")); | ||
pos = posClosingBracket + 1; | ||
@@ -555,7 +555,4 @@ } | ||
} | ||
function token_eq(token1, token2) { | ||
return token1.type == token2.type && token1.value == token2.value; | ||
} | ||
function passIgnoreWhitespaceBeforeScriptMark(tokens) { | ||
const is_script_mark = (token) => token_eq(token, SUB_SYMBOL) || token_eq(token, SUP_SYMBOL); | ||
const is_script_mark = (token) => token.eq(SUB_SYMBOL) || token.eq(SUP_SYMBOL); | ||
let out_tokens = []; | ||
@@ -630,11 +627,23 @@ for (let i = 0;i < tokens.length; i++) { | ||
]; | ||
class Token { | ||
type; | ||
value; | ||
constructor(type, value) { | ||
this.type = type; | ||
this.value = value; | ||
} | ||
eq(token) { | ||
return this.type === token.type && this.value === token.value; | ||
} | ||
} | ||
var EMPTY_NODE = { type: "empty", content: "" }; | ||
var LEFT_CURLY_BRACKET = { type: 6 /* CONTROL */, value: "{" }; | ||
var RIGHT_CURLY_BRACKET = { type: 6 /* CONTROL */, value: "}" }; | ||
var LEFT_SQUARE_BRACKET = { type: 0 /* ELEMENT */, value: "[" }; | ||
var RIGHT_SQUARE_BRACKET = { type: 0 /* ELEMENT */, value: "]" }; | ||
var LEFT_COMMAND = { type: 1 /* COMMAND */, value: "\\left" }; | ||
var RIGHT_COMMAND = { type: 1 /* COMMAND */, value: "\\right" }; | ||
var BEGIN_COMMAND = { type: 1 /* COMMAND */, value: "\\begin" }; | ||
var END_COMMAND = { type: 1 /* COMMAND */, value: "\\end" }; | ||
var LEFT_CURLY_BRACKET = new Token(6 /* CONTROL */, "{"); | ||
var RIGHT_CURLY_BRACKET = new Token(6 /* CONTROL */, "}"); | ||
var LEFT_SQUARE_BRACKET = new Token(0 /* ELEMENT */, "["); | ||
var RIGHT_SQUARE_BRACKET = new Token(0 /* ELEMENT */, "]"); | ||
var LEFT_COMMAND = new Token(1 /* COMMAND */, "\\left"); | ||
var RIGHT_COMMAND = new Token(1 /* COMMAND */, "\\right"); | ||
var BEGIN_COMMAND = new Token(1 /* COMMAND */, "\\begin"); | ||
var END_COMMAND = new Token(1 /* COMMAND */, "\\end"); | ||
@@ -647,4 +656,4 @@ class LatexParserError extends Error { | ||
} | ||
var SUB_SYMBOL = { type: 6 /* CONTROL */, value: "_" }; | ||
var SUP_SYMBOL = { type: 6 /* CONTROL */, value: "^" }; | ||
var SUB_SYMBOL = new Token(6 /* CONTROL */, "_"); | ||
var SUP_SYMBOL = new Token(6 /* CONTROL */, "^"); | ||
@@ -701,7 +710,7 @@ class LatexParser { | ||
pos += num_prime; | ||
if (pos < tokens.length && token_eq(tokens[pos], SUB_SYMBOL)) { | ||
if (pos < tokens.length && tokens[pos].eq(SUB_SYMBOL)) { | ||
[sub, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
num_prime += eat_primes(tokens, pos); | ||
pos += num_prime; | ||
if (pos < tokens.length && token_eq(tokens[pos], SUP_SYMBOL)) { | ||
if (pos < tokens.length && tokens[pos].eq(SUP_SYMBOL)) { | ||
[sup, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
@@ -712,3 +721,3 @@ if (eat_primes(tokens, pos) > 0) { | ||
} | ||
} else if (pos < tokens.length && token_eq(tokens[pos], SUP_SYMBOL)) { | ||
} else if (pos < tokens.length && tokens[pos].eq(SUP_SYMBOL)) { | ||
[sup, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
@@ -718,3 +727,3 @@ if (eat_primes(tokens, pos) > 0) { | ||
} | ||
if (pos < tokens.length && token_eq(tokens[pos], SUB_SYMBOL)) { | ||
if (pos < tokens.length && tokens[pos].eq(SUB_SYMBOL)) { | ||
[sub, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
@@ -765,5 +774,5 @@ if (eat_primes(tokens, pos) > 0) { | ||
case 1 /* COMMAND */: | ||
if (token_eq(firstToken, BEGIN_COMMAND)) { | ||
if (firstToken.eq(BEGIN_COMMAND)) { | ||
return this.parseBeginEndExpr(tokens, start); | ||
} else if (token_eq(firstToken, LEFT_COMMAND)) { | ||
} else if (firstToken.eq(LEFT_COMMAND)) { | ||
return this.parseLeftRightExpr(tokens, start); | ||
@@ -816,3 +825,3 @@ } else { | ||
case 1: { | ||
if (command === "\\sqrt" && pos < tokens.length && token_eq(tokens[pos], LEFT_SQUARE_BRACKET)) { | ||
if (command === "\\sqrt" && pos < tokens.length && tokens[pos].eq(LEFT_SQUARE_BRACKET)) { | ||
const posLeftSquareBracket = pos; | ||
@@ -828,5 +837,5 @@ const posRightSquareBracket = find_closing_square_bracket(tokens, pos); | ||
} | ||
assert(token_eq(tokens[pos], LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos].eq(LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos + 1].type === 2 /* TEXT */); | ||
assert(token_eq(tokens[pos + 2], RIGHT_CURLY_BRACKET)); | ||
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET)); | ||
const text = tokens[pos + 1].value; | ||
@@ -848,3 +857,3 @@ return [{ type: "text", content: text }, pos + 3]; | ||
parseLeftRightExpr(tokens, start) { | ||
assert(token_eq(tokens[start], LEFT_COMMAND)); | ||
assert(tokens[start].eq(LEFT_COMMAND)); | ||
let pos = start + 1; | ||
@@ -887,7 +896,7 @@ pos += eat_whitespaces(tokens, pos).length; | ||
parseBeginEndExpr(tokens, start) { | ||
assert(token_eq(tokens[start], BEGIN_COMMAND)); | ||
assert(tokens[start].eq(BEGIN_COMMAND)); | ||
let pos = start + 1; | ||
assert(token_eq(tokens[pos], LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos].eq(LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos + 1].type === 2 /* TEXT */); | ||
assert(token_eq(tokens[pos + 2], RIGHT_CURLY_BRACKET)); | ||
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET)); | ||
const envName = tokens[pos + 1].value; | ||
@@ -903,5 +912,5 @@ pos += 3; | ||
pos = endIdx + 1; | ||
assert(token_eq(tokens[pos], LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos].eq(LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos + 1].type === 2 /* TEXT */); | ||
assert(token_eq(tokens[pos + 2], RIGHT_CURLY_BRACKET)); | ||
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET)); | ||
if (tokens[pos + 1].value !== envName) { | ||
@@ -1393,5 +1402,7 @@ throw new LatexParserError("Mismatched \\begin and \\end environments"); | ||
} | ||
export { | ||
tex2typst, | ||
symbolMap | ||
}; | ||
console.log(tex2typst("\\sqrt[3]{x}")); | ||
// export { | ||
// tex2typst, | ||
// symbolMap | ||
// }; |
@@ -1,2 +0,8 @@ | ||
import { TexNode, Token } from "./types"; | ||
import { TexNode, TokenType } from "./types"; | ||
export declare class Token { | ||
type: TokenType; | ||
value: string; | ||
constructor(type: TokenType, value: string); | ||
eq(token: Token): boolean; | ||
} | ||
export declare function tokenize(latex: string): Token[]; | ||
@@ -3,0 +9,0 @@ export declare class LatexParserError extends Error { |
@@ -1,1 +0,1 @@ | ||
var O=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 W(z,Z=""){if(!z)throw new H(Z)}function l(z){if(x.includes(z))return 1;else if(_.includes(z))return 2;else return 0}function i(z,Z){W(j(z[Z],D));let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched curly brackets");if(j(z[V],D))J+=1;else if(j(z[V],N))J-=1;V+=1}return V-1}function d(z,Z){W(j(z[Z],I));let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched square brackets");if(j(z[V],I))J+=1;else if(j(z[V],T))J-=1;V+=1}return V-1}function L(z){return"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(z)}function g(z){return"0123456789".includes(z)}function A(z,Z){let J=Z;while(J<z.length&&[4,5].includes(z[J].type))J++;return z.slice(Z,J)}function C(z,Z){const J=z[Z];if(J.type===0&&["(",")","[","]","|","\\{","\\}"].includes(J.value))return J;else if(J.type===1&&["lfloor","rfloor","lceil","rceil","langle","rangle"].includes(J.value.slice(1)))return J;else return null}function U(z,Z){let J=Z;while(J<z.length&&j(z[J],{type:0,value:"'"}))J+=1;return J-Z}function p(z,Z){let J=Z;while(J<z.length&&L(z[J]))J+=1;return z.substring(Z,J)}function a(z,Z){let J=1,V=Z;while(J>0){if(V>=z.length)return-1;if(j(z[V],f))J+=1;else if(j(z[V],k))J-=1;V+=1}return V-1}function r(z,Z){let J=1,V=Z;while(J>0){if(V>=z.length)return-1;if(j(z[V],B))J+=1;else if(j(z[V],n))J-=1;V+=1}return V-1}function t(z,Z){W(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 P(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:3,value:z.slice(J+1,$)},J=$;break}case"{":case"}":case"_":case"^":case"&":X={type:6,value:V},J++;break;case"\n":X={type:5,value:V},J++;break;case"\r":{if(J+1<z.length&&z[J+1]==="\n")X={type:5,value:"\n"},J+=2;else X={type:5,value:"\n"},J++;break}case" ":{let $=J;while($<z.length&&z[$]===" ")$+=1;X={type:4,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:6,value:$};else if(["\\{","\\}","\\%","\\$","\\&","\\#","\\_"].includes($))X={type:0,value:$};else{const q=p(z,J+1);X={type:1,value:"\\"+q}}J+=X.value.length;break}default:{if(g(V)){let $=J;while($<z.length&&g(z[$]))$+=1;X={type:0,value:z.slice(J,$)}}else if(L(V))X={type:0,value:V};else if("+-*/=\'<>!.,;?()[]|".includes(V))X={type:0,value:V};else X={type:7,value:V};J+=X.value.length}}if(Z.push(X),X.type===1&&["\\text","\\operatorname","\\begin","\\end"].includes(X.value)){if(J>=z.length||z[J]!=="{")throw new H(`No content for ${X.value} command`);Z.push({type:6,value:"{"});const $=t(z,J);J++;let q=z.slice(J,$);const Q=["{","}","\\","$","&","#","_","%"];for(let F of Q)q=q.replaceAll("\\"+F,F);Z.push({type:2,value:q}),Z.push({type:6,value:"}"}),J=$+1}}return Z}function j(z,Z){return z.type==Z.type&&z.value==Z.value}function s(z){const Z=(V)=>j(V,M)||j(V,h);let J=[];for(let V=0;V<z.length;V++){if(z[V].type===4&&V+1<z.length&&Z(z[V+1]))continue;if(z[V].type===4&&V-1>=0&&Z(z[V-1]))continue;J.push(z[V])}return J}function o(z,Z){let J=[];for(let V of z)if(V.type===1&&Z[V.value]){const X=P(Z[V.value]);J=J.concat(X)}else J.push(V);return J}function u(z,Z){const J=new y;let V=P(z);return V=s(V),V=o(V,Z),J.parse(V)}var x=["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"],_=["frac","tfrac","binom","dbinom","dfrac","tbinom"],v={type:"empty",content:""},D={type:6,value:"{"},N={type:6,value:"}"},I={type:0,value:"["},T={type:0,value:"]"},f={type:1,value:"\\left"},k={type:1,value:"\\right"},B={type:1,value:"\\begin"},n={type:1,value:"\\end"};class H extends Error{constructor(z){super(z);this.name="LatexParserError"}}var M={type:6,value:"_"},h={type:6,value:"^"};class y{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[$,q]=this.parseNextExpr(z,X);if(X=q,!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 v;else if(V.length===1)return V[0];else return{type:"ordgroup",content:"",args:V}}if(Z.length===0)return v;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,q=0;if(q+=U(z,V),V+=q,V<z.length&&j(z[V],M)){if([X,V]=this.parseNextExprWithoutSupSub(z,V+1),q+=U(z,V),V+=q,V<z.length&&j(z[V],h)){if([$,V]=this.parseNextExprWithoutSupSub(z,V+1),U(z,V)>0)throw new H("Double superscript")}}else if(V<z.length&&j(z[V],h)){if([$,V]=this.parseNextExprWithoutSupSub(z,V+1),U(z,V)>0)throw new H("Double superscript");if(V<z.length&&j(z[V],M)){if([X,V]=this.parseNextExprWithoutSupSub(z,V+1),U(z,V)>0)throw new H("Double superscript")}}if(X!==null||$!==null||q>0){const Q={base:J};if(X)Q.sub=X;if(q>0){Q.sup={type:"ordgroup",content:"",args:[]};for(let F=0;F<q;F++)Q.sup.args.push({type:"element",content:"'"});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];switch(J.type){case 0:return[{type:"element",content:J.value},Z+1];case 2:return[{type:"text",content:J.value},Z+1];case 3:return[{type:"comment",content:J.value},Z+1];case 4:return[{type:"whitespace",content:J.value},Z+1];case 5:return[{type:"newline",content:J.value},Z+1];case 1:if(j(J,B))return this.parseBeginEndExpr(z,Z);else if(j(J,f))return this.parseLeftRightExpr(z,Z);else return this.parseCommandExpr(z,Z);case 6:switch(J.value){case"{":const $=i(z,Z),q=z.slice(Z+1,$);return[this.parse(q),$+1];case"}":throw new H("Unmatched '}'");case"\\\\":return[{type:"control",content:"\\\\"},Z+1];case"\\,":return[{type:"control",content:"\\,"},Z+1];case"_":return[v,Z];case"^":return[v,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){W(z[Z].type===1);const J=z[Z].value;let V=Z+1;if(["left","right","begin","end"].includes(J.slice(1)))throw new H("Unexpected command: "+J);switch(l(J.slice(1))){case 0:if(!O.has(J.slice(1)))return[{type:"unknownMacro",content:J},V];return[{type:"symbol",content:J},V];case 1:{if(J==="\\sqrt"&&V<z.length&&j(z[V],I)){const Q=V,F=d(z,V),S=z.slice(Q+1,F),R=this.parse(S),[w,c]=this.parseNextExprWithoutSupSub(z,F+1);return[{type:"unaryFunc",content:J,args:[w],data:R},c]}else if(J==="\\text"){if(V+2>=z.length)throw new H("Expecting content for \\text command");return W(j(z[V],D)),W(z[V+1].type===2),W(j(z[V+2],N)),[{type:"text",content:z[V+1].value},V+3]}let[$,q]=this.parseNextExprWithoutSupSub(z,V);return[{type:"unaryFunc",content:J,args:[$]},q]}case 2:{const[$,q]=this.parseNextExprWithoutSupSub(z,V),[Q,F]=this.parseNextExprWithoutSupSub(z,q);return[{type:"binaryFunc",content:J,args:[$,Q]},F]}default:throw new Error("Invalid number of parameters")}}parseLeftRightExpr(z,Z){W(j(z[Z],f));let J=Z+1;if(J+=A(z,J).length,J>=z.length)throw new H("Expecting delimiter after \\left");const V=C(z,J);if(V===null)throw new H("Invalid delimiter after \\left");J++;const X=J,$=a(z,J);if($===-1)throw new H("No matching \\right");const q=$;if(J=$+1,J+=A(z,J).length,J>=z.length)throw new H("Expecting \\right after \\left");const Q=C(z,J);if(Q===null)throw new H("Invalid delimiter after \\right");J++;const F=z.slice(X,q),S=this.parse(F);return[{type:"leftright",content:"",args:[{type:"element",content:V.value},S,{type:"element",content:Q.value}]},J]}parseBeginEndExpr(z,Z){W(j(z[Z],B));let J=Z+1;W(j(z[J],D)),W(z[J+1].type===2),W(j(z[J+2],N));const V=z[J+1].value;J+=3,J+=A(z,J).length;const X=J,$=r(z,J);if($===-1)throw new H("No matching \\end");const q=$;if(J=$+1,W(j(z[J],D)),W(z[J+1].type===2),W(j(z[J+2],N)),z[J+1].value!==V)throw new H("Mismatched \\begin and \\end environments");J+=3;const Q=z.slice(X,q);while(Q.length>0&&[4,5].includes(Q[Q.length-1].type))Q.pop();const F=this.parseAligned(Q);return[{type:"beginend",content:V,data:F},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[$,q]=this.parseNextExpr(z,Z);if(Z=q,$.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}}function E(z){return z.type==="atom"&&["(",")","[","]","{","}","|","\u230A","\u230B","\u2308","\u2309"].includes(z.content)}function G(z){switch(z.type){case"empty":case"whitespace":return{type:"empty",content:""};case"ordgroup":return{type:"group",content:"",args:z.args.map(G)};case"element":return{type:"atom",content:Y(z.content)};case"symbol":return{type:"symbol",content:Y(z.content)};case"text":return{type:"text",content:z.content};case"comment":return{type:"comment",content:z.content};case"supsub":{let{base:Z,sup:J,sub:V}=z.data;if(Z&&Z.type==="unaryFunc"&&Z.content==="\\overbrace"&&J)return{type:"binaryFunc",content:"overbrace",args:[G(Z.args[0]),G(J)]};else if(Z&&Z.type==="unaryFunc"&&Z.content==="\\underbrace"&&V)return{type:"binaryFunc",content:"underbrace",args:[G(Z.args[0]),G(V)]};const X={base:G(Z)};if(X.base.type==="empty")X.base={type:"text",content:""};if(J)X.sup=G(J);if(V)X.sub=G(V);return{type:"supsub",content:"",data:X}}case"leftright":{const[Z,J,V]=z.args,X={type:"group",content:"",args:z.args.map(G)};if(["[]","()","\\{\\}","\\lfloor\\rfloor","\\lceil\\rceil"].includes(Z.content+V.content))return X;return{type:"unaryFunc",content:"lr",args:[X]}}case"binaryFunc":return{type:"binaryFunc",content:Y(z.content),args:z.args.map(G)};case"unaryFunc":{const Z=G(z.args[0]);if(z.content==="\\sqrt"&&z.data)return{type:"binaryFunc",content:"root",args:[G(z.data),Z]};if(z.content==="\\mathbf")return{type:"unaryFunc",content:"upright",args:[{type:"unaryFunc",content:"bold",args:[Z]}]};if(z.content==="\\mathbb"&&Z.type==="atom"&&/^[A-Z]$/.test(Z.content))return{type:"symbol",content:Z.content+Z.content};if(z.content==="\\operatorname"){const J=z.args;if(J.length!==1||J[0].type!=="text")throw new K("Expecting body of \\operatorname to be text but got",z);const V=J[0].content;if(e.includes(V))return{type:"symbol",content:V};else return{type:"unaryFunc",content:"op",args:[{type:"text",content:V}]}}return{type:"unaryFunc",content:Y(z.content),args:z.args.map(G)}}case"newline":return{type:"newline",content:"\n"};case"beginend":{const J=z.data.map((V)=>V.map(G));if(z.content.startsWith("align"))return{type:"align",content:"",data:J};else return{type:"matrix",content:"mat",data:J}}case"unknownMacro":return{type:"unknown",content:Y(z.content)};case"control":if(z.content==="\\\\")return{type:"symbol",content:"\\"};else if(z.content==="\\,")return{type:"symbol",content:"thin"};else throw new K(`Unknown control sequence: ${z.content}`,z);default:throw new K(`Unimplemented node type: ${z.type}`,z)}}function Y(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(O.has(Z))return O.get(Z);else return Z}return z}var e=["dim","id","im","mod","Pr","sech","csch"];class K extends Error{node;constructor(z,Z){super(z);this.name="TypstWriterError",this.node=Z}}class b{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){switch(z.type){case"empty":break;case"atom":{if(z.content===","&&this.insideFunctionDepth>0)this.queue.push({type:"symbol",content:"comma"});else this.queue.push({type:"atom",content:z.content});break}case"symbol":case"text":case"comment":case"newline":this.queue.push(z);break;case"group":for(let Z of z.args)this.append(Z);break;case"supsub":{let{base:Z,sup:J,sub:V}=z.data;this.appendWithBracketsIfNeeded(Z);let X=!1;const $=J&&J.type==="atom"&&J.content==="\'";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:""});break}case"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--;break}case"unaryFunc":{const Z={type:"symbol",content:z.content},J=z.args[0];this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--;break}case"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:"\\"})});break}case"matrix":{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(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--;break}case"unknown":{if(this.nonStrict)this.queue.push({type:"symbol",content:z.content});else throw new K(`Unknown macro: ${z.content}`,z);break}default:throw new K(`Unimplemented node type to append: ${z.type}`,z)}}appendWithBracketsIfNeeded(z){let Z=["group","supsub","empty"].includes(z.type);if(z.type==="group"){const J=z.args[0],V=z.args[z.args.length-1];if(E(J)&&E(V))Z=!1}if(Z)this.queue.push({type:"atom",content:"("}),this.append(z),this.queue.push({type:"atom",content:")"});else this.append(z);return!Z}flushQueue(){this.queue.forEach((z)=>{let Z="";switch(z.type){case"atom":case"symbol":Z=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=[]}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 m(z,Z){const J={nonStrict:!0,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=u(z,J.customTexMacros),X=G(V),$=new b(J.nonStrict,J.preferTypstIntrinsic);return $.append(X),$.finalize()}if(typeof window!=="undefined")window.tex2typst=m; | ||
var O=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 W(z,Z=""){if(!z)throw new H(Z)}function l(z){if(x.includes(z))return 1;else if(_.includes(z))return 2;else return 0}function i(z,Z){W(z[Z].eq(D));let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched curly brackets");if(z[V].eq(D))J+=1;else if(z[V].eq(v))J-=1;V+=1}return V-1}function T(z,Z){W(z[Z].eq(I));let J=1,V=Z+1;while(J>0){if(V>=z.length)throw new H("Unmatched square brackets");if(z[V].eq(I))J+=1;else if(z[V].eq(d))J-=1;V+=1}return V-1}function L(z){return"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(z)}function g(z){return"0123456789".includes(z)}function A(z,Z){let J=Z;while(J<z.length&&[4,5].includes(z[J].type))J++;return z.slice(Z,J)}function C(z,Z){const J=z[Z];if(J.type===0&&["(",")","[","]","|","\\{","\\}"].includes(J.value))return J;else if(J.type===1&&["lfloor","rfloor","lceil","rceil","langle","rangle"].includes(J.value.slice(1)))return J;else return null}function U(z,Z){let J=Z;while(J<z.length&&z[J].eq(new j(0,"'")))J+=1;return J-Z}function p(z,Z){let J=Z;while(J<z.length&&L(z[J]))J+=1;return z.substring(Z,J)}function a(z,Z){let J=1,V=Z;while(J>0){if(V>=z.length)return-1;if(z[V].eq(f))J+=1;else if(z[V].eq(k))J-=1;V+=1}return V-1}function n(z,Z){let J=1,V=Z;while(J>0){if(V>=z.length)return-1;if(z[V].eq(B))J+=1;else if(z[V].eq(r))J-=1;V+=1}return V-1}function t(z,Z){W(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 P(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=new j(3,z.slice(J+1,$)),J=$;break}case"{":case"}":case"_":case"^":case"&":X=new j(6,V),J++;break;case"\n":X=new j(5,V),J++;break;case"\r":{if(J+1<z.length&&z[J+1]==="\n")X=new j(5,"\n"),J+=2;else X=new j(5,"\n"),J++;break}case" ":{let $=J;while($<z.length&&z[$]===" ")$+=1;X=new j(4,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=new j(6,$);else if(["\\{","\\}","\\%","\\$","\\&","\\#","\\_"].includes($))X=new j(0,$);else{const q=p(z,J+1);X=new j(1,"\\"+q)}J+=X.value.length;break}default:{if(g(V)){let $=J;while($<z.length&&g(z[$]))$+=1;X=new j(0,z.slice(J,$))}else if(L(V))X=new j(0,V);else if("+-*/=\'<>!.,;?()[]|".includes(V))X=new j(0,V);else X=new j(7,V);J+=X.value.length}}if(Z.push(X),X.type===1&&["\\text","\\operatorname","\\begin","\\end"].includes(X.value)){if(J>=z.length||z[J]!=="{")throw new H(`No content for ${X.value} command`);Z.push(new j(6,"{"));const $=t(z,J);J++;let q=z.slice(J,$);const Q=["{","}","\\","$","&","#","_","%"];for(let F of Q)q=q.replaceAll("\\"+F,F);Z.push(new j(2,q)),Z.push(new j(6,"}")),J=$+1}}return Z}function s(z){const Z=(V)=>V.eq(M)||V.eq(h);let J=[];for(let V=0;V<z.length;V++){if(z[V].type===4&&V+1<z.length&&Z(z[V+1]))continue;if(z[V].type===4&&V-1>=0&&Z(z[V-1]))continue;J.push(z[V])}return J}function o(z,Z){let J=[];for(let V of z)if(V.type===1&&Z[V.value]){const X=P(Z[V.value]);J=J.concat(X)}else J.push(V);return J}function u(z,Z){const J=new y;let V=P(z);return V=s(V),V=o(V,Z),J.parse(V)}var x=["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"],_=["frac","tfrac","binom","dbinom","dfrac","tbinom"];class j{type;value;constructor(z,Z){this.type=z,this.value=Z}eq(z){return this.type===z.type&&this.value===z.value}}var N={type:"empty",content:""},D=new j(6,"{"),v=new j(6,"}"),I=new j(0,"["),d=new j(0,"]"),f=new j(1,"\\left"),k=new j(1,"\\right"),B=new j(1,"\\begin"),r=new j(1,"\\end");class H extends Error{constructor(z){super(z);this.name="LatexParserError"}}var M=new j(6,"_"),h=new j(6,"^");class y{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[$,q]=this.parseNextExpr(z,X);if(X=q,!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 N;else if(V.length===1)return V[0];else return{type:"ordgroup",content:"",args:V}}if(Z.length===0)return N;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,q=0;if(q+=U(z,V),V+=q,V<z.length&&z[V].eq(M)){if([X,V]=this.parseNextExprWithoutSupSub(z,V+1),q+=U(z,V),V+=q,V<z.length&&z[V].eq(h)){if([$,V]=this.parseNextExprWithoutSupSub(z,V+1),U(z,V)>0)throw new H("Double superscript")}}else if(V<z.length&&z[V].eq(h)){if([$,V]=this.parseNextExprWithoutSupSub(z,V+1),U(z,V)>0)throw new H("Double superscript");if(V<z.length&&z[V].eq(M)){if([X,V]=this.parseNextExprWithoutSupSub(z,V+1),U(z,V)>0)throw new H("Double superscript")}}if(X!==null||$!==null||q>0){const Q={base:J};if(X)Q.sub=X;if(q>0){Q.sup={type:"ordgroup",content:"",args:[]};for(let F=0;F<q;F++)Q.sup.args.push({type:"element",content:"'"});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];switch(J.type){case 0:return[{type:"element",content:J.value},Z+1];case 2:return[{type:"text",content:J.value},Z+1];case 3:return[{type:"comment",content:J.value},Z+1];case 4:return[{type:"whitespace",content:J.value},Z+1];case 5:return[{type:"newline",content:J.value},Z+1];case 1:if(J.eq(B))return this.parseBeginEndExpr(z,Z);else if(J.eq(f))return this.parseLeftRightExpr(z,Z);else return this.parseCommandExpr(z,Z);case 6:switch(J.value){case"{":const $=i(z,Z),q=z.slice(Z+1,$);return[this.parse(q),$+1];case"}":throw new H("Unmatched '}'");case"\\\\":return[{type:"control",content:"\\\\"},Z+1];case"\\,":return[{type:"control",content:"\\,"},Z+1];case"_":return[N,Z];case"^":return[N,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){W(z[Z].type===1);const J=z[Z].value;let V=Z+1;if(["left","right","begin","end"].includes(J.slice(1)))throw new H("Unexpected command: "+J);switch(l(J.slice(1))){case 0:if(!O.has(J.slice(1)))return[{type:"unknownMacro",content:J},V];return[{type:"symbol",content:J},V];case 1:{if(J==="\\sqrt"&&V<z.length&&z[V].eq(I)){const Q=V,F=T(z,V),S=z.slice(Q+1,F),R=this.parse(S),[w,c]=this.parseNextExprWithoutSupSub(z,F+1);return[{type:"unaryFunc",content:J,args:[w],data:R},c]}else if(J==="\\text"){if(V+2>=z.length)throw new H("Expecting content for \\text command");return W(z[V].eq(D)),W(z[V+1].type===2),W(z[V+2].eq(v)),[{type:"text",content:z[V+1].value},V+3]}let[$,q]=this.parseNextExprWithoutSupSub(z,V);return[{type:"unaryFunc",content:J,args:[$]},q]}case 2:{const[$,q]=this.parseNextExprWithoutSupSub(z,V),[Q,F]=this.parseNextExprWithoutSupSub(z,q);return[{type:"binaryFunc",content:J,args:[$,Q]},F]}default:throw new Error("Invalid number of parameters")}}parseLeftRightExpr(z,Z){W(z[Z].eq(f));let J=Z+1;if(J+=A(z,J).length,J>=z.length)throw new H("Expecting delimiter after \\left");const V=C(z,J);if(V===null)throw new H("Invalid delimiter after \\left");J++;const X=J,$=a(z,J);if($===-1)throw new H("No matching \\right");const q=$;if(J=$+1,J+=A(z,J).length,J>=z.length)throw new H("Expecting \\right after \\left");const Q=C(z,J);if(Q===null)throw new H("Invalid delimiter after \\right");J++;const F=z.slice(X,q),S=this.parse(F);return[{type:"leftright",content:"",args:[{type:"element",content:V.value},S,{type:"element",content:Q.value}]},J]}parseBeginEndExpr(z,Z){W(z[Z].eq(B));let J=Z+1;W(z[J].eq(D)),W(z[J+1].type===2),W(z[J+2].eq(v));const V=z[J+1].value;J+=3,J+=A(z,J).length;const X=J,$=n(z,J);if($===-1)throw new H("No matching \\end");const q=$;if(J=$+1,W(z[J].eq(D)),W(z[J+1].type===2),W(z[J+2].eq(v)),z[J+1].value!==V)throw new H("Mismatched \\begin and \\end environments");J+=3;const Q=z.slice(X,q);while(Q.length>0&&[4,5].includes(Q[Q.length-1].type))Q.pop();const F=this.parseAligned(Q);return[{type:"beginend",content:V,data:F},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[$,q]=this.parseNextExpr(z,Z);if(Z=q,$.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}}function E(z){return z.type==="atom"&&["(",")","[","]","{","}","|","\u230A","\u230B","\u2308","\u2309"].includes(z.content)}function G(z){switch(z.type){case"empty":case"whitespace":return{type:"empty",content:""};case"ordgroup":return{type:"group",content:"",args:z.args.map(G)};case"element":return{type:"atom",content:Y(z.content)};case"symbol":return{type:"symbol",content:Y(z.content)};case"text":return{type:"text",content:z.content};case"comment":return{type:"comment",content:z.content};case"supsub":{let{base:Z,sup:J,sub:V}=z.data;if(Z&&Z.type==="unaryFunc"&&Z.content==="\\overbrace"&&J)return{type:"binaryFunc",content:"overbrace",args:[G(Z.args[0]),G(J)]};else if(Z&&Z.type==="unaryFunc"&&Z.content==="\\underbrace"&&V)return{type:"binaryFunc",content:"underbrace",args:[G(Z.args[0]),G(V)]};const X={base:G(Z)};if(X.base.type==="empty")X.base={type:"text",content:""};if(J)X.sup=G(J);if(V)X.sub=G(V);return{type:"supsub",content:"",data:X}}case"leftright":{const[Z,J,V]=z.args,X={type:"group",content:"",args:z.args.map(G)};if(["[]","()","\\{\\}","\\lfloor\\rfloor","\\lceil\\rceil"].includes(Z.content+V.content))return X;return{type:"unaryFunc",content:"lr",args:[X]}}case"binaryFunc":return{type:"binaryFunc",content:Y(z.content),args:z.args.map(G)};case"unaryFunc":{const Z=G(z.args[0]);if(z.content==="\\sqrt"&&z.data)return{type:"binaryFunc",content:"root",args:[G(z.data),Z]};if(z.content==="\\mathbf")return{type:"unaryFunc",content:"upright",args:[{type:"unaryFunc",content:"bold",args:[Z]}]};if(z.content==="\\mathbb"&&Z.type==="atom"&&/^[A-Z]$/.test(Z.content))return{type:"symbol",content:Z.content+Z.content};if(z.content==="\\operatorname"){const J=z.args;if(J.length!==1||J[0].type!=="text")throw new K("Expecting body of \\operatorname to be text but got",z);const V=J[0].content;if(e.includes(V))return{type:"symbol",content:V};else return{type:"unaryFunc",content:"op",args:[{type:"text",content:V}]}}return{type:"unaryFunc",content:Y(z.content),args:z.args.map(G)}}case"newline":return{type:"newline",content:"\n"};case"beginend":{const J=z.data.map((V)=>V.map(G));if(z.content.startsWith("align"))return{type:"align",content:"",data:J};else return{type:"matrix",content:"mat",data:J}}case"unknownMacro":return{type:"unknown",content:Y(z.content)};case"control":if(z.content==="\\\\")return{type:"symbol",content:"\\"};else if(z.content==="\\,")return{type:"symbol",content:"thin"};else throw new K(`Unknown control sequence: ${z.content}`,z);default:throw new K(`Unimplemented node type: ${z.type}`,z)}}function Y(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(O.has(Z))return O.get(Z);else return Z}return z}var e=["dim","id","im","mod","Pr","sech","csch"];class K extends Error{node;constructor(z,Z){super(z);this.name="TypstWriterError",this.node=Z}}class b{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){switch(z.type){case"empty":break;case"atom":{if(z.content===","&&this.insideFunctionDepth>0)this.queue.push({type:"symbol",content:"comma"});else this.queue.push({type:"atom",content:z.content});break}case"symbol":case"text":case"comment":case"newline":this.queue.push(z);break;case"group":for(let Z of z.args)this.append(Z);break;case"supsub":{let{base:Z,sup:J,sub:V}=z.data;this.appendWithBracketsIfNeeded(Z);let X=!1;const $=J&&J.type==="atom"&&J.content==="\'";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:""});break}case"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--;break}case"unaryFunc":{const Z={type:"symbol",content:z.content},J=z.args[0];this.queue.push(Z),this.insideFunctionDepth++,this.queue.push({type:"atom",content:"("}),this.append(J),this.queue.push({type:"atom",content:")"}),this.insideFunctionDepth--;break}case"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:"\\"})});break}case"matrix":{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(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--;break}case"unknown":{if(this.nonStrict)this.queue.push({type:"symbol",content:z.content});else throw new K(`Unknown macro: ${z.content}`,z);break}default:throw new K(`Unimplemented node type to append: ${z.type}`,z)}}appendWithBracketsIfNeeded(z){let Z=["group","supsub","empty"].includes(z.type);if(z.type==="group"){const J=z.args[0],V=z.args[z.args.length-1];if(E(J)&&E(V))Z=!1}if(Z)this.queue.push({type:"atom",content:"("}),this.append(z),this.queue.push({type:"atom",content:")"});else this.append(z);return!Z}flushQueue(){this.queue.forEach((z)=>{let Z="";switch(z.type){case"atom":case"symbol":Z=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=[]}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 m(z,Z){const J={nonStrict:!0,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=u(z,J.customTexMacros),X=G(V),$=new b(J.nonStrict,J.preferTypstIntrinsic);return $.append(X),$.finalize()}if(typeof window!=="undefined")window.tex2typst=m; |
@@ -11,6 +11,2 @@ export declare enum TokenType { | ||
} | ||
export interface Token { | ||
type: TokenType; | ||
value: string; | ||
} | ||
export interface TexSupsubData { | ||
@@ -17,0 +13,0 @@ base: TexNode; |
{ | ||
"name": "tex2typst", | ||
"version": "0.2.9", | ||
"version": "0.2.10", | ||
"description": "JavaScript library for converting TeX code to Typst", | ||
@@ -9,3 +9,3 @@ "type": "module", | ||
"repository": "https://github.com/qwinsi/tex2typst", | ||
"license": "MIT", | ||
"license": "GPL-3.0", | ||
"keywords": [ | ||
@@ -12,0 +12,0 @@ "LaTeX", |
@@ -62,7 +62,8 @@ # tex2typst | ||
graph LR | ||
tex[TeX code] --parser--> ast[TeX AST] --writer--> typst[Typst code] | ||
tex[TeX code] --parser--> tex_ast[TeX AST] --converter--> typst_ast[Typst AST] --writer--> typst[Typst code] | ||
``` | ||
- parser: Implemented in class `LatexParser()`. | ||
- writer: Implemented in class `TypstWriter()` | ||
- parser: Implemented in class `LatexParser`. | ||
- converter: Implemented in function `convertTree`. | ||
- writer: Implemented in class `TypstWriter`. | ||
@@ -69,0 +70,0 @@ ## Contributing |
import { symbolMap } from "./map"; | ||
import { TexNode, TexSupsubData, Token, TokenType } from "./types"; | ||
import { TexNode, TexSupsubData, TokenType } from "./types"; | ||
@@ -46,2 +46,17 @@ | ||
export class Token { | ||
type: TokenType; | ||
value: string; | ||
constructor(type: TokenType, value: string) { | ||
this.type = type; | ||
this.value = value; | ||
} | ||
public eq(token: Token): boolean { | ||
return this.type === token.type && this.value === token.value; | ||
} | ||
} | ||
const EMPTY_NODE: TexNode = { type: 'empty', content: '' }; | ||
@@ -65,7 +80,7 @@ | ||
const LEFT_CURLY_BRACKET: Token = {type: TokenType.CONTROL, value: '{'}; | ||
const RIGHT_CURLY_BRACKET: Token = {type: TokenType.CONTROL, value: '}'}; | ||
const LEFT_CURLY_BRACKET: Token = new Token(TokenType.CONTROL, '{'); | ||
const RIGHT_CURLY_BRACKET: Token = new Token(TokenType.CONTROL, '}'); | ||
function find_closing_curly_bracket(tokens: Token[], start: number): number { | ||
assert(token_eq(tokens[start], LEFT_CURLY_BRACKET)); | ||
assert(tokens[start].eq(LEFT_CURLY_BRACKET)); | ||
let count = 1; | ||
@@ -78,5 +93,5 @@ let pos = start + 1; | ||
} | ||
if (token_eq(tokens[pos], LEFT_CURLY_BRACKET)) { | ||
if (tokens[pos].eq(LEFT_CURLY_BRACKET)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], RIGHT_CURLY_BRACKET)) { | ||
} else if (tokens[pos].eq(RIGHT_CURLY_BRACKET)) { | ||
count -= 1; | ||
@@ -90,7 +105,7 @@ } | ||
const LEFT_SQUARE_BRACKET: Token = {type: TokenType.ELEMENT, value: '['}; | ||
const RIGHT_SQUARE_BRACKET: Token = {type: TokenType.ELEMENT, value: ']'}; | ||
const LEFT_SQUARE_BRACKET: Token = new Token(TokenType.ELEMENT, '['); | ||
const RIGHT_SQUARE_BRACKET: Token = new Token(TokenType.ELEMENT, ']'); | ||
function find_closing_square_bracket(tokens: Token[], start: number): number { | ||
assert(token_eq(tokens[start], LEFT_SQUARE_BRACKET)); | ||
assert(tokens[start].eq(LEFT_SQUARE_BRACKET)); | ||
let count = 1; | ||
@@ -103,5 +118,5 @@ let pos = start + 1; | ||
} | ||
if (token_eq(tokens[pos], LEFT_SQUARE_BRACKET)) { | ||
if (tokens[pos].eq(LEFT_SQUARE_BRACKET)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], RIGHT_SQUARE_BRACKET)) { | ||
} else if (tokens[pos].eq(RIGHT_SQUARE_BRACKET)) { | ||
count -= 1; | ||
@@ -146,3 +161,3 @@ } | ||
let pos = start; | ||
while (pos < tokens.length && token_eq(tokens[pos], { type: TokenType.ELEMENT, value: "'" })) { | ||
while (pos < tokens.length && tokens[pos].eq(new Token(TokenType.ELEMENT, "'"))) { | ||
pos += 1; | ||
@@ -163,7 +178,5 @@ } | ||
const LEFT_COMMAND: Token = new Token(TokenType.COMMAND, '\\left'); | ||
const RIGHT_COMMAND: Token = new Token(TokenType.COMMAND, '\\right'); | ||
const LEFT_COMMAND: Token = { type: TokenType.COMMAND, value: '\\left' }; | ||
const RIGHT_COMMAND: Token = { type: TokenType.COMMAND, value: '\\right' }; | ||
function find_closing_right_command(tokens: Token[], start: number): number { | ||
@@ -177,5 +190,5 @@ let count = 1; | ||
} | ||
if (token_eq(tokens[pos], LEFT_COMMAND)) { | ||
if (tokens[pos].eq(LEFT_COMMAND)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], RIGHT_COMMAND)) { | ||
} else if (tokens[pos].eq(RIGHT_COMMAND)) { | ||
count -= 1; | ||
@@ -190,4 +203,4 @@ } | ||
const BEGIN_COMMAND: Token = { type: TokenType.COMMAND, value: '\\begin' }; | ||
const END_COMMAND: Token = { type: TokenType.COMMAND, value: '\\end' }; | ||
const BEGIN_COMMAND: Token = new Token(TokenType.COMMAND, '\\begin'); | ||
const END_COMMAND: Token = new Token(TokenType.COMMAND, '\\end'); | ||
@@ -203,5 +216,5 @@ | ||
} | ||
if (token_eq(tokens[pos], BEGIN_COMMAND)) { | ||
if (tokens[pos].eq(BEGIN_COMMAND)) { | ||
count += 1; | ||
} else if (token_eq(tokens[pos], END_COMMAND)) { | ||
} else if (tokens[pos].eq(END_COMMAND)) { | ||
count -= 1; | ||
@@ -253,3 +266,3 @@ } | ||
} | ||
token = { type: TokenType.COMMENT, value: latex.slice(pos + 1, newPos) }; | ||
token = new Token(TokenType.COMMENT, latex.slice(pos + 1, newPos)); | ||
pos = newPos; | ||
@@ -263,7 +276,7 @@ break; | ||
case '&': | ||
token = { type: TokenType.CONTROL, value: firstChar}; | ||
token = new Token(TokenType.CONTROL, firstChar); | ||
pos++; | ||
break; | ||
case '\n': | ||
token = { type: TokenType.NEWLINE, value: firstChar}; | ||
token = new Token(TokenType.NEWLINE, firstChar); | ||
pos++; | ||
@@ -273,6 +286,6 @@ break; | ||
if (pos + 1 < latex.length && latex[pos + 1] === '\n') { | ||
token = { type: TokenType.NEWLINE, value: '\n' }; | ||
token = new Token(TokenType.NEWLINE, '\n'); | ||
pos += 2; | ||
} else { | ||
token = { type: TokenType.NEWLINE, value: '\n' }; | ||
token = new Token(TokenType.NEWLINE, '\n'); | ||
pos ++; | ||
@@ -287,3 +300,3 @@ } | ||
} | ||
token = {type: TokenType.WHITESPACE, value: latex.slice(pos, newPos)}; | ||
token = new Token(TokenType.WHITESPACE, latex.slice(pos, newPos)); | ||
pos = newPos; | ||
@@ -298,8 +311,8 @@ break; | ||
if (['\\\\', '\\,'].includes(firstTwoChars)) { | ||
token = { type: TokenType.CONTROL, value: firstTwoChars }; | ||
token = new Token(TokenType.CONTROL, firstTwoChars); | ||
} else if (['\\{','\\}', '\\%', '\\$', '\\&', '\\#', '\\_'].includes(firstTwoChars)) { | ||
token = { type: TokenType.ELEMENT, value: firstTwoChars }; | ||
token = new Token(TokenType.ELEMENT, firstTwoChars); | ||
} else { | ||
const command = eat_command_name(latex, pos + 1); | ||
token = { type: TokenType.COMMAND, value: '\\' + command}; | ||
token = new Token(TokenType.COMMAND, '\\' + command); | ||
} | ||
@@ -315,9 +328,9 @@ pos += token.value.length; | ||
} | ||
token = { type: TokenType.ELEMENT, value: latex.slice(pos, newPos) } | ||
token = new Token(TokenType.ELEMENT, latex.slice(pos, newPos)); | ||
} else if (isalpha(firstChar)) { | ||
token = { type: TokenType.ELEMENT, value: firstChar }; | ||
token = new Token(TokenType.ELEMENT, firstChar); | ||
} else if ('+-*/=\'<>!.,;?()[]|'.includes(firstChar)) { | ||
token = { type: TokenType.ELEMENT, value: firstChar } | ||
token = new Token(TokenType.ELEMENT, firstChar) | ||
} else { | ||
token = { type: TokenType.UNKNOWN, value: firstChar }; | ||
token = new Token(TokenType.UNKNOWN, firstChar); | ||
} | ||
@@ -334,3 +347,3 @@ pos += token.value.length; | ||
} | ||
tokens.push({ type: TokenType.CONTROL, value: '{' }); | ||
tokens.push(new Token(TokenType.CONTROL, '{')); | ||
const posClosingBracket = find_closing_curly_bracket_char(latex, pos); | ||
@@ -344,4 +357,4 @@ pos++; | ||
} | ||
tokens.push({ type: TokenType.TEXT, value: textInside }); | ||
tokens.push({ type: TokenType.CONTROL, value: '}' }); | ||
tokens.push(new Token(TokenType.TEXT, textInside)); | ||
tokens.push(new Token(TokenType.CONTROL, '}')); | ||
pos = posClosingBracket + 1; | ||
@@ -353,7 +366,3 @@ } | ||
function token_eq(token1: Token, token2: Token) { | ||
return token1.type == token2.type && token1.value == token2.value; | ||
} | ||
export class LatexParserError extends Error { | ||
@@ -369,4 +378,4 @@ constructor(message: string) { | ||
const SUB_SYMBOL:Token = { type: TokenType.CONTROL, value: '_' }; | ||
const SUP_SYMBOL:Token = { type: TokenType.CONTROL, value: '^' }; | ||
const SUB_SYMBOL:Token = new Token(TokenType.CONTROL, '_'); | ||
const SUP_SYMBOL:Token = new Token(TokenType.CONTROL, '^'); | ||
@@ -431,7 +440,7 @@ export class LatexParser { | ||
pos += num_prime; | ||
if (pos < tokens.length && token_eq(tokens[pos], SUB_SYMBOL)) { | ||
if (pos < tokens.length && tokens[pos].eq(SUB_SYMBOL)) { | ||
[sub, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
num_prime += eat_primes(tokens, pos); | ||
pos += num_prime; | ||
if (pos < tokens.length && token_eq(tokens[pos], SUP_SYMBOL)) { | ||
if (pos < tokens.length && tokens[pos].eq(SUP_SYMBOL)) { | ||
[sup, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
@@ -442,3 +451,3 @@ if (eat_primes(tokens, pos) > 0) { | ||
} | ||
} else if (pos < tokens.length && token_eq(tokens[pos], SUP_SYMBOL)) { | ||
} else if (pos < tokens.length && tokens[pos].eq(SUP_SYMBOL)) { | ||
[sup, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
@@ -448,3 +457,3 @@ if (eat_primes(tokens, pos) > 0) { | ||
} | ||
if (pos < tokens.length && token_eq(tokens[pos], SUB_SYMBOL)) { | ||
if (pos < tokens.length && tokens[pos].eq(SUB_SYMBOL)) { | ||
[sub, pos] = this.parseNextExprWithoutSupSub(tokens, pos + 1); | ||
@@ -497,5 +506,5 @@ if (eat_primes(tokens, pos) > 0) { | ||
case TokenType.COMMAND: | ||
if (token_eq(firstToken, BEGIN_COMMAND)) { | ||
if (firstToken.eq(BEGIN_COMMAND)) { | ||
return this.parseBeginEndExpr(tokens, start); | ||
} else if (token_eq(firstToken, LEFT_COMMAND)) { | ||
} else if (firstToken.eq(LEFT_COMMAND)) { | ||
return this.parseLeftRightExpr(tokens, start); | ||
@@ -554,3 +563,3 @@ } else { | ||
case 1: { | ||
if (command === '\\sqrt' && pos < tokens.length && token_eq(tokens[pos], LEFT_SQUARE_BRACKET)) { | ||
if (command === '\\sqrt' && pos < tokens.length && tokens[pos].eq(LEFT_SQUARE_BRACKET)) { | ||
const posLeftSquareBracket = pos; | ||
@@ -566,5 +575,5 @@ const posRightSquareBracket = find_closing_square_bracket(tokens, pos); | ||
} | ||
assert(token_eq(tokens[pos], LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos].eq(LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos + 1].type === TokenType.TEXT); | ||
assert(token_eq(tokens[pos + 2], RIGHT_CURLY_BRACKET)); | ||
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET)); | ||
const text = tokens[pos + 1].value; | ||
@@ -587,3 +596,3 @@ return [{ type: 'text', content: text }, pos + 3]; | ||
parseLeftRightExpr(tokens: Token[], start: number): ParseResult { | ||
assert(token_eq(tokens[start], LEFT_COMMAND)); | ||
assert(tokens[start].eq(LEFT_COMMAND)); | ||
@@ -633,8 +642,8 @@ let pos = start + 1; | ||
parseBeginEndExpr(tokens: Token[], start: number): ParseResult { | ||
assert(token_eq(tokens[start], BEGIN_COMMAND)); | ||
assert(tokens[start].eq(BEGIN_COMMAND)); | ||
let pos = start + 1; | ||
assert(token_eq(tokens[pos], LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos].eq(LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos + 1].type === TokenType.TEXT); | ||
assert(token_eq(tokens[pos + 2], RIGHT_CURLY_BRACKET)); | ||
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET)); | ||
const envName = tokens[pos + 1].value; | ||
@@ -654,5 +663,5 @@ pos += 3; | ||
assert(token_eq(tokens[pos], LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos].eq(LEFT_CURLY_BRACKET)); | ||
assert(tokens[pos + 1].type === TokenType.TEXT); | ||
assert(token_eq(tokens[pos + 2], RIGHT_CURLY_BRACKET)); | ||
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET)); | ||
if (tokens[pos + 1].value !== envName) { | ||
@@ -706,3 +715,3 @@ throw new LatexParserError('Mismatched \\begin and \\end environments'); | ||
function passIgnoreWhitespaceBeforeScriptMark(tokens: Token[]): Token[] { | ||
const is_script_mark = (token: Token) => token_eq(token, SUB_SYMBOL) || token_eq(token, SUP_SYMBOL); | ||
const is_script_mark = (token: Token) => token.eq(SUB_SYMBOL) || token.eq(SUP_SYMBOL); | ||
let out_tokens: Token[] = []; | ||
@@ -709,0 +718,0 @@ for (let i = 0; i < tokens.length; i++) { |
@@ -12,6 +12,2 @@ export enum TokenType { | ||
export interface Token { | ||
type: TokenType; | ||
value: string; | ||
} | ||
@@ -18,0 +14,0 @@ |
@@ -283,4 +283,13 @@ import { symbolMap } from "./map"; | ||
} | ||
this.buffer = smartFloorPass(this.buffer); | ||
this.buffer = smartCeilPass(this.buffer); | ||
const smartRoundPass = function (input: string): string { | ||
// Use regex to replace all "⌊ xxx ⌉" with "round(xxx)" | ||
let res = input.replace(/⌊\s*(.*?)\s*⌉/g, "round($1)"); | ||
// Typst disallow "round()" with empty argument, so add an empty string inside if it's empty. | ||
res = res.replace(/round\(\)/g, 'round("")'); | ||
return res; | ||
} | ||
const all_passes = [smartFloorPass, smartCeilPass, smartRoundPass]; | ||
for (const pass of all_passes) { | ||
this.buffer = pass(this.buffer); | ||
} | ||
return this.buffer; | ||
@@ -356,3 +365,8 @@ } | ||
}; | ||
if (["[]", "()", "\\{\\}", "\\lfloor\\rfloor", "\\lceil\\rceil"].includes(left.content + right.content)) { | ||
if ([ | ||
"[]", "()", "\\{\\}", | ||
"\\lfloor\\rfloor", | ||
"\\lceil\\rceil", | ||
"\\lfloor\\rceil", | ||
].includes(left.content + right.content)) { | ||
return group; | ||
@@ -359,0 +373,0 @@ } |
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Unpublished package
Supply chain riskPackage version was not found on the registry. It may exist on a different registry and need to be configured to pull from that registry.
Found 1 instance in 1 package
Copyleft License
License(Experimental) Copyleft license information was found.
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found.
Found 1 instance in 1 package
Unpopular package
QualityThis package is not very popular.
Found 1 instance in 1 package
5143027
0
72
2
70
3160
2