tex2typst 0.3.18 → 0.3.19
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 +113 -105
- package/dist/tex-parser.d.ts +0 -1
- package/dist/tex-tokenizer.d.ts +4 -0
- package/dist/tex2typst.min.js +10 -10
- package/dist/types.d.ts +1 -2
- package/dist/typst-parser.d.ts +0 -1
- package/dist/typst-tokenizer.d.ts +2 -0
- package/package.json +1 -1
- package/src/convert.ts +6 -9
- package/src/index.ts +0 -1
- package/src/tex-parser.ts +5 -138
- package/src/tex-tokenizer.ts +138 -0
- package/src/types.ts +1 -2
- package/src/typst-parser.ts +1 -74
- package/src/typst-tokenizer.ts +76 -0
- package/src/typst-writer.ts +22 -7
package/dist/index.js
CHANGED
|
@@ -1633,8 +1633,8 @@ var JSLex = class {
|
|
|
1633
1633
|
}
|
|
1634
1634
|
};
|
|
1635
1635
|
|
|
1636
|
-
// src/tex-
|
|
1637
|
-
var
|
|
1636
|
+
// src/tex-tokenizer.ts
|
|
1637
|
+
var TEX_UNARY_COMMANDS = [
|
|
1638
1638
|
"sqrt",
|
|
1639
1639
|
"text",
|
|
1640
1640
|
"bar",
|
|
@@ -1667,7 +1667,7 @@ var UNARY_COMMANDS = [
|
|
|
1667
1667
|
"overrightarrow",
|
|
1668
1668
|
"hspace"
|
|
1669
1669
|
];
|
|
1670
|
-
var
|
|
1670
|
+
var TEX_BINARY_COMMANDS = [
|
|
1671
1671
|
"frac",
|
|
1672
1672
|
"tfrac",
|
|
1673
1673
|
"binom",
|
|
@@ -1677,81 +1677,6 @@ var BINARY_COMMANDS = [
|
|
|
1677
1677
|
"overset",
|
|
1678
1678
|
"underset"
|
|
1679
1679
|
];
|
|
1680
|
-
var IGNORED_COMMANDS = [
|
|
1681
|
-
"bigl",
|
|
1682
|
-
"bigr",
|
|
1683
|
-
"biggl",
|
|
1684
|
-
"biggr",
|
|
1685
|
-
"Bigl",
|
|
1686
|
-
"Bigr",
|
|
1687
|
-
"Biggl",
|
|
1688
|
-
"Biggr"
|
|
1689
|
-
];
|
|
1690
|
-
var EMPTY_NODE = new TexNode("empty", "");
|
|
1691
|
-
function get_command_param_num(command) {
|
|
1692
|
-
if (UNARY_COMMANDS.includes(command)) {
|
|
1693
|
-
return 1;
|
|
1694
|
-
} else if (BINARY_COMMANDS.includes(command)) {
|
|
1695
|
-
return 2;
|
|
1696
|
-
} else {
|
|
1697
|
-
return 0;
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
var LEFT_CURLY_BRACKET = new TexToken(6 /* CONTROL */, "{");
|
|
1701
|
-
var RIGHT_CURLY_BRACKET = new TexToken(6 /* CONTROL */, "}");
|
|
1702
|
-
var LEFT_SQUARE_BRACKET = new TexToken(0 /* ELEMENT */, "[");
|
|
1703
|
-
var RIGHT_SQUARE_BRACKET = new TexToken(0 /* ELEMENT */, "]");
|
|
1704
|
-
function eat_whitespaces(tokens, start) {
|
|
1705
|
-
let pos = start;
|
|
1706
|
-
while (pos < tokens.length && [4 /* SPACE */, 5 /* NEWLINE */].includes(tokens[pos].type)) {
|
|
1707
|
-
pos++;
|
|
1708
|
-
}
|
|
1709
|
-
return tokens.slice(start, pos);
|
|
1710
|
-
}
|
|
1711
|
-
function eat_parenthesis(tokens, start) {
|
|
1712
|
-
const firstToken = tokens[start];
|
|
1713
|
-
if (firstToken.type === 0 /* ELEMENT */ && ["(", ")", "[", "]", "|", "\\{", "\\}", ".", "\\|"].includes(firstToken.value)) {
|
|
1714
|
-
return firstToken;
|
|
1715
|
-
} else if (firstToken.type === 1 /* COMMAND */ && ["lfloor", "rfloor", "lceil", "rceil", "langle", "rangle"].includes(firstToken.value.slice(1))) {
|
|
1716
|
-
return firstToken;
|
|
1717
|
-
} else {
|
|
1718
|
-
return null;
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
function eat_primes(tokens, start) {
|
|
1722
|
-
let pos = start;
|
|
1723
|
-
while (pos < tokens.length && tokens[pos].eq(new TexToken(0 /* ELEMENT */, "'"))) {
|
|
1724
|
-
pos += 1;
|
|
1725
|
-
}
|
|
1726
|
-
return pos - start;
|
|
1727
|
-
}
|
|
1728
|
-
function find_closing_match(tokens, start, leftToken, rightToken) {
|
|
1729
|
-
assert(tokens[start].eq(leftToken));
|
|
1730
|
-
let count = 1;
|
|
1731
|
-
let pos = start + 1;
|
|
1732
|
-
while (count > 0) {
|
|
1733
|
-
if (pos >= tokens.length) {
|
|
1734
|
-
return -1;
|
|
1735
|
-
}
|
|
1736
|
-
if (tokens[pos].eq(leftToken)) {
|
|
1737
|
-
count += 1;
|
|
1738
|
-
} else if (tokens[pos].eq(rightToken)) {
|
|
1739
|
-
count -= 1;
|
|
1740
|
-
}
|
|
1741
|
-
pos += 1;
|
|
1742
|
-
}
|
|
1743
|
-
return pos - 1;
|
|
1744
|
-
}
|
|
1745
|
-
var LEFT_COMMAND = new TexToken(1 /* COMMAND */, "\\left");
|
|
1746
|
-
var RIGHT_COMMAND = new TexToken(1 /* COMMAND */, "\\right");
|
|
1747
|
-
function find_closing_right_command(tokens, start) {
|
|
1748
|
-
return find_closing_match(tokens, start, LEFT_COMMAND, RIGHT_COMMAND);
|
|
1749
|
-
}
|
|
1750
|
-
var BEGIN_COMMAND = new TexToken(1 /* COMMAND */, "\\begin");
|
|
1751
|
-
var END_COMMAND = new TexToken(1 /* COMMAND */, "\\end");
|
|
1752
|
-
function find_closing_end_command(tokens, start) {
|
|
1753
|
-
return find_closing_match(tokens, start, BEGIN_COMMAND, END_COMMAND);
|
|
1754
|
-
}
|
|
1755
1680
|
function unescape(str) {
|
|
1756
1681
|
const chars = ["{", "}", "\\", "$", "&", "#", "_", "%"];
|
|
1757
1682
|
for (const char of chars) {
|
|
@@ -1780,13 +1705,14 @@ var rules_map = /* @__PURE__ */ new Map([
|
|
|
1780
1705
|
[String.raw`\r?\n`, (_s) => new TexToken(5 /* NEWLINE */, "\n")],
|
|
1781
1706
|
[String.raw`\s+`, (s) => new TexToken(4 /* SPACE */, s.text())],
|
|
1782
1707
|
[String.raw`\\[{}%$&#_|]`, (s) => new TexToken(0 /* ELEMENT */, s.text())],
|
|
1708
|
+
// e.g. match `\frac13`, `\frac1 b`, `\frac a b`
|
|
1783
1709
|
[String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`, (s) => {
|
|
1784
1710
|
const text = s.text();
|
|
1785
1711
|
const regex = RegExp(String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`);
|
|
1786
1712
|
const match = text.match(regex);
|
|
1787
1713
|
assert(match !== null);
|
|
1788
1714
|
const command = match[1];
|
|
1789
|
-
if (
|
|
1715
|
+
if (TEX_BINARY_COMMANDS.includes(command.substring(1))) {
|
|
1790
1716
|
const arg1 = match[2].trimStart();
|
|
1791
1717
|
const arg2 = match[3];
|
|
1792
1718
|
return [
|
|
@@ -1799,13 +1725,14 @@ var rules_map = /* @__PURE__ */ new Map([
|
|
|
1799
1725
|
return [];
|
|
1800
1726
|
}
|
|
1801
1727
|
}],
|
|
1728
|
+
// e.g. match `\sqrt3`, `\sqrt a`
|
|
1802
1729
|
[String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])`, (s) => {
|
|
1803
1730
|
const text = s.text();
|
|
1804
1731
|
const regex = RegExp(String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])`);
|
|
1805
1732
|
const match = text.match(regex);
|
|
1806
1733
|
assert(match !== null);
|
|
1807
1734
|
const command = match[1];
|
|
1808
|
-
if (
|
|
1735
|
+
if (TEX_UNARY_COMMANDS.includes(command.substring(1))) {
|
|
1809
1736
|
const arg1 = match[2].trimStart();
|
|
1810
1737
|
return [
|
|
1811
1738
|
new TexToken(1 /* COMMAND */, command),
|
|
@@ -1835,6 +1762,83 @@ function tokenize_tex(input) {
|
|
|
1835
1762
|
const lexer = new JSLex(spec);
|
|
1836
1763
|
return lexer.collect(input);
|
|
1837
1764
|
}
|
|
1765
|
+
|
|
1766
|
+
// src/tex-parser.ts
|
|
1767
|
+
var IGNORED_COMMANDS = [
|
|
1768
|
+
"bigl",
|
|
1769
|
+
"bigr",
|
|
1770
|
+
"biggl",
|
|
1771
|
+
"biggr",
|
|
1772
|
+
"Bigl",
|
|
1773
|
+
"Bigr",
|
|
1774
|
+
"Biggl",
|
|
1775
|
+
"Biggr"
|
|
1776
|
+
];
|
|
1777
|
+
var EMPTY_NODE = new TexNode("empty", "");
|
|
1778
|
+
function get_command_param_num(command) {
|
|
1779
|
+
if (TEX_UNARY_COMMANDS.includes(command)) {
|
|
1780
|
+
return 1;
|
|
1781
|
+
} else if (TEX_BINARY_COMMANDS.includes(command)) {
|
|
1782
|
+
return 2;
|
|
1783
|
+
} else {
|
|
1784
|
+
return 0;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
var LEFT_CURLY_BRACKET = new TexToken(6 /* CONTROL */, "{");
|
|
1788
|
+
var RIGHT_CURLY_BRACKET = new TexToken(6 /* CONTROL */, "}");
|
|
1789
|
+
var LEFT_SQUARE_BRACKET = new TexToken(0 /* ELEMENT */, "[");
|
|
1790
|
+
var RIGHT_SQUARE_BRACKET = new TexToken(0 /* ELEMENT */, "]");
|
|
1791
|
+
function eat_whitespaces(tokens, start) {
|
|
1792
|
+
let pos = start;
|
|
1793
|
+
while (pos < tokens.length && [4 /* SPACE */, 5 /* NEWLINE */].includes(tokens[pos].type)) {
|
|
1794
|
+
pos++;
|
|
1795
|
+
}
|
|
1796
|
+
return tokens.slice(start, pos);
|
|
1797
|
+
}
|
|
1798
|
+
function eat_parenthesis(tokens, start) {
|
|
1799
|
+
const firstToken = tokens[start];
|
|
1800
|
+
if (firstToken.type === 0 /* ELEMENT */ && ["(", ")", "[", "]", "|", "\\{", "\\}", ".", "\\|"].includes(firstToken.value)) {
|
|
1801
|
+
return firstToken;
|
|
1802
|
+
} else if (firstToken.type === 1 /* COMMAND */ && ["lfloor", "rfloor", "lceil", "rceil", "langle", "rangle"].includes(firstToken.value.slice(1))) {
|
|
1803
|
+
return firstToken;
|
|
1804
|
+
} else {
|
|
1805
|
+
return null;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
function eat_primes(tokens, start) {
|
|
1809
|
+
let pos = start;
|
|
1810
|
+
while (pos < tokens.length && tokens[pos].eq(new TexToken(0 /* ELEMENT */, "'"))) {
|
|
1811
|
+
pos += 1;
|
|
1812
|
+
}
|
|
1813
|
+
return pos - start;
|
|
1814
|
+
}
|
|
1815
|
+
function find_closing_match(tokens, start, leftToken, rightToken) {
|
|
1816
|
+
assert(tokens[start].eq(leftToken));
|
|
1817
|
+
let count = 1;
|
|
1818
|
+
let pos = start + 1;
|
|
1819
|
+
while (count > 0) {
|
|
1820
|
+
if (pos >= tokens.length) {
|
|
1821
|
+
return -1;
|
|
1822
|
+
}
|
|
1823
|
+
if (tokens[pos].eq(leftToken)) {
|
|
1824
|
+
count += 1;
|
|
1825
|
+
} else if (tokens[pos].eq(rightToken)) {
|
|
1826
|
+
count -= 1;
|
|
1827
|
+
}
|
|
1828
|
+
pos += 1;
|
|
1829
|
+
}
|
|
1830
|
+
return pos - 1;
|
|
1831
|
+
}
|
|
1832
|
+
var LEFT_COMMAND = new TexToken(1 /* COMMAND */, "\\left");
|
|
1833
|
+
var RIGHT_COMMAND = new TexToken(1 /* COMMAND */, "\\right");
|
|
1834
|
+
function find_closing_right_command(tokens, start) {
|
|
1835
|
+
return find_closing_match(tokens, start, LEFT_COMMAND, RIGHT_COMMAND);
|
|
1836
|
+
}
|
|
1837
|
+
var BEGIN_COMMAND = new TexToken(1 /* COMMAND */, "\\begin");
|
|
1838
|
+
var END_COMMAND = new TexToken(1 /* COMMAND */, "\\end");
|
|
1839
|
+
function find_closing_end_command(tokens, start) {
|
|
1840
|
+
return find_closing_match(tokens, start, BEGIN_COMMAND, END_COMMAND);
|
|
1841
|
+
}
|
|
1838
1842
|
var LatexParserError = class extends Error {
|
|
1839
1843
|
constructor(message) {
|
|
1840
1844
|
super(message);
|
|
@@ -2274,6 +2278,7 @@ var TYPST_LEFT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, "(");
|
|
|
2274
2278
|
var TYPST_RIGHT_PARENTHESIS = new TypstToken(2 /* ELEMENT */, ")");
|
|
2275
2279
|
var TYPST_COMMA = new TypstToken(2 /* ELEMENT */, ",");
|
|
2276
2280
|
var TYPST_NEWLINE = new TypstToken(1 /* SYMBOL */, "\n");
|
|
2281
|
+
var SOFT_SPACE = new TypstToken(6 /* CONTROL */, " ");
|
|
2277
2282
|
function typst_primitive_to_string(value) {
|
|
2278
2283
|
switch (typeof value) {
|
|
2279
2284
|
case "string":
|
|
@@ -2397,7 +2402,7 @@ var TypstWriter = class {
|
|
|
2397
2402
|
trailing_space_needed = this.appendWithBracketsIfNeeded(sup);
|
|
2398
2403
|
}
|
|
2399
2404
|
if (trailing_space_needed) {
|
|
2400
|
-
this.queue.push(
|
|
2405
|
+
this.queue.push(SOFT_SPACE);
|
|
2401
2406
|
}
|
|
2402
2407
|
break;
|
|
2403
2408
|
}
|
|
@@ -2428,7 +2433,12 @@ var TypstWriter = class {
|
|
|
2428
2433
|
}
|
|
2429
2434
|
case "fraction": {
|
|
2430
2435
|
const [numerator, denominator] = node.args;
|
|
2431
|
-
this.
|
|
2436
|
+
const pos = this.queue.length;
|
|
2437
|
+
const no_wrap = this.appendWithBracketsIfNeeded(numerator);
|
|
2438
|
+
const wrapped = !no_wrap;
|
|
2439
|
+
if (wrapped) {
|
|
2440
|
+
this.queue.splice(pos, 0, SOFT_SPACE);
|
|
2441
|
+
}
|
|
2432
2442
|
this.queue.push(new TypstToken(2 /* ELEMENT */, "/"));
|
|
2433
2443
|
this.appendWithBracketsIfNeeded(denominator);
|
|
2434
2444
|
break;
|
|
@@ -2537,17 +2547,17 @@ var TypstWriter = class {
|
|
|
2537
2547
|
return !need_to_wrap;
|
|
2538
2548
|
}
|
|
2539
2549
|
flushQueue() {
|
|
2540
|
-
const
|
|
2550
|
+
const dummy_token = new TypstToken(1 /* SYMBOL */, "");
|
|
2541
2551
|
for (let i = 0; i < this.queue.length; i++) {
|
|
2542
2552
|
let token = this.queue[i];
|
|
2543
2553
|
if (token.eq(SOFT_SPACE)) {
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
this.queue[i].value = "";
|
|
2554
|
+
const to_delete = i === 0 || i === this.queue.length - 1 || this.queue[i - 1].isOneOf([TYPST_NEWLINE]) || this.queue[i + 1].isOneOf([TYPST_RIGHT_PARENTHESIS, TYPST_COMMA, TYPST_NEWLINE]);
|
|
2555
|
+
if (to_delete) {
|
|
2556
|
+
this.queue[i] = dummy_token;
|
|
2548
2557
|
}
|
|
2549
2558
|
}
|
|
2550
2559
|
}
|
|
2560
|
+
this.queue = this.queue.filter((token) => !token.eq(dummy_token));
|
|
2551
2561
|
this.queue.forEach((token) => {
|
|
2552
2562
|
this.writeBuffer(token);
|
|
2553
2563
|
});
|
|
@@ -2813,16 +2823,13 @@ function convert_tex_node_to_typst(node, options = {}) {
|
|
|
2813
2823
|
);
|
|
2814
2824
|
}
|
|
2815
2825
|
if (node.content === "\\operatorname") {
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
"funcCall",
|
|
2822
|
-
"op",
|
|
2823
|
-
[arg0]
|
|
2824
|
-
);
|
|
2826
|
+
if (options.optimize) {
|
|
2827
|
+
const text = arg0.content;
|
|
2828
|
+
if (TYPST_INTRINSIC_SYMBOLS.includes(text)) {
|
|
2829
|
+
return new TypstNode("symbol", text);
|
|
2830
|
+
}
|
|
2825
2831
|
}
|
|
2832
|
+
return new TypstNode("funcCall", "op", [arg0]);
|
|
2826
2833
|
}
|
|
2827
2834
|
if (node.content === "\\hspace") {
|
|
2828
2835
|
const text = arg0.content;
|
|
@@ -3191,15 +3198,8 @@ function convert_typst_node_to_tex(node) {
|
|
|
3191
3198
|
}
|
|
3192
3199
|
}
|
|
3193
3200
|
|
|
3194
|
-
// src/typst-
|
|
3201
|
+
// src/typst-tokenizer.ts
|
|
3195
3202
|
var TYPST_SHORTHANDS = Array.from(reverseShorthandMap.keys());
|
|
3196
|
-
function eat_primes2(tokens, start) {
|
|
3197
|
-
let pos = start;
|
|
3198
|
-
while (pos < tokens.length && tokens[pos].eq(new TypstToken(2 /* ELEMENT */, "'"))) {
|
|
3199
|
-
pos += 1;
|
|
3200
|
-
}
|
|
3201
|
-
return pos - start;
|
|
3202
|
-
}
|
|
3203
3203
|
function generate_regex_for_shorthands() {
|
|
3204
3204
|
const regex_list = TYPST_SHORTHANDS.map((s) => {
|
|
3205
3205
|
s = s.replaceAll("|", "\\|");
|
|
@@ -3263,6 +3263,15 @@ function tokenize_typst(input) {
|
|
|
3263
3263
|
const lexer = new JSLex(spec2);
|
|
3264
3264
|
return lexer.collect(input);
|
|
3265
3265
|
}
|
|
3266
|
+
|
|
3267
|
+
// src/typst-parser.ts
|
|
3268
|
+
function eat_primes2(tokens, start) {
|
|
3269
|
+
let pos = start;
|
|
3270
|
+
while (pos < tokens.length && tokens[pos].eq(new TypstToken(2 /* ELEMENT */, "'"))) {
|
|
3271
|
+
pos += 1;
|
|
3272
|
+
}
|
|
3273
|
+
return pos - start;
|
|
3274
|
+
}
|
|
3266
3275
|
function _find_closing_match(tokens, start, leftBrackets, rightBrackets) {
|
|
3267
3276
|
assert(tokens[start].isOneOf(leftBrackets));
|
|
3268
3277
|
let count = 1;
|
|
@@ -3733,7 +3742,6 @@ var TexWriter = class {
|
|
|
3733
3742
|
function tex2typst(tex, options) {
|
|
3734
3743
|
const opt = {
|
|
3735
3744
|
nonStrict: true,
|
|
3736
|
-
preferTypstIntrinsic: true,
|
|
3737
3745
|
preferShorthands: true,
|
|
3738
3746
|
keepSpaces: false,
|
|
3739
3747
|
fracToSlash: true,
|
package/dist/tex-parser.d.ts
CHANGED