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