@lexical/markdown 0.1.19 → 0.2.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 +348 -123
- package/LexicalMarkdown.prod.js +30 -23
- package/package.json +8 -8
package/LexicalMarkdown.dev.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
var lexical = require('lexical');
|
|
10
9
|
var code = require('@lexical/code');
|
|
11
10
|
var list = require('@lexical/list');
|
|
11
|
+
var lexical = require('lexical');
|
|
12
12
|
var link = require('@lexical/link');
|
|
13
13
|
var richText = require('@lexical/rich-text');
|
|
14
14
|
var text = require('@lexical/text');
|
|
@@ -23,7 +23,7 @@ var text = require('@lexical/text');
|
|
|
23
23
|
*/
|
|
24
24
|
/*
|
|
25
25
|
How to add a new syntax to capture and transform.
|
|
26
|
-
1. Create a new enumeration by adding to
|
|
26
|
+
1. Create a new enumeration by adding to MarkdownFormatKind.
|
|
27
27
|
2. Add a new criteria with a regEx pattern. See markdownStrikethrough as an example.
|
|
28
28
|
3. Add your block criteria (e.g. '# ') to allMarkdownCriteria or
|
|
29
29
|
your text criteria (e.g. *MyItalic*) to allMarkdownCriteriaForTextNodes.
|
|
@@ -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,10 +49,10 @@ 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,
|
|
56
56
|
regEx: /(?:)/,
|
|
57
57
|
regExForAutoFormatting: /(?:)/,
|
|
58
58
|
requiresParagraphStart: false
|
|
@@ -61,101 +61,133 @@ const paragraphStartBase = { ...autoFormatBase,
|
|
|
61
61
|
requiresParagraphStart: true
|
|
62
62
|
};
|
|
63
63
|
const markdownHeader1 = { ...paragraphStartBase,
|
|
64
|
-
|
|
65
|
-
regEx: /^(?:#)/,
|
|
64
|
+
markdownFormatKind: 'paragraphH1',
|
|
65
|
+
regEx: /^(?:# )/,
|
|
66
66
|
regExForAutoFormatting: /^(?:# )/
|
|
67
67
|
};
|
|
68
68
|
const markdownHeader2 = { ...paragraphStartBase,
|
|
69
|
-
|
|
70
|
-
regEx: /^(?:##)/,
|
|
69
|
+
markdownFormatKind: 'paragraphH2',
|
|
70
|
+
regEx: /^(?:## )/,
|
|
71
71
|
regExForAutoFormatting: /^(?:## )/
|
|
72
72
|
};
|
|
73
73
|
const markdownHeader3 = { ...paragraphStartBase,
|
|
74
|
-
|
|
75
|
-
regEx: /^(?:###)/,
|
|
74
|
+
markdownFormatKind: 'paragraphH2',
|
|
75
|
+
regEx: /^(?:### )/,
|
|
76
76
|
regExForAutoFormatting: /^(?:### )/
|
|
77
77
|
};
|
|
78
78
|
const markdownBlockQuote = { ...paragraphStartBase,
|
|
79
|
-
|
|
80
|
-
regEx: /^(?:>)/,
|
|
79
|
+
markdownFormatKind: 'paragraphBlockQuote',
|
|
80
|
+
regEx: /^(?:> )/,
|
|
81
81
|
regExForAutoFormatting: /^(?:> )/
|
|
82
82
|
};
|
|
83
83
|
const markdownUnorderedListDash = { ...paragraphStartBase,
|
|
84
|
-
|
|
85
|
-
regEx: /^(?:- )/,
|
|
86
|
-
regExForAutoFormatting: /^(?:- )/
|
|
84
|
+
markdownFormatKind: 'paragraphUnorderedList',
|
|
85
|
+
regEx: /^(\s{0,10})(?:- )/,
|
|
86
|
+
regExForAutoFormatting: /^(\s{0,10})(?:- )/
|
|
87
87
|
};
|
|
88
88
|
const markdownUnorderedListAsterisk = { ...paragraphStartBase,
|
|
89
|
-
|
|
90
|
-
regEx: /^(?:\* )/,
|
|
91
|
-
regExForAutoFormatting: /^(?:\* )/
|
|
89
|
+
markdownFormatKind: 'paragraphUnorderedList',
|
|
90
|
+
regEx: /^(\s{0,10})(?:\* )/,
|
|
91
|
+
regExForAutoFormatting: /^(\s{0,10})(?:\* )/
|
|
92
92
|
};
|
|
93
93
|
const markdownCodeBlock = { ...paragraphStartBase,
|
|
94
|
-
|
|
94
|
+
markdownFormatKind: 'paragraphCodeBlock',
|
|
95
95
|
regEx: /^(```)$/,
|
|
96
96
|
regExForAutoFormatting: /^(```)([a-z]*)( )/
|
|
97
97
|
};
|
|
98
98
|
const markdownOrderedList = { ...paragraphStartBase,
|
|
99
|
-
|
|
100
|
-
regEx: /^(\d+)\.\s/,
|
|
101
|
-
regExForAutoFormatting: /^(\d+)\.\s/
|
|
99
|
+
markdownFormatKind: 'paragraphOrderedList',
|
|
100
|
+
regEx: /^(\s{0,10})(\d+)\.\s/,
|
|
101
|
+
regExForAutoFormatting: /^(\s{0,10})(\d+)\.\s/
|
|
102
102
|
};
|
|
103
103
|
const markdownHorizontalRule = { ...paragraphStartBase,
|
|
104
|
-
|
|
104
|
+
markdownFormatKind: 'horizontalRule',
|
|
105
105
|
regEx: /^(?:\*\*\*)$/,
|
|
106
106
|
regExForAutoFormatting: /^(?:\*\*\* )/
|
|
107
107
|
};
|
|
108
108
|
const markdownHorizontalRuleUsingDashes = { ...paragraphStartBase,
|
|
109
|
-
|
|
109
|
+
markdownFormatKind: 'horizontalRule',
|
|
110
110
|
regEx: /^(?:---)$/,
|
|
111
111
|
regExForAutoFormatting: /^(?:--- )/
|
|
112
112
|
};
|
|
113
|
+
const markdownInlineCode = { ...autoFormatBase,
|
|
114
|
+
markdownFormatKind: 'code',
|
|
115
|
+
regEx: /(`)([^`]*)(`)/,
|
|
116
|
+
regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/
|
|
117
|
+
};
|
|
113
118
|
const markdownItalic = { ...autoFormatBase,
|
|
114
|
-
|
|
115
|
-
regEx: /(\*)(
|
|
119
|
+
markdownFormatKind: 'italic',
|
|
120
|
+
regEx: /(\*)([^\*]*)(\*)/,
|
|
116
121
|
regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
|
|
117
122
|
};
|
|
118
123
|
const markdownBold = { ...autoFormatBase,
|
|
119
|
-
|
|
120
|
-
regEx: /(\*\*)(
|
|
124
|
+
markdownFormatKind: 'bold',
|
|
125
|
+
regEx: /(\*\*)([^\*\*]*)(\*\*)/,
|
|
121
126
|
regExForAutoFormatting: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
|
|
122
127
|
};
|
|
123
|
-
const
|
|
124
|
-
|
|
128
|
+
const markdownBold2 = { ...autoFormatBase,
|
|
129
|
+
markdownFormatKind: 'bold',
|
|
125
130
|
regEx: /(__)(\s*)([^__]*)(\s*)(__)/,
|
|
126
131
|
regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
|
|
127
132
|
};
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
regEx: /(
|
|
131
|
-
regExForAutoFormatting: /(
|
|
133
|
+
const markdownItalic2 = { ...autoFormatBase,
|
|
134
|
+
markdownFormatKind: 'italic',
|
|
135
|
+
regEx: /(_)([^_]*)(_)/,
|
|
136
|
+
regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/ // Maintain 7 groups.
|
|
137
|
+
|
|
132
138
|
}; // Markdown does not support underline, but we can allow folks to use
|
|
133
139
|
// the HTML tags for underline.
|
|
134
140
|
|
|
135
141
|
const fakeMarkdownUnderline = { ...autoFormatBase,
|
|
136
|
-
|
|
142
|
+
markdownFormatKind: 'underline',
|
|
137
143
|
regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)/,
|
|
138
144
|
regExForAutoFormatting: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)(\s)$/
|
|
139
145
|
};
|
|
140
146
|
const markdownStrikethrough = { ...autoFormatBase,
|
|
141
|
-
|
|
142
|
-
regEx: /(~~)(
|
|
147
|
+
markdownFormatKind: 'strikethrough',
|
|
148
|
+
regEx: /(~~)([^~~]*)(~~)/,
|
|
143
149
|
regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
|
|
144
150
|
};
|
|
151
|
+
const markdownStrikethroughItalicBold = { ...autoFormatBase,
|
|
152
|
+
markdownFormatKind: 'strikethrough_italic_bold',
|
|
153
|
+
regEx: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)/,
|
|
154
|
+
regExForAutoFormatting: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/
|
|
155
|
+
};
|
|
156
|
+
const markdownItalicbold = { ...autoFormatBase,
|
|
157
|
+
markdownFormatKind: 'italic_bold',
|
|
158
|
+
regEx: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,
|
|
159
|
+
regExForAutoFormatting: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/
|
|
160
|
+
};
|
|
161
|
+
const markdownStrikethroughItalic = { ...autoFormatBase,
|
|
162
|
+
markdownFormatKind: 'strikethrough_italic',
|
|
163
|
+
regEx: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,
|
|
164
|
+
regExForAutoFormatting: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/
|
|
165
|
+
};
|
|
166
|
+
const markdownStrikethroughBold = { ...autoFormatBase,
|
|
167
|
+
markdownFormatKind: 'strikethrough_bold',
|
|
168
|
+
regEx: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,
|
|
169
|
+
regExForAutoFormatting: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/
|
|
170
|
+
};
|
|
145
171
|
const markdownLink = { ...autoFormatBase,
|
|
146
|
-
|
|
172
|
+
markdownFormatKind: 'link',
|
|
147
173
|
regEx: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))/,
|
|
148
174
|
regExForAutoFormatting: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))(\s)$/
|
|
149
175
|
};
|
|
150
|
-
const allMarkdownCriteriaForTextNodes = [
|
|
176
|
+
const allMarkdownCriteriaForTextNodes = [// Place the combination formats ahead of the individual formats.
|
|
177
|
+
// Combos
|
|
178
|
+
markdownStrikethroughItalicBold, markdownItalicbold, markdownStrikethroughItalic, markdownStrikethroughBold, // Individuals
|
|
179
|
+
markdownInlineCode, markdownItalic, markdownBold, markdownBold2, markdownItalic2, // Must appear after markdownBold2.
|
|
180
|
+
fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
|
|
151
181
|
const allMarkdownCriteria = [markdownHeader1, markdownHeader2, markdownHeader3, markdownBlockQuote, markdownUnorderedListDash, markdownUnorderedListAsterisk, markdownOrderedList, markdownCodeBlock, markdownHorizontalRule, markdownHorizontalRuleUsingDashes, ...allMarkdownCriteriaForTextNodes];
|
|
152
182
|
function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset, triggerState) {
|
|
153
183
|
return {
|
|
184
|
+
currentElementNode: null,
|
|
154
185
|
editor,
|
|
155
186
|
isAutoFormatting,
|
|
187
|
+
isWithinCodeBlock: false,
|
|
156
188
|
joinedText: null,
|
|
157
189
|
markdownCriteria: {
|
|
158
|
-
|
|
190
|
+
markdownFormatKind: 'noTransformation',
|
|
159
191
|
regEx: /(?:)/,
|
|
160
192
|
// Empty reg ex.
|
|
161
193
|
regExForAutoFormatting: /(?:)/,
|
|
@@ -172,7 +204,7 @@ function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset,
|
|
|
172
204
|
function resetScanningContext(scanningContext) {
|
|
173
205
|
scanningContext.joinedText = '';
|
|
174
206
|
scanningContext.markdownCriteria = {
|
|
175
|
-
|
|
207
|
+
markdownFormatKind: 'noTransformation',
|
|
176
208
|
regEx: /(?:)/,
|
|
177
209
|
// Empty reg ex.
|
|
178
210
|
regExForAutoFormatting: /(?:)/,
|
|
@@ -186,6 +218,13 @@ function resetScanningContext(scanningContext) {
|
|
|
186
218
|
scanningContext.textNodeWithOffset = null;
|
|
187
219
|
return scanningContext;
|
|
188
220
|
}
|
|
221
|
+
function getCodeBlockCriteria() {
|
|
222
|
+
return markdownCodeBlock;
|
|
223
|
+
}
|
|
224
|
+
function getPatternMatchResultsForCodeBlock(scanningContext, text) {
|
|
225
|
+
const markdownCriteria = getCodeBlockCriteria();
|
|
226
|
+
return getPatternMatchResultsWithRegEx(text, true, false, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
|
|
227
|
+
}
|
|
189
228
|
|
|
190
229
|
function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfString, matchMustAppearAtEndOfString, regEx) {
|
|
191
230
|
const patternMatchResults = {
|
|
@@ -217,6 +256,9 @@ function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfS
|
|
|
217
256
|
return null;
|
|
218
257
|
}
|
|
219
258
|
|
|
259
|
+
function hasPatternMatchResults(scanningContext) {
|
|
260
|
+
return scanningContext.patternMatchResults.regExCaptureGroups.length > 0;
|
|
261
|
+
}
|
|
220
262
|
function getTextNodeWithOffsetOrThrow(scanningContext) {
|
|
221
263
|
const textNodeWithOffset = scanningContext.textNodeWithOffset;
|
|
222
264
|
|
|
@@ -233,7 +275,7 @@ function getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext)
|
|
|
233
275
|
|
|
234
276
|
if (textNodeWithOffset.node.getPreviousSibling() === null) {
|
|
235
277
|
const textToSearch = textNodeWithOffset.node.getTextContent();
|
|
236
|
-
return getPatternMatchResultsWithRegEx(textToSearch, true, false, markdownCriteria.regExForAutoFormatting);
|
|
278
|
+
return getPatternMatchResultsWithRegEx(textToSearch, true, false, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
|
|
237
279
|
}
|
|
238
280
|
|
|
239
281
|
return null;
|
|
@@ -259,63 +301,124 @@ function getPatternMatchResultsForText(markdownCriteria, scanningContext) {
|
|
|
259
301
|
|
|
260
302
|
function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNode) {
|
|
261
303
|
let newNode = null;
|
|
304
|
+
const shouldDelete = false;
|
|
262
305
|
const children = element.getChildren();
|
|
263
306
|
const markdownCriteria = scanningContext.markdownCriteria;
|
|
264
307
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
265
308
|
|
|
266
|
-
if (markdownCriteria.
|
|
267
|
-
switch (markdownCriteria.
|
|
309
|
+
if (markdownCriteria.markdownFormatKind != null) {
|
|
310
|
+
switch (markdownCriteria.markdownFormatKind) {
|
|
268
311
|
case 'paragraphH1':
|
|
269
312
|
{
|
|
270
313
|
newNode = richText.$createHeadingNode('h1');
|
|
271
314
|
newNode.append(...children);
|
|
272
|
-
return
|
|
315
|
+
return {
|
|
316
|
+
newNode,
|
|
317
|
+
shouldDelete
|
|
318
|
+
};
|
|
273
319
|
}
|
|
274
320
|
|
|
275
321
|
case 'paragraphH2':
|
|
276
322
|
{
|
|
277
323
|
newNode = richText.$createHeadingNode('h2');
|
|
278
324
|
newNode.append(...children);
|
|
279
|
-
return
|
|
325
|
+
return {
|
|
326
|
+
newNode,
|
|
327
|
+
shouldDelete
|
|
328
|
+
};
|
|
280
329
|
}
|
|
281
330
|
|
|
282
331
|
case 'paragraphH3':
|
|
283
332
|
{
|
|
284
333
|
newNode = richText.$createHeadingNode('h3');
|
|
285
334
|
newNode.append(...children);
|
|
286
|
-
return
|
|
335
|
+
return {
|
|
336
|
+
newNode,
|
|
337
|
+
shouldDelete
|
|
338
|
+
};
|
|
287
339
|
}
|
|
288
340
|
|
|
289
341
|
case 'paragraphBlockQuote':
|
|
290
342
|
{
|
|
291
343
|
newNode = richText.$createQuoteNode();
|
|
292
344
|
newNode.append(...children);
|
|
293
|
-
return
|
|
345
|
+
return {
|
|
346
|
+
newNode,
|
|
347
|
+
shouldDelete
|
|
348
|
+
};
|
|
294
349
|
}
|
|
295
350
|
|
|
296
351
|
case 'paragraphUnorderedList':
|
|
297
352
|
{
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
353
|
+
createListOrMergeWithPrevious(element, children, patternMatchResults, 'ul');
|
|
354
|
+
return {
|
|
355
|
+
newNode: null,
|
|
356
|
+
shouldDelete: false
|
|
357
|
+
};
|
|
303
358
|
}
|
|
304
359
|
|
|
305
360
|
case 'paragraphOrderedList':
|
|
306
361
|
{
|
|
307
|
-
const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1';
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
return
|
|
362
|
+
const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1'; // For conversion, don't use start number.
|
|
363
|
+
// For short-cuts aka autoFormatting, use start number.
|
|
364
|
+
// Later, this should be surface dependent and externalized.
|
|
365
|
+
|
|
366
|
+
const start = scanningContext.isAutoFormatting ? parseInt(startAsString, 10) : undefined;
|
|
367
|
+
createListOrMergeWithPrevious(element, children, patternMatchResults, 'ol', start);
|
|
368
|
+
return {
|
|
369
|
+
newNode: null,
|
|
370
|
+
shouldDelete: false
|
|
371
|
+
};
|
|
314
372
|
}
|
|
315
373
|
|
|
316
374
|
case 'paragraphCodeBlock':
|
|
317
375
|
{
|
|
318
376
|
// Toggle code and paragraph nodes.
|
|
377
|
+
if (scanningContext.isAutoFormatting === false) {
|
|
378
|
+
const shouldToggle = hasPatternMatchResults(scanningContext);
|
|
379
|
+
|
|
380
|
+
if (shouldToggle) {
|
|
381
|
+
scanningContext.isWithinCodeBlock = scanningContext.isWithinCodeBlock !== true; // When toggling, always clear the code block element node.
|
|
382
|
+
|
|
383
|
+
scanningContext.currentElementNode = null;
|
|
384
|
+
return {
|
|
385
|
+
newNode: null,
|
|
386
|
+
shouldDelete: true
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (scanningContext.isWithinCodeBlock) {
|
|
391
|
+
// Create the code block and return it to the caller.
|
|
392
|
+
if (scanningContext.currentElementNode == null) {
|
|
393
|
+
const newCodeBlockNode = code.$createCodeNode();
|
|
394
|
+
newCodeBlockNode.append(...children);
|
|
395
|
+
scanningContext.currentElementNode = newCodeBlockNode;
|
|
396
|
+
return {
|
|
397
|
+
newNode: newCodeBlockNode,
|
|
398
|
+
shouldDelete: false
|
|
399
|
+
};
|
|
400
|
+
} // Build up the code block with a line break and the children.
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
if (scanningContext.currentElementNode != null) {
|
|
404
|
+
const codeBlockNode = scanningContext.currentElementNode;
|
|
405
|
+
const lineBreakNode = lexical.$createLineBreakNode();
|
|
406
|
+
codeBlockNode.append(lineBreakNode);
|
|
407
|
+
|
|
408
|
+
if (children.length) {
|
|
409
|
+
codeBlockNode.append(lineBreakNode);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
codeBlockNode.append(...children);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return {
|
|
417
|
+
newNode: null,
|
|
418
|
+
shouldDelete: true
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
|
|
319
422
|
if (scanningContext.triggerState != null && scanningContext.triggerState.isCodeBlock) {
|
|
320
423
|
newNode = lexical.$createParagraphNode();
|
|
321
424
|
} else {
|
|
@@ -328,53 +431,94 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
|
|
|
328
431
|
}
|
|
329
432
|
|
|
330
433
|
newNode.append(...children);
|
|
331
|
-
return
|
|
434
|
+
return {
|
|
435
|
+
newNode,
|
|
436
|
+
shouldDelete
|
|
437
|
+
};
|
|
332
438
|
}
|
|
333
439
|
|
|
334
440
|
case 'horizontalRule':
|
|
335
441
|
{
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
442
|
+
if (createHorizontalRuleNode != null) {
|
|
443
|
+
// return null for newNode. Insert the HR here.
|
|
444
|
+
const horizontalRuleNode = createHorizontalRuleNode();
|
|
445
|
+
element.insertBefore(horizontalRuleNode);
|
|
446
|
+
}
|
|
447
|
+
|
|
339
448
|
break;
|
|
340
449
|
}
|
|
341
450
|
}
|
|
342
451
|
}
|
|
343
452
|
|
|
344
|
-
return
|
|
453
|
+
return {
|
|
454
|
+
newNode,
|
|
455
|
+
shouldDelete
|
|
456
|
+
};
|
|
345
457
|
}
|
|
346
458
|
|
|
347
|
-
function
|
|
348
|
-
const
|
|
349
|
-
const
|
|
350
|
-
const
|
|
459
|
+
function createListOrMergeWithPrevious(element, children, patternMatchResults, tag, start) {
|
|
460
|
+
const listItem = list.$createListItemNode();
|
|
461
|
+
const indentMatch = patternMatchResults.regExCaptureGroups[0].text.match(/^\s*/);
|
|
462
|
+
const indent = indentMatch ? Math.floor(indentMatch[0].length / 4) : 0;
|
|
463
|
+
listItem.append(...children); // Checking if previous element is a list, and if so append
|
|
464
|
+
// new list item inside instead of creating new list
|
|
465
|
+
|
|
466
|
+
const prevElement = element.getPreviousSibling();
|
|
467
|
+
|
|
468
|
+
if (list.$isListNode(prevElement) && prevElement.getTag() === tag) {
|
|
469
|
+
prevElement.append(listItem);
|
|
470
|
+
element.remove();
|
|
471
|
+
} else {
|
|
472
|
+
const list$1 = list.$createListNode(tag, start);
|
|
473
|
+
list$1.append(listItem);
|
|
474
|
+
element.replace(list$1);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (indent) {
|
|
478
|
+
listItem.setIndent(indent);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode) {
|
|
483
|
+
if (scanningContext.textNodeWithOffset != null) {
|
|
484
|
+
const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
|
|
485
|
+
|
|
486
|
+
if (hasPatternMatchResults(scanningContext)) {
|
|
487
|
+
const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
|
|
351
488
|
|
|
352
|
-
|
|
489
|
+
const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
|
|
353
490
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
491
|
+
if (textNode.getTextContent() === '') {
|
|
492
|
+
textNode.selectPrevious();
|
|
493
|
+
textNode.remove();
|
|
494
|
+
}
|
|
495
|
+
}
|
|
357
496
|
} // Transform the current element kind to the new element kind.
|
|
358
497
|
|
|
359
498
|
|
|
360
|
-
const
|
|
499
|
+
const {
|
|
500
|
+
newNode,
|
|
501
|
+
shouldDelete
|
|
502
|
+
} = getNewNodeForCriteria(scanningContext, elementNode, createHorizontalRuleNode);
|
|
361
503
|
|
|
362
|
-
if (
|
|
363
|
-
|
|
504
|
+
if (shouldDelete) {
|
|
505
|
+
elementNode.remove();
|
|
506
|
+
} else if (newNode !== null) {
|
|
507
|
+
elementNode.replace(newNode);
|
|
364
508
|
}
|
|
365
509
|
}
|
|
366
510
|
function transformTextNodeForText(scanningContext) {
|
|
367
511
|
const markdownCriteria = scanningContext.markdownCriteria;
|
|
368
512
|
|
|
369
|
-
if (markdownCriteria.
|
|
370
|
-
const formatting = getTextFormatType(markdownCriteria.
|
|
513
|
+
if (markdownCriteria.markdownFormatKind != null) {
|
|
514
|
+
const formatting = getTextFormatType(markdownCriteria.markdownFormatKind);
|
|
371
515
|
|
|
372
516
|
if (formatting != null) {
|
|
373
517
|
transformTextNodeWithFormatting(formatting, scanningContext);
|
|
374
518
|
return;
|
|
375
519
|
}
|
|
376
520
|
|
|
377
|
-
if (markdownCriteria.
|
|
521
|
+
if (markdownCriteria.markdownFormatKind === 'link') {
|
|
378
522
|
transformTextNodeWithLink(scanningContext);
|
|
379
523
|
}
|
|
380
524
|
}
|
|
@@ -466,17 +610,33 @@ function getJoinedTextLength(patternMatchResults) {
|
|
|
466
610
|
return patternMatchResults.regExCaptureGroups[lastGroupIndex].offsetInParent + patternMatchResults.regExCaptureGroups[lastGroupIndex].text.length;
|
|
467
611
|
}
|
|
468
612
|
|
|
469
|
-
function getTextFormatType(
|
|
470
|
-
switch (
|
|
613
|
+
function getTextFormatType(markdownFormatKind) {
|
|
614
|
+
switch (markdownFormatKind) {
|
|
471
615
|
case 'italic':
|
|
472
616
|
case 'bold':
|
|
473
617
|
case 'underline':
|
|
474
618
|
case 'strikethrough':
|
|
475
|
-
|
|
619
|
+
case 'code':
|
|
620
|
+
return [markdownFormatKind];
|
|
621
|
+
|
|
622
|
+
case 'strikethrough_italic_bold':
|
|
623
|
+
{
|
|
624
|
+
return ['strikethrough', 'italic', 'bold'];
|
|
625
|
+
}
|
|
476
626
|
|
|
477
|
-
case '
|
|
627
|
+
case 'italic_bold':
|
|
478
628
|
{
|
|
479
|
-
return ['
|
|
629
|
+
return ['italic', 'bold'];
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
case 'strikethrough_italic':
|
|
633
|
+
{
|
|
634
|
+
return ['strikethrough', 'italic'];
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
case 'strikethrough_bold':
|
|
638
|
+
{
|
|
639
|
+
return ['strikethrough', 'bold'];
|
|
480
640
|
}
|
|
481
641
|
}
|
|
482
642
|
|
|
@@ -643,7 +803,8 @@ function getAllMarkdownCriteria() {
|
|
|
643
803
|
}
|
|
644
804
|
function transformTextNodeForMarkdownCriteria(scanningContext, createHorizontalRuleNode) {
|
|
645
805
|
if (scanningContext.markdownCriteria.requiresParagraphStart === true) {
|
|
646
|
-
|
|
806
|
+
const elementNode = getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
|
|
807
|
+
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
647
808
|
} else {
|
|
648
809
|
transformTextNodeForText(scanningContext);
|
|
649
810
|
}
|
|
@@ -689,7 +850,7 @@ function getCriteriaWithPatternMatchResults(markdownCriteriaArray, scanningConte
|
|
|
689
850
|
for (let i = 0; i < count; i++) {
|
|
690
851
|
const markdownCriteria = markdownCriteriaArray[i]; // Skip code block nodes, unless the autoFormatKind calls for toggling the code block.
|
|
691
852
|
|
|
692
|
-
if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || markdownCriteria.
|
|
853
|
+
if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || markdownCriteria.markdownFormatKind === 'paragraphCodeBlock') {
|
|
693
854
|
const patternMatchResults = getPatternMatchResultsForCriteria(markdownCriteria, scanningContext);
|
|
694
855
|
|
|
695
856
|
if (patternMatchResults != null) {
|
|
@@ -776,7 +937,7 @@ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
|
|
|
776
937
|
const currentTextContentLength = currentTriggerState.textContent.length;
|
|
777
938
|
const triggerOffset = currentTriggerState.anchorOffset - triggerStringLength;
|
|
778
939
|
|
|
779
|
-
if ((currentTriggerState.hasParentNode === true && currentTriggerState.isSimpleText && currentTriggerState.isSelectionCollapsed && currentTriggerState.
|
|
940
|
+
if ((currentTriggerState.hasParentNode === true && currentTriggerState.isSimpleText && currentTriggerState.isSelectionCollapsed && currentTriggerState.anchorOffset !== priorTriggerState.anchorOffset && triggerOffset >= 0 && triggerOffset + triggerStringLength <= currentTextContentLength && currentTriggerState.textContent.substr(triggerOffset, triggerStringLength) === triggerString && // Some code differentiation needed if trigger kind is not a simple space character.
|
|
780
941
|
currentTriggerState.textContent !== priorTriggerState.textContent) === false) {
|
|
781
942
|
return null;
|
|
782
943
|
}
|
|
@@ -794,62 +955,125 @@ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
|
|
|
794
955
|
*
|
|
795
956
|
*/
|
|
796
957
|
function convertStringToLexical(text, editor) {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
root.append(...nodes);
|
|
801
|
-
}
|
|
958
|
+
if (!text.length) {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
802
961
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
if (lexical.$isParagraphNode(elementNode)) {
|
|
807
|
-
const paragraphNode = elementNode;
|
|
808
|
-
const allCriteria = getAllMarkdownCriteria();
|
|
809
|
-
const count = allCriteria.length;
|
|
962
|
+
const nodes = [];
|
|
963
|
+
const splitLines = text.split('\n');
|
|
964
|
+
const splitLinesCount = splitLines.length;
|
|
810
965
|
|
|
811
|
-
|
|
812
|
-
|
|
966
|
+
for (let i = 0; i < splitLinesCount; i++) {
|
|
967
|
+
if (splitLines[i].length > 0) {
|
|
968
|
+
nodes.push(lexical.$createParagraphNode().append(lexical.$createTextNode(splitLines[i])));
|
|
969
|
+
} else {
|
|
970
|
+
nodes.push(lexical.$createParagraphNode());
|
|
971
|
+
}
|
|
972
|
+
}
|
|
813
973
|
|
|
814
|
-
|
|
815
|
-
|
|
974
|
+
if (nodes.length) {
|
|
975
|
+
const root = lexical.$getRoot();
|
|
976
|
+
root.clear();
|
|
977
|
+
root.append(...nodes);
|
|
978
|
+
return root;
|
|
979
|
+
}
|
|
816
980
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
981
|
+
return null;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
function convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode) {
|
|
985
|
+
const textContent = elementNode.getTextContent(); // Handle paragraph nodes below.
|
|
986
|
+
|
|
987
|
+
if (lexical.$isParagraphNode(elementNode)) {
|
|
988
|
+
const paragraphNode = elementNode;
|
|
989
|
+
const firstChild = paragraphNode.getFirstChild();
|
|
990
|
+
const firstChildIsTextNode = lexical.$isTextNode(firstChild); // Handle conversion to code block.
|
|
820
991
|
|
|
992
|
+
if (scanningContext.isWithinCodeBlock === true) {
|
|
993
|
+
if (firstChild != null && firstChildIsTextNode) {
|
|
994
|
+
// Test if we encounter ending code block.
|
|
821
995
|
scanningContext.textNodeWithOffset = {
|
|
822
996
|
node: firstChild,
|
|
823
997
|
offset: 0
|
|
824
998
|
};
|
|
825
|
-
|
|
826
|
-
const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
|
|
999
|
+
const patternMatchResults = getPatternMatchResultsForCodeBlock(scanningContext, textContent);
|
|
827
1000
|
|
|
828
1001
|
if (patternMatchResults != null) {
|
|
829
|
-
//
|
|
830
|
-
scanningContext.
|
|
831
|
-
|
|
1002
|
+
// Toggle transform to or from code block.
|
|
1003
|
+
scanningContext.patternMatchResults = patternMatchResults;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
scanningContext.markdownCriteria = getCodeBlockCriteria(); // Perform text transformation here.
|
|
1008
|
+
|
|
1009
|
+
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
if (elementNode.getChildren().length) {
|
|
1014
|
+
const allCriteria = getAllMarkdownCriteria();
|
|
1015
|
+
const count = allCriteria.length;
|
|
1016
|
+
|
|
1017
|
+
for (let i = 0; i < count; i++) {
|
|
1018
|
+
const criteria = allCriteria[i];
|
|
1019
|
+
|
|
1020
|
+
if (criteria.requiresParagraphStart === true) {
|
|
1021
|
+
if (!(firstChild != null && firstChildIsTextNode)) {
|
|
1022
|
+
throw Error(`Expect paragraph containing only text nodes.`);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
scanningContext.textNodeWithOffset = {
|
|
1026
|
+
node: firstChild,
|
|
1027
|
+
offset: 0
|
|
1028
|
+
};
|
|
1029
|
+
scanningContext.joinedText = paragraphNode.getTextContent();
|
|
1030
|
+
const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
|
|
1031
|
+
|
|
1032
|
+
if (patternMatchResults != null) {
|
|
1033
|
+
// Lazy fill-in the particular format criteria and any matching result information.
|
|
1034
|
+
scanningContext.markdownCriteria = criteria;
|
|
1035
|
+
scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
|
|
1036
|
+
|
|
1037
|
+
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
832
1040
|
}
|
|
833
1041
|
}
|
|
834
1042
|
}
|
|
835
1043
|
}
|
|
836
1044
|
}
|
|
837
1045
|
|
|
838
|
-
function convertMarkdownForElementNodes(
|
|
1046
|
+
function convertMarkdownForElementNodes(editor, createHorizontalRuleNode) {
|
|
839
1047
|
// Please see the declaration of ScanningContext for a detailed explanation.
|
|
840
1048
|
const scanningContext = getInitialScanningContext(editor, false, null, null);
|
|
841
|
-
const
|
|
1049
|
+
const root = lexical.$getRoot();
|
|
1050
|
+
let done = false;
|
|
1051
|
+
let startIndex = 0;
|
|
842
1052
|
|
|
843
|
-
|
|
844
|
-
|
|
1053
|
+
while (!done) {
|
|
1054
|
+
done = true;
|
|
1055
|
+
const elementNodes = root.getChildren();
|
|
1056
|
+
const countOfElementNodes = elementNodes.length;
|
|
845
1057
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
} // Reset the scanning information that relates to the particular element node.
|
|
1058
|
+
for (let i = startIndex; i < countOfElementNodes; i++) {
|
|
1059
|
+
const elementNode = elementNodes[i];
|
|
849
1060
|
|
|
1061
|
+
if (lexical.$isElementNode(elementNode)) {
|
|
1062
|
+
convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode);
|
|
1063
|
+
} // Reset the scanning information that relates to the particular element node.
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
resetScanningContext(scanningContext);
|
|
1067
|
+
|
|
1068
|
+
if (root.getChildren().length !== countOfElementNodes) {
|
|
1069
|
+
// The conversion added or removed an from root's children.
|
|
1070
|
+
startIndex = i;
|
|
1071
|
+
done = false;
|
|
1072
|
+
break;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
} // while
|
|
850
1076
|
|
|
851
|
-
resetScanningContext(scanningContext);
|
|
852
|
-
}
|
|
853
1077
|
}
|
|
854
1078
|
|
|
855
1079
|
/**
|
|
@@ -885,8 +1109,9 @@ function registerMarkdownShortcuts(editor, createHorizontalRuleNode) {
|
|
|
885
1109
|
});
|
|
886
1110
|
}
|
|
887
1111
|
function $convertFromMarkdownString(markdownString, editor, createHorizontalRuleNode) {
|
|
888
|
-
convertStringToLexical(markdownString)
|
|
889
|
-
|
|
1112
|
+
if (convertStringToLexical(markdownString) != null) {
|
|
1113
|
+
convertMarkdownForElementNodes(editor, createHorizontalRuleNode);
|
|
1114
|
+
}
|
|
890
1115
|
}
|
|
891
1116
|
|
|
892
1117
|
exports.$convertFromMarkdownString = $convertFromMarkdownString;
|
package/LexicalMarkdown.prod.js
CHANGED
|
@@ -4,26 +4,33 @@
|
|
|
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
|
|
8
|
-
const x=[{triggerKind:"space_trigger",triggerString:" "}],y={
|
|
9
|
-
regEx:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)/,regExForAutoFormatting:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/},{...y,
|
|
10
|
-
{...y,
|
|
11
|
-
|
|
12
|
-
regEx:/^(
|
|
13
|
-
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
function
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
c.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
function
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
7
|
+
var k=require("@lexical/code"),m=require("@lexical/list"),p=require("lexical"),t=require("@lexical/link"),u=require("@lexical/rich-text"),v=require("@lexical/text");function w(b){throw Error(`Minified Lexical error #${b}; 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:"paragraphH2",regEx:/^(?:### )/,regExForAutoFormatting:/^(?:### )/},{...A,markdownFormatKind:"paragraphBlockQuote",regEx:/^(?:> )/,regExForAutoFormatting:/^(?:> )/},{...A,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})(?:- )/,regExForAutoFormatting:/^(\s{0,10})(?:- )/},{...A,markdownFormatKind:"paragraphUnorderedList",
|
|
13
|
+
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:/^(?:\*\*\* )/},{...A,markdownFormatKind:"horizontalRule",regEx:/^(?:---)$/,regExForAutoFormatting:/^(?:--- )/},...C];
|
|
14
|
+
function E(b,d,e,a){return{currentElementNode:null,editor:b,isAutoFormatting:d,isWithinCodeBlock:!1,joinedText:null,markdownCriteria:{markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null},patternMatchResults:{regExCaptureGroups:[]},textNodeWithOffset:e,triggerState:a}}
|
|
15
|
+
function F(b,d,e,a){const c={regExCaptureGroups:[]};a=b.match(a);if(null!==a&&0<a.length&&(!1===d||0===a.index)&&(!1===e||a.index+a[0].length===b.length)){b=a.length;d=a.index;for(e=0;e<b;e++){const f=a[e];c.regExCaptureGroups.push({offsetInParent:d,text:f});0<e&&(d+=f.length)}return c}return null}function I(b){b=b.textNodeWithOffset;null==b&&w(82);return b}
|
|
16
|
+
function J(b,d){var e=I(d);return null===e.node.getPreviousSibling()?(e=e.node.getTextContent(),F(e,!0,!1,d.isAutoFormatting?b.regExForAutoFormatting:b.regEx)):null}
|
|
17
|
+
function K(b,d,e){var a=null,c=d.getChildren();const f=b.markdownCriteria,g=b.patternMatchResults;if(null!=f.markdownFormatKind)switch(f.markdownFormatKind){case "paragraphH1":a=u.$createHeadingNode("h1");a.append(...c);break;case "paragraphH2":a=u.$createHeadingNode("h2");a.append(...c);break;case "paragraphH3":a=u.$createHeadingNode("h3");a.append(...c);break;case "paragraphBlockQuote":a=u.$createQuoteNode();a.append(...c);break;case "paragraphUnorderedList":return L(d,c,g,"ul"),{newNode:null,shouldDelete:!1};
|
|
18
|
+
case "paragraphOrderedList":return a=1<g.regExCaptureGroups.length?g.regExCaptureGroups[g.regExCaptureGroups.length-1].text:"1",b=b.isAutoFormatting?parseInt(a,10):void 0,L(d,c,g,"ol",b),{newNode:null,shouldDelete:!1};case "paragraphCodeBlock":if(!1===b.isAutoFormatting){if(0<b.patternMatchResults.regExCaptureGroups.length)return b.isWithinCodeBlock=!0!==b.isWithinCodeBlock,b.currentElementNode=null,{newNode:null,shouldDelete:!0};if(b.isWithinCodeBlock){if(null==b.currentElementNode)return d=k.$createCodeNode(),
|
|
19
|
+
d.append(...c),b.currentElementNode=d,{newNode:d,shouldDelete:!1};null!=b.currentElementNode&&(d=b.currentElementNode,b=p.$createLineBreakNode(),d.append(b),c.length&&d.append(b),d.append(...c))}return{newNode:null,shouldDelete:!0}}null!=b.triggerState&&b.triggerState.isCodeBlock?a=p.$createParagraphNode():(a=k.$createCodeNode(),d=3<=g.regExCaptureGroups.length?g.regExCaptureGroups[2].text:null,null!=d&&0<d.length&&a.setLanguage(d));a.append(...c);break;case "horizontalRule":null!=e&&(c=e(),d.insertBefore(c))}return{newNode:a,
|
|
20
|
+
shouldDelete:!1}}function L(b,d,e,a,c){const f=m.$createListItemNode();e=(e=e.regExCaptureGroups[0].text.match(/^\s*/))?Math.floor(e[0].length/4):0;f.append(...d);d=b.getPreviousSibling();m.$isListNode(d)&&d.getTag()===a?(d.append(f),b.remove()):(a=m.$createListNode(a,c),a.append(f),b.replace(a));e&&f.setIndent(e)}
|
|
21
|
+
function M(b,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:c,shouldDelete:f}=K(d,b,e);f?b.remove():null!==c&&b.replace(c)}
|
|
22
|
+
function N(b){switch(b){case "italic":case "bold":case "underline":case "strikethrough":case "code":return[b];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}
|
|
23
|
+
function Q(b,d,e,a,c){var f=c.patternMatchResults;const g=f.regExCaptureGroups;var h=g.length;if(b>=h||d>=h)return null;c=I(c).node.getParentOrThrow();h=f.regExCaptureGroups.length;2>h?f=0:(--h,f=f.regExCaptureGroups[h].offsetInParent+f.regExCaptureGroups[h].text.length);b=g[b];d=g[d];a=a?d.offsetInParent+d.text.length:d.offsetInParent;e=v.$findNodeWithOffsetFromJoinedText(e?b.offsetInParent+b.text.length:b.offsetInParent,f,1,c);a=v.$findNodeWithOffsetFromJoinedText(a,f,1,c);if(null==e||null==a)return null;
|
|
24
|
+
c=p.$createRangeSelection();c.anchor.set(e.node.getKey(),e.offset,"text");c.focus.set(a.node.getKey(),a.offset,"text");return c}function R(b,d,e){const a=e.patternMatchResults.regExCaptureGroups;e=Q(b,d,!1,!0,e);if(null!=e&&(p.$setSelection(e),e=p.$getSelection(),null!=e&&p.$isRangeSelection(e)&&!1===e.isCollapsed())){e.removeText();e=0;const c=a.length;for(let f=b;f<c;f++){const g=a[f];f>b&&(g.offsetInParent-=e);f<=d&&(e+=g.text.length,g.text="")}}}
|
|
25
|
+
function S(b){var d=b.patternMatchResults.regExCaptureGroups.length;2>d||(--d,b=Q(d,d,!0,!0,b),null!=b&&p.$setSelection(b))}
|
|
26
|
+
function T(b,d,e){b.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 c=N(a.markdownFormatKind);if(null!=c){if(a=c,7===d.patternMatchResults.regExCaptureGroups.length){R(5,5,d);R(1,1,d);c=d.patternMatchResults.regExCaptureGroups;3<c.length||w(65);if(0!==c[3].text.length&&(c=Q(3,3,!1,!0,d),null!=c&&(p.$setSelection(c),c=p.$getSelection(),p.$isRangeSelection(c))))for(var f=0;f<a.length;f++)c.formatText(a[f]);
|
|
27
|
+
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);c=d.patternMatchResults.regExCaptureGroups;if(!(1>=c.length)){f={offsetInParent:c[1].offsetInParent,text:f};var g=Q(1,1,!1,!1,d);if(null!=g&&(p.$setSelection(g),g=p.$getSelection(),null!=g&&p.$isRangeSelection(g)&&g.isCollapsed())){g.insertText(f.text);c.splice(1,0,f);f=f.text.length;g=c.length;for(let h=2;h<g;h++)c[h].offsetInParent+=
|
|
28
|
+
f}}c=Q(1,1,!1,!0,d);null!=c&&(p.$setSelection(c),d.editor.dispatchCommand(t.TOGGLE_LINK_COMMAND,a),S(d))}}},{tag:"history-push"})}
|
|
29
|
+
function U(b,d){let e=null;b.getEditorState().read(()=>{var a=p.$getSelection();if(p.$isRangeSelection(a)){var c=a.anchor.getNode();a=p.$isTextNode(c)?{node:c,offset:a.anchor.offset}:null}else a=null;if(null!==a){a=E(b,!0,a,d);a:{c=!1===d.isParentAListItemNode?D:C;const h=a.triggerState,r=c.length;for(let n=0;n<r;n++){const l=c[n];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();
|
|
30
|
+
p.$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){c={markdownCriteria:l,patternMatchResults:f};break a}}}c={markdownCriteria:null,patternMatchResults:null}}null!==c.markdownCriteria&&null!==c.patternMatchResults&&(e=a,e.markdownCriteria=c.markdownCriteria,e.patternMatchResults=c.patternMatchResults)}});return e}
|
|
31
|
+
function V(b){let d=null;b.read(()=>{const e=p.$getSelection();if(p.$isRangeSelection(e)&&e.isCollapsed()){var a=e.anchor.getNode(),c=a.getParent(),f=m.$isListItemNode(c);d={anchorOffset:e.anchor.offset,hasParentNode:null!==c,isCodeBlock:k.$isCodeNode(a),isParentAListItemNode:f,isSelectionCollapsed:!0,isSimpleText:p.$isTextNode(a)&&a.isSimpleText(),nodeKey:a.getKey(),textContent:a.getTextContent()}}});return d}
|
|
32
|
+
exports.$convertFromMarkdownString=function(b,d,e){if(b.length){var a=[];b=b.split("\n");var c=b.length;for(var f=0;f<c;f++)0<b[f].length?a.push(p.$createParagraphNode().append(p.$createTextNode(b[f]))):a.push(p.$createParagraphNode());a.length?(b=p.$getRoot(),b.clear(),b.append(...a),a=b):a=null}else a=null;if(null!=a)for(d=E(d,!1,null,null),a=p.$getRoot(),b=!1,c=0;!b;){b=!0;f=a.getChildren();const q=f.length;for(let z=c;z<q;z++){var g=f[z];if(p.$isElementNode(g)){var h=d,r=e,n=g.getTextContent();
|
|
33
|
+
if(p.$isParagraphNode(g)){var l=g.getFirstChild();const O=p.$isTextNode(l);if(!0===h.isWithinCodeBlock)null!=l&&O&&(h.textNodeWithOffset={node:l,offset:0},l=F(n,!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){n=D.length;for(let G=0;G<n;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);
|
|
34
|
+
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){c=z;b=!1;break}}}};
|
|
35
|
+
exports.registerMarkdownShortcuts=function(b,d){let e=null;return b.registerUpdateListener(({tags:a})=>{if(!1===a.has("historic")){a=V(b.getEditorState());if(null==a)var c=null;else a:{c=a;var f=e;if(null==c||null==f)c=null;else{var g=x.length;for(let h=0;h<g;h++){const r=x[h].triggerString,n=r.length,l=c.textContent.length,q=c.anchorOffset-n;if(!1===(!0===c.hasParentNode&&c.isSimpleText&&c.isSelectionCollapsed&&c.anchorOffset!==f.anchorOffset&&0<=q&&q+n<=l&&c.textContent.substr(q,n)===r&&c.textContent!==
|
|
36
|
+
f.textContent)){c=null;break a}}c=U(b,c)}}null!=c&&T(b,c,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.
|
|
11
|
+
"version": "0.2.0",
|
|
12
12
|
"main": "LexicalMarkdown.js",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"lexical": "0.
|
|
14
|
+
"lexical": "0.2.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lexical/utils": "0.
|
|
18
|
-
"@lexical/code": "0.
|
|
19
|
-
"@lexical/text": "0.
|
|
20
|
-
"@lexical/rich-text": "0.
|
|
21
|
-
"@lexical/list": "0.
|
|
22
|
-
"@lexical/link": "0.
|
|
17
|
+
"@lexical/utils": "0.2.0",
|
|
18
|
+
"@lexical/code": "0.2.0",
|
|
19
|
+
"@lexical/text": "0.2.0",
|
|
20
|
+
"@lexical/rich-text": "0.2.0",
|
|
21
|
+
"@lexical/list": "0.2.0",
|
|
22
|
+
"@lexical/link": "0.2.0"
|
|
23
23
|
},
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|