@lexical/markdown 0.50.1-nightly.20260916.0 → 0.51.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/dist/utils.d.ts CHANGED
@@ -6,21 +6,7 @@
6
6
  *
7
7
  */
8
8
  import type { ElementTransformer, MultilineElementTransformer, TextFormatTransformer, TextMatchTransformer, Transformer } from './MarkdownTransformers.js';
9
- import { type ElementNode, type LexicalNode, type TextFormatType } from 'lexical';
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
- type MarkdownCriteria = Readonly<{
12
- export?: (node: LexicalNode, traverseChildren: (elementNode: ElementNode) => string) => string | null;
13
- exportFormat?: TextFormatType;
14
- exportTag?: string;
15
- exportTagClose?: string;
16
- markdownFormatKind: MarkdownFormatKind | null | undefined;
17
- regEx: RegExp;
18
- regExForAutoFormatting: RegExp;
19
- requiresParagraphStart: boolean | null | undefined;
20
- }>;
21
- type MarkdownCriteriaArray = MarkdownCriteria[];
22
- export declare function getAllMarkdownCriteriaForParagraphs(): MarkdownCriteriaArray;
23
- export declare function getAllMarkdownCriteriaForTextNodes(): MarkdownCriteriaArray;
9
+ import { type LexicalNode } from 'lexical';
24
10
  export declare function indexBy<T>(list: T[], callback: (arg0: T) => string | undefined): Readonly<Record<string, T[]>>;
