@lexical/markdown 0.1.20 → 0.2.1
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 +194 -87
- package/LexicalMarkdown.prod.js +31 -26
- package/package.json +8 -8
package/LexicalMarkdown.dev.js
CHANGED
|
@@ -41,7 +41,7 @@ const SEPARATOR_LENGTH = SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES.length;
|
|
|
41
41
|
const spaceTrigger = {
|
|
42
42
|
triggerKind: 'space_trigger',
|
|
43
43
|
triggerString: '\u0020'
|
|
44
|
-
}; //
|
|
44
|
+
}; // Future todo: add support for ``` + carriage return either inside or not inside code block. Should toggle between.
|
|
45
45
|
// const codeBlockTrigger : AutoFormatTrigger = {
|
|
46
46
|
// triggerKind: 'codeBlock_trigger',
|
|
47
47
|
// triggerString: '```', // + new paragraph element or new code block element.
|
|
@@ -49,7 +49,7 @@ const spaceTrigger = {
|
|
|
49
49
|
|
|
50
50
|
const triggers = [spaceTrigger
|
|
51
51
|
/*, codeBlockTrigger*/
|
|
52
|
-
]; // Todo: speed up performance by having non-capture group variations of the regex.
|
|
52
|
+
]; // Future Todo: speed up performance by having non-capture group variations of the regex.
|
|
53
53
|
|
|
54
54
|
const autoFormatBase = {
|
|
55
55
|
markdownFormatKind: null,
|
|
@@ -62,33 +62,43 @@ const paragraphStartBase = { ...autoFormatBase,
|
|
|
62
62
|
};
|
|
63
63
|
const markdownHeader1 = { ...paragraphStartBase,
|
|
64
64
|
markdownFormatKind: 'paragraphH1',
|
|
65
|
-
regEx: /^(?:#)/,
|
|
65
|
+
regEx: /^(?:# )/,
|
|
66
66
|
regExForAutoFormatting: /^(?:# )/
|
|
67
67
|
};
|
|
68
68
|
const markdownHeader2 = { ...paragraphStartBase,
|
|
69
69
|
markdownFormatKind: 'paragraphH2',
|
|
70
|
-
regEx: /^(?:##)/,
|
|
70
|
+
regEx: /^(?:## )/,
|
|
71
71
|
regExForAutoFormatting: /^(?:## )/
|
|
72
72
|
};
|
|
73
73
|
const markdownHeader3 = { ...paragraphStartBase,
|
|
74
|
-
markdownFormatKind: '
|
|
75
|
-
regEx: /^(?:###)/,
|
|
74
|
+
markdownFormatKind: 'paragraphH3',
|
|
75
|
+
regEx: /^(?:### )/,
|
|
76
76
|
regExForAutoFormatting: /^(?:### )/
|
|
77
77
|
};
|
|
78
|
+
const markdownHeader4 = { ...paragraphStartBase,
|
|
79
|
+
markdownFormatKind: 'paragraphH4',
|
|
80
|
+
regEx: /^(?:#### )/,
|
|
81
|
+
regExForAutoFormatting: /^(?:#### )/
|
|
82
|
+
};
|
|
83
|
+
const markdownHeader5 = { ...paragraphStartBase,
|
|
84
|
+
markdownFormatKind: 'paragraphH5',
|
|
85
|
+
regEx: /^(?:##### )/,
|
|
86
|
+
regExForAutoFormatting: /^(?:##### )/
|
|
87
|
+
};
|
|
78
88
|
const markdownBlockQuote = { ...paragraphStartBase,
|
|
79
89
|
markdownFormatKind: 'paragraphBlockQuote',
|
|
80
|
-
regEx: /^(?:>)/,
|
|
90
|
+
regEx: /^(?:> )/,
|
|
81
91
|
regExForAutoFormatting: /^(?:> )/
|
|
82
92
|
};
|
|
83
93
|
const markdownUnorderedListDash = { ...paragraphStartBase,
|
|
84
94
|
markdownFormatKind: 'paragraphUnorderedList',
|
|
85
|
-
regEx: /^(?:- )/,
|
|
86
|
-
regExForAutoFormatting: /^(?:- )/
|
|
95
|
+
regEx: /^(\s{0,10})(?:- )/,
|
|
96
|
+
regExForAutoFormatting: /^(\s{0,10})(?:- )/
|
|
87
97
|
};
|
|
88
98
|
const markdownUnorderedListAsterisk = { ...paragraphStartBase,
|
|
89
99
|
markdownFormatKind: 'paragraphUnorderedList',
|
|
90
|
-
regEx: /^(?:\* )/,
|
|
91
|
-
regExForAutoFormatting: /^(?:\* )/
|
|
100
|
+
regEx: /^(\s{0,10})(?:\* )/,
|
|
101
|
+
regExForAutoFormatting: /^(\s{0,10})(?:\* )/
|
|
92
102
|
};
|
|
93
103
|
const markdownCodeBlock = { ...paragraphStartBase,
|
|
94
104
|
markdownFormatKind: 'paragraphCodeBlock',
|
|
@@ -97,8 +107,8 @@ const markdownCodeBlock = { ...paragraphStartBase,
|
|
|
97
107
|
};
|
|
98
108
|
const markdownOrderedList = { ...paragraphStartBase,
|
|
99
109
|
markdownFormatKind: 'paragraphOrderedList',
|
|
100
|
-
regEx: /^(\d+)\.\s/,
|
|
101
|
-
regExForAutoFormatting: /^(\d+)\.\s/
|
|
110
|
+
regEx: /^(\s{0,10})(\d+)\.\s/,
|
|
111
|
+
regExForAutoFormatting: /^(\s{0,10})(\d+)\.\s/
|
|
102
112
|
};
|
|
103
113
|
const markdownHorizontalRule = { ...paragraphStartBase,
|
|
104
114
|
markdownFormatKind: 'horizontalRule',
|
|
@@ -110,25 +120,31 @@ const markdownHorizontalRuleUsingDashes = { ...paragraphStartBase,
|
|
|
110
120
|
regEx: /^(?:---)$/,
|
|
111
121
|
regExForAutoFormatting: /^(?:--- )/
|
|
112
122
|
};
|
|
123
|
+
const markdownInlineCode = { ...autoFormatBase,
|
|
124
|
+
markdownFormatKind: 'code',
|
|
125
|
+
regEx: /(`)([^`]*)(`)/,
|
|
126
|
+
regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/
|
|
127
|
+
};
|
|
113
128
|
const markdownItalic = { ...autoFormatBase,
|
|
114
129
|
markdownFormatKind: 'italic',
|
|
115
|
-
regEx: /(\*)(
|
|
130
|
+
regEx: /(\*)([^\*]*)(\*)/,
|
|
116
131
|
regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
|
|
117
132
|
};
|
|
118
133
|
const markdownBold = { ...autoFormatBase,
|
|
119
134
|
markdownFormatKind: 'bold',
|
|
120
|
-
regEx: /(\*\*)(
|
|
135
|
+
regEx: /(\*\*)([^\*\*]*)(\*\*)/,
|
|
121
136
|
regExForAutoFormatting: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
|
|
122
137
|
};
|
|
123
|
-
const
|
|
138
|
+
const markdownBold2 = { ...autoFormatBase,
|
|
124
139
|
markdownFormatKind: 'bold',
|
|
125
140
|
regEx: /(__)(\s*)([^__]*)(\s*)(__)/,
|
|
126
141
|
regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
|
|
127
142
|
};
|
|
128
|
-
const
|
|
129
|
-
markdownFormatKind: '
|
|
130
|
-
regEx: /(
|
|
131
|
-
regExForAutoFormatting: /(
|
|
143
|
+
const markdownItalic2 = { ...autoFormatBase,
|
|
144
|
+
markdownFormatKind: 'italic',
|
|
145
|
+
regEx: /(_)([^_]*)(_)/,
|
|
146
|
+
regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/ // Maintain 7 groups.
|
|
147
|
+
|
|
132
148
|
}; // Markdown does not support underline, but we can allow folks to use
|
|
133
149
|
// the HTML tags for underline.
|
|
134
150
|
|
|
@@ -139,16 +155,40 @@ const fakeMarkdownUnderline = { ...autoFormatBase,
|
|
|
139
155
|
};
|
|
140
156
|
const markdownStrikethrough = { ...autoFormatBase,
|
|
141
157
|
markdownFormatKind: 'strikethrough',
|
|
142
|
-
regEx: /(~~)(
|
|
158
|
+
regEx: /(~~)([^~~]*)(~~)/,
|
|
143
159
|
regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
|
|
144
160
|
};
|
|
161
|
+
const markdownStrikethroughItalicBold = { ...autoFormatBase,
|
|
162
|
+
markdownFormatKind: 'strikethrough_italic_bold',
|
|
163
|
+
regEx: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)/,
|
|
164
|
+
regExForAutoFormatting: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/
|
|
165
|
+
};
|
|
166
|
+
const markdownItalicbold = { ...autoFormatBase,
|
|
167
|
+
markdownFormatKind: 'italic_bold',
|
|
168
|
+
regEx: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,
|
|
169
|
+
regExForAutoFormatting: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/
|
|
170
|
+
};
|
|
171
|
+
const markdownStrikethroughItalic = { ...autoFormatBase,
|
|
172
|
+
markdownFormatKind: 'strikethrough_italic',
|
|
173
|
+
regEx: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,
|
|
174
|
+
regExForAutoFormatting: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/
|
|
175
|
+
};
|
|
176
|
+
const markdownStrikethroughBold = { ...autoFormatBase,
|
|
177
|
+
markdownFormatKind: 'strikethrough_bold',
|
|
178
|
+
regEx: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,
|
|
179
|
+
regExForAutoFormatting: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/
|
|
180
|
+
};
|
|
145
181
|
const markdownLink = { ...autoFormatBase,
|
|
146
182
|
markdownFormatKind: 'link',
|
|
147
183
|
regEx: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))/,
|
|
148
184
|
regExForAutoFormatting: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))(\s)$/
|
|
149
185
|
};
|
|
150
|
-
const allMarkdownCriteriaForTextNodes = [
|
|
151
|
-
|
|
186
|
+
const allMarkdownCriteriaForTextNodes = [// Place the combination formats ahead of the individual formats.
|
|
187
|
+
// Combos
|
|
188
|
+
markdownStrikethroughItalicBold, markdownItalicbold, markdownStrikethroughItalic, markdownStrikethroughBold, // Individuals
|
|
189
|
+
markdownInlineCode, markdownItalic, markdownBold, markdownBold2, markdownItalic2, // Must appear after markdownBold2.
|
|
190
|
+
fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
|
|
191
|
+
const allMarkdownCriteria = [markdownHeader1, markdownHeader2, markdownHeader3, markdownHeader4, markdownHeader5, markdownBlockQuote, markdownUnorderedListDash, markdownUnorderedListAsterisk, markdownOrderedList, markdownCodeBlock, markdownHorizontalRule, markdownHorizontalRuleUsingDashes, ...allMarkdownCriteriaForTextNodes];
|
|
152
192
|
function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset, triggerState) {
|
|
153
193
|
return {
|
|
154
194
|
currentElementNode: null,
|
|
@@ -226,6 +266,9 @@ function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfS
|
|
|
226
266
|
return null;
|
|
227
267
|
}
|
|
228
268
|
|
|
269
|
+
function hasPatternMatchResults(scanningContext) {
|
|
270
|
+
return scanningContext.patternMatchResults.regExCaptureGroups.length > 0;
|
|
271
|
+
}
|
|
229
272
|
function getTextNodeWithOffsetOrThrow(scanningContext) {
|
|
230
273
|
const textNodeWithOffset = scanningContext.textNodeWithOffset;
|
|
231
274
|
|
|
@@ -305,9 +348,9 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
|
|
|
305
348
|
};
|
|
306
349
|
}
|
|
307
350
|
|
|
308
|
-
case '
|
|
351
|
+
case 'paragraphH4':
|
|
309
352
|
{
|
|
310
|
-
newNode = richText.$
|
|
353
|
+
newNode = richText.$createHeadingNode('h4');
|
|
311
354
|
newNode.append(...children);
|
|
312
355
|
return {
|
|
313
356
|
newNode,
|
|
@@ -315,37 +358,54 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
|
|
|
315
358
|
};
|
|
316
359
|
}
|
|
317
360
|
|
|
318
|
-
case '
|
|
361
|
+
case 'paragraphH5':
|
|
319
362
|
{
|
|
320
|
-
newNode =
|
|
321
|
-
|
|
322
|
-
listItem.append(...children);
|
|
323
|
-
newNode.append(listItem);
|
|
363
|
+
newNode = richText.$createHeadingNode('h5');
|
|
364
|
+
newNode.append(...children);
|
|
324
365
|
return {
|
|
325
366
|
newNode,
|
|
326
367
|
shouldDelete
|
|
327
368
|
};
|
|
328
369
|
}
|
|
329
370
|
|
|
330
|
-
case '
|
|
371
|
+
case 'paragraphBlockQuote':
|
|
331
372
|
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
newNode = list.$createListNode('ol', start);
|
|
335
|
-
const listItem = list.$createListItemNode();
|
|
336
|
-
listItem.append(...children);
|
|
337
|
-
newNode.append(listItem);
|
|
373
|
+
newNode = richText.$createQuoteNode();
|
|
374
|
+
newNode.append(...children);
|
|
338
375
|
return {
|
|
339
376
|
newNode,
|
|
340
377
|
shouldDelete
|
|
341
378
|
};
|
|
342
379
|
}
|
|
343
380
|
|
|
381
|
+
case 'paragraphUnorderedList':
|
|
382
|
+
{
|
|
383
|
+
createListOrMergeWithPrevious(element, children, patternMatchResults, 'ul');
|
|
384
|
+
return {
|
|
385
|
+
newNode: null,
|
|
386
|
+
shouldDelete: false
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
case 'paragraphOrderedList':
|
|
391
|
+
{
|
|
392
|
+
const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1'; // For conversion, don't use start number.
|
|
393
|
+
// For short-cuts aka autoFormatting, use start number.
|
|
394
|
+
// Later, this should be surface dependent and externalized.
|
|
395
|
+
|
|
396
|
+
const start = scanningContext.isAutoFormatting ? parseInt(startAsString, 10) : undefined;
|
|
397
|
+
createListOrMergeWithPrevious(element, children, patternMatchResults, 'ol', start);
|
|
398
|
+
return {
|
|
399
|
+
newNode: null,
|
|
400
|
+
shouldDelete: false
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
344
404
|
case 'paragraphCodeBlock':
|
|
345
405
|
{
|
|
346
406
|
// Toggle code and paragraph nodes.
|
|
347
407
|
if (scanningContext.isAutoFormatting === false) {
|
|
348
|
-
const shouldToggle = scanningContext
|
|
408
|
+
const shouldToggle = hasPatternMatchResults(scanningContext);
|
|
349
409
|
|
|
350
410
|
if (shouldToggle) {
|
|
351
411
|
scanningContext.isWithinCodeBlock = scanningContext.isWithinCodeBlock !== true; // When toggling, always clear the code block element node.
|
|
@@ -374,6 +434,11 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
|
|
|
374
434
|
const codeBlockNode = scanningContext.currentElementNode;
|
|
375
435
|
const lineBreakNode = lexical.$createLineBreakNode();
|
|
376
436
|
codeBlockNode.append(lineBreakNode);
|
|
437
|
+
|
|
438
|
+
if (children.length) {
|
|
439
|
+
codeBlockNode.append(lineBreakNode);
|
|
440
|
+
}
|
|
441
|
+
|
|
377
442
|
codeBlockNode.append(...children);
|
|
378
443
|
}
|
|
379
444
|
}
|
|
@@ -421,18 +486,42 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
|
|
|
421
486
|
};
|
|
422
487
|
}
|
|
423
488
|
|
|
424
|
-
function
|
|
425
|
-
const
|
|
426
|
-
const
|
|
489
|
+
function createListOrMergeWithPrevious(element, children, patternMatchResults, tag, start) {
|
|
490
|
+
const listItem = list.$createListItemNode();
|
|
491
|
+
const indentMatch = patternMatchResults.regExCaptureGroups[0].text.match(/^\s*/);
|
|
492
|
+
const indent = indentMatch ? Math.floor(indentMatch[0].length / 4) : 0;
|
|
493
|
+
listItem.append(...children); // Checking if previous element is a list, and if so append
|
|
494
|
+
// new list item inside instead of creating new list
|
|
495
|
+
|
|
496
|
+
const prevElement = element.getPreviousSibling();
|
|
497
|
+
|
|
498
|
+
if (list.$isListNode(prevElement) && prevElement.getTag() === tag) {
|
|
499
|
+
prevElement.append(listItem);
|
|
500
|
+
element.remove();
|
|
501
|
+
} else {
|
|
502
|
+
const list$1 = list.$createListNode(tag, start);
|
|
503
|
+
list$1.append(listItem);
|
|
504
|
+
element.replace(list$1);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (indent) {
|
|
508
|
+
listItem.setIndent(indent);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode) {
|
|
513
|
+
if (scanningContext.textNodeWithOffset != null) {
|
|
514
|
+
const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
|
|
427
515
|
|
|
428
|
-
|
|
429
|
-
|
|
516
|
+
if (hasPatternMatchResults(scanningContext)) {
|
|
517
|
+
const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
|
|
430
518
|
|
|
431
|
-
|
|
519
|
+
const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
|
|
432
520
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
521
|
+
if (textNode.getTextContent() === '') {
|
|
522
|
+
textNode.selectPrevious();
|
|
523
|
+
textNode.remove();
|
|
524
|
+
}
|
|
436
525
|
}
|
|
437
526
|
} // Transform the current element kind to the new element kind.
|
|
438
527
|
|
|
@@ -440,12 +529,12 @@ function transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNod
|
|
|
440
529
|
const {
|
|
441
530
|
newNode,
|
|
442
531
|
shouldDelete
|
|
443
|
-
} = getNewNodeForCriteria(scanningContext,
|
|
532
|
+
} = getNewNodeForCriteria(scanningContext, elementNode, createHorizontalRuleNode);
|
|
444
533
|
|
|
445
534
|
if (shouldDelete) {
|
|
446
|
-
|
|
535
|
+
elementNode.remove();
|
|
447
536
|
} else if (newNode !== null) {
|
|
448
|
-
|
|
537
|
+
elementNode.replace(newNode);
|
|
449
538
|
}
|
|
450
539
|
}
|
|
451
540
|
function transformTextNodeForText(scanningContext) {
|
|
@@ -557,11 +646,27 @@ function getTextFormatType(markdownFormatKind) {
|
|
|
557
646
|
case 'bold':
|
|
558
647
|
case 'underline':
|
|
559
648
|
case 'strikethrough':
|
|
649
|
+
case 'code':
|
|
560
650
|
return [markdownFormatKind];
|
|
561
651
|
|
|
562
|
-
case '
|
|
652
|
+
case 'strikethrough_italic_bold':
|
|
653
|
+
{
|
|
654
|
+
return ['strikethrough', 'italic', 'bold'];
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
case 'italic_bold':
|
|
658
|
+
{
|
|
659
|
+
return ['italic', 'bold'];
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
case 'strikethrough_italic':
|
|
663
|
+
{
|
|
664
|
+
return ['strikethrough', 'italic'];
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
case 'strikethrough_bold':
|
|
563
668
|
{
|
|
564
|
-
return ['
|
|
669
|
+
return ['strikethrough', 'bold'];
|
|
565
670
|
}
|
|
566
671
|
}
|
|
567
672
|
|
|
@@ -728,7 +833,8 @@ function getAllMarkdownCriteria() {
|
|
|
728
833
|
}
|
|
729
834
|
function transformTextNodeForMarkdownCriteria(scanningContext, createHorizontalRuleNode) {
|
|
730
835
|
if (scanningContext.markdownCriteria.requiresParagraphStart === true) {
|
|
731
|
-
|
|
836
|
+
const elementNode = getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
|
|
837
|
+
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
732
838
|
} else {
|
|
733
839
|
transformTextNodeForText(scanningContext);
|
|
734
840
|
}
|
|
@@ -908,58 +1014,59 @@ function convertStringToLexical(text, editor) {
|
|
|
908
1014
|
function convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode) {
|
|
909
1015
|
const textContent = elementNode.getTextContent(); // Handle paragraph nodes below.
|
|
910
1016
|
|
|
911
|
-
if (lexical.$isParagraphNode(elementNode)
|
|
1017
|
+
if (lexical.$isParagraphNode(elementNode)) {
|
|
912
1018
|
const paragraphNode = elementNode;
|
|
913
1019
|
const firstChild = paragraphNode.getFirstChild();
|
|
914
1020
|
const firstChildIsTextNode = lexical.$isTextNode(firstChild); // Handle conversion to code block.
|
|
915
1021
|
|
|
916
1022
|
if (scanningContext.isWithinCodeBlock === true) {
|
|
917
|
-
if (
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
};
|
|
925
|
-
const patternMatchResults = getPatternMatchResultsForCodeBlock(scanningContext, textContent);
|
|
1023
|
+
if (firstChild != null && firstChildIsTextNode) {
|
|
1024
|
+
// Test if we encounter ending code block.
|
|
1025
|
+
scanningContext.textNodeWithOffset = {
|
|
1026
|
+
node: firstChild,
|
|
1027
|
+
offset: 0
|
|
1028
|
+
};
|
|
1029
|
+
const patternMatchResults = getPatternMatchResultsForCodeBlock(scanningContext, textContent);
|
|
926
1030
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1031
|
+
if (patternMatchResults != null) {
|
|
1032
|
+
// Toggle transform to or from code block.
|
|
1033
|
+
scanningContext.patternMatchResults = patternMatchResults;
|
|
1034
|
+
}
|
|
930
1035
|
}
|
|
931
1036
|
|
|
932
1037
|
scanningContext.markdownCriteria = getCodeBlockCriteria(); // Perform text transformation here.
|
|
933
1038
|
|
|
934
|
-
|
|
1039
|
+
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
935
1040
|
return;
|
|
936
1041
|
}
|
|
937
1042
|
|
|
938
|
-
|
|
939
|
-
|
|
1043
|
+
if (elementNode.getChildren().length) {
|
|
1044
|
+
const allCriteria = getAllMarkdownCriteria();
|
|
1045
|
+
const count = allCriteria.length;
|
|
940
1046
|
|
|
941
|
-
|
|
942
|
-
|
|
1047
|
+
for (let i = 0; i < count; i++) {
|
|
1048
|
+
const criteria = allCriteria[i];
|
|
943
1049
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1050
|
+
if (criteria.requiresParagraphStart === true) {
|
|
1051
|
+
if (!(firstChild != null && firstChildIsTextNode)) {
|
|
1052
|
+
throw Error(`Expect paragraph containing only text nodes.`);
|
|
1053
|
+
}
|
|
948
1054
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1055
|
+
scanningContext.textNodeWithOffset = {
|
|
1056
|
+
node: firstChild,
|
|
1057
|
+
offset: 0
|
|
1058
|
+
};
|
|
1059
|
+
scanningContext.joinedText = paragraphNode.getTextContent();
|
|
1060
|
+
const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
|
|
955
1061
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1062
|
+
if (patternMatchResults != null) {
|
|
1063
|
+
// Lazy fill-in the particular format criteria and any matching result information.
|
|
1064
|
+
scanningContext.markdownCriteria = criteria;
|
|
1065
|
+
scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
|
|
960
1066
|
|
|
961
|
-
|
|
962
|
-
|
|
1067
|
+
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
963
1070
|
}
|
|
964
1071
|
}
|
|
965
1072
|
}
|
package/LexicalMarkdown.prod.js
CHANGED
|
@@ -4,29 +4,34 @@
|
|
|
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
|
-
var k=require("@lexical/code"),
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
regEx:/(
|
|
11
|
-
|
|
12
|
-
{...A,markdownFormatKind:"
|
|
13
|
-
|
|
14
|
-
function
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
function
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
var k=require("@lexical/code"),m=require("@lexical/list"),n=require("lexical"),t=require("@lexical/link"),u=require("@lexical/rich-text"),v=require("@lexical/text");function w(c){throw Error(`Minified Lexical error #${c}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
|
8
|
+
const x=[{triggerKind:"space_trigger",triggerString:" "}],y={markdownFormatKind:null,regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:!1},A={...y,requiresParagraphStart:!0},B={...A,markdownFormatKind:"paragraphCodeBlock",regEx:/^(```)$/,regExForAutoFormatting:/^(```)([a-z]*)( )/},C=[{...y,markdownFormatKind:"strikethrough_italic_bold",regEx:/(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)/,regExForAutoFormatting:/(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/},
|
|
9
|
+
{...y,markdownFormatKind:"italic_bold",regEx:/(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,regExForAutoFormatting:/(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/},{...y,markdownFormatKind:"strikethrough_italic",regEx:/(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,regExForAutoFormatting:/(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/},{...y,markdownFormatKind:"strikethrough_bold",regEx:/(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,regExForAutoFormatting:/(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/},
|
|
10
|
+
{...y,markdownFormatKind:"code",regEx:/(`)([^`]*)(`)/,regExForAutoFormatting:/(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/},{...y,markdownFormatKind:"italic",regEx:/(\*)([^\*]*)(\*)/,regExForAutoFormatting:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/},{...y,markdownFormatKind:"bold",regEx:/(\*\*)([^\*\*]*)(\*\*)/,regExForAutoFormatting:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/},{...y,markdownFormatKind:"bold",regEx:/(__)(\s*)([^__]*)(\s*)(__)/,regExForAutoFormatting:/(__)(\s*)([^__]*)(\s*)(__)(\s)$/},{...y,markdownFormatKind:"italic",
|
|
11
|
+
regEx:/(_)([^_]*)(_)/,regExForAutoFormatting:/(_)()([^_]*)()(_)(\s)$/},{...y,markdownFormatKind:"underline",regEx:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)/,regExForAutoFormatting:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/},{...y,markdownFormatKind:"strikethrough",regEx:/(~~)([^~~]*)(~~)/,regExForAutoFormatting:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/},{...y,markdownFormatKind:"link",regEx:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))/,regExForAutoFormatting:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))(\s)$/}],D=[{...A,
|
|
12
|
+
markdownFormatKind:"paragraphH1",regEx:/^(?:# )/,regExForAutoFormatting:/^(?:# )/},{...A,markdownFormatKind:"paragraphH2",regEx:/^(?:## )/,regExForAutoFormatting:/^(?:## )/},{...A,markdownFormatKind:"paragraphH3",regEx:/^(?:### )/,regExForAutoFormatting:/^(?:### )/},{...A,markdownFormatKind:"paragraphH4",regEx:/^(?:#### )/,regExForAutoFormatting:/^(?:#### )/},{...A,markdownFormatKind:"paragraphH5",regEx:/^(?:##### )/,regExForAutoFormatting:/^(?:##### )/},{...A,markdownFormatKind:"paragraphBlockQuote",
|
|
13
|
+
regEx:/^(?:> )/,regExForAutoFormatting:/^(?:> )/},{...A,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})(?:- )/,regExForAutoFormatting:/^(\s{0,10})(?:- )/},{...A,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})(?:\* )/,regExForAutoFormatting:/^(\s{0,10})(?:\* )/},{...A,markdownFormatKind:"paragraphOrderedList",regEx:/^(\s{0,10})(\d+)\.\s/,regExForAutoFormatting:/^(\s{0,10})(\d+)\.\s/},B,{...A,markdownFormatKind:"horizontalRule",regEx:/^(?:\*\*\*)$/,regExForAutoFormatting:/^(?:\*\*\* )/},
|
|
14
|
+
{...A,markdownFormatKind:"horizontalRule",regEx:/^(?:---)$/,regExForAutoFormatting:/^(?:--- )/},...C];function E(c,d,e,a){return{currentElementNode:null,editor:c,isAutoFormatting:d,isWithinCodeBlock:!1,joinedText:null,markdownCriteria:{markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null},patternMatchResults:{regExCaptureGroups:[]},textNodeWithOffset:e,triggerState:a}}
|
|
15
|
+
function F(c,d,e,a){const b={regExCaptureGroups:[]};a=c.match(a);if(null!==a&&0<a.length&&(!1===d||0===a.index)&&(!1===e||a.index+a[0].length===c.length)){c=a.length;d=a.index;for(e=0;e<c;e++){const f=a[e];b.regExCaptureGroups.push({offsetInParent:d,text:f});0<e&&(d+=f.length)}return b}return null}function I(c){c=c.textNodeWithOffset;null==c&&w(82);return c}
|
|
16
|
+
function J(c,d){var e=I(d);return null===e.node.getPreviousSibling()?(e=e.node.getTextContent(),F(e,!0,!1,d.isAutoFormatting?c.regExForAutoFormatting:c.regEx)):null}
|
|
17
|
+
function K(c,d,e){var a=null,b=d.getChildren();const f=c.markdownCriteria,g=c.patternMatchResults;if(null!=f.markdownFormatKind)switch(f.markdownFormatKind){case "paragraphH1":a=u.$createHeadingNode("h1");a.append(...b);break;case "paragraphH2":a=u.$createHeadingNode("h2");a.append(...b);break;case "paragraphH3":a=u.$createHeadingNode("h3");a.append(...b);break;case "paragraphH4":a=u.$createHeadingNode("h4");a.append(...b);break;case "paragraphH5":a=u.$createHeadingNode("h5");a.append(...b);break;
|
|
18
|
+
case "paragraphBlockQuote":a=u.$createQuoteNode();a.append(...b);break;case "paragraphUnorderedList":return L(d,b,g,"ul"),{newNode:null,shouldDelete:!1};case "paragraphOrderedList":return a=1<g.regExCaptureGroups.length?g.regExCaptureGroups[g.regExCaptureGroups.length-1].text:"1",c=c.isAutoFormatting?parseInt(a,10):void 0,L(d,b,g,"ol",c),{newNode:null,shouldDelete:!1};case "paragraphCodeBlock":if(!1===c.isAutoFormatting){if(0<c.patternMatchResults.regExCaptureGroups.length)return c.isWithinCodeBlock=
|
|
19
|
+
!0!==c.isWithinCodeBlock,c.currentElementNode=null,{newNode:null,shouldDelete:!0};if(c.isWithinCodeBlock){if(null==c.currentElementNode)return d=k.$createCodeNode(),d.append(...b),c.currentElementNode=d,{newNode:d,shouldDelete:!1};null!=c.currentElementNode&&(d=c.currentElementNode,c=n.$createLineBreakNode(),d.append(c),b.length&&d.append(c),d.append(...b))}return{newNode:null,shouldDelete:!0}}null!=c.triggerState&&c.triggerState.isCodeBlock?a=n.$createParagraphNode():(a=k.$createCodeNode(),d=3<=
|
|
20
|
+
g.regExCaptureGroups.length?g.regExCaptureGroups[2].text:null,null!=d&&0<d.length&&a.setLanguage(d));a.append(...b);break;case "horizontalRule":null!=e&&(b=e(),d.insertBefore(b))}return{newNode:a,shouldDelete:!1}}
|
|
21
|
+
function L(c,d,e,a,b){const f=m.$createListItemNode();e=(e=e.regExCaptureGroups[0].text.match(/^\s*/))?Math.floor(e[0].length/4):0;f.append(...d);d=c.getPreviousSibling();m.$isListNode(d)&&d.getTag()===a?(d.append(f),c.remove()):(a=m.$createListNode(a,b),a.append(f),c.replace(a));e&&f.setIndent(e)}
|
|
22
|
+
function M(c,d,e){if(null!=d.textNodeWithOffset){var a=I(d);0<d.patternMatchResults.regExCaptureGroups.length&&(a=a.node.spliceText(0,d.patternMatchResults.regExCaptureGroups[0].text.length,"",!0),""===a.getTextContent()&&(a.selectPrevious(),a.remove()))}const {newNode:b,shouldDelete:f}=K(d,c,e);f?c.remove():null!==b&&c.replace(b)}
|
|
23
|
+
function N(c){switch(c){case "italic":case "bold":case "underline":case "strikethrough":case "code":return[c];case "strikethrough_italic_bold":return["strikethrough","italic","bold"];case "italic_bold":return["italic","bold"];case "strikethrough_italic":return["strikethrough","italic"];case "strikethrough_bold":return["strikethrough","bold"]}return null}
|
|
24
|
+
function Q(c,d,e,a,b){var f=b.patternMatchResults;const g=f.regExCaptureGroups;var h=g.length;if(c>=h||d>=h)return null;b=I(b).node.getParentOrThrow();h=f.regExCaptureGroups.length;2>h?f=0:(--h,f=f.regExCaptureGroups[h].offsetInParent+f.regExCaptureGroups[h].text.length);c=g[c];d=g[d];a=a?d.offsetInParent+d.text.length:d.offsetInParent;e=v.$findNodeWithOffsetFromJoinedText(e?c.offsetInParent+c.text.length:c.offsetInParent,f,1,b);a=v.$findNodeWithOffsetFromJoinedText(a,f,1,b);if(null==e||null==a)return null;
|
|
25
|
+
b=n.$createRangeSelection();b.anchor.set(e.node.getKey(),e.offset,"text");b.focus.set(a.node.getKey(),a.offset,"text");return b}function R(c,d,e){const a=e.patternMatchResults.regExCaptureGroups;e=Q(c,d,!1,!0,e);if(null!=e&&(n.$setSelection(e),e=n.$getSelection(),null!=e&&n.$isRangeSelection(e)&&!1===e.isCollapsed())){e.removeText();e=0;const b=a.length;for(let f=c;f<b;f++){const g=a[f];f>c&&(g.offsetInParent-=e);f<=d&&(e+=g.text.length,g.text="")}}}
|
|
26
|
+
function S(c){var d=c.patternMatchResults.regExCaptureGroups.length;2>d||(--d,c=Q(d,d,!0,!0,c),null!=c&&n.$setSelection(c))}
|
|
27
|
+
function T(c,d,e){c.update(()=>{if(!0===d.markdownCriteria.requiresParagraphStart){var a=I(d).node.getParentOrThrow();M(a,d,e)}else if(a=d.markdownCriteria,null!=a.markdownFormatKind){var b=N(a.markdownFormatKind);if(null!=b){if(a=b,7===d.patternMatchResults.regExCaptureGroups.length){R(5,5,d);R(1,1,d);b=d.patternMatchResults.regExCaptureGroups;3<b.length||w(65);if(0!==b[3].text.length&&(b=Q(3,3,!1,!0,d),null!=b&&(n.$setSelection(b),b=n.$getSelection(),n.$isRangeSelection(b))))for(var f=0;f<a.length;f++)b.formatText(a[f]);
|
|
28
|
+
S(d)}}else if("link"===a.markdownFormatKind&&(a=d.patternMatchResults.regExCaptureGroups,7===a.length&&(f=a[2].text,a=a[4].text,0!==f.length&&0!==a.length))){R(1,5,d);b=d.patternMatchResults.regExCaptureGroups;if(!(1>=b.length)){f={offsetInParent:b[1].offsetInParent,text:f};var g=Q(1,1,!1,!1,d);if(null!=g&&(n.$setSelection(g),g=n.$getSelection(),null!=g&&n.$isRangeSelection(g)&&g.isCollapsed())){g.insertText(f.text);b.splice(1,0,f);f=f.text.length;g=b.length;for(let h=2;h<g;h++)b[h].offsetInParent+=
|
|
29
|
+
f}}b=Q(1,1,!1,!0,d);null!=b&&(n.$setSelection(b),d.editor.dispatchCommand(t.TOGGLE_LINK_COMMAND,a),S(d))}}},{tag:"history-push"})}
|
|
30
|
+
function U(c,d){let e=null;c.getEditorState().read(()=>{var a=n.$getSelection();if(n.$isRangeSelection(a)){var b=a.anchor.getNode();a=n.$isTextNode(b)?{node:b,offset:a.anchor.offset}:null}else a=null;if(null!==a){a=E(c,!0,a,d);a:{b=!1===d.isParentAListItemNode?D:C;const h=a.triggerState,r=b.length;for(let p=0;p<r;p++){const l=b[p];if(null!=h&&!1===h.isCodeBlock||"paragraphCodeBlock"===l.markdownFormatKind){var f=l,g=a;if(!0===f.requiresParagraphStart)f=J(f,g);else{if(null==g.joinedText){const q=I(g).node.getParentOrThrow();
|
|
31
|
+
n.$isElementNode(q)?null==g.joinedText&&(g.joinedText=v.$joinTextNodesInElementNode(q,"\u0004",I(g))):w(52,q.__key)}f=F(g.joinedText,!1,!0,f.regExForAutoFormatting)}if(null!=f){b={markdownCriteria:l,patternMatchResults:f};break a}}}b={markdownCriteria:null,patternMatchResults:null}}null!==b.markdownCriteria&&null!==b.patternMatchResults&&(e=a,e.markdownCriteria=b.markdownCriteria,e.patternMatchResults=b.patternMatchResults)}});return e}
|
|
32
|
+
function V(c){let d=null;c.read(()=>{const e=n.$getSelection();if(n.$isRangeSelection(e)&&e.isCollapsed()){var a=e.anchor.getNode(),b=a.getParent(),f=m.$isListItemNode(b);d={anchorOffset:e.anchor.offset,hasParentNode:null!==b,isCodeBlock:k.$isCodeNode(a),isParentAListItemNode:f,isSelectionCollapsed:!0,isSimpleText:n.$isTextNode(a)&&a.isSimpleText(),nodeKey:a.getKey(),textContent:a.getTextContent()}}});return d}
|
|
33
|
+
exports.$convertFromMarkdownString=function(c,d,e){if(c.length){var a=[];c=c.split("\n");var b=c.length;for(var f=0;f<b;f++)0<c[f].length?a.push(n.$createParagraphNode().append(n.$createTextNode(c[f]))):a.push(n.$createParagraphNode());a.length?(c=n.$getRoot(),c.clear(),c.append(...a),a=c):a=null}else a=null;if(null!=a)for(d=E(d,!1,null,null),a=n.$getRoot(),c=!1,b=0;!c;){c=!0;f=a.getChildren();const q=f.length;for(let z=b;z<q;z++){var g=f[z];if(n.$isElementNode(g)){var h=d,r=e,p=g.getTextContent();
|
|
34
|
+
if(n.$isParagraphNode(g)){var l=g.getFirstChild();const O=n.$isTextNode(l);if(!0===h.isWithinCodeBlock)null!=l&&O&&(h.textNodeWithOffset={node:l,offset:0},l=F(p,!0,!1,h.isAutoFormatting?B.regExForAutoFormatting:B.regEx),null!=l&&(h.patternMatchResults=l)),h.markdownCriteria=B,M(g,h,r);else if(g.getChildren().length){p=D.length;for(let G=0;G<p;G++){const H=D[G];if(!0===H.requiresParagraphStart){null!=l&&O||w(80);h.textNodeWithOffset={node:l,offset:0};h.joinedText=g.getTextContent();const P=J(H,h);
|
|
35
|
+
if(null!=P){h.markdownCriteria=H;h.patternMatchResults=P;M(g,h,r);break}}}}}}h=d;h.joinedText="";h.markdownCriteria={markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null};h.patternMatchResults={regExCaptureGroups:[]};h.triggerState=null;h.textNodeWithOffset=null;if(a.getChildren().length!==q){b=z;c=!1;break}}}};
|
|
36
|
+
exports.registerMarkdownShortcuts=function(c,d){let e=null;return c.registerUpdateListener(({tags:a})=>{if(!1===a.has("historic")){a=V(c.getEditorState());if(null==a)var b=null;else a:{b=a;var f=e;if(null==b||null==f)b=null;else{var g=x.length;for(let h=0;h<g;h++){const r=x[h].triggerString,p=r.length,l=b.textContent.length,q=b.anchorOffset-p;if(!1===(!0===b.hasParentNode&&b.isSimpleText&&b.isSelectionCollapsed&&b.anchorOffset!==f.anchorOffset&&0<=q&&q+p<=l&&b.textContent.substr(q,p)===r&&b.textContent!==
|
|
37
|
+
f.textContent)){b=null;break a}}b=U(c,b)}}null!=b&&T(c,b,d);e=a}else e=null})};
|
package/package.json
CHANGED
|
@@ -8,18 +8,18 @@
|
|
|
8
8
|
"markdown"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.1
|
|
11
|
+
"version": "0.2.1",
|
|
12
12
|
"main": "LexicalMarkdown.js",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"lexical": "0.1
|
|
14
|
+
"lexical": "0.2.1"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lexical/utils": "0.1
|
|
18
|
-
"@lexical/code": "0.1
|
|
19
|
-
"@lexical/text": "0.1
|
|
20
|
-
"@lexical/rich-text": "0.1
|
|
21
|
-
"@lexical/list": "0.1
|
|
22
|
-
"@lexical/link": "0.1
|
|
17
|
+
"@lexical/utils": "0.2.1",
|
|
18
|
+
"@lexical/code": "0.2.1",
|
|
19
|
+
"@lexical/text": "0.2.1",
|
|
20
|
+
"@lexical/rich-text": "0.2.1",
|
|
21
|
+
"@lexical/list": "0.2.1",
|
|
22
|
+
"@lexical/link": "0.2.1"
|
|
23
23
|
},
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|