@particle-academy/fancy-code 0.15.1 → 0.16.0

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.cjs CHANGED
@@ -268,864 +268,20 @@ function getRegisteredLanguages() {
268
268
  }
269
269
  return names;
270
270
  }
271
-
272
- // src/engine/tokenizers/javascript.ts
273
- var KEYWORDS = /* @__PURE__ */ new Set([
274
- "abstract",
275
- "arguments",
276
- "as",
277
- "async",
278
- "await",
279
- "boolean",
280
- "break",
281
- "byte",
282
- "case",
283
- "catch",
284
- "char",
285
- "class",
286
- "const",
287
- "continue",
288
- "debugger",
289
- "default",
290
- "delete",
291
- "do",
292
- "double",
293
- "else",
294
- "enum",
295
- "export",
296
- "extends",
297
- "false",
298
- "final",
299
- "finally",
300
- "float",
301
- "for",
302
- "from",
303
- "function",
304
- "get",
305
- "goto",
306
- "if",
307
- "implements",
308
- "import",
309
- "in",
310
- "instanceof",
311
- "int",
312
- "interface",
313
- "keyof",
314
- "let",
315
- "long",
316
- "native",
317
- "new",
318
- "null",
319
- "of",
320
- "package",
321
- "private",
322
- "protected",
323
- "public",
324
- "readonly",
325
- "return",
326
- "set",
327
- "short",
328
- "static",
329
- "super",
330
- "switch",
331
- "synchronized",
332
- "this",
333
- "throw",
334
- "throws",
335
- "transient",
336
- "true",
337
- "try",
338
- "type",
339
- "typeof",
340
- "undefined",
341
- "var",
342
- "void",
343
- "volatile",
344
- "while",
345
- "with",
346
- "yield"
347
- ]);
348
- var TYPE_KEYWORDS = /* @__PURE__ */ new Set([
349
- "string",
350
- "number",
351
- "boolean",
352
- "any",
353
- "void",
354
- "never",
355
- "unknown",
356
- "object",
357
- "symbol",
358
- "bigint",
359
- "undefined",
360
- "null"
361
- ]);
362
- var tokenizeJavaScript = (source) => {
363
- const tokens = [];
364
- const len = source.length;
365
- let i = 0;
366
- while (i < len) {
367
- const ch = source[i];
368
- if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
369
- i++;
370
- continue;
371
- }
372
- if (ch === "/" && source[i + 1] === "/") {
373
- const pos = i;
374
- i += 2;
375
- while (i < len && source[i] !== "\n") i++;
376
- tokens.push({ type: "comment", start: pos, end: i });
377
- continue;
378
- }
379
- if (ch === "/" && source[i + 1] === "*") {
380
- const pos = i;
381
- i += 2;
382
- while (i < len && !(source[i] === "*" && source[i + 1] === "/")) i++;
383
- i += 2;
384
- tokens.push({ type: "comment", start: pos, end: i });
385
- continue;
386
- }
387
- if (ch === "`") {
388
- const pos = i;
389
- i++;
390
- while (i < len && source[i] !== "`") {
391
- if (source[i] === "\\") i++;
392
- i++;
393
- }
394
- i++;
395
- tokens.push({ type: "string", start: pos, end: i });
396
- continue;
397
- }
398
- if (ch === '"' || ch === "'") {
399
- const pos = i;
400
- const quote = ch;
401
- i++;
402
- while (i < len && source[i] !== quote) {
403
- if (source[i] === "\\") i++;
404
- i++;
405
- }
406
- i++;
407
- tokens.push({ type: "string", start: pos, end: i });
408
- continue;
409
- }
410
- if (ch >= "0" && ch <= "9" || ch === "." && source[i + 1] >= "0" && source[i + 1] <= "9") {
411
- const pos = i;
412
- if (ch === "0" && (source[i + 1] === "x" || source[i + 1] === "X")) {
413
- i += 2;
414
- while (i < len && /[0-9a-fA-F_]/.test(source[i])) i++;
415
- } else if (ch === "0" && (source[i + 1] === "b" || source[i + 1] === "B")) {
416
- i += 2;
417
- while (i < len && /[01_]/.test(source[i])) i++;
418
- } else {
419
- while (i < len && /[0-9_.]/.test(source[i])) i++;
420
- if (i < len && (source[i] === "e" || source[i] === "E")) {
421
- i++;
422
- if (i < len && (source[i] === "+" || source[i] === "-")) i++;
423
- while (i < len && source[i] >= "0" && source[i] <= "9") i++;
424
- }
425
- }
426
- if (i < len && source[i] === "n") i++;
427
- tokens.push({ type: "number", start: pos, end: i });
428
- continue;
429
- }
430
- if (/[a-zA-Z_$]/.test(ch)) {
431
- const pos = i;
432
- i++;
433
- while (i < len && /[a-zA-Z0-9_$]/.test(source[i])) i++;
434
- const word = source.slice(pos, i);
435
- let j = i;
436
- while (j < len && (source[j] === " " || source[j] === " ")) j++;
437
- if (TYPE_KEYWORDS.has(word)) {
438
- tokens.push({ type: "type", start: pos, end: i });
439
- } else if (KEYWORDS.has(word)) {
440
- tokens.push({ type: "keyword", start: pos, end: i });
441
- } else if (source[j] === "(") {
442
- tokens.push({ type: "function", start: pos, end: i });
443
- } else if (word[0] >= "A" && word[0] <= "Z") {
444
- tokens.push({ type: "type", start: pos, end: i });
445
- } else {
446
- tokens.push({ type: "variable", start: pos, end: i });
447
- }
448
- continue;
449
- }
450
- if ("+-*/%=<>!&|^~?:".includes(ch)) {
451
- const pos = i;
452
- i++;
453
- while (i < len && "+-*/%=<>!&|^~?:".includes(source[i])) i++;
454
- tokens.push({ type: "operator", start: pos, end: i });
455
- continue;
456
- }
457
- if ("(){}[];,.@#".includes(ch)) {
458
- tokens.push({ type: "punctuation", start: i, end: i + 1 });
459
- i++;
460
- continue;
461
- }
462
- tokens.push({ type: "plain", start: i, end: i + 1 });
463
- i++;
464
- }
465
- return tokens;
466
- };
467
-
468
- // src/engine/tokenizers/php.ts
469
- var PHP_KEYWORDS = /* @__PURE__ */ new Set([
470
- "abstract",
471
- "and",
472
- "array",
473
- "as",
474
- "break",
475
- "callable",
476
- "case",
477
- "catch",
478
- "class",
479
- "clone",
480
- "const",
481
- "continue",
482
- "declare",
483
- "default",
484
- "do",
485
- "echo",
486
- "else",
487
- "elseif",
488
- "empty",
489
- "enddeclare",
490
- "endfor",
491
- "endforeach",
492
- "endif",
493
- "endswitch",
494
- "endwhile",
495
- "enum",
496
- "eval",
497
- "exit",
498
- "extends",
499
- "false",
500
- "final",
501
- "finally",
502
- "fn",
503
- "for",
504
- "foreach",
505
- "function",
506
- "global",
507
- "goto",
508
- "if",
509
- "implements",
510
- "include",
511
- "include_once",
512
- "instanceof",
513
- "insteadof",
514
- "interface",
515
- "isset",
516
- "list",
517
- "match",
518
- "namespace",
519
- "new",
520
- "null",
521
- "or",
522
- "print",
523
- "private",
524
- "protected",
525
- "public",
526
- "readonly",
527
- "require",
528
- "require_once",
529
- "return",
530
- "self",
531
- "static",
532
- "switch",
533
- "throw",
534
- "trait",
535
- "true",
536
- "try",
537
- "unset",
538
- "use",
539
- "var",
540
- "while",
541
- "xor",
542
- "yield"
543
- ]);
544
- function tokenizePhpBlock(source, offset) {
545
- const tokens = [];
546
- const len = source.length;
547
- let i = offset;
548
- while (i < len) {
549
- const ch = source[i];
550
- if (ch === "?" && source[i + 1] === ">") {
551
- return { tokens, end: i };
552
- }
553
- if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
554
- i++;
555
- continue;
556
- }
557
- if (ch === "/" && source[i + 1] === "/" || ch === "#") {
558
- const pos = i;
559
- while (i < len && source[i] !== "\n") i++;
560
- tokens.push({ type: "comment", start: pos, end: i });
561
- continue;
562
- }
563
- if (ch === "/" && source[i + 1] === "*") {
564
- const pos = i;
565
- i += 2;
566
- while (i < len && !(source[i] === "*" && source[i + 1] === "/")) i++;
567
- i += 2;
568
- tokens.push({ type: "comment", start: pos, end: i });
569
- continue;
570
- }
571
- if (ch === "$") {
572
- const pos = i;
573
- i++;
574
- while (i < len && /[a-zA-Z0-9_]/.test(source[i])) i++;
575
- tokens.push({ type: "variable", start: pos, end: i });
576
- continue;
577
- }
578
- if (ch === '"' || ch === "'") {
579
- const pos = i;
580
- const quote = ch;
581
- i++;
582
- while (i < len && source[i] !== quote) {
583
- if (source[i] === "\\") i++;
584
- i++;
585
- }
586
- i++;
587
- tokens.push({ type: "string", start: pos, end: i });
588
- continue;
589
- }
590
- if (ch >= "0" && ch <= "9") {
591
- const pos = i;
592
- while (i < len && /[0-9_.]/.test(source[i])) i++;
593
- if (i < len && (source[i] === "e" || source[i] === "E")) {
594
- i++;
595
- if (i < len && (source[i] === "+" || source[i] === "-")) i++;
596
- while (i < len && source[i] >= "0" && source[i] <= "9") i++;
597
- }
598
- tokens.push({ type: "number", start: pos, end: i });
599
- continue;
600
- }
601
- if (/[a-zA-Z_]/.test(ch)) {
602
- const pos = i;
603
- i++;
604
- while (i < len && /[a-zA-Z0-9_]/.test(source[i])) i++;
605
- const word = source.slice(pos, i);
606
- let j = i;
607
- while (j < len && (source[j] === " " || source[j] === " ")) j++;
608
- if (PHP_KEYWORDS.has(word.toLowerCase())) {
609
- tokens.push({ type: "keyword", start: pos, end: i });
610
- } else if (source[j] === "(") {
611
- tokens.push({ type: "function", start: pos, end: i });
612
- } else if (word[0] >= "A" && word[0] <= "Z") {
613
- tokens.push({ type: "type", start: pos, end: i });
614
- } else {
615
- tokens.push({ type: "variable", start: pos, end: i });
616
- }
617
- continue;
618
- }
619
- if ("+-*/%=<>!&|^~?:.".includes(ch)) {
620
- const pos = i;
621
- i++;
622
- while (i < len && "+-*/%=<>!&|^~?:.".includes(source[i])) i++;
623
- tokens.push({ type: "operator", start: pos, end: i });
624
- continue;
625
- }
626
- if ("(){}[];,@\\".includes(ch)) {
627
- tokens.push({ type: "punctuation", start: i, end: i + 1 });
628
- i++;
629
- continue;
630
- }
631
- tokens.push({ type: "plain", start: i, end: i + 1 });
632
- i++;
633
- }
634
- return { tokens, end: i };
635
- }
636
- var tokenizePhp = (source) => {
637
- const tokens = [];
638
- const len = source.length;
639
- let i = 0;
640
- let htmlChunkStart = 0;
641
- while (i < len) {
642
- if (source[i] === "<" && source[i + 1] === "?") {
643
- if (i > htmlChunkStart) {
644
- const htmlChunk = source.slice(htmlChunkStart, i);
645
- const htmlTokens = fancyFileCommons.tokenizeHtml(htmlChunk);
646
- for (const t of htmlTokens) {
647
- tokens.push({ type: t.type, start: t.start + htmlChunkStart, end: t.end + htmlChunkStart });
648
- }
649
- }
650
- const tagStart = i;
651
- i += 2;
652
- if (i < len && source.slice(i, i + 3).toLowerCase() === "php") {
653
- i += 3;
654
- } else if (i < len && source[i] === "=") {
655
- i++;
656
- }
657
- tokens.push({ type: "keyword", start: tagStart, end: i });
658
- const result = tokenizePhpBlock(source, i);
659
- tokens.push(...result.tokens);
660
- i = result.end;
661
- if (i < len && source[i] === "?" && source[i + 1] === ">") {
662
- tokens.push({ type: "keyword", start: i, end: i + 2 });
663
- i += 2;
664
- }
665
- htmlChunkStart = i;
666
- continue;
667
- }
668
- i++;
669
- }
670
- if (htmlChunkStart < len) {
671
- const htmlChunk = source.slice(htmlChunkStart);
672
- const htmlTokens = fancyFileCommons.tokenizeHtml(htmlChunk);
673
- for (const t of htmlTokens) {
674
- tokens.push({ type: t.type, start: t.start + htmlChunkStart, end: t.end + htmlChunkStart });
675
- }
676
- }
677
- return tokens;
678
- };
679
-
680
- // src/engine/tokenizers/python.ts
681
- var KEYWORDS2 = /* @__PURE__ */ new Set([
682
- "and",
683
- "as",
684
- "assert",
685
- "async",
686
- "await",
687
- "break",
688
- "class",
689
- "continue",
690
- "def",
691
- "del",
692
- "elif",
693
- "else",
694
- "except",
695
- "finally",
696
- "for",
697
- "from",
698
- "global",
699
- "if",
700
- "import",
701
- "in",
702
- "is",
703
- "lambda",
704
- "nonlocal",
705
- "not",
706
- "or",
707
- "pass",
708
- "raise",
709
- "return",
710
- "try",
711
- "while",
712
- "with",
713
- "yield",
714
- "True",
715
- "False",
716
- "None"
717
- ]);
718
- var TYPES = /* @__PURE__ */ new Set([
719
- "int",
720
- "str",
721
- "float",
722
- "bool",
723
- "list",
724
- "dict",
725
- "tuple",
726
- "set",
727
- "bytes",
728
- "bytearray",
729
- "memoryview",
730
- "range",
731
- "frozenset",
732
- "complex",
733
- "type",
734
- "object",
735
- "property",
736
- "classmethod",
737
- "staticmethod",
738
- "Any",
739
- "Optional",
740
- "Union",
741
- "Callable",
742
- "List",
743
- "Dict",
744
- "Tuple",
745
- "Set",
746
- "Sequence",
747
- "Mapping",
748
- "Iterator",
749
- "Generator",
750
- "Coroutine"
751
- ]);
752
- var tokenizePython = (source) => {
753
- const tokens = [];
754
- const len = source.length;
755
- let i = 0;
756
- while (i < len) {
757
- const ch = source[i];
758
- if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
759
- i++;
760
- continue;
761
- }
762
- if (ch === "#") {
763
- const pos = i;
764
- i++;
765
- while (i < len && source[i] !== "\n") i++;
766
- tokens.push({ type: "comment", start: pos, end: i });
767
- continue;
768
- }
769
- if (ch === "@" && i + 1 < len && /[a-zA-Z_]/.test(source[i + 1])) {
770
- const pos = i;
771
- i++;
772
- while (i < len && /[a-zA-Z0-9_.]/.test(source[i])) i++;
773
- tokens.push({ type: "keyword", start: pos, end: i });
774
- continue;
775
- }
776
- if (ch === '"' || ch === "'" || (ch === "f" || ch === "r" || ch === "b" || ch === "F" || ch === "R" || ch === "B") && (source[i + 1] === '"' || source[i + 1] === "'")) {
777
- const pos = i;
778
- if (ch !== '"' && ch !== "'") i++;
779
- const quote = source[i];
780
- if (source[i + 1] === quote && source[i + 2] === quote) {
781
- const triple = quote + quote + quote;
782
- i += 3;
783
- while (i < len && source.slice(i, i + 3) !== triple) {
784
- if (source[i] === "\\") i++;
785
- i++;
786
- }
787
- i += 3;
788
- tokens.push({ type: "string", start: pos, end: i });
789
- continue;
790
- }
791
- i++;
792
- while (i < len && source[i] !== quote && source[i] !== "\n") {
793
- if (source[i] === "\\") i++;
794
- i++;
795
- }
796
- if (i < len && source[i] === quote) i++;
797
- tokens.push({ type: "string", start: pos, end: i });
798
- continue;
799
- }
800
- if (ch >= "0" && ch <= "9" || ch === "." && i + 1 < len && source[i + 1] >= "0" && source[i + 1] <= "9") {
801
- const pos = i;
802
- if (ch === "0" && (source[i + 1] === "x" || source[i + 1] === "X")) {
803
- i += 2;
804
- while (i < len && /[0-9a-fA-F_]/.test(source[i])) i++;
805
- } else if (ch === "0" && (source[i + 1] === "b" || source[i + 1] === "B")) {
806
- i += 2;
807
- while (i < len && /[01_]/.test(source[i])) i++;
808
- } else if (ch === "0" && (source[i + 1] === "o" || source[i + 1] === "O")) {
809
- i += 2;
810
- while (i < len && /[0-7_]/.test(source[i])) i++;
811
- } else {
812
- while (i < len && /[0-9_.]/.test(source[i])) i++;
813
- if (i < len && (source[i] === "e" || source[i] === "E")) {
814
- i++;
815
- if (i < len && (source[i] === "+" || source[i] === "-")) i++;
816
- while (i < len && source[i] >= "0" && source[i] <= "9") i++;
817
- }
818
- }
819
- if (i < len && source[i] === "j") i++;
820
- tokens.push({ type: "number", start: pos, end: i });
821
- continue;
822
- }
823
- if (/[a-zA-Z_]/.test(ch)) {
824
- const pos = i;
825
- i++;
826
- while (i < len && /[a-zA-Z0-9_]/.test(source[i])) i++;
827
- const word = source.slice(pos, i);
828
- let j = i;
829
- while (j < len && (source[j] === " " || source[j] === " ")) j++;
830
- if (KEYWORDS2.has(word)) {
831
- tokens.push({ type: "keyword", start: pos, end: i });
832
- } else if (TYPES.has(word)) {
833
- tokens.push({ type: "type", start: pos, end: i });
834
- } else if (source[j] === "(") {
835
- tokens.push({ type: "function", start: pos, end: i });
836
- } else if (word[0] >= "A" && word[0] <= "Z") {
837
- tokens.push({ type: "type", start: pos, end: i });
838
- } else {
839
- tokens.push({ type: "variable", start: pos, end: i });
840
- }
841
- continue;
842
- }
843
- if ("+-*/%=<>!&|^~:@".includes(ch)) {
844
- const pos = i;
845
- i++;
846
- while (i < len && "+-*/%=<>!&|^~:".includes(source[i])) i++;
847
- tokens.push({ type: "operator", start: pos, end: i });
848
- continue;
849
- }
850
- if ("()[]{},.;\\".includes(ch)) {
851
- tokens.push({ type: "punctuation", start: i, end: i + 1 });
852
- i++;
853
- continue;
854
- }
855
- tokens.push({ type: "plain", start: i, end: i + 1 });
856
- i++;
857
- }
858
- return tokens;
859
- };
860
-
861
- // src/engine/tokenizers/go.ts
862
- var KEYWORDS3 = /* @__PURE__ */ new Set([
863
- "break",
864
- "case",
865
- "chan",
866
- "const",
867
- "continue",
868
- "default",
869
- "defer",
870
- "else",
871
- "fallthrough",
872
- "for",
873
- "func",
874
- "go",
875
- "goto",
876
- "if",
877
- "import",
878
- "interface",
879
- "map",
880
- "package",
881
- "range",
882
- "return",
883
- "select",
884
- "struct",
885
- "switch",
886
- "type",
887
- "var",
888
- "nil",
889
- "true",
890
- "false",
891
- "iota"
892
- ]);
893
- var TYPES2 = /* @__PURE__ */ new Set([
894
- "bool",
895
- "byte",
896
- "complex64",
897
- "complex128",
898
- "error",
899
- "float32",
900
- "float64",
901
- "int",
902
- "int8",
903
- "int16",
904
- "int32",
905
- "int64",
906
- "rune",
907
- "string",
908
- "uint",
909
- "uint8",
910
- "uint16",
911
- "uint32",
912
- "uint64",
913
- "uintptr",
914
- "any"
915
- ]);
916
- var BUILTINS = /* @__PURE__ */ new Set([
917
- "make",
918
- "len",
919
- "cap",
920
- "new",
921
- "append",
922
- "copy",
923
- "close",
924
- "delete",
925
- "complex",
926
- "real",
927
- "imag",
928
- "panic",
929
- "recover",
930
- "print",
931
- "println"
932
- ]);
933
- var tokenizeGo = (source) => {
934
- const tokens = [];
935
- const len = source.length;
936
- let i = 0;
937
- while (i < len) {
938
- const ch = source[i];
939
- if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
940
- i++;
941
- continue;
942
- }
943
- if (ch === "/" && source[i + 1] === "/") {
944
- const pos = i;
945
- i += 2;
946
- while (i < len && source[i] !== "\n") i++;
947
- tokens.push({ type: "comment", start: pos, end: i });
948
- continue;
949
- }
950
- if (ch === "/" && source[i + 1] === "*") {
951
- const pos = i;
952
- i += 2;
953
- while (i < len && !(source[i] === "*" && source[i + 1] === "/")) i++;
954
- i += 2;
955
- tokens.push({ type: "comment", start: pos, end: i });
956
- continue;
957
- }
958
- if (ch === "`") {
959
- const pos = i;
960
- i++;
961
- while (i < len && source[i] !== "`") i++;
962
- i++;
963
- tokens.push({ type: "string", start: pos, end: i });
964
- continue;
965
- }
966
- if (ch === '"') {
967
- const pos = i;
968
- i++;
969
- while (i < len && source[i] !== '"' && source[i] !== "\n") {
970
- if (source[i] === "\\") i++;
971
- i++;
972
- }
973
- if (i < len && source[i] === '"') i++;
974
- tokens.push({ type: "string", start: pos, end: i });
975
- continue;
976
- }
977
- if (ch === "'") {
978
- const pos = i;
979
- i++;
980
- while (i < len && source[i] !== "'" && source[i] !== "\n") {
981
- if (source[i] === "\\") i++;
982
- i++;
983
- }
984
- if (i < len && source[i] === "'") i++;
985
- tokens.push({ type: "string", start: pos, end: i });
986
- continue;
987
- }
988
- if (ch >= "0" && ch <= "9" || ch === "." && i + 1 < len && source[i + 1] >= "0" && source[i + 1] <= "9") {
989
- const pos = i;
990
- if (ch === "0" && (source[i + 1] === "x" || source[i + 1] === "X")) {
991
- i += 2;
992
- while (i < len && /[0-9a-fA-F_]/.test(source[i])) i++;
993
- } else if (ch === "0" && (source[i + 1] === "b" || source[i + 1] === "B")) {
994
- i += 2;
995
- while (i < len && /[01_]/.test(source[i])) i++;
996
- } else if (ch === "0" && (source[i + 1] === "o" || source[i + 1] === "O")) {
997
- i += 2;
998
- while (i < len && /[0-7_]/.test(source[i])) i++;
999
- } else {
1000
- while (i < len && /[0-9_.]/.test(source[i])) i++;
1001
- if (i < len && (source[i] === "e" || source[i] === "E")) {
1002
- i++;
1003
- if (i < len && (source[i] === "+" || source[i] === "-")) i++;
1004
- while (i < len && source[i] >= "0" && source[i] <= "9") i++;
1005
- }
1006
- }
1007
- if (i < len && source[i] === "i") i++;
1008
- tokens.push({ type: "number", start: pos, end: i });
1009
- continue;
1010
- }
1011
- if (/[a-zA-Z_]/.test(ch)) {
1012
- const pos = i;
1013
- i++;
1014
- while (i < len && /[a-zA-Z0-9_]/.test(source[i])) i++;
1015
- const word = source.slice(pos, i);
1016
- let j = i;
1017
- while (j < len && (source[j] === " " || source[j] === " ")) j++;
1018
- if (KEYWORDS3.has(word)) {
1019
- tokens.push({ type: "keyword", start: pos, end: i });
1020
- } else if (TYPES2.has(word)) {
1021
- tokens.push({ type: "type", start: pos, end: i });
1022
- } else if (BUILTINS.has(word) && source[j] === "(") {
1023
- tokens.push({ type: "function", start: pos, end: i });
1024
- } else if (source[j] === "(") {
1025
- tokens.push({ type: "function", start: pos, end: i });
1026
- } else if (word[0] >= "A" && word[0] <= "Z") {
1027
- tokens.push({ type: "type", start: pos, end: i });
1028
- } else {
1029
- tokens.push({ type: "variable", start: pos, end: i });
1030
- }
1031
- continue;
1032
- }
1033
- if ("+-*/%=<>!&|^~:".includes(ch)) {
1034
- const pos = i;
1035
- i++;
1036
- while (i < len && "+-*/%=<>!&|^~:".includes(source[i])) i++;
1037
- tokens.push({ type: "operator", start: pos, end: i });
1038
- continue;
1039
- }
1040
- if ("(){}[];,.".includes(ch)) {
1041
- tokens.push({ type: "punctuation", start: i, end: i + 1 });
1042
- i++;
1043
- continue;
1044
- }
1045
- tokens.push({ type: "plain", start: i, end: i + 1 });
1046
- i++;
1047
- }
1048
- return tokens;
1049
- };
1050
-
1051
- // src/engine/tokenizers/markdown.ts
1052
- function tokenizeMarkdown(source) {
1053
- const tokens = [];
1054
- const lines = source.split("\n");
1055
- let offset = 0;
1056
- let inFence = false;
1057
- for (const line of lines) {
1058
- const base = offset;
1059
- const len = line.length;
1060
- offset += len + 1;
1061
- if (/^\s*(```|~~~)/.test(line)) {
1062
- tokens.push(fancyFileCommons.tok("string", base, base + len));
1063
- inFence = !inFence;
1064
- continue;
1065
- }
1066
- if (inFence) {
1067
- tokens.push(fancyFileCommons.tok("string", base, base + len));
1068
- continue;
1069
- }
1070
- if (/^#{1,6}\s/.test(line)) {
1071
- tokens.push(fancyFileCommons.tok("keyword", base, base + len));
1072
- continue;
1073
- }
1074
- if (/^\s*>/.test(line)) {
1075
- tokens.push(fancyFileCommons.tok("comment", base, base + len));
1076
- continue;
1077
- }
1078
- const list = line.match(/^(\s*)([-*+]|\d+\.)\s/);
1079
- if (list) {
1080
- const start = base + list[1].length;
1081
- tokens.push(fancyFileCommons.tok("operator", start, start + list[2].length));
1082
- }
1083
- pushInline(line, base, tokens);
1084
- }
1085
- return tokens;
1086
- }
1087
- function pushInline(line, base, out) {
1088
- if (line.length > 5e3) return;
1089
- const spans = [];
1090
- const add = (type, start, end) => {
1091
- spans.push(fancyFileCommons.tok(type, base + start, base + end));
1092
- };
1093
- let m;
1094
- const code = /`[^`]+`/g;
1095
- while (m = code.exec(line)) add("string", m.index, m.index + m[0].length);
1096
- const emph = /(\*\*|__)(?=\S)([\s\S]*?\S)\1|(\*|_)(?=\S)([\s\S]*?\S)\3/g;
1097
- while (m = emph.exec(line)) add("type", m.index, m.index + m[0].length);
1098
- const link = /!?\[[^\]]*\]\(([^)]+)\)/g;
1099
- while (m = link.exec(line)) {
1100
- add("tag", m.index, m.index + m[0].length - m[1].length - 1);
1101
- const urlStart = m.index + m[0].length - m[1].length - 1;
1102
- add("attributeValue", urlStart, urlStart + m[1].length);
1103
- }
1104
- spans.sort((a, b) => a.start - b.start || b.end - a.end);
1105
- let lastEnd = -1;
1106
- for (const s of spans) {
1107
- if (s.start >= lastEnd) {
1108
- out.push(s);
1109
- lastEnd = s.end;
1110
- }
1111
- }
1112
- }
1113
-
1114
- // src/languages/builtin.ts
1115
271
  registerLanguage({
1116
272
  name: "Markdown",
1117
273
  aliases: ["md", "markdown", "mkd"],
1118
- tokenize: tokenizeMarkdown
274
+ tokenize: fancyFileCommons.tokenizeMarkdown
1119
275
  });
1120
276
  registerLanguage({
1121
277
  name: "JavaScript",
1122
278
  aliases: ["js", "javascript", "jsx"],
1123
- tokenize: tokenizeJavaScript
279
+ tokenize: fancyFileCommons.tokenizeJavaScript
1124
280
  });
1125
281
  registerLanguage({
1126
282
  name: "TypeScript",
1127
283
  aliases: ["ts", "typescript", "tsx"],
1128
- tokenize: tokenizeJavaScript
284
+ tokenize: fancyFileCommons.tokenizeJavaScript
1129
285
  // Same tokenizer — JS/TS syntax is identical for highlighting
1130
286
  });
1131
287
  registerLanguage({
@@ -1136,17 +292,27 @@ registerLanguage({
1136
292
  registerLanguage({
1137
293
  name: "PHP",
1138
294
  aliases: ["php"],
1139
- tokenize: tokenizePhp
295
+ tokenize: fancyFileCommons.tokenizePhp
1140
296
  });
1141
297
  registerLanguage({
1142
298
  name: "Python",
1143
299
  aliases: ["py", "python"],
1144
- tokenize: tokenizePython
300
+ tokenize: fancyFileCommons.tokenizePython
1145
301
  });
1146
302
  registerLanguage({
1147
303
  name: "Go",
1148
304
  aliases: ["go", "golang"],
1149
- tokenize: tokenizeGo
305
+ tokenize: fancyFileCommons.tokenizeGo
306
+ });
307
+ registerLanguage({
308
+ name: "Shell",
309
+ aliases: ["sh", "bash", "zsh", "shell"],
310
+ tokenize: fancyFileCommons.tokenizeShell
311
+ });
312
+ registerLanguage({
313
+ name: "Dotenv",
314
+ aliases: ["env", "dotenv"],
315
+ tokenize: fancyFileCommons.tokenizeDotenv
1150
316
  });
1151
317
  var iconBtnClass = "inline-flex items-center justify-center rounded-md p-1 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200";
1152
318
  function LanguageSelector() {
@@ -2081,6 +1247,10 @@ Object.defineProperty(exports, "languageFromFilename", {
2081
1247
  enumerable: true,
2082
1248
  get: function () { return fancyFileCommons.languageFromFilename; }
2083
1249
  });
1250
+ Object.defineProperty(exports, "tokenizeMarkdown", {
1251
+ enumerable: true,
1252
+ get: function () { return fancyFileCommons.tokenizeMarkdown; }
1253
+ });
2084
1254
  exports.CodeEditor = CodeEditor;
2085
1255
  exports.CodeEditorInputTag = CodeEditorInputTag;
2086
1256
  exports.FileViewer = FileViewer;
@@ -2100,7 +1270,6 @@ exports.registerOfficeViewer = registerOfficeViewer;
2100
1270
  exports.registerTheme = registerTheme;
2101
1271
  exports.renderMarkdown = renderMarkdown;
2102
1272
  exports.resolveFileKind = resolveFileKind;
2103
- exports.tokenizeMarkdown = tokenizeMarkdown;
2104
1273
  exports.useCodeEditor = useCodeEditor;
2105
1274
  exports.useCodeEditorInputTagAdapter = useCodeEditorInputTagAdapter;
2106
1275
  //# sourceMappingURL=index.cjs.map