@lofcz/platejs-markdown 53.1.4 → 53.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -324,7 +324,7 @@ declare const htmlToJsx: (html: string) => string;
324
324
  //#endregion
325
325
  //#region src/lib/deserializer/utils/markdownToSlateNodesSafely.d.ts
326
326
  declare const markdownToSlateNodesSafely: (editor: SlateEditor, data: string, options?: Omit<DeserializeMdOptions, "editor">) => (platejs2.TText | {
327
- children: platejs2.Descendant[] | {
327
+ children: Descendant[] | {
328
328
  text: string;
329
329
  }[];
330
330
  type: string;
package/dist/index.js CHANGED
@@ -1149,7 +1149,7 @@ const serializeMdWithSourceMap = (editor, options) => {
1149
1149
  const startLine = info.now.line;
1150
1150
  const emitted = handler(node, parent, state, info);
1151
1151
  const source = node?.data?.sourceMap;
1152
- if (source && emitted.trim()) pushSegment(source, emitted, startLine, startLine + (emitted.replace(/(?:\r?\n|\r)+$/g, "").split(/\r?\n|\r/g).length - 1));
1152
+ if (source) pushSegment(source, emitted, startLine, startLine + (emitted.replace(/(?:\r?\n|\r)+$/g, "").split(/\r?\n|\r/g).length - 1));
1153
1153
  if (type === "table" && Array.isArray(node?.children)) for (let r = 0; r < node.children.length; r++) {
1154
1154
  const line = r === 0 ? startLine : startLine + 1 + r;
1155
1155
  const cells = node.children[r]?.children;
@@ -1501,6 +1501,23 @@ const groupInlineChildrenIntoParagraphs = (editor, children = []) => {
1501
1501
  type: paragraphType
1502
1502
  }];
1503
1503
  };
1504
+ const normalizeParagraphLineBreaks = (children, options) => children.flatMap((child) => {
1505
+ const text = child.text;
1506
+ if (text === "" && options.preserveEmptyParagraphs !== false) return [{
1507
+ ...child,
1508
+ text: "​"
1509
+ }];
1510
+ if (typeof text !== "string" || !text.includes("\n")) return [child];
1511
+ return text.split("\n").flatMap((part, index, parts) => {
1512
+ const nodes = [];
1513
+ if (part) nodes.push({
1514
+ ...child,
1515
+ text: part
1516
+ });
1517
+ if (index < parts.length - 1) nodes.push({ type: "break" });
1518
+ return nodes;
1519
+ });
1520
+ });
1504
1521
  const defaultRules = {
1505
1522
  a: {
1506
1523
  deserialize: (mdastNode, deco, options) => ({
@@ -1985,15 +2002,7 @@ const defaultRules = {
1985
2002
  return elements.length === 1 ? elements[0] : elements;
1986
2003
  },
1987
2004
  serialize: (node, options) => {
1988
- let enrichedChildren = node.children;
1989
- enrichedChildren = enrichedChildren.map((child) => {
1990
- if (child.text === "\n") return { type: "break" };
1991
- if (child.text === "" && options.preserveEmptyParagraphs !== false) return {
1992
- ...child,
1993
- text: "​"
1994
- };
1995
- return child;
1996
- });
2005
+ const enrichedChildren = normalizeParagraphLineBreaks(node.children, options);
1997
2006
  const convertedNodes = convertNodesSerialize(enrichedChildren, options);
1998
2007
  if (convertedNodes.length > 0 && enrichedChildren.at(-1).type === "break") {
1999
2008
  convertedNodes.at(-1).type = "html";
@@ -2487,8 +2496,9 @@ const remarkToSlate = function(options = {}) {
2487
2496
 
2488
2497
  //#endregion
2489
2498
  //#region src/lib/deserializer/utils/splitIncompleteMdx.ts
2490
- /** Check if character is valid for tag name: A-Z / a-z / 0-9 / - _ : */
2491
- const isNameChar = (c) => c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 45 || c === 95 || c === 58;
2499
+ /** Check if character is valid for tag name: A-Z / a-z / 0-9 / $ - . _ : */
2500
+ const isNameChar = (c) => c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 36 || c === 45 || c === 46 || c === 95 || c === 58;
2501
+ const isNameBoundary = (c) => c === 47 || c === 62 || c === 9 || c === 10 || c === 12 || c === 13 || c === 32;
2492
2502
  const splitIncompleteMdx = (data) => {
2493
2503
  const stack = [];
2494
2504
  const len = data.length;
@@ -2517,6 +2527,11 @@ const splitIncompleteMdx = (data) => {
2517
2527
  break;
2518
2528
  }
2519
2529
  const tagName = data.slice(nameStart, i).toLowerCase();
2530
+ const next = data.codePointAt(i);
2531
+ if (next !== void 0 && !isNameBoundary(next)) {
2532
+ cutPos = tagStart;
2533
+ break;
2534
+ }
2520
2535
  let inQuote = null;
2521
2536
  let foundTagEnd = false;
2522
2537
  let selfClosing = false;
@@ -2557,18 +2572,45 @@ const splitIncompleteMdx = (data) => {
2557
2572
 
2558
2573
  //#endregion
2559
2574
  //#region src/lib/deserializer/utils/markdownToSlateNodesSafely.ts
2575
+ const isPlainTextNode = (node) => TextApi.isText(node) && Object.keys(node).every((key) => key === "text");
2576
+ const isSplitInsideTableRow = (completeString) => {
2577
+ return completeString.slice(completeString.lastIndexOf("\n") + 1).includes("|");
2578
+ };
2579
+ const markdownToSlateNodesWithoutMdx = (editor, data, options) => markdownToSlateNodes(editor, data, {
2580
+ ...options,
2581
+ withoutMdx: true
2582
+ });
2583
+ const markdownToSlateNodesWithMdxFallback = (editor, data, options) => {
2584
+ try {
2585
+ return markdownToSlateNodes(editor, data, options);
2586
+ } catch {
2587
+ return markdownToSlateNodesWithoutMdx(editor, data, options);
2588
+ }
2589
+ };
2590
+ const appendInlineNodesToLastTextContainer = (editor, node, inlineNodes) => {
2591
+ if (!ElementApi.isElement(node) || editor.api.isVoid(node)) return false;
2592
+ const paragraphType = getPluginType(editor, KEYS.p);
2593
+ if (node.type === paragraphType || node.children.some((child) => TextApi.isText(child))) {
2594
+ const lastChild = node.children.at(-1);
2595
+ if (isPlainTextNode(lastChild) && inlineNodes.every((inlineNode) => isPlainTextNode(inlineNode))) {
2596
+ lastChild.text += inlineNodes.map((inlineNode) => inlineNode.text).join("");
2597
+ return true;
2598
+ }
2599
+ node.children.push(...inlineNodes);
2600
+ return true;
2601
+ }
2602
+ for (let i = node.children.length - 1; i >= 0; i--) if (appendInlineNodesToLastTextContainer(editor, node.children[i], inlineNodes)) return true;
2603
+ return false;
2604
+ };
2560
2605
  const markdownToSlateNodesSafely = (editor, data, options) => {
2561
2606
  const result = splitIncompleteMdx(data);
2562
- if (!Array.isArray(result)) return markdownToSlateNodes(editor, data, {
2563
- ...options,
2564
- withoutMdx: true
2565
- });
2607
+ if (!Array.isArray(result)) return markdownToSlateNodesWithoutMdx(editor, data, options);
2566
2608
  const [completeString, incompleteString] = result;
2567
2609
  const incompleteNodes = deserializeInlineMd(editor, incompleteString, {
2568
2610
  ...options,
2569
2611
  withoutMdx: true
2570
2612
  });
2571
- const completeNodes = markdownToSlateNodes(editor, completeString, options);
2613
+ const completeNodes = markdownToSlateNodesWithMdxFallback(editor, completeString, options);
2572
2614
  const newBlock = {
2573
2615
  children: incompleteNodes,
2574
2616
  type: getPluginType(editor, KEYS.p)
@@ -2576,10 +2618,25 @@ const markdownToSlateNodesSafely = (editor, data, options) => {
2576
2618
  if (completeNodes.length === 0) return [newBlock];
2577
2619
  const lastBlock = completeNodes.at(-1);
2578
2620
  if (ElementApi.isElement(lastBlock) && editor.api.isVoid(lastBlock)) return [...completeNodes, newBlock];
2579
- if (ElementApi.isElement(lastBlock) && lastBlock?.children) {
2580
- lastBlock.children.push(...incompleteNodes);
2581
- return completeNodes;
2621
+ const tableType = getPluginType(editor, KEYS.table);
2622
+ if (ElementApi.isElement(lastBlock) && lastBlock.type === tableType) {
2623
+ if (isSplitInsideTableRow(completeString)) {
2624
+ const withoutMdxNodes = markdownToSlateNodesWithoutMdx(editor, data, options);
2625
+ const tableOrdinal = completeNodes.filter((node) => ElementApi.isElement(node) && node.type === tableType).indexOf(lastBlock);
2626
+ let fallbackTableIndex = -1;
2627
+ let seenTables = -1;
2628
+ for (const [index, node] of withoutMdxNodes.entries()) if (ElementApi.isElement(node) && node.type === tableType) {
2629
+ seenTables += 1;
2630
+ if (seenTables === tableOrdinal) {
2631
+ fallbackTableIndex = index;
2632
+ break;
2633
+ }
2634
+ }
2635
+ if (fallbackTableIndex !== -1) return [...completeNodes.slice(0, -1), ...withoutMdxNodes.slice(fallbackTableIndex)];
2636
+ }
2637
+ return [...completeNodes, newBlock];
2582
2638
  }
2639
+ if (ElementApi.isElement(lastBlock) && appendInlineNodesToLastTextContainer(editor, lastBlock, incompleteNodes)) return completeNodes;
2583
2640
  return completeNodes;
2584
2641
  };
2585
2642
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lofcz/platejs-markdown",
3
- "version": "53.1.4",
3
+ "version": "53.2.1",
4
4
  "description": "Markdown serializer plugin for Plate",
5
5
  "keywords": [
6
6
  "markdown",
@@ -52,8 +52,9 @@
52
52
  "remark-gfm": "4.0.1",
53
53
  "remark-math": "6.0.0",
54
54
  "@plate/scripts": "1.0.0",
55
- "platejs": "npm:@lofcz/platejs@53.1.1",
56
- "@platejs/footnote": "npm:@lofcz/platejs-footnote@53.0.0"
55
+ "@platejs/footnote": "npm:@lofcz/platejs-footnote@53.0.0",
56
+ "@platejs/table": "npm:@lofcz/platejs-table@53.1.8",
57
+ "platejs": "npm:@lofcz/platejs@53.1.1"
57
58
  },
58
59
  "peerDependencies": {
59
60
  "platejs": ">=53.0.0",