@zuilib/text-editor 0.7.2 → 0.8.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
@@ -14,11 +14,11 @@ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
14
14
  import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
15
15
  import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
16
16
  import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
17
- import { CHECK_LIST, CODE, TRANSFORMERS as TRANSFORMERS2 } from "@lexical/markdown";
17
+ import { CHECK_LIST, CODE as CODE2, TRANSFORMERS as TRANSFORMERS2 } from "@lexical/markdown";
18
18
  import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
19
19
  import { HeadingNode, QuoteNode } from "@lexical/rich-text";
20
20
  import { ListItemNode, ListNode as ListNode2 } from "@lexical/list";
21
- import { CodeHighlightNode, CodeNode } from "@lexical/code";
21
+ import { CodeHighlightNode, CodeNode as CodeNode2 } from "@lexical/code";
22
22
  import { AutoLinkNode, LinkNode } from "@lexical/link";
23
23
  import { TableCellNode as TableCellNode2, TableNode as TableNode2, TableRowNode as TableRowNode2 } from "@lexical/table";
24
24
 
@@ -160,12 +160,1411 @@ function CodeBlockShortcutPlugin() {
160
160
  // src/plugins/CodeHighlightPlugin.tsx
161
161
  import { useEffect as useEffect3 } from "react";
162
162
  import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
163
- import { registerCodeHighlighting } from "@lexical/code";
163
+
164
+ // src/code/registry.ts
165
+ var PLAIN_LANGUAGE = "plain";
166
+ var PLAIN = {
167
+ name: PLAIN_LANGUAGE,
168
+ aliases: ["plaintext", "text", "txt"],
169
+ rules: []
170
+ };
171
+ var grammars = /* @__PURE__ */ new Map();
172
+ function normalize(name) {
173
+ return name.trim().toLowerCase();
174
+ }
175
+ function registerCodeLanguage(grammar) {
176
+ for (const name of [grammar.name, ...grammar.aliases ?? []]) {
177
+ grammars.set(normalize(name), grammar);
178
+ }
179
+ }
180
+ function hasCodeLanguage(name) {
181
+ return grammars.has(normalize(name));
182
+ }
183
+ function resolveCodeLanguage(name) {
184
+ if (!name) return PLAIN;
185
+ const key = normalize(name);
186
+ return grammars.get(key) ?? (key.startsWith("diff-") ? grammars.get("diff") : void 0) ?? PLAIN;
187
+ }
188
+ function getCodeLanguages() {
189
+ return [...new Set([...grammars.values()].map((g) => g.name))].sort();
190
+ }
191
+ registerCodeLanguage(PLAIN);
192
+
193
+ // src/code/languages/common.ts
194
+ var LINE_COMMENT = String.raw`//[^\n]*`;
195
+ var BLOCK_COMMENT = String.raw`/\*[^]*?(?:\*/|$)`;
196
+ var HASH_COMMENT = String.raw`#[^\n]*`;
197
+ var DOUBLE_QUOTED = String.raw`"(?:[^"\\\n]|\\[^])*"?`;
198
+ var SINGLE_QUOTED = String.raw`'(?:[^'\\\n]|\\[^])*'?`;
199
+ var TRIPLE_DOUBLE_QUOTED = String.raw`"""[^]*?(?:"""|$)`;
200
+ var TRIPLE_SINGLE_QUOTED = String.raw`'''[^]*?(?:'''|$)`;
201
+ var BACKTICK_QUOTED = String.raw`\`(?:[^\`\\]|\\[^])*\`?`;
202
+ var C_NUMBER = String.raw`\b(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d+)?)[a-zA-Z]*\b`;
203
+ var ANNOTATION = String.raw`@[\w.]+`;
204
+ var MEMBER = String.raw`(?<=\.\s*)[A-Za-z_$][\w$]*\b(?!\s*\()`;
205
+ var C_OPERATOR = String.raw`[-+*/%=!<>&|^~?:]+`;
206
+ var PUNCTUATION = String.raw`[{}()\[\];,.]`;
207
+
208
+ // src/code/languages/c.ts
209
+ var PREPROCESSOR = String.raw`(?<=^|\n)[ \t]*#[ \t]*\w+[^\n]*`;
210
+ var c = {
211
+ name: "c",
212
+ aliases: ["h", "cpp", "c++", "cc", "cxx", "hpp", "hh"],
213
+ rules: [
214
+ { type: "comment", match: LINE_COMMENT },
215
+ { type: "comment", match: BLOCK_COMMENT },
216
+ { type: "meta", match: PREPROCESSOR },
217
+ { type: "string", match: DOUBLE_QUOTED },
218
+ { type: "string", match: SINGLE_QUOTED },
219
+ { type: "number", match: C_NUMBER },
220
+ { type: "property", match: MEMBER },
221
+ { type: "operator", match: String.raw`->|::|` + C_OPERATOR },
222
+ { type: "punctuation", match: PUNCTUATION }
223
+ ],
224
+ keywords: [
225
+ "auto",
226
+ "break",
227
+ "case",
228
+ "const",
229
+ "continue",
230
+ "default",
231
+ "do",
232
+ "else",
233
+ "enum",
234
+ "extern",
235
+ "for",
236
+ "goto",
237
+ "if",
238
+ "inline",
239
+ "register",
240
+ "restrict",
241
+ "return",
242
+ "sizeof",
243
+ "static",
244
+ "struct",
245
+ "switch",
246
+ "typedef",
247
+ "union",
248
+ "volatile",
249
+ "while",
250
+ // C++
251
+ "catch",
252
+ "class",
253
+ "const_cast",
254
+ "constexpr",
255
+ "consteval",
256
+ "delete",
257
+ "dynamic_cast",
258
+ "explicit",
259
+ "export",
260
+ "final",
261
+ "friend",
262
+ "mutable",
263
+ "namespace",
264
+ "new",
265
+ "noexcept",
266
+ "operator",
267
+ "override",
268
+ "private",
269
+ "protected",
270
+ "public",
271
+ "reinterpret_cast",
272
+ "static_cast",
273
+ "template",
274
+ "this",
275
+ "throw",
276
+ "try",
277
+ "typename",
278
+ "using",
279
+ "virtual"
280
+ ],
281
+ types: [
282
+ "bool",
283
+ "char",
284
+ "double",
285
+ "float",
286
+ "int",
287
+ "long",
288
+ "short",
289
+ "signed",
290
+ "unsigned",
291
+ "void",
292
+ "wchar_t",
293
+ "size_t",
294
+ "ssize_t",
295
+ "int8_t",
296
+ "int16_t",
297
+ "int32_t",
298
+ "int64_t",
299
+ "uint8_t",
300
+ "uint16_t",
301
+ "uint32_t",
302
+ "uint64_t"
303
+ ],
304
+ constants: ["true", "false", "NULL", "nullptr"],
305
+ callIsFunction: true,
306
+ capitalizedIsType: true
307
+ };
308
+
309
+ // src/code/languages/css.ts
310
+ var css = {
311
+ name: "css",
312
+ aliases: ["scss", "less", "postcss"],
313
+ rules: [
314
+ { type: "comment", match: BLOCK_COMMENT },
315
+ { type: "comment", match: LINE_COMMENT },
316
+ { type: "keyword", match: String.raw`@[\w-]+|!\s*important\b` },
317
+ { type: "variable", match: String.raw`--[\w-]+|\$[\w-]+` },
318
+ { type: "string", match: DOUBLE_QUOTED },
319
+ { type: "string", match: SINGLE_QUOTED },
320
+ { type: "tag", match: String.raw`(?<=(?:^|[{};]|\*/)\s*)[^{};@\s][^{};]*?(?=\s*\{)` },
321
+ { type: "property", match: String.raw`(?<=[{;(]\s*)[-\w]+(?=\s*:)` },
322
+ { type: "constant", match: String.raw`#[\da-fA-F]{3,8}\b` },
323
+ { type: "function", match: String.raw`[-\w]+(?=\()` },
324
+ { type: "number", match: String.raw`(?<![\w-])[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?(?:%|[a-zA-Z]+)?` },
325
+ { type: "punctuation", match: String.raw`[{}()\[\];:,]` },
326
+ { type: "operator", match: String.raw`[>+~*/=]` }
327
+ ]
328
+ };
329
+
330
+ // src/code/languages/diff.ts
331
+ var LINE = String.raw`[^\n]*`;
332
+ var AT = String.raw`(?<=^|\n)`;
333
+ var diff = {
334
+ name: "diff",
335
+ aliases: ["patch"],
336
+ rules: [
337
+ { type: "comment", match: AT + String.raw`(?:diff |index |--- |\+\+\+ |Index: |={3,}|\*{3} )` + LINE },
338
+ { type: "meta", match: AT + String.raw`@@` + LINE },
339
+ { type: "inserted", match: AT + String.raw`\+` + LINE },
340
+ { type: "deleted", match: AT + "-" + LINE }
341
+ ]
342
+ };
343
+
344
+ // src/code/languages/go.ts
345
+ var go = {
346
+ name: "go",
347
+ aliases: ["golang"],
348
+ rules: [
349
+ { type: "comment", match: LINE_COMMENT },
350
+ { type: "comment", match: BLOCK_COMMENT },
351
+ { type: "string", match: String.raw`\`[^\`]*\`?` },
352
+ { type: "string", match: DOUBLE_QUOTED },
353
+ { type: "string", match: SINGLE_QUOTED },
354
+ { type: "number", match: C_NUMBER },
355
+ { type: "property", match: MEMBER },
356
+ { type: "operator", match: String.raw`:=|<-|\.\.\.|` + C_OPERATOR },
357
+ { type: "punctuation", match: PUNCTUATION }
358
+ ],
359
+ keywords: [
360
+ "break",
361
+ "case",
362
+ "chan",
363
+ "const",
364
+ "continue",
365
+ "default",
366
+ "defer",
367
+ "else",
368
+ "fallthrough",
369
+ "for",
370
+ "func",
371
+ "go",
372
+ "goto",
373
+ "if",
374
+ "import",
375
+ "interface",
376
+ "map",
377
+ "package",
378
+ "range",
379
+ "return",
380
+ "select",
381
+ "struct",
382
+ "switch",
383
+ "type",
384
+ "var"
385
+ ],
386
+ types: [
387
+ "any",
388
+ "bool",
389
+ "byte",
390
+ "comparable",
391
+ "complex64",
392
+ "complex128",
393
+ "error",
394
+ "float32",
395
+ "float64",
396
+ "int",
397
+ "int8",
398
+ "int16",
399
+ "int32",
400
+ "int64",
401
+ "rune",
402
+ "string",
403
+ "uint",
404
+ "uint8",
405
+ "uint16",
406
+ "uint32",
407
+ "uint64",
408
+ "uintptr"
409
+ ],
410
+ builtins: [
411
+ "append",
412
+ "cap",
413
+ "clear",
414
+ "close",
415
+ "complex",
416
+ "copy",
417
+ "delete",
418
+ "imag",
419
+ "len",
420
+ "make",
421
+ "max",
422
+ "min",
423
+ "new",
424
+ "panic",
425
+ "print",
426
+ "println",
427
+ "real",
428
+ "recover"
429
+ ],
430
+ constants: ["true", "false", "nil", "iota"],
431
+ callIsFunction: true,
432
+ // Exported names are Capitalized in Go; coloring them all as types is noise
433
+ capitalizedIsType: false
434
+ };
435
+
436
+ // src/code/languages/java.ts
437
+ var java = {
438
+ name: "java",
439
+ rules: [
440
+ { type: "comment", match: LINE_COMMENT },
441
+ { type: "comment", match: BLOCK_COMMENT },
442
+ { type: "string", match: TRIPLE_DOUBLE_QUOTED },
443
+ { type: "string", match: DOUBLE_QUOTED },
444
+ { type: "string", match: SINGLE_QUOTED },
445
+ { type: "meta", match: ANNOTATION },
446
+ { type: "number", match: C_NUMBER },
447
+ { type: "property", match: MEMBER },
448
+ { type: "operator", match: String.raw`->|::|` + C_OPERATOR },
449
+ { type: "punctuation", match: PUNCTUATION }
450
+ ],
451
+ keywords: [
452
+ "abstract",
453
+ "assert",
454
+ "break",
455
+ "case",
456
+ "catch",
457
+ "class",
458
+ "const",
459
+ "continue",
460
+ "default",
461
+ "do",
462
+ "else",
463
+ "enum",
464
+ "extends",
465
+ "final",
466
+ "finally",
467
+ "for",
468
+ "goto",
469
+ "if",
470
+ "implements",
471
+ "import",
472
+ "instanceof",
473
+ "interface",
474
+ "native",
475
+ "new",
476
+ "package",
477
+ "permits",
478
+ "private",
479
+ "protected",
480
+ "public",
481
+ "record",
482
+ "return",
483
+ "sealed",
484
+ "static",
485
+ "strictfp",
486
+ "super",
487
+ "switch",
488
+ "synchronized",
489
+ "this",
490
+ "throw",
491
+ "throws",
492
+ "transient",
493
+ "try",
494
+ "var",
495
+ "volatile",
496
+ "while",
497
+ "yield"
498
+ ],
499
+ types: ["boolean", "byte", "char", "double", "float", "int", "long", "short", "void"],
500
+ constants: ["true", "false", "null"],
501
+ callIsFunction: true,
502
+ capitalizedIsType: true
503
+ };
504
+
505
+ // src/code/languages/javascript.ts
506
+ var REGEX = String.raw`(?<=(?:^|[=(,:;!&|?{}\[+\-*%<>~^]|\breturn|\btypeof|\bcase|\bof|\bin)\s*)/(?![/*])(?:[^/\\\n\[]|\\[^]|\[(?:[^\]\\\n]|\\[^])*\])+/[dgimsuyv]*`;
507
+ var JSX_TAG = String.raw`(?<=<\/?)[A-Za-z][\w.:-]*`;
508
+ var javascript = {
509
+ name: "javascript",
510
+ aliases: ["js", "jsx", "mjs", "cjs", "typescript", "ts", "tsx", "mts", "cts"],
511
+ rules: [
512
+ { type: "comment", match: LINE_COMMENT },
513
+ { type: "comment", match: BLOCK_COMMENT },
514
+ { type: "string", match: BACKTICK_QUOTED },
515
+ { type: "string", match: DOUBLE_QUOTED },
516
+ { type: "string", match: SINGLE_QUOTED },
517
+ { type: "regex", match: REGEX },
518
+ { type: "meta", match: ANNOTATION },
519
+ { type: "number", match: C_NUMBER },
520
+ { type: "property", match: MEMBER },
521
+ { type: "tag", match: JSX_TAG },
522
+ { type: "operator", match: String.raw`=>|\.\.\.|` + C_OPERATOR },
523
+ { type: "punctuation", match: PUNCTUATION }
524
+ ],
525
+ keywords: [
526
+ "as",
527
+ "async",
528
+ "await",
529
+ "break",
530
+ "case",
531
+ "catch",
532
+ "class",
533
+ "const",
534
+ "continue",
535
+ "debugger",
536
+ "default",
537
+ "delete",
538
+ "do",
539
+ "else",
540
+ "enum",
541
+ "export",
542
+ "extends",
543
+ "finally",
544
+ "for",
545
+ "from",
546
+ "function",
547
+ "get",
548
+ "if",
549
+ "implements",
550
+ "import",
551
+ "in",
552
+ "instanceof",
553
+ "interface",
554
+ "let",
555
+ "new",
556
+ "of",
557
+ "package",
558
+ "private",
559
+ "protected",
560
+ "public",
561
+ "return",
562
+ "set",
563
+ "static",
564
+ "super",
565
+ "switch",
566
+ "this",
567
+ "throw",
568
+ "try",
569
+ "typeof",
570
+ "var",
571
+ "void",
572
+ "while",
573
+ "with",
574
+ "yield",
575
+ // TypeScript
576
+ "abstract",
577
+ "asserts",
578
+ "declare",
579
+ "infer",
580
+ "is",
581
+ "keyof",
582
+ "module",
583
+ "namespace",
584
+ "override",
585
+ "readonly",
586
+ "satisfies",
587
+ "type",
588
+ "unique"
589
+ ],
590
+ types: [
591
+ "any",
592
+ "bigint",
593
+ "boolean",
594
+ "never",
595
+ "null",
596
+ "number",
597
+ "object",
598
+ "string",
599
+ "symbol",
600
+ "undefined",
601
+ "unknown",
602
+ "void"
603
+ ],
604
+ builtins: [
605
+ "Array",
606
+ "BigInt",
607
+ "Boolean",
608
+ "Date",
609
+ "Error",
610
+ "JSON",
611
+ "Map",
612
+ "Math",
613
+ "Number",
614
+ "Object",
615
+ "Promise",
616
+ "Proxy",
617
+ "Reflect",
618
+ "RegExp",
619
+ "Set",
620
+ "String",
621
+ "Symbol",
622
+ "WeakMap",
623
+ "WeakSet",
624
+ "console",
625
+ "document",
626
+ "globalThis",
627
+ "window",
628
+ "parseFloat",
629
+ "parseInt",
630
+ "setTimeout",
631
+ "setInterval",
632
+ "clearTimeout",
633
+ "clearInterval",
634
+ "fetch",
635
+ "require",
636
+ "process"
637
+ ],
638
+ constants: ["true", "false", "null", "undefined", "NaN", "Infinity"],
639
+ callIsFunction: true,
640
+ capitalizedIsType: true
641
+ };
642
+
643
+ // src/code/languages/json.ts
644
+ var json = {
645
+ name: "json",
646
+ aliases: ["jsonc", "json5"],
647
+ rules: [
648
+ { type: "comment", match: String.raw`//[^\n]*|/\*[^]*?(?:\*/|$)` },
649
+ { type: "property", match: String.raw`"(?:[^"\\\n]|\\[^])*"(?=\s*:)` },
650
+ { type: "string", match: String.raw`"(?:[^"\\\n]|\\[^])*"?` },
651
+ { type: "number", match: String.raw`-?\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b` },
652
+ { type: "punctuation", match: String.raw`[{}\[\]:,]` }
653
+ ],
654
+ constants: ["true", "false", "null"]
655
+ };
656
+
657
+ // src/code/languages/kotlin.ts
658
+ var kotlin = {
659
+ name: "kotlin",
660
+ aliases: ["kt", "kts"],
661
+ rules: [
662
+ { type: "comment", match: LINE_COMMENT },
663
+ { type: "comment", match: BLOCK_COMMENT },
664
+ { type: "string", match: TRIPLE_DOUBLE_QUOTED },
665
+ { type: "string", match: DOUBLE_QUOTED },
666
+ { type: "string", match: SINGLE_QUOTED },
667
+ { type: "meta", match: ANNOTATION },
668
+ { type: "number", match: C_NUMBER },
669
+ { type: "property", match: MEMBER },
670
+ { type: "operator", match: String.raw`->|\.\.|\?:|!!|` + C_OPERATOR },
671
+ { type: "punctuation", match: PUNCTUATION }
672
+ ],
673
+ keywords: [
674
+ "abstract",
675
+ "actual",
676
+ "annotation",
677
+ "as",
678
+ "break",
679
+ "by",
680
+ "catch",
681
+ "class",
682
+ "companion",
683
+ "const",
684
+ "constructor",
685
+ "continue",
686
+ "crossinline",
687
+ "data",
688
+ "do",
689
+ "else",
690
+ "enum",
691
+ "expect",
692
+ "external",
693
+ "final",
694
+ "finally",
695
+ "for",
696
+ "fun",
697
+ "get",
698
+ "if",
699
+ "import",
700
+ "in",
701
+ "infix",
702
+ "init",
703
+ "inline",
704
+ "inner",
705
+ "interface",
706
+ "internal",
707
+ "is",
708
+ "lateinit",
709
+ "noinline",
710
+ "object",
711
+ "open",
712
+ "operator",
713
+ "out",
714
+ "override",
715
+ "package",
716
+ "private",
717
+ "protected",
718
+ "public",
719
+ "reified",
720
+ "return",
721
+ "sealed",
722
+ "set",
723
+ "super",
724
+ "suspend",
725
+ "tailrec",
726
+ "this",
727
+ "throw",
728
+ "try",
729
+ "typealias",
730
+ "val",
731
+ "value",
732
+ "var",
733
+ "vararg",
734
+ "when",
735
+ "where",
736
+ "while"
737
+ ],
738
+ builtins: [
739
+ "it",
740
+ "println",
741
+ "print",
742
+ "listOf",
743
+ "mutableListOf",
744
+ "mapOf",
745
+ "mutableMapOf",
746
+ "setOf",
747
+ "mutableSetOf",
748
+ "arrayOf",
749
+ "emptyList",
750
+ "emptyMap",
751
+ "lazy",
752
+ "require",
753
+ "check",
754
+ "error",
755
+ "TODO",
756
+ "apply",
757
+ "also",
758
+ "let",
759
+ "run",
760
+ "with",
761
+ "takeIf",
762
+ "takeUnless",
763
+ "repeat"
764
+ ],
765
+ constants: ["true", "false", "null"],
766
+ callIsFunction: true,
767
+ capitalizedIsType: true
768
+ };
769
+
770
+ // src/code/languages/markdown.ts
771
+ var AT2 = String.raw`(?<=^|\n)`;
772
+ var markdown = {
773
+ name: "markdown",
774
+ aliases: ["md", "mdx"],
775
+ rules: [
776
+ { type: "comment", match: String.raw`<!--[^]*?(?:-->|$)` },
777
+ { type: "string", match: String.raw`\`\`\`[^]*?(?:\`\`\`|$)|\`[^\`\n]*\`` },
778
+ { type: "keyword", match: AT2 + String.raw`#{1,6}[ \t][^\n]*` },
779
+ { type: "meta", match: AT2 + String.raw`(?:>|[-*+]|\d+\.)(?=\s)` },
780
+ { type: "tag", match: String.raw`\*\*[^*\n]+\*\*|__[^_\n]+__` },
781
+ { type: "variable", match: String.raw`(?<![*\w])\*[^*\n]+\*(?!\w)|(?<![_\w])_[^_\n]+_(?!\w)` },
782
+ { type: "function", match: String.raw`!?\[[^\]\n]*\](?=\()` },
783
+ { type: "string", match: String.raw`(?<=\]\()[^)\n]*(?=\))` },
784
+ { type: "punctuation", match: AT2 + String.raw`(?:---+|\*\*\*+|___+)(?=\n|$)` }
785
+ ]
786
+ };
787
+
788
+ // src/code/languages/markup.ts
789
+ var markup = {
790
+ name: "html",
791
+ aliases: ["xml", "svg", "xhtml", "vue", "markup", "rss", "atom"],
792
+ rules: [
793
+ { type: "comment", match: String.raw`<!--[^]*?(?:-->|$)` },
794
+ { type: "string", match: String.raw`<!\[CDATA\[[^]*?(?:\]\]>|$)` },
795
+ { type: "meta", match: String.raw`<![\w]+[^>]*>?|<\?[^]*?(?:\?>|$)` },
796
+ { type: "tag", match: String.raw`(?<=<\/?)[A-Za-z][\w:.-]*` },
797
+ { type: "string", match: String.raw`(?<=<[^>]*=\s*)(?:"[^"]*"|'[^']*')` },
798
+ { type: "attr", match: String.raw`(?<=<[^>]*\s)[^\s"'<>/=]+` },
799
+ { type: "punctuation", match: String.raw`<\/?|\/?>|(?<=<[^>]*)=` },
800
+ { type: "constant", match: String.raw`&#?\w+;` }
801
+ ]
802
+ };
803
+
804
+ // src/code/languages/python.ts
805
+ var PREFIX = String.raw`(?:\b[rRbBuUfF]{1,2})?`;
806
+ var NUMBER = String.raw`\b(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d+)?[jJ]?)\b`;
807
+ var python = {
808
+ name: "python",
809
+ aliases: ["py", "py3"],
810
+ rules: [
811
+ { type: "comment", match: HASH_COMMENT },
812
+ { type: "string", match: PREFIX + String.raw`"""[^]*?(?:"""|$)` },
813
+ { type: "string", match: PREFIX + String.raw`'''[^]*?(?:'''|$)` },
814
+ { type: "string", match: PREFIX + String.raw`"(?:[^"\\\n]|\\[^])*"?` },
815
+ { type: "string", match: PREFIX + String.raw`'(?:[^'\\\n]|\\[^])*'?` },
816
+ { type: "meta", match: String.raw`@[\w.]+` },
817
+ { type: "number", match: NUMBER },
818
+ { type: "property", match: MEMBER },
819
+ { type: "operator", match: String.raw`->|:=|\*\*|//|[-+*/%=!<>&|^~@]+` },
820
+ { type: "punctuation", match: PUNCTUATION + "|:" }
821
+ ],
822
+ keywords: [
823
+ "and",
824
+ "as",
825
+ "assert",
826
+ "async",
827
+ "await",
828
+ "break",
829
+ "case",
830
+ "class",
831
+ "continue",
832
+ "def",
833
+ "del",
834
+ "elif",
835
+ "else",
836
+ "except",
837
+ "finally",
838
+ "for",
839
+ "from",
840
+ "global",
841
+ "if",
842
+ "import",
843
+ "in",
844
+ "is",
845
+ "lambda",
846
+ "match",
847
+ "nonlocal",
848
+ "not",
849
+ "or",
850
+ "pass",
851
+ "raise",
852
+ "return",
853
+ "try",
854
+ "while",
855
+ "with",
856
+ "yield"
857
+ ],
858
+ builtins: [
859
+ "self",
860
+ "cls",
861
+ "print",
862
+ "len",
863
+ "range",
864
+ "enumerate",
865
+ "zip",
866
+ "map",
867
+ "filter",
868
+ "sorted",
869
+ "reversed",
870
+ "open",
871
+ "input",
872
+ "abs",
873
+ "min",
874
+ "max",
875
+ "sum",
876
+ "any",
877
+ "all",
878
+ "iter",
879
+ "next",
880
+ "isinstance",
881
+ "issubclass",
882
+ "getattr",
883
+ "setattr",
884
+ "hasattr",
885
+ "super",
886
+ "type",
887
+ "id",
888
+ "hash",
889
+ "repr",
890
+ "format",
891
+ "vars",
892
+ "dir"
893
+ ],
894
+ types: ["int", "float", "str", "bytes", "bool", "list", "dict", "set", "tuple", "object", "complex", "frozenset"],
895
+ constants: ["True", "False", "None", "Ellipsis", "NotImplemented"],
896
+ callIsFunction: true,
897
+ capitalizedIsType: true
898
+ };
899
+
900
+ // src/code/languages/rust.ts
901
+ var NUMBER2 = String.raw`\b(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d+)?)(?:[iuf](?:8|16|32|64|128|size))?\b`;
902
+ var rust = {
903
+ name: "rust",
904
+ aliases: ["rs"],
905
+ rules: [
906
+ { type: "comment", match: LINE_COMMENT },
907
+ { type: "comment", match: BLOCK_COMMENT },
908
+ { type: "meta", match: String.raw`#!?\[[^\]\n]*\]` },
909
+ { type: "string", match: String.raw`b?r#*"[^]*?(?:"#*|$)` },
910
+ { type: "string", match: String.raw`b?"(?:[^"\\]|\\[^])*"?` },
911
+ { type: "string", match: String.raw`b?'(?:[^'\\\n]|\\[^])'` },
912
+ { type: "variable", match: String.raw`'[a-z_]\w*\b(?!')` },
913
+ { type: "function", match: String.raw`\b[a-z_]\w*!(?=[\s(\[{])` },
914
+ { type: "number", match: NUMBER2 },
915
+ { type: "property", match: MEMBER },
916
+ { type: "operator", match: String.raw`->|=>|::|\.\.=?|` + C_OPERATOR },
917
+ { type: "punctuation", match: PUNCTUATION + "|#" }
918
+ ],
919
+ keywords: [
920
+ "as",
921
+ "async",
922
+ "await",
923
+ "break",
924
+ "const",
925
+ "continue",
926
+ "crate",
927
+ "dyn",
928
+ "else",
929
+ "enum",
930
+ "extern",
931
+ "fn",
932
+ "for",
933
+ "if",
934
+ "impl",
935
+ "in",
936
+ "let",
937
+ "loop",
938
+ "match",
939
+ "mod",
940
+ "move",
941
+ "mut",
942
+ "pub",
943
+ "ref",
944
+ "return",
945
+ "self",
946
+ "Self",
947
+ "static",
948
+ "struct",
949
+ "super",
950
+ "trait",
951
+ "type",
952
+ "union",
953
+ "unsafe",
954
+ "use",
955
+ "where",
956
+ "while"
957
+ ],
958
+ types: [
959
+ "bool",
960
+ "char",
961
+ "f32",
962
+ "f64",
963
+ "i8",
964
+ "i16",
965
+ "i32",
966
+ "i64",
967
+ "i128",
968
+ "isize",
969
+ "str",
970
+ "u8",
971
+ "u16",
972
+ "u32",
973
+ "u64",
974
+ "u128",
975
+ "usize",
976
+ "String",
977
+ "Vec",
978
+ "Option",
979
+ "Result",
980
+ "Box",
981
+ "Rc",
982
+ "Arc",
983
+ "HashMap",
984
+ "HashSet"
985
+ ],
986
+ constants: ["true", "false", "None", "Some", "Ok", "Err"],
987
+ callIsFunction: true,
988
+ capitalizedIsType: true
989
+ };
990
+
991
+ // src/code/languages/shell.ts
992
+ var shell = {
993
+ name: "shell",
994
+ aliases: ["sh", "bash", "zsh", "console", "shellsession"],
995
+ rules: [
996
+ { type: "variable", match: String.raw`\$\{[^}\n]*\}|\$\w+|\$[@#?*!$-]` },
997
+ { type: "comment", match: String.raw`(?<=^|\s)#[^\n]*` },
998
+ { type: "string", match: String.raw`"(?:[^"\\\n]|\\[^])*"?` },
999
+ { type: "string", match: String.raw`'[^'\n]*'?` },
1000
+ { type: "punctuation", match: String.raw`(?<=^|\n)[$#](?=\s)` },
1001
+ { type: "attr", match: String.raw`(?<=\s)--?[A-Za-z][\w-]*` },
1002
+ { type: "operator", match: String.raw`\|\|?|&&?|;;?|[<>]+|=` },
1003
+ { type: "punctuation", match: String.raw`[(){}\[\]]` }
1004
+ ],
1005
+ identifier: String.raw`[A-Za-z_][\w.-]*`,
1006
+ keywords: [
1007
+ "if",
1008
+ "then",
1009
+ "else",
1010
+ "elif",
1011
+ "fi",
1012
+ "for",
1013
+ "while",
1014
+ "until",
1015
+ "do",
1016
+ "done",
1017
+ "case",
1018
+ "esac",
1019
+ "in",
1020
+ "function",
1021
+ "select",
1022
+ "time",
1023
+ "return",
1024
+ "exit",
1025
+ "local",
1026
+ "export",
1027
+ "readonly",
1028
+ "declare",
1029
+ "set",
1030
+ "unset",
1031
+ "shift",
1032
+ "source",
1033
+ "alias",
1034
+ "break",
1035
+ "continue"
1036
+ ],
1037
+ builtins: [
1038
+ "echo",
1039
+ "cd",
1040
+ "ls",
1041
+ "pwd",
1042
+ "cat",
1043
+ "grep",
1044
+ "sed",
1045
+ "awk",
1046
+ "mkdir",
1047
+ "rm",
1048
+ "cp",
1049
+ "mv",
1050
+ "chmod",
1051
+ "chown",
1052
+ "curl",
1053
+ "wget",
1054
+ "git",
1055
+ "npm",
1056
+ "pnpm",
1057
+ "yarn",
1058
+ "npx",
1059
+ "node",
1060
+ "python",
1061
+ "python3",
1062
+ "pip",
1063
+ "docker",
1064
+ "kubectl",
1065
+ "sudo",
1066
+ "test",
1067
+ "printf",
1068
+ "read",
1069
+ "eval",
1070
+ "exec",
1071
+ "trap",
1072
+ "wait",
1073
+ "kill",
1074
+ "ps",
1075
+ "tar",
1076
+ "zip",
1077
+ "unzip",
1078
+ "touch",
1079
+ "find",
1080
+ "xargs",
1081
+ "sort",
1082
+ "uniq",
1083
+ "head",
1084
+ "tail",
1085
+ "wc",
1086
+ "tee",
1087
+ "which",
1088
+ "env",
1089
+ "ssh",
1090
+ "scp",
1091
+ "make",
1092
+ "cargo",
1093
+ "go",
1094
+ "brew",
1095
+ "apt",
1096
+ "apt-get",
1097
+ "gradle",
1098
+ "mvn",
1099
+ "java",
1100
+ "jq",
1101
+ "true",
1102
+ "false"
1103
+ ]
1104
+ };
1105
+
1106
+ // src/code/languages/sql.ts
1107
+ var sql = {
1108
+ name: "sql",
1109
+ aliases: ["mysql", "postgres", "postgresql", "pgsql", "plsql", "sqlite", "soql"],
1110
+ caseInsensitive: true,
1111
+ rules: [
1112
+ { type: "comment", match: String.raw`--[^\n]*` },
1113
+ { type: "comment", match: BLOCK_COMMENT },
1114
+ { type: "string", match: String.raw`'(?:[^'\n]|'')*'?` },
1115
+ { type: "variable", match: String.raw`[@:]\w+|\$\d+` },
1116
+ { type: "number", match: String.raw`\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b` },
1117
+ { type: "operator", match: String.raw`\|\||::|[-+*/%=<>!]+` },
1118
+ { type: "punctuation", match: String.raw`[(),;.]` }
1119
+ ],
1120
+ keywords: [
1121
+ "add",
1122
+ "all",
1123
+ "alter",
1124
+ "and",
1125
+ "as",
1126
+ "asc",
1127
+ "begin",
1128
+ "between",
1129
+ "by",
1130
+ "cascade",
1131
+ "case",
1132
+ "check",
1133
+ "column",
1134
+ "commit",
1135
+ "constraint",
1136
+ "create",
1137
+ "cross",
1138
+ "default",
1139
+ "delete",
1140
+ "desc",
1141
+ "distinct",
1142
+ "drop",
1143
+ "else",
1144
+ "end",
1145
+ "except",
1146
+ "exists",
1147
+ "foreign",
1148
+ "from",
1149
+ "full",
1150
+ "group",
1151
+ "having",
1152
+ "if",
1153
+ "in",
1154
+ "index",
1155
+ "inner",
1156
+ "insert",
1157
+ "intersect",
1158
+ "into",
1159
+ "is",
1160
+ "join",
1161
+ "key",
1162
+ "left",
1163
+ "like",
1164
+ "limit",
1165
+ "not",
1166
+ "null",
1167
+ "offset",
1168
+ "on",
1169
+ "or",
1170
+ "order",
1171
+ "outer",
1172
+ "primary",
1173
+ "references",
1174
+ "returning",
1175
+ "right",
1176
+ "rollback",
1177
+ "select",
1178
+ "set",
1179
+ "table",
1180
+ "then",
1181
+ "top",
1182
+ "transaction",
1183
+ "truncate",
1184
+ "union",
1185
+ "unique",
1186
+ "update",
1187
+ "using",
1188
+ "values",
1189
+ "view",
1190
+ "when",
1191
+ "where",
1192
+ "with",
1193
+ "recursive",
1194
+ "ilike",
1195
+ "over",
1196
+ "partition",
1197
+ "window",
1198
+ "rows",
1199
+ "range",
1200
+ "fetch",
1201
+ "first",
1202
+ "next",
1203
+ "only",
1204
+ "nulls",
1205
+ "last",
1206
+ "explain",
1207
+ "analyze",
1208
+ "grant",
1209
+ "revoke",
1210
+ "schema",
1211
+ "database",
1212
+ "trigger",
1213
+ "procedure",
1214
+ "function",
1215
+ "returns",
1216
+ "declare",
1217
+ "cursor",
1218
+ "loop",
1219
+ "while",
1220
+ "for",
1221
+ "exec",
1222
+ "execute",
1223
+ "merge",
1224
+ "matched",
1225
+ "replace",
1226
+ "ignore",
1227
+ "conflict",
1228
+ "do",
1229
+ "nothing",
1230
+ "nowait",
1231
+ "lock",
1232
+ "share",
1233
+ "lateral",
1234
+ "natural",
1235
+ "any",
1236
+ "some",
1237
+ "escape"
1238
+ ],
1239
+ types: [
1240
+ "int",
1241
+ "integer",
1242
+ "bigint",
1243
+ "smallint",
1244
+ "tinyint",
1245
+ "varchar",
1246
+ "char",
1247
+ "text",
1248
+ "boolean",
1249
+ "bool",
1250
+ "date",
1251
+ "timestamp",
1252
+ "timestamptz",
1253
+ "time",
1254
+ "interval",
1255
+ "decimal",
1256
+ "numeric",
1257
+ "float",
1258
+ "real",
1259
+ "double",
1260
+ "serial",
1261
+ "bigserial",
1262
+ "uuid",
1263
+ "json",
1264
+ "jsonb",
1265
+ "bytea",
1266
+ "blob",
1267
+ "array",
1268
+ "money",
1269
+ "precision",
1270
+ "varying"
1271
+ ],
1272
+ builtins: [
1273
+ "count",
1274
+ "sum",
1275
+ "avg",
1276
+ "min",
1277
+ "max",
1278
+ "coalesce",
1279
+ "now",
1280
+ "cast",
1281
+ "concat",
1282
+ "lower",
1283
+ "upper",
1284
+ "length",
1285
+ "substring",
1286
+ "round",
1287
+ "trim",
1288
+ "nullif",
1289
+ "greatest",
1290
+ "least",
1291
+ "array_agg",
1292
+ "string_agg",
1293
+ "json_agg",
1294
+ "row_number",
1295
+ "rank",
1296
+ "dense_rank",
1297
+ "date_trunc",
1298
+ "extract",
1299
+ "current_date",
1300
+ "current_timestamp",
1301
+ "current_user",
1302
+ "exists",
1303
+ "abs",
1304
+ "ceil",
1305
+ "floor",
1306
+ "random",
1307
+ "generate_series"
1308
+ ],
1309
+ constants: ["true", "false", "null", "unknown"],
1310
+ callIsFunction: true
1311
+ };
1312
+
1313
+ // src/code/languages/yaml.ts
1314
+ var LINE_START = String.raw`(?<=^|\n)`;
1315
+ var KEY = String.raw`(?<=^|\n|\s|-\s)(?:"(?:[^"\\\n]|\\[^])*"|'(?:[^'\n]|'')*'|[^\s"'#\-\[\]{},:!&*?|>][^:#\n]*?)(?=:(?:\s|$))`;
1316
+ var yaml = {
1317
+ name: "yaml",
1318
+ aliases: ["yml"],
1319
+ rules: [
1320
+ { type: "comment", match: String.raw`(?<=^|\s)#[^\n]*` },
1321
+ { type: "meta", match: LINE_START + String.raw`(?:---|\.\.\.)(?=\s|$)` },
1322
+ { type: "property", match: KEY },
1323
+ { type: "variable", match: String.raw`[&*][\w-]+` },
1324
+ { type: "meta", match: String.raw`![\w!/:-]*` },
1325
+ { type: "string", match: String.raw`"(?:[^"\\\n]|\\[^])*"?` },
1326
+ { type: "string", match: String.raw`'(?:[^'\n]|'')*'?` },
1327
+ { type: "punctuation", match: String.raw`(?<=:\s*)[|>][-+]?\d*(?=[ \t]*(?:\n|$|#))` },
1328
+ { type: "punctuation", match: String.raw`(?<=^|\n|\s)-(?=\s)|[\[\]{},:]` },
1329
+ { type: "constant", match: String.raw`(?<=:\s)~(?=\s|$)` },
1330
+ {
1331
+ type: "number",
1332
+ match: String.raw`(?<![\w.-])[-+]?(?:0x[\da-fA-F]+|\d[\d_]*(?:\.\d*)?(?:[eE][+-]?\d+)?|\.inf|\.nan)(?![\w.-])`
1333
+ }
1334
+ ],
1335
+ constants: [
1336
+ "true",
1337
+ "false",
1338
+ "null",
1339
+ "yes",
1340
+ "no",
1341
+ "on",
1342
+ "off",
1343
+ "True",
1344
+ "False",
1345
+ "Null",
1346
+ "Yes",
1347
+ "No",
1348
+ "On",
1349
+ "Off",
1350
+ "TRUE",
1351
+ "FALSE",
1352
+ "NULL",
1353
+ "YES",
1354
+ "NO",
1355
+ "ON",
1356
+ "OFF"
1357
+ ]
1358
+ };
1359
+
1360
+ // src/code/languages/index.ts
1361
+ var BUILTIN_CODE_LANGUAGES = [
1362
+ javascript,
1363
+ kotlin,
1364
+ java,
1365
+ c,
1366
+ python,
1367
+ go,
1368
+ rust,
1369
+ json,
1370
+ yaml,
1371
+ shell,
1372
+ sql,
1373
+ css,
1374
+ markup,
1375
+ diff,
1376
+ markdown
1377
+ ];
1378
+ for (const grammar of BUILTIN_CODE_LANGUAGES) registerCodeLanguage(grammar);
1379
+
1380
+ // src/code/lexer.ts
1381
+ var DEFAULT_IDENTIFIER = String.raw`[A-Za-z_$][\w$]*`;
1382
+ var WHITESPACE = String.raw`\s+`;
1383
+ var SCREAMING_CASE = /^[A-Z][A-Z\d_]+$/;
1384
+ var CAPITALIZED = /^[A-Z]/;
1385
+ var compiled = /* @__PURE__ */ new WeakMap();
1386
+ function countGroups(source) {
1387
+ return new RegExp(`${source}|`).exec("").length - 1;
1388
+ }
1389
+ function compile(grammar) {
1390
+ const cached = compiled.get(grammar);
1391
+ if (cached) return cached;
1392
+ const rules = [...grammar.rules, "whitespace", "identifier"];
1393
+ const sources = rules.map((rule) => {
1394
+ if (rule === "whitespace") return WHITESPACE;
1395
+ if (rule === "identifier") return grammar.identifier ?? DEFAULT_IDENTIFIER;
1396
+ return rule.match;
1397
+ });
1398
+ const groupStarts = [];
1399
+ let group = 1;
1400
+ for (const source of sources) {
1401
+ groupStarts.push(group);
1402
+ group += 1 + countGroups(source);
1403
+ }
1404
+ const regex = new RegExp(
1405
+ sources.map((source) => `(${source})`).join("|"),
1406
+ grammar.caseInsensitive ? "yi" : "y"
1407
+ );
1408
+ const words = /* @__PURE__ */ new Map();
1409
+ const addWords = (list, type) => {
1410
+ for (const word of list ?? []) {
1411
+ words.set(grammar.caseInsensitive ? word.toLowerCase() : word, type);
1412
+ }
1413
+ };
1414
+ addWords(grammar.builtins, "builtin");
1415
+ addWords(grammar.types, "type");
1416
+ addWords(grammar.constants, "constant");
1417
+ addWords(grammar.keywords, "keyword");
1418
+ const result = { regex, groupStarts, rules, words };
1419
+ compiled.set(grammar, result);
1420
+ return result;
1421
+ }
1422
+ function isCallee(code, end) {
1423
+ let i = end;
1424
+ while (code[i] === " " || code[i] === " ") i++;
1425
+ return code[i] === "(";
1426
+ }
1427
+ function classifyIdentifier(word, grammar, words, code, end) {
1428
+ const known = words.get(grammar.caseInsensitive ? word.toLowerCase() : word);
1429
+ if (known) return known;
1430
+ if (grammar.capitalizedIsType) {
1431
+ if (SCREAMING_CASE.test(word)) return "constant";
1432
+ if (CAPITALIZED.test(word)) return "type";
1433
+ }
1434
+ if (grammar.callIsFunction && isCallee(code, end)) return "function";
1435
+ return "text";
1436
+ }
1437
+ function matchedRule(match, compiled2) {
1438
+ const { groupStarts, rules } = compiled2;
1439
+ for (let i = 0; i < groupStarts.length; i++) {
1440
+ if (match[groupStarts[i]] !== void 0) return rules[i];
1441
+ }
1442
+ throw new Error("zui code lexer: no alternative matched");
1443
+ }
1444
+ function tokenizeCode(code, grammar) {
1445
+ const c2 = compile(grammar);
1446
+ const tokens = [];
1447
+ const push = (type, text) => {
1448
+ const last = tokens[tokens.length - 1];
1449
+ if (last && last.type === type) {
1450
+ tokens[tokens.length - 1] = { type, text: last.text + text };
1451
+ } else {
1452
+ tokens.push({ type, text });
1453
+ }
1454
+ };
1455
+ let pos = 0;
1456
+ let textStart = 0;
1457
+ const flushText = (end) => {
1458
+ if (end > textStart) push("text", code.slice(textStart, end));
1459
+ };
1460
+ while (pos < code.length) {
1461
+ c2.regex.lastIndex = pos;
1462
+ const match = c2.regex.exec(code);
1463
+ if (match === null || match[0].length === 0) {
1464
+ pos += 1;
1465
+ continue;
1466
+ }
1467
+ const text = match[0];
1468
+ const end = pos + text.length;
1469
+ const rule = matchedRule(match, c2);
1470
+ let type;
1471
+ if (rule === "whitespace") type = "text";
1472
+ else if (rule === "identifier") type = classifyIdentifier(text, grammar, c2.words, code, end);
1473
+ else type = rule.type;
1474
+ if (type !== "text") {
1475
+ flushText(pos);
1476
+ push(type, text);
1477
+ textStart = end;
1478
+ }
1479
+ pos = end;
1480
+ }
1481
+ flushText(code.length);
1482
+ return tokens;
1483
+ }
1484
+
1485
+ // src/code/lexicalTokenizer.ts
1486
+ import {
1487
+ $createLineBreakNode,
1488
+ $createTabNode,
1489
+ $nodesOfType
1490
+ } from "lexical";
1491
+ import { $createCodeHighlightNode, CodeNode, registerCodeHighlighting } from "@lexical/code";
1492
+ import { mergeRegister } from "@lexical/utils";
1493
+ var MAX_HIGHLIGHT_LENGTH = 2e5;
1494
+ function grammarFor(code, language) {
1495
+ return code.length > MAX_HIGHLIGHT_LENGTH ? PLAIN : resolveCodeLanguage(language);
1496
+ }
1497
+ var codeTokenizer = {
1498
+ defaultLanguage: PLAIN_LANGUAGE,
1499
+ tokenize(code, language) {
1500
+ return tokenizeCode(code, grammarFor(code, language)).map(
1501
+ (token) => token.type === "text" ? token.text : { type: token.type, alias: "", content: token.text }
1502
+ );
1503
+ },
1504
+ $tokenize(codeNode, language) {
1505
+ const code = codeNode.getTextContent();
1506
+ const nodes = [];
1507
+ for (const { type, text } of tokenizeCode(code, grammarFor(code, language))) {
1508
+ const highlightType = type === "text" ? void 0 : type;
1509
+ for (const part of text.split(/(\n|\t)/)) {
1510
+ if (part === "\n") nodes.push($createLineBreakNode());
1511
+ else if (part === " ") nodes.push($createTabNode());
1512
+ else if (part.length > 0) nodes.push($createCodeHighlightNode(part, highlightType));
1513
+ }
1514
+ }
1515
+ return nodes;
1516
+ }
1517
+ };
1518
+ function openLanguageGate(language) {
1519
+ const prism = globalThis.Prism;
1520
+ const table = prism?.languages;
1521
+ if (!table || Object.prototype.hasOwnProperty.call(table, language)) return false;
1522
+ table[language] = {};
1523
+ return true;
1524
+ }
1525
+ function registerCodeBlockHighlighting(editor) {
1526
+ const unregister = mergeRegister(
1527
+ editor.registerNodeTransform(CodeNode, (node) => {
1528
+ const language = node.getLanguage();
1529
+ if (language && openLanguageGate(language)) node.markDirty();
1530
+ }),
1531
+ registerCodeHighlighting(editor, codeTokenizer)
1532
+ );
1533
+ editor.update(
1534
+ () => {
1535
+ for (const node of $nodesOfType(CodeNode)) node.markDirty();
1536
+ },
1537
+ { tag: "history-merge" }
1538
+ );
1539
+ return unregister;
1540
+ }
1541
+
1542
+ // src/code/types.ts
1543
+ var CODE_TOKEN_TYPES = [
1544
+ "comment",
1545
+ "string",
1546
+ "number",
1547
+ "keyword",
1548
+ "builtin",
1549
+ "type",
1550
+ "function",
1551
+ "property",
1552
+ "variable",
1553
+ "constant",
1554
+ "operator",
1555
+ "punctuation",
1556
+ "tag",
1557
+ "attr",
1558
+ "regex",
1559
+ "meta",
1560
+ "inserted",
1561
+ "deleted"
1562
+ ];
1563
+
1564
+ // src/plugins/CodeHighlightPlugin.tsx
164
1565
  function CodeHighlightPlugin() {
165
1566
  const [editor] = useLexicalComposerContext3();
166
- useEffect3(() => {
167
- return registerCodeHighlighting(editor);
168
- }, [editor]);
1567
+ useEffect3(() => registerCodeBlockHighlighting(editor), [editor]);
169
1568
  return null;
170
1569
  }
171
1570
 
@@ -199,8 +1598,8 @@ function MarkdownSyncPlugin({
199
1598
  if (dirtyElements.size === 0 && dirtyLeaves.size === 0) return;
200
1599
  if (tags.has("initial-load")) return;
201
1600
  editorState.read(() => {
202
- const markdown = $convertToMarkdownString(transformers);
203
- onChangeRef.current?.(markdown);
1601
+ const markdown2 = $convertToMarkdownString(transformers);
1602
+ onChangeRef.current?.(markdown2);
204
1603
  });
205
1604
  }
206
1605
  );
@@ -211,7 +1610,7 @@ function MarkdownSyncPlugin({
211
1610
  // src/nodes/FrontmatterNode.ts
212
1611
  import {
213
1612
  $applyNodeReplacement,
214
- $createLineBreakNode,
1613
+ $createLineBreakNode as $createLineBreakNode2,
215
1614
  $createTextNode,
216
1615
  ElementNode
217
1616
  } from "lexical";
@@ -280,7 +1679,7 @@ ${body}
280
1679
  while (lines.length > 0 && lines[lines.length - 1].length === 0) lines.pop();
281
1680
  const node = $createFrontmatterNode();
282
1681
  lines.forEach((line, index) => {
283
- if (index > 0) node.append($createLineBreakNode());
1682
+ if (index > 0) node.append($createLineBreakNode2());
284
1683
  node.append($createTextNode(line));
285
1684
  });
286
1685
  rootNode.append(node);
@@ -381,9 +1780,9 @@ var SIDE_FIXED_POINTS = {
381
1780
  function serializeDrawingData(data) {
382
1781
  return JSON.stringify(data);
383
1782
  }
384
- function parseDrawingData(json) {
1783
+ function parseDrawingData(json2) {
385
1784
  try {
386
- return normalizeDrawingData(JSON.parse(json));
1785
+ return normalizeDrawingData(JSON.parse(json2));
387
1786
  } catch {
388
1787
  return EMPTY_DRAWING;
389
1788
  }
@@ -531,7 +1930,7 @@ function bbox(shape) {
531
1930
  h: Math.abs(shape.h)
532
1931
  };
533
1932
  }
534
- function normalize(shape) {
1933
+ function normalize2(shape) {
535
1934
  if (isConnectorType(shape.type)) return shape;
536
1935
  if (shape.w >= 0 && shape.h >= 0) return shape;
537
1936
  const b = bbox(shape);
@@ -573,10 +1972,10 @@ function manhattan(a, b) {
573
1972
  return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
574
1973
  }
575
1974
  function ellipsePolygon(r, segments = 40) {
576
- const c = rectCenter(r);
1975
+ const c2 = rectCenter(r);
577
1976
  return Array.from({ length: segments }, (_, i) => {
578
1977
  const a = i * 2 * Math.PI / segments;
579
- return { x: c.x + r.w / 2 * Math.cos(a), y: c.y + r.h / 2 * Math.sin(a) };
1978
+ return { x: c2.x + r.w / 2 * Math.cos(a), y: c2.y + r.h / 2 * Math.sin(a) };
580
1979
  });
581
1980
  }
582
1981
  function rectPolygon(r) {
@@ -898,7 +2297,7 @@ function fixedPointFor(box, point) {
898
2297
  [fy * b.h, "fy", 0],
899
2298
  [(1 - fy) * b.h, "fy", 1]
900
2299
  ];
901
- edges.sort((a, c) => a[0] - c[0]);
2300
+ edges.sort((a, c2) => a[0] - c2[0]);
902
2301
  const [, axis, value] = edges[0];
903
2302
  const snapped = axis === "fx" ? [value, fy] : [fx, value];
904
2303
  return [round3(snapped[0]), round3(snapped[1])];
@@ -920,9 +2319,9 @@ function bindingHeading(box, binding, toward) {
920
2319
  const fixed = edgeHeading(binding);
921
2320
  if (fixed) return fixed;
922
2321
  const b = bbox(box);
923
- const c = center(box);
924
- const dx = (toward.x - c.x) / Math.max(b.w, 1);
925
- const dy = (toward.y - c.y) / Math.max(b.h, 1);
2322
+ const c2 = center(box);
2323
+ const dx = (toward.x - c2.x) / Math.max(b.w, 1);
2324
+ const dy = (toward.y - c2.y) / Math.max(b.h, 1);
926
2325
  if (Math.abs(dx) >= Math.abs(dy)) return dx >= 0 ? "right" : "left";
927
2326
  return dy >= 0 ? "down" : "up";
928
2327
  }
@@ -1192,17 +2591,17 @@ function simplify(points) {
1192
2591
  return out;
1193
2592
  }
1194
2593
  function applyElbowOverride(points, t, obstacles) {
1195
- const [a, b, c, d] = points;
1196
- const horizontalMiddle = Math.abs(b.y - c.y) < 0.01 && Math.abs(b.x - c.x) > 0.01;
1197
- const verticalMiddle = Math.abs(b.x - c.x) < 0.01 && Math.abs(b.y - c.y) > 0.01;
2594
+ const [a, b, c2, d] = points;
2595
+ const horizontalMiddle = Math.abs(b.y - c2.y) < 0.01 && Math.abs(b.x - c2.x) > 0.01;
2596
+ const verticalMiddle = Math.abs(b.x - c2.x) < 0.01 && Math.abs(b.y - c2.y) > 0.01;
1198
2597
  const clamped = Math.min(0.95, Math.max(0.05, t));
1199
2598
  let next;
1200
2599
  if (verticalMiddle) {
1201
2600
  const x = a.x + (d.x - a.x) * clamped;
1202
- next = [a, { x, y: b.y }, { x, y: c.y }, d];
2601
+ next = [a, { x, y: b.y }, { x, y: c2.y }, d];
1203
2602
  } else if (horizontalMiddle) {
1204
2603
  const y = a.y + (d.y - a.y) * clamped;
1205
- next = [a, { x: b.x, y }, { x: c.x, y }, d];
2604
+ next = [a, { x: b.x, y }, { x: c2.x, y }, d];
1206
2605
  } else {
1207
2606
  return points;
1208
2607
  }
@@ -1569,9 +2968,9 @@ var STROKE_WIDTH = 2;
1569
2968
  function isDrawingSkeleton(value) {
1570
2969
  return isRecord2(value) && Array.isArray(value.boxes);
1571
2970
  }
1572
- function parseDrawingSkeleton(json) {
2971
+ function parseDrawingSkeleton(json2) {
1573
2972
  try {
1574
- const parsed = JSON.parse(json);
2973
+ const parsed = JSON.parse(json2);
1575
2974
  if (!isDrawingSkeleton(parsed)) return EMPTY_DRAWING;
1576
2975
  return expandSkeleton(normalizeSkeleton(parsed));
1577
2976
  } catch {
@@ -1584,7 +2983,7 @@ function expandSkeleton(skeleton) {
1584
2983
  const sizes = new Map(boxes.map((box) => [box.id, measureBox(box, boxTypes.get(box.id))]));
1585
2984
  const boxIds = new Set(boxTypes.keys());
1586
2985
  const connectors = (skeleton.connectors ?? []).filter(
1587
- (c) => boxIds.has(endId(c.from)) && boxIds.has(endId(c.to)) && endId(c.from) !== endId(c.to)
2986
+ (c2) => boxIds.has(endId(c2.from)) && boxIds.has(endId(c2.to)) && endId(c2.from) !== endId(c2.to)
1588
2987
  );
1589
2988
  const positions = layoutBoxes(boxes, sizes, connectors, skeleton.direction ?? "right");
1590
2989
  const boxShapes = boxes.map(
@@ -1599,7 +2998,7 @@ function expandSkeleton(skeleton) {
1599
2998
  used.add(id);
1600
2999
  return id;
1601
3000
  };
1602
- const connectorShapes = connectors.map((c) => expandConnector(c, centers, nextId("c")));
3001
+ const connectorShapes = connectors.map((c2) => expandConnector(c2, centers, nextId("c")));
1603
3002
  const textShapes = (skeleton.texts ?? []).map((t) => expandText(t, nextId("t")));
1604
3003
  const shapes = resolveBindings([...boxShapes, ...connectorShapes, ...textShapes]);
1605
3004
  const bottom = shapes.reduce((max, shape) => {
@@ -1652,7 +3051,7 @@ function layoutBoxes(boxes, sizes, connectors, direction) {
1652
3051
  const positions = /* @__PURE__ */ new Map();
1653
3052
  const auto = boxes.filter((box) => box.x === void 0 || box.y === void 0);
1654
3053
  const autoIds = new Set(auto.map((box) => box.id));
1655
- const edges = connectors.map((c) => ({ from: endId(c.from), to: endId(c.to) })).filter((e) => e.from !== e.to && autoIds.has(e.from) && autoIds.has(e.to));
3054
+ const edges = connectors.map((c2) => ({ from: endId(c2.from), to: endId(c2.to) })).filter((e) => e.from !== e.to && autoIds.has(e.from) && autoIds.has(e.to));
1656
3055
  const ranks = rankNodes(
1657
3056
  auto.map((box) => box.id),
1658
3057
  acyclicEdges(
@@ -1671,7 +3070,7 @@ function layoutBoxes(boxes, sizes, connectors, direction) {
1671
3070
  const rowCross = rows.map(
1672
3071
  (row) => row.reduce((sum, id) => sum + sizes.get(id)[cross], 0) + Math.max(0, row.length - 1) * STACK_GAP
1673
3072
  );
1674
- const maxCross = rowCross.reduce((max, c) => Math.max(max, c), 0);
3073
+ const maxCross = rowCross.reduce((max, c2) => Math.max(max, c2), 0);
1675
3074
  let mainOffset = LAYOUT_ORIGIN;
1676
3075
  rows.forEach((row, rank) => {
1677
3076
  let crossOffset = LAYOUT_ORIGIN + (maxCross - rowCross[rank]) / 2;
@@ -1800,8 +3199,8 @@ function normalizeSkeleton(raw) {
1800
3199
  const box = normalizeBox(b);
1801
3200
  return box ? [box] : [];
1802
3201
  });
1803
- const connectors = Array.isArray(value.connectors) ? value.connectors.flatMap((c) => {
1804
- const connector = normalizeConnector(c);
3202
+ const connectors = Array.isArray(value.connectors) ? value.connectors.flatMap((c2) => {
3203
+ const connector = normalizeConnector(c2);
1805
3204
  return connector ? [connector] : [];
1806
3205
  }) : [];
1807
3206
  const texts = Array.isArray(value.texts) ? value.texts.flatMap((t) => {
@@ -2497,7 +3896,7 @@ var textStyle = { userSelect: "none" };
2497
3896
  function luminance(color) {
2498
3897
  const m = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color);
2499
3898
  if (!m) return 1;
2500
- const hex = m[1].length === 3 ? m[1].replace(/./g, (c) => c + c) : m[1];
3899
+ const hex = m[1].length === 3 ? m[1].replace(/./g, (c2) => c2 + c2) : m[1];
2501
3900
  const [r, g, b] = [0, 2, 4].map((i) => parseInt(hex.slice(i, i + 2), 16) / 255);
2502
3901
  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
2503
3902
  }
@@ -3103,9 +4502,9 @@ function DrawingCanvas({ nodeKey, data }) {
3103
4502
  ...nextWidth !== "full" || explicitFull ? { width: nextWidth } : {},
3104
4503
  shapes: nextShapes
3105
4504
  };
3106
- const json = serializeDrawingData(payload);
3107
- if (json === lastCommittedRef.current) return;
3108
- lastCommittedRef.current = json;
4505
+ const json2 = serializeDrawingData(payload);
4506
+ if (json2 === lastCommittedRef.current) return;
4507
+ lastCommittedRef.current = json2;
3109
4508
  editor.update(() => {
3110
4509
  const node = $getNodeByKey2(nodeKey);
3111
4510
  if ($isDrawingNode(node)) node.setData(payload);
@@ -3349,7 +4748,7 @@ function DrawingCanvas({ nodeKey, data }) {
3349
4748
  })
3350
4749
  );
3351
4750
  }
3352
- updateShapes((prev) => prev.map(normalize), { commit: true });
4751
+ updateShapes((prev) => prev.map(normalize2), { commit: true });
3353
4752
  },
3354
4753
  [getPoint, paths, updateShapes, startTextEditing]
3355
4754
  );
@@ -4076,6 +5475,19 @@ var TABLE = {
4076
5475
  type: "element"
4077
5476
  };
4078
5477
 
5478
+ // src/transformers/codeTransformer.ts
5479
+ import { CODE } from "@lexical/markdown";
5480
+ import { $isCodeNode as $isCodeNode2 } from "@lexical/code";
5481
+ var CODE_BLOCK = {
5482
+ ...CODE,
5483
+ export: (node, exportChildren) => {
5484
+ if (!$isCodeNode2(node)) return null;
5485
+ if (node.getLanguage() !== PLAIN_LANGUAGE) return CODE.export?.(node, exportChildren) ?? null;
5486
+ const text = node.getTextContent();
5487
+ return "```" + (text ? "\n" + text : "") + "\n```";
5488
+ }
5489
+ };
5490
+
4079
5491
  // src/theme.ts
4080
5492
  var editorTheme = {
4081
5493
  ltr: "text-left",
@@ -4113,38 +5525,9 @@ var editorTheme = {
4113
5525
  underlineStrikethrough: "underline line-through"
4114
5526
  },
4115
5527
  code: "zui-code bg-muted rounded-md p-4 font-mono text-sm block my-2 overflow-x-auto",
4116
- codeHighlight: {
4117
- atrule: "text-blue-500",
4118
- attr: "text-yellow-500",
4119
- boolean: "text-purple-500",
4120
- builtin: "text-cyan-500",
4121
- cdata: "text-gray-500",
4122
- char: "text-green-500",
4123
- class: "text-yellow-500",
4124
- "class-name": "text-yellow-500",
4125
- comment: "text-gray-500",
4126
- constant: "text-purple-500",
4127
- deleted: "text-red-500",
4128
- doctype: "text-gray-500",
4129
- entity: "text-red-500",
4130
- function: "text-blue-500",
4131
- important: "text-red-500",
4132
- inserted: "text-green-500",
4133
- keyword: "text-purple-500",
4134
- namespace: "text-purple-500",
4135
- number: "text-green-500",
4136
- operator: "text-gray-500",
4137
- prolog: "text-gray-500",
4138
- property: "text-blue-500",
4139
- punctuation: "text-gray-500",
4140
- regex: "text-red-500",
4141
- selector: "text-blue-500",
4142
- string: "text-green-500",
4143
- symbol: "text-green-500",
4144
- tag: "text-red-500",
4145
- url: "text-blue-500",
4146
- variable: "text-blue-500"
4147
- },
5528
+ codeHighlight: Object.fromEntries(
5529
+ CODE_TOKEN_TYPES.map((type) => [type, `zui-token zui-token-${type}`])
5530
+ ),
4148
5531
  quote: "zui-quote border-l-4 border-border pl-4 italic",
4149
5532
  frontmatter: "zui-frontmatter",
4150
5533
  table: "zui-table",
@@ -4170,8 +5553,16 @@ function useEditorContext() {
4170
5553
 
4171
5554
  // src/EditorRoot.tsx
4172
5555
  import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
4173
- var SYNC_TRANSFORMERS = [FRONTMATTER, DRAWING, DIAGRAM, CHECK_LIST, TABLE, ...TRANSFORMERS2];
4174
- var SHORTCUT_TRANSFORMERS = [TABLE, ...TRANSFORMERS2.filter((t) => t !== CODE)];
5556
+ var SYNC_TRANSFORMERS = [
5557
+ FRONTMATTER,
5558
+ DRAWING,
5559
+ DIAGRAM,
5560
+ CHECK_LIST,
5561
+ TABLE,
5562
+ CODE_BLOCK,
5563
+ ...TRANSFORMERS2.filter((t) => t !== CODE2)
5564
+ ];
5565
+ var SHORTCUT_TRANSFORMERS = [TABLE, ...TRANSFORMERS2.filter((t) => t !== CODE2)];
4175
5566
  var NO_DEFAULT_BLOCK_WIDTH = {};
4176
5567
  function onError(error) {
4177
5568
  console.error(error);
@@ -4181,7 +5572,7 @@ var editorNodes = [
4181
5572
  ListNode2,
4182
5573
  ListItemNode,
4183
5574
  QuoteNode,
4184
- CodeNode,
5575
+ CodeNode2,
4185
5576
  CodeHighlightNode,
4186
5577
  AutoLinkNode,
4187
5578
  LinkNode,
@@ -4445,7 +5836,7 @@ import {
4445
5836
  } from "lexical";
4446
5837
  import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
4447
5838
  import { INSERT_TABLE_COMMAND } from "@lexical/table";
4448
- import { $insertNodeToNearestRoot, mergeRegister } from "@lexical/utils";
5839
+ import { $insertNodeToNearestRoot, mergeRegister as mergeRegister2 } from "@lexical/utils";
4449
5840
  var TRACKED_FORMATS = [
4450
5841
  "bold",
4451
5842
  "italic",
@@ -4470,7 +5861,7 @@ function useMarkdownEditor() {
4470
5861
  const activeDrawingRef = useRef7(null);
4471
5862
  const [drawingWidth, setDrawingWidth] = useState6(null);
4472
5863
  useEffect10(
4473
- () => mergeRegister(
5864
+ () => mergeRegister2(
4474
5865
  editor.registerUpdateListener(({ editorState }) => {
4475
5866
  editorState.read(() => {
4476
5867
  const table = $getSelectedTable();
@@ -4937,7 +6328,7 @@ function OutlinePlugin() {
4937
6328
  title: collapsed ? "Show outline" : "Hide outline",
4938
6329
  "aria-label": collapsed ? "Show outline" : "Hide outline",
4939
6330
  "aria-expanded": !collapsed,
4940
- onClick: () => setCollapsed((c) => !c),
6331
+ onClick: () => setCollapsed((c2) => !c2),
4941
6332
  children: /* @__PURE__ */ jsx16(
4942
6333
  "svg",
4943
6334
  {
@@ -5187,6 +6578,9 @@ export {
5187
6578
  BLOCK_WIDTHS,
5188
6579
  BOX_DEFINITIONS,
5189
6580
  BOX_TYPES,
6581
+ BUILTIN_CODE_LANGUAGES,
6582
+ CODE_BLOCK,
6583
+ CODE_TOKEN_TYPES,
5190
6584
  COLOR_PRESETS,
5191
6585
  CONNECTOR_TYPES,
5192
6586
  DEFAULT_TABLE_SETTINGS,
@@ -5203,6 +6597,7 @@ export {
5203
6597
  HistoryButtons,
5204
6598
  InsertButtons,
5205
6599
  MarkdownEditor_default as MarkdownEditor,
6600
+ PLAIN_LANGUAGE,
5206
6601
  SHAPE_TYPES,
5207
6602
  SIDE_FIXED_POINTS,
5208
6603
  STROKE_COLORS,
@@ -5214,12 +6609,15 @@ export {
5214
6609
  anchorPoint,
5215
6610
  bindEndpoints,
5216
6611
  boxOutline,
6612
+ codeTokenizer,
5217
6613
  connectorPoints,
5218
6614
  drawingToMermaid,
5219
6615
  expandSkeleton,
5220
6616
  findBoxAt,
5221
6617
  fixedPointFor,
5222
6618
  formatTableSettingsMarker,
6619
+ getCodeLanguages,
6620
+ hasCodeLanguage,
5223
6621
  isBlockWidth,
5224
6622
  isDrawingSkeleton,
5225
6623
  makeBinding,
@@ -5227,8 +6625,12 @@ export {
5227
6625
  parseDrawingData,
5228
6626
  parseDrawingSkeleton,
5229
6627
  parseTableSettingsMarker,
6628
+ registerCodeBlockHighlighting,
6629
+ registerCodeLanguage,
5230
6630
  resolveBindings,
6631
+ resolveCodeLanguage,
5231
6632
  routeElbow,
5232
6633
  serializeDrawingData,
6634
+ tokenizeCode,
5233
6635
  useMarkdownEditor
5234
6636
  };