@lexical/markdown 0.44.1-nightly.20260519.0 → 0.45.1-dev.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.
Files changed (29) hide show
  1. package/{LexicalMarkdown.dev.js → dist/LexicalMarkdown.dev.js} +1 -1
  2. package/{LexicalMarkdown.dev.mjs → dist/LexicalMarkdown.dev.mjs} +1 -1
  3. package/dist/LexicalMarkdown.prod.js +9 -0
  4. package/dist/LexicalMarkdown.prod.mjs +9 -0
  5. package/package.json +37 -22
  6. package/src/MarkdownExport.ts +627 -0
  7. package/src/MarkdownImport.ts +363 -0
  8. package/src/MarkdownShortcuts.ts +677 -0
  9. package/src/MarkdownTransformers.ts +962 -0
  10. package/src/importTextFormatTransformer.ts +389 -0
  11. package/src/importTextMatchTransformer.ts +110 -0
  12. package/src/importTextTransformers.ts +141 -0
  13. package/src/index.ts +138 -0
  14. package/src/utils.ts +472 -0
  15. package/LexicalMarkdown.prod.js +0 -9
  16. package/LexicalMarkdown.prod.mjs +0 -9
  17. /package/{LexicalMarkdown.js → dist/LexicalMarkdown.js} +0 -0
  18. /package/{LexicalMarkdown.js.flow → dist/LexicalMarkdown.js.flow} +0 -0
  19. /package/{LexicalMarkdown.mjs → dist/LexicalMarkdown.mjs} +0 -0
  20. /package/{LexicalMarkdown.node.mjs → dist/LexicalMarkdown.node.mjs} +0 -0
  21. /package/{MarkdownExport.d.ts → dist/MarkdownExport.d.ts} +0 -0
  22. /package/{MarkdownImport.d.ts → dist/MarkdownImport.d.ts} +0 -0
  23. /package/{MarkdownShortcuts.d.ts → dist/MarkdownShortcuts.d.ts} +0 -0
  24. /package/{MarkdownTransformers.d.ts → dist/MarkdownTransformers.d.ts} +0 -0
  25. /package/{importTextFormatTransformer.d.ts → dist/importTextFormatTransformer.d.ts} +0 -0
  26. /package/{importTextMatchTransformer.d.ts → dist/importTextMatchTransformer.d.ts} +0 -0
  27. /package/{importTextTransformers.d.ts → dist/importTextTransformers.d.ts} +0 -0
  28. /package/{index.d.ts → dist/index.d.ts} +0 -0
  29. /package/{utils.d.ts → dist/utils.d.ts} +0 -0
