@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.
- package/{LexicalMarkdown.dev.js → dist/LexicalMarkdown.dev.js} +1 -1
- package/{LexicalMarkdown.dev.mjs → dist/LexicalMarkdown.dev.mjs} +1 -1
- package/dist/LexicalMarkdown.prod.js +9 -0
- package/dist/LexicalMarkdown.prod.mjs +9 -0
- package/package.json +37 -22
- package/src/MarkdownExport.ts +627 -0
- package/src/MarkdownImport.ts +363 -0
- package/src/MarkdownShortcuts.ts +677 -0
- package/src/MarkdownTransformers.ts +962 -0
- package/src/importTextFormatTransformer.ts +389 -0
- package/src/importTextMatchTransformer.ts +110 -0
- package/src/importTextTransformers.ts +141 -0
- package/src/index.ts +138 -0
- package/src/utils.ts +472 -0
- package/LexicalMarkdown.prod.js +0 -9
- package/LexicalMarkdown.prod.mjs +0 -9
- /package/{LexicalMarkdown.js → dist/LexicalMarkdown.js} +0 -0
- /package/{LexicalMarkdown.js.flow → dist/LexicalMarkdown.js.flow} +0 -0
- /package/{LexicalMarkdown.mjs → dist/LexicalMarkdown.mjs} +0 -0
- /package/{LexicalMarkdown.node.mjs → dist/LexicalMarkdown.node.mjs} +0 -0
- /package/{MarkdownExport.d.ts → dist/MarkdownExport.d.ts} +0 -0
- /package/{MarkdownImport.d.ts → dist/MarkdownImport.d.ts} +0 -0
- /package/{MarkdownShortcuts.d.ts → dist/MarkdownShortcuts.d.ts} +0 -0
- /package/{MarkdownTransformers.d.ts → dist/MarkdownTransformers.d.ts} +0 -0
- /package/{importTextFormatTransformer.d.ts → dist/importTextFormatTransformer.d.ts} +0 -0
- /package/{importTextMatchTransformer.d.ts → dist/importTextMatchTransformer.d.ts} +0 -0
- /package/{importTextTransformers.d.ts → dist/importTextTransformers.d.ts} +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /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
|
+
}
|
package/LexicalMarkdown.prod.js
DELETED
|
@@ -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))};
|