@lexical/markdown 0.3.4 → 0.3.7

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.
@@ -8,9 +8,10 @@
8
8
 
9
9
  var lexical = require('lexical');
10
10
  var code = require('@lexical/code');
11
- var link = require('@lexical/link');
12
11
  var list = require('@lexical/list');
13
12
  var richText = require('@lexical/rich-text');
13
+ var utils = require('@lexical/utils');
14
+ var link = require('@lexical/link');
14
15
 
15
16
  /**
16
17
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -68,7 +69,7 @@ function createMarkdownExport(transformers) {
68
69
  }
69
70
  }
70
71
 
71
- return output.join('\n');
72
+ return output.join('\n\n');
72
73
  };
73
74
  }
74
75
 
@@ -89,23 +90,21 @@ function exportChildren(node, textTransformersIndex, textMatchTransformers) {
89
90
  const children = node.getChildren();
90
91
 
91
92
  mainLoop: for (const child of children) {
93
+ for (const transformer of textMatchTransformers) {
94
+ const result = transformer.export(child, parentNode => exportChildren(parentNode, textTransformersIndex, textMatchTransformers), (textNode, textContent) => exportTextFormat(textNode, textContent, textTransformersIndex));
95
+
96
+ if (result != null) {
97
+ output.push(result);
98
+ continue mainLoop;
99
+ }
100
+ }
101
+
92
102
  if (lexical.$isLineBreakNode(child)) {
93
103
  output.push('\n');
94
104
  } else if (lexical.$isTextNode(child)) {
95
105
  output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex));
96
- } else {
97
- for (const transformer of textMatchTransformers) {
98
- const result = transformer.export(child, parentNode => exportChildren(parentNode, textTransformersIndex, textMatchTransformers), (textNode, textContent) => exportTextFormat(textNode, textContent, textTransformersIndex));
99
-
100
- if (result != null) {
101
- output.push(result);
102
- continue mainLoop;
103
- }
104
- }
105
-
106
- if (lexical.$isElementNode(child)) {
107
- output.push(exportChildren(child, textTransformersIndex, textMatchTransformers));
108
- }
106
+ } else if (lexical.$isElementNode(child)) {
107
+ output.push(exportChildren(child, textTransformersIndex, textMatchTransformers));
109
108
  }
110
109
  }
111
110
 
@@ -199,6 +198,7 @@ function hasFormat(node, format) {
199
198
  * LICENSE file in the root directory of this source tree.
200
199
  *
201
200
  */
