tex2typst 0.3.24 → 0.3.25
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 +261 -211
- package/dist/tex-types.d.ts +11 -7
- package/dist/tex2typst.min.js +13 -13
- package/dist/typst-types.d.ts +18 -16
- package/package.json +1 -1
- package/src/convert.ts +131 -101
- package/src/tex-parser.ts +9 -14
- package/src/tex-tokenizer.ts +3 -2
- package/src/tex-types.ts +28 -17
- package/src/typst-parser.ts +39 -19
- package/src/typst-tokenizer.ts +2 -2
- package/src/typst-types.ts +45 -37
- package/src/typst-writer.ts +73 -73
package/src/tex-types.ts
CHANGED
|
@@ -18,7 +18,7 @@ export enum TexTokenType {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export class TexToken {
|
|
21
|
-
type: TexTokenType;
|
|
21
|
+
readonly type: TexTokenType;
|
|
22
22
|
value: string;
|
|
23
23
|
|
|
24
24
|
constructor(type: TexTokenType, value: string) {
|
|
@@ -55,6 +55,7 @@ export interface TexSupsubData {
|
|
|
55
55
|
|
|
56
56
|
// \left. or \right. will be represented as null.
|
|
57
57
|
export interface TexLeftRightData {
|
|
58
|
+
body: TexNode;
|
|
58
59
|
left: TexToken | null;
|
|
59
60
|
right: TexToken | null;
|
|
60
61
|
}
|
|
@@ -68,14 +69,12 @@ type TexNodeType = 'terminal' | 'text' | 'ordgroup' | 'supsub'
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
export abstract class TexNode {
|
|
71
|
-
type: TexNodeType;
|
|
72
|
+
readonly type: TexNodeType;
|
|
72
73
|
head: TexToken;
|
|
73
|
-
args?: TexNode[];
|
|
74
74
|
|
|
75
|
-
constructor(type: TexNodeType, head: TexToken | null
|
|
75
|
+
constructor(type: TexNodeType, head: TexToken | null) {
|
|
76
76
|
this.type = type;
|
|
77
77
|
this.head = head ? head : TexToken.EMPTY;
|
|
78
|
-
this.args = args;
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
// Note that this is only shallow equality.
|
|
@@ -148,12 +147,14 @@ export class TexText extends TexNode {
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
export class TexGroup extends TexNode {
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
public items: TexNode[];
|
|
151
|
+
constructor(items: TexNode[]) {
|
|
152
|
+
super('ordgroup', TexToken.EMPTY);
|
|
153
|
+
this.items = items;
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
public serialize(): TexToken[] {
|
|
156
|
-
return this.
|
|
157
|
+
return this.items.map((n) => n.serialize()).flat();
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
160
|
|
|
@@ -163,7 +164,7 @@ export class TexSupSub extends TexNode {
|
|
|
163
164
|
public sub: TexNode | null;
|
|
164
165
|
|
|
165
166
|
constructor(data: TexSupsubData) {
|
|
166
|
-
super('supsub', TexToken.EMPTY
|
|
167
|
+
super('supsub', TexToken.EMPTY);
|
|
167
168
|
this.base = data.base;
|
|
168
169
|
this.sup = data.sup;
|
|
169
170
|
this.sub = data.sub;
|
|
@@ -211,11 +212,14 @@ export class TexSupSub extends TexNode {
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
export class TexFuncCall extends TexNode {
|
|
215
|
+
public args: TexNode[];
|
|
216
|
+
|
|
214
217
|
// For type="sqrt", it's additional argument wrapped square bracket. e.g. 3 in \sqrt[3]{x}
|
|
215
218
|
public data: TexNode | null;
|
|
216
219
|
|
|
217
220
|
constructor(head: TexToken, args: TexNode[], data: TexNode | null = null) {
|
|
218
|
-
super('funcCall', head
|
|
221
|
+
super('funcCall', head);
|
|
222
|
+
this.args = args;
|
|
219
223
|
this.data = data;
|
|
220
224
|
}
|
|
221
225
|
|
|
@@ -230,7 +234,7 @@ export class TexFuncCall extends TexNode {
|
|
|
230
234
|
tokens.push(new TexToken(TexTokenType.ELEMENT, ']'));
|
|
231
235
|
}
|
|
232
236
|
|
|
233
|
-
for (const arg of this.args
|
|
237
|
+
for (const arg of this.args) {
|
|
234
238
|
tokens.push(new TexToken(TexTokenType.ELEMENT, '{'));
|
|
235
239
|
tokens = tokens.concat(arg.serialize());
|
|
236
240
|
tokens.push(new TexToken(TexTokenType.ELEMENT, '}'));
|
|
@@ -241,11 +245,13 @@ export class TexFuncCall extends TexNode {
|
|
|
241
245
|
}
|
|
242
246
|
|
|
243
247
|
export class TexLeftRight extends TexNode {
|
|
248
|
+
public body: TexNode;
|
|
244
249
|
public left: TexToken | null;
|
|
245
250
|
public right: TexToken | null;
|
|
246
251
|
|
|
247
|
-
constructor(
|
|
248
|
-
super('leftright', TexToken.EMPTY
|
|
252
|
+
constructor(data: TexLeftRightData) {
|
|
253
|
+
super('leftright', TexToken.EMPTY);
|
|
254
|
+
this.body = data.body;
|
|
249
255
|
this.left = data.left;
|
|
250
256
|
this.right = data.right;
|
|
251
257
|
}
|
|
@@ -254,7 +260,7 @@ export class TexLeftRight extends TexNode {
|
|
|
254
260
|
let tokens: TexToken[] = [];
|
|
255
261
|
tokens.push(new TexToken(TexTokenType.COMMAND, '\\left'));
|
|
256
262
|
tokens.push(new TexToken(TexTokenType.ELEMENT, this.left? this.left.value: '.'));
|
|
257
|
-
tokens = tokens.concat(this.
|
|
263
|
+
tokens = tokens.concat(this.body.serialize());
|
|
258
264
|
tokens.push(new TexToken(TexTokenType.COMMAND, '\\right'));
|
|
259
265
|
tokens.push(new TexToken(TexTokenType.ELEMENT, this.right? this.right.value: '.'));
|
|
260
266
|
return tokens;
|
|
@@ -263,11 +269,14 @@ export class TexLeftRight extends TexNode {
|
|
|
263
269
|
|
|
264
270
|
export class TexBeginEnd extends TexNode {
|
|
265
271
|
public matrix: TexNode[][];
|
|
272
|
+
// for environment="array" or "subarray", there's additional data like {c|c} right after \begin{env}
|
|
273
|
+
public data: TexNode | null;
|
|
266
274
|
|
|
267
|
-
constructor(head: TexToken,
|
|
275
|
+
constructor(head: TexToken, matrix: TexNode[][], data: TexNode | null = null) {
|
|
268
276
|
assert(head.type === TexTokenType.LITERAL);
|
|
269
|
-
super('beginend', head
|
|
270
|
-
this.matrix =
|
|
277
|
+
super('beginend', head);
|
|
278
|
+
this.matrix = matrix;
|
|
279
|
+
this.data = data;
|
|
271
280
|
}
|
|
272
281
|
|
|
273
282
|
public serialize(): TexToken[] {
|
|
@@ -330,6 +339,8 @@ export function writeTexTokenBuffer(buffer: string, token: TexToken): string {
|
|
|
330
339
|
no_need_space ||= /[\(\[{]\s*(-|\+)$/.test(buffer) || buffer === '-' || buffer === '+';
|
|
331
340
|
// "&=" instead of "& ="
|
|
332
341
|
no_need_space ||= buffer.endsWith('&') && str === '=';
|
|
342
|
+
// "2y" instead of "2 y"
|
|
343
|
+
no_need_space ||= /\d$/.test(buffer) && /^[a-zA-Z]$/.test(str);
|
|
333
344
|
}
|
|
334
345
|
|
|
335
346
|
if (!no_need_space) {
|
package/src/typst-parser.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import { array_find } from "./generic";
|
|
3
|
-
import {
|
|
3
|
+
import { TypstFraction, TypstFuncCall, TypstGroup, TypstLeftright, TypstLeftRightData, TypstMarkupFunc, TypstMatrixLike, TypstNode, TypstSupsub, TypstTerminal } from "./typst-types";
|
|
4
4
|
import { TypstNamedParams } from "./typst-types";
|
|
5
5
|
import { TypstSupsubData } from "./typst-types";
|
|
6
6
|
import { TypstToken } from "./typst-types";
|
|
@@ -19,7 +19,6 @@ function eat_primes(tokens: TypstToken[], start: number): number {
|
|
|
19
19
|
return pos - start;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
function _find_closing_match(tokens: TypstToken[], start: number,
|
|
24
23
|
leftBrackets: TypstToken[], rightBrackets: TypstToken[]): number {
|
|
25
24
|
assert(tokens[start].isOneOf(leftBrackets));
|
|
@@ -168,10 +167,10 @@ function process_operators(nodes: TypstNode[], parenthesis = false): TypstNode {
|
|
|
168
167
|
let numerator = args.pop()!;
|
|
169
168
|
|
|
170
169
|
if(denominator.type === 'leftright') {
|
|
171
|
-
denominator =
|
|
170
|
+
denominator = (denominator as TypstLeftright).body;
|
|
172
171
|
}
|
|
173
172
|
if(numerator.type === 'leftright') {
|
|
174
|
-
numerator =
|
|
173
|
+
numerator = (numerator as TypstLeftright).body;
|
|
175
174
|
}
|
|
176
175
|
|
|
177
176
|
args.push(new TypstFraction([numerator, denominator]));
|
|
@@ -181,15 +180,24 @@ function process_operators(nodes: TypstNode[], parenthesis = false): TypstNode {
|
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
182
|
}
|
|
183
|
+
const body = args.length === 1? args[0]: new TypstGroup(args);
|
|
184
184
|
if(parenthesis) {
|
|
185
|
-
return new TypstLeftright(null,
|
|
185
|
+
return new TypstLeftright(null, { body: body, left: LEFT_PARENTHESES, right: RIGHT_PARENTHESES } as TypstLeftRightData);
|
|
186
186
|
} else {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
187
|
+
return body;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function parse_named_params(groups: TypstGroup[]): TypstNamedParams {
|
|
192
|
+
const COLON = new TypstToken(TypstTokenType.ELEMENT, ':').toNode();
|
|
193
|
+
|
|
194
|
+
const np: TypstNamedParams = {};
|
|
195
|
+
for (const group of groups) {
|
|
196
|
+
assert(group.items.length == 3);
|
|
197
|
+
assert(group.items[1].eq(COLON));
|
|
198
|
+
np[group.items[0].toString()] = new TypstTerminal(new TypstToken(TypstTokenType.LITERAL, group.items[2].toString()));
|
|
192
199
|
}
|
|
200
|
+
return np;
|
|
193
201
|
}
|
|
194
202
|
|
|
195
203
|
export class TypstParserError extends Error {
|
|
@@ -322,19 +330,31 @@ export class TypstParser {
|
|
|
322
330
|
if (start + 1 < tokens.length && tokens[start + 1].eq(LEFT_PARENTHESES)) {
|
|
323
331
|
if(firstToken.value === 'mat') {
|
|
324
332
|
const [matrix, named_params, newPos] = this.parseMatrix(tokens, start + 1, SEMICOLON, COMMA);
|
|
325
|
-
const mat = new
|
|
333
|
+
const mat = new TypstMatrixLike(firstToken, matrix);
|
|
326
334
|
mat.setOptions(named_params);
|
|
327
335
|
return [mat, newPos];
|
|
328
336
|
}
|
|
329
337
|
if(firstToken.value === 'cases') {
|
|
330
338
|
const [cases, named_params, newPos] = this.parseMatrix(tokens, start + 1, COMMA, CONTROL_AND);
|
|
331
|
-
const casesNode = new
|
|
339
|
+
const casesNode = new TypstMatrixLike(firstToken, cases);
|
|
332
340
|
casesNode.setOptions(named_params);
|
|
333
341
|
return [casesNode, newPos];
|
|
334
342
|
}
|
|
335
343
|
if (firstToken.value === 'lr') {
|
|
336
344
|
return this.parseLrArguments(tokens, start + 1);
|
|
337
345
|
}
|
|
346
|
+
if (['#heading', '#text'].includes(firstToken.value)) {
|
|
347
|
+
const [args, newPos] = this.parseArguments(tokens, start + 1);
|
|
348
|
+
const named_params = parse_named_params(args as TypstGroup[]);
|
|
349
|
+
assert(tokens[newPos].eq(LEFT_BRACKET));
|
|
350
|
+
const DOLLAR = new TypstToken(TypstTokenType.ELEMENT, '$');
|
|
351
|
+
const end = _find_closing_match(tokens, newPos + 1, [DOLLAR], [DOLLAR]);
|
|
352
|
+
const [group, _] = this.parseGroup(tokens, newPos + 2, end);
|
|
353
|
+
assert(tokens[end + 1].eq(RIGHT_BRACKET));
|
|
354
|
+
const markup_func = new TypstMarkupFunc(firstToken, [group]);
|
|
355
|
+
markup_func.setOptions(named_params);
|
|
356
|
+
return [markup_func, end + 2];
|
|
357
|
+
}
|
|
338
358
|
const [args, newPos] = this.parseArguments(tokens, start + 1);
|
|
339
359
|
const func_call = new TypstFuncCall(firstToken, args);
|
|
340
360
|
return [func_call, newPos];
|
|
@@ -359,13 +379,13 @@ export class TypstParser {
|
|
|
359
379
|
const inner_end = find_closing_delim(tokens, inner_start);
|
|
360
380
|
const inner_args= this.parseArgumentsWithSeparator(tokens, inner_start + 1, inner_end, COMMA);
|
|
361
381
|
return [
|
|
362
|
-
new TypstLeftright(lr_token, inner_args,
|
|
382
|
+
new TypstLeftright(lr_token, { body: new TypstGroup(inner_args), left: tokens[inner_start], right: tokens[inner_end]}),
|
|
363
383
|
end + 1,
|
|
364
384
|
];
|
|
365
385
|
} else {
|
|
366
386
|
const [args, end] = this.parseArguments(tokens, start);
|
|
367
387
|
return [
|
|
368
|
-
new TypstLeftright(lr_token, args,
|
|
388
|
+
new TypstLeftright(lr_token, { body: new TypstGroup(args), left: null, right: null }),
|
|
369
389
|
end,
|
|
370
390
|
];
|
|
371
391
|
}
|
|
@@ -400,18 +420,18 @@ export class TypstParser {
|
|
|
400
420
|
continue;
|
|
401
421
|
}
|
|
402
422
|
|
|
403
|
-
const g = arr[i];
|
|
404
|
-
const pos_colon = array_find(g.
|
|
423
|
+
const g = arr[i] as TypstGroup;
|
|
424
|
+
const pos_colon = array_find(g.items, COLON);
|
|
405
425
|
if(pos_colon === -1 || pos_colon === 0) {
|
|
406
426
|
continue;
|
|
407
427
|
}
|
|
408
428
|
to_delete.push(i);
|
|
409
|
-
const param_name = g.
|
|
429
|
+
const param_name = g.items[pos_colon - 1];
|
|
410
430
|
if(param_name.eq(new TypstToken(TypstTokenType.SYMBOL, 'delim').toNode())) {
|
|
411
|
-
if(g.
|
|
431
|
+
if(g.items.length !== 3) {
|
|
412
432
|
throw new TypstParserError('Invalid number of arguments for delim');
|
|
413
433
|
}
|
|
414
|
-
np['delim'] = g.
|
|
434
|
+
np['delim'] = g.items[pos_colon + 1];
|
|
415
435
|
} else {
|
|
416
436
|
throw new TypstParserError('Not implemented for other named parameters');
|
|
417
437
|
}
|
package/src/typst-tokenizer.ts
CHANGED
|
@@ -69,10 +69,10 @@ const rules_map = new Map<string, (a: Scanner<TypstToken>) => TypstToken | Typst
|
|
|
69
69
|
new TypstToken(TypstTokenType.ELEMENT, ")"),
|
|
70
70
|
];
|
|
71
71
|
}],
|
|
72
|
-
[String.raw
|
|
72
|
+
[String.raw`#none`, (s) => new TypstToken(TypstTokenType.NONE, s.text()!)],
|
|
73
|
+
[String.raw`#?[a-zA-Z\.]+`, (s) => {
|
|
73
74
|
return new TypstToken(s.text()!.length === 1? TypstTokenType.ELEMENT: TypstTokenType.SYMBOL, s.text()!);
|
|
74
75
|
}],
|
|
75
|
-
[String.raw`#none`, (s) => new TypstToken(TypstTokenType.NONE, s.text()!)],
|
|
76
76
|
[String.raw`.`, (s) => new TypstToken(TypstTokenType.ELEMENT, s.text()!)],
|
|
77
77
|
]);
|
|
78
78
|
|
package/src/typst-types.ts
CHANGED
|
@@ -14,7 +14,7 @@ export enum TypstTokenType {
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
export class TypstToken {
|
|
17
|
-
type: TypstTokenType;
|
|
17
|
+
readonly type: TypstTokenType;
|
|
18
18
|
value: string;
|
|
19
19
|
|
|
20
20
|
constructor(type: TypstTokenType, content: string) {
|
|
@@ -56,6 +56,7 @@ export interface TypstSupsubData {
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
export interface TypstLeftRightData {
|
|
59
|
+
body: TypstNode;
|
|
59
60
|
left: TypstToken | null;
|
|
60
61
|
right: TypstToken | null;
|
|
61
62
|
}
|
|
@@ -64,22 +65,21 @@ export interface TypstLeftRightData {
|
|
|
64
65
|
* fraction: `1/2`, `(x + y)/2`, `(1+x)/(1-x)`
|
|
65
66
|
* group: `a + 1/3`
|
|
66
67
|
* leftright: `(a + 1/3)`, `[a + 1/3)`, `lr(]sum_(x=1)^n])`
|
|
68
|
+
* markupFunc: `#heading(level: 2)[something]`, `#text(fill: red)[some text and math $x + y$]`
|
|
67
69
|
*/
|
|
68
|
-
export type TypstNodeType = 'terminal' | 'group' | 'supsub' | 'funcCall' | 'fraction'| 'leftright' | '
|
|
70
|
+
export type TypstNodeType = 'terminal' | 'group' | 'supsub' | 'funcCall' | 'fraction'| 'leftright' | 'matrixLike'| 'markupFunc';
|
|
69
71
|
|
|
70
72
|
export type TypstNamedParams = { [key: string]: TypstNode; };
|
|
71
73
|
|
|
72
74
|
export abstract class TypstNode {
|
|
73
75
|
readonly type: TypstNodeType;
|
|
74
76
|
head: TypstToken;
|
|
75
|
-
args?: TypstNode[];
|
|
76
77
|
// Some Typst functions accept additional options. e.g. mat() has option "delim", op() has option "limits"
|
|
77
78
|
options?: TypstNamedParams;
|
|
78
79
|
|
|
79
|
-
constructor(type: TypstNodeType, head: TypstToken | null
|
|
80
|
+
constructor(type: TypstNodeType, head: TypstToken | null) {
|
|
80
81
|
this.type = type;
|
|
81
82
|
this.head = head ? head : TypstToken.NONE;
|
|
82
|
-
this.args = args;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// whether the node is over high so that if it's wrapped in braces, \left and \right should be used in its TeX form
|
|
@@ -115,12 +115,14 @@ export class TypstTerminal extends TypstNode {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
export class TypstGroup extends TypstNode {
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
public items: TypstNode[];
|
|
119
|
+
constructor(items: TypstNode[]) {
|
|
120
|
+
super('group', TypstToken.NONE);
|
|
121
|
+
this.items = items;
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
public isOverHigh(): boolean {
|
|
123
|
-
return this.
|
|
125
|
+
return this.items.some((n) => n.isOverHigh());
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
|
|
@@ -130,7 +132,7 @@ export class TypstSupsub extends TypstNode {
|
|
|
130
132
|
public sub: TypstNode | null;
|
|
131
133
|
|
|
132
134
|
constructor(data: TypstSupsubData) {
|
|
133
|
-
super('supsub', TypstToken.NONE
|
|
135
|
+
super('supsub', TypstToken.NONE);
|
|
134
136
|
this.base = data.base;
|
|
135
137
|
this.sup = data.sup;
|
|
136
138
|
this.sub = data.sub;
|
|
@@ -142,21 +144,26 @@ export class TypstSupsub extends TypstNode {
|
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
export class TypstFuncCall extends TypstNode {
|
|
147
|
+
public args: TypstNode[];
|
|
145
148
|
constructor(head: TypstToken, args: TypstNode[]) {
|
|
146
|
-
super('funcCall', head
|
|
149
|
+
super('funcCall', head);
|
|
150
|
+
this.args = args;
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
public isOverHigh(): boolean {
|
|
150
154
|
if (this.head.value === 'frac') {
|
|
151
155
|
return true;
|
|
152
156
|
}
|
|
153
|
-
return this.args
|
|
157
|
+
return this.args.some((n) => n.isOverHigh());
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
export class TypstFraction extends TypstNode {
|
|
162
|
+
public args: TypstNode[];
|
|
163
|
+
|
|
158
164
|
constructor(args: TypstNode[]) {
|
|
159
|
-
super('fraction', TypstToken.NONE
|
|
165
|
+
super('fraction', TypstToken.NONE);
|
|
166
|
+
this.args = args;
|
|
160
167
|
}
|
|
161
168
|
|
|
162
169
|
public isOverHigh(): boolean {
|
|
@@ -166,56 +173,57 @@ export class TypstFraction extends TypstNode {
|
|
|
166
173
|
|
|
167
174
|
|
|
168
175
|
export class TypstLeftright extends TypstNode {
|
|
176
|
+
public body: TypstNode;
|
|
169
177
|
public left: TypstToken | null;
|
|
170
178
|
public right: TypstToken | null;
|
|
171
179
|
|
|
172
|
-
|
|
173
|
-
|
|
180
|
+
// head is either null or 'lr'
|
|
181
|
+
constructor(head: TypstToken | null, data: TypstLeftRightData) {
|
|
182
|
+
super('leftright', head);
|
|
183
|
+
this.body = data.body;
|
|
174
184
|
this.left = data.left;
|
|
175
185
|
this.right = data.right;
|
|
176
186
|
}
|
|
177
187
|
|
|
178
188
|
public isOverHigh(): boolean {
|
|
179
|
-
return this.
|
|
189
|
+
return this.body.isOverHigh();
|
|
180
190
|
}
|
|
181
191
|
}
|
|
182
192
|
|
|
183
|
-
export class TypstAlign extends TypstNode {
|
|
184
|
-
public matrix: TypstNode[][];
|
|
185
193
|
|
|
186
|
-
|
|
187
|
-
super('align', TypstToken.NONE, []);
|
|
188
|
-
this.matrix = data;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
public isOverHigh(): boolean {
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export class TypstMatrix extends TypstNode {
|
|
194
|
+
export class TypstMatrixLike extends TypstNode {
|
|
197
195
|
public matrix: TypstNode[][];
|
|
198
196
|
|
|
199
|
-
|
|
200
|
-
|
|
197
|
+
// head is 'mat', 'cases' or null
|
|
198
|
+
constructor(head: TypstToken | null, data: TypstNode[][]) {
|
|
199
|
+
super('matrixLike', head);
|
|
201
200
|
this.matrix = data;
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
public isOverHigh(): boolean {
|
|
205
204
|
return true;
|
|
206
205
|
}
|
|
206
|
+
|
|
207
|
+
static readonly MAT = new TypstToken(TypstTokenType.SYMBOL, 'mat');
|
|
208
|
+
static readonly CASES = new TypstToken(TypstTokenType.SYMBOL, 'cases');
|
|
207
209
|
}
|
|
208
210
|
|
|
209
|
-
export class
|
|
210
|
-
|
|
211
|
+
export class TypstMarkupFunc extends TypstNode {
|
|
212
|
+
/*
|
|
213
|
+
In idealized situations, for `#heading([some text and math $x + y$ example])`,
|
|
214
|
+
fragments would be [TypstMarkup{"some text and math "}, TypstNode{"x + y"}, TypstMarkup{" example"}]
|
|
215
|
+
At present, we haven't implemented anything about TypstMarkup.
|
|
216
|
+
So only pattens like `#heading(level: 2)[$x+y$]`, `#text(fill: red)[$x + y$]` are supported.
|
|
217
|
+
Therefore, fragments is always a list containing exactly 1 TypstNode in well-working situations.
|
|
218
|
+
*/
|
|
219
|
+
public fragments: TypstNode[];
|
|
211
220
|
|
|
212
|
-
constructor(
|
|
213
|
-
super('
|
|
214
|
-
this.
|
|
221
|
+
constructor(head: TypstToken, fragments: TypstNode[]) {
|
|
222
|
+
super('markupFunc', head);
|
|
223
|
+
this.fragments = fragments;
|
|
215
224
|
}
|
|
216
225
|
|
|
217
226
|
public isOverHigh(): boolean {
|
|
218
|
-
return
|
|
227
|
+
return this.fragments.some((n) => n.isOverHigh());
|
|
219
228
|
}
|
|
220
229
|
}
|
|
221
|
-
|