tex2typst 0.0.19 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.js +77 -3
- package/dist/tex2typst.min.js +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
- package/src/parser.ts +79 -1
- package/src/types.ts +1 -1
- package/src/writer.ts +23 -2
package/README.md
CHANGED
|
@@ -16,12 +16,12 @@ npm install tex2typst
|
|
|
16
16
|
## Or just loading it in a web page
|
|
17
17
|
|
|
18
18
|
```html
|
|
19
|
-
<script src="https://cdn.jsdelivr.net/npm/tex2typst@0.
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/npm/tex2typst@0.1.20/dist/tex2typst.min.js"></script>
|
|
20
20
|
<!-- or -->
|
|
21
|
-
<script src="https://unpkg.com/tex2typst@0.
|
|
21
|
+
<script src="https://unpkg.com/tex2typst@0.1.20/dist/tex2typst.min.js"></script>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Replace `0.
|
|
24
|
+
Replace `0.1.20` with the latest version number in case this README is outdated.
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
package/dist/index.js
CHANGED
|
@@ -187,6 +187,10 @@ function katexNodeToTexNode(node) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
throw new KatexNodeToTexNodeError(`Unknown error type in parsed result:`, node);
|
|
190
|
+
case "comment":
|
|
191
|
+
res.type = "comment";
|
|
192
|
+
res.content = node.text;
|
|
193
|
+
break;
|
|
190
194
|
default:
|
|
191
195
|
throw new KatexNodeToTexNodeError(`Unknown node type: ${node.type}`, node);
|
|
192
196
|
break;
|
|
@@ -196,6 +200,44 @@ function katexNodeToTexNode(node) {
|
|
|
196
200
|
throw e;
|
|
197
201
|
}
|
|
198
202
|
}
|
|
203
|
+
function splitTex(tex) {
|
|
204
|
+
const lines = tex.split("\n");
|
|
205
|
+
const out_tex_list = [];
|
|
206
|
+
let current_tex = "";
|
|
207
|
+
for (let i = 0;i < lines.length; i++) {
|
|
208
|
+
const line = lines[i];
|
|
209
|
+
let index = -1;
|
|
210
|
+
while (index + 1 < line.length) {
|
|
211
|
+
index = line.indexOf("%", index + 1);
|
|
212
|
+
if (index === -1) {
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
if (index === 0 || line[index - 1] !== "\\") {
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (index !== -1) {
|
|
220
|
+
current_tex += line.substring(0, index);
|
|
221
|
+
const comment = line.substring(index);
|
|
222
|
+
out_tex_list.push(current_tex);
|
|
223
|
+
current_tex = "";
|
|
224
|
+
out_tex_list.push(comment);
|
|
225
|
+
} else {
|
|
226
|
+
current_tex += line;
|
|
227
|
+
}
|
|
228
|
+
if (i < lines.length - 1) {
|
|
229
|
+
const has_begin_command = line.includes("\\begin{");
|
|
230
|
+
const followed_by_end_command = lines[i + 1].includes("\\end{");
|
|
231
|
+
if (!has_begin_command && !followed_by_end_command) {
|
|
232
|
+
current_tex += "\\SyMbOlNeWlInE ";
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (current_tex.length > 0) {
|
|
237
|
+
out_tex_list.push(current_tex);
|
|
238
|
+
}
|
|
239
|
+
return out_tex_list;
|
|
240
|
+
}
|
|
199
241
|
function parseTex(tex, customTexMacros) {
|
|
200
242
|
const macros = {
|
|
201
243
|
"\\mod": "\\operatorname{SyMb01-mod}",
|
|
@@ -213,6 +255,7 @@ function parseTex(tex, customTexMacros) {
|
|
|
213
255
|
"\\slash": "\\operatorname{SyMb01-slash}",
|
|
214
256
|
"\\LaTeX": "\\operatorname{SyMb01-LaTeX}",
|
|
215
257
|
"\\TeX": "\\operatorname{SyMb01-TeX}",
|
|
258
|
+
"\\SyMbOlNeWlInE": "\\operatorname{SyMb01-newline}",
|
|
216
259
|
...customTexMacros
|
|
217
260
|
};
|
|
218
261
|
const options = {
|
|
@@ -221,7 +264,21 @@ function parseTex(tex, customTexMacros) {
|
|
|
221
264
|
strict: "ignore",
|
|
222
265
|
throwOnError: false
|
|
223
266
|
};
|
|
224
|
-
|
|
267
|
+
const tex_list = splitTex(tex);
|
|
268
|
+
let treeArray = [];
|
|
269
|
+
for (const tex_item of tex_list) {
|
|
270
|
+
if (tex_item.startsWith("%")) {
|
|
271
|
+
const tex_node = {
|
|
272
|
+
type: "comment",
|
|
273
|
+
mode: "math",
|
|
274
|
+
text: tex_item.substring(1)
|
|
275
|
+
};
|
|
276
|
+
treeArray.push(tex_node);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const trees = generateParseTree(tex_item, options);
|
|
280
|
+
treeArray = treeArray.concat(trees);
|
|
281
|
+
}
|
|
225
282
|
let t = {
|
|
226
283
|
type: "ordgroup",
|
|
227
284
|
mode: "math",
|
|
@@ -514,7 +571,9 @@ function convertToken(token) {
|
|
|
514
571
|
if (/^[a-zA-Z0-9]$/.test(token)) {
|
|
515
572
|
return token;
|
|
516
573
|
} else if (token === "\\\\") {
|
|
517
|
-
return "
|
|
574
|
+
return "\\";
|
|
575
|
+
} else if (token == "/") {
|
|
576
|
+
return "\\/";
|
|
518
577
|
} else if (["\\$", "\\#", "\\&", "\\_"].includes(token)) {
|
|
519
578
|
return token;
|
|
520
579
|
} else if (token.startsWith("\\")) {
|
|
@@ -567,6 +626,7 @@ class TypstWriter {
|
|
|
567
626
|
no_need_space ||= str === "'";
|
|
568
627
|
no_need_space ||= /[0-9]$/.test(this.buffer) && /^[0-9]/.test(str);
|
|
569
628
|
no_need_space ||= /[\(\[{]\s*(-|\+)$/.test(this.buffer) || this.buffer === "-" || this.buffer === "+";
|
|
629
|
+
no_need_space ||= str.startsWith("\n");
|
|
570
630
|
no_need_space ||= this.buffer === "";
|
|
571
631
|
no_need_space ||= /[\s"_^{\(]$/.test(this.buffer);
|
|
572
632
|
if (!no_need_space) {
|
|
@@ -697,7 +757,12 @@ class TypstWriter {
|
|
|
697
757
|
if (this.preferTypstIntrinsic && TYPST_INTRINSIC_SYMBOLS.includes(text)) {
|
|
698
758
|
this.queue.push({ type: "symbol", content: text });
|
|
699
759
|
} else if (text.startsWith("SyMb01-")) {
|
|
700
|
-
|
|
760
|
+
const special_symbol = text.substring(7);
|
|
761
|
+
if (special_symbol === "newline") {
|
|
762
|
+
this.queue.push({ type: "newline", content: "\n" });
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
this.queue.push({ type: "symbol", content: "\\" + special_symbol });
|
|
701
766
|
} else {
|
|
702
767
|
this.queue.push({ type: "symbol", content: "op" });
|
|
703
768
|
this.queue.push({ type: "atom", content: "(" });
|
|
@@ -734,6 +799,7 @@ class TypstWriter {
|
|
|
734
799
|
matrix.forEach((row, i) => {
|
|
735
800
|
row.forEach((cell, j) => {
|
|
736
801
|
if (cell.type === "ordgroup" && cell.args.length === 0) {
|
|
802
|
+
this.queue.push({ type: "atom", content: "," });
|
|
737
803
|
return;
|
|
738
804
|
}
|
|
739
805
|
this.append(cell);
|
|
@@ -754,6 +820,8 @@ class TypstWriter {
|
|
|
754
820
|
} else {
|
|
755
821
|
throw new TypstWriterError(`Unknown macro: ${node.content}`, node);
|
|
756
822
|
}
|
|
823
|
+
} else if (node.type === "comment") {
|
|
824
|
+
this.queue.push({ type: "comment", content: node.content });
|
|
757
825
|
} else {
|
|
758
826
|
throw new TypstWriterError(`Unimplemented node type to append: ${node.type}`, node);
|
|
759
827
|
}
|
|
@@ -775,6 +843,12 @@ class TypstWriter {
|
|
|
775
843
|
this.needSpaceAfterSingleItemScript = true;
|
|
776
844
|
str = "";
|
|
777
845
|
break;
|
|
846
|
+
case "comment":
|
|
847
|
+
str = `//${node.content}`;
|
|
848
|
+
break;
|
|
849
|
+
case "newline":
|
|
850
|
+
str = "\n";
|
|
851
|
+
break;
|
|
778
852
|
default:
|
|
779
853
|
throw new TypstWriterError(`Unexpected node type to stringify: ${node.type}`, node);
|
|
780
854
|
}
|