@lexical/markdown 0.14.5 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LexicalMarkdown.dev.js +47 -36
- package/LexicalMarkdown.dev.mjs +48 -37
- package/LexicalMarkdown.js +2 -0
- package/LexicalMarkdown.js.flow +4 -0
- package/LexicalMarkdown.mjs +2 -0
- package/LexicalMarkdown.node.mjs +2 -0
- package/LexicalMarkdown.prod.js +32 -29
- package/LexicalMarkdown.prod.mjs +3 -1
- package/MarkdownExport.d.ts +1 -1
- package/MarkdownImport.d.ts +1 -1
- package/index.d.ts +2 -2
- package/package.json +8 -8
- package/utils.d.ts +2 -1
package/LexicalMarkdown.dev.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
8
|
+
|
|
7
9
|
'use strict';
|
|
8
10
|
|
|
9
11
|
var lexical = require('lexical');
|
|
@@ -20,6 +22,7 @@ var link = require('@lexical/link');
|
|
|
20
22
|
* LICENSE file in the root directory of this source tree.
|
|
21
23
|
*
|
|
22
24
|
*/
|
|
25
|
+
|
|
23
26
|
function indexBy(list, callback) {
|
|
24
27
|
const index = {};
|
|
25
28
|
for (const item of list) {
|
|
@@ -41,6 +44,14 @@ function transformersByType(transformers) {
|
|
|
41
44
|
};
|
|
42
45
|
}
|
|
43
46
|
const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/;
|
|
47
|
+
const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/;
|
|
48
|
+
function isEmptyParagraph(node) {
|
|
49
|
+
if (!lexical.$isParagraphNode(node)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
const firstChild = node.getFirstChild();
|
|
53
|
+
return firstChild == null || node.getChildrenSize() === 1 && lexical.$isTextNode(firstChild) && MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent());
|
|
54
|
+
}
|
|
44
55
|
|
|
45
56
|
/**
|
|
46
57
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -49,8 +60,10 @@ const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/;
|
|
|
49
60
|
* LICENSE file in the root directory of this source tree.
|
|
50
61
|
*
|
|
51
62
|
*/
|
|
52
|
-
|
|
63
|
+
|
|
64
|
+
function createMarkdownExport(transformers, shouldPreserveNewLines = false) {
|
|
53
65
|
const byType = transformersByType(transformers);
|
|
66
|
+
const isNewlineDelimited = !shouldPreserveNewLines;
|
|
54
67
|
|
|
55
68
|
// Export only uses text formats that are responsible for single format
|
|
56
69
|
// e.g. it will filter out *** (bold, italic) and instead use separate ** and *
|
|
@@ -58,13 +71,18 @@ function createMarkdownExport(transformers) {
|
|
|
58
71
|
return node => {
|
|
59
72
|
const output = [];
|
|
60
73
|
const children = (node || lexical.$getRoot()).getChildren();
|
|
61
|
-
for (
|
|
74
|
+
for (let i = 0; i < children.length; i++) {
|
|
75
|
+
const child = children[i];
|
|
62
76
|
const result = exportTopLevelElements(child, byType.element, textFormatTransformers, byType.textMatch);
|
|
63
77
|
if (result != null) {
|
|
64
|
-
output.push(
|
|
78
|
+
output.push(
|
|
79
|
+
// seperate consecutive group of texts with a line break: eg. ["hello", "world"] -> ["hello", "/nworld"]
|
|
80
|
+
isNewlineDelimited && i > 0 && !isEmptyParagraph(child) && !isEmptyParagraph(children[i - 1]) ? '\n'.concat(result) : result);
|
|
65
81
|
}
|
|
66
82
|
}
|
|
67
|
-
|
|
83
|
+
// Ensure consecutive groups of texts are atleast \n\n apart while each empty paragraph render as a newline.
|
|
84
|
+
// Eg. ["hello", "", "", "hi", "\nworld"] -> "hello\n\n\nhi\n\nworld"
|
|
85
|
+
return output.join('\n');
|
|
68
86
|
};
|
|
69
87
|
}
|
|
70
88
|
function exportTopLevelElements(node, elementTransformers, textTransformersIndex, textMatchTransformers) {
|
|
@@ -98,6 +116,7 @@ function exportChildren(node, textTransformersIndex, textMatchTransformers) {
|
|
|
98
116
|
} else if (lexical.$isTextNode(child)) {
|
|
99
117
|
output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex));
|
|
100
118
|
} else if (lexical.$isElementNode(child)) {
|
|
119
|
+
// empty paragraph returns ""
|
|
101
120
|
output.push(exportChildren(child, textTransformersIndex, textMatchTransformers));
|
|
102
121
|
} else if (lexical.$isDecoratorNode(child)) {
|
|
103
122
|
output.push(child.getTextContent());
|
|
@@ -189,20 +208,15 @@ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !==
|
|
|
189
208
|
* LICENSE file in the root directory of this source tree.
|
|
190
209
|
*
|
|
191
210
|
*/
|
|
211
|
+
|
|
192
212
|
const documentMode = CAN_USE_DOM && 'documentMode' in document ? document.documentMode : null;
|
|
193
|
-
CAN_USE_DOM && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
194
|
-
CAN_USE_DOM && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
|
|
195
213
|
CAN_USE_DOM && 'InputEvent' in window && !documentMode ? 'getTargetRanges' in new window.InputEvent('input') : false;
|
|
196
214
|
const IS_SAFARI = CAN_USE_DOM && /Version\/[\d.]+.*Safari/.test(navigator.userAgent);
|
|
197
215
|
const IS_IOS = CAN_USE_DOM && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
|
198
|
-
const IS_ANDROID = CAN_USE_DOM && /Android/.test(navigator.userAgent);
|
|
199
216
|
|
|
200
217
|
// Keep these in case we need to use them in the future.
|
|
201
218
|
// export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
|
|
202
219
|
const IS_CHROME = CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent);
|
|
203
|
-
// export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
|
|
204
|
-
|
|
205
|
-
CAN_USE_DOM && IS_ANDROID && IS_CHROME;
|
|
206
220
|
const IS_APPLE_WEBKIT = CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.userAgent) && !IS_CHROME;
|
|
207
221
|
|
|
208
222
|
/**
|
|
@@ -212,9 +226,9 @@ const IS_APPLE_WEBKIT = CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.user
|
|
|
212
226
|
* LICENSE file in the root directory of this source tree.
|
|
213
227
|
*
|
|
214
228
|
*/
|
|
215
|
-
|
|
216
|
-
const CODE_BLOCK_REG_EXP =
|
|
217
|
-
function createMarkdownImport(transformers) {
|
|
229
|
+
|
|
230
|
+
const CODE_BLOCK_REG_EXP = /^[ \t]*```(\w{1,10})?\s?$/;
|
|
231
|
+
function createMarkdownImport(transformers, shouldPreserveNewLines = false) {
|
|
218
232
|
const byType = transformersByType(transformers);
|
|
219
233
|
const textFormatTransformersIndex = createTextFormatTransformersIndex(byType.textFormat);
|
|
220
234
|
return (markdownString, node) => {
|
|
@@ -228,19 +242,20 @@ function createMarkdownImport(transformers) {
|
|
|
228
242
|
// is ignored for further processing
|
|
229
243
|
// TODO:
|
|
230
244
|
// Abstract it to be dynamic as other transformers (add multiline match option)
|
|
231
|
-
const [codeBlockNode, shiftedIndex] = importCodeBlock(lines, i, root);
|
|
245
|
+
const [codeBlockNode, shiftedIndex] = $importCodeBlock(lines, i, root);
|
|
232
246
|
if (codeBlockNode != null) {
|
|
233
247
|
i = shiftedIndex;
|
|
234
248
|
continue;
|
|
235
249
|
}
|
|
236
|
-
importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch);
|
|
250
|
+
$importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch);
|
|
237
251
|
}
|
|
238
252
|
|
|
239
|
-
//
|
|
240
|
-
// allow empty lines and uses them as delimiter
|
|
253
|
+
// By default, removing empty paragraphs as md does not really
|
|
254
|
+
// allow empty lines and uses them as delimiter.
|
|
255
|
+
// If you need empty lines set shouldPreserveNewLines = true.
|
|
241
256
|
const children = root.getChildren();
|
|
242
257
|
for (const child of children) {
|
|
243
|
-
if (isEmptyParagraph(child) && root.getChildrenSize() > 1) {
|
|
258
|
+
if (!shouldPreserveNewLines && isEmptyParagraph(child) && root.getChildrenSize() > 1) {
|
|
244
259
|
child.remove();
|
|
245
260
|
}
|
|
246
261
|
}
|
|
@@ -249,14 +264,7 @@ function createMarkdownImport(transformers) {
|
|
|
249
264
|
}
|
|
250
265
|
};
|
|
251
266
|
}
|
|
252
|
-
function
|
|
253
|
-
if (!lexical.$isParagraphNode(node)) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
const firstChild = node.getFirstChild();
|
|
257
|
-
return firstChild == null || node.getChildrenSize() === 1 && lexical.$isTextNode(firstChild) && MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent());
|
|
258
|
-
}
|
|
259
|
-
function importBlocks(lineText, rootNode, elementTransformers, textFormatTransformersIndex, textMatchTransformers) {
|
|
267
|
+
function $importBlocks(lineText, rootNode, elementTransformers, textFormatTransformersIndex, textMatchTransformers) {
|
|
260
268
|
const lineTextTrimmed = lineText.trim();
|
|
261
269
|
const textNode = lexical.$createTextNode(lineTextTrimmed);
|
|
262
270
|
const elementNode = lexical.$createParagraphNode();
|
|
@@ -297,7 +305,7 @@ function importBlocks(lineText, rootNode, elementTransformers, textFormatTransfo
|
|
|
297
305
|
}
|
|
298
306
|
}
|
|
299
307
|
}
|
|
300
|
-
function importCodeBlock(lines, startLineIndex, rootNode) {
|
|
308
|
+
function $importCodeBlock(lines, startLineIndex, rootNode) {
|
|
301
309
|
const openMatch = lines[startLineIndex].match(CODE_BLOCK_REG_EXP);
|
|
302
310
|
if (openMatch) {
|
|
303
311
|
let endLineIndex = startLineIndex;
|
|
@@ -466,6 +474,7 @@ function createTextFormatTransformersIndex(textTransformers) {
|
|
|
466
474
|
* LICENSE file in the root directory of this source tree.
|
|
467
475
|
*
|
|
468
476
|
*/
|
|
477
|
+
|
|
469
478
|
function runElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers) {
|
|
470
479
|
const grandParentNode = parentNode.getParent();
|
|
471
480
|
if (!lexical.$isRootOrShadowRoot(grandParentNode) || parentNode.getFirstChild() !== anchorNode) {
|
|
@@ -530,7 +539,7 @@ function runTextMatchTransformers(anchorNode, anchorOffset, transformersByTrigge
|
|
|
530
539
|
}
|
|
531
540
|
return false;
|
|
532
541
|
}
|
|
533
|
-
function runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformers) {
|
|
542
|
+
function $runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformers) {
|
|
534
543
|
const textContent = anchorNode.getTextContent();
|
|
535
544
|
const closeTagEndIndex = anchorOffset - 1;
|
|
536
545
|
const closeChar = textContent[closeTagEndIndex];
|
|
@@ -682,14 +691,14 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
|
|
|
682
691
|
}
|
|
683
692
|
}
|
|
684
693
|
}
|
|
685
|
-
const transform = (parentNode, anchorNode, anchorOffset) => {
|
|
694
|
+
const $transform = (parentNode, anchorNode, anchorOffset) => {
|
|
686
695
|
if (runElementTransformers(parentNode, anchorNode, anchorOffset, byType.element)) {
|
|
687
696
|
return;
|
|
688
697
|
}
|
|
689
698
|
if (runTextMatchTransformers(anchorNode, anchorOffset, textMatchTransformersIndex)) {
|
|
690
699
|
return;
|
|
691
700
|
}
|
|
692
|
-
runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformersIndex);
|
|
701
|
+
$runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformersIndex);
|
|
693
702
|
};
|
|
694
703
|
return editor.registerUpdateListener(({
|
|
695
704
|
tags,
|
|
@@ -726,7 +735,7 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
|
|
|
726
735
|
if (parentNode === null || code.$isCodeNode(parentNode)) {
|
|
727
736
|
return;
|
|
728
737
|
}
|
|
729
|
-
transform(parentNode, anchorNode, selection.anchor.offset);
|
|
738
|
+
$transform(parentNode, anchorNode, selection.anchor.offset);
|
|
730
739
|
});
|
|
731
740
|
});
|
|
732
741
|
}
|
|
@@ -738,6 +747,7 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
|
|
|
738
747
|
* LICENSE file in the root directory of this source tree.
|
|
739
748
|
*
|
|
740
749
|
*/
|
|
750
|
+
|
|
741
751
|
const createBlockNode = createNode => {
|
|
742
752
|
return (parentNode, children, match) => {
|
|
743
753
|
const node = createNode(match);
|
|
@@ -870,7 +880,7 @@ const CODE = {
|
|
|
870
880
|
const textContent = node.getTextContent();
|
|
871
881
|
return '```' + (node.getLanguage() || '') + (textContent ? '\n' + textContent : '') + '\n' + '```';
|
|
872
882
|
},
|
|
873
|
-
regExp:
|
|
883
|
+
regExp: /^[ \t]*```(\w{1,10})?\s/,
|
|
874
884
|
replace: createBlockNode(match => {
|
|
875
885
|
return code.$createCodeNode(match ? match[1] : undefined);
|
|
876
886
|
}),
|
|
@@ -996,6 +1006,7 @@ const LINK = {
|
|
|
996
1006
|
* LICENSE file in the root directory of this source tree.
|
|
997
1007
|
*
|
|
998
1008
|
*/
|
|
1009
|
+
|
|
999
1010
|
const ELEMENT_TRANSFORMERS = [HEADING, QUOTE, CODE, UNORDERED_LIST, ORDERED_LIST];
|
|
1000
1011
|
|
|
1001
1012
|
// Order of text format transformers matters:
|
|
@@ -1005,12 +1016,12 @@ const ELEMENT_TRANSFORMERS = [HEADING, QUOTE, CODE, UNORDERED_LIST, ORDERED_LIST
|
|
|
1005
1016
|
const TEXT_FORMAT_TRANSFORMERS = [INLINE_CODE, BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, HIGHLIGHT, ITALIC_STAR, ITALIC_UNDERSCORE, STRIKETHROUGH];
|
|
1006
1017
|
const TEXT_MATCH_TRANSFORMERS = [LINK];
|
|
1007
1018
|
const TRANSFORMERS = [...ELEMENT_TRANSFORMERS, ...TEXT_FORMAT_TRANSFORMERS, ...TEXT_MATCH_TRANSFORMERS];
|
|
1008
|
-
function $convertFromMarkdownString(markdown, transformers = TRANSFORMERS, node) {
|
|
1009
|
-
const importMarkdown = createMarkdownImport(transformers);
|
|
1019
|
+
function $convertFromMarkdownString(markdown, transformers = TRANSFORMERS, node, shouldPreserveNewLines = false) {
|
|
1020
|
+
const importMarkdown = createMarkdownImport(transformers, shouldPreserveNewLines);
|
|
1010
1021
|
return importMarkdown(markdown, node);
|
|
1011
1022
|
}
|
|
1012
|
-
function $convertToMarkdownString(transformers = TRANSFORMERS, node) {
|
|
1013
|
-
const exportMarkdown = createMarkdownExport(transformers);
|
|
1023
|
+
function $convertToMarkdownString(transformers = TRANSFORMERS, node, shouldPreserveNewLines = false) {
|
|
1024
|
+
const exportMarkdown = createMarkdownExport(transformers, shouldPreserveNewLines);
|
|
1014
1025
|
return exportMarkdown(node);
|
|
1015
1026
|
}
|
|
1016
1027
|
|
package/LexicalMarkdown.dev.mjs
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
import { $isParagraphNode, $isTextNode, $getRoot, $isElementNode, $isDecoratorNode, $isLineBreakNode, $getSelection, $createTextNode, $createParagraphNode, $createLineBreakNode, $isRangeSelection, $isRootOrShadowRoot, $createRangeSelection, $setSelection } from 'lexical';
|
|
8
10
|
import { $createCodeNode, $isCodeNode, CodeNode } from '@lexical/code';
|
|
9
11
|
import { $isListNode, $isListItemNode, ListNode, ListItemNode, $createListItemNode, $createListNode } from '@lexical/list';
|
|
10
12
|
import { $isQuoteNode, HeadingNode, $isHeadingNode, QuoteNode, $createQuoteNode, $createHeadingNode } from '@lexical/rich-text';
|
|
@@ -18,6 +20,7 @@ import { LinkNode, $isLinkNode, $createLinkNode } from '@lexical/link';
|
|
|
18
20
|
* LICENSE file in the root directory of this source tree.
|
|
19
21
|
*
|
|
20
22
|
*/
|
|
23
|
+
|
|
21
24
|
function indexBy(list, callback) {
|
|
22
25
|
const index = {};
|
|
23
26
|
for (const item of list) {
|
|
@@ -39,6 +42,14 @@ function transformersByType(transformers) {
|
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
44
|
const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/;
|
|
45
|
+
const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/;
|
|
46
|
+
function isEmptyParagraph(node) {
|
|
47
|
+
if (!$isParagraphNode(node)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const firstChild = node.getFirstChild();
|
|
51
|
+
return firstChild == null || node.getChildrenSize() === 1 && $isTextNode(firstChild) && MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent());
|
|
52
|
+
}
|
|
42
53
|
|
|
43
54
|
/**
|
|
44
55
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -47,8 +58,10 @@ const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/;
|
|
|
47
58
|
* LICENSE file in the root directory of this source tree.
|
|
48
59
|
*
|
|
49
60
|
*/
|
|
50
|
-
|
|
61
|
+
|
|
62
|
+
function createMarkdownExport(transformers, shouldPreserveNewLines = false) {
|
|
51
63
|
const byType = transformersByType(transformers);
|
|
64
|
+
const isNewlineDelimited = !shouldPreserveNewLines;
|
|
52
65
|
|
|
53
66
|
// Export only uses text formats that are responsible for single format
|
|
54
67
|
// e.g. it will filter out *** (bold, italic) and instead use separate ** and *
|
|
@@ -56,13 +69,18 @@ function createMarkdownExport(transformers) {
|
|
|
56
69
|
return node => {
|
|
57
70
|
const output = [];
|
|
58
71
|
const children = (node || $getRoot()).getChildren();
|
|
59
|
-
for (
|
|
72
|
+
for (let i = 0; i < children.length; i++) {
|
|
73
|
+
const child = children[i];
|
|
60
74
|
const result = exportTopLevelElements(child, byType.element, textFormatTransformers, byType.textMatch);
|
|
61
75
|
if (result != null) {
|
|
62
|
-
output.push(
|
|
76
|
+
output.push(
|
|
77
|
+
// seperate consecutive group of texts with a line break: eg. ["hello", "world"] -> ["hello", "/nworld"]
|
|
78
|
+
isNewlineDelimited && i > 0 && !isEmptyParagraph(child) && !isEmptyParagraph(children[i - 1]) ? '\n'.concat(result) : result);
|
|
63
79
|
}
|
|
64
80
|
}
|
|
65
|
-
|
|
81
|
+
// Ensure consecutive groups of texts are atleast \n\n apart while each empty paragraph render as a newline.
|
|
82
|
+
// Eg. ["hello", "", "", "hi", "\nworld"] -> "hello\n\n\nhi\n\nworld"
|
|
83
|
+
return output.join('\n');
|
|
66
84
|
};
|
|
67
85
|
}
|
|
68
86
|
function exportTopLevelElements(node, elementTransformers, textTransformersIndex, textMatchTransformers) {
|
|
@@ -96,6 +114,7 @@ function exportChildren(node, textTransformersIndex, textMatchTransformers) {
|
|
|
96
114
|
} else if ($isTextNode(child)) {
|
|
97
115
|
output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex));
|
|
98
116
|
} else if ($isElementNode(child)) {
|
|
117
|
+
// empty paragraph returns ""
|
|
99
118
|
output.push(exportChildren(child, textTransformersIndex, textMatchTransformers));
|
|
100
119
|
} else if ($isDecoratorNode(child)) {
|
|
101
120
|
output.push(child.getTextContent());
|
|
@@ -187,20 +206,15 @@ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !==
|
|
|
187
206
|
* LICENSE file in the root directory of this source tree.
|
|
188
207
|
*
|
|
189
208
|
*/
|
|
209
|
+
|
|
190
210
|
const documentMode = CAN_USE_DOM && 'documentMode' in document ? document.documentMode : null;
|
|
191
|
-
CAN_USE_DOM && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
192
|
-
CAN_USE_DOM && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
|
|
193
211
|
CAN_USE_DOM && 'InputEvent' in window && !documentMode ? 'getTargetRanges' in new window.InputEvent('input') : false;
|
|
194
212
|
const IS_SAFARI = CAN_USE_DOM && /Version\/[\d.]+.*Safari/.test(navigator.userAgent);
|
|
195
213
|
const IS_IOS = CAN_USE_DOM && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
|
196
|
-
const IS_ANDROID = CAN_USE_DOM && /Android/.test(navigator.userAgent);
|
|
197
214
|
|
|
198
215
|
// Keep these in case we need to use them in the future.
|
|
199
216
|
// export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
|
|
200
217
|
const IS_CHROME = CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent);
|
|
201
|
-
// export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
|
|
202
|
-
|
|
203
|
-
CAN_USE_DOM && IS_ANDROID && IS_CHROME;
|
|
204
218
|
const IS_APPLE_WEBKIT = CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.userAgent) && !IS_CHROME;
|
|
205
219
|
|
|
206
220
|
/**
|
|
@@ -210,9 +224,9 @@ const IS_APPLE_WEBKIT = CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.user
|
|
|
210
224
|
* LICENSE file in the root directory of this source tree.
|
|
211
225
|
*
|
|
212
226
|
*/
|
|
213
|
-
|
|
214
|
-
const CODE_BLOCK_REG_EXP =
|
|
215
|
-
function createMarkdownImport(transformers) {
|
|
227
|
+
|
|
228
|
+
const CODE_BLOCK_REG_EXP = /^[ \t]*```(\w{1,10})?\s?$/;
|
|
229
|
+
function createMarkdownImport(transformers, shouldPreserveNewLines = false) {
|
|
216
230
|
const byType = transformersByType(transformers);
|
|
217
231
|
const textFormatTransformersIndex = createTextFormatTransformersIndex(byType.textFormat);
|
|
218
232
|
return (markdownString, node) => {
|
|
@@ -226,19 +240,20 @@ function createMarkdownImport(transformers) {
|
|
|
226
240
|
// is ignored for further processing
|
|
227
241
|
// TODO:
|
|
228
242
|
// Abstract it to be dynamic as other transformers (add multiline match option)
|
|
229
|
-
const [codeBlockNode, shiftedIndex] = importCodeBlock(lines, i, root);
|
|
243
|
+
const [codeBlockNode, shiftedIndex] = $importCodeBlock(lines, i, root);
|
|
230
244
|
if (codeBlockNode != null) {
|
|
231
245
|
i = shiftedIndex;
|
|
232
246
|
continue;
|
|
233
247
|
}
|
|
234
|
-
importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch);
|
|
248
|
+
$importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch);
|
|
235
249
|
}
|
|
236
250
|
|
|
237
|
-
//
|
|
238
|
-
// allow empty lines and uses them as delimiter
|
|
251
|
+
// By default, removing empty paragraphs as md does not really
|
|
252
|
+
// allow empty lines and uses them as delimiter.
|
|
253
|
+
// If you need empty lines set shouldPreserveNewLines = true.
|
|
239
254
|
const children = root.getChildren();
|
|
240
255
|
for (const child of children) {
|
|
241
|
-
if (isEmptyParagraph(child) && root.getChildrenSize() > 1) {
|
|
256
|
+
if (!shouldPreserveNewLines && isEmptyParagraph(child) && root.getChildrenSize() > 1) {
|
|
242
257
|
child.remove();
|
|
243
258
|
}
|
|
244
259
|
}
|
|
@@ -247,14 +262,7 @@ function createMarkdownImport(transformers) {
|
|
|
247
262
|
}
|
|
248
263
|
};
|
|
249
264
|
}
|
|
250
|
-
function
|
|
251
|
-
if (!$isParagraphNode(node)) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
const firstChild = node.getFirstChild();
|
|
255
|
-
return firstChild == null || node.getChildrenSize() === 1 && $isTextNode(firstChild) && MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent());
|
|
256
|
-
}
|
|
257
|
-
function importBlocks(lineText, rootNode, elementTransformers, textFormatTransformersIndex, textMatchTransformers) {
|
|
265
|
+
function $importBlocks(lineText, rootNode, elementTransformers, textFormatTransformersIndex, textMatchTransformers) {
|
|
258
266
|
const lineTextTrimmed = lineText.trim();
|
|
259
267
|
const textNode = $createTextNode(lineTextTrimmed);
|
|
260
268
|
const elementNode = $createParagraphNode();
|
|
@@ -295,7 +303,7 @@ function importBlocks(lineText, rootNode, elementTransformers, textFormatTransfo
|
|
|
295
303
|
}
|
|
296
304
|
}
|
|
297
305
|
}
|
|
298
|
-
function importCodeBlock(lines, startLineIndex, rootNode) {
|
|
306
|
+
function $importCodeBlock(lines, startLineIndex, rootNode) {
|
|
299
307
|
const openMatch = lines[startLineIndex].match(CODE_BLOCK_REG_EXP);
|
|
300
308
|
if (openMatch) {
|
|
301
309
|
let endLineIndex = startLineIndex;
|
|
@@ -464,6 +472,7 @@ function createTextFormatTransformersIndex(textTransformers) {
|
|
|
464
472
|
* LICENSE file in the root directory of this source tree.
|
|
465
473
|
*
|
|
466
474
|
*/
|
|
475
|
+
|
|
467
476
|
function runElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers) {
|
|
468
477
|
const grandParentNode = parentNode.getParent();
|
|
469
478
|
if (!$isRootOrShadowRoot(grandParentNode) || parentNode.getFirstChild() !== anchorNode) {
|
|
@@ -528,7 +537,7 @@ function runTextMatchTransformers(anchorNode, anchorOffset, transformersByTrigge
|
|
|
528
537
|
}
|
|
529
538
|
return false;
|
|
530
539
|
}
|
|
531
|
-
function runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformers) {
|
|
540
|
+
function $runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformers) {
|
|
532
541
|
const textContent = anchorNode.getTextContent();
|
|
533
542
|
const closeTagEndIndex = anchorOffset - 1;
|
|
534
543
|
const closeChar = textContent[closeTagEndIndex];
|
|
@@ -680,14 +689,14 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
|
|
|
680
689
|
}
|
|
681
690
|
}
|
|
682
691
|
}
|
|
683
|
-
const transform = (parentNode, anchorNode, anchorOffset) => {
|
|
692
|
+
const $transform = (parentNode, anchorNode, anchorOffset) => {
|
|
684
693
|
if (runElementTransformers(parentNode, anchorNode, anchorOffset, byType.element)) {
|
|
685
694
|
return;
|
|
686
695
|
}
|
|
687
696
|
if (runTextMatchTransformers(anchorNode, anchorOffset, textMatchTransformersIndex)) {
|
|
688
697
|
return;
|
|
689
698
|
}
|
|
690
|
-
runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformersIndex);
|
|
699
|
+
$runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransformersIndex);
|
|
691
700
|
};
|
|
692
701
|
return editor.registerUpdateListener(({
|
|
693
702
|
tags,
|
|
@@ -724,7 +733,7 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
|
|
|
724
733
|
if (parentNode === null || $isCodeNode(parentNode)) {
|
|
725
734
|
return;
|
|
726
735
|
}
|
|
727
|
-
transform(parentNode, anchorNode, selection.anchor.offset);
|
|
736
|
+
$transform(parentNode, anchorNode, selection.anchor.offset);
|
|
728
737
|
});
|
|
729
738
|
});
|
|
730
739
|
}
|
|
@@ -736,6 +745,7 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
|
|
|
736
745
|
* LICENSE file in the root directory of this source tree.
|
|
737
746
|
*
|
|
738
747
|
*/
|
|
748
|
+
|
|
739
749
|
const createBlockNode = createNode => {
|
|
740
750
|
return (parentNode, children, match) => {
|
|
741
751
|
const node = createNode(match);
|
|
@@ -868,7 +878,7 @@ const CODE = {
|
|
|
868
878
|
const textContent = node.getTextContent();
|
|
869
879
|
return '```' + (node.getLanguage() || '') + (textContent ? '\n' + textContent : '') + '\n' + '```';
|
|
870
880
|
},
|
|
871
|
-
regExp:
|
|
881
|
+
regExp: /^[ \t]*```(\w{1,10})?\s/,
|
|
872
882
|
replace: createBlockNode(match => {
|
|
873
883
|
return $createCodeNode(match ? match[1] : undefined);
|
|
874
884
|
}),
|
|
@@ -994,6 +1004,7 @@ const LINK = {
|
|
|
994
1004
|
* LICENSE file in the root directory of this source tree.
|
|
995
1005
|
*
|
|
996
1006
|
*/
|
|
1007
|
+
|
|
997
1008
|
const ELEMENT_TRANSFORMERS = [HEADING, QUOTE, CODE, UNORDERED_LIST, ORDERED_LIST];
|
|
998
1009
|
|
|
999
1010
|
// Order of text format transformers matters:
|
|
@@ -1003,12 +1014,12 @@ const ELEMENT_TRANSFORMERS = [HEADING, QUOTE, CODE, UNORDERED_LIST, ORDERED_LIST
|
|
|
1003
1014
|
const TEXT_FORMAT_TRANSFORMERS = [INLINE_CODE, BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, HIGHLIGHT, ITALIC_STAR, ITALIC_UNDERSCORE, STRIKETHROUGH];
|
|
1004
1015
|
const TEXT_MATCH_TRANSFORMERS = [LINK];
|
|
1005
1016
|
const TRANSFORMERS = [...ELEMENT_TRANSFORMERS, ...TEXT_FORMAT_TRANSFORMERS, ...TEXT_MATCH_TRANSFORMERS];
|
|
1006
|
-
function $convertFromMarkdownString(markdown, transformers = TRANSFORMERS, node) {
|
|
1007
|
-
const importMarkdown = createMarkdownImport(transformers);
|
|
1017
|
+
function $convertFromMarkdownString(markdown, transformers = TRANSFORMERS, node, shouldPreserveNewLines = false) {
|
|
1018
|
+
const importMarkdown = createMarkdownImport(transformers, shouldPreserveNewLines);
|
|
1008
1019
|
return importMarkdown(markdown, node);
|
|
1009
1020
|
}
|
|
1010
|
-
function $convertToMarkdownString(transformers = TRANSFORMERS, node) {
|
|
1011
|
-
const exportMarkdown = createMarkdownExport(transformers);
|
|
1021
|
+
function $convertToMarkdownString(transformers = TRANSFORMERS, node, shouldPreserveNewLines = false) {
|
|
1022
|
+
const exportMarkdown = createMarkdownExport(transformers, shouldPreserveNewLines);
|
|
1012
1023
|
return exportMarkdown(node);
|
|
1013
1024
|
}
|
|
1014
1025
|
|
package/LexicalMarkdown.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
8
|
+
|
|
7
9
|
'use strict'
|
|
8
10
|
const LexicalMarkdown = process.env.NODE_ENV === 'development' ? require('./LexicalMarkdown.dev.js') : require('./LexicalMarkdown.prod.js');
|
|
9
11
|
module.exports = LexicalMarkdown;
|
package/LexicalMarkdown.js.flow
CHANGED
|
@@ -68,12 +68,16 @@ declare export function registerMarkdownShortcuts(
|
|
|
68
68
|
declare export function $convertFromMarkdownString(
|
|
69
69
|
markdown: string,
|
|
70
70
|
transformers?: Array<Transformer>,
|
|
71
|
+
node?: ElementNode,
|
|
72
|
+
shouldPreserveNewLines?: boolean,
|
|
71
73
|
): void;
|
|
72
74
|
|
|
73
75
|
// TODO:
|
|
74
76
|
// transformers should be required argument, breaking change
|
|
75
77
|
declare export function $convertToMarkdownString(
|
|
76
78
|
transformers?: Array<Transformer>,
|
|
79
|
+
node?: ElementNode,
|
|
80
|
+
shouldPreserveNewLines?: boolean,
|
|
77
81
|
): string;
|
|
78
82
|
|
|
79
83
|
declare export var BOLD_ITALIC_STAR: TextFormatTransformer;
|
package/LexicalMarkdown.mjs
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
8
|
+
|
|
7
9
|
import * as modDev from './LexicalMarkdown.dev.mjs';
|
|
8
10
|
import * as modProd from './LexicalMarkdown.prod.mjs';
|
|
9
11
|
const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;
|
package/LexicalMarkdown.node.mjs
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
8
|
+
|
|
7
9
|
const mod = await (process.env.NODE_ENV === 'development' ? import('./LexicalMarkdown.dev.mjs') : import('./LexicalMarkdown.prod.mjs'));
|
|
8
10
|
export const $convertFromMarkdownString = mod.$convertFromMarkdownString;
|
|
9
11
|
export const $convertToMarkdownString = mod.$convertToMarkdownString;
|
package/LexicalMarkdown.prod.js
CHANGED
|
@@ -3,33 +3,36 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
function K(a
|
|
10
|
-
function
|
|
11
|
-
function
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
c.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
a
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
exports
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
8
|
+
|
|
9
|
+
'use strict';var m=require("lexical"),u=require("@lexical/code"),B=require("@lexical/list"),F=require("@lexical/rich-text"),aa=require("@lexical/utils"),G=require("@lexical/link");function H(a,b){let c={};for(let d of a)a=b(d),c[a]?c[a].push(d):c[a]=[d];return c}function I(a){a=H(a,b=>b.type);return{element:a.element||[],textFormat:a["text-format"]||[],textMatch:a["text-match"]||[]}}let J=/[!-/:-@[-`{-~\s]/,ba=/^\s{0,3}$/;
|
|
10
|
+
function K(a){if(!m.$isParagraphNode(a))return!1;let b=a.getFirstChild();return null==b||1===a.getChildrenSize()&&m.$isTextNode(b)&&ba.test(b.getTextContent())}function ca(a,b=!1){let c=I(a),d=!b,f=c.textFormat.filter(e=>1===e.format.length);return e=>{let k=[];e=(e||m.$getRoot()).getChildren();for(let g=0;g<e.length;g++){let p=e[g],v=da(p,c.element,f,c.textMatch);null!=v&&k.push(d&&0<g&&!K(p)&&!K(e[g-1])?"\n".concat(v):v)}return k.join("\n")}}
|
|
11
|
+
function da(a,b,c,d){for(let f of b)if(b=f.export(a,e=>L(e,c,d)),null!=b)return b;return m.$isElementNode(a)?L(a,c,d):m.$isDecoratorNode(a)?a.getTextContent():null}
|
|
12
|
+
function L(a,b,c){let d=[];a=a.getChildren();a:for(let f of a){for(let e of c)if(a=e.export(f,k=>L(k,b,c),(k,g)=>M(k,g,b)),null!=a){d.push(a);continue a}m.$isLineBreakNode(f)?d.push("\n"):m.$isTextNode(f)?d.push(M(f,f.getTextContent(),b)):m.$isElementNode(f)?d.push(L(f,b,c)):m.$isDecoratorNode(f)&&d.push(f.getTextContent())}return d.join("")}
|
|
13
|
+
function M(a,b,c){let d=b.trim(),f=d,e=new Set;for(let g of c){c=g.format[0];let p=g.tag;if(N(a,c)&&!e.has(c)){e.add(c);var k=O(a,!0);N(k,c)||(f=p+f);k=O(a,!1);N(k,c)||(f+=p)}}return b.replace(d,()=>f)}
|
|
14
|
+
function O(a,b){let c=b?a.getPreviousSibling():a.getNextSibling();c||(a=a.getParentOrThrow(),a.isInline()&&(c=b?a.getPreviousSibling():a.getNextSibling()));for(;c;){if(m.$isElementNode(c)){if(!c.isInline())break;a=b?c.getLastDescendant():c.getFirstDescendant();if(m.$isTextNode(a))return a;c=b?c.getPreviousSibling():c.getNextSibling()}if(m.$isTextNode(c))return c;if(!m.$isElementNode(c))break}return null}function N(a,b){return m.$isTextNode(a)&&a.hasFormat(b)}
|
|
15
|
+
let P="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement,ea=P&&"documentMode"in document?document.documentMode:null;P&&"InputEvent"in window&&!ea?"getTargetRanges"in new window.InputEvent("input"):!1;
|
|
16
|
+
let Q=P&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent),R=P&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,fa=P&&/^(?=.*Chrome).*/i.test(navigator.userAgent),S=P&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&!fa,T=/^[ \t]*```(\w{1,10})?\s?$/;
|
|
17
|
+
function ha(a,b=!1){let c=I(a),d=ia(c.textFormat);return(f,e)=>{f=f.split("\n");let k=f.length;e=e||m.$getRoot();e.clear();for(let h=0;h<k;h++){var g=f[h];a:{var p=f,v=h;var r=e;var q=p[v].match(T);if(q)for(var l=v,t=p.length;++l<t;)if(p[l].match(T)){q=u.$createCodeNode(q[1]);p=m.$createTextNode(p.slice(v+1,l).join("\n"));q.append(p);r.append(q);r=[q,l];break a}r=[null,v]}let [x,y]=r;if(null!=x)h=y;else{r=g;t=e;var n=c.element;l=d;p=c.textMatch;v=r.trim();q=m.$createTextNode(v);g=m.$createParagraphNode();
|
|
18
|
+
g.append(q);t.append(g);for(let {regExp:w,replace:z}of n)if(t=r.match(w)){q.setTextContent(r.slice(t[0].length));z(g,[q],t,!0);break}U(q,l,p);g.isAttached()&&0<v.length&&(r=g.getPreviousSibling(),m.$isParagraphNode(r)||F.$isQuoteNode(r)||B.$isListNode(r))&&(l=r,B.$isListNode(r)&&(r=r.getLastDescendant(),l=null==r?null:aa.$findMatchingParent(r,B.$isListItemNode)),null!=l&&0<l.getTextContentSize()&&(l.splice(l.getChildrenSize(),0,[m.$createLineBreakNode(),...g.getChildren()]),g.remove()))}}f=e.getChildren();
|
|
19
|
+
for(let h of f)!b&&K(h)&&1<e.getChildrenSize()&&h.remove();null!==m.$getSelection()&&e.selectEnd()}}function U(a,b,c){var d=a.getTextContent();let f=ja(d,b);if(f){var e,k;if(f[0]===d)var g=a;else{d=f.index||0;let p=d+f[0].length;0===d?[g,e]=a.splitText(p):[k,g,e]=a.splitText(d,p)}g.setTextContent(f[2]);if(a=b.transformersByTag[f[1]])for(let p of a.format)g.hasFormat(p)||g.toggleFormat(p);g.hasFormat("code")||U(g,b,c);k&&U(k,b,c);e&&U(e,b,c)}else V(a,c)}
|
|
20
|
+
function V(a,b){a:for(;a;){for(let c of b){let d=a.getTextContent().match(c.importRegExp);if(!d)continue;let f=d.index||0,e=f+d[0].length,k,g;0===f?[k,a]=a.splitText(e):[,k,g]=a.splitText(f,e);g&&V(g,b);c.replace(k,d);continue a}break}}
|
|
21
|
+
function ja(a,b){var c=a.match(b.openTagsRegExp);if(null==c)return null;for(let e of c){var d=e.replace(/^\s/,"");c=b.fullMatchRegExpByTag[d];if(null!=c&&(c=a.match(c),d=b.transformersByTag[d],null!=c&&null!=d)){if(!1!==d.intraword)return c;var {index:f=0}=c;d=a[f-1];f=a[f+c[0].length];if(!(d&&!J.test(d)||f&&!J.test(f)))return c}}return null}
|
|
22
|
+
function ia(a){let b={},c={},d=[];for(let f of a){({tag:a}=f);b[a]=f;let e=a.replace(/(\*|\^|\+)/g,"\\$1");d.push(e);c[a]=Q||R||S?new RegExp(`(${e})(?![${e}\\s])(.*?[^${e}\\s])${e}(?!${e})`):new RegExp(`(?<![\\\\${e}])(${e})((\\\\${e})?.*?[^${e}\\s](\\\\${e})?)((?<!\\\\)|(?<=\\\\\\\\))(${e})(?![\\\\${e}])`)}return{fullMatchRegExpByTag:c,openTagsRegExp:new RegExp((Q||R||S?"":"(?<![\\\\])")+"("+d.join("|")+")","g"),transformersByTag:b}}var ka;
|
|
23
|
+
function W(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}ka=W&&W.__esModule&&Object.prototype.hasOwnProperty.call(W,"default")?W["default"]:W;
|
|
24
|
+
function la(a,b,c){let d=c.length;for(;b>=d;b--){let f=b-d;if(ma(a,f,c,0,d)&&" "!==a[f+d])return f}return-1}function ma(a,b,c,d,f){for(let e=0;e<f;e++)if(a[b+e]!==c[d+e])return!1;return!0}
|
|
25
|
+
let na=a=>(b,c,d)=>{d=a(d);d.append(...c);b.replace(d);d.select(0,0)},X=a=>(b,c,d)=>{var f=b.getPreviousSibling(),e=b.getNextSibling();const k=B.$createListItemNode("check"===a?"x"===d[3]:void 0);B.$isListNode(e)&&e.getListType()===a?(f=e.getFirstChild(),null!==f?f.insertBefore(k):e.append(k),b.remove()):B.$isListNode(f)&&f.getListType()===a?(f.append(k),b.remove()):(e=B.$createListNode(a,"number"===a?Number(d[2]):void 0),e.append(k),b.replace(e));k.append(...c);k.select(0,0);c=d[1];b=c.match(/\t/g);
|
|
26
|
+
c=c.match(/ /g);d=0;b&&(d+=b.length);c&&(d+=Math.floor(c.length/4));(b=d)&&k.setIndent(b)},Y=(a,b,c)=>{const d=[];var f=a.getChildren();let e=0;for(const g of f)if(B.$isListItemNode(g)){if(1===g.getChildrenSize()&&(f=g.getFirstChild(),B.$isListNode(f))){d.push(Y(f,b,c+1));continue}f=" ".repeat(4*c);var k=a.getListType();k="number"===k?`${a.getStart()+e}. `:"check"===k?`- [${g.getChecked()?"x":" "}] `:"- ";d.push(f+k+b(g));e++}return d.join("\n")},oa={dependencies:[F.HeadingNode],export:(a,b)=>{if(!F.$isHeadingNode(a))return null;
|
|
27
|
+
const c=Number(a.getTag().slice(1));return"#".repeat(c)+" "+b(a)},regExp:/^(#{1,6})\s/,replace:na(a=>F.$createHeadingNode("h"+a[1].length)),type:"element"},pa={dependencies:[F.QuoteNode],export:(a,b)=>{if(!F.$isQuoteNode(a))return null;a=b(a).split("\n");b=[];for(const c of a)b.push("> "+c);return b.join("\n")},regExp:/^>\s/,replace:(a,b,c,d)=>{if(d&&(c=a.getPreviousSibling(),F.$isQuoteNode(c))){c.splice(c.getChildrenSize(),0,[m.$createLineBreakNode(),...b]);c.select(0,0);a.remove();return}c=F.$createQuoteNode();
|
|
28
|
+
c.append(...b);a.replace(c);c.select(0,0)},type:"element"},qa={dependencies:[u.CodeNode],export:a=>{if(!u.$isCodeNode(a))return null;const b=a.getTextContent();return"```"+(a.getLanguage()||"")+(b?"\n"+b:"")+"\n```"},regExp:/^[ \t]*```(\w{1,10})?\s/,replace:na(a=>u.$createCodeNode(a?a[1]:void 0)),type:"element"},ra={dependencies:[B.ListNode,B.ListItemNode],export:(a,b)=>B.$isListNode(a)?Y(a,b,0):null,regExp:/^(\s*)[-*+]\s/,replace:X("bullet"),type:"element"},sa={dependencies:[B.ListNode,B.ListItemNode],
|
|
29
|
+
export:(a,b)=>B.$isListNode(a)?Y(a,b,0):null,regExp:/^(\s*)(?:-\s)?\s?(\[(\s|x)?\])\s/i,replace:X("check"),type:"element"},ta={dependencies:[B.ListNode,B.ListItemNode],export:(a,b)=>B.$isListNode(a)?Y(a,b,0):null,regExp:/^(\s*)(\d{1,})\.\s/,replace:X("number"),type:"element"},ua={format:["code"],tag:"`",type:"text-format"},va={format:["highlight"],tag:"==",type:"text-format"},wa={format:["bold","italic"],tag:"***",type:"text-format"},ya={format:["bold","italic"],intraword:!1,tag:"___",type:"text-format"},
|
|
30
|
+
za={format:["bold"],tag:"**",type:"text-format"},Aa={format:["bold"],intraword:!1,tag:"__",type:"text-format"},Ba={format:["strikethrough"],tag:"~~",type:"text-format"},Ca={format:["italic"],tag:"*",type:"text-format"},Da={format:["italic"],intraword:!1,tag:"_",type:"text-format"},Ea={dependencies:[G.LinkNode],export:(a,b,c)=>{if(!G.$isLinkNode(a))return null;b=(b=a.getTitle())?`[${a.getTextContent()}](${a.getURL()} "${b}")`:`[${a.getTextContent()}](${a.getURL()})`;const d=a.getFirstChild();return 1===
|
|
31
|
+
a.getChildrenSize()&&m.$isTextNode(d)?c(d,b):b},importRegExp:/(?:\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))/,regExp:/(?:\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))$/,replace:(a,b)=>{const [,c,d,f]=b;b=G.$createLinkNode(d,{title:f});const e=m.$createTextNode(c);e.setFormat(a.getFormat());b.append(e);a.replace(b)},trigger:")",type:"text-match"},Fa=[oa,pa,qa,ra,ta],Ga=[ua,wa,ya,za,Aa,va,Ca,Da,Ba],Ha=[Ea],Z=[...Fa,...Ga,...Ha];
|
|
32
|
+
exports.$convertFromMarkdownString=function(a,b=Z,c,d=!1){return ha(b,d)(a,c)};exports.$convertToMarkdownString=function(a=Z,b,c=!1){return ca(a,c)(b)};exports.BOLD_ITALIC_STAR=wa;exports.BOLD_ITALIC_UNDERSCORE=ya;exports.BOLD_STAR=za;exports.BOLD_UNDERSCORE=Aa;exports.CHECK_LIST=sa;exports.CODE=qa;exports.ELEMENT_TRANSFORMERS=Fa;exports.HEADING=oa;exports.HIGHLIGHT=va;exports.INLINE_CODE=ua;exports.ITALIC_STAR=Ca;exports.ITALIC_UNDERSCORE=Da;exports.LINK=Ea;exports.ORDERED_LIST=ta;
|
|
33
|
+
exports.QUOTE=pa;exports.STRIKETHROUGH=Ba;exports.TEXT_FORMAT_TRANSFORMERS=Ga;exports.TEXT_MATCH_TRANSFORMERS=Ha;exports.TRANSFORMERS=Z;exports.UNORDERED_LIST=ra;
|
|
34
|
+
exports.registerMarkdownShortcuts=function(a,b=Z){let c=I(b),d=H(c.textFormat,({tag:e})=>e[e.length-1]),f=H(c.textMatch,({trigger:e})=>e);for(let e of b)if(b=e.type,"element"===b||"text-match"===b){b=e.dependencies;for(let k of b)a.hasNode(k)||ka(173,k.getType())}return a.registerUpdateListener(({tags:e,dirtyLeaves:k,editorState:g,prevEditorState:p})=>{if(!e.has("collaboration")&&!e.has("historic")&&!a.isComposing()){var v=g.read(m.$getSelection);e=p.read(m.$getSelection);if(m.$isRangeSelection(e)&&
|
|
35
|
+
m.$isRangeSelection(v)&&v.isCollapsed()){p=v.anchor.key;var r=v.anchor.offset,q=g._nodeMap.get(p);!m.$isTextNode(q)||!k.has(p)||1!==r&&r>e.anchor.offset+1||a.update(()=>{if(!q.hasFormat("code")){var l=q.getParent();if(null!==l&&!u.$isCodeNode(l)){var t=v.anchor.offset;b:{var n=c.element,h=l.getParent();if(m.$isRootOrShadowRoot(h)&&l.getFirstChild()===q&&(h=q.getTextContent()," "===h[t-1]))for(let {regExp:C,replace:D}of n)if((n=h.match(C))&&n[0].length===t){h=q.getNextSiblings();let [E,xa]=q.splitText(t);
|
|
36
|
+
E.remove();h=xa?[xa,...h]:h;D(l,h,n,!1);l=!0;break b}l=!1}if(!l){b:{n=q.getTextContent();l=f[n[t-1]];if(null!=l){t<n.length&&(n=n.slice(0,t));for(y of l)if(l=n.match(y.regExp),null!==l){n=l.index||0;h=n+l[0].length;var x=void 0;0===n?[x]=q.splitText(h):[,x]=q.splitText(n,h);x.selectNext(0,0);y.replace(x,l);var y=!0;break b}}y=!1}if(!y)b:{h=q.getTextContent();--t;var w=h[t];if(y=d[w])for(let C of y){var {tag:z}=C;y=z.length;let D=t-y+1;if(!(1<y&&!ma(h,D,z,0,y)||" "===h[D-1])&&(x=h[t+1],!1!==C.intraword||
|
|
37
|
+
!x||J.test(x))){l=x=q;n=la(h,D,z);for(var A=l;0>n&&(A=A.getPreviousSibling())&&!m.$isLineBreakNode(A);)m.$isTextNode(A)&&(n=A.getTextContent(),l=A,n=la(n,n.length,z));if(!(0>n||l===x&&n+y===D||(z=l.getTextContent(),0<n&&z[n-1]===w||(A=z[n-1],!1===C.intraword&&A&&!J.test(A))))){h=x.getTextContent();h=h.slice(0,D)+h.slice(t+1);x.setTextContent(h);h=l===x?h:z;l.setTextContent(h.slice(0,n)+h.slice(n+y));h=m.$getSelection();w=m.$createRangeSelection();m.$setSelection(w);t=t-y*(l===x?2:1)+1;w.anchor.set(l.__key,
|
|
38
|
+
n,"text");w.focus.set(x.__key,t,"text");for(let E of C.format)w.hasFormat(E)||w.formatText(E);w.anchor.set(w.focus.key,w.focus.offset,w.focus.type);for(let E of C.format)w.hasFormat(E)&&w.toggleFormat(E);m.$isRangeSelection(h)&&(w.format=h.format);break b}}}}}}}})}}})}
|
package/LexicalMarkdown.prod.mjs
CHANGED
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
6
7
|
*/
|
|
7
|
-
import{$getRoot as t,$isElementNode as e,$isDecoratorNode as n,$isLineBreakNode as o,$isTextNode as r,$getSelection as i,$isParagraphNode as s,$createTextNode as c,$createParagraphNode as l,$createLineBreakNode as a,$isRangeSelection as f,$isRootOrShadowRoot as u,$createRangeSelection as g,$setSelection as p}from"lexical";import{$createCodeNode as d,$isCodeNode as m,CodeNode as h}from"@lexical/code";import{$isListNode as x,$isListItemNode as T,ListNode as C,ListItemNode as y,$createListItemNode as v,$createListNode as w}from"@lexical/list";import{$isQuoteNode as S,HeadingNode as b,$isHeadingNode as E,QuoteNode as $,$createQuoteNode as F,$createHeadingNode as P}from"@lexical/rich-text";import{$findMatchingParent as k}from"@lexical/utils";import{LinkNode as M,$isLinkNode as R,$createLinkNode as _}from"@lexical/link";function L(t,e){const n={};for(const o of t){const t=e(o);n[t]?n[t].push(o):n[t]=[o]}return n}function A(t){const e=L(t,(t=>t.type));return{element:e.element||[],textFormat:e["text-format"]||[],textMatch:e["text-match"]||[]}}const N=/[!-/:-@[-`{-~\s]/;function z(t,o,r,i){for(const e of o){const n=e.export(t,(t=>j(t,r,i)));if(null!=n)return n}return e(t)?j(t,r,i):n(t)?t.getTextContent():null}function j(t,i,s){const c=[],l=t.getChildren();t:for(const t of l){for(const e of s){const n=e.export(t,(t=>j(t,i,s)),((t,e)=>B(t,e,i)));if(null!=n){c.push(n);continue t}}o(t)?c.push("\n"):r(t)?c.push(B(t,t.getTextContent(),i)):e(t)?c.push(j(t,i,s)):n(t)&&c.push(t.getTextContent())}return c.join("")}function B(t,e,n){const o=e.trim();let r=o;const i=new Set;for(const e of n){const n=e.format[0],o=e.tag;if(D(t,n)&&!i.has(n)){i.add(n);D(I(t,!0),n)||(r=o+r);D(I(t,!1),n)||(r+=o)}}return e.replace(o,(()=>r))}function I(t,n){let o=n?t.getPreviousSibling():t.getNextSibling();if(!o){const e=t.getParentOrThrow();e.isInline()&&(o=n?e.getPreviousSibling():e.getNextSibling())}for(;o;){if(e(o)){if(!o.isInline())break;const t=n?o.getLastDescendant():o.getFirstDescendant();if(r(t))return t;o=n?o.getPreviousSibling():o.getNextSibling()}if(r(o))return o;if(!e(o))return null}return null}function D(t,e){return r(t)&&t.hasFormat(e)}const U="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,K=U&&"documentMode"in document?document.documentMode:null;U&&/Mac|iPod|iPhone|iPad/.test(navigator.platform),U&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent),U&&"InputEvent"in window&&!K&&new window.InputEvent("input");const O=U&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent),V=U&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,W=(U&&/Android/.test(navigator.userAgent),U&&/^(?=.*Chrome).*/i.test(navigator.userAgent)),q=U&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&!W,G=/^\s{0,3}$/,H=/^```(\w{1,10})?\s?$/;function J(e){const n=A(e),o=function(t){const e={},n={},o=[],r="(?<![\\\\])";for(const r of t){const{tag:t}=r;e[t]=r;const i=t.replace(/(\*|\^|\+)/g,"\\$1");o.push(i),n[t]=O||V||q?new RegExp(`(${i})(?![${i}\\s])(.*?[^${i}\\s])${i}(?!${i})`):new RegExp(`(?<![\\\\${i}])(${i})((\\\\${i})?.*?[^${i}\\s](\\\\${i})?)((?<!\\\\)|(?<=\\\\\\\\))(${i})(?![\\\\${i}])`)}return{fullMatchRegExpByTag:n,openTagsRegExp:new RegExp((O||V||q?"":`${r}`)+"("+o.join("|")+")","g"),transformersByTag:e}}(n.textFormat);return(e,r)=>{const s=e.split("\n"),c=s.length,l=r||t();l.clear();for(let t=0;t<c;t++){const e=s[t],[r,i]=Y(s,t,l);null==r?X(e,l,n.element,o,n.textMatch):t=i}const a=l.getChildren();for(const t of a)Q(t)&&l.getChildrenSize()>1&&t.remove();null!==i()&&l.selectEnd()}}function Q(t){if(!s(t))return!1;const e=t.getFirstChild();return null==e||1===t.getChildrenSize()&&r(e)&&G.test(e.getTextContent())}function X(t,e,n,o,r){const i=t.trim(),f=c(i),u=l();u.append(f),e.append(u);for(const{regExp:e,replace:o}of n){const n=t.match(e);if(n){f.setTextContent(t.slice(n[0].length)),o(u,[f],n,!0);break}}if(Z(f,o,r),u.isAttached()&&i.length>0){const t=u.getPreviousSibling();if(s(t)||S(t)||x(t)){let e=t;if(x(t)){const n=t.getLastDescendant();e=null==n?null:k(n,T)}null!=e&&e.getTextContentSize()>0&&(e.splice(e.getChildrenSize(),0,[a(),...u.getChildren()]),u.remove())}}}function Y(t,e,n){const o=t[e].match(H);if(o){let r=e;const i=t.length;for(;++r<i;){if(t[r].match(H)){const i=d(o[1]),s=c(t.slice(e+1,r).join("\n"));return i.append(s),n.append(i),[i,r]}}}return[null,e]}function Z(t,e,n){const o=t.getTextContent(),r=function(t,e){const n=t.match(e.openTagsRegExp);if(null==n)return null;for(const o of n){const n=o.replace(/^\s/,""),r=e.fullMatchRegExpByTag[n];if(null==r)continue;const i=t.match(r),s=e.transformersByTag[n];if(null!=i&&null!=s){if(!1!==s.intraword)return i;const{index:e=0}=i,n=t[e-1],o=t[e+i[0].length];if((!n||N.test(n))&&(!o||N.test(o)))return i}}return null}(o,e);if(!r)return void tt(t,n);let i,s,c;if(r[0]===o)i=t;else{const e=r.index||0,n=e+r[0].length;0===e?[i,s]=t.splitText(n):[c,i,s]=t.splitText(e,n)}i.setTextContent(r[2]);const l=e.transformersByTag[r[1]];if(l)for(const t of l.format)i.hasFormat(t)||i.toggleFormat(t);i.hasFormat("code")||Z(i,e,n),c&&Z(c,e,n),s&&Z(s,e,n)}function tt(t,e){let n=t;t:for(;n;){for(const t of e){const o=n.getTextContent().match(t.importRegExp);if(!o)continue;const r=o.index||0,i=r+o[0].length;let s,c;0===r?[s,n]=n.splitText(i):[,s,c]=n.splitText(r,i),c&&tt(c,e),t.replace(s,o);continue t}break}}function et(t,e,n){const o=n.length;for(let r=e;r>=o;r--){const e=r-o;if(nt(t,e,n,0,o)&&" "!==t[e+o])return e}return-1}function nt(t,e,n,o,r){for(let i=0;i<r;i++)if(t[e+i]!==n[o+i])return!1;return!0}function ot(t,e=$t){const n=A(e),s=L(n.textFormat,(({tag:t})=>t[t.length-1])),c=L(n.textMatch,(({trigger:t})=>t));for(const n of e){const e=n.type;if("element"===e||"text-match"===e){const e=n.dependencies;for(const n of e)if(!t.hasNode(n))throw Error(`MarkdownShortcuts: missing dependency ${n.getType()} for transformer. Ensure node dependency is included in editor initial config.`)}}const l=(t,e,l)=>{(function(t,e,n,o){const r=t.getParent();if(!u(r)||t.getFirstChild()!==e)return!1;const i=e.getTextContent();if(" "!==i[n-1])return!1;for(const{regExp:r,replace:s}of o){const o=i.match(r);if(o&&o[0].length===n){const r=e.getNextSiblings(),[i,c]=e.splitText(n);return i.remove(),s(t,c?[c,...r]:r,o,!1),!0}}return!1})(t,e,l,n.element)||function(t,e,n){let o=t.getTextContent();const r=n[o[e-1]];if(null==r)return!1;e<o.length&&(o=o.slice(0,e));for(const e of r){const n=o.match(e.regExp);if(null===n)continue;const r=n.index||0,i=r+n[0].length;let s;return 0===r?[s]=t.splitText(i):[,s]=t.splitText(r,i),s.selectNext(0,0),e.replace(s,n),!0}return!1}(e,l,c)||function(t,e,n){const s=t.getTextContent(),c=e-1,l=s[c],a=n[l];if(!a)return!1;for(const e of a){const{tag:n}=e,a=n.length,u=c-a+1;if(a>1&&!nt(s,u,n,0,a))continue;if(" "===s[u-1])continue;const d=s[c+1];if(!1===e.intraword&&d&&!N.test(d))continue;const m=t;let h=m,x=et(s,u,n),T=h;for(;x<0&&(T=T.getPreviousSibling())&&!o(T);)if(r(T)){const t=T.getTextContent();h=T,x=et(t,t.length,n)}if(x<0)continue;if(h===m&&x+a===u)continue;const C=h.getTextContent();if(x>0&&C[x-1]===l)continue;const y=C[x-1];if(!1===e.intraword&&y&&!N.test(y))continue;const v=m.getTextContent(),w=v.slice(0,u)+v.slice(c+1);m.setTextContent(w);const S=h===m?w:C;h.setTextContent(S.slice(0,x)+S.slice(x+a));const b=i(),E=g();p(E);const $=c-a*(h===m?2:1)+1;E.anchor.set(h.__key,x,"text"),E.focus.set(m.__key,$,"text");for(const t of e.format)E.hasFormat(t)||E.formatText(t);E.anchor.set(E.focus.key,E.focus.offset,E.focus.type);for(const t of e.format)E.hasFormat(t)&&E.toggleFormat(t);return f(b)&&(E.format=b.format),!0}}(e,l,s)};return t.registerUpdateListener((({tags:e,dirtyLeaves:n,editorState:o,prevEditorState:s})=>{if(e.has("collaboration")||e.has("historic"))return;if(t.isComposing())return;const c=o.read(i),a=s.read(i);if(!f(a)||!f(c)||!c.isCollapsed())return;const u=c.anchor.key,g=c.anchor.offset,p=o._nodeMap.get(u);!r(p)||!n.has(u)||1!==g&&g>a.anchor.offset+1||t.update((()=>{if(p.hasFormat("code"))return;const t=p.getParent();null===t||m(t)||l(t,p,c.anchor.offset)}))}))}const rt=t=>(e,n,o)=>{const r=t(o);r.append(...n),e.replace(r),r.select(0,0)};const it=t=>(e,n,o)=>{const r=e.getPreviousSibling(),i=e.getNextSibling(),s=v("check"===t?"x"===o[3]:void 0);if(x(i)&&i.getListType()===t){const t=i.getFirstChild();null!==t?t.insertBefore(s):i.append(s),e.remove()}else if(x(r)&&r.getListType()===t)r.append(s),e.remove();else{const n=w(t,"number"===t?Number(o[2]):void 0);n.append(s),e.replace(n)}s.append(...n),s.select(0,0);const c=function(t){const e=t.match(/\t/g),n=t.match(/ /g);let o=0;return e&&(o+=e.length),n&&(o+=Math.floor(n.length/4)),o}(o[1]);c&&s.setIndent(c)},st=(t,e,n)=>{const o=[],r=t.getChildren();let i=0;for(const s of r)if(T(s)){if(1===s.getChildrenSize()){const t=s.getFirstChild();if(x(t)){o.push(st(t,e,n+1));continue}}const r=" ".repeat(4*n),c=t.getListType(),l="number"===c?`${t.getStart()+i}. `:"check"===c?`- [${s.getChecked()?"x":" "}] `:"- ";o.push(r+l+e(s)),i++}return o.join("\n")},ct={dependencies:[b],export:(t,e)=>{if(!E(t))return null;const n=Number(t.getTag().slice(1));return"#".repeat(n)+" "+e(t)},regExp:/^(#{1,6})\s/,replace:rt((t=>{const e="h"+t[1].length;return P(e)})),type:"element"},lt={dependencies:[$],export:(t,e)=>{if(!S(t))return null;const n=e(t).split("\n"),o=[];for(const t of n)o.push("> "+t);return o.join("\n")},regExp:/^>\s/,replace:(t,e,n,o)=>{if(o){const n=t.getPreviousSibling();if(S(n))return n.splice(n.getChildrenSize(),0,[a(),...e]),n.select(0,0),void t.remove()}const r=F();r.append(...e),t.replace(r),r.select(0,0)},type:"element"},at={dependencies:[h],export:t=>{if(!m(t))return null;const e=t.getTextContent();return"```"+(t.getLanguage()||"")+(e?"\n"+e:"")+"\n```"},regExp:/^```(\w{1,10})?\s/,replace:rt((t=>d(t?t[1]:void 0))),type:"element"},ft={dependencies:[C,y],export:(t,e)=>x(t)?st(t,e,0):null,regExp:/^(\s*)[-*+]\s/,replace:it("bullet"),type:"element"},ut={dependencies:[C,y],export:(t,e)=>x(t)?st(t,e,0):null,regExp:/^(\s*)(?:-\s)?\s?(\[(\s|x)?\])\s/i,replace:it("check"),type:"element"},gt={dependencies:[C,y],export:(t,e)=>x(t)?st(t,e,0):null,regExp:/^(\s*)(\d{1,})\.\s/,replace:it("number"),type:"element"},pt={format:["code"],tag:"`",type:"text-format"},dt={format:["highlight"],tag:"==",type:"text-format"},mt={format:["bold","italic"],tag:"***",type:"text-format"},ht={format:["bold","italic"],intraword:!1,tag:"___",type:"text-format"},xt={format:["bold"],tag:"**",type:"text-format"},Tt={format:["bold"],intraword:!1,tag:"__",type:"text-format"},Ct={format:["strikethrough"],tag:"~~",type:"text-format"},yt={format:["italic"],tag:"*",type:"text-format"},vt={format:["italic"],intraword:!1,tag:"_",type:"text-format"},wt={dependencies:[M],export:(t,e,n)=>{if(!R(t))return null;const o=t.getTitle(),i=o?`[${t.getTextContent()}](${t.getURL()} "${o}")`:`[${t.getTextContent()}](${t.getURL()})`,s=t.getFirstChild();return 1===t.getChildrenSize()&&r(s)?n(s,i):i},importRegExp:/(?:\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))/,regExp:/(?:\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))$/,replace:(t,e)=>{const[,n,o,r]=e,i=_(o,{title:r}),s=c(n);s.setFormat(t.getFormat()),i.append(s),t.replace(i)},trigger:")",type:"text-match"},St=[ct,lt,at,ft,gt],bt=[pt,mt,ht,xt,Tt,dt,yt,vt,Ct],Et=[wt],$t=[...St,...bt,...Et];function Ft(t,e=$t,n){return J(e)(t,n)}function Pt(e=$t,n){const o=function(e){const n=A(e),o=n.textFormat.filter((t=>1===t.format.length));return e=>{const r=[],i=(e||t()).getChildren();for(const t of i){const e=z(t,n.element,o,n.textMatch);null!=e&&r.push(e)}return r.join("\n\n")}}(e);return o(n)}export{Ft as $convertFromMarkdownString,Pt as $convertToMarkdownString,mt as BOLD_ITALIC_STAR,ht as BOLD_ITALIC_UNDERSCORE,xt as BOLD_STAR,Tt as BOLD_UNDERSCORE,ut as CHECK_LIST,at as CODE,St as ELEMENT_TRANSFORMERS,ct as HEADING,dt as HIGHLIGHT,pt as INLINE_CODE,yt as ITALIC_STAR,vt as ITALIC_UNDERSCORE,wt as LINK,gt as ORDERED_LIST,lt as QUOTE,Ct as STRIKETHROUGH,bt as TEXT_FORMAT_TRANSFORMERS,Et as TEXT_MATCH_TRANSFORMERS,$t as TRANSFORMERS,ft as UNORDERED_LIST,ot as registerMarkdownShortcuts};
|
|
8
|
+
|
|
9
|
+
import{$isParagraphNode as t,$isTextNode as e,$getRoot as n,$isElementNode as o,$isDecoratorNode as r,$isLineBreakNode as i,$getSelection as s,$createTextNode as c,$createParagraphNode as l,$createLineBreakNode as a,$isRangeSelection as f,$isRootOrShadowRoot as u,$createRangeSelection as g,$setSelection as p}from"lexical";import{$createCodeNode as d,$isCodeNode as m,CodeNode as h}from"@lexical/code";import{$isListNode as x,$isListItemNode as T,ListNode as C,ListItemNode as y,$createListItemNode as v,$createListNode as w}from"@lexical/list";import{$isQuoteNode as b,HeadingNode as S,$isHeadingNode as $,QuoteNode as E,$createQuoteNode as F,$createHeadingNode as P}from"@lexical/rich-text";import{$findMatchingParent as k}from"@lexical/utils";import{LinkNode as M,$isLinkNode as _,$createLinkNode as L}from"@lexical/link";function R(t,e){const n={};for(const o of t){const t=e(o);n[t]?n[t].push(o):n[t]=[o]}return n}function N(t){const e=R(t,(t=>t.type));return{element:e.element||[],textFormat:e["text-format"]||[],textMatch:e["text-match"]||[]}}const j=/[!-/:-@[-`{-~\s]/,z=/^\s{0,3}$/;function A(n){if(!t(n))return!1;const o=n.getFirstChild();return null==o||1===n.getChildrenSize()&&e(o)&&z.test(o.getTextContent())}function B(t,e,n,i){for(const o of e){const e=o.export(t,(t=>I(t,n,i)));if(null!=e)return e}return o(t)?I(t,n,i):r(t)?t.getTextContent():null}function I(t,n,s){const c=[],l=t.getChildren();t:for(const t of l){for(const e of s){const o=e.export(t,(t=>I(t,n,s)),((t,e)=>U(t,e,n)));if(null!=o){c.push(o);continue t}}i(t)?c.push("\n"):e(t)?c.push(U(t,t.getTextContent(),n)):o(t)?c.push(I(t,n,s)):r(t)&&c.push(t.getTextContent())}return c.join("")}function U(t,e,n){const o=e.trim();let r=o;const i=new Set;for(const e of n){const n=e.format[0],o=e.tag;if(O(t,n)&&!i.has(n)){i.add(n);O(D(t,!0),n)||(r=o+r);O(D(t,!1),n)||(r+=o)}}return e.replace(o,(()=>r))}function D(t,n){let r=n?t.getPreviousSibling():t.getNextSibling();if(!r){const e=t.getParentOrThrow();e.isInline()&&(r=n?e.getPreviousSibling():e.getNextSibling())}for(;r;){if(o(r)){if(!r.isInline())break;const t=n?r.getLastDescendant():r.getFirstDescendant();if(e(t))return t;r=n?r.getPreviousSibling():r.getNextSibling()}if(e(r))return r;if(!o(r))return null}return null}function O(t,n){return e(t)&&t.hasFormat(n)}const K="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,V=K&&"documentMode"in document?document.documentMode:null;K&&"InputEvent"in window&&!V&&new window.InputEvent("input");const W=K&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent),q=K&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,G=K&&/^(?=.*Chrome).*/i.test(navigator.userAgent),H=K&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&!G,J=/^[ \t]*```(\w{1,10})?\s?$/;function Q(t,e=!1){const o=N(t),r=function(t){const e={},n={},o=[],r="(?<![\\\\])";for(const r of t){const{tag:t}=r;e[t]=r;const i=t.replace(/(\*|\^|\+)/g,"\\$1");o.push(i),n[t]=W||q||H?new RegExp(`(${i})(?![${i}\\s])(.*?[^${i}\\s])${i}(?!${i})`):new RegExp(`(?<![\\\\${i}])(${i})((\\\\${i})?.*?[^${i}\\s](\\\\${i})?)((?<!\\\\)|(?<=\\\\\\\\))(${i})(?![\\\\${i}])`)}return{fullMatchRegExpByTag:n,openTagsRegExp:new RegExp((W||q||H?"":`${r}`)+"("+o.join("|")+")","g"),transformersByTag:e}}(o.textFormat);return(t,i)=>{const c=t.split("\n"),l=c.length,a=i||n();a.clear();for(let t=0;t<l;t++){const e=c[t],[n,i]=Y(c,t,a);null==n?X(e,a,o.element,r,o.textMatch):t=i}const f=a.getChildren();for(const t of f)!e&&A(t)&&a.getChildrenSize()>1&&t.remove();null!==s()&&a.selectEnd()}}function X(e,n,o,r,i){const s=e.trim(),f=c(s),u=l();u.append(f),n.append(u);for(const{regExp:t,replace:n}of o){const o=e.match(t);if(o){f.setTextContent(e.slice(o[0].length)),n(u,[f],o,!0);break}}if(Z(f,r,i),u.isAttached()&&s.length>0){const e=u.getPreviousSibling();if(t(e)||b(e)||x(e)){let t=e;if(x(e)){const n=e.getLastDescendant();t=null==n?null:k(n,T)}null!=t&&t.getTextContentSize()>0&&(t.splice(t.getChildrenSize(),0,[a(),...u.getChildren()]),u.remove())}}}function Y(t,e,n){const o=t[e].match(J);if(o){let r=e;const i=t.length;for(;++r<i;){if(t[r].match(J)){const i=d(o[1]),s=c(t.slice(e+1,r).join("\n"));return i.append(s),n.append(i),[i,r]}}}return[null,e]}function Z(t,e,n){const o=t.getTextContent(),r=function(t,e){const n=t.match(e.openTagsRegExp);if(null==n)return null;for(const o of n){const n=o.replace(/^\s/,""),r=e.fullMatchRegExpByTag[n];if(null==r)continue;const i=t.match(r),s=e.transformersByTag[n];if(null!=i&&null!=s){if(!1!==s.intraword)return i;const{index:e=0}=i,n=t[e-1],o=t[e+i[0].length];if((!n||j.test(n))&&(!o||j.test(o)))return i}}return null}(o,e);if(!r)return void tt(t,n);let i,s,c;if(r[0]===o)i=t;else{const e=r.index||0,n=e+r[0].length;0===e?[i,s]=t.splitText(n):[c,i,s]=t.splitText(e,n)}i.setTextContent(r[2]);const l=e.transformersByTag[r[1]];if(l)for(const t of l.format)i.hasFormat(t)||i.toggleFormat(t);i.hasFormat("code")||Z(i,e,n),c&&Z(c,e,n),s&&Z(s,e,n)}function tt(t,e){let n=t;t:for(;n;){for(const t of e){const o=n.getTextContent().match(t.importRegExp);if(!o)continue;const r=o.index||0,i=r+o[0].length;let s,c;0===r?[s,n]=n.splitText(i):[,s,c]=n.splitText(r,i),c&&tt(c,e),t.replace(s,o);continue t}break}}function et(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var nt=et((function(t){const e=new URLSearchParams;e.append("code",t);for(let t=1;t<arguments.length;t++)e.append("v",arguments[t]);throw Error(`Minified Lexical error #${t}; visit https://lexical.dev/docs/error?${e} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}));function ot(t,e,n){const o=n.length;for(let r=e;r>=o;r--){const e=r-o;if(rt(t,e,n,0,o)&&" "!==t[e+o])return e}return-1}function rt(t,e,n,o,r){for(let i=0;i<r;i++)if(t[e+i]!==n[o+i])return!1;return!0}function it(t,n=Pt){const o=N(n),r=R(o.textFormat,(({tag:t})=>t[t.length-1])),c=R(o.textMatch,(({trigger:t})=>t));for(const e of n){const n=e.type;if("element"===n||"text-match"===n){const n=e.dependencies;for(const e of n)t.hasNode(e)||nt(173,e.getType())}}const l=(t,n,l)=>{(function(t,e,n,o){const r=t.getParent();if(!u(r)||t.getFirstChild()!==e)return!1;const i=e.getTextContent();if(" "!==i[n-1])return!1;for(const{regExp:r,replace:s}of o){const o=i.match(r);if(o&&o[0].length===n){const r=e.getNextSiblings(),[i,c]=e.splitText(n);return i.remove(),s(t,c?[c,...r]:r,o,!1),!0}}return!1})(t,n,l,o.element)||function(t,e,n){let o=t.getTextContent();const r=n[o[e-1]];if(null==r)return!1;e<o.length&&(o=o.slice(0,e));for(const e of r){const n=o.match(e.regExp);if(null===n)continue;const r=n.index||0,i=r+n[0].length;let s;return 0===r?[s]=t.splitText(i):[,s]=t.splitText(r,i),s.selectNext(0,0),e.replace(s,n),!0}return!1}(n,l,c)||function(t,n,o){const r=t.getTextContent(),c=n-1,l=r[c],a=o[l];if(!a)return!1;for(const n of a){const{tag:o}=n,a=o.length,u=c-a+1;if(a>1&&!rt(r,u,o,0,a))continue;if(" "===r[u-1])continue;const d=r[c+1];if(!1===n.intraword&&d&&!j.test(d))continue;const m=t;let h=m,x=ot(r,u,o),T=h;for(;x<0&&(T=T.getPreviousSibling())&&!i(T);)if(e(T)){const t=T.getTextContent();h=T,x=ot(t,t.length,o)}if(x<0)continue;if(h===m&&x+a===u)continue;const C=h.getTextContent();if(x>0&&C[x-1]===l)continue;const y=C[x-1];if(!1===n.intraword&&y&&!j.test(y))continue;const v=m.getTextContent(),w=v.slice(0,u)+v.slice(c+1);m.setTextContent(w);const b=h===m?w:C;h.setTextContent(b.slice(0,x)+b.slice(x+a));const S=s(),$=g();p($);const E=c-a*(h===m?2:1)+1;$.anchor.set(h.__key,x,"text"),$.focus.set(m.__key,E,"text");for(const t of n.format)$.hasFormat(t)||$.formatText(t);$.anchor.set($.focus.key,$.focus.offset,$.focus.type);for(const t of n.format)$.hasFormat(t)&&$.toggleFormat(t);return f(S)&&($.format=S.format),!0}}(n,l,r)};return t.registerUpdateListener((({tags:n,dirtyLeaves:o,editorState:r,prevEditorState:i})=>{if(n.has("collaboration")||n.has("historic"))return;if(t.isComposing())return;const c=r.read(s),a=i.read(s);if(!f(a)||!f(c)||!c.isCollapsed())return;const u=c.anchor.key,g=c.anchor.offset,p=r._nodeMap.get(u);!e(p)||!o.has(u)||1!==g&&g>a.anchor.offset+1||t.update((()=>{if(p.hasFormat("code"))return;const t=p.getParent();null===t||m(t)||l(t,p,c.anchor.offset)}))}))}const st=t=>(e,n,o)=>{const r=t(o);r.append(...n),e.replace(r),r.select(0,0)};const ct=t=>(e,n,o)=>{const r=e.getPreviousSibling(),i=e.getNextSibling(),s=v("check"===t?"x"===o[3]:void 0);if(x(i)&&i.getListType()===t){const t=i.getFirstChild();null!==t?t.insertBefore(s):i.append(s),e.remove()}else if(x(r)&&r.getListType()===t)r.append(s),e.remove();else{const n=w(t,"number"===t?Number(o[2]):void 0);n.append(s),e.replace(n)}s.append(...n),s.select(0,0);const c=function(t){const e=t.match(/\t/g),n=t.match(/ /g);let o=0;return e&&(o+=e.length),n&&(o+=Math.floor(n.length/4)),o}(o[1]);c&&s.setIndent(c)},lt=(t,e,n)=>{const o=[],r=t.getChildren();let i=0;for(const s of r)if(T(s)){if(1===s.getChildrenSize()){const t=s.getFirstChild();if(x(t)){o.push(lt(t,e,n+1));continue}}const r=" ".repeat(4*n),c=t.getListType(),l="number"===c?`${t.getStart()+i}. `:"check"===c?`- [${s.getChecked()?"x":" "}] `:"- ";o.push(r+l+e(s)),i++}return o.join("\n")},at={dependencies:[S],export:(t,e)=>{if(!$(t))return null;const n=Number(t.getTag().slice(1));return"#".repeat(n)+" "+e(t)},regExp:/^(#{1,6})\s/,replace:st((t=>{const e="h"+t[1].length;return P(e)})),type:"element"},ft={dependencies:[E],export:(t,e)=>{if(!b(t))return null;const n=e(t).split("\n"),o=[];for(const t of n)o.push("> "+t);return o.join("\n")},regExp:/^>\s/,replace:(t,e,n,o)=>{if(o){const n=t.getPreviousSibling();if(b(n))return n.splice(n.getChildrenSize(),0,[a(),...e]),n.select(0,0),void t.remove()}const r=F();r.append(...e),t.replace(r),r.select(0,0)},type:"element"},ut={dependencies:[h],export:t=>{if(!m(t))return null;const e=t.getTextContent();return"```"+(t.getLanguage()||"")+(e?"\n"+e:"")+"\n```"},regExp:/^[ \t]*```(\w{1,10})?\s/,replace:st((t=>d(t?t[1]:void 0))),type:"element"},gt={dependencies:[C,y],export:(t,e)=>x(t)?lt(t,e,0):null,regExp:/^(\s*)[-*+]\s/,replace:ct("bullet"),type:"element"},pt={dependencies:[C,y],export:(t,e)=>x(t)?lt(t,e,0):null,regExp:/^(\s*)(?:-\s)?\s?(\[(\s|x)?\])\s/i,replace:ct("check"),type:"element"},dt={dependencies:[C,y],export:(t,e)=>x(t)?lt(t,e,0):null,regExp:/^(\s*)(\d{1,})\.\s/,replace:ct("number"),type:"element"},mt={format:["code"],tag:"`",type:"text-format"},ht={format:["highlight"],tag:"==",type:"text-format"},xt={format:["bold","italic"],tag:"***",type:"text-format"},Tt={format:["bold","italic"],intraword:!1,tag:"___",type:"text-format"},Ct={format:["bold"],tag:"**",type:"text-format"},yt={format:["bold"],intraword:!1,tag:"__",type:"text-format"},vt={format:["strikethrough"],tag:"~~",type:"text-format"},wt={format:["italic"],tag:"*",type:"text-format"},bt={format:["italic"],intraword:!1,tag:"_",type:"text-format"},St={dependencies:[M],export:(t,n,o)=>{if(!_(t))return null;const r=t.getTitle(),i=r?`[${t.getTextContent()}](${t.getURL()} "${r}")`:`[${t.getTextContent()}](${t.getURL()})`,s=t.getFirstChild();return 1===t.getChildrenSize()&&e(s)?o(s,i):i},importRegExp:/(?:\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))/,regExp:/(?:\[([^[]+)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))$/,replace:(t,e)=>{const[,n,o,r]=e,i=L(o,{title:r}),s=c(n);s.setFormat(t.getFormat()),i.append(s),t.replace(i)},trigger:")",type:"text-match"},$t=[at,ft,ut,gt,dt],Et=[mt,xt,Tt,Ct,yt,ht,wt,bt,vt],Ft=[St],Pt=[...$t,...Et,...Ft];function kt(t,e=Pt,n,o=!1){return Q(e,o)(t,n)}function Mt(t=Pt,e,o=!1){const r=function(t,e=!1){const o=N(t),r=!e,i=o.textFormat.filter((t=>1===t.format.length));return t=>{const e=[],s=(t||n()).getChildren();for(let t=0;t<s.length;t++){const n=s[t],c=B(n,o.element,i,o.textMatch);null!=c&&e.push(r&&t>0&&!A(n)&&!A(s[t-1])?"\n".concat(c):c)}return e.join("\n")}}(t,o);return r(e)}export{kt as $convertFromMarkdownString,Mt as $convertToMarkdownString,xt as BOLD_ITALIC_STAR,Tt as BOLD_ITALIC_UNDERSCORE,Ct as BOLD_STAR,yt as BOLD_UNDERSCORE,pt as CHECK_LIST,ut as CODE,$t as ELEMENT_TRANSFORMERS,at as HEADING,ht as HIGHLIGHT,mt as INLINE_CODE,wt as ITALIC_STAR,bt as ITALIC_UNDERSCORE,St as LINK,dt as ORDERED_LIST,ft as QUOTE,vt as STRIKETHROUGH,Et as TEXT_FORMAT_TRANSFORMERS,Ft as TEXT_MATCH_TRANSFORMERS,Pt as TRANSFORMERS,gt as UNORDERED_LIST,it as registerMarkdownShortcuts};
|
package/MarkdownExport.d.ts
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Transformer } from '@lexical/markdown';
|
|
9
9
|
import type { ElementNode } from 'lexical';
|
|
10
|
-
export declare function createMarkdownExport(transformers: Array<Transformer
|
|
10
|
+
export declare function createMarkdownExport(transformers: Array<Transformer>, shouldPreserveNewLines?: boolean): (node?: ElementNode) => string;
|
package/MarkdownImport.d.ts
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Transformer } from '@lexical/markdown';
|
|
9
9
|
import { ElementNode } from 'lexical';
|
|
10
|
-
export declare function createMarkdownImport(transformers: Array<Transformer
|
|
10
|
+
export declare function createMarkdownImport(transformers: Array<Transformer>, shouldPreserveNewLines?: boolean): (markdownString: string, node?: ElementNode) => void;
|
package/index.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ declare const ELEMENT_TRANSFORMERS: Array<ElementTransformer>;
|
|
|
13
13
|
declare const TEXT_FORMAT_TRANSFORMERS: Array<TextFormatTransformer>;
|
|
14
14
|
declare const TEXT_MATCH_TRANSFORMERS: Array<TextMatchTransformer>;
|
|
15
15
|
declare const TRANSFORMERS: Array<Transformer>;
|
|
16
|
-
declare function $convertFromMarkdownString(markdown: string, transformers?: Array<Transformer>, node?: ElementNode): void;
|
|
17
|
-
declare function $convertToMarkdownString(transformers?: Array<Transformer>, node?: ElementNode): string;
|
|
16
|
+
declare function $convertFromMarkdownString(markdown: string, transformers?: Array<Transformer>, node?: ElementNode, shouldPreserveNewLines?: boolean): void;
|
|
17
|
+
declare function $convertToMarkdownString(transformers?: Array<Transformer>, node?: ElementNode, shouldPreserveNewLines?: boolean): string;
|
|
18
18
|
export { $convertFromMarkdownString, $convertToMarkdownString, BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, CHECK_LIST, CODE, ELEMENT_TRANSFORMERS, ElementTransformer, HEADING, HIGHLIGHT, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, LINK, ORDERED_LIST, QUOTE, registerMarkdownShortcuts, STRIKETHROUGH, TEXT_FORMAT_TRANSFORMERS, TEXT_MATCH_TRANSFORMERS, TextFormatTransformer, TextMatchTransformer, Transformer, TRANSFORMERS, UNORDERED_LIST, };
|
package/package.json
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
"markdown"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.16.0",
|
|
12
12
|
"main": "LexicalMarkdown.js",
|
|
13
13
|
"types": "index.d.ts",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@lexical/code": "0.
|
|
16
|
-
"@lexical/link": "0.
|
|
17
|
-
"@lexical/list": "0.
|
|
18
|
-
"@lexical/rich-text": "0.
|
|
19
|
-
"@lexical/text": "0.
|
|
20
|
-
"@lexical/utils": "0.
|
|
21
|
-
"lexical": "0.
|
|
15
|
+
"@lexical/code": "0.16.0",
|
|
16
|
+
"@lexical/link": "0.16.0",
|
|
17
|
+
"@lexical/list": "0.16.0",
|
|
18
|
+
"@lexical/rich-text": "0.16.0",
|
|
19
|
+
"@lexical/text": "0.16.0",
|
|
20
|
+
"@lexical/utils": "0.16.0",
|
|
21
|
+
"lexical": "0.16.0"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
package/utils.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
import type { ElementTransformer, TextFormatTransformer, TextMatchTransformer, Transformer } from '@lexical/markdown';
|
|
9
|
-
import type
|
|
9
|
+
import { type ElementNode, type LexicalNode, type TextFormatType } from 'lexical';
|
|
10
10
|
type MarkdownFormatKind = 'noTransformation' | 'paragraphH1' | 'paragraphH2' | 'paragraphH3' | 'paragraphH4' | 'paragraphH5' | 'paragraphH6' | 'paragraphBlockQuote' | 'paragraphUnorderedList' | 'paragraphOrderedList' | 'paragraphCodeBlock' | 'horizontalRule' | 'bold' | 'code' | 'italic' | 'underline' | 'strikethrough' | 'italic_bold' | 'strikethrough_italic' | 'strikethrough_bold' | 'strikethrough_italic_bold' | 'link';
|
|
11
11
|
type MarkdownCriteria = Readonly<{
|
|
12
12
|
export?: (node: LexicalNode, traverseChildren: (elementNode: ElementNode) => string) => string | null;
|
|
@@ -28,4 +28,5 @@ export declare function transformersByType(transformers: Array<Transformer>): Re
|
|
|
28
28
|
textMatch: Array<TextMatchTransformer>;
|
|
29
29
|
}>;
|
|
30
30
|
export declare const PUNCTUATION_OR_SPACE: RegExp;
|
|
31
|
+
export declare function isEmptyParagraph(node: LexicalNode): boolean;
|
|
31
32
|
export {};
|