tex2typst 0.6.1 → 0.6.2
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 +122 -238
- package/dist/tex2typst.min.js +10 -11
- package/package.json +1 -1
- package/src/convert.ts +7 -3
- package/src/lex.ts +70 -197
- package/src/tex-tokenizer.ts +29 -34
- package/src/typst-tokenizer.ts +43 -39
package/dist/index.js
CHANGED
|
@@ -324,7 +324,7 @@ function array_intersperse(array, sep) {
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
// src/lex.ts
|
|
327
|
-
var EOF =
|
|
327
|
+
var EOF = null;
|
|
328
328
|
function matchcompare(m1, m2) {
|
|
329
329
|
const m1_len = m1.reMatchArray[0].length;
|
|
330
330
|
const m2_len = m2.reMatchArray[0].length;
|
|
@@ -334,114 +334,31 @@ function matchcompare(m1, m2) {
|
|
|
334
334
|
return m1.index - m2.index;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
+
var ScanResult = class _ScanResult {
|
|
338
|
+
result;
|
|
339
|
+
status;
|
|
340
|
+
constructor(status, result) {
|
|
341
|
+
this.result = result;
|
|
342
|
+
this.status = status;
|
|
343
|
+
}
|
|
344
|
+
static Accepted(result) {
|
|
345
|
+
return new _ScanResult(0 /* ACCEPTED */, result);
|
|
346
|
+
}
|
|
347
|
+
static Rejected() {
|
|
348
|
+
return new _ScanResult(1 /* REJECTED */, []);
|
|
349
|
+
}
|
|
350
|
+
static Error(message) {
|
|
351
|
+
return new _ScanResult(2 /* ERROR */, []);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
337
354
|
var Scanner = class {
|
|
338
355
|
_input;
|
|
339
|
-
|
|
356
|
+
rules;
|
|
340
357
|
// position within input stream
|
|
341
358
|
_pos = 0;
|
|
342
|
-
|
|
343
|
-
_line = 0;
|
|
344
|
-
// current column number
|
|
345
|
-
_col = 0;
|
|
346
|
-
_offset = 0;
|
|
347
|
-
_less = null;
|
|
348
|
-
_go = false;
|
|
349
|
-
_newstate = null;
|
|
350
|
-
_state;
|
|
351
|
-
_text = null;
|
|
352
|
-
_leng = null;
|
|
353
|
-
_reMatchArray = null;
|
|
354
|
-
constructor(input, lexer) {
|
|
359
|
+
constructor(input, rules) {
|
|
355
360
|
this._input = input;
|
|
356
|
-
this.
|
|
357
|
-
this._state = lexer.states[0];
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Analogous to yytext and yyleng in lex - will be set during scan.
|
|
361
|
-
*/
|
|
362
|
-
text() {
|
|
363
|
-
return this._text;
|
|
364
|
-
}
|
|
365
|
-
leng() {
|
|
366
|
-
return this._leng;
|
|
367
|
-
}
|
|
368
|
-
reMatchArray() {
|
|
369
|
-
return this._reMatchArray;
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Position of in stream, line number and column number of match.
|
|
373
|
-
*/
|
|
374
|
-
pos() {
|
|
375
|
-
return this._pos;
|
|
376
|
-
}
|
|
377
|
-
line() {
|
|
378
|
-
return this._line;
|
|
379
|
-
}
|
|
380
|
-
column() {
|
|
381
|
-
return this._col;
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Analogous to input() in lex.
|
|
385
|
-
* @return {string} The next character in the stream.
|
|
386
|
-
*/
|
|
387
|
-
input() {
|
|
388
|
-
return this._input.charAt(this._pos + this._leng + this._offset++);
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Similar to unput() in lex, but does not allow modifying the stream.
|
|
392
|
-
* @return {int} The offset position after the operation.
|
|
393
|
-
*/
|
|
394
|
-
unput() {
|
|
395
|
-
return this._offset = this._offset > 0 ? this._offset-- : 0;
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Analogous to yyless(n) in lex - retains the first n characters from this pattern, and returns
|
|
399
|
-
* the rest to the input stream, such that they will be used in the next pattern-matching operation.
|
|
400
|
-
* @param {int} n Number of characters to retain.
|
|
401
|
-
* @return {int} Length of the stream after the operation has completed.
|
|
402
|
-
*/
|
|
403
|
-
less(n) {
|
|
404
|
-
this._less = n;
|
|
405
|
-
this._offset = 0;
|
|
406
|
-
this._text = this._text.substring(0, n);
|
|
407
|
-
return this._leng = this._text.length;
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Like less(), but instead of retaining the first n characters, it chops off the last n.
|
|
411
|
-
* @param {int} n Number of characters to chop.
|
|
412
|
-
* @return {int} Length of the stream after the operation has completed.
|
|
413
|
-
*/
|
|
414
|
-
pushback(n) {
|
|
415
|
-
return this.less(this._leng - n);
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Similar to REJECT in lex, except it doesn't break the current execution context.
|
|
419
|
-
* TIP: reject() should be the last instruction in a spec callback.
|
|
420
|
-
*/
|
|
421
|
-
reject() {
|
|
422
|
-
this._go = true;
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Analogous to BEGIN in lex - sets the named state (start condition).
|
|
426
|
-
* @param {string|int} state Name of state to switch to, or ordinal number (0 is first, etc).
|
|
427
|
-
* @return {string} The new state on successful switch, throws exception on failure.
|
|
428
|
-
*/
|
|
429
|
-
begin(state) {
|
|
430
|
-
if (this._lexer.specification[state]) {
|
|
431
|
-
return this._newstate = state;
|
|
432
|
-
}
|
|
433
|
-
const s = this._lexer.states[parseInt(state)];
|
|
434
|
-
if (s) {
|
|
435
|
-
return this._newstate = s;
|
|
436
|
-
}
|
|
437
|
-
throw "Unknown state '" + state + "' requested";
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* Simple accessor for reading in the current state.
|
|
441
|
-
* @return {string} The current state.
|
|
442
|
-
*/
|
|
443
|
-
state() {
|
|
444
|
-
return this._state;
|
|
361
|
+
this.rules = rules;
|
|
445
362
|
}
|
|
446
363
|
/**
|
|
447
364
|
* Scan method to be returned to caller - grabs the next token and fires appropriate calback.
|
|
@@ -452,7 +369,7 @@ var Scanner = class {
|
|
|
452
369
|
return EOF;
|
|
453
370
|
}
|
|
454
371
|
const str = this._input.substring(this._pos);
|
|
455
|
-
const rules = this.
|
|
372
|
+
const rules = this.rules;
|
|
456
373
|
const matches = [];
|
|
457
374
|
for (let i = 0; i < rules.length; i++) {
|
|
458
375
|
const rule = rules[i];
|
|
@@ -469,87 +386,50 @@ var Scanner = class {
|
|
|
469
386
|
throw new Error("No match found for input '" + str + "'");
|
|
470
387
|
}
|
|
471
388
|
matches.sort(matchcompare);
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
this._text = matched_text;
|
|
483
|
-
this._leng = matched_text.length;
|
|
484
|
-
this._reMatchArray = m.reMatchArray;
|
|
485
|
-
result = m.rule.action(this);
|
|
486
|
-
if (this._newstate && this._newstate != this._state) {
|
|
487
|
-
this._state = this._newstate;
|
|
488
|
-
break;
|
|
389
|
+
for (const m of matches) {
|
|
390
|
+
const matched_text = m.reMatchArray[0];
|
|
391
|
+
const result = m.rule.action({
|
|
392
|
+
pos: this._pos,
|
|
393
|
+
text: matched_text,
|
|
394
|
+
reMatchArray: m.reMatchArray
|
|
395
|
+
});
|
|
396
|
+
if (result.status === 0 /* ACCEPTED */) {
|
|
397
|
+
this._pos += matched_text.length;
|
|
398
|
+
return result.result;
|
|
489
399
|
}
|
|
490
400
|
}
|
|
491
|
-
|
|
492
|
-
const len = text.length;
|
|
493
|
-
this._pos += len + this._offset;
|
|
494
|
-
const nlm = text.match(/\n/g);
|
|
495
|
-
if (nlm !== null) {
|
|
496
|
-
this._line += nlm.length;
|
|
497
|
-
this._col = len - text.lastIndexOf("\n") - 1;
|
|
498
|
-
} else {
|
|
499
|
-
this._col += len;
|
|
500
|
-
}
|
|
501
|
-
return result;
|
|
401
|
+
throw new Error("No match found for input '" + str + "'");
|
|
502
402
|
}
|
|
503
403
|
};
|
|
504
404
|
var JSLex = class {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
throw "Duplicate state declaration encountered for state '" + s + "'";
|
|
514
|
-
}
|
|
515
|
-
this.specification[s] = [];
|
|
516
|
-
for (const [k, v] of rule_map.entries()) {
|
|
517
|
-
let re;
|
|
518
|
-
try {
|
|
519
|
-
re = new RegExp("^" + k);
|
|
520
|
-
} catch (err) {
|
|
521
|
-
throw "Invalid regexp '" + k + "' in state '" + s + "' (" + err.message + ")";
|
|
522
|
-
}
|
|
523
|
-
this.specification[s].push({
|
|
524
|
-
re,
|
|
525
|
-
action: v
|
|
526
|
-
});
|
|
405
|
+
rules = [];
|
|
406
|
+
constructor(ruleMap) {
|
|
407
|
+
for (const [k, v] of ruleMap.entries()) {
|
|
408
|
+
let re;
|
|
409
|
+
try {
|
|
410
|
+
re = new RegExp("^" + k);
|
|
411
|
+
} catch (err) {
|
|
412
|
+
throw "Invalid regexp '" + k + "' (" + err.message + ")";
|
|
527
413
|
}
|
|
414
|
+
this.rules.push({
|
|
415
|
+
re,
|
|
416
|
+
action: v
|
|
417
|
+
});
|
|
528
418
|
}
|
|
529
419
|
}
|
|
530
|
-
/**
|
|
531
|
-
* Scanner function - makes a new scanner object which is used to get tokens one at a time.
|
|
532
|
-
* @param {string} input Input text to tokenize.
|
|
533
|
-
* @return {function} Scanner function.
|
|
534
|
-
*/
|
|
535
|
-
scanner(input) {
|
|
536
|
-
return new Scanner(input, this);
|
|
537
|
-
}
|
|
538
420
|
/**
|
|
539
421
|
* Similar to lex's yylex() function, consumes all input, calling calback for each token.
|
|
540
422
|
* @param {string} input Text to lex.
|
|
541
423
|
* @param {function} callback Function to execute for each token.
|
|
542
424
|
*/
|
|
543
425
|
lex(input, callback) {
|
|
544
|
-
const scanner = this.
|
|
426
|
+
const scanner = new Scanner(input, this.rules);
|
|
545
427
|
while (true) {
|
|
546
428
|
const token = scanner.scan();
|
|
547
429
|
if (token === EOF) {
|
|
548
|
-
|
|
549
|
-
}
|
|
550
|
-
if (token !== void 0) {
|
|
551
|
-
callback(token);
|
|
430
|
+
break;
|
|
552
431
|
}
|
|
432
|
+
callback(token);
|
|
553
433
|
}
|
|
554
434
|
}
|
|
555
435
|
/**
|
|
@@ -647,8 +527,8 @@ var rules_map = /* @__PURE__ */ new Map([
|
|
|
647
527
|
[
|
|
648
528
|
String.raw`\\begin{(array|subarry)}{(.+?)}`,
|
|
649
529
|
(s) => {
|
|
650
|
-
const match = s.reMatchArray
|
|
651
|
-
return [
|
|
530
|
+
const match = s.reMatchArray;
|
|
531
|
+
return ScanResult.Accepted([
|
|
652
532
|
new TexToken(2 /* COMMAND */, "\\begin"),
|
|
653
533
|
new TexToken(7 /* CONTROL */, "{"),
|
|
654
534
|
new TexToken(3 /* LITERAL */, match[1]),
|
|
@@ -656,74 +536,69 @@ var rules_map = /* @__PURE__ */ new Map([
|
|
|
656
536
|
new TexToken(7 /* CONTROL */, "{"),
|
|
657
537
|
new TexToken(3 /* LITERAL */, match[2]),
|
|
658
538
|
new TexToken(7 /* CONTROL */, "}")
|
|
659
|
-
];
|
|
539
|
+
]);
|
|
660
540
|
}
|
|
661
541
|
],
|
|
662
542
|
[
|
|
663
543
|
String.raw`\\(text|operatorname\*?|textcolor|begin|end|hspace|array)\s*{(.+?)}`,
|
|
664
544
|
(s) => {
|
|
665
|
-
const match = s.reMatchArray
|
|
666
|
-
return [
|
|
545
|
+
const match = s.reMatchArray;
|
|
546
|
+
return ScanResult.Accepted([
|
|
667
547
|
new TexToken(2 /* COMMAND */, "\\" + match[1]),
|
|
668
548
|
new TexToken(7 /* CONTROL */, "{"),
|
|
669
549
|
new TexToken(3 /* LITERAL */, unescape(match[2])),
|
|
670
550
|
new TexToken(7 /* CONTROL */, "}")
|
|
671
|
-
];
|
|
551
|
+
]);
|
|
672
552
|
}
|
|
673
553
|
],
|
|
674
|
-
[String.raw`%[^\n]*`, (s) => new TexToken(4 /* COMMENT */, s.text
|
|
675
|
-
[String.raw`[{}_^&]`, (s) => new TexToken(7 /* CONTROL */, s.text
|
|
676
|
-
[String.raw`\\[\\,:;!> ]`, (s) => new TexToken(7 /* CONTROL */, s.text
|
|
677
|
-
[String.raw`~`, (s) => new TexToken(7 /* CONTROL */, s.text
|
|
678
|
-
[String.raw`\r?\n`, (_s) => new TexToken(6 /* NEWLINE */, "\n")],
|
|
679
|
-
[String.raw`\s+`, (s) => new TexToken(5 /* SPACE */, s.text
|
|
680
|
-
[String.raw`\\[{}%$&#_|]`, (s) => new TexToken(1 /* ELEMENT */, s.text
|
|
554
|
+
[String.raw`%[^\n]*`, (s) => ScanResult.Accepted(new TexToken(4 /* COMMENT */, s.text.substring(1)))],
|
|
555
|
+
[String.raw`[{}_^&]`, (s) => ScanResult.Accepted([new TexToken(7 /* CONTROL */, s.text)])],
|
|
556
|
+
[String.raw`\\[\\,:;!> ]`, (s) => ScanResult.Accepted([new TexToken(7 /* CONTROL */, s.text)])],
|
|
557
|
+
[String.raw`~`, (s) => ScanResult.Accepted([new TexToken(7 /* CONTROL */, s.text)])],
|
|
558
|
+
[String.raw`\r?\n`, (_s) => ScanResult.Accepted([new TexToken(6 /* NEWLINE */, "\n")])],
|
|
559
|
+
[String.raw`\s+`, (s) => ScanResult.Accepted([new TexToken(5 /* SPACE */, s.text)])],
|
|
560
|
+
[String.raw`\\[{}%$&#_|]`, (s) => ScanResult.Accepted([new TexToken(1 /* ELEMENT */, s.text)])],
|
|
681
561
|
// e.g. match `\frac13`, `\frac1 b`, `\frac a b`
|
|
682
562
|
[String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])\s*([0-9a-zA-Z])`, (s) => {
|
|
683
|
-
const match = s.reMatchArray
|
|
563
|
+
const match = s.reMatchArray;
|
|
684
564
|
const command = match[1];
|
|
685
565
|
if (TEX_BINARY_COMMANDS.includes(command.substring(1))) {
|
|
686
566
|
const arg1 = match[2].trimStart();
|
|
687
567
|
const arg2 = match[3];
|
|
688
|
-
return [
|
|
568
|
+
return ScanResult.Accepted([
|
|
689
569
|
new TexToken(2 /* COMMAND */, command),
|
|
690
570
|
new TexToken(1 /* ELEMENT */, arg1),
|
|
691
571
|
new TexToken(1 /* ELEMENT */, arg2)
|
|
692
|
-
];
|
|
572
|
+
]);
|
|
693
573
|
} else {
|
|
694
|
-
|
|
695
|
-
return [];
|
|
574
|
+
return ScanResult.Rejected();
|
|
696
575
|
}
|
|
697
576
|
}],
|
|
698
577
|
// e.g. match `\sqrt3`, `\sqrt a`
|
|
699
578
|
[String.raw`(\\[a-zA-Z]+)(\s*\d|\s+[a-zA-Z])`, (s) => {
|
|
700
|
-
const match = s.reMatchArray
|
|
579
|
+
const match = s.reMatchArray;
|
|
701
580
|
const command = match[1];
|
|
702
581
|
if (TEX_UNARY_COMMANDS.includes(command.substring(1))) {
|
|
703
582
|
const arg1 = match[2].trimStart();
|
|
704
|
-
return [
|
|
583
|
+
return ScanResult.Accepted([
|
|
705
584
|
new TexToken(2 /* COMMAND */, command),
|
|
706
585
|
new TexToken(1 /* ELEMENT */, arg1)
|
|
707
|
-
];
|
|
586
|
+
]);
|
|
708
587
|
} else {
|
|
709
|
-
|
|
710
|
-
return [];
|
|
588
|
+
return ScanResult.Rejected();
|
|
711
589
|
}
|
|
712
590
|
}],
|
|
713
|
-
[String.raw`\\[a-zA-Z]+`, (s) => new TexToken(2 /* COMMAND */, s.text
|
|
591
|
+
[String.raw`\\[a-zA-Z]+`, (s) => ScanResult.Accepted(new TexToken(2 /* COMMAND */, s.text))],
|
|
714
592
|
// Numbers like "123", "3.14"
|
|
715
|
-
[String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TexToken(1 /* ELEMENT */, s.text
|
|
716
|
-
[String.raw`[a-zA-Z]`, (s) => new TexToken(1 /* ELEMENT */, s.text
|
|
717
|
-
[String.raw`[+\-*/='<>!.,;:?()\[\]|]`, (s) => new TexToken(1 /* ELEMENT */, s.text
|
|
593
|
+
[String.raw`[0-9]+(\.[0-9]+)?`, (s) => ScanResult.Accepted(new TexToken(1 /* ELEMENT */, s.text))],
|
|
594
|
+
[String.raw`[a-zA-Z]`, (s) => ScanResult.Accepted(new TexToken(1 /* ELEMENT */, s.text))],
|
|
595
|
+
[String.raw`[+\-*/='<>!.,;:?()\[\]|]`, (s) => ScanResult.Accepted(new TexToken(1 /* ELEMENT */, s.text))],
|
|
718
596
|
// non-ASCII characters
|
|
719
|
-
[String.raw`[^\x00-\x7F]`, (s) => new TexToken(1 /* ELEMENT */, s.text
|
|
720
|
-
[String.raw`.`, (s) => new TexToken(8 /* UNKNOWN */, s.text
|
|
597
|
+
[String.raw`[^\x00-\x7F]`, (s) => ScanResult.Accepted(new TexToken(1 /* ELEMENT */, s.text))],
|
|
598
|
+
[String.raw`.`, (s) => ScanResult.Accepted([new TexToken(8 /* UNKNOWN */, s.text)])]
|
|
721
599
|
]);
|
|
722
|
-
var spec = {
|
|
723
|
-
"start": rules_map
|
|
724
|
-
};
|
|
725
600
|
function tokenize_tex(input) {
|
|
726
|
-
const lexer = new JSLex(
|
|
601
|
+
const lexer = new JSLex(rules_map);
|
|
727
602
|
return lexer.collect(input);
|
|
728
603
|
}
|
|
729
604
|
|
|
@@ -3065,8 +2940,6 @@ function tex_token_to_typst(token, options) {
|
|
|
3065
2940
|
case 7 /* CONTROL */: {
|
|
3066
2941
|
if (token.value === "\\\\") {
|
|
3067
2942
|
return new TypstToken(7 /* CONTROL */, "\\");
|
|
3068
|
-
} else if (token.value === "\\!") {
|
|
3069
|
-
return new TypstToken(1 /* SYMBOL */, "#h(-math.thin.amount)");
|
|
3070
2943
|
} else if (token.value === "~") {
|
|
3071
2944
|
const typst_symbol = symbolMap.get("~");
|
|
3072
2945
|
return new TypstToken(1 /* SYMBOL */, typst_symbol);
|
|
@@ -3166,6 +3039,12 @@ function convert_tex_node_to_typst(abstractNode, options) {
|
|
|
3166
3039
|
switch (abstractNode.type) {
|
|
3167
3040
|
case "terminal": {
|
|
3168
3041
|
const node2 = abstractNode;
|
|
3042
|
+
if (node2.head.eq(new TexToken(7 /* CONTROL */, "\\!"))) {
|
|
3043
|
+
return new TypstFuncCall(
|
|
3044
|
+
new TypstToken(1 /* SYMBOL */, "#h"),
|
|
3045
|
+
[new TypstToken(3 /* LITERAL */, "-math.thin.amount").toNode()]
|
|
3046
|
+
);
|
|
3047
|
+
}
|
|
3169
3048
|
return tex_token_to_typst(node2.head, options).toNode();
|
|
3170
3049
|
}
|
|
3171
3050
|
case "text": {
|
|
@@ -3880,64 +3759,69 @@ function generate_regex_for_shorthands() {
|
|
|
3880
3759
|
}
|
|
3881
3760
|
var REGEX_SHORTHANDS = generate_regex_for_shorthands();
|
|
3882
3761
|
var rules_map2 = /* @__PURE__ */ new Map([
|
|
3883
|
-
[String.raw`//[^\n]*`, (s) => new TypstToken(5 /* COMMENT */, s.text
|
|
3884
|
-
[String.raw`/`, (s) => new TypstToken(2 /* ELEMENT */, s.text
|
|
3885
|
-
[String.raw`[_^&]`, (s) => new TypstToken(7 /* CONTROL */, s.text
|
|
3886
|
-
[String.raw`\r?\n`, (_s) => new TypstToken(8 /* NEWLINE */, "\n")],
|
|
3887
|
-
[String.raw`\s+`, (s) => new TypstToken(6 /* SPACE */, s.text
|
|
3888
|
-
[String.raw`\\[$&#_]`, (s) => new TypstToken(2 /* ELEMENT */, s.text
|
|
3889
|
-
[
|
|
3890
|
-
|
|
3762
|
+
[String.raw`//[^\n]*`, (s) => ScanResult.Accepted(new TypstToken(5 /* COMMENT */, s.text.substring(2)))],
|
|
3763
|
+
[String.raw`/`, (s) => ScanResult.Accepted(new TypstToken(2 /* ELEMENT */, s.text))],
|
|
3764
|
+
[String.raw`[_^&]`, (s) => ScanResult.Accepted(new TypstToken(7 /* CONTROL */, s.text))],
|
|
3765
|
+
[String.raw`\r?\n`, (_s) => ScanResult.Accepted(new TypstToken(8 /* NEWLINE */, "\n"))],
|
|
3766
|
+
[String.raw`\s+`, (s) => ScanResult.Accepted(new TypstToken(6 /* SPACE */, s.text))],
|
|
3767
|
+
[String.raw`\\[$&#_]`, (s) => ScanResult.Accepted(new TypstToken(2 /* ELEMENT */, s.text))],
|
|
3768
|
+
[
|
|
3769
|
+
String.raw`\\\n`,
|
|
3770
|
+
(s) => ScanResult.Accepted([
|
|
3891
3771
|
new TypstToken(7 /* CONTROL */, "\\"),
|
|
3892
3772
|
new TypstToken(8 /* NEWLINE */, "\n")
|
|
3893
|
-
]
|
|
3894
|
-
|
|
3773
|
+
])
|
|
3774
|
+
],
|
|
3895
3775
|
[String.raw`\\\s`, (s) => {
|
|
3896
|
-
return [
|
|
3776
|
+
return ScanResult.Accepted([
|
|
3897
3777
|
new TypstToken(7 /* CONTROL */, "\\"),
|
|
3898
3778
|
new TypstToken(6 /* SPACE */, " ")
|
|
3899
|
-
];
|
|
3779
|
+
]);
|
|
3900
3780
|
}],
|
|
3901
3781
|
// this backslash is dummy and will be ignored in later stages
|
|
3902
|
-
[String.raw`\\\S`, (_s) => new TypstToken(7 /* CONTROL */, "")],
|
|
3782
|
+
[String.raw`\\\S`, (_s) => ScanResult.Accepted(new TypstToken(7 /* CONTROL */, ""))],
|
|
3903
3783
|
[
|
|
3904
3784
|
String.raw`"([^"]|(\\"))*"`,
|
|
3905
3785
|
(s) => {
|
|
3906
|
-
const text = s.text
|
|
3786
|
+
const text = s.text.substring(1, s.text.length - 1);
|
|
3907
3787
|
text.replaceAll('\\"', '"');
|
|
3908
|
-
return new TypstToken(4 /* TEXT */, text);
|
|
3788
|
+
return ScanResult.Accepted(new TypstToken(4 /* TEXT */, text));
|
|
3909
3789
|
}
|
|
3910
3790
|
],
|
|
3911
3791
|
[
|
|
3912
3792
|
REGEX_SHORTHANDS,
|
|
3913
3793
|
(s) => {
|
|
3914
|
-
const shorthand = s.text
|
|
3794
|
+
const shorthand = s.text;
|
|
3915
3795
|
const symbol = reverseShorthandMap.get(shorthand);
|
|
3916
|
-
return new TypstToken(1 /* SYMBOL */, symbol);
|
|
3796
|
+
return ScanResult.Accepted(new TypstToken(1 /* SYMBOL */, symbol));
|
|
3917
3797
|
}
|
|
3918
3798
|
],
|
|
3919
|
-
[String.raw`[0-9]+(\.[0-9]+)?`, (s) => new TypstToken(2 /* ELEMENT */, s.text
|
|
3920
|
-
[String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => new TypstToken(2 /* ELEMENT */, s.text
|
|
3921
|
-
[
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3799
|
+
[String.raw`[0-9]+(\.[0-9]+)?`, (s) => ScanResult.Accepted(new TypstToken(2 /* ELEMENT */, s.text))],
|
|
3800
|
+
[String.raw`[+\-*/=\'<>!.,;?()\[\]|]`, (s) => ScanResult.Accepted(new TypstToken(2 /* ELEMENT */, s.text))],
|
|
3801
|
+
[
|
|
3802
|
+
String.raw`#h\((.+?)\)`,
|
|
3803
|
+
(s) => {
|
|
3804
|
+
const match = s.reMatchArray;
|
|
3805
|
+
return ScanResult.Accepted([
|
|
3806
|
+
new TypstToken(1 /* SYMBOL */, "#h"),
|
|
3807
|
+
new TypstToken(2 /* ELEMENT */, "("),
|
|
3808
|
+
new TypstToken(3 /* LITERAL */, match[1]),
|
|
3809
|
+
new TypstToken(2 /* ELEMENT */, ")")
|
|
3810
|
+
]);
|
|
3811
|
+
}
|
|
3812
|
+
],
|
|
3813
|
+
[String.raw`#none`, (s) => ScanResult.Accepted(new TypstToken(0 /* NONE */, s.text))],
|
|
3814
|
+
[
|
|
3815
|
+
String.raw`#none`,
|
|
3816
|
+
(s) => ScanResult.Accepted(new TypstToken(0 /* NONE */, s.text))
|
|
3817
|
+
],
|
|
3931
3818
|
[String.raw`#?[a-zA-Z\.]+`, (s) => {
|
|
3932
|
-
return new TypstToken(s.text
|
|
3819
|
+
return ScanResult.Accepted(new TypstToken(s.text.length === 1 ? 2 /* ELEMENT */ : 1 /* SYMBOL */, s.text));
|
|
3933
3820
|
}],
|
|
3934
|
-
[String.raw`.`, (s) => new TypstToken(2 /* ELEMENT */, s.text
|
|
3821
|
+
[String.raw`.`, (s) => ScanResult.Accepted(new TypstToken(2 /* ELEMENT */, s.text))]
|
|
3935
3822
|
]);
|
|
3936
|
-
var spec2 = {
|
|
3937
|
-
"start": rules_map2
|
|
3938
|
-
};
|
|
3939
3823
|
function tokenize_typst(input) {
|
|
3940
|
-
const lexer = new JSLex(
|
|
3824
|
+
const lexer = new JSLex(rules_map2);
|
|
3941
3825
|
return lexer.collect(input);
|
|
3942
3826
|
}
|
|
3943
3827
|
|