tex2typst 0.3.27-beta.1 → 0.3.27
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 +1 -1
- package/dist/index.d.ts +23 -24
- package/dist/index.js +338 -314
- package/dist/parser.js +23 -0
- package/dist/tex2typst.min.js +12 -12
- package/package.json +1 -1
- package/src/convert.ts +53 -2
- package/src/exposed-types.ts +23 -24
- package/src/index.ts +7 -3
- package/src/jslex.ts +1 -1
- package/src/tex-tokenizer.ts +1 -0
- package/src/tex2typst.ts +2 -4
- package/src/typst-parser.ts +9 -10
- package/src/typst-types.ts +484 -230
- package/src/typst-writer.ts +28 -274
- package/tests/cheat-sheet.test.ts +42 -0
- package/tests/cheat-sheet.toml +304 -0
- package/tests/example.ts +15 -0
- package/tests/general-symbols.test.ts +22 -0
- package/tests/general-symbols.toml +755 -0
- package/tests/integration-tex2typst.yaml +89 -0
- package/tests/struct-bidirection.yaml +179 -0
- package/tests/struct-tex2typst.yaml +443 -0
- package/tests/struct-typst2tex.yaml +412 -0
- package/tests/symbol.yml +123 -0
- package/tests/test-common.ts +26 -0
- package/tests/tex-parser.test.ts +57 -0
- package/tests/tex-to-typst.test.ts +143 -0
- package/tests/typst-parser.test.ts +134 -0
- package/tests/typst-to-tex.test.ts +76 -0
- package/tsconfig.json +4 -4
package/src/convert.ts
CHANGED
|
@@ -188,6 +188,41 @@ function convert_tex_array_align_literal(alignLiteral: string): TypstNamedParams
|
|
|
188
188
|
return np;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
const TYPST_LEFT_PARENTHESIS: TypstToken = new TypstToken(TypstTokenType.ELEMENT, '(');
|
|
192
|
+
const TYPST_RIGHT_PARENTHESIS: TypstToken = new TypstToken(TypstTokenType.ELEMENT, ')');
|
|
193
|
+
|
|
194
|
+
function is_delimiter(c: TypstNode): boolean {
|
|
195
|
+
return c.head.type === TypstTokenType.ELEMENT && ['(', ')', '[', ']', '{', '}', '|', '⌊', '⌋', '⌈', '⌉'].includes(c.head.value);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function appendWithBracketsIfNeeded(node: TypstNode): TypstNode {
|
|
199
|
+
let need_to_wrap = ['group', 'supsub', 'matrixLike', 'fraction','empty'].includes(node.type);
|
|
200
|
+
|
|
201
|
+
if (node.type === 'group') {
|
|
202
|
+
const group = node as TypstGroup;
|
|
203
|
+
if (group.items.length === 0) {
|
|
204
|
+
// e.g. TeX `P_{}` converts to Typst `P_()`
|
|
205
|
+
need_to_wrap = true;
|
|
206
|
+
} else {
|
|
207
|
+
const first = group.items[0];
|
|
208
|
+
const last = group.items[group.items.length - 1];
|
|
209
|
+
if (is_delimiter(first) && is_delimiter(last)) {
|
|
210
|
+
need_to_wrap = false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (need_to_wrap) {
|
|
216
|
+
return new TypstLeftright(null, {
|
|
217
|
+
left: TYPST_LEFT_PARENTHESIS,
|
|
218
|
+
right: TYPST_RIGHT_PARENTHESIS,
|
|
219
|
+
body: node,
|
|
220
|
+
|
|
221
|
+
});
|
|
222
|
+
} else {
|
|
223
|
+
return node;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
191
226
|
|
|
192
227
|
export function convert_tex_node_to_typst(abstractNode: TexNode, options: Tex2TypstOptions = {}): TypstNode {
|
|
193
228
|
switch (abstractNode.type) {
|
|
@@ -234,6 +269,14 @@ export function convert_tex_node_to_typst(abstractNode: TexNode, options: Tex2Ty
|
|
|
234
269
|
sub: sub? convert_tex_node_to_typst(sub, options) : null,
|
|
235
270
|
};
|
|
236
271
|
|
|
272
|
+
data.base = appendWithBracketsIfNeeded(data.base);
|
|
273
|
+
if (data.sup) {
|
|
274
|
+
data.sup = appendWithBracketsIfNeeded(data.sup);
|
|
275
|
+
}
|
|
276
|
+
if (data.sub) {
|
|
277
|
+
data.sub = appendWithBracketsIfNeeded(data.sub);
|
|
278
|
+
}
|
|
279
|
+
|
|
237
280
|
return new TypstSupsub(data);
|
|
238
281
|
}
|
|
239
282
|
case 'leftright': {
|
|
@@ -348,12 +391,20 @@ export function convert_tex_node_to_typst(abstractNode: TexNode, options: Tex2Ty
|
|
|
348
391
|
return res;
|
|
349
392
|
}
|
|
350
393
|
|
|
351
|
-
// \substack{a \\ b} ->
|
|
394
|
+
// \substack{a \\ b} -> a \ b
|
|
352
395
|
// as in translation from \sum_{\substack{a \\ b}} to sum_(a \ b)
|
|
353
396
|
if (node.head.value === '\\substack') {
|
|
354
397
|
return arg0;
|
|
355
398
|
}
|
|
356
399
|
|
|
400
|
+
// \set{a, b, c} -> {a, b, c}
|
|
401
|
+
if (node.head.value === '\\set') {
|
|
402
|
+
return new TypstLeftright(
|
|
403
|
+
null,
|
|
404
|
+
{ body: arg0, left: TypstToken.LEFT_BRACE, right: TypstToken.RIGHT_BRACE }
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
357
408
|
if (node.head.value === '\\overset') {
|
|
358
409
|
return convert_overset(node, options);
|
|
359
410
|
}
|
|
@@ -364,7 +415,7 @@ export function convert_tex_node_to_typst(abstractNode: TexNode, options: Tex2Ty
|
|
|
364
415
|
// \frac{a}{b} -> a / b
|
|
365
416
|
if (node.head.value === '\\frac') {
|
|
366
417
|
if (options.fracToSlash) {
|
|
367
|
-
return new TypstFraction(node.args.map((n) => convert_tex_node_to_typst(n, options)));
|
|
418
|
+
return new TypstFraction(node.args.map((n) => convert_tex_node_to_typst(n, options)).map(appendWithBracketsIfNeeded));
|
|
368
419
|
}
|
|
369
420
|
}
|
|
370
421
|
|
package/src/exposed-types.ts
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* ATTENTION:
|
|
4
|
-
* Don't use any options except those explicitly documented in
|
|
5
|
-
* https://github.com/qwinsi/tex2typst/blob/main/docs/api-reference.md
|
|
6
|
-
* Any undocumented options may be not working at present or break in the future!
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export declare function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export declare const
|
|
24
|
-
export declare const shorthandMap: Map<string, string>;
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* ATTENTION:
|
|
4
|
+
* Don't use any options except those explicitly documented in
|
|
5
|
+
* https://github.com/qwinsi/tex2typst/blob/main/docs/api-reference.md
|
|
6
|
+
* Any undocumented options may be not working at present or break in the future!
|
|
7
|
+
*/
|
|
8
|
+
export interface Tex2TypstOptions {
|
|
9
|
+
nonStrict?: boolean; /** default is true */
|
|
10
|
+
preferShorthands?: boolean; /** default is true */
|
|
11
|
+
keepSpaces?: boolean; /** default is false */
|
|
12
|
+
fracToSlash?: boolean; /** default is true */
|
|
13
|
+
inftyToOo?: boolean; /** default is false */
|
|
14
|
+
optimize?: boolean; /** default is true */
|
|
15
|
+
nonAsciiWrapper?: string; /** default is "" */
|
|
16
|
+
customTexMacros?: { [key: string]: string; };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export declare function tex2typst(tex: string, options?: Tex2TypstOptions): string;
|
|
20
|
+
export declare function typst2tex(typst: string): string;
|
|
21
|
+
|
|
22
|
+
export declare const symbolMap: Map<string, string>;
|
|
23
|
+
export declare const shorthandMap: Map<string, string>;
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parseTex } from "./tex-parser";
|
|
2
2
|
import type { Tex2TypstOptions } from "./exposed-types";
|
|
3
|
-
import { TypstWriter
|
|
3
|
+
import { TypstWriter } from "./typst-writer";
|
|
4
|
+
import { type TypstWriterOptions } from "./typst-types";
|
|
4
5
|
import { convert_tex_node_to_typst, convert_typst_node_to_tex } from "./convert";
|
|
5
6
|
import { symbolMap } from "./map";
|
|
6
7
|
import { parseTypst } from "./typst-parser";
|
|
@@ -21,9 +22,12 @@ export function tex2typst(tex: string, options?: Tex2TypstOptions): string {
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
if(options !== undefined) {
|
|
25
|
+
if (typeof options !== 'object') {
|
|
26
|
+
throw new Error("options must be an object");
|
|
27
|
+
}
|
|
24
28
|
for (const key in opt) {
|
|
25
|
-
if (
|
|
26
|
-
opt[key] = options[key];
|
|
29
|
+
if (key in options) {
|
|
30
|
+
opt[key as keyof Tex2TypstOptions] = options[key as keyof Tex2TypstOptions] as any;
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
}
|
package/src/jslex.ts
CHANGED
package/src/tex-tokenizer.ts
CHANGED
package/src/tex2typst.ts
CHANGED
package/src/typst-parser.ts
CHANGED
|
@@ -53,8 +53,8 @@ function find_closing_delim(tokens: TypstToken[], start: number): number {
|
|
|
53
53
|
return _find_closing_match(
|
|
54
54
|
tokens,
|
|
55
55
|
start,
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
TypstToken.LEFT_DELIMITERS,
|
|
57
|
+
TypstToken.RIGHT_DELIMITERS
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -218,7 +218,6 @@ const LEFT_BRACKET: TypstToken = new TypstToken(TypstTokenType.ELEMENT, '[');
|
|
|
218
218
|
const RIGHT_BRACKET: TypstToken = new TypstToken(TypstTokenType.ELEMENT, ']');
|
|
219
219
|
const LEFT_CURLY_BRACKET: TypstToken = new TypstToken(TypstTokenType.ELEMENT, '{');
|
|
220
220
|
const RIGHT_CURLY_BRACKET: TypstToken = new TypstToken(TypstTokenType.ELEMENT, '}');
|
|
221
|
-
const VERTICAL_BAR = new TypstToken(TypstTokenType.ELEMENT, '|');
|
|
222
221
|
const COMMA = new TypstToken(TypstTokenType.ELEMENT, ',');
|
|
223
222
|
const SEMICOLON = new TypstToken(TypstTokenType.ELEMENT, ';');
|
|
224
223
|
const SINGLE_SPACE = new TypstToken(TypstTokenType.SPACE, ' ');
|
|
@@ -373,20 +372,20 @@ export class TypstParser {
|
|
|
373
372
|
// start: the position of the left parentheses
|
|
374
373
|
parseLrArguments(tokens: TypstToken[], start: number): [TypstNode, number] {
|
|
375
374
|
const lr_token = tokens[start];
|
|
376
|
-
|
|
377
|
-
|
|
375
|
+
const end = find_closing_match(tokens, start);
|
|
376
|
+
if (tokens[start + 1].isOneOf(TypstToken.LEFT_DELIMITERS)) {
|
|
378
377
|
const inner_start = start + 1;
|
|
379
378
|
const inner_end = find_closing_delim(tokens, inner_start);
|
|
380
|
-
const inner_args= this.
|
|
379
|
+
const [inner_args, _]= this.parseGroup(tokens, inner_start + 1, inner_end);
|
|
381
380
|
return [
|
|
382
|
-
new TypstLeftright(lr_token, { body:
|
|
381
|
+
new TypstLeftright(lr_token, { body: inner_args, left: tokens[inner_start], right: tokens[inner_end]}),
|
|
383
382
|
end + 1,
|
|
384
383
|
];
|
|
385
384
|
} else {
|
|
386
|
-
const [
|
|
385
|
+
const [inner_args, _] = this.parseGroup(tokens, start + 1, end - 1);
|
|
387
386
|
return [
|
|
388
|
-
new TypstLeftright(lr_token, { body:
|
|
389
|
-
end,
|
|
387
|
+
new TypstLeftright(lr_token, { body: inner_args, left: null, right: null }),
|
|
388
|
+
end + 1,
|
|
390
389
|
];
|
|
391
390
|
}
|
|
392
391
|
}
|