25
11
  export declare function transformersByType(transformers: Transformer[]): Readonly<{
26
12
  element: ElementTransformer[];
@@ -33,4 +19,3 @@ export declare const WHITESPACE: RegExp;
33
19
  export declare const PUNCTUATION: RegExp;
34
20
  export declare function isEmptyParagraph(node: LexicalNode): boolean;
35
21
  export declare function unescapeText(value: string): string;
36
- export {};
package/package.json CHANGED
@@ -8,19 +8,19 @@
8
8
  "markdown"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.50.1-nightly.20260916.0",
11
+ "version": "0.51.0",
12
12
  "main": "./dist/LexicalMarkdown.js",
13
13
  "types": "./dist/typescript-too-old.d.ts",
14
14
  "dependencies": {
15
- "@lexical/code-core": "0.50.1-nightly.20260916.0",
16
- "@lexical/internal": "0.50.1-nightly.20260916.0",
17
- "@lexical/link": "0.50.1-nightly.20260916.0",
18
- "@lexical/list": "0.50.1-nightly.20260916.0",
19
- "@lexical/rich-text": "0.50.1-nightly.20260916.0",
20
- "@lexical/selection": "0.50.1-nightly.20260916.0",
21
- "@lexical/text": "0.50.1-nightly.20260916.0",
22
- "@lexical/utils": "0.50.1-nightly.20260916.0",
23
- "lexical": "0.50.1-nightly.20260916.0"
15
+ "@lexical/code-core": "0.51.0",
16
+ "@lexical/internal": "0.51.0",
17
+ "@lexical/link": "0.51.0",
18
+ "@lexical/list": "0.51.0",
19
+ "@lexical/rich-text": "0.51.0",
20
+ "@lexical/selection": "0.51.0",
21
+ "@lexical/text": "0.51.0",
22
+ "@lexical/utils": "0.51.0",
23
+ "lexical": "0.51.0"
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
package/src/utils.ts CHANGED
@@ -14,392 +14,7 @@ import type {
14
14
  Transformer,
15
15
  } from './MarkdownTransformers';
16
16
 
17
- import {$isCodeNode} from '@lexical/code-core';
18
- import {$isListItemNode, $isListNode, type ListNode} from '@lexical/list';
19
- import {$isHeadingNode, $isQuoteNode} from '@lexical/rich-text';
20
- import {
21
- $isParagraphNode,
22
- $isTextNode,
23
- type ElementNode,
24
- type LexicalNode,
25
- type TextFormatType,
26
- } from 'lexical';
27
-
28
- type MarkdownFormatKind =
29
- | 'noTransformation'
30
- | 'paragraphH1'
31
- | 'paragraphH2'
32
- | 'paragraphH3'
33
- | 'paragraphH4'
34
- | 'paragraphH5'
35
- | 'paragraphH6'
36
- | 'paragraphBlockQuote'
37
- | 'paragraphUnorderedList'
38
- | 'paragraphOrderedList'
39
- | 'paragraphCodeBlock'
40
- | 'horizontalRule'
41
- | 'bold'
42
- | 'code'
43
- | 'italic'
44
- | 'underline'
45
- | 'strikethrough'
46
- | 'italic_bold'
47
- | 'strikethrough_italic'
48
- | 'strikethrough_bold'
49
- | 'strikethrough_italic_bold'
50
- | 'link';
51
-
52
- type MarkdownCriteria = Readonly<{
53
- export?: (
54
- node: LexicalNode,
55
- traverseChildren: (elementNode: ElementNode) => string,
56
- ) => string | null;
57
- exportFormat?: TextFormatType;
58
- exportTag?: string;
59
- exportTagClose?: string;
60
- markdownFormatKind: MarkdownFormatKind | null | undefined;
61
- regEx: RegExp;
62
- regExForAutoFormatting: RegExp;
63
- requiresParagraphStart: boolean | null | undefined;
64
- }>;
65
-
66
- type MarkdownCriteriaArray = MarkdownCriteria[];
67
-
68
- const autoFormatBase: MarkdownCriteria = {
69
- markdownFormatKind: null,
70
- regEx: /(?:)/,
71
- regExForAutoFormatting: /(?:)/,
72
- requiresParagraphStart: false,
73
- };
74
-
75
- const paragraphStartBase: MarkdownCriteria = {
76
- ...autoFormatBase,
77
- requiresParagraphStart: true,
78
- };
79
-
80
- const markdownHeader1: MarkdownCriteria = {
81
- ...paragraphStartBase,
82
- export: createHeadingExport(1),
83
- markdownFormatKind: 'paragraphH1',
84
- regEx: /^(?:# )/,
85
- regExForAutoFormatting: /^(?:# )/,
86
- };
87
-
88
- const markdownHeader2: MarkdownCriteria = {
89
- ...paragraphStartBase,
90
- export: createHeadingExport(2),
91
- markdownFormatKind: 'paragraphH2',
92
- regEx: /^(?:## )/,
93
- regExForAutoFormatting: /^(?:## )/,
94
- };
95
-
96
- const markdownHeader3: MarkdownCriteria = {
97
- ...paragraphStartBase,
98
- export: createHeadingExport(3),
99
- markdownFormatKind: 'paragraphH3',
100
- regEx: /^(?:### )/,
101
- regExForAutoFormatting: /^(?:### )/,
102
- };
103
-
104
- const markdownHeader4: MarkdownCriteria = {
105
- ...paragraphStartBase,
106
- export: createHeadingExport(4),
107
- markdownFormatKind: 'paragraphH4',
108
- regEx: /^(?:#### )/,
109
- regExForAutoFormatting: /^(?:#### )/,
110
- };
111
-
112
- const markdownHeader5: MarkdownCriteria = {
113
- ...paragraphStartBase,
114
- export: createHeadingExport(5),
115
- markdownFormatKind: 'paragraphH5',
116
- regEx: /^(?:##### )/,
117
- regExForAutoFormatting: /^(?:##### )/,
118
- };
119
-
120
- const markdownHeader6: MarkdownCriteria = {
121
- ...paragraphStartBase,
122
- export: createHeadingExport(6),
123
- markdownFormatKind: 'paragraphH6',
124
- regEx: /^(?:###### )/,
125
- regExForAutoFormatting: /^(?:###### )/,
126
- };
127
-
128
- const markdownBlockQuote: MarkdownCriteria = {
129
- ...paragraphStartBase,
130
- export: blockQuoteExport,
131
- markdownFormatKind: 'paragraphBlockQuote',
132
- regEx: /^(?:> )/,
133
- regExForAutoFormatting: /^(?:> )/,
134
- };
135
-
136
- const markdownUnorderedListDash: MarkdownCriteria = {
137
- ...paragraphStartBase,
138
- export: listExport,
139
- markdownFormatKind: 'paragraphUnorderedList',
140
- regEx: /^(\s{0,10})(?:- )/,
141
- regExForAutoFormatting: /^(\s{0,10})(?:- )/,
142
- };
143
-
144
- const markdownUnorderedListAsterisk: MarkdownCriteria = {
145
- ...paragraphStartBase,
146
- export: listExport,
147
- markdownFormatKind: 'paragraphUnorderedList',
148
- regEx: /^(\s{0,10})(?:\* )/,
149
- regExForAutoFormatting: /^(\s{0,10})(?:\* )/,
150
- };
151
-
152
- const markdownCodeBlock: MarkdownCriteria = {
153
- ...paragraphStartBase,
154
- export: codeBlockExport,
155
- markdownFormatKind: 'paragraphCodeBlock',
156
- regEx: /^(```)$/,
157
- regExForAutoFormatting: /^(```)([a-z]*)( )/,
158
- };
159
-
160
- const markdownOrderedList: MarkdownCriteria = {
161
- ...paragraphStartBase,
162
- export: listExport,
163
- markdownFormatKind: 'paragraphOrderedList',
164
- regEx: /^(\s{0,10})(\d+)\.\s/,
165
- regExForAutoFormatting: /^(\s{0,10})(\d+)\.\s/,
166
- };
167
-
168
- const markdownHorizontalRule: MarkdownCriteria = {
169
- ...paragraphStartBase,
170
- markdownFormatKind: 'horizontalRule',
171
- regEx: /^(?:\*\*\*)$/,
172
- regExForAutoFormatting: /^(?:\*\*\* )/,
173
- };
174
-
175
- const markdownHorizontalRuleUsingDashes: MarkdownCriteria = {
176
- ...paragraphStartBase,
177
- markdownFormatKind: 'horizontalRule',
178
- regEx: /^(?:---)$/,
179
- regExForAutoFormatting: /^(?:--- )/,
180
- };
181
-
182
- const markdownInlineCode: MarkdownCriteria = {
183
- ...autoFormatBase,
184
- exportFormat: 'code',
185
- exportTag: '`',
186
- markdownFormatKind: 'code',
187
- regEx: /(`)(\s*)([^`]*)(\s*)(`)()/,
188
- regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/,
189
- };
190
-
191
- const markdownBold: MarkdownCriteria = {
192
- ...autoFormatBase,
193
- exportFormat: 'bold',
194
- exportTag: '**',
195
- markdownFormatKind: 'bold',
196
- regEx: /(\*\*)(\s*)([^**]*)(\s*)(\*\*)()/,
197
- regExForAutoFormatting: /(\*\*)(\s*\b)([^**]*)(\b\s*)(\*\*)(\s)$/,
198
- };
199
-
200
- const markdownItalic: MarkdownCriteria = {
201
- ...autoFormatBase,
202
- exportFormat: 'italic',
203
- exportTag: '*',
204
- markdownFormatKind: 'italic',
205
- regEx: /(\*)(\s*)([^*]*)(\s*)(\*)()/,
206
- regExForAutoFormatting: /(\*)(\s*\b)([^*]*)(\b\s*)(\*)(\s)$/,
207
- };
208
-
209
- const markdownBold2: MarkdownCriteria = {
210
- ...autoFormatBase,
211
- exportFormat: 'bold',
212
- exportTag: '_',
213
- markdownFormatKind: 'bold',
214
- regEx: /(__)(\s*)([^__]*)(\s*)(__)()/,
215
- regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/,
216
- };
217
-
218
- const markdownItalic2: MarkdownCriteria = {
219
- ...autoFormatBase,
220
- exportFormat: 'italic',
221
- exportTag: '_',
222
- markdownFormatKind: 'italic',
223
- regEx: /(_)()([^_]*)()(_)()/,
224
- regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/, // Maintain 7 groups.
225
- };
226
-
227
- const fakeMarkdownUnderline: MarkdownCriteria = {
228
- ...autoFormatBase,
229
- exportFormat: 'underline',
230
- exportTag: '<u>',
231
- exportTagClose: '</u>',
232
- markdownFormatKind: 'underline',
233
- regEx: /(<u>)(\s*)([^<]*)(\s*)(<\/u>)()/,
234
- regExForAutoFormatting: /(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/,
235
- };
236
-
237
- const markdownStrikethrough: MarkdownCriteria = {
238
- ...autoFormatBase,
239
- exportFormat: 'strikethrough',
240
- exportTag: '~~',
241
- markdownFormatKind: 'strikethrough',
242
- regEx: /(~~)(\s*)([^~~]*)(\s*)(~~)()/,
243
- regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/,
244
- };
245
-
246
- const markdownStrikethroughItalicBold: MarkdownCriteria = {
247
- ...autoFormatBase,
248
- markdownFormatKind: 'strikethrough_italic_bold',
249
- regEx: /(~~_\*\*)(\s*\b)([^~~_**][^**_~~]*)(\b\s*)(\*\*_~~)()/,
250
- regExForAutoFormatting:
251
- /(~~_\*\*)(\s*\b)([^~~_**][^**_~~]*)(\b\s*)(\*\*_~~)(\s)$/,
252
- };
253
-
254
- const markdownItalicbold: MarkdownCriteria = {
255
- ...autoFormatBase,
256
- markdownFormatKind: 'italic_bold',
257
- regEx: /(_\*\*)(\s*\b)([^_**][^**_]*)(\b\s*)(\*\*_)/,
258
- regExForAutoFormatting: /(_\*\*)(\s*\b)([^_**][^**_]*)(\b\s*)(\*\*_)(\s)$/,
259
- };
260
-
261
- const markdownStrikethroughItalic: MarkdownCriteria = {
262
- ...autoFormatBase,
263
- markdownFormatKind: 'strikethrough_italic',
264
- regEx: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,
265
- regExForAutoFormatting: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/,
266
- };
267
-
268
- const markdownStrikethroughBold: MarkdownCriteria = {
269
- ...autoFormatBase,
270
- markdownFormatKind: 'strikethrough_bold',
271
- regEx: /(~~\*\*)(\s*\b)([^~~**][^**~~]*)(\b\s*)(\*\*~~)/,
272
- regExForAutoFormatting:
273
- /(~~\*\*)(\s*\b)([^~~**][^**~~]*)(\b\s*)(\*\*~~)(\s)$/,
274
- };
275
-
276
- const markdownLink: MarkdownCriteria = {
277
- ...autoFormatBase,
278
- markdownFormatKind: 'link',
279
- regEx: /(\[)([^\]]*)(\]\()([^)]*)(\)*)()/,
280
- regExForAutoFormatting: /(\[)([^\]]*)(\]\()([^)]*)(\)*)(\s)$/,
281
- };
282
-
283
- const allMarkdownCriteriaForTextNodes: MarkdownCriteriaArray = [
284
- // Place the combination formats ahead of the individual formats.
285
- // Combos
286
- markdownStrikethroughItalicBold,
287
- markdownItalicbold,
288
- markdownStrikethroughItalic,
289
- markdownStrikethroughBold, // Individuals
290
- markdownInlineCode,
291
- markdownBold,
292
- markdownItalic, // Must appear after markdownBold
293
- markdownBold2,
294
- markdownItalic2, // Must appear after markdownBold2.
295
- fakeMarkdownUnderline,
296
- markdownStrikethrough,
297
- markdownLink,
298
- ];
299
-
300
- const allMarkdownCriteriaForParagraphs: MarkdownCriteriaArray = [
301
- markdownHeader1,
302
- markdownHeader2,
303
- markdownHeader3,
304
- markdownHeader4,
305
- markdownHeader5,
306
- markdownHeader6,
307
- markdownBlockQuote,
308
- markdownUnorderedListDash,
309
- markdownUnorderedListAsterisk,
310
- markdownOrderedList,
311
- markdownCodeBlock,
312
- markdownHorizontalRule,
313
- markdownHorizontalRuleUsingDashes,
314
- ];
315
-
316
- export function getAllMarkdownCriteriaForParagraphs(): MarkdownCriteriaArray {
317
- return allMarkdownCriteriaForParagraphs;
318
- }
319
-
320
- export function getAllMarkdownCriteriaForTextNodes(): MarkdownCriteriaArray {
321
- return allMarkdownCriteriaForTextNodes;
322
- }
323
-
324
- type Block = (
325
- node: LexicalNode,
326
- exportChildren: (elementNode: ElementNode) => string,
327
- ) => string | null;
328
-
329
- function createHeadingExport(level: number): Block {
330
- return (node, exportChildren) => {
331
- return $isHeadingNode(node) && node.getTag() === 'h' + level
332
- ? '#'.repeat(level) + ' ' + exportChildren(node)
333
- : null;
334
- };
335
- }
336
-
337
- function listExport(
338
- node: LexicalNode,
339
- exportChildren: (_node: ElementNode) => string,
340
- ) {
341
- return $isListNode(node) ? processNestedLists(node, exportChildren, 0) : null;
342
- }
343
-
344
- // TODO: should be param
345
- const LIST_INDENT_SIZE = 4;
346
-
347
- function processNestedLists(
348
- listNode: ListNode,
349
- exportChildren: (node: ElementNode) => string,
350
- depth: number,
351
- ): string {
352
- const output = [];
353
- const children = listNode.getChildren();
354
- let index = 0;
355
-
356
- for (const listItemNode of children) {
357
- if ($isListItemNode(listItemNode)) {
358
- if (listItemNode.getChildrenSize() === 1) {
359
- const firstChild = listItemNode.getFirstChild();
360
-
361
- if ($isListNode(firstChild)) {
362
- output.push(
363
- processNestedLists(firstChild, exportChildren, depth + 1),
364
- );
365
- continue;
366
- }
367
- }
368
-
369
- const indent = ' '.repeat(depth * LIST_INDENT_SIZE);
370
- const prefix =
371
- listNode.getListType() === 'bullet'
372
- ? '- '
373
- : `${listNode.getStart() + index}. `;
374
- output.push(indent + prefix + exportChildren(listItemNode));
375
- index++;
376
- }
377
- }
378
-
379
- return output.join('\n');
380
- }
381
-
382
- function blockQuoteExport(
383
- node: LexicalNode,
384
- exportChildren: (_node: ElementNode) => string,
385
- ) {
386
- return $isQuoteNode(node) ? '> ' + exportChildren(node) : null;
387
- }
388
-
389
- function codeBlockExport(node: LexicalNode) {
390
- if (!$isCodeNode(node)) {
391
- return null;
392
- }
393
-
394
- const textContent = node.getTextContent();
395
- return (
396
- '```' +
397
- (node.getLanguage() || '') +
398
- (textContent ? '\n' + textContent : '') +
399
- '\n' +
400
- '```'
401
- );
402
- }
17
+ import {$isParagraphNode, $isTextNode, type LexicalNode} from 'lexical';
403
18
 
404
19
  export function indexBy<T>(
405
20
  list: T[],