@lexical/markdown 0.3.3 → 0.3.6

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.
@@ -18,7 +19,6 @@ var richText = require('@lexical/rich-text');
18
19
  * This source code is licensed under the MIT license found in the
19
20
  * LICENSE file in the root directory of this source tree.
20
21
  *
21
- *
22
22
  */
23
23
  function indexBy(list, callback) {
24
24
  const index = {};
@@ -51,7 +51,6 @@ const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/;
51
51
  * This source code is licensed under the MIT license found in the
52
52
  * LICENSE file in the root directory of this source tree.
53
53
  *
54
- *
55
54
  */
56
55
  function createMarkdownExport(transformers) {
57
56
  const byType = transformersByType(transformers); // Export only uses text formats that are responsible for single format
@@ -70,7 +69,7 @@ function createMarkdownExport(transformers) {
70
69
  }
71
70
  }
72
71
 
73
- return output.join('\n');
72
+ return output.join('\n\n');
74
73
  };
75
74
  }
76
75
 
@@ -200,8 +199,8 @@ function hasFormat(node, format) {
200
199
  * This source code is licensed under the MIT license found in the
201
200
  * LICENSE file in the root directory of this source tree.
202
201
  *
203
- *
204
202
  */
203
+ const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/;
205
204
  const CODE_BLOCK_REG_EXP = /^```(\w{1,10})?\s?$/;
206
205
  function createMarkdownImport(transformers) {
207
206
  const byType = transformersByType(transformers);
@@ -226,6 +225,16 @@ function createMarkdownImport(transformers) {
226
225
  }
227
226
 
228
227
  importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch);
228
+ } // Removing empty paragraphs as md does not really
229
+ // allow empty lines and uses them as dilimiter
230
+
231
+
232
+ const children = root.getChildren();
233
+
234
+ for (const child of children) {
235
+ if (lexical.$isParagraphNode(child) && MARKDOWN_EMPTY_LINE_REG_EXP.test(child.getTextContent())) {
236
+ child.remove();
237
+ }
229
238
  }
230
239
 
231
240
  root.selectEnd();
@@ -233,7 +242,8 @@ function createMarkdownImport(transformers) {
233
242
  }
234
243
 
235
244
  function importBlocks(lineText, rootNode, elementTransformers, textFormatTransformersIndex, textMatchTransformers) {
236
- const textNode = lexical.$createTextNode(lineText);
245
+ const lineTextTrimmed = lineText.trim();
246
+ const textNode = lexical.$createTextNode(lineTextTrimmed);
237
247
  const elementNode = lexical.$createParagraphNode();
238
248
  elementNode.append(textNode);
239
249
  rootNode.append(elementNode);
@@ -251,7 +261,32 @@ function importBlocks(lineText, rootNode, elementTransformers, textFormatTransfo
251
261
  }
252
262
  }
253
263
 
254
- importTextFormatTransformers(textNode, textFormatTransformersIndex, textMatchTransformers);
264
+ importTextFormatTransformers(textNode, textFormatTransformersIndex, textMatchTransformers); // If no transformer found and we left with original paragraph node
265
+ // can check if its content can be appended to the previous node
266
+ // if it's a paragraph, quote or list
267
+
268
+ if (elementNode.isAttached() && lineTextTrimmed.length > 0) {
269
+ const previousNode = elementNode.getPreviousSibling();
270
+
271
+ if (lexical.$isParagraphNode(previousNode) || richText.$isQuoteNode(previousNode) || list.$isListNode(previousNode)) {
272
+ let targetNode = previousNode;
273
+
274
+ if (list.$isListNode(previousNode)) {
275
+ const lastDescendant = previousNode.getLastDescendant();
276
+
277
+ if (lastDescendant == null) {
278
+ targetNode = null;
279
+ } else {
280
+ targetNode = utils.$findMatchingParent(lastDescendant, list.$isListItemNode);
281
+ }
282
+ }
283
+
284
+ if (targetNode != null && targetNode.getTextContentSize() > 0) {
285
+ targetNode.splice(targetNode.getChildrenSize(), 0, [lexical.$createLineBreakNode(), ...elementNode.getChildren()]);
286
+ elementNode.remove();
287
+ }
288
+ }
289
+ }
255
290
  }
256
291
 
257
292
  function importCodeBlock(lines, startLineIndex, rootNode) {
@@ -302,7 +337,7 @@ function importTextFormatTransformers(textNode, textFormatTransformersIndex, tex
302
337
  if (match[0] === textContent) {
303
338
  currentNode = textNode;
304
339
  } else {
305
- const startIndex = match.index;
340
+ const startIndex = match.index || 0;
306
341
  const endIndex = startIndex + match[0].length;
307
342
 
308
343
  if (startIndex === 0) {
@@ -345,7 +380,7 @@ function importTextMatchTransformers(textNode_, textMatchTransformers) {
345
380
  continue;
346
381
  }
347
382
 
348
- const startIndex = match.index;
383
+ const startIndex = match.index || 0;
349
384
  const endIndex = startIndex + match[0].length;
350
385
  let replaceNode;
351
386
 
@@ -392,7 +427,7 @@ function findOutermostMatch(textContent, textTransformersIndex) {
392
427
 
393
428
 
394
429
  const {
395
- index
430
+ index = 0
396
431
  } = fullMatch;
397
432
  const beforeChar = textContent[index - 1];
398
433
  const afterChar = textContent[index + fullMatch[0].length];
@@ -436,7 +471,6 @@ function createTextFormatTransformersIndex(textTransformers) {
436
471
  * This source code is licensed under the MIT license found in the
437
472
  * LICENSE file in the root directory of this source tree.
438
473
  *
439
- *
440
474
  */
441
475
 
442
476
  function runElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers) {
@@ -498,7 +532,7 @@ function runTextMatchTransformers(anchorNode, anchorOffset, transformersByTrigge
498
532
  continue;
499
533
  }
500
534
 
501
- const startIndex = match.index;
535
+ const startIndex = match.index || 0;
502
536
  const endIndex = startIndex + match[0].length;
503
537
  let replaceNode;
504
538
 
@@ -602,6 +636,7 @@ function runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransform
602
636
  closeNode.setTextContent(closeNodeText);
603
637
  const openNodeText = openNode === closeNode ? closeNodeText : prevOpenNodeText;
604
638
  openNode.setTextContent(openNodeText.slice(0, openTagStartIndex) + openNodeText.slice(openTagStartIndex + tagLength));
639
+ const selection = lexical.$getSelection();
605
640
  const nextSelection = lexical.$createRangeSelection();
606
641
  lexical.$setSelection(nextSelection); // Adjust offset based on deleted chars
607
642
 
@@ -624,6 +659,10 @@ function runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransform
624
659
  }
625
660
  }
626
661
 
662
+ if (lexical.$isRangeSelection(selection)) {
663
+ nextSelection.format = selection.format;
664
+ }
665
+
627
666
  return true;
628
667
  }
629
668
 
@@ -726,7 +765,6 @@ function registerMarkdownShortcuts(editor, transformers = TRANSFORMERS) {
726
765
  * This source code is licensed under the MIT license found in the
727
766
  * LICENSE file in the root directory of this source tree.
728
767
  *
729
-
730
768
  */
731
769
 
732
770
  const replaceWithBlock = createNode => {
@@ -811,10 +849,37 @@ const HEADING = {
811
849
  };
812
850
  const QUOTE = {
813
851
  export: (node, exportChildren) => {
814
- return richText.$isQuoteNode(node) ? '> ' + exportChildren(node) : null;
852
+ if (!richText.$isQuoteNode(node)) {
853
+ return null;
854
+ }
855
+
856
+ const lines = exportChildren(node).split('\n');
857
+ const output = [];
858
+
859
+ for (const line of lines) {
860
+ output.push('> ' + line);
861
+ }
862
+
863
+ return output.join('\n');
815
864
  },
816
865
  regExp: /^>\s/,
817
- replace: replaceWithBlock(() => richText.$createQuoteNode()),
866
+ replace: (parentNode, children, _match, isImport) => {
867
+ if (isImport) {
868
+ const previousNode = parentNode.getPreviousSibling();
869
+
870
+ if (richText.$isQuoteNode(previousNode)) {
871
+ previousNode.splice(previousNode.getChildrenSize(), 0, [lexical.$createLineBreakNode(), ...children]);
872
+ previousNode.select(0, 0);
873
+ parentNode.remove();
874
+ return;
875
+ }
876
+ }
877
+
878
+ const node = richText.$createQuoteNode();
879
+ node.append(...children);
880
+ parentNode.replace(node);
881
+ node.select(0, 0);
882
+ },
818
883
  type: 'element'
819
884
  };
820
885
  const CODE = {
@@ -939,7 +1004,6 @@ const LINK = {
939
1004
  * This source code is licensed under the MIT license found in the
940
1005
  * LICENSE file in the root directory of this source tree.
941
1006
  *
942
- *
943
1007
  */
944
1008
  const ELEMENT_TRANSFORMERS = [HEADING, QUOTE, CODE, UNORDERED_LIST, ORDERED_LIST]; // Order of text format transformers matters:
945
1009
  //
@@ -4,25 +4,26 @@
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)if(k.$isLineBreakNode(e))d.push("\n");else if(k.$isTextNode(e))d.push(L(e,e.getTextContent(),b));else{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.$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 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)}
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(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?$/;
12
+ 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();
13
+ 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();
14
+ for(let g of e)k.$isParagraphNode(g)&&da.test(g.getTextContent())&&g.remove();d.selectEnd()}}
15
+ 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}}
16
+ 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}
17
+ 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}
18
+ 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()&&
19
+ (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");
20
+ 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?
21
+ 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",
22
+ "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)?
23
+ 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;
24
+ 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;
25
+ 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(()=>
26
+ {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),
27
+ 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||
28
+ 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)&&
29
+ t.toggleFormat(D);k.$isRangeSelection(n)&&(t.format=n.format);break b}}}}}}}})}}})}
package/README.md CHANGED
@@ -22,21 +22,21 @@ 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>
26
- <RichTextPlugin initialEditorState={() => {
27
- $convertFromMarkdownString(markdown, TRANSFORMERS);
28
- }} />
25
+ <LexicalComposer initialConfig={{
26
+ editorState: () => $convertFromMarkdownString(markdown, TRANSFORMERS)
27
+ }}>
28
+ <RichTextPlugin />
29
29
  </LexicalComposer>
30
30
  ```
31
31
 
32
32
  ## Shortcuts
33
- Can use `<LexicalMarkdownShortcutPlugin>` if using React
33
+ Can use `<MarkdownShortcutPlugin>` if using React
34
34
  ```jsx
35
35
  import { TRANSFORMERS } from '@lexical/markdown';
36
36
  import {MarkdownShortcutPlugin} from '@lexical/react/LexicalMarkdownShortcutPlugin';
37
37
 
38
38
  <LexicalComposer>
39
- <LexicalMarkdownShortcutPlugin transformers={TRANSFORMERS} />
39
+ <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
40
40
  </LexicalComposer>
41
41
  ```
42
42
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { AutoFormatTriggerState, ScanningContext } from './utils';
9
+ import type { DecoratorNode, EditorState, LexicalEditor } from 'lexical';
10
+ export declare function updateAutoFormatting<T>(editor: LexicalEditor, scanningContext: ScanningContext, createHorizontalRuleNode: () => DecoratorNode<T>): void;
11
+ export declare function getTriggerState(editorState: EditorState): null | AutoFormatTriggerState;
12
+ export declare function findScanningContext(editor: LexicalEditor, currentTriggerState: null | AutoFormatTriggerState, priorTriggerState: null | AutoFormatTriggerState): null | ScanningContext;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { DecoratorNode, LexicalEditor, RootNode } from 'lexical';
9
+ export declare function convertStringToLexical(text: string, editor: LexicalEditor): null | RootNode;
10
+ export declare function convertMarkdownForElementNodes<T>(editor: LexicalEditor, createHorizontalRuleNode: null | (() => DecoratorNode<T>)): void;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ export declare function $convertToMarkdownString(): string;
package/index.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { ElementTransformer, TextFormatTransformer, TextMatchTransformer, Transformer } from './v2/MarkdownTransformers';
9
+ import { registerMarkdownShortcuts } from './v2/MarkdownShortcuts';
10
+ import { BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, CHECK_LIST, CODE, HEADING, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, LINK, ORDERED_LIST, QUOTE, STRIKETHROUGH, UNORDERED_LIST } from './v2/MarkdownTransformers';
11
+ declare const ELEMENT_TRANSFORMERS: Array<ElementTransformer>;
12
+ declare const TEXT_FORMAT_TRANSFORMERS: Array<TextFormatTransformer>;
13
+ declare const TEXT_MATCH_TRANSFORMERS: Array<TextMatchTransformer>;
14
+ declare const TRANSFORMERS: Array<Transformer>;
15
+ declare function $convertFromMarkdownString(markdown: string, transformers?: Array<Transformer>): void;
16
+ declare function $convertToMarkdownString(transformers?: Array<Transformer>): string;
17
+ export { $convertFromMarkdownString, $convertToMarkdownString, BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, CHECK_LIST, CODE, ELEMENT_TRANSFORMERS, ElementTransformer, HEADING, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, LINK, ORDERED_LIST, QUOTE, registerMarkdownShortcuts, STRIKETHROUGH, TEXT_FORMAT_TRANSFORMERS, TEXT_MATCH_TRANSFORMERS, TextFormatTransformer, TextMatchTransformer, Transformer, TRANSFORMERS, UNORDERED_LIST, };
package/package.json CHANGED
@@ -8,18 +8,18 @@
8
8
  "markdown"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.3.3",
11
+ "version": "0.3.6",
12
12
  "main": "LexicalMarkdown.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.3.3"
14
+ "lexical": "0.3.6"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.3.3",
18
- "@lexical/code": "0.3.3",
19
- "@lexical/text": "0.3.3",
20
- "@lexical/rich-text": "0.3.3",
21
- "@lexical/list": "0.3.3",
22
- "@lexical/link": "0.3.3"
17
+ "@lexical/utils": "0.3.6",
18
+ "@lexical/code": "0.3.6",
19
+ "@lexical/text": "0.3.6",
20
+ "@lexical/rich-text": "0.3.6",
21
+ "@lexical/list": "0.3.6",
22
+ "@lexical/link": "0.3.6"
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",
package/utils.d.ts ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { TextNodeWithOffset } from '@lexical/text';
9
+ import type { DecoratorNode, ElementNode, LexicalEditor, LexicalNode, NodeKey, TextFormatType } from 'lexical';
10
+ export declare type AutoFormatTriggerState = Readonly<{
11
+ anchorOffset: number;
12
+ hasParentNode: boolean;
13
+ isCodeBlock: boolean;
14
+ isParentAListItemNode: boolean;
15
+ isSelectionCollapsed: boolean;
16
+ isSimpleText: boolean;
17
+ nodeKey: NodeKey;
18
+ textContent: string;
19
+ }>;
20
+ export declare 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';
21
+ export declare type ScanningContext = {
22
+ currentElementNode: null | ElementNode;
23
+ editor: LexicalEditor;
24
+ isAutoFormatting: boolean;
25
+ isWithinCodeBlock: boolean;
26
+ joinedText: string | null | undefined;
27
+ markdownCriteria: MarkdownCriteria;
28
+ patternMatchResults: PatternMatchResults;
29
+ textNodeWithOffset: TextNodeWithOffset | null | undefined;
30
+ triggerState: AutoFormatTriggerState | null | undefined;
31
+ };
32
+ export declare type MarkdownCriteria = Readonly<{
33
+ export?: (node: LexicalNode, traverseChildren: (node: ElementNode) => string) => string | null;
34
+ exportFormat?: TextFormatType;
35
+ exportTag?: string;
36
+ exportTagClose?: string;
37
+ markdownFormatKind: MarkdownFormatKind | null | undefined;
38
+ regEx: RegExp;
39
+ regExForAutoFormatting: RegExp;
40
+ requiresParagraphStart: boolean | null | undefined;
41
+ }>;
42
+ declare type CaptureGroupDetail = {
43
+ offsetInParent: number;
44
+ text: string;
45
+ };
46
+ export declare type PatternMatchResults = {
47
+ regExCaptureGroups: Array<CaptureGroupDetail>;
48
+ };
49
+ export declare type MarkdownCriteriaWithPatternMatchResults = {
50
+ markdownCriteria: null | MarkdownCriteria;
51
+ patternMatchResults: null | PatternMatchResults;
52
+ };
53
+ export declare type MarkdownCriteriaArray = Array<MarkdownCriteria>;
54
+ export declare type AutoFormatTriggerKind = 'space_trigger' | 'codeBlock_trigger';
55
+ export declare type AutoFormatTrigger = {
56
+ triggerKind: AutoFormatTriggerKind;
57
+ triggerString: string;
58
+ };
59
+ export declare const triggers: Array<AutoFormatTrigger>;
60
+ export declare const allMarkdownCriteria: MarkdownCriteriaArray;
61
+ export declare function getAllTriggers(): Array<AutoFormatTrigger>;
62
+ export declare function getAllMarkdownCriteriaForParagraphs(): MarkdownCriteriaArray;
63
+ export declare function getAllMarkdownCriteriaForTextNodes(): MarkdownCriteriaArray;
64
+ export declare function getAllMarkdownCriteria(): MarkdownCriteriaArray;
65
+ export declare function getInitialScanningContext(editor: LexicalEditor, isAutoFormatting: boolean, textNodeWithOffset: null | TextNodeWithOffset, triggerState: null | AutoFormatTriggerState): ScanningContext;
66
+ export declare function resetScanningContext(scanningContext: ScanningContext): ScanningContext;
67
+ export declare function getCodeBlockCriteria(): MarkdownCriteria;
68
+ export declare function getPatternMatchResultsForCriteria(markdownCriteria: MarkdownCriteria, scanningContext: ScanningContext, parentElementNode: ElementNode): null | PatternMatchResults;
69
+ export declare function getPatternMatchResultsForCodeBlock(scanningContext: ScanningContext, text: string): null | PatternMatchResults;
70
+ export declare function hasPatternMatchResults(scanningContext: ScanningContext): boolean;
71
+ export declare function getTextNodeWithOffsetOrThrow(scanningContext: ScanningContext): TextNodeWithOffset;
72
+ export declare function transformTextNodeForMarkdownCriteria<T>(scanningContext: ScanningContext, elementNode: ElementNode, createHorizontalRuleNode: null | (() => DecoratorNode<T>)): void;
73
+ export declare function getParentElementNodeOrThrow(scanningContext: ScanningContext): ElementNode;
74
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { Transformer } from '@lexical/markdown';
9
+ export declare function createMarkdownExport(transformers: Array<Transformer>): () => string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { Transformer } from '@lexical/markdown';
9
+ export declare function createMarkdownImport(transformers: Array<Transformer>): (markdownString: string) => void;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { Transformer } from '@lexical/markdown';
9
+ import type { LexicalEditor } from 'lexical';
10
+ export declare function registerMarkdownShortcuts(editor: LexicalEditor, transformers?: Array<Transformer>): () => void;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { ElementNode, LexicalNode, TextFormatType, TextNode } from 'lexical';
9
+ export declare type Transformer = ElementTransformer | TextFormatTransformer | TextMatchTransformer;
10
+ export declare type ElementTransformer = {
11
+ export: (node: LexicalNode, traverseChildren: (node: ElementNode) => string) => string | null;
12
+ regExp: RegExp;
13
+ replace: (parentNode: ElementNode, children: Array<LexicalNode>, match: Array<string>, isImport: boolean) => void;
14
+ type: 'element';
15
+ };
16
+ export declare type TextFormatTransformer = Readonly<{
17
+ format: ReadonlyArray<TextFormatType>;
18
+ tag: string;
19
+ intraword?: boolean;
20
+ type: 'text-format';
21
+ }>;
22
+ export declare type TextMatchTransformer = Readonly<{
23
+ export: (node: LexicalNode, exportChildren: (node: ElementNode) => string, exportFormat: (node: TextNode, textContent: string) => string) => string | null;
24
+ importRegExp: RegExp;
25
+ regExp: RegExp;
26
+ replace: (node: TextNode, match: RegExpMatchArray) => void;
27
+ trigger: string;
28
+ type: 'text-match';
29
+ }>;
30
+ export declare const HEADING: ElementTransformer;
31
+ export declare const QUOTE: ElementTransformer;
32
+ export declare const CODE: ElementTransformer;
33
+ export declare const UNORDERED_LIST: ElementTransformer;
34
+ export declare const CHECK_LIST: ElementTransformer;
35
+ export declare const ORDERED_LIST: ElementTransformer;
36
+ export declare const INLINE_CODE: TextFormatTransformer;
37
+ export declare const BOLD_ITALIC_STAR: TextFormatTransformer;
38
+ export declare const BOLD_ITALIC_UNDERSCORE: TextFormatTransformer;
39
+ export declare const BOLD_STAR: TextFormatTransformer;
40
+ export declare const BOLD_UNDERSCORE: TextFormatTransformer;
41
+ export declare const STRIKETHROUGH: TextFormatTransformer;
42
+ export declare const ITALIC_STAR: TextFormatTransformer;
43
+ export declare const ITALIC_UNDERSCORE: TextFormatTransformer;
44
+ export declare const LINK: TextMatchTransformer;
package/v2/utils.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { ElementTransformer, TextFormatTransformer, TextMatchTransformer, Transformer } from '@lexical/markdown';
9
+ export declare function indexBy<T>(list: Array<T>, callback: (arg0: T) => string): Readonly<Record<string, Array<T>>>;
10
+ export declare function transformersByType(transformers: Array<Transformer>): Readonly<{
11
+ element: Array<ElementTransformer>;
12
+ textFormat: Array<TextFormatTransformer>;
13
+ textMatch: Array<TextMatchTransformer>;
14
+ }>;
15
+ export declare const PUNCTUATION_OR_SPACE: RegExp;
@@ -1,98 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
-
9
- import type {
10
- LexicalEditor,
11
- ElementNode,
12
- LexicalNode,
13
- TextNode,
14
- TextFormatType,
15
- } from 'lexical';
16
-
17
- export type Transformer =
18
- | ElementTransformer
19
- | TextFormatTransformer
20
- | TextMatchTransformer;
21
-
22
- export type ElementTransformer = {
23
- export: (
24
- node: LexicalNode,
25
- traverseChildren: (node: ElementNode) => string,
26
- ) => string | null;
27
- regExp: RegExp;
28
- replace: (
29
- parentNode: ElementNode,
30
- children: Array<LexicalNode>,
31
- match: Array<string>,
32
- isImport: boolean,
33
- ) => void;
34
- type: 'element';
35
- };
36
-
37
- export type TextFormatTransformer = {
38
- format: Array<TextFormatType>;
39
- tag: string;
40
- intraword?: boolean;
41
- type: 'text-format';
42
- };
43
-
44
- export type TextMatchTransformer = {
45
- export: (
46
- node: LexicalNode,
47
- exportChildren: (node: ElementNode) => string,
48
- exportFormat: (node: TextNode, textContent: string) => string,
49
- ) => string | null;
50
- importRegExp: RegExp;
51
- regExp: RegExp;
52
- replace: (node: TextNode, match: RegExpMatchArray) => void;
53
- trigger: string;
54
- type: 'text-match';
55
- };
56
-
57
- // TODO:
58
- // transformers should be required argument, breaking change
59
- export function registerMarkdownShortcuts(
60
- editor: LexicalEditor,
61
- transformers?: Array<Transformer>,
62
- ): () => void;
63
-
64
- // TODO:
65
- // transformers should be required argument, breaking change
66
- export function $convertFromMarkdownString(
67
- markdown: string,
68
- transformers?: Array<Transformer>,
69
- ): void;
70
-
71
- // TODO:
72
- // transformers should be required argument, breaking change
73
- export function $convertToMarkdownString(
74
- transformers?: Array<Transformer>,
75
- ): string;
76
-
77
- export const BOLD_ITALIC_STAR: TextFormatTransformer;
78
- export const BOLD_ITALIC_UNDERSCORE: TextFormatTransformer;
79
- export const BOLD_STAR: TextFormatTransformer;
80
- export const BOLD_UNDERSCORE: TextFormatTransformer;
81
- export const INLINE_CODE: TextFormatTransformer;
82
- export const ITALIC_STAR: TextFormatTransformer;
83
- export const ITALIC_UNDERSCORE: TextFormatTransformer;
84
- export const STRIKETHROUGH: TextFormatTransformer;
85
-
86
- export const UNORDERED_LIST: ElementTransformer;
87
- export const CODE: ElementTransformer;
88
- export const HEADING: ElementTransformer;
89
- export const ORDERED_LIST: ElementTransformer;
90
- export const QUOTE: ElementTransformer;
91
- export const CHECK_LIST: ElementTransformer;
92
-
93
- export const LINK: TextMatchTransformer;
94
-
95
- export const TRANSFORMERS: Array<Transformer>;
96
- export const ELEMENT_TRANSFORMERS: Array<ElementTransformer>;
97
- export const TEXT_FORMAT_TRANSFORMERS: Array<TextFormatTransformer>;
98
- export const TEXT_MATCH_TRANSFORMERS: Array<TextFormatTransformer>;