201
+ const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/;
202
202
  const CODE_BLOCK_REG_EXP = /^```(\w{1,10})?\s?$/;
203
203
  function createMarkdownImport(transformers) {
204
204
  const byType = transformersByType(transformers);
@@ -223,6 +223,16 @@ function createMarkdownImport(transformers) {
223
223
  }
224
224
 
225
225
  importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch);
226
+ } // Removing empty paragraphs as md does not really
227
+ // allow empty lines and uses them as dilimiter
228
+
229
+
230
+ const children = root.getChildren();
231
+
232
+ for (const child of children) {
233
+ if (lexical.$isParagraphNode(child) && MARKDOWN_EMPTY_LINE_REG_EXP.test(child.getTextContent())) {
234
+ child.remove();
235
+ }
226
236
  }
227
237
 
228
238
  root.selectEnd();
@@ -230,7 +240,8 @@ function createMarkdownImport(transformers) {
230
240
  }
231
241
 
232
242
  function importBlocks(lineText, rootNode, elementTransformers, textFormatTransformersIndex, textMatchTransformers) {
233
- const textNode = lexical.$createTextNode(lineText);
243
+ const lineTextTrimmed = lineText.trim();
244
+ const textNode = lexical.$createTextNode(lineTextTrimmed);
234
245
  const elementNode = lexical.$createParagraphNode();
235
246
  elementNode.append(textNode);
236
247
  rootNode.append(elementNode);
@@ -248,7 +259,32 @@ function importBlocks(lineText, rootNode, elementTransformers, textFormatTransfo
248
259
  }
249
260
  }
250
261
 
251
- importTextFormatTransformers(textNode, textFormatTransformersIndex, textMatchTransformers);
262
+ importTextFormatTransformers(textNode, textFormatTransformersIndex, textMatchTransformers); // If no transformer found and we left with original paragraph node
263
+ // can check if its content can be appended to the previous node
264
+ // if it's a paragraph, quote or list
265
+
266
+ if (elementNode.isAttached() && lineTextTrimmed.length > 0) {
267
+ const previousNode = elementNode.getPreviousSibling();
268
+
269
+ if (lexical.$isParagraphNode(previousNode) || richText.$isQuoteNode(previousNode) || list.$isListNode(previousNode)) {
270
+ let targetNode = previousNode;
271
+
272
+ if (list.$isListNode(previousNode)) {
273
+ const lastDescendant = previousNode.getLastDescendant();
274
+
275
+ if (lastDescendant == null) {
276
+ targetNode = null;
277
+ } else {
278
+ targetNode = utils.$findMatchingParent(lastDescendant, list.$isListItemNode);
279
+ }
280
+ }
281
+
282
+ if (targetNode != null && targetNode.getTextContentSize() > 0) {
283
+ targetNode.splice(targetNode.getChildrenSize(), 0, [lexical.$createLineBreakNode(), ...elementNode.getChildren()]);
284
+ elementNode.remove();
285
+ }
286
+ }
287
+ }
252
288
  }
253
289
 
254
290
  function importCodeBlock(lines, startLineIndex, rootNode) {
@@ -299,7 +335,7 @@ function importTextFormatTransformers(textNode, textFormatTransformersIndex, tex
299
335
  if (match[0] === textContent) {
300
336
  currentNode = textNode;
301
337
  } else {
302
- const startIndex = match.index;
338
+ const startIndex = match.index || 0;
303
339
  const endIndex = startIndex + match[0].length;
304
340
 
305
341
  if (startIndex === 0) {
@@ -342,7 +378,7 @@ function importTextMatchTransformers(textNode_, textMatchTransformers) {
342
378
  continue;
343
379
  }
344
380
 
345
- const startIndex = match.index;
381
+ const startIndex = match.index || 0;
346
382
  const endIndex = startIndex + match[0].length;
347
383
  let replaceNode;
348
384
 
@@ -389,7 +425,7 @@ function findOutermostMatch(textContent, textTransformersIndex) {
389
425
 
390
426
 
391
427
  const {
392
- index
428
+ index = 0
393
429
  } = fullMatch;
394
430
  const beforeChar = textContent[index - 1];
395
431
  const afterChar = textContent[index + fullMatch[0].length];
@@ -494,7 +530,7 @@ function runTextMatchTransformers(anchorNode, anchorOffset, transformersByTrigge
494
530
  continue;
495
531
  }
496
532
 
497
- const startIndex = match.index;
533
+ const startIndex = match.index || 0;
498
534
  const endIndex = startIndex + match[0].length;
499
535
  let replaceNode;
500
536
 
@@ -598,6 +634,7 @@ function runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransform
598
634
  closeNode.setTextContent(closeNodeText);
599
635
  const openNodeText = openNode === closeNode ? closeNodeText : prevOpenNodeText;
600
636
  openNode.setTextContent(openNodeText.slice(0, openTagStartIndex) + openNodeText.slice(openTagStartIndex + tagLength));
637
+ const selection = lexical.$getSelection();
601
638
  const nextSelection = lexical.$createRangeSelection();
602
639
  lexical.$setSelection(nextSelection); // Adjust offset based on deleted chars
603
640
 
@@ -620,6 +657,10 @@ function runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransform
620
657
  }
621
658
  }
622
659
 
660
+ if (lexical.$isRangeSelection(selection)) {
661
+ nextSelection.format = selection.format;
662
+ }
663
+
623
664
  return true;
624
665
  }
625
666
 
@@ -806,10 +847,37 @@ const HEADING = {
806
847
  };
807
848
  const QUOTE = {
808
849
  export: (node, exportChildren) => {
809
- return richText.$isQuoteNode(node) ? '> ' + exportChildren(node) : null;
850
+ if (!richText.$isQuoteNode(node)) {
851
+ return null;
852
+ }
853
+
854
+ const lines = exportChildren(node).split('\n');
855
+ const output = [];
856
+
857
+ for (const line of lines) {
858
+ output.push('> ' + line);
859
+ }
860
+
861
+ return output.join('\n');
810
862
  },
811
863
  regExp: /^>\s/,
812
- replace: replaceWithBlock(() => richText.$createQuoteNode()),
864
+ replace: (parentNode, children, _match, isImport) => {
865
+ if (isImport) {
866
+ const previousNode = parentNode.getPreviousSibling();
867
+
868
+ if (richText.$isQuoteNode(previousNode)) {
869
+ previousNode.splice(previousNode.getChildrenSize(), 0, [lexical.$createLineBreakNode(), ...children]);
870
+ previousNode.select(0, 0);
871
+ parentNode.remove();
872
+ return;
873
+ }
874
+ }
875
+
876
+ const node = richText.$createQuoteNode();
877
+ node.append(...children);
878
+ parentNode.replace(node);
879
+ node.select(0, 0);
880
+ },
813
881
  type: 'element'
814
882
  };
815
883
  const CODE = {
@@ -4,25 +4,25 @@
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
- 'use strict';var n=require("lexical"),y=require("@lexical/code"),D=require("@lexical/link"),E=require("@lexical/list"),F=require("@lexical/rich-text");function G(a,b){let c={};for(let d of a)a=b(d),c[a]?c[a].push(d):c[a]=[d];return c}function H(a){a=G(a,b=>b.type);return{element:a.element,textFormat:a["text-format"],textMatch:a["text-match"]}}let I=/[!-/:-@[-`{-~\s]/;
8
- function aa(a){let b=H(a),c=b.textFormat.filter(d=>1===d.format.length);return()=>{let d=[];var e=n.$getRoot().getChildren();for(let f of e)e=ba(f,b.element,c,b.textMatch),null!=e&&d.push(e);return d.join("\n")}}function ba(a,b,c,d){for(let e of b)if(b=e.export(a,f=>K(f,c,d)),null!=b)return b;return n.$isElementNode(a)?K(a,c,d):null}
9
- function K(a,b,c){let d=[];a=a.getChildren();a:for(let e of a)if(n.$isLineBreakNode(e))d.push("\n");else if(n.$isTextNode(e))d.push(L(e,e.getTextContent(),b));else{for(let f of c)if(a=f.export(e,m=>K(m,b,c),(m,h)=>L(m,h,b)),null!=a){d.push(a);continue a}n.$isElementNode(e)&&d.push(K(e,b,c))}return d.join("")}
10
- function L(a,b,c){let d=b.trim(),e=d,f=new Set;for(let h of c){c=h.format[0];let p=h.tag;if(M(a,c)&&!f.has(c)){f.add(c);var m=N(a,!0);M(m,c)||(e=p+e);m=N(a,!1);M(m,c)||(e+=p)}}return b.replace(d,e)}
11
- function N(a,b){let c=b?a.getPreviousSibling():a.getNextSibling();c||(a=a.getParentOrThrow(),a.isInline()&&(c=b?a.getPreviousSibling():a.getNextSibling()));for(;c;){if(n.$isElementNode(c)){if(!c.isInline())break;a=b?c.getLastDescendant():c.getFirstDescendant();if(n.$isTextNode(a))return a;c=b?c.getPreviousSibling():c.getNextSibling()}if(n.$isTextNode(c))return c;if(!n.$isElementNode(c))break}return null}function M(a,b){return n.$isTextNode(a)&&a.hasFormat(b)}let O=/^```(\w{1,10})?\s?$/;
12
- function ca(a){let b=H(a),c=da(b.textFormat);return d=>{d=d.split("\n");let e=d.length,f=n.$getRoot();f.clear();for(let q=0;q<e;q++){var m=d[q];a:{var h=d,p=q;var r=f;var w=h[p].match(O);if(w)for(var t=p,l=h.length;++t<l;)if(h[t].match(O)){w=y.$createCodeNode(w[1]);h=n.$createTextNode(h.slice(p+1,t).join("\n"));w.append(h);r.append(w);r=[w,t];break a}r=[null,p]}let [k,g]=r;if(null!=k)q=g;else{w=f;l=b.element;r=c;t=b.textMatch;h=n.$createTextNode(m);p=n.$createParagraphNode();p.append(h);w.append(p);
13
- for(let {regExp:u,replace:v}of l)if(w=m.match(u)){h.setTextContent(m.slice(w[0].length));v(p,[h],w,!0);break}P(h,r,t)}}f.selectEnd()}}
14
- function P(a,b,c){let d=a.getTextContent(),e=ea(d,b);if(e){if(e[0]===d)var f=a;else{var m=e.index,h=m+e[0].length;0===m?[f,r]=a.splitText(h):[,f,r]=a.splitText(m,h)}f.setTextContent(e[2]);if(m=b.transformersByTag[e[1]])for(var p of m.format)f.hasFormat(p)||f.toggleFormat(p);f.hasFormat("code")||P(f,b,c);r&&P(r,b,c)}else a:for(b=a;b;){for(m of c)if(f=b.getTextContent().match(m.importRegExp)){var r=f.index;p=r+f[0].length;0===r?[h,b]=b.splitText(p):[,h,b]=b.splitText(r,p);m.replace(h,f);continue a}break}}
15
- function ea(a,b){var c=a.match(b.openTagsRegExp);if(null==c)return null;for(let f of c){var d=f.replace(/^\s/,"");c=b.fullMatchRegExpByTag[d];if(null!=c&&(c=a.match(c),d=b.transformersByTag[d],null!=c&&null!=d)){if(!1!==d.intraword)return c;var {index:e}=c;d=a[e-1];e=a[e+c[0].length];if(!(d&&!I.test(d)||e&&!I.test(e)))return c}}return null}
16
- function da(a){let b={},c={},d=[];for(let e of a){({tag:a}=e);b[a]=e;let f=a.replace(/(\*|\^)/g,"\\$1");d.push(f);c[a]=new RegExp(`(${f})(?![${f}\\s])(.*?[^${f}\\s])${f}(?!${f})`)}return{fullMatchRegExpByTag:c,openTagsRegExp:new RegExp("("+d.join("|")+")","g"),transformersByTag:b}}function Q(a,b,c){let d=c.length;for(;b>=d;b--){let e=b-d;if(R(a,e,c,0,d)&&" "!==a[e+d])return e}return-1}function R(a,b,c,d,e){for(let f=0;f<e;f++)if(a[b+f]!==c[d+f])return!1;return!0}
17
- let S=a=>(b,c,d)=>{d=a(d);d.append(...c);b.replace(d);d.select(0,0)},T=a=>(b,c,d)=>{var e=b.getPreviousSibling();const f=E.$createListItemNode("check"===a?"x"===d[3]:void 0);E.$isListNode(e)&&e.getListType()===a?(e.append(f),b.remove()):(e=E.$createListNode(a,"number"===a?Number(d[2]):void 0),e.append(f),b.replace(e));f.append(...c);f.select(0,0);(b=Math.floor(d[1].length/4))&&f.setIndent(b)},U=(a,b,c)=>{const d=[];var e=a.getChildren();let f=0;for(const h of e)if(E.$isListItemNode(h)){if(1===h.getChildrenSize()&&
18
- (e=h.getFirstChild(),E.$isListNode(e))){d.push(U(e,b,c+1));continue}e=" ".repeat(4*c);var m=a.getListType();m="number"===m?`${a.getStart()+f}. `:"check"===m?`- [${h.getChecked()?"x":" "}] `:"- ";d.push(e+m+b(h));f++}return d.join("\n")},V={export:(a,b)=>{if(!F.$isHeadingNode(a))return null;const c=Number(a.getTag().slice(1));return"#".repeat(c)+" "+b(a)},regExp:/^(#{1,6})\s/,replace:S(a=>F.$createHeadingNode("h"+a[1].length)),type:"element"},W={export:(a,b)=>F.$isQuoteNode(a)?"> "+b(a):null,regExp:/^>\s/,
19
- replace:S(()=>F.$createQuoteNode()),type:"element"},X={export:a=>{if(!y.$isCodeNode(a))return null;const b=a.getTextContent();return"```"+(a.getLanguage()||"")+(b?"\n"+b:"")+"\n```"},regExp:/^```(\w{1,10})?\s/,replace:S(a=>y.$createCodeNode(a?a[1]:void 0)),type:"element"},Y={export:(a,b)=>E.$isListNode(a)?U(a,b,0):null,regExp:/^(\s*)[-*+]\s/,replace:T("bullet"),type:"element"},fa={export:(a,b)=>E.$isListNode(a)?U(a,b,0):null,regExp:/^(\s*)(?:-\s)?\s?(\[(\s|x)?\])\s/i,replace:T("check"),type:"element"},
20
- ha={export:(a,b)=>E.$isListNode(a)?U(a,b,0):null,regExp:/^(\s*)(\d{1,})\.\s/,replace:T("number"),type:"element"},ia={format:["code"],tag:"`",type:"text-format"},ja={format:["bold","italic"],tag:"***",type:"text-format"},ka={format:["bold","italic"],intraword:!1,tag:"___",type:"text-format"},la={format:["bold"],tag:"**",type:"text-format"},ma={format:["bold"],intraword:!1,tag:"__",type:"text-format"},na={format:["strikethrough"],tag:"~~",type:"text-format"},oa={format:["italic"],tag:"*",type:"text-format"},
21
- pa={format:["italic"],intraword:!1,tag:"_",type:"text-format"},qa={export:(a,b,c)=>{if(!D.$isLinkNode(a))return null;b=`[${a.getTextContent()}](${a.getURL()})`;const d=a.getFirstChild();return 1===a.getChildrenSize()&&n.$isTextNode(d)?c(d,b):b},importRegExp:/(?:\[([^[]+)\])(?:\(([^(]+)\))/,regExp:/(?:\[([^[]+)\])(?:\(([^(]+)\))$/,replace:(a,b)=>{const [,c,d]=b;b=D.$createLinkNode(d);const e=n.$createTextNode(c);e.setFormat(a.getFormat());b.append(e);a.replace(b)},trigger:")",type:"text-match"},ra=
22
- [V,W,X,Y,ha],sa=[ia,ja,ka,la,ma,oa,pa,na],ta=[qa],Z=[...ra,...sa,...ta];exports.$convertFromMarkdownString=function(a,b=Z){return ca(b)(a)};exports.$convertToMarkdownString=function(a=Z){return aa(a)()};exports.BOLD_ITALIC_STAR=ja;exports.BOLD_ITALIC_UNDERSCORE=ka;exports.BOLD_STAR=la;exports.BOLD_UNDERSCORE=ma;exports.CHECK_LIST=fa;exports.CODE=X;exports.ELEMENT_TRANSFORMERS=ra;exports.HEADING=V;exports.INLINE_CODE=ia;exports.ITALIC_STAR=oa;exports.ITALIC_UNDERSCORE=pa;exports.LINK=qa;
23
- exports.ORDERED_LIST=ha;exports.QUOTE=W;exports.STRIKETHROUGH=na;exports.TEXT_FORMAT_TRANSFORMERS=sa;exports.TEXT_MATCH_TRANSFORMERS=ta;exports.TRANSFORMERS=Z;exports.UNORDERED_LIST=Y;
24
- exports.registerMarkdownShortcuts=function(a,b=Z){let c=H(b),d=G(c.textFormat,({tag:f})=>f[f.length-1]),e=G(c.textMatch,({trigger:f})=>f);return a.registerUpdateListener(({tags:f,dirtyLeaves:m,editorState:h,prevEditorState:p})=>{if(!f.has("historic")){var r=h.read(n.$getSelection);f=p.read(n.$getSelection);if(n.$isRangeSelection(f)&&n.$isRangeSelection(r)&&r.isCollapsed()){p=r.anchor.key;var w=r.anchor.offset,t=h._nodeMap.get(p);n.$isTextNode(t)&&m.has(p)&&(1===w||w===f.anchor.offset+1)&&a.update(()=>
25
- {if(!t.hasFormat("code")){var l=t.getParent();if(null!==l&&!y.$isCodeNode(l)){var q=r.anchor.offset;b:{var k=c.element,g=l.getParent();if(n.$isRootNode(g)&&l.getFirstChild()===t&&(g=t.getTextContent()," "===g[q-1]))for(let {regExp:J,replace:B}of k)if((k=g.match(J))&&k[0].length===q){g=t.getNextSiblings();let [C,z]=t.splitText(q);C.remove();g=z?[z,...g]:g;B(l,g,k,!1);l=!0;break b}l=!1}if(!l){b:{k=t.getTextContent();l=e[k[q-1]];if(null!=l){q<k.length&&(k=k.slice(0,q));for(v of l)if(l=k.match(v.regExp),
26
- null!==l){k=l.index;g=k+l[0].length;var u=void 0;0===k?[u]=t.splitText(g):[,u]=t.splitText(k,g);u.selectNext();v.replace(u,l);var v=!0;break b}}v=!1}if(!v)b:{g=t.getTextContent();--q;let J=g[q];if(v=d[J])for(let B of v){var {tag:A}=B;v=A.length;let C=q-v+1;if(!(1<v&&!R(g,C,A,0,v)||" "===g[C-1])&&(u=g[q+1],!1!==B.intraword||!u||I.test(u))){l=u=t;k=Q(g,C,A);for(var x=l;0>k&&(x=x.getPreviousSibling())&&!n.$isLineBreakNode(x);)n.$isTextNode(x)&&(k=x.getTextContent(),l=x,k=Q(k,k.length,A));if(!(0>k||l===
27
- u&&k+v===C||(A=l.getTextContent(),0<k&&A[k-1]===J||(x=A[k-1],!1===B.intraword&&x&&!I.test(x))))){g=u.getTextContent();g=g.slice(0,C)+g.slice(q+1);u.setTextContent(g);g=l===u?g:A;l.setTextContent(g.slice(0,k)+g.slice(k+v));g=n.$createRangeSelection();n.$setSelection(g);q=q-v*(l===u?2:1)+1;g.anchor.set(l.__key,k,"text");g.focus.set(u.__key,q,"text");for(let z of B.format)g.hasFormat(z)||g.formatText(z);g.anchor.set(g.focus.key,g.focus.offset,g.focus.type);for(let z of B.format)g.hasFormat(z)&&g.toggleFormat(z);
28
- break b}}}}}}}})}}})}
7
+ 'use strict';var k=require("lexical"),y=require("@lexical/code"),E=require("@lexical/list"),F=require("@lexical/rich-text"),aa=require("@lexical/utils"),G=require("@lexical/link");function H(a,b){let c={};for(let d of a)a=b(d),c[a]?c[a].push(d):c[a]=[d];return c}function I(a){a=H(a,b=>b.type);return{element:a.element,textFormat:a["text-format"],textMatch:a["text-match"]}}let J=/[!-/:-@[-`{-~\s]/;
8
+ function ba(a){let b=I(a),c=b.textFormat.filter(d=>1===d.format.length);return()=>{let d=[];var e=k.$getRoot().getChildren();for(let f of e)e=ca(f,b.element,c,b.textMatch),null!=e&&d.push(e);return d.join("\n\n")}}function ca(a,b,c,d){for(let e of b)if(b=e.export(a,f=>K(f,c,d)),null!=b)return b;return k.$isElementNode(a)?K(a,c,d):null}
9
+ function K(a,b,c){let d=[];a=a.getChildren();a:for(let e of a){for(let f of c)if(a=f.export(e,h=>K(h,b,c),(h,p)=>L(h,p,b)),null!=a){d.push(a);continue a}k.$isLineBreakNode(e)?d.push("\n"):k.$isTextNode(e)?d.push(L(e,e.getTextContent(),b)):k.$isElementNode(e)&&d.push(K(e,b,c))}return d.join("")}function L(a,b,c){let d=b.trim(),e=d,f=new Set;for(let p of c){c=p.format[0];let r=p.tag;if(M(a,c)&&!f.has(c)){f.add(c);var h=N(a,!0);M(h,c)||(e=r+e);h=N(a,!1);M(h,c)||(e+=r)}}return b.replace(d,e)}
10
+ function N(a,b){let c=b?a.getPreviousSibling():a.getNextSibling();c||(a=a.getParentOrThrow(),a.isInline()&&(c=b?a.getPreviousSibling():a.getNextSibling()));for(;c;){if(k.$isElementNode(c)){if(!c.isInline())break;a=b?c.getLastDescendant():c.getFirstDescendant();if(k.$isTextNode(a))return a;c=b?c.getPreviousSibling():c.getNextSibling()}if(k.$isTextNode(c))return c;if(!k.$isElementNode(c))break}return null}function M(a,b){return k.$isTextNode(a)&&a.hasFormat(b)}let da=/^\s{0,3}$/,O=/^```(\w{1,10})?\s?$/;
11
+ function ea(a){let b=I(a),c=fa(b.textFormat);return d=>{var e=d.split("\n");let f=e.length;d=k.$getRoot();d.clear();for(let g=0;g<f;g++){var h=e[g];a:{var p=e,r=g;var l=d;var x=p[r].match(O);if(x)for(var q=r,m=p.length;++q<m;)if(p[q].match(O)){x=y.$createCodeNode(x[1]);p=k.$createTextNode(p.slice(r+1,q).join("\n"));x.append(p);l.append(x);l=[x,q];break a}l=[null,r]}let [n,u]=l;if(null!=n)g=u;else{l=h;m=d;var v=b.element;q=c;p=b.textMatch;r=l.trim();x=k.$createTextNode(r);h=k.$createParagraphNode();
12
+ h.append(x);m.append(h);for(let {regExp:w,replace:t}of v)if(m=l.match(w)){x.setTextContent(l.slice(m[0].length));t(h,[x],m,!0);break}P(x,q,p);h.isAttached()&&0<r.length&&(l=h.getPreviousSibling(),k.$isParagraphNode(l)||F.$isQuoteNode(l)||E.$isListNode(l))&&(q=l,E.$isListNode(l)&&(l=l.getLastDescendant(),q=null==l?null:aa.$findMatchingParent(l,E.$isListItemNode)),null!=q&&0<q.getTextContentSize()&&(q.splice(q.getChildrenSize(),0,[k.$createLineBreakNode(),...h.getChildren()]),h.remove()))}}e=d.getChildren();
13
+ for(let g of e)k.$isParagraphNode(g)&&da.test(g.getTextContent())&&g.remove();d.selectEnd()}}
14
+ function P(a,b,c){let d=a.getTextContent(),e=ha(d,b);if(e){if(e[0]===d)var f=a;else{var h=e.index||0,p=h+e[0].length;0===h?[f,l]=a.splitText(p):[,f,l]=a.splitText(h,p)}f.setTextContent(e[2]);if(h=b.transformersByTag[e[1]])for(var r of h.format)f.hasFormat(r)||f.toggleFormat(r);f.hasFormat("code")||P(f,b,c);l&&P(l,b,c)}else a:for(b=a;b;){for(h of c)if(f=b.getTextContent().match(h.importRegExp)){var l=f.index||0;r=l+f[0].length;0===l?[p,b]=b.splitText(r):[,p,b]=b.splitText(l,r);h.replace(p,f);continue a}break}}
15
+ function ha(a,b){var c=a.match(b.openTagsRegExp);if(null==c)return null;for(let f of c){var d=f.replace(/^\s/,"");c=b.fullMatchRegExpByTag[d];if(null!=c&&(c=a.match(c),d=b.transformersByTag[d],null!=c&&null!=d)){if(!1!==d.intraword)return c;var {index:e=0}=c;d=a[e-1];e=a[e+c[0].length];if(!(d&&!J.test(d)||e&&!J.test(e)))return c}}return null}
16
+ function fa(a){let b={},c={},d=[];for(let e of a){({tag:a}=e);b[a]=e;let f=a.replace(/(\*|\^)/g,"\\$1");d.push(f);c[a]=new RegExp(`(${f})(?![${f}\\s])(.*?[^${f}\\s])${f}(?!${f})`)}return{fullMatchRegExpByTag:c,openTagsRegExp:new RegExp("("+d.join("|")+")","g"),transformersByTag:b}}function Q(a,b,c){let d=c.length;for(;b>=d;b--){let e=b-d;if(R(a,e,c,0,d)&&" "!==a[e+d])return e}return-1}function R(a,b,c,d,e){for(let f=0;f<e;f++)if(a[b+f]!==c[d+f])return!1;return!0}
17
+ let S=a=>(b,c,d)=>{d=a(d);d.append(...c);b.replace(d);d.select(0,0)},T=a=>(b,c,d)=>{var e=b.getPreviousSibling();const f=E.$createListItemNode("check"===a?"x"===d[3]:void 0);E.$isListNode(e)&&e.getListType()===a?(e.append(f),b.remove()):(e=E.$createListNode(a,"number"===a?Number(d[2]):void 0),e.append(f),b.replace(e));f.append(...c);f.select(0,0);(b=Math.floor(d[1].length/4))&&f.setIndent(b)},U=(a,b,c)=>{const d=[];var e=a.getChildren();let f=0;for(const p of e)if(E.$isListItemNode(p)){if(1===p.getChildrenSize()&&
18
+ (e=p.getFirstChild(),E.$isListNode(e))){d.push(U(e,b,c+1));continue}e=" ".repeat(4*c);var h=a.getListType();h="number"===h?`${a.getStart()+f}. `:"check"===h?`- [${p.getChecked()?"x":" "}] `:"- ";d.push(e+h+b(p));f++}return d.join("\n")},V={export:(a,b)=>{if(!F.$isHeadingNode(a))return null;const c=Number(a.getTag().slice(1));return"#".repeat(c)+" "+b(a)},regExp:/^(#{1,6})\s/,replace:S(a=>F.$createHeadingNode("h"+a[1].length)),type:"element"},W={export:(a,b)=>{if(!F.$isQuoteNode(a))return null;a=b(a).split("\n");
19
+ b=[];for(const c of a)b.push("> "+c);return b.join("\n")},regExp:/^>\s/,replace:(a,b,c,d)=>{if(d&&(c=a.getPreviousSibling(),F.$isQuoteNode(c))){c.splice(c.getChildrenSize(),0,[k.$createLineBreakNode(),...b]);c.select(0,0);a.remove();return}c=F.$createQuoteNode();c.append(...b);a.replace(c);c.select(0,0)},type:"element"},X={export:a=>{if(!y.$isCodeNode(a))return null;const b=a.getTextContent();return"```"+(a.getLanguage()||"")+(b?"\n"+b:"")+"\n```"},regExp:/^```(\w{1,10})?\s/,replace:S(a=>y.$createCodeNode(a?
20
+ a[1]:void 0)),type:"element"},Y={export:(a,b)=>E.$isListNode(a)?U(a,b,0):null,regExp:/^(\s*)[-*+]\s/,replace:T("bullet"),type:"element"},ia={export:(a,b)=>E.$isListNode(a)?U(a,b,0):null,regExp:/^(\s*)(?:-\s)?\s?(\[(\s|x)?\])\s/i,replace:T("check"),type:"element"},ja={export:(a,b)=>E.$isListNode(a)?U(a,b,0):null,regExp:/^(\s*)(\d{1,})\.\s/,replace:T("number"),type:"element"},ka={format:["code"],tag:"`",type:"text-format"},la={format:["bold","italic"],tag:"***",type:"text-format"},ma={format:["bold",
21
+ "italic"],intraword:!1,tag:"___",type:"text-format"},na={format:["bold"],tag:"**",type:"text-format"},pa={format:["bold"],intraword:!1,tag:"__",type:"text-format"},qa={format:["strikethrough"],tag:"~~",type:"text-format"},ra={format:["italic"],tag:"*",type:"text-format"},sa={format:["italic"],intraword:!1,tag:"_",type:"text-format"},ta={export:(a,b,c)=>{if(!G.$isLinkNode(a))return null;b=`[${a.getTextContent()}](${a.getURL()})`;const d=a.getFirstChild();return 1===a.getChildrenSize()&&k.$isTextNode(d)?
22
+ c(d,b):b},importRegExp:/(?:\[([^[]+)\])(?:\(([^(]+)\))/,regExp:/(?:\[([^[]+)\])(?:\(([^(]+)\))$/,replace:(a,b)=>{const [,c,d]=b;b=G.$createLinkNode(d);const e=k.$createTextNode(c);e.setFormat(a.getFormat());b.append(e);a.replace(b)},trigger:")",type:"text-match"},ua=[V,W,X,Y,ja],va=[ka,la,ma,na,pa,ra,sa,qa],wa=[ta],Z=[...ua,...va,...wa];exports.$convertFromMarkdownString=function(a,b=Z){return ea(b)(a)};exports.$convertToMarkdownString=function(a=Z){return ba(a)()};exports.BOLD_ITALIC_STAR=la;
23
+ exports.BOLD_ITALIC_UNDERSCORE=ma;exports.BOLD_STAR=na;exports.BOLD_UNDERSCORE=pa;exports.CHECK_LIST=ia;exports.CODE=X;exports.ELEMENT_TRANSFORMERS=ua;exports.HEADING=V;exports.INLINE_CODE=ka;exports.ITALIC_STAR=ra;exports.ITALIC_UNDERSCORE=sa;exports.LINK=ta;exports.ORDERED_LIST=ja;exports.QUOTE=W;exports.STRIKETHROUGH=qa;exports.TEXT_FORMAT_TRANSFORMERS=va;exports.TEXT_MATCH_TRANSFORMERS=wa;exports.TRANSFORMERS=Z;exports.UNORDERED_LIST=Y;
24
+ exports.registerMarkdownShortcuts=function(a,b=Z){let c=I(b),d=H(c.textFormat,({tag:f})=>f[f.length-1]),e=H(c.textMatch,({trigger:f})=>f);return a.registerUpdateListener(({tags:f,dirtyLeaves:h,editorState:p,prevEditorState:r})=>{if(!f.has("historic")){var l=p.read(k.$getSelection);f=r.read(k.$getSelection);if(k.$isRangeSelection(f)&&k.$isRangeSelection(l)&&l.isCollapsed()){r=l.anchor.key;var x=l.anchor.offset,q=p._nodeMap.get(r);k.$isTextNode(q)&&h.has(r)&&(1===x||x===f.anchor.offset+1)&&a.update(()=>
25
+ {if(!q.hasFormat("code")){var m=q.getParent();if(null!==m&&!y.$isCodeNode(m)){var v=l.anchor.offset;b:{var g=c.element,n=m.getParent();if(k.$isRootNode(n)&&m.getFirstChild()===q&&(n=q.getTextContent()," "===n[v-1]))for(let {regExp:B,replace:C}of g)if((g=n.match(B))&&g[0].length===v){n=q.getNextSiblings();let [D,oa]=q.splitText(v);D.remove();n=oa?[oa,...n]:n;C(m,n,g,!1);m=!0;break b}m=!1}if(!m){b:{g=q.getTextContent();m=e[g[v-1]];if(null!=m){v<g.length&&(g=g.slice(0,v));for(w of m)if(m=g.match(w.regExp),
26
+ null!==m){g=m.index||0;n=g+m[0].length;var u=void 0;0===g?[u]=q.splitText(n):[,u]=q.splitText(g,n);u.selectNext();w.replace(u,m);var w=!0;break b}}w=!1}if(!w)b:{n=q.getTextContent();--v;var t=n[v];if(w=d[t])for(let B of w){var {tag:A}=B;w=A.length;let C=v-w+1;if(!(1<w&&!R(n,C,A,0,w)||" "===n[C-1])&&(u=n[v+1],!1!==B.intraword||!u||J.test(u))){m=u=q;g=Q(n,C,A);for(var z=m;0>g&&(z=z.getPreviousSibling())&&!k.$isLineBreakNode(z);)k.$isTextNode(z)&&(g=z.getTextContent(),m=z,g=Q(g,g.length,A));if(!(0>g||
27
+ m===u&&g+w===C||(A=m.getTextContent(),0<g&&A[g-1]===t||(z=A[g-1],!1===B.intraword&&z&&!J.test(z))))){n=u.getTextContent();n=n.slice(0,C)+n.slice(v+1);u.setTextContent(n);n=m===u?n:A;m.setTextContent(n.slice(0,g)+n.slice(g+w));n=k.$getSelection();t=k.$createRangeSelection();k.$setSelection(t);v=v-w*(m===u?2:1)+1;t.anchor.set(m.__key,g,"text");t.focus.set(u.__key,v,"text");for(let D of B.format)t.hasFormat(D)||t.formatText(D);t.anchor.set(t.focus.key,t.focus.offset,t.focus.type);for(let D of B.format)t.hasFormat(D)&&
28
+ t.toggleFormat(D);k.$isRangeSelection(n)&&(t.format=n.format);break b}}}}}}}})}}})}
package/README.md CHANGED
@@ -22,9 +22,9 @@ editor.update(() => {
22
22
 
23
23
  It can also be used for initializing editor's state from markdown string. Here's an example with react `<RichTextPlugin>`
24
24
  ```jsx
25
- <LexicalComposer initialEditorState={() => {
26
- $convertFromMarkdownString(markdown, TRANSFORMERS);
27
- }}>
25
+ <LexicalComposer initialConfig={{
26
+ editorState: () => $convertFromMarkdownString(markdown, TRANSFORMERS)
27
+ }}>
28
28
  <RichTextPlugin />
29
29
  </LexicalComposer>
30
30
  ```
package/package.json CHANGED
@@ -8,18 +8,18 @@
8
8
  "markdown"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.3.4",
11
+ "version": "0.3.7",
12
12
  "main": "LexicalMarkdown.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.3.4"
14
+ "lexical": "0.3.7"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.3.4",
18
- "@lexical/code": "0.3.4",
19
- "@lexical/text": "0.3.4",
20
- "@lexical/rich-text": "0.3.4",
21
- "@lexical/list": "0.3.4",
22
- "@lexical/link": "0.3.4"
17
+ "@lexical/utils": "0.3.7",
18
+ "@lexical/code": "0.3.7",
19
+ "@lexical/text": "0.3.7",
20
+ "@lexical/rich-text": "0.3.7",
21
+ "@lexical/list": "0.3.7",
22
+ "@lexical/link": "0.3.7"
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",