tex2typst 0.3.21 → 0.3.23
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/generic.d.ts +1 -1
- package/dist/index.js +273 -316
- package/dist/jslex.d.ts +2 -0
- package/dist/tex2typst.min.js +12 -12
- package/dist/types.d.ts +11 -13
- package/package.json +1 -1
- package/src/convert.ts +212 -211
- package/src/generic.ts +1 -1
- package/src/jslex.ts +19 -12
- package/src/map.ts +1 -4
- package/src/tex-parser.ts +11 -10
- package/src/tex-tokenizer.ts +26 -23
- package/src/tex-writer.ts +1 -1
- package/src/types.ts +27 -21
- package/src/typst-parser.ts +1 -16
- package/src/typst-tokenizer.ts +9 -0
- package/src/typst-writer.ts +8 -23
package/src/map.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const symbolMap = new Map<string, string>([
|
|
2
2
|
['displaystyle', 'display'],
|
|
3
|
+
['hspace', '#h'],
|
|
3
4
|
|
|
4
5
|
['|', 'bar.v.double'],
|
|
5
|
-
['!', '#h(-math.thin.amount)'],
|
|
6
6
|
[',', 'thin'],
|
|
7
7
|
[':', 'med'],
|
|
8
8
|
[';', 'thick'],
|
|
@@ -1066,7 +1066,6 @@ const reverseSymbolMap = new Map<string, string>();
|
|
|
1066
1066
|
for(const [key, value] of Array.from(symbolMap.entries()).reverse()) {
|
|
1067
1067
|
reverseSymbolMap.set(value, key);
|
|
1068
1068
|
}
|
|
1069
|
-
reverseSymbolMap.set('dif', 'mathrm{d}');
|
|
1070
1069
|
reverseSymbolMap.set('oo', 'infty');
|
|
1071
1070
|
|
|
1072
1071
|
// force override some one-to-multiple mappings
|
|
@@ -1078,8 +1077,6 @@ const typst_to_tex_map = new Map<string, string>([
|
|
|
1078
1077
|
['upright', 'mathrm'],
|
|
1079
1078
|
['bold', 'boldsymbol'],
|
|
1080
1079
|
['infinity', 'infty'],
|
|
1081
|
-
|
|
1082
|
-
['hyph.minus', '\\text{-}'],
|
|
1083
1080
|
]);
|
|
1084
1081
|
|
|
1085
1082
|
for(const [key, value] of typst_to_tex_map) {
|
package/src/tex-parser.ts
CHANGED
|
@@ -231,8 +231,8 @@ export class LatexParser {
|
|
|
231
231
|
switch (firstToken.type) {
|
|
232
232
|
case TexTokenType.ELEMENT:
|
|
233
233
|
return [new TexNode('element', firstToken.value), start + 1];
|
|
234
|
-
case TexTokenType.
|
|
235
|
-
return [new TexNode('
|
|
234
|
+
case TexTokenType.LITERAL:
|
|
235
|
+
return [new TexNode('literal', firstToken.value), start + 1];
|
|
236
236
|
case TexTokenType.COMMENT:
|
|
237
237
|
return [new TexNode('comment', firstToken.value), start + 1];
|
|
238
238
|
case TexTokenType.SPACE:
|
|
@@ -321,7 +321,7 @@ export class LatexParser {
|
|
|
321
321
|
throw new LatexParserError('Expecting content for \\text command');
|
|
322
322
|
}
|
|
323
323
|
assert(tokens[pos].eq(LEFT_CURLY_BRACKET));
|
|
324
|
-
assert(tokens[pos + 1].type === TexTokenType.
|
|
324
|
+
assert(tokens[pos + 1].type === TexTokenType.LITERAL);
|
|
325
325
|
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
|
|
326
326
|
const text = tokens[pos + 1].value;
|
|
327
327
|
return [new TexNode('text', text), pos + 3];
|
|
@@ -412,24 +412,25 @@ export class LatexParser {
|
|
|
412
412
|
|
|
413
413
|
let pos = start + 1;
|
|
414
414
|
assert(tokens[pos].eq(LEFT_CURLY_BRACKET));
|
|
415
|
-
assert(tokens[pos + 1].type === TexTokenType.
|
|
415
|
+
assert(tokens[pos + 1].type === TexTokenType.LITERAL);
|
|
416
416
|
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
|
|
417
417
|
const envName = tokens[pos + 1].value;
|
|
418
418
|
pos += 3;
|
|
419
419
|
|
|
420
|
-
const args: TexNode[] = [];
|
|
421
|
-
while (pos < tokens.length) {
|
|
422
|
-
const whitespaceCount = eat_whitespaces(tokens, pos).length;
|
|
423
|
-
pos += whitespaceCount;
|
|
424
420
|
|
|
421
|
+
const args: TexNode[] = [];
|
|
422
|
+
if(['array', 'subarray'].includes(envName)) {
|
|
425
423
|
if (pos >= tokens.length || !tokens[pos].eq(LEFT_CURLY_BRACKET)) {
|
|
426
|
-
|
|
424
|
+
throw new LatexParserError(`Missing arg for \\begin{${envName}}`);
|
|
427
425
|
}
|
|
428
426
|
const [arg, newPos] = this.parseNextArg(tokens, pos);
|
|
429
427
|
args.push(arg);
|
|
430
428
|
pos = newPos;
|
|
431
429
|
}
|
|
432
430
|
|
|
431
|
+
pos += eat_whitespaces(tokens, pos).length; // ignore whitespaces and '\n' after \begin{envName}
|
|
432
|
+
|
|
433
|
+
|
|
433
434
|
const exprInsideStart = pos;
|
|
434
435
|
|
|
435
436
|
const endIdx = find_closing_end_command(tokens, start);
|
|
@@ -440,7 +441,7 @@ export class LatexParser {
|
|
|
440
441
|
pos = endIdx + 1;
|
|
441
442
|
|
|
442
443
|
assert(tokens[pos].eq(LEFT_CURLY_BRACKET));
|
|
443
|
-
assert(tokens[pos + 1].type === TexTokenType.
|
|
444
|
+
assert(tokens[pos + 1].type === TexTokenType.LITERAL);
|
|
444
445
|
assert(tokens[pos + 2].eq(RIGHT_CURLY_BRACKET));
|
|
445
446
|
if (tokens[pos + 1].value !== envName) {
|
|
446
447
|
throw new LatexParserError('Mismatched \\begin and \\end environments');
|
package/src/tex-tokenizer.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { TexToken, TexTokenType } from "./types";
|
|
2
|
-
import { assert } from "./util";
|
|
3
2
|
import { JSLex, Scanner } from "./jslex";
|
|
4
3
|
|
|
5
4
|
export const TEX_UNARY_COMMANDS = [
|
|
@@ -59,15 +58,28 @@ function unescape(str: string): string {
|
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
const rules_map = new Map<string, (a: Scanner<TexToken>) => TexToken | TexToken[]>([
|
|
61
|
+
// math `\begin{array}{cc}`
|
|
62
62
|
[
|
|
63
|
-
String.raw`\\(
|
|
64
|
-
const
|
|
65
|
-
const command = text.substring(0, text.indexOf('{'));
|
|
66
|
-
const text_inside = text.substring(text.indexOf('{') + 1, text.lastIndexOf('}'));
|
|
63
|
+
String.raw`\\begin{(array|subarry)}{(.+?)}`, (s) => {
|
|
64
|
+
const match = s.reMatchArray()!;
|
|
67
65
|
return [
|
|
68
|
-
new TexToken(TexTokenType.COMMAND,
|
|
66
|
+
new TexToken(TexTokenType.COMMAND, '\\begin'),
|
|
67
|
+
new TexToken(TexTokenType.CONTROL, '{'),
|
|
68
|
+
new TexToken(TexTokenType.LITERAL, match[1]),
|
|
69
|
+
new TexToken(TexTokenType.CONTROL, '}'),
|
|
70
|
+
new TexToken(TexTokenType.CONTROL, '{'),
|
|
71
|
+
new TexToken(TexTokenType.LITERAL, match[2]),
|
|
72
|
+
new TexToken(TexTokenType.CONTROL, '}'),
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
String.raw`\\(text|operatorname|begin|end|hspace|array){(.+?)}`, (s) => {
|
|
78
|
+
const match = s.reMatchArray()!;
|
|
79
|
+
return [
|
|
80
|
+
new TexToken(TexTokenType.COMMAND, '\\' + match[1]),
|
|
69
81
|
new TexToken(TexTokenType.CONTROL, '{'),
|
|
70
|
-
new TexToken(TexTokenType.
|
|
82
|
+
new TexToken(TexTokenType.LITERAL, unescape(match[2])),
|
|
71
83
|
new TexToken(TexTokenType.CONTROL, '}')
|
|
72
84
|
]
|
|
73
85
|
}
|
|
@@ -80,14 +92,11 @@ const rules_map = new Map<string, (a: Scanner<TexToken>) => TexToken | TexToken[
|
|
|
80
92
|
[String.raw`\\[{}%$&#_|]`, (s) => new TexToken(TexTokenType.ELEMENT, s.text()!)],
|
|
81
93
|
// e.g. match `\frac13`, `\frac1 b`, `\frac a b`
|
|
82
94
|
[String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`, (s) => {
|
|
83
|
-
const
|
|
84
|
-
const regex = RegExp(String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`);
|
|
85
|
-
const match = text.match(regex);
|
|
86
|
-
assert(match !== null);
|
|
95
|
+
const match = s.reMatchArray()!;
|
|
87
96
|
const command = match![1];
|
|
88
97
|
if (TEX_BINARY_COMMANDS.includes(command.substring(1))) {
|
|
89
|
-
const arg1 = match
|
|
90
|
-
const arg2 = match
|
|
98
|
+
const arg1 = match[2].trimStart();
|
|
99
|
+
const arg2 = match[3];
|
|
91
100
|
return [
|
|
92
101
|
new TexToken(TexTokenType.COMMAND, command),
|
|
93
102
|
new TexToken(TexTokenType.ELEMENT, arg1),
|
|
@@ -100,13 +109,10 @@ const rules_map = new Map<string, (a: Scanner<TexToken>) => TexToken | TexToken[
|
|
|
100
109
|
}],
|
|
101
110
|
// e.g. match `\sqrt3`, `\sqrt a`
|
|
102
111
|
[String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])`, (s) => {
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const match = text.match(regex);
|
|
106
|
-
assert(match !== null);
|
|
107
|
-
const command = match![1];
|
|
112
|
+
const match = s.reMatchArray()!;
|
|
113
|
+
const command = match[1];
|
|
108
114
|
if (TEX_UNARY_COMMANDS.includes(command.substring(1))) {
|
|
109
|
-
const arg1 = match
|
|
115
|
+
const arg1 = match[2].trimStart();
|
|
110
116
|
return [
|
|
111
117
|
new TexToken(TexTokenType.COMMAND, command),
|
|
112
118
|
new TexToken(TexTokenType.ELEMENT, arg1),
|
|
@@ -116,10 +122,7 @@ const rules_map = new Map<string, (a: Scanner<TexToken>) => TexToken | TexToken[
|
|
|
116
122
|
return [];
|
|
117
123
|
}
|
|
118
124
|
}],
|
|
119
|
-
[String.raw`\\[a-zA-Z]+`, (s) =>
|
|
120
|
-
const command = s.text()!;
|
|
121
|
-
return [ new TexToken(TexTokenType.COMMAND, command), ];
|
|
122
|
-
}],
|
|
125
|
+
[String.raw`\\[a-zA-Z]+`, (s) => new TexToken(TexTokenType.COMMAND, s.text()!)],
|
|
123
126
|
// Numbers like "123", "3.14"
|
|
124
127
|
[String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TexToken(TexTokenType.ELEMENT, s.text()!)],
|
|
125
128
|
[String.raw`[a-zA-Z]`, (s) => new TexToken(TexTokenType.ELEMENT, s.text()!)],
|
package/src/tex-writer.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { array_includes } from "./generic";
|
|
|
3
3
|
export enum TexTokenType {
|
|
4
4
|
ELEMENT,
|
|
5
5
|
COMMAND,
|
|
6
|
-
|
|
6
|
+
LITERAL,
|
|
7
7
|
COMMENT,
|
|
8
8
|
SPACE,
|
|
9
9
|
NEWLINE,
|
|
@@ -26,10 +26,8 @@ export class TexToken {
|
|
|
26
26
|
|
|
27
27
|
public toString(): string {
|
|
28
28
|
switch (this.type) {
|
|
29
|
-
case TexTokenType.TEXT:
|
|
30
|
-
return `\\text{${this.value}}`;
|
|
31
29
|
case TexTokenType.COMMENT:
|
|
32
|
-
return
|
|
30
|
+
return "%" + this.value;
|
|
33
31
|
default:
|
|
34
32
|
return this.value;
|
|
35
33
|
}
|
|
@@ -56,7 +54,7 @@ export type TexArrayData = TexNode[][];
|
|
|
56
54
|
* empty: special type when something is empty. e.g. the base of _{a} or ^{a}
|
|
57
55
|
* whitespace: space, tab, newline
|
|
58
56
|
*/
|
|
59
|
-
type TexNodeType = 'element' | 'text' | 'comment' | 'whitespace' | 'control' | 'ordgroup' | 'supsub'
|
|
57
|
+
type TexNodeType = 'element' | 'text' | 'literal' | 'comment' | 'whitespace' | 'control' | 'ordgroup' | 'supsub'
|
|
60
58
|
| 'unaryFunc' | 'binaryFunc' | 'leftright' | 'beginend' | 'symbol' | 'empty' | 'unknownMacro';
|
|
61
59
|
|
|
62
60
|
|
|
@@ -89,16 +87,6 @@ export class TexNode {
|
|
|
89
87
|
return this.type === other.type && this.content === other.content;
|
|
90
88
|
}
|
|
91
89
|
|
|
92
|
-
public toString(): string {
|
|
93
|
-
switch (this.type) {
|
|
94
|
-
case 'text':
|
|
95
|
-
return `\\text{${this.content}}`;
|
|
96
|
-
default:
|
|
97
|
-
throw new Error(`toString() is not implemented for type ${this.type}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
90
|
public serialize(): TexToken[] {
|
|
103
91
|
switch (this.type) {
|
|
104
92
|
case 'empty':
|
|
@@ -110,8 +98,15 @@ export class TexNode {
|
|
|
110
98
|
}
|
|
111
99
|
case 'symbol':
|
|
112
100
|
return [new TexToken(TexTokenType.COMMAND, this.content)];
|
|
101
|
+
case 'literal':
|
|
102
|
+
return [new TexToken(TexTokenType.LITERAL, this.content)];
|
|
113
103
|
case 'text':
|
|
114
|
-
return [
|
|
104
|
+
return [
|
|
105
|
+
new TexToken(TexTokenType.COMMAND, '\\text'),
|
|
106
|
+
new TexToken(TexTokenType.ELEMENT, '{'),
|
|
107
|
+
new TexToken(TexTokenType.LITERAL, this.content),
|
|
108
|
+
new TexToken(TexTokenType.ELEMENT, '}'),
|
|
109
|
+
];
|
|
115
110
|
case 'comment':
|
|
116
111
|
return [new TexToken(TexTokenType.COMMENT, this.content)];
|
|
117
112
|
case 'whitespace': {
|
|
@@ -243,6 +238,7 @@ export enum TypstTokenType {
|
|
|
243
238
|
NONE,
|
|
244
239
|
SYMBOL,
|
|
245
240
|
ELEMENT,
|
|
241
|
+
LITERAL,
|
|
246
242
|
TEXT,
|
|
247
243
|
COMMENT,
|
|
248
244
|
SPACE,
|
|
@@ -271,6 +267,8 @@ export class TypstToken {
|
|
|
271
267
|
switch(this.type) {
|
|
272
268
|
case TypstTokenType.NONE:
|
|
273
269
|
return new TypstNode('none', '#none');
|
|
270
|
+
case TypstTokenType.LITERAL:
|
|
271
|
+
return new TypstNode('literal', this.value);
|
|
274
272
|
case TypstTokenType.TEXT:
|
|
275
273
|
return new TypstNode('text', this.value);
|
|
276
274
|
case TypstTokenType.COMMENT:
|
|
@@ -326,11 +324,10 @@ export interface TypstLrData {
|
|
|
326
324
|
rightDelim: string | null;
|
|
327
325
|
}
|
|
328
326
|
|
|
329
|
-
type TypstNodeType = 'atom' | 'symbol' | 'text' | 'control' | 'comment' | 'whitespace'
|
|
327
|
+
type TypstNodeType = 'atom' | 'symbol' | 'text' | 'literal' | 'control' | 'comment' | 'whitespace'
|
|
330
328
|
| 'none' | 'group' | 'supsub' | 'funcCall' | 'fraction' | 'align' | 'matrix' | 'cases' | 'unknown';
|
|
331
329
|
|
|
332
|
-
export type
|
|
333
|
-
export type TypstNamedParams = { [key: string]: TypstPrimitiveValue };
|
|
330
|
+
export type TypstNamedParams = { [key: string]: TypstNode };
|
|
334
331
|
|
|
335
332
|
|
|
336
333
|
export class TypstNode {
|
|
@@ -382,12 +379,21 @@ export class TypstNode {
|
|
|
382
379
|
return false;
|
|
383
380
|
}
|
|
384
381
|
}
|
|
382
|
+
|
|
383
|
+
public toString(): string {
|
|
384
|
+
switch (this.type) {
|
|
385
|
+
case 'text':
|
|
386
|
+
return `"${this.content}"`;
|
|
387
|
+
case 'comment':
|
|
388
|
+
return `//${this.content}`;
|
|
389
|
+
default:
|
|
390
|
+
return this.content;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
385
393
|
}
|
|
386
394
|
|
|
387
395
|
// #none
|
|
388
396
|
export const TYPST_NONE = new TypstNode('none', '#none');
|
|
389
|
-
export const TYPST_TRUE: TypstPrimitiveValue = true;
|
|
390
|
-
export const TYPST_FALSE: TypstPrimitiveValue = false;
|
|
391
397
|
|
|
392
398
|
/**
|
|
393
399
|
* ATTENTION:
|
package/src/typst-parser.ts
CHANGED
|
@@ -413,22 +413,7 @@ export class TypstParser {
|
|
|
413
413
|
if(g.args!.length !== 3) {
|
|
414
414
|
throw new TypstParserError('Invalid number of arguments for delim');
|
|
415
415
|
}
|
|
416
|
-
|
|
417
|
-
case 'text': {
|
|
418
|
-
np['delim'] = g.args![pos_colon + 1].content;
|
|
419
|
-
break;
|
|
420
|
-
}
|
|
421
|
-
case 'none': {
|
|
422
|
-
np['delim'] = TYPST_NONE;
|
|
423
|
-
break;
|
|
424
|
-
}
|
|
425
|
-
case 'symbol': {
|
|
426
|
-
np['delim'] = g.args![pos_colon + 1];
|
|
427
|
-
break;
|
|
428
|
-
}
|
|
429
|
-
default:
|
|
430
|
-
throw new TypstParserError('Not implemented for other types of delim');
|
|
431
|
-
}
|
|
416
|
+
np['delim'] = g.args![pos_colon + 1];
|
|
432
417
|
} else {
|
|
433
418
|
throw new TypstParserError('Not implemented for other named parameters');
|
|
434
419
|
}
|
package/src/typst-tokenizer.ts
CHANGED
|
@@ -59,6 +59,15 @@ const rules_map = new Map<string, (a: Scanner<TypstToken>) => TypstToken | Typst
|
|
|
59
59
|
],
|
|
60
60
|
[String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(TypstTokenType.ELEMENT, s.text()!)],
|
|
61
61
|
[String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(TypstTokenType.ELEMENT, s.text()!)],
|
|
62
|
+
[String.raw`#h\((.+?)\)`, (s) => {
|
|
63
|
+
const match = s.reMatchArray()!;
|
|
64
|
+
return [
|
|
65
|
+
new TypstToken(TypstTokenType.SYMBOL, "#h"),
|
|
66
|
+
new TypstToken(TypstTokenType.ELEMENT, "("),
|
|
67
|
+
new TypstToken(TypstTokenType.LITERAL, match[1]),
|
|
68
|
+
new TypstToken(TypstTokenType.ELEMENT, ")"),
|
|
69
|
+
];
|
|
70
|
+
}],
|
|
62
71
|
[String.raw`[a-zA-Z\.]+`, (s) => {
|
|
63
72
|
return new TypstToken(s.text()!.length === 1? TypstTokenType.ELEMENT: TypstTokenType.SYMBOL, s.text()!);
|
|
64
73
|
}],
|
package/src/typst-writer.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { TexNode, TypstNode,
|
|
1
|
+
import { TexNode, TypstNode, TypstSupsubData, TypstToken, TypstTokenType } from "./types";
|
|
2
2
|
import { shorthandMap } from "./typst-shorthands";
|
|
3
|
-
import { assert } from "./util";
|
|
4
3
|
|
|
5
4
|
function is_delimiter(c: TypstNode): boolean {
|
|
6
5
|
return c.type === 'atom' && ['(', ')', '[', ']', '{', '}', '|', '⌊', '⌋', '⌈', '⌉'].includes(c.content);
|
|
@@ -13,20 +12,6 @@ const TYPST_NEWLINE: TypstToken = new TypstToken(TypstTokenType.SYMBOL, '\n');
|
|
|
13
12
|
|
|
14
13
|
const SOFT_SPACE = new TypstToken(TypstTokenType.CONTROL, ' ');
|
|
15
14
|
|
|
16
|
-
function typst_primitive_to_string(value: TypstPrimitiveValue) {
|
|
17
|
-
switch (typeof value) {
|
|
18
|
-
case 'string':
|
|
19
|
-
return `"${value}"`;
|
|
20
|
-
case 'number':
|
|
21
|
-
return (value as number).toString();
|
|
22
|
-
case 'boolean':
|
|
23
|
-
return (value as boolean) ? '#true' : '#false';
|
|
24
|
-
default:
|
|
25
|
-
assert(value instanceof TypstNode, 'Not a valid primitive value');
|
|
26
|
-
return (value as TypstNode).content;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
15
|
export class TypstWriterError extends Error {
|
|
31
16
|
node: TexNode | TypstNode | TypstToken;
|
|
32
17
|
|
|
@@ -132,6 +117,9 @@ export class TypstWriter {
|
|
|
132
117
|
this.queue.push(new TypstToken(TypstTokenType.SYMBOL, content));
|
|
133
118
|
break;
|
|
134
119
|
}
|
|
120
|
+
case 'literal':
|
|
121
|
+
this.queue.push(new TypstToken(TypstTokenType.LITERAL, node.content));
|
|
122
|
+
break;
|
|
135
123
|
case 'text':
|
|
136
124
|
this.queue.push(new TypstToken(TypstTokenType.TEXT, node.content));
|
|
137
125
|
break;
|
|
@@ -198,8 +186,7 @@ export class TypstWriter {
|
|
|
198
186
|
}
|
|
199
187
|
if (node.options) {
|
|
200
188
|
for (const [key, value] of Object.entries(node.options)) {
|
|
201
|
-
|
|
202
|
-
this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `, ${key}: ${value_str}`));
|
|
189
|
+
this.queue.push(new TypstToken(TypstTokenType.LITERAL, `, ${key}: ${value.toString()}`));
|
|
203
190
|
}
|
|
204
191
|
}
|
|
205
192
|
this.queue.push(TYPST_RIGHT_PARENTHESIS);
|
|
@@ -246,8 +233,7 @@ export class TypstWriter {
|
|
|
246
233
|
this.queue.push(TYPST_LEFT_PARENTHESIS);
|
|
247
234
|
if (node.options) {
|
|
248
235
|
for (const [key, value] of Object.entries(node.options)) {
|
|
249
|
-
|
|
250
|
-
this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `${key}: ${value_str}, `));
|
|
236
|
+
this.queue.push(new TypstToken(TypstTokenType.LITERAL, `${key}: ${value.toString()}, `));
|
|
251
237
|
}
|
|
252
238
|
}
|
|
253
239
|
matrix.forEach((row, i) => {
|
|
@@ -282,8 +268,7 @@ export class TypstWriter {
|
|
|
282
268
|
this.queue.push(TYPST_LEFT_PARENTHESIS);
|
|
283
269
|
if (node.options) {
|
|
284
270
|
for (const [key, value] of Object.entries(node.options)) {
|
|
285
|
-
|
|
286
|
-
this.queue.push(new TypstToken(TypstTokenType.SYMBOL, `${key}: ${value_str}, `));
|
|
271
|
+
this.queue.push(new TypstToken(TypstTokenType.LITERAL, `${key}: ${value.toString()}, `));
|
|
287
272
|
}
|
|
288
273
|
}
|
|
289
274
|
cases.forEach((row, i) => {
|
|
@@ -316,7 +301,7 @@ export class TypstWriter {
|
|
|
316
301
|
}
|
|
317
302
|
|
|
318
303
|
private appendWithBracketsIfNeeded(node: TypstNode): boolean {
|
|
319
|
-
let need_to_wrap = ['group', 'supsub', 'fraction','empty'].includes(node.type);
|
|
304
|
+
let need_to_wrap = ['group', 'supsub', 'align', 'fraction','empty'].includes(node.type);
|
|
320
305
|
|
|
321
306
|
if (node.type === 'group') {
|
|
322
307
|
if (node.args!.length === 0) {
|