package/src/index.ts ADDED
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import type {
10
+ ElementTransformer,
11
+ MultilineElementTransformer,
12
+ TextFormatTransformer,
13
+ TextMatchTransformer,
14
+ Transformer,
15
+ } from './MarkdownTransformers';
16
+ import type {BaseSelection, ElementNode} from 'lexical';
17
+
18
+ import {$isRangeSelection} from 'lexical';
19
+
20
+ import {
21
+ createMarkdownExport,
22
+ createSelectionMarkdownExport,
23
+ } from './MarkdownExport';
24
+ import {createMarkdownImport} from './MarkdownImport';
25
+ import {registerMarkdownShortcuts} from './MarkdownShortcuts';
26
+ import {
27
+ BOLD_ITALIC_STAR,
28
+ BOLD_ITALIC_UNDERSCORE,
29
+ BOLD_STAR,
30
+ BOLD_UNDERSCORE,
31
+ CHECK_LIST,
32
+ CODE,
33
+ ELEMENT_TRANSFORMERS,
34
+ HEADING,
35
+ HIGHLIGHT,
36
+ INLINE_CODE,
37
+ ITALIC_STAR,
38
+ ITALIC_UNDERSCORE,
39
+ LINK,
40
+ MULTILINE_ELEMENT_TRANSFORMERS,
41
+ normalizeMarkdown,
42
+ ORDERED_LIST,
43
+ QUOTE,
44
+ STRIKETHROUGH,
45
+ TEXT_FORMAT_TRANSFORMERS,
46
+ TEXT_MATCH_TRANSFORMERS,
47
+ TRANSFORMERS,
48
+ UNORDERED_LIST,
49
+ } from './MarkdownTransformers';
50
+
51
+ /**
52
+ * Renders markdown from a string. The selection is moved to the start after the operation.
53
+ *
54
+ * @param {boolean} [shouldPreserveNewLines] By setting this to true, new lines will be preserved between conversions
55
+ * @param {boolean} [shouldMergeAdjacentLines] By setting this to true, adjacent non empty lines will be merged according to commonmark spec: https://spec.commonmark.org/0.24/#example-177. Not applicable if shouldPreserveNewLines = true.
56
+ */
57
+ function $convertFromMarkdownString(
58
+ markdown: string,
59
+ transformers: Array<Transformer> = TRANSFORMERS,
60
+ node?: ElementNode,
61
+ shouldPreserveNewLines = false,
62
+ shouldMergeAdjacentLines = false,
63
+ ): void {
64
+ const sanitizedMarkdown = shouldPreserveNewLines
65
+ ? markdown
66
+ : normalizeMarkdown(markdown, shouldMergeAdjacentLines);
67
+ const importMarkdown = createMarkdownImport(
68
+ transformers,
69
+ shouldPreserveNewLines,
70
+ );
71
+ return importMarkdown(sanitizedMarkdown, node);
72
+ }
73
+
74
+ /**
75
+ * Renders string from markdown. The selection is moved to the start after the operation.
76
+ */
77
+ function $convertToMarkdownString(
78
+ transformers: Array<Transformer> = TRANSFORMERS,
79
+ node?: ElementNode,
80
+ shouldPreserveNewLines: boolean = false,
81
+ ): string {
82
+ const exportMarkdown = createMarkdownExport(
83
+ transformers,
84
+ shouldPreserveNewLines,
85
+ );
86
+ return exportMarkdown(node);
87
+ }
88
+
89
+ /**
90
+ * Converts the selected content to a markdown string.
91
+ */
92
+ function $convertSelectionToMarkdownString(
93
+ transformers: Transformer[] = TRANSFORMERS,
94
+ selection: BaseSelection | null,
95
+ shouldPreserveNewLines: boolean = false,
96
+ ): string {
97
+ if (!selection || ($isRangeSelection(selection) && selection.isCollapsed())) {
98
+ return '';
99
+ }
100
+ const exportMarkdown = createSelectionMarkdownExport(
101
+ transformers,
102
+ shouldPreserveNewLines,
103
+ );
104
+ return exportMarkdown(selection);
105
+ }
106
+
107
+ export {
108
+ $convertFromMarkdownString,
109
+ $convertSelectionToMarkdownString,
110
+ $convertToMarkdownString,
111
+ BOLD_ITALIC_STAR,
112
+ BOLD_ITALIC_UNDERSCORE,
113
+ BOLD_STAR,
114
+ BOLD_UNDERSCORE,
115
+ CHECK_LIST,
116
+ CODE,
117
+ ELEMENT_TRANSFORMERS,
118
+ type ElementTransformer,
119
+ HEADING,
120
+ HIGHLIGHT,
121
+ INLINE_CODE,
122
+ ITALIC_STAR,
123
+ ITALIC_UNDERSCORE,
124
+ LINK,
125
+ MULTILINE_ELEMENT_TRANSFORMERS,
126
+ type MultilineElementTransformer,
127
+ ORDERED_LIST,
128
+ QUOTE,
129
+ registerMarkdownShortcuts,
130
+ STRIKETHROUGH,
131
+ TEXT_FORMAT_TRANSFORMERS,
132
+ TEXT_MATCH_TRANSFORMERS,
133
+ type TextFormatTransformer,
134
+ type TextMatchTransformer,
135
+ type Transformer,
136
+ TRANSFORMERS,
137
+ UNORDERED_LIST,
138
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,472 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import type {ListNode} from '@lexical/list';
10
+
11
+ import {$isCodeNode} from '@lexical/code-core';
12
+ import {$isListItemNode, $isListNode} from '@lexical/list';
13
+ import {$isHeadingNode, $isQuoteNode} from '@lexical/rich-text';
14
+ import {
15
+ $isParagraphNode,
16
+ $isTextNode,
17
+ type ElementNode,
18
+ type LexicalNode,
19
+ type TextFormatType,
20
+ } from 'lexical';
21
+
22
+ import {
23
+ ElementTransformer,
24
+ MultilineElementTransformer,
25
+ TextFormatTransformer,
26
+ TextMatchTransformer,
27
+ Transformer,
28
+ } from './MarkdownTransformers';
29
+
30
+ type MarkdownFormatKind =
31
+ | 'noTransformation'
32
+ | 'paragraphH1'
33
+ | 'paragraphH2'
34
+ | 'paragraphH3'
35
+ | 'paragraphH4'
36
+ | 'paragraphH5'
37
+ | 'paragraphH6'
38
+ | 'paragraphBlockQuote'
39
+ | 'paragraphUnorderedList'
40
+ | 'paragraphOrderedList'
41
+ | 'paragraphCodeBlock'
42
+ | 'horizontalRule'
43
+ | 'bold'
44
+ | 'code'
45
+ | 'italic'
46
+ | 'underline'
47
+ | 'strikethrough'
48
+ | 'italic_bold'
49
+ | 'strikethrough_italic'
50
+ | 'strikethrough_bold'
51
+ | 'strikethrough_italic_bold'
52
+ | 'link';
53
+
54
+ type MarkdownCriteria = Readonly<{
55
+ export?: (
56
+ node: LexicalNode,
57
+ traverseChildren: (elementNode: ElementNode) => string,
58
+ ) => string | null;
59
+ exportFormat?: TextFormatType;
60
+ exportTag?: string;
61
+ exportTagClose?: string;
62
+ markdownFormatKind: MarkdownFormatKind | null | undefined;
63
+ regEx: RegExp;
64
+ regExForAutoFormatting: RegExp;
65
+ requiresParagraphStart: boolean | null | undefined;
66
+ }>;
67
+
68
+ type MarkdownCriteriaArray = Array<MarkdownCriteria>;
69
+
70
+ const autoFormatBase: MarkdownCriteria = {
71
+ markdownFormatKind: null,
72
+ regEx: /(?:)/,
73
+ regExForAutoFormatting: /(?:)/,
74
+ requiresParagraphStart: false,
75
+ };
76
+
77
+ const paragraphStartBase: MarkdownCriteria = {
78
+ ...autoFormatBase,
79
+ requiresParagraphStart: true,
80
+ };
81
+
82
+ const markdownHeader1: MarkdownCriteria = {
83
+ ...paragraphStartBase,
84
+ export: createHeadingExport(1),
85
+ markdownFormatKind: 'paragraphH1',
86
+ regEx: /^(?:# )/,
87
+ regExForAutoFormatting: /^(?:# )/,
88
+ };
89
+
90
+ const markdownHeader2: MarkdownCriteria = {
91
+ ...paragraphStartBase,
92
+ export: createHeadingExport(2),
93
+ markdownFormatKind: 'paragraphH2',
94
+ regEx: /^(?:## )/,
95
+ regExForAutoFormatting: /^(?:## )/,
96
+ };
97
+
98
+ const markdownHeader3: MarkdownCriteria = {
99
+ ...paragraphStartBase,
100
+ export: createHeadingExport(3),
101
+ markdownFormatKind: 'paragraphH3',
102
+ regEx: /^(?:### )/,
103
+ regExForAutoFormatting: /^(?:### )/,
104
+ };
105
+
106
+ const markdownHeader4: MarkdownCriteria = {
107
+ ...paragraphStartBase,
108
+ export: createHeadingExport(4),
109
+ markdownFormatKind: 'paragraphH4',
110
+ regEx: /^(?:#### )/,
111
+ regExForAutoFormatting: /^(?:#### )/,
112
+ };
113
+
114
+ const markdownHeader5: MarkdownCriteria = {
115
+ ...paragraphStartBase,
116
+ export: createHeadingExport(5),
117
+ markdownFormatKind: 'paragraphH5',
118
+ regEx: /^(?:##### )/,
119
+ regExForAutoFormatting: /^(?:##### )/,
120
+ };
121
+
122
+ const markdownHeader6: MarkdownCriteria = {
123
+ ...paragraphStartBase,
124
+ export: createHeadingExport(6),
125
+ markdownFormatKind: 'paragraphH6',
126
+ regEx: /^(?:###### )/,
127
+ regExForAutoFormatting: /^(?:###### )/,
128
+ };
129
+
130
+ const markdownBlockQuote: MarkdownCriteria = {
131
+ ...paragraphStartBase,
132
+ export: blockQuoteExport,
133
+ markdownFormatKind: 'paragraphBlockQuote',
134
+ regEx: /^(?:> )/,
135
+ regExForAutoFormatting: /^(?:> )/,
136
+ };
137
+
138
+ const markdownUnorderedListDash: MarkdownCriteria = {
139
+ ...paragraphStartBase,
140
+ export: listExport,
141
+ markdownFormatKind: 'paragraphUnorderedList',
142
+ regEx: /^(\s{0,10})(?:- )/,
143
+ regExForAutoFormatting: /^(\s{0,10})(?:- )/,
144
+ };
145
+
146
+ const markdownUnorderedListAsterisk: MarkdownCriteria = {
147
+ ...paragraphStartBase,
148
+ export: listExport,
149
+ markdownFormatKind: 'paragraphUnorderedList',
150
+ regEx: /^(\s{0,10})(?:\* )/,
151
+ regExForAutoFormatting: /^(\s{0,10})(?:\* )/,
152
+ };
153
+
154
+ const markdownCodeBlock: MarkdownCriteria = {
155
+ ...paragraphStartBase,
156
+ export: codeBlockExport,
157
+ markdownFormatKind: 'paragraphCodeBlock',
158
+ regEx: /^(```)$/,
159
+ regExForAutoFormatting: /^(```)([a-z]*)( )/,
160
+ };
161
+
162
+ const markdownOrderedList: MarkdownCriteria = {
163
+ ...paragraphStartBase,
164
+ export: listExport,
165
+ markdownFormatKind: 'paragraphOrderedList',
166
+ regEx: /^(\s{0,10})(\d+)\.\s/,
167
+ regExForAutoFormatting: /^(\s{0,10})(\d+)\.\s/,
168
+ };
169
+
170
+ const markdownHorizontalRule: MarkdownCriteria = {
171
+ ...paragraphStartBase,
172
+ markdownFormatKind: 'horizontalRule',
173
+ regEx: /^(?:\*\*\*)$/,
174
+ regExForAutoFormatting: /^(?:\*\*\* )/,
175
+ };
176
+
177
+ const markdownHorizontalRuleUsingDashes: MarkdownCriteria = {
178
+ ...paragraphStartBase,
179
+ markdownFormatKind: 'horizontalRule',
180
+ regEx: /^(?:---)$/,
181
+ regExForAutoFormatting: /^(?:--- )/,
182
+ };
183
+
184
+ const markdownInlineCode: MarkdownCriteria = {
185
+ ...autoFormatBase,
186
+ exportFormat: 'code',
187
+ exportTag: '`',
188
+ markdownFormatKind: 'code',
189
+ regEx: /(`)(\s*)([^`]*)(\s*)(`)()/,
190
+ regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/,
191
+ };
192
+
193
+ const markdownBold: MarkdownCriteria = {
194
+ ...autoFormatBase,
195
+ exportFormat: 'bold',
196
+ exportTag: '**',
197
+ markdownFormatKind: 'bold',
198
+ regEx: /(\*\*)(\s*)([^**]*)(\s*)(\*\*)()/,
199
+ regExForAutoFormatting: /(\*\*)(\s*\b)([^**]*)(\b\s*)(\*\*)(\s)$/,
200
+ };
201
+
202
+ const markdownItalic: MarkdownCriteria = {
203
+ ...autoFormatBase,
204
+ exportFormat: 'italic',
205
+ exportTag: '*',
206
+ markdownFormatKind: 'italic',
207
+ regEx: /(\*)(\s*)([^*]*)(\s*)(\*)()/,
208
+ regExForAutoFormatting: /(\*)(\s*\b)([^*]*)(\b\s*)(\*)(\s)$/,
209
+ };
210
+
211
+ const markdownBold2: MarkdownCriteria = {
212
+ ...autoFormatBase,
213
+ exportFormat: 'bold',
214
+ exportTag: '_',
215
+ markdownFormatKind: 'bold',
216
+ regEx: /(__)(\s*)([^__]*)(\s*)(__)()/,
217
+ regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/,
218
+ };
219
+
220
+ const markdownItalic2: MarkdownCriteria = {
221
+ ...autoFormatBase,
222
+ exportFormat: 'italic',
223
+ exportTag: '_',
224
+ markdownFormatKind: 'italic',
225
+ regEx: /(_)()([^_]*)()(_)()/,
226
+ regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/, // Maintain 7 groups.
227
+ };
228
+
229
+ const fakeMarkdownUnderline: MarkdownCriteria = {
230
+ ...autoFormatBase,
231
+ exportFormat: 'underline',
232
+ exportTag: '<u>',
233
+ exportTagClose: '</u>',
234
+ markdownFormatKind: 'underline',
235
+ regEx: /(<u>)(\s*)([^<]*)(\s*)(<\/u>)()/,
236
+ regExForAutoFormatting: /(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/,
237
+ };
238
+
239
+ const markdownStrikethrough: MarkdownCriteria = {
240
+ ...autoFormatBase,
241
+ exportFormat: 'strikethrough',
242
+ exportTag: '~~',
243
+ markdownFormatKind: 'strikethrough',
244
+ regEx: /(~~)(\s*)([^~~]*)(\s*)(~~)()/,
245
+ regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/,
246
+ };
247
+
248
+ const markdownStrikethroughItalicBold: MarkdownCriteria = {
249
+ ...autoFormatBase,
250
+ markdownFormatKind: 'strikethrough_italic_bold',
251
+ regEx: /(~~_\*\*)(\s*\b)([^~~_**][^**_~~]*)(\b\s*)(\*\*_~~)()/,
252
+ regExForAutoFormatting:
253
+ /(~~_\*\*)(\s*\b)([^~~_**][^**_~~]*)(\b\s*)(\*\*_~~)(\s)$/,
254
+ };
255
+
256
+ const markdownItalicbold: MarkdownCriteria = {
257
+ ...autoFormatBase,
258
+ markdownFormatKind: 'italic_bold',
259
+ regEx: /(_\*\*)(\s*\b)([^_**][^**_]*)(\b\s*)(\*\*_)/,
260
+ regExForAutoFormatting: /(_\*\*)(\s*\b)([^_**][^**_]*)(\b\s*)(\*\*_)(\s)$/,
261
+ };
262
+
263
+ const markdownStrikethroughItalic: MarkdownCriteria = {
264
+ ...autoFormatBase,
265
+ markdownFormatKind: 'strikethrough_italic',
266
+ regEx: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,
267
+ regExForAutoFormatting: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/,
268
+ };
269
+
270
+ const markdownStrikethroughBold: MarkdownCriteria = {
271
+ ...autoFormatBase,
272
+ markdownFormatKind: 'strikethrough_bold',
273
+ regEx: /(~~\*\*)(\s*\b)([^~~**][^**~~]*)(\b\s*)(\*\*~~)/,
274
+ regExForAutoFormatting:
275
+ /(~~\*\*)(\s*\b)([^~~**][^**~~]*)(\b\s*)(\*\*~~)(\s)$/,
276
+ };
277
+
278
+ const markdownLink: MarkdownCriteria = {
279
+ ...autoFormatBase,
280
+ markdownFormatKind: 'link',
281
+ regEx: /(\[)([^\]]*)(\]\()([^)]*)(\)*)()/,
282
+ regExForAutoFormatting: /(\[)([^\]]*)(\]\()([^)]*)(\)*)(\s)$/,
283
+ };
284
+
285
+ const allMarkdownCriteriaForTextNodes: MarkdownCriteriaArray = [
286
+ // Place the combination formats ahead of the individual formats.
287
+ // Combos
288
+ markdownStrikethroughItalicBold,
289
+ markdownItalicbold,
290
+ markdownStrikethroughItalic,
291
+ markdownStrikethroughBold, // Individuals
292
+ markdownInlineCode,
293
+ markdownBold,
294
+ markdownItalic, // Must appear after markdownBold
295
+ markdownBold2,
296
+ markdownItalic2, // Must appear after markdownBold2.
297
+ fakeMarkdownUnderline,
298
+ markdownStrikethrough,
299
+ markdownLink,
300
+ ];
301
+
302
+ const allMarkdownCriteriaForParagraphs: MarkdownCriteriaArray = [
303
+ markdownHeader1,
304
+ markdownHeader2,
305
+ markdownHeader3,
306
+ markdownHeader4,
307
+ markdownHeader5,
308
+ markdownHeader6,
309
+ markdownBlockQuote,
310
+ markdownUnorderedListDash,
311
+ markdownUnorderedListAsterisk,
312
+ markdownOrderedList,
313
+ markdownCodeBlock,
314
+ markdownHorizontalRule,
315
+ markdownHorizontalRuleUsingDashes,
316
+ ];
317
+
318
+ export function getAllMarkdownCriteriaForParagraphs(): MarkdownCriteriaArray {
319
+ return allMarkdownCriteriaForParagraphs;
320
+ }
321
+
322
+ export function getAllMarkdownCriteriaForTextNodes(): MarkdownCriteriaArray {
323
+ return allMarkdownCriteriaForTextNodes;
324
+ }
325
+
326
+ type Block = (
327
+ node: LexicalNode,
328
+ exportChildren: (elementNode: ElementNode) => string,
329
+ ) => string | null;
330
+
331
+ function createHeadingExport(level: number): Block {
332
+ return (node, exportChildren) => {
333
+ return $isHeadingNode(node) && node.getTag() === 'h' + level
334
+ ? '#'.repeat(level) + ' ' + exportChildren(node)
335
+ : null;
336
+ };
337
+ }
338
+
339
+ function listExport(
340
+ node: LexicalNode,
341
+ exportChildren: (_node: ElementNode) => string,
342
+ ) {
343
+ return $isListNode(node) ? processNestedLists(node, exportChildren, 0) : null;
344
+ }
345
+
346
+ // TODO: should be param
347
+ const LIST_INDENT_SIZE = 4;
348
+
349
+ function processNestedLists(
350
+ listNode: ListNode,
351
+ exportChildren: (node: ElementNode) => string,
352
+ depth: number,
353
+ ): string {
354
+ const output = [];
355
+ const children = listNode.getChildren();
356
+ let index = 0;
357
+
358
+ for (const listItemNode of children) {
359
+ if ($isListItemNode(listItemNode)) {
360
+ if (listItemNode.getChildrenSize() === 1) {
361
+ const firstChild = listItemNode.getFirstChild();
362
+
363
+ if ($isListNode(firstChild)) {
364
+ output.push(
365
+ processNestedLists(firstChild, exportChildren, depth + 1),
366
+ );
367
+ continue;
368
+ }
369
+ }
370
+
371
+ const indent = ' '.repeat(depth * LIST_INDENT_SIZE);
372
+ const prefix =
373
+ listNode.getListType() === 'bullet'
374
+ ? '- '
375
+ : `${listNode.getStart() + index}. `;
376
+ output.push(indent + prefix + exportChildren(listItemNode));
377
+ index++;
378
+ }
379
+ }
380
+
381
+ return output.join('\n');
382
+ }
383
+
384
+ function blockQuoteExport(
385
+ node: LexicalNode,
386
+ exportChildren: (_node: ElementNode) => string,
387
+ ) {
388
+ return $isQuoteNode(node) ? '> ' + exportChildren(node) : null;
389
+ }
390
+
391
+ function codeBlockExport(node: LexicalNode) {
392
+ if (!$isCodeNode(node)) {
393
+ return null;
394
+ }
395
+
396
+ const textContent = node.getTextContent();
397
+ return (
398
+ '```' +
399
+ (node.getLanguage() || '') +
400
+ (textContent ? '\n' + textContent : '') +
401
+ '\n' +
402
+ '```'
403
+ );
404
+ }
405
+
406
+ export function indexBy<T>(
407
+ list: Array<T>,
408
+ callback: (arg0: T) => string | undefined,
409
+ ): Readonly<Record<string, Array<T>>> {
410
+ const index: Record<string, Array<T>> = {};
411
+
412
+ for (const item of list) {
413
+ const key = callback(item);
414
+
415
+ if (!key) {
416
+ continue;
417
+ }
418
+
419
+ if (index[key]) {
420
+ index[key].push(item);
421
+ } else {
422
+ index[key] = [item];
423
+ }
424
+ }
425
+
426
+ return index;
427
+ }
428
+
429
+ export function transformersByType(transformers: Array<Transformer>): Readonly<{
430
+ element: Array<ElementTransformer>;
431
+ multilineElement: Array<MultilineElementTransformer>;
432
+ textFormat: Array<TextFormatTransformer>;
433
+ textMatch: Array<TextMatchTransformer>;
434
+ }> {
435
+ const byType = indexBy(transformers, t => t.type);
436
+
437
+ return {
438
+ element: (byType.element || []) as Array<ElementTransformer>,
439
+ multilineElement: (byType['multiline-element'] ||
440
+ []) as Array<MultilineElementTransformer>,
441
+ textFormat: (byType['text-format'] || []) as Array<TextFormatTransformer>,
442
+ textMatch: (byType['text-match'] || []) as Array<TextMatchTransformer>,
443
+ };
444
+ }
445
+
446
+ export const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/;
447
+ export const WHITESPACE = /\s/;
448
+ export const PUNCTUATION = /[!"#$%&'()*+,\-./:;<=>?@[\]^_`{|}~]/;
449
+
450
+ const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/;
451
+
452
+ export function isEmptyParagraph(node: LexicalNode): boolean {
453
+ if (!$isParagraphNode(node)) {
454
+ return false;
455
+ }
456
+
457
+ const firstChild = node.getFirstChild();
458
+ return (
459
+ firstChild == null ||
460
+ (node.getChildrenSize() === 1 &&
461
+ $isTextNode(firstChild) &&
462
+ MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent()))
463
+ );
464
+ }
465
+
466
+ export function unescapeText(value: string): string {
467
+ return value
468
+ .replace(/\\([!-/:-@[-`{-~])/g, '$1')
469
+ .replace(/&#(\d+);/g, (_, codePoint) =>
470
+ String.fromCodePoint(Number(codePoint)),
471
+ );
472
+ }
@@ -1,9 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
-
9
- "use strict";var e=require("lexical"),t=require("@lexical/selection"),n=require("@lexical/code-core"),o=require("@lexical/link"),r=require("@lexical/list"),i=require("@lexical/rich-text"),s=require("@lexical/utils");function l(e,t){const n={};for(const o of e){const e=t(o);e&&(n[e]?n[e].push(o):n[e]=[o])}return n}function c(e){const t=l(e,e=>e.type);return{element:t.element||[],multilineElement:t["multiline-element"]||[],textFormat:t["text-format"]||[],textMatch:t["text-match"]||[]}}const a=/[!-/:-@[-`{-~\s]/,d=/[ \t\n\r\f]/,f=/[!"#$%&'()*+,\-./:;<=>?@[\]^_`{|}~]/,u=/^\s{0,3}$/;function g(t){if(!e.$isParagraphNode(t))return!1;const n=t.getFirstChild();return null==n||1===t.getChildrenSize()&&e.$isTextNode(n)&&u.test(n.getTextContent())}function p(e){return e.replace(/\\([!-/:-@[-`{-~])/g,"$1").replace(/&#(\d+);/g,(e,t)=>String.fromCodePoint(Number(t)))}const h=/^(\s*)(\d{1,})\.\s/,x=/^(\s*)[-*+]\s/,m=/^(\s*)(?:[-*+]\s)?\s?(\[(\s|x)?\])\s/i,$=/^(#{1,6})\s/,N=/^>\s/,T=/^([ \t]*`{3,})([\w-]+)?[ \t]?/,C=/^[ \t]*`{3,}$/,E=/^[ \t]*```[^`]+(?:(?:`{1,2}|`{4,})[^`]+)*```(?:[^`]|$)/,S=/^(?:\|)(.+)(?:\|)\s?$/,I=/^(\| ?:?-*:? ?)+\|\s?$/,L=/^<[a-z_][\w-]*(?:\s[^<>]*)?\/?>/i,R=/^<\/[a-z_][\w-]*\s*>/i,v=e=>new RegExp(`(?:${e.source})$`,e.flags),O=e.createState("mdListMarker",{parse:e=>"string"==typeof e&&/^[-*+]$/.test(e)?e:"-",resetOnCopyNode:!0}),y=e.createState("mdCodeFence",{parse:e=>"string"==typeof e&&/^`{3,}$/.test(e)?e:"```",resetOnCopyNode:!0}),_=e.createState("mdHardLineBreak",{parse:e=>"string"==typeof e&&/^(\\| {2,})$/.test(e)?e:"",resetOnCopyNode:!0});function k(e){if(e.endsWith("\\"))return[e.slice(0,-1),"\\"];const t=e.match(/^(.*?\S)( {2,})$/);return t?[t[1],t[2]]:null}function w(t){const n=t.getChildren(),o=n.length-1,r=n[o];if(!e.$isTextNode(r))return null;const i=r.getTextContent(),s=k(i);if(null!==s){const[e,t]=s;return r.setTextContent(e),t}return/^ {2,}$/.test(i)&&function(t,n){for(let o=n-1;o>=0;o--){if(e.$isLineBreakNode(t[o]))return!1;if(/\S/.test(t[o].getTextContent()))return!0}return!1}(n,o)?(r.setTextContent(""),i):null}function M(t){const n=e.$createLineBreakNode(),o=w(t);return null!==o&&e.$setState(n,_,o),n}const A=e=>(t,n,o,r)=>{const i=e(o);i.append(...n),t.replace(i),r||i.select(0,0)};const b=t=>(n,o,i,s)=>{const l=n.getPreviousSibling(),c=n.getNextSibling(),a=r.$createListItemNode("check"===t?"x"===i[3]:void 0),d=i[0].trim()[0],f="bullet"!==t&&"check"!==t||d!==O.parse(d)?void 0:d;if(r.$isListNode(c)&&c.getListType()===t){f&&e.$setState(c,O,f);const t=c.getFirstChild();null!==t?t.insertBefore(a):c.append(a),n.remove()}else if(r.$isListNode(l)&&l.getListType()===t)f&&e.$setState(l,O,f),l.append(a),n.remove();else{const o=r.$createListNode(t,"number"===t?Number(i[2]):void 0);f&&e.$setState(o,O,f),o.append(a),n.replace(o)}a.append(...o),s||a.select(0,0);const u=function(e){const t=e.match(/\t/g),n=e.match(/ /g);let o=0;return t&&(o+=t.length),n&&(o+=Math.floor(n.length/4)),o}(i[1]);u&&a.setIndent(u)},F=(t,n,o,i)=>{const s=[],l=t.getChildren();let c=0;for(const a of l)if(r.$isListItemNode(a)){if(1===a.getChildrenSize()){const e=a.getFirstChild();if(r.$isListNode(e)){const t=F(e,n,o+1,i);t&&s.push(t);continue}}if(i&&!a.getChildren().some(e=>e.isSelected(i)))continue;const l=" ".repeat(4*o),d=t.getListType(),f=e.$getState(t,O),u="number"===d?`${t.getStart()+c}. `:"check"===d?`${f} [${a.getChecked()?"x":" "}] `:f+" ";let g=n(a);"number"!==d&&(g=g.replace(/^(\s{0,3}\d+)(\.\s)/,"$1\\$2")),s.push(l+u+g),c++}return s.join("\n")},B={dependencies:[i.HeadingNode],export:(e,t)=>{if(!i.$isHeadingNode(e))return null;const n=Number(e.getTag().slice(1));return"#".repeat(n)+" "+t(e)},regExp:$,replace:A(e=>{const t="h"+e[1].length;return i.$createHeadingNode(t)}),triggerOnEnter:!0,type:"element"},D={dependencies:[i.QuoteNode],export:(e,t)=>{if(!i.$isQuoteNode(e))return null;const n=t(e).split("\n"),o=[];for(const e of n)o.push("> "+e);return o.join("\n")},regExp:N,replace:(e,t,n,o)=>{if(o){const n=e.getPreviousSibling();if(i.$isQuoteNode(n))return n.splice(n.getChildrenSize(),0,[M(n),...t]),void e.remove()}const r=i.$createQuoteNode();r.append(...t),e.replace(r),o||r.select(0,0)},triggerOnEnter:!0,type:"element"},P={dependencies:[n.CodeNode],export:t=>{if(!n.$isCodeNode(t))return null;const o=t.getTextContent();let r=e.$getState(t,y);if(o.indexOf(r)>-1){const e=o.match(/`{3,}/g);if(e){const t=Math.max(...e.map(e=>e.length));r="`".repeat(t+1)}}return r+(t.getLanguage()||"")+(o?"\n"+o:"")+"\n"+r},handleImportAfterStartMatch:({lines:e,rootNode:t,startLineIndex:n,startMatch:o})=>{const r=o[1],i=r.trim().length,s=e[n],l=o.index+r.length,c=s.slice(l),a=new RegExp(`\`{${i},}$`);if(a.test(c)){const e=c.match(a),r=c.slice(0,c.lastIndexOf(e[0])),i=[...o];return i[2]="",P.replace(t,null,i,e,[r],!0),[!0,n]}const d=new RegExp(`^[ \\t]*\`{${i},}$`);for(let r=n+1;r<e.length;r++){const i=e[r];if(d.test(i)){const l=i.match(d),c=e.slice(n+1,r),a=s.slice(o[0].length);return a.length>0&&c.unshift(a),P.replace(t,null,o,l,c,!0),[!0,r]}}const f=e.slice(n+1),u=s.slice(o[0].length);return u.length>0&&f.unshift(u),P.replace(t,null,o,null,f,!0),[!0,e.length-1]},regExpEnd:{optional:!0,regExp:C},regExpStart:T,replace:(t,o,r,i,s,l)=>{let c,a;const d=r[1]?r[1].trim():"```",f=r[2]||void 0;if(!o&&s){if(1===s.length)i?(c=n.$createCodeNode(f),a=s[0]):(c=n.$createCodeNode(f),a=s[0].startsWith(" ")?s[0].slice(1):s[0]);else{for(c=n.$createCodeNode(f),s.length>0&&(0===s[0].trim().length?s.shift():s[0].startsWith(" ")&&(s[0]=s[0].slice(1)));s.length>0&&!s[s.length-1].length;)s.pop();a=s.join("\n")}e.$setState(c,y,d);const o=e.$createTextNode(a);c.append(o),t.append(c)}else o&&A(e=>n.$createCodeNode(e?e[2]:void 0))(t,o,r,l)},type:"multiline-element"},H={dependencies:[r.ListNode,r.ListItemNode],export:(e,t,n)=>r.$isListNode(e)?F(e,t,0,n):null,regExp:x,replace:b("bullet"),triggerOnEnter:!0,type:"element"},j={dependencies:[r.ListNode,r.ListItemNode],export:(e,t,n)=>r.$isListNode(e)?F(e,t,0,n):null,regExp:m,replace:b("check"),triggerOnEnter:!0,type:"element"},U={dependencies:[r.ListNode,r.ListItemNode],export:(e,t,n)=>r.$isListNode(e)?F(e,t,0,n):null,regExp:h,replace:b("number"),triggerOnEnter:!0,type:"element"},z={format:["code"],tag:"`",type:"text-format"},G={format:["highlight"],tag:"==",type:"text-format"},W={format:["bold","italic"],tag:"***",type:"text-format"},q={format:["bold","italic"],intraword:!1,tag:"___",type:"text-format"},Q={format:["bold"],tag:"**",type:"text-format"},K={format:["bold"],intraword:!1,tag:"__",type:"text-format"},Y={format:["strikethrough"],tag:"~~",type:"text-format"},X={format:["italic"],tag:"*",type:"text-format"},J={format:["italic"],intraword:!1,tag:"_",type:"text-format"},V={dependencies:[o.LinkNode],export:(e,t,n)=>{if(!o.$isLinkNode(e)||o.$isAutoLinkNode(e))return null;const r=t(e);let i=e.getTitle();null!=i&&(i=i.replace(/([\\"])/g,"\\$1"));return i?`[${r}](${e.getURL()} "${i}")`:`[${r}](${e.getURL()})`},importRegExp:/(?:\[(.+?)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))/,regExp:/(?:\[([^[\]]*(?:\[[^[\]]*\][^[\]]*)*)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))$/,replace:(t,n)=>{if(e.$findMatchingParent(t,o.$isLinkNode))return;const[,r,i,s]=n,l=null!=i?p(i):void 0,c=null!=s?p(s):void 0,a=o.$createLinkNode(l,{title:c}),d=r.split("[").length-1,f=r.split("]").length-1;let u=r,g="";if(d<f)return;if(d>f){const e=r.split("[");g="["+e[0],u=e.slice(1).join("[")}const h=e.$createTextNode(u);return h.setFormat(t.getFormat()),a.append(h),t.replace(a),g&&a.insertBefore(e.$createTextNode(g)),h},trigger:")",type:"text-match"},Z=[B,D,H,U],ee=[P],te=[z,W,q,Q,K,G,X,J,Y],ne=[V],oe=[...Z,...ee,...te,...ne];function re(t,n,o,r,i,s){let l=t.isSelected(n);for(const c of o){if(!c.export)continue;const o=c.export(t,e=>ie(e,n,r,i,s).markdown,n);if(null!=o){if(!l&&e.$isElementNode(t)){ie(t,n,r,i,s).shouldInclude&&(l=!0)}return{markdown:o,shouldInclude:l}}}if(e.$isElementNode(t)){const e=ie(t,n,r,i,s);return{markdown:e.markdown,shouldInclude:l||e.shouldInclude}}return e.$isDecoratorNode(t)?{markdown:t.getTextContent(),shouldInclude:l}:{markdown:null,shouldInclude:l}}function ie(n,o,r,i,s,l,c){const a=[],d=n.getChildren();let f=!1;l||(l=[]),c||(c=[]);e:for(const n of d){let d=n.isSelected(o);for(const u of i){if(!u.export)continue;const g=u.export(n,e=>ie(e,o,r,i,s,l,[...c,...l]).markdown,(e,n)=>ae(e,t.$sliceSelectedTextNodeContent(o,e,"clone").getTextContent(),r,l,c,s));if(null!=g){!d&&e.$isElementNode(n)&&n.getChildren().some(e=>e.isSelected(o))&&n.extractWithChild(n,o,"html")&&(d=!0),d&&(a.push(g),f=!0);continue e}}if(e.$isLineBreakNode(n))d&&(a.push(ce(n)),f=!0);else if(e.$isTextNode(n)){if(d){const e=t.$sliceSelectedTextNodeContent(o,n,"clone");a.push(ae(n,e.getTextContent(),r,l,c,s)),f=!0}}else if(e.$isElementNode(n)){const e=ie(n,o,r,i,s,l,c);!d&&e.shouldInclude&&n.extractWithChild(n,o,"html")&&(d=!0),(d||e.shouldInclude)&&(a.push(e.markdown),f=!0)}else e.$isDecoratorNode(n)&&d&&(a.push(n.getTextContent()),f=!0)}return{markdown:a.join(""),shouldInclude:f}}function se(t,n,o,r,i){for(const e of n){if(!e.export)continue;const n=e.export(t,e=>le(e,o,r,void 0,void 0,i));if(null!=n)return n}return e.$isElementNode(t)?le(t,o,r,void 0,void 0,i):e.$isDecoratorNode(t)?t.getTextContent():null}function le(t,n,o,r,i,s=!1){const l=[],c=t.getChildren();r||(r=[]),i||(i=[]);e:for(const t of c){for(const e of o){if(!e.export)continue;const c=e.export(t,e=>le(e,n,o,r,[...i,...r],s),(e,t)=>ae(e,t,n,r,i,s));if(null!=c){l.push(c);continue e}}e.$isLineBreakNode(t)?l.push(ce(t)):e.$isTextNode(t)?l.push(ae(t,t.getTextContent(),n,r,i,s)):e.$isElementNode(t)?l.push(le(t,n,o,r,i,s)):e.$isDecoratorNode(t)&&l.push(t.getTextContent())}return l.join("")}function ce(t){return e.$getState(t,_)+"\n"}function ae(e,t,n,o,r,i=!1){let s=t;e.hasFormat("code")||(s=i?s.replace(/([*_`~])/g,"\\$1"):s.replace(/([*_`~\\])/g,"\\$1"));const l=s.match(/^(\s*)(.*?)(\s*)$/s)||["","",s,""],c=l[1],a=l[2],d=l[3],f=""===a;let u="",g="",p="";const h=de(e,!0),x=de(e,!1),m=new Set;for(const t of n){const n=t.format[0],r=t.tag;ue(e,n)&&!m.has(n)&&(m.add(n),ue(h,n)&&o.find(e=>e.tag===r)||(o.push({format:n,tag:r}),u+=r))}for(let t=0;t<o.length;t++){const n=fe(e,o[t].format),i=fe(x,o[t].format);if(n&&i)continue;const s=[...o];for(;s.length>t;){const e=s.pop();r&&e&&r.find(t=>t.tag===e.tag)||(e&&"string"==typeof e.tag&&(n?i||(p+=e.tag):g+=e.tag),o.pop())}break}return f&&!e.hasFormat("code")?g+s:g+c+u+a+p+d}function de(t,n){const o=n?t.getPreviousSibling():t.getNextSibling();return e.$isTextNode(o)?o:null}function fe(t,n){return e.$isTextNode(t)&&t.hasFormat(n)}function ue(e,t){return!!fe(e,t)&&("code"===t||(!e||!/^\s*$/.test(e.getTextContent())))}function ge(e,t){const n=e.getTextContent(),o=t.fullMatchRegExpByTag["`"],r=t.transformersByTag["`"],i=[];let s=null;if(o&&r){const e=new RegExp(o.source,"g"),t=Array.from(n.matchAll(e));for(const e of t){const t=e.index+e[1].length,n=e.index+e[0].length;s||(s={content:e[3],endIndex:n,startIndex:t,tag:"`"}),i.push({end:n,start:t})}}const l=function(e,t,n=[]){const o=[],r=new Set(Object.keys(t.transformersByTag).filter(e=>"`"!==e[0]).map(e=>e[0])),i=t=>{let n=0;for(let o=t-1;o>=0&&"\\"===e[o];o--)n++;return n%2==1},s=e=>n.some(t=>e>=t.start&&e<t.end);let l=0;for(;l<e.length;){const t=e[l];if(!r.has(t)||i(l)||s(l)){l++;continue}let n=1;for(;l+n<e.length&&e[l+n]===t;)n++;const c=pe(t,e,l,n,!0),a=pe(t,e,l,n,!1);(c||a)&&o.push({active:!0,canClose:a,canOpen:c,char:t,index:l,length:n,originalLength:n}),l+=n}return o}(n,t,i),c=l.length>0?function(e,t,n){const o={};let r=0,i=null;for(;r<t.length;){const s=t[r];if(!s.active||!s.canClose||0===s.length){r++;continue}const l=`${s.char}${s.canOpen}`,c=o[l]??-1;let a=!1;for(let o=r-1;o>c;o--){const l=t[o];if(!l.active||!l.canOpen||0===l.length||l.char!==s.char)continue;if(l.canClose||s.canOpen){if((l.originalLength+s.originalLength)%3==0&&l.originalLength%3!=0&&s.originalLength%3!=0)continue}const c=Math.min(l.length,s.length),d=Object.keys(n.transformersByTag).filter(e=>e[0]===l.char&&e.length<=c).sort((e,t)=>t.length-e.length)[0];if(!d)continue;a=!0;const f=d.length,u={content:e.slice(l.index+l.length,s.index),endIndex:s.index+f,startIndex:l.index+(l.length-f),tag:d};(!i||u.startIndex<i.startIndex||u.startIndex===i.startIndex&&u.endIndex>i.endIndex)&&(i=u);for(let e=o+1;e<r;e++)t[e].active=!1;l.length-=f,s.length-=f,l.active=l.length>0,s.length>0?s.index+=f:(s.active=!1,r++);break}a||(o[l]=r-1,s.canOpen||(s.active=!1),r++)}return i}(n,l,t):null;let a=null,d=null;if(s&&c?c.startIndex<=s.startIndex&&c.endIndex>=s.endIndex?(a=c,d=t.transformersByTag[c.tag]):(a=s,d=r):s?(a=s,d=r):c&&(a=c,d=t.transformersByTag[c.tag]),!a||!d)return null;const f=[n.slice(a.startIndex,a.endIndex),a.tag,a.content];return f.index=a.startIndex,f.input=n,{endIndex:a.endIndex,match:f,startIndex:a.startIndex,transformer:d}}function pe(e,t,n,o,r){if(!he(t,n,o,r))return!1;if("*"===e)return!0;if("_"===e){if(!he(t,n,o,!r))return!0;const e=r?t[n-1]:t[n+o];return void 0!==e&&f.test(e)}return!0}function he(e,t,n,o){const r=e[t-1],i=e[t+n],[s,l]=o?[i,r]:[r,i];return void 0!==s&&!d.test(s)&&(!f.test(s)||(void 0===l||d.test(l)||f.test(l)))}function xe(t){return e.$isTextNode(t)&&!t.hasFormat("code")}function me(e,t,n){let o=ge(e,t),r=function(e,t){const n=e;let o,r,i,s;for(const e of t){if(!e.replace||!e.importRegExp)continue;const t=n.getTextContent().match(e.importRegExp);if(!t)continue;const l=t.index||0,c=e.getEndIndex?e.getEndIndex(n,t):l+t[0].length;!1!==c&&(void 0===o||void 0===r||l<o&&(c>r||c<=o))&&(o=l,r=c,i=e,s=t)}return void 0===o||void 0===r||void 0===i||void 0===s?null:{endIndex:r,match:s,startIndex:o,transformer:i}}(e,n);if(o&&r&&(o.startIndex<=r.startIndex&&o.endIndex>=r.endIndex||r.startIndex>o.endIndex?r=null:o=null),o){const r=function(e,t,n,o,r){const i=e.getTextContent();let s,l,c;if(r[0]===i?s=e:0===t?[s,l]=e.splitText(n):[c,s,l]=e.splitText(t,n),s.setTextContent(r[2]),o)for(const e of o.format)s.hasFormat(e)||s.toggleFormat(e);return{nodeAfter:l,nodeBefore:c,transformedNode:s}}(e,o.startIndex,o.endIndex,o.transformer,o.match);xe(r.nodeAfter)&&me(r.nodeAfter,t,n),xe(r.nodeBefore)&&me(r.nodeBefore,t,n),xe(r.transformedNode)&&me(r.transformedNode,t,n)}else if(r){const o=function(e,t,n,o,r){let i,s,l;return 0===t?[i,s]=e.splitText(n):[l,i,s]=e.splitText(t,n),o.replace?{nodeAfter:s,nodeBefore:l,transformedNode:o.replace(i,r)||void 0}:null}(e,r.startIndex,r.endIndex,r.transformer,r.match);if(!o)return;xe(o.nodeAfter)&&me(o.nodeAfter,t,n),xe(o.nodeBefore)&&me(o.nodeBefore,t,n),xe(o.transformedNode)&&me(o.transformedNode,t,n)}const i=p(e.getTextContent());e.setTextContent(i)}function $e(t,n=!1){const o=c(t),r=function(e){const t={},n={},o=[];for(const r of e){const{tag:e}=r;t[e]=r;const i=e.replace(/(\*|\^|\+)/g,"\\$1");o.push(i),1===e.length?n[e]="`"===e?new RegExp("(^|[^\\\\`])(`)((?:\\\\`|[^`])+?)(`)(?!`)"):new RegExp(`(^|[^\\\\${i}])(${i})((\\\\${i})?.*?[^${i}\\s](\\\\${i})?)(${i})(?![\\\\${i}])`):n[e]=new RegExp(`(^|[^\\\\])(${i})((\\\\${i})?.*?[^\\s](\\\\${i})?)(${i})(?!\\\\)`)}return{fullMatchRegExpByTag:n,openTagsRegExp:new RegExp(`(${o.join("|")})`,"g"),transformersByTag:t}}(o.textFormat);return(t,i)=>{const s=t.split("\n"),l=s.length,c=i||e.$getRoot();c.clear();for(let e=0;e<l;e++){const t=s[e],[i,l]=Ne(s,e,o.multilineElement,c);i?e=l:Te(t,c,o.element,r,o.textMatch,n)}const a=c.getChildren();for(const t of a)if(!n&&g(t)&&c.getChildrenSize()>1)t.remove();else if(e.$isElementNode(t))for(const e of t.getAllTextNodes())Ce(e);null!==e.$getSelection()&&c.selectStart()}}function Ne(e,t,n,o){for(const r of n){const{handleImportAfterStartMatch:n,regExpEnd:i,regExpStart:s,replace:l}=r,c=e[t].match(s);if(!c)continue;if(n){const i=n({lines:e,rootNode:o,startLineIndex:t,startMatch:c,transformer:r});if(null===i)continue;if(i)return i}const a="object"==typeof i&&"regExp"in i?i.regExp:i,d=i&&"object"==typeof i&&"optional"in i?i.optional:!i;let f=t;const u=e.length;for(;f<u;){const n=a?e[f].match(a):null;if(!n&&(!d||d&&f<u-1)){f++;continue}if(n&&t===f&&n.index===c.index){f++;continue}const r=[];if(n&&t===f)r.push(e[t].slice(c[0].length,-n[0].length));else for(let o=t;o<=f;o++)if(o===t){const t=e[o].slice(c[0].length);r.push(t)}else if(o===f&&n){const t=e[o].slice(0,-n[0].length);r.push(t)}else r.push(e[o]);if(!1!==l(o,null,c,n,r,!0))return[!0,f];break}}return[!1,t]}function Te(t,n,o,l,c,a){const d=e.$createTextNode(t),f=e.$createParagraphNode();f.append(d),n.append(f);for(const{regExp:e,replace:n}of o){const o=t.match(e);if(o&&(d.setTextContent(t.slice(o[0].length)),!1!==n(f,[d],o,!0)))break}if(me(d,l,c),f.isAttached()&&t.length>0){const t=f.getPreviousSibling();if(!a&&(e.$isParagraphNode(t)||i.$isQuoteNode(t)||r.$isListNode(t))){let e=t;if(r.$isListNode(t)){const n=t.getLastDescendant();e=null==n?null:s.$findMatchingParent(n,r.$isListItemNode)}null!=e&&e.getTextContentSize()>0&&(e.splice(e.getChildrenSize(),0,[M(e),...f.getChildren()]),f.remove())}}}function Ce(t){const n=new Set,o=t.getTextContent();let r=o.indexOf("\t");for(;-1!==r;)n.add(r),n.add(r+1),r=o.indexOf("\t",r+1);t.splitText(...n).forEach(t=>{"\t"===t.getTextContent()&&t.replace(e.$createTabNode())})}function Ee(e,...t){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",e);for(const e of t)o.append("v",e);throw n.search=o.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function Se(t,n,o,r,i){const s=t.getParent();if(!e.$isRootOrShadowRoot(s)||t.getFirstChild()!==n)return!1;const l=n.getTextContent();if(!i&&" "!==l[o-1])return!1;for(const{regExp:e,replace:s}of r){const r=l.match(e),c=i||r&&r[0].endsWith(" ")?o:o-1;if(r&&r[0].length===c){const e=n.getNextSiblings(),[i,l]=n.splitText(o);if(!1!==s(t,l?[l,...e]:e,r,!1))return i.remove(),!0}}return!1}function Ie(t,n,o,r,i){const s=t.getParent();if(!e.$isRootOrShadowRoot(s)||t.getFirstChild()!==n)return!1;const l=n.getTextContent();if(!i&&" "!==l[o-1])return!1;for(const{regExpStart:e,replace:s,regExpEnd:c}of r){if(c&&!("optional"in c)||c&&"optional"in c&&!c.optional)continue;const r=l.match(e);if(r){const e=i||r[0].endsWith(" ")?o:o-1;if(r[0].length!==e)continue;const l=n.getNextSiblings(),[c,a]=n.splitText(o);if(!1!==s(t,a?[a,...l]:l,r,null,null,!1))return c.remove(),!0}}return!1}function Le(e,t){let n=0;const o=e.getTextContent();for(let e=0;e<t;e++)"`"===o[e]&&n++;return n%2!=0}function Re(e,t,n){const o=n.length;for(let r=t;r>=o;r--){const t=r-o;if(ve(e,t,n,0,o)&&" "!==e[t+o])return t}return-1}function ve(e,t,n,o,r){for(let i=0;i<r;i++)if(e[t+i]!==n[o+i])return!1;return!0}exports.$convertFromMarkdownString=function(e,t=oe,n,o=!1,r=!1){const i=o?e:function(e,t=!1){const n=e.split("\n");let o=!1;const r=[];for(let e=0;e<n.length;e++){const i=n[e],s=i.trimEnd(),l=r[r.length-1],c=e<n.length-1?k(i):null,a=void 0!==l&&null!==k(l);E.test(s)?r.push(s):T.test(s)||C.test(s)?(o=!o,r.push(s)):o?r.push(i):""===s||""===l||!l||$.test(l)||$.test(s)||N.test(s)||h.test(s)||x.test(s)||m.test(s)||S.test(s)||I.test(s)||a||!t||L.test(s)||R.test(s)||v(R).test(l)||v(L).test(l)||C.test(l)?r.push(!t&&""!==s||null!==c?i:s):r[r.length-1]=l+" "+(null===c?s:i).trimStart()}return r.join("\n")}(e,r);return $e(t,o)(i,n)},exports.$convertSelectionToMarkdownString=function(t=oe,n,o=!1){if(!n||e.$isRangeSelection(n)&&n.isCollapsed())return"";const r=function(t,n=!1){const o=c(t),r=[...o.multilineElement,...o.element],i=!n,s=o.textFormat.filter(e=>1===e.format.length).sort((e,t)=>Number(e.format.includes("code"))-Number(t.format.includes("code")));return t=>{const l=[],c=e.$getRoot().getChildren();for(let e=0;e<c.length;e++){const a=c[e],{shouldInclude:d,markdown:f}=re(a,t,r,s,o.textMatch,n);d&&null!=f&&l.push(i&&e>0&&!g(a)&&!g(c[e-1])?"\n".concat(f):f)}return l.join("\n")}}(t,o);return r(n)},exports.$convertToMarkdownString=function(t=oe,n,o=!1){return function(t,n=!1){const o=c(t),r=[...o.multilineElement,...o.element],i=!n,s=o.textFormat.filter(e=>1===e.format.length).sort((e,t)=>Number(e.format.includes("code"))-Number(t.format.includes("code")));return t=>{const l=[],c=(t||e.$getRoot()).getChildren();for(let e=0;e<c.length;e++){const t=c[e],a=se(t,r,s,o.textMatch,n);null!=a&&l.push(i&&e>0&&!g(t)&&!g(c[e-1])?"\n".concat(a):a)}return l.join("\n")}}(t,o)(n)},exports.BOLD_ITALIC_STAR=W,exports.BOLD_ITALIC_UNDERSCORE=q,exports.BOLD_STAR=Q,exports.BOLD_UNDERSCORE=K,exports.CHECK_LIST=j,exports.CODE=P,exports.ELEMENT_TRANSFORMERS=Z,exports.HEADING=B,exports.HIGHLIGHT=G,exports.INLINE_CODE=z,exports.ITALIC_STAR=X,exports.ITALIC_UNDERSCORE=J,exports.LINK=V,exports.MULTILINE_ELEMENT_TRANSFORMERS=ee,exports.ORDERED_LIST=U,exports.QUOTE=D,exports.STRIKETHROUGH=Y,exports.TEXT_FORMAT_TRANSFORMERS=te,exports.TEXT_MATCH_TRANSFORMERS=ne,exports.TRANSFORMERS=oe,exports.UNORDERED_LIST=H,exports.registerMarkdownShortcuts=function(t,o=oe){const r=c(o),i=r.element.filter(e=>e.triggerOnEnter),s=l(r.textFormat,({tag:e})=>e[e.length-1]),d=l(r.textMatch,({trigger:e})=>e),f=new Set([" "]);for(const e of r.textFormat)f.add(e.tag.slice(-1));for(const e of r.textMatch)void 0!==e.trigger&&f.add(e.trigger);for(const e of o){const n=e.type;if("element"===n||"text-match"===n||"multiline-element"===n){const n=e.dependencies;for(const e of n)t.hasNode(e)||Ee(173,e.getType())}}const u=(t,n,o)=>!!Se(t,n,o,r.element)||(!!Ie(t,n,o,r.multilineElement)||(!!function(e,t,n){let o=e.getTextContent();const r=n[o[t-1]];if(null==r)return!1;t<o.length&&(o=o.slice(0,t));for(const t of r){if(!t.replace||!t.regExp)continue;const n=o.match(t.regExp);if(null===n)continue;const r=n.index||0,i=r+n[0].length;let s;return 0===r?[s]=e.splitText(i):[,s]=e.splitText(r,i),s.selectNext(0,0),t.replace(s,n),!0}return!1}(n,o,d)||!!function(t,n,o){const r=t.getTextContent(),i=n-1,s=r[i],l=o[s];if(!l)return!1;for(const n of l){const{tag:o}=n,l=o.length,c=i-l+1;if(l>1&&!ve(r,c,o,0,l))continue;if(" "===r[c-1])continue;const d=r[i+1];if(!1===n.intraword&&d&&!a.test(d))continue;const f=t;let u=f,g=Re(r,c,o),p=u;for(;g<0&&(p=p.getPreviousSibling())&&!e.$isLineBreakNode(p);)if(e.$isTextNode(p)){if(p.hasFormat("code"))continue;const e=p.getTextContent();u=p,g=Re(e,e.length,o)}if(g<0)continue;if(u===f&&g+l===c)continue;const h=u.getTextContent();if(g>0&&h[g-1]===s)continue;const x=h[g-1];if(!1===n.intraword&&x&&!a.test(x))continue;if(!n.format.includes("code")&&Le(u,g))continue;const m=f.getTextContent(),$=m.slice(0,c)+m.slice(i+1);f.setTextContent($);const N=u===f?$:h;u.setTextContent(N.slice(0,g)+N.slice(g+l));const T=e.$getSelection(),C=e.$createRangeSelection();e.$setSelection(C);const E=i-l*(u===f?2:1)+1;C.anchor.set(u.__key,g,"text"),C.focus.set(f.__key,E,"text");for(const e of n.format)C.hasFormat(e)||C.formatText(e);C.anchor.set(C.focus.key,C.focus.offset,C.focus.type);for(const e of n.format)C.hasFormat(e)&&C.toggleFormat(e);return e.$isRangeSelection(T)&&(C.format=T.format),!0}return!1}(n,o,s)));return e.mergeRegister(t.registerUpdateListener(({tags:o,dirtyLeaves:r,editorState:i,prevEditorState:s})=>{if(o.has(e.COLLABORATION_TAG)||o.has(e.HISTORIC_TAG))return;if(t.isComposing())return;const l=o.has(e.COMPOSITION_END_TAG),c=i.read(e.$getSelection),a=s.read(e.$getSelection);if(!e.$isRangeSelection(a)||!e.$isRangeSelection(c)||!c.isCollapsed()||c.is(a)&&!l)return;const d=c.anchor.key,g=c.anchor.offset,p=i._nodeMap.get(d);if(e.$isTextNode(p)&&r.has(d)&&(l||1===g||!(g>a.anchor.offset+1))){if(l){const e=i.read(()=>p.getTextContent())[g-1];if(!f.has(e))return}t.update(()=>{if(!xe(p))return;const t=p.getParent();null===t||n.$isCodeNode(t)||u(t,p,c.anchor.offset)&&e.$addUpdateTag(e.HISTORY_PUSH_TAG)})}}),t.registerCommand(e.KEY_ENTER_COMMAND,t=>{if(null!==t&&t.shiftKey)return!1;const o=e.$getSelection();if(!e.$isRangeSelection(o)||!o.isCollapsed())return!1;const s=o.anchor.offset,l=o.anchor.getNode();if(!e.$isTextNode(l)||!xe(l))return!1;const c=l.getParent();if(null===c||n.$isCodeNode(c))return!1;return s===l.getTextContent().length&&(!(!Ie(c,l,s,r.multilineElement,!0)&&!Se(c,l,s,i,!0))&&(null!==t&&t.preventDefault(),!0))},e.COMMAND_PRIORITY_LOW))};