@lofcz/platejs-markdown 52.3.5 → 52.3.8

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.js CHANGED
@@ -3,6 +3,7 @@ import "mdast-util-mdx";
3
3
  import kebabCase from "lodash/kebabCase.js";
4
4
  import remarkStringify from "remark-stringify";
5
5
  import { unified } from "unified";
6
+ import { defaultHandlers, toMarkdown } from "mdast-util-to-markdown";
6
7
  import remarkParse from "remark-parse";
7
8
  import { marked } from "marked";
8
9
  import baseRemarkMdx from "remark-mdx";
@@ -522,9 +523,9 @@ function listToMdastTree(nodes, options, isBlock = false) {
522
523
  children: convertNodesSerialize(node.children, options),
523
524
  type: "paragraph"
524
525
  }],
526
+ spread: options.spread ?? false,
525
527
  type: "listItem"
526
528
  };
527
- if (options.spread) listItem.spread = true;
528
529
  if (node.listStyleType === "todo" && node.checked !== void 0) listItem.checked = node.checked;
529
530
  stackTop.list.children.push(listItem);
530
531
  const nextNode = nodes[i + 1];
@@ -568,9 +569,9 @@ function processListWithBlockIds(nodes, options) {
568
569
  children: convertNodesSerialize(node.children, options),
569
570
  type: "paragraph"
570
571
  }],
572
+ spread: options.spread ?? false,
571
573
  type: "listItem"
572
574
  };
573
- if (options.spread) listItem.spread = true;
574
575
  if (node.listStyleType === "todo" && node.checked !== void 0) listItem.checked = node.checked;
575
576
  singleList.children.push(listItem);
576
577
  if (node.id) fragments.push(wrapWithBlockId(singleList, String(node.id)));
@@ -591,12 +592,12 @@ const convertNodesSerialize = (nodes, options, isBlock = false) => {
591
592
  for (let i = 0; i <= nodes.length; i++) {
592
593
  const n = nodes[i];
593
594
  if (n && TextApi.isText(n)) {
594
- if (shouldIncludeText(n, options)) textQueue.push(n);
595
+ if (shouldIncludeText$1(n, options)) textQueue.push(n);
595
596
  } else {
596
597
  if (textQueue.length > 0) mdastNodes.push(...convertTextsSerialize(textQueue, options));
597
598
  textQueue = [];
598
599
  if (!n) continue;
599
- if (!shouldIncludeNode$1(n, options)) continue;
600
+ if (!shouldIncludeNode$2(n, options)) continue;
600
601
  const pType = getPluginType(options.editor, KEYS.p) ?? KEYS.p;
601
602
  if (n?.type === pType && "listStyleType" in n) {
602
603
  listBlock.push(n);
@@ -631,7 +632,7 @@ const buildMdastNode = (node, options, isBlock = false) => {
631
632
  }
632
633
  unreachable(node);
633
634
  };
634
- const shouldIncludeText = (text, options) => {
635
+ const shouldIncludeText$1 = (text, options) => {
635
636
  const { allowedNodes, allowNode, disallowedNodes } = options;
636
637
  if (allowedNodes && disallowedNodes && allowedNodes.length > 0 && disallowedNodes.length > 0) throw new Error("Cannot combine allowedNodes with disallowedNodes");
637
638
  for (const [key, value] of Object.entries(text)) {
@@ -643,7 +644,7 @@ const shouldIncludeText = (text, options) => {
643
644
  if (allowNode?.serialize) return allowNode.serialize(text);
644
645
  return true;
645
646
  };
646
- const shouldIncludeNode$1 = (node, options) => {
647
+ const shouldIncludeNode$2 = (node, options) => {
647
648
  const { allowedNodes, allowNode, disallowedNodes } = options;
648
649
  if (!node.type) return true;
649
650
  if (allowedNodes && disallowedNodes && allowedNodes.length > 0 && disallowedNodes.length > 0) throw new Error("Cannot combine allowedNodes with disallowedNodes");
@@ -693,12 +694,382 @@ const slateToMdast = ({ children, options }) => {
693
694
  };
694
695
  };
695
696
 
697
+ //#endregion
698
+ //#region src/lib/serializer/serializeMdWithSourceMap.ts
699
+ const collectSlateText = (node) => {
700
+ if (typeof node === "string") return node;
701
+ if (node?.text != null) return node.text;
702
+ if (Array.isArray(node?.children)) return node.children.map(collectSlateText).join("");
703
+ return "";
704
+ };
705
+ const comparePaths = (a, b) => {
706
+ const len = Math.min(a.length, b.length);
707
+ for (let i = 0; i < len; i++) if (a[i] !== b[i]) return a[i] - b[i];
708
+ return a.length - b.length;
709
+ };
710
+ const isPathPrefix = (prefix, path) => prefix.length < path.length && prefix.every((part, index) => path[index] === part);
711
+ const toPathKey = (path) => path.join(".");
712
+ const annotatePaths = (node, path) => {
713
+ if (node == null || typeof node !== "object") return node;
714
+ const clone = {
715
+ ...node,
716
+ __sourceMapPath: path
717
+ };
718
+ if (Array.isArray(node.children)) clone.children = node.children.map((child, i) => annotatePaths(child, [...path, i]));
719
+ return clone;
720
+ };
721
+ const MDX_MDAST_TYPES = new Set(["mdxJsxFlowElement", "mdxJsxTextElement"]);
722
+ const propagateMdxFlag = (node) => {
723
+ if (!node || typeof node !== "object") return;
724
+ if (node.data?.sourceMap) node.data.sourceMap.containsMdx = true;
725
+ if (Array.isArray(node.children)) for (const child of node.children) propagateMdxFlag(child);
726
+ };
727
+ const SEGMENT_SKIP_TYPES = new Set([
728
+ "table",
729
+ "tr",
730
+ KEYS.table,
731
+ KEYS.tr,
732
+ "column_group",
733
+ "column",
734
+ KEYS.columnGroup,
735
+ KEYS.column
736
+ ]);
737
+ const MEDIA_TYPES = new Set([
738
+ "img",
739
+ "image",
740
+ "media_embed",
741
+ "video",
742
+ "audio",
743
+ "file",
744
+ "excalidraw",
745
+ KEYS.img,
746
+ KEYS.mediaEmbed,
747
+ KEYS.video,
748
+ KEYS.audio,
749
+ KEYS.file,
750
+ KEYS.excalidraw
751
+ ]);
752
+ const slateNodeKind = (node, editor) => {
753
+ if (node.listStyleType) return "list_item";
754
+ const key = getPluginKey(editor, node.type) ?? node.type;
755
+ if (KEYS.heading.includes(key) || key === "heading") return "heading";
756
+ if (key === KEYS.blockquote) return "blockquote";
757
+ if (key === KEYS.codeBlock || key === "code_block") return "code_block";
758
+ if (key === KEYS.td || key === KEYS.th) return "table_cell";
759
+ if (MEDIA_TYPES.has(key)) return "media";
760
+ const pType = getPluginType(editor, KEYS.p) ?? KEYS.p;
761
+ if (node.type === pType) return "paragraph";
762
+ if (SEGMENT_SKIP_TYPES.has(key)) return null;
763
+ if (Array.isArray(node.children)) return "block";
764
+ return null;
765
+ };
766
+ const buildSource = (node, editor) => {
767
+ if (!node || typeof node !== "object" || !Array.isArray(node.children)) return null;
768
+ const kind = slateNodeKind(node, editor);
769
+ if (!kind) return null;
770
+ const path = Array.isArray(node.__sourceMapPath) ? node.__sourceMapPath : null;
771
+ if (!path) return null;
772
+ const text = collectSlateText(node);
773
+ if (!text.trim() && kind !== "media" && kind !== "block") return null;
774
+ return {
775
+ containsMdx: false,
776
+ kind,
777
+ nodeId: typeof node.id === "string" ? node.id : void 0,
778
+ path,
779
+ pathKey: toPathKey(path),
780
+ text
781
+ };
782
+ };
783
+ const attachSource = (mdastNode, source) => {
784
+ if (!source || !mdastNode || typeof mdastNode !== "object") return mdastNode;
785
+ mdastNode.data = {
786
+ ...mdastNode.data ?? {},
787
+ sourceMap: source
788
+ };
789
+ return mdastNode;
790
+ };
791
+ const shouldIncludeText = (text, options) => {
792
+ const { allowedNodes, allowNode, disallowedNodes } = options;
793
+ if (allowedNodes && disallowedNodes && allowedNodes.length > 0 && disallowedNodes.length > 0) throw new Error("Cannot combine allowedNodes with disallowedNodes");
794
+ for (const [key, value] of Object.entries(text)) {
795
+ if (key === "text") continue;
796
+ if (allowedNodes) {
797
+ if (!allowedNodes.includes(key) && value) return false;
798
+ } else if (disallowedNodes?.includes(key) && value) return false;
799
+ }
800
+ if (allowNode?.serialize) return allowNode.serialize(text);
801
+ return true;
802
+ };
803
+ const shouldIncludeNode$1 = (node, options) => {
804
+ const { allowedNodes, allowNode, disallowedNodes } = options;
805
+ if (!node.type) return true;
806
+ if (allowedNodes && disallowedNodes && allowedNodes.length > 0 && disallowedNodes.length > 0) throw new Error("Cannot combine allowedNodes with disallowedNodes");
807
+ if (allowedNodes) {
808
+ if (!allowedNodes.includes(node.type)) return false;
809
+ } else if (disallowedNodes?.includes(node.type)) return false;
810
+ if (allowNode?.serialize) return allowNode.serialize(node);
811
+ return true;
812
+ };
813
+ /**
814
+ * After building a table mdast node, attach sourceMap to individual cells by
815
+ * walking the Slate table and mdast table in parallel.
816
+ */
817
+ const attachTableCellSources = (mdastTable, slateTable, editor) => {
818
+ const mdastRows = mdastTable.children || [];
819
+ const slateRows = slateTable.children || [];
820
+ for (let r = 0; r < Math.min(mdastRows.length, slateRows.length); r++) {
821
+ const mdastCells = mdastRows[r]?.children || [];
822
+ const slateCells = slateRows[r]?.children || [];
823
+ for (let c = 0; c < Math.min(mdastCells.length, slateCells.length); c++) {
824
+ const source = buildSource(slateCells[c], editor);
825
+ if (source) attachSource(mdastCells[c], source);
826
+ }
827
+ }
828
+ };
829
+ const buildMdastNodeWithSource = (node, options, isBlock = false) => {
830
+ let mdastNode = buildMdastNode(node, options, isBlock);
831
+ if (!mdastNode) {
832
+ const text = collectSlateText(node);
833
+ if (text.trim()) mdastNode = {
834
+ children: [{
835
+ type: "text",
836
+ value: text
837
+ }],
838
+ type: "paragraph"
839
+ };
840
+ else mdastNode = {
841
+ type: "html",
842
+ value: `<!-- ${node.type ?? "unknown"} -->`
843
+ };
844
+ }
845
+ if (mdastNode?.type === "table") {
846
+ attachTableCellSources(mdastNode, node, options.editor);
847
+ return mdastNode;
848
+ }
849
+ const source = buildSource(node, options.editor);
850
+ if (!source) {
851
+ if (mdastNode && MDX_MDAST_TYPES.has(mdastNode.type ?? "")) propagateMdxFlag(mdastNode);
852
+ return mdastNode;
853
+ }
854
+ if (MDX_MDAST_TYPES.has(mdastNode?.type ?? "")) {
855
+ source.containsMdx = true;
856
+ if (Array.isArray(mdastNode?.children)) for (const child of mdastNode.children) propagateMdxFlag(child);
857
+ }
858
+ if (source.kind === "blockquote" && Array.isArray(mdastNode?.children) && mdastNode.children[0]) {
859
+ attachSource(mdastNode.children[0], source);
860
+ return mdastNode;
861
+ }
862
+ return attachSource(mdastNode, source);
863
+ };
864
+ const convertNodesWithSource = (nodes, options, isBlock = false) => {
865
+ const mdastNodes = [];
866
+ let textQueue = [];
867
+ const listBlock = [];
868
+ for (let i = 0; i <= nodes.length; i++) {
869
+ const n = nodes[i];
870
+ if (n && TextApi.isText(n)) {
871
+ if (shouldIncludeText(n, options)) textQueue.push(n);
872
+ continue;
873
+ }
874
+ if (textQueue.length > 0) mdastNodes.push(...convertTextsSerialize(textQueue, options));
875
+ textQueue = [];
876
+ if (!n) continue;
877
+ if (!shouldIncludeNode$1(n, options)) continue;
878
+ const pType = getPluginType(options.editor, KEYS.p) ?? KEYS.p;
879
+ if (n?.type === pType && "listStyleType" in n) {
880
+ listBlock.push(n);
881
+ const next = nodes[i + 1];
882
+ const isNextIndent = next && next.type === pType && "listStyleType" in next;
883
+ const firstList = listBlock.at(0);
884
+ const hasDifferentListStyle = isNextIndent && firstList && next.listStyleType !== firstList.listStyleType && next.indent === firstList.indent;
885
+ if (!isNextIndent || hasDifferentListStyle) {
886
+ mdastNodes.push(listToMdastTreeWithSource(listBlock, options));
887
+ listBlock.length = 0;
888
+ }
889
+ continue;
890
+ }
891
+ const node = buildMdastNodeWithSource(n, options, isBlock);
892
+ if (node) mdastNodes.push(node);
893
+ }
894
+ return mdastNodes;
895
+ };
896
+ const listToMdastTreeWithSource = (nodes, options) => {
897
+ const root = {
898
+ children: [],
899
+ ordered: nodes[0].listStyleType === "decimal",
900
+ spread: options.spread ?? false,
901
+ start: nodes[0].listStart,
902
+ type: "list"
903
+ };
904
+ const indentStack = [{
905
+ indent: nodes[0].indent,
906
+ list: root,
907
+ parent: null,
908
+ styleType: nodes[0].listStyleType
909
+ }];
910
+ for (let i = 0; i < nodes.length; i++) {
911
+ const node = nodes[i];
912
+ const currentIndent = node.indent;
913
+ while (indentStack.length > 1 && indentStack.at(-1).indent > currentIndent) indentStack.pop();
914
+ let stackTop = indentStack.at(-1);
915
+ if (stackTop.indent === currentIndent && stackTop.styleType !== node.listStyleType && !!stackTop.parent) {
916
+ const siblingList = {
917
+ children: [],
918
+ ordered: node.listStyleType === "decimal",
919
+ spread: options.spread ?? false,
920
+ start: node.listStart,
921
+ type: "list"
922
+ };
923
+ stackTop.parent.children.push(siblingList);
924
+ indentStack[indentStack.length - 1] = {
925
+ indent: currentIndent,
926
+ list: siblingList,
927
+ parent: stackTop.parent,
928
+ styleType: node.listStyleType
929
+ };
930
+ stackTop = indentStack.at(-1);
931
+ }
932
+ const paragraph = {
933
+ children: convertNodesWithSource(node.children, options),
934
+ type: "paragraph"
935
+ };
936
+ attachSource(paragraph, buildSource(node, options.editor));
937
+ const listItem = {
938
+ checked: null,
939
+ children: [paragraph],
940
+ spread: options.spread ?? false,
941
+ type: "listItem"
942
+ };
943
+ if (node.listStyleType === "todo" && node.checked !== void 0) listItem.checked = node.checked;
944
+ stackTop.list.children.push(listItem);
945
+ const nextNode = nodes[i + 1];
946
+ if (nextNode && nextNode.indent > currentIndent) {
947
+ const nestedList = {
948
+ children: [],
949
+ ordered: nextNode.listStyleType === "decimal",
950
+ spread: options.spread ?? false,
951
+ start: nextNode.listStart,
952
+ type: "list"
953
+ };
954
+ listItem.children.push(nestedList);
955
+ indentStack.push({
956
+ indent: nextNode.indent,
957
+ list: nestedList,
958
+ parent: listItem,
959
+ styleType: nextNode.listStyleType
960
+ });
961
+ }
962
+ }
963
+ return root;
964
+ };
965
+ const collectExtensionHandlers = (extensions, into) => {
966
+ if (!extensions) return into;
967
+ for (const ext of extensions) {
968
+ if (!ext) continue;
969
+ if (Array.isArray(ext)) {
970
+ collectExtensionHandlers(ext, into);
971
+ continue;
972
+ }
973
+ if (Array.isArray(ext.extensions)) collectExtensionHandlers(ext.extensions, into);
974
+ if (ext.handlers) Object.assign(into, ext.handlers);
975
+ }
976
+ return into;
977
+ };
978
+ /**
979
+ * Strip `handlers` from extension objects so that `toMarkdown`'s `configure()`
980
+ * won't overwrite our wrapped handlers while keeping `unsafe`, `join`, etc.
981
+ */
982
+ const stripExtensionHandlers = (extensions) => extensions.map((ext) => {
983
+ if (!ext) return ext;
984
+ if (Array.isArray(ext)) return stripExtensionHandlers(ext);
985
+ if (typeof ext !== "object") return ext;
986
+ const { handlers: _h, ...rest } = ext;
987
+ if (Array.isArray(rest.extensions)) rest.extensions = stripExtensionHandlers(rest.extensions);
988
+ return rest;
989
+ });
990
+ const serializeMdWithSourceMap = (editor, options) => {
991
+ const mergedOptions = getMergedOptionsSerialize(editor, options);
992
+ const mdast = {
993
+ children: convertNodesWithSource((mergedOptions.value ?? editor.children).map((child, index) => annotatePaths(child, [index])), mergedOptions, true),
994
+ type: "root"
995
+ };
996
+ const extensionProcessor = unified().use(mergedOptions.remarkPlugins ?? []);
997
+ try {
998
+ extensionProcessor.freeze();
999
+ } catch {}
1000
+ const extensions = extensionProcessor.data("toMarkdownExtensions") ?? [];
1001
+ const handlers = { ...defaultHandlers };
1002
+ collectExtensionHandlers(extensions, handlers);
1003
+ const segments = [];
1004
+ const wrappedHandlers = {};
1005
+ const pushSegment = (source, emitted, startLine, endLine) => {
1006
+ segments.push({
1007
+ containsMdx: source.containsMdx,
1008
+ endLine,
1009
+ kind: source.kind,
1010
+ markdown: emitted,
1011
+ nodeId: source.nodeId,
1012
+ path: source.path,
1013
+ pathKey: source.pathKey,
1014
+ startLine,
1015
+ text: source.text
1016
+ });
1017
+ };
1018
+ for (const [type, handler] of Object.entries(handlers)) wrappedHandlers[type] = (node, parent, state, info) => {
1019
+ const startLine = info.now.line;
1020
+ const emitted = handler(node, parent, state, info);
1021
+ const source = node?.data?.sourceMap;
1022
+ if (source && emitted.trim()) pushSegment(source, emitted, startLine, startLine + (emitted.split(/\r?\n|\r/g).length - 1));
1023
+ if (type === "table" && Array.isArray(node?.children)) for (let r = 0; r < node.children.length; r++) {
1024
+ const line = r === 0 ? startLine : startLine + 1 + r;
1025
+ const cells = node.children[r]?.children;
1026
+ if (!Array.isArray(cells)) continue;
1027
+ for (const cell of cells) {
1028
+ const cellSource = cell?.data?.sourceMap;
1029
+ if (cellSource) pushSegment(cellSource, emitted, line, line);
1030
+ }
1031
+ }
1032
+ return emitted;
1033
+ };
1034
+ const markdown = toMarkdown(mdast, {
1035
+ emphasis: "_",
1036
+ ...mergedOptions.remarkStringifyOptions ?? {},
1037
+ extensions: stripExtensionHandlers(extensions),
1038
+ handlers: wrappedHandlers
1039
+ });
1040
+ const deduped = /* @__PURE__ */ new Map();
1041
+ for (const seg of segments) {
1042
+ const existing = deduped.get(seg.pathKey);
1043
+ const span = seg.endLine - seg.startLine;
1044
+ const existingSpan = existing ? existing.endLine - existing.startLine : Number.POSITIVE_INFINITY;
1045
+ if (!existing || span <= existingSpan) deduped.set(seg.pathKey, seg);
1046
+ }
1047
+ const ordered = Array.from(deduped.values()).sort((a, b) => comparePaths(a.path, b.path));
1048
+ return {
1049
+ markdown,
1050
+ segments: ordered.filter((seg) => !ordered.some((other) => other !== seg && isPathPrefix(seg.path, other.path)))
1051
+ };
1052
+ };
1053
+
696
1054
  //#endregion
697
1055
  //#region src/lib/rules/defaultRules.ts
698
1056
  const LEADING_NEWLINE_REGEX = /^\n/;
699
1057
  function isBoolean(value) {
700
1058
  return value === true || value === false || !!value && typeof value === "object" && Object.prototype.toString.call(value) === "[object Boolean]";
701
1059
  }
1060
+ const createClassicListItemContent = (editor, children = []) => ({
1061
+ children: children.length > 0 ? children : [{ text: "" }],
1062
+ type: getPluginType(editor, KEYS.lic)
1063
+ });
1064
+ const deserializeClassicListItemChildren = (mdastChildren, deco, options) => {
1065
+ const licType = getPluginType(options.editor, KEYS.lic);
1066
+ const children = mdastChildren.map((child) => {
1067
+ if (child.type === "paragraph") return createClassicListItemContent(options.editor, convertChildrenDeserialize(child.children, deco, options));
1068
+ return convertChildrenDeserialize([child], deco, options)[0];
1069
+ }).filter(Boolean);
1070
+ if (!children.some((child) => child.type === licType)) children.unshift(createClassicListItemContent(options.editor));
1071
+ return children;
1072
+ };
702
1073
  const defaultRules = {
703
1074
  a: {
704
1075
  deserialize: (mdastNode, deco, options) => ({
@@ -989,13 +1360,7 @@ const defaultRules = {
989
1360
  if (!!!options.editor?.plugins.list) return {
990
1361
  children: mdastNode.children.map((child) => {
991
1362
  if (child.type === "listItem") return {
992
- children: child.children.map((itemChild) => {
993
- if (itemChild.type === "paragraph") return {
994
- children: convertChildrenDeserialize(itemChild.children, deco, options),
995
- type: getPluginType(options.editor, KEYS.lic)
996
- };
997
- return convertChildrenDeserialize([itemChild], deco, options)[0];
998
- }),
1363
+ children: deserializeClassicListItemChildren(child.children, deco, options),
999
1364
  type: getPluginType(options.editor, KEYS.li)
1000
1365
  };
1001
1366
  return convertChildrenDeserialize([child], deco, options)[0];
@@ -1015,7 +1380,7 @@ const defaultRules = {
1015
1380
  children: [{ text: "" }],
1016
1381
  type: getPluginType(options.editor, KEYS.p)
1017
1382
  };
1018
- (Array.isArray(result) ? result : [result]).forEach((node) => {
1383
+ (Array.isArray(result) ? result : [result]).forEach((node, nodeIndex) => {
1019
1384
  const itemContent = {
1020
1385
  ...node,
1021
1386
  indent,
@@ -1023,7 +1388,10 @@ const defaultRules = {
1023
1388
  };
1024
1389
  itemContent.listStyleType = listStyleType;
1025
1390
  if (isTodoList) itemContent.checked = listItem.checked;
1026
- if (isOrdered) itemContent.listStart = startIndex + index;
1391
+ if (isOrdered) {
1392
+ itemContent.listStart = startIndex + index;
1393
+ if (index === 0 && nodeIndex === 0 && itemContent.listStart > 1) itemContent.listRestartPolite = itemContent.listStart;
1394
+ }
1027
1395
  items.push(itemContent);
1028
1396
  });
1029
1397
  subLists.forEach((subNode) => {
@@ -1084,18 +1452,10 @@ const defaultRules = {
1084
1452
  }
1085
1453
  },
1086
1454
  listItem: {
1087
- deserialize: (mdastNode, deco, options) => {
1088
- return {
1089
- children: mdastNode.children.map((child) => {
1090
- if (child.type === "paragraph") return {
1091
- children: convertChildrenDeserialize(child.children, deco, options),
1092
- type: getPluginType(options.editor, KEYS.lic)
1093
- };
1094
- return convertChildrenDeserialize([child], deco, options)[0];
1095
- }),
1096
- type: getPluginType(options.editor, KEYS.li)
1097
- };
1098
- },
1455
+ deserialize: (mdastNode, deco, options) => ({
1456
+ children: deserializeClassicListItemChildren(mdastNode.children, deco, options),
1457
+ type: getPluginType(options.editor, KEYS.li)
1458
+ }),
1099
1459
  serialize: (node, options) => ({
1100
1460
  children: convertNodesSerialize(node.children, options),
1101
1461
  type: "listItem"
@@ -1462,17 +1822,17 @@ const stripMarkdown = (text) => {
1462
1822
  const LEADING_SPACES_REGEX = /^\s*/;
1463
1823
  const TRAILING_SPACES_REGEX = /\s*$/;
1464
1824
  const deserializeInlineMd = (editor, text, options) => {
1825
+ const trimmedText = text.trim();
1465
1826
  const leadingSpaces = LEADING_SPACES_REGEX.exec(text)?.[0] || "";
1466
1827
  const trailingSpaces = TRAILING_SPACES_REGEX.exec(text)?.[0] || "";
1467
- const strippedText = stripMarkdownBlocks(text.trim());
1828
+ const strippedText = stripMarkdownBlocks(trimmedText);
1829
+ if (!strippedText) return text ? [{ text }] : [];
1468
1830
  const fragment = [];
1469
1831
  if (leadingSpaces) fragment.push({ text: leadingSpaces });
1470
- if (strippedText) {
1471
- const result = editor.getApi(MarkdownPlugin).markdown.deserialize(strippedText, options)[0];
1472
- if (result) {
1473
- const nodes = ElementApi.isElement(result) ? result.children : [result];
1474
- fragment.push(...nodes);
1475
- }
1832
+ const result = editor.getApi(MarkdownPlugin).markdown.deserialize(strippedText, options)[0];
1833
+ if (result) {
1834
+ const nodes = ElementApi.isElement(result) ? result.children : [result];
1835
+ fragment.push(...nodes);
1476
1836
  }
1477
1837
  if (trailingSpaces) fragment.push({ text: trailingSpaces });
1478
1838
  return fragment;
@@ -1692,6 +2052,7 @@ const splitIncompleteMdx = (data) => {
1692
2052
  }
1693
2053
  const tagName = data.slice(nameStart, i).toLowerCase();
1694
2054
  let inQuote = null;
2055
+ let foundTagEnd = false;
1695
2056
  let selfClosing = false;
1696
2057
  while (i < len) {
1697
2058
  const ch = data[i];
@@ -1699,13 +2060,14 @@ const splitIncompleteMdx = (data) => {
1699
2060
  if (ch === inQuote) inQuote = null;
1700
2061
  } else if (ch === "\"" || ch === "'") inQuote = ch;
1701
2062
  else if (ch === ">") {
2063
+ foundTagEnd = true;
1702
2064
  selfClosing = data[i - 1] === "/";
1703
2065
  i++;
1704
2066
  break;
1705
2067
  }
1706
2068
  i++;
1707
2069
  }
1708
- if (i >= len) {
2070
+ if (!foundTagEnd) {
1709
2071
  cutPos = tagStart;
1710
2072
  break;
1711
2073
  }
@@ -1741,7 +2103,6 @@ const markdownToSlateNodesSafely = (editor, data, options) => {
1741
2103
  withoutMdx: true
1742
2104
  });
1743
2105
  const completeNodes = markdownToSlateNodes(editor, completeString, options);
1744
- if (incompleteNodes.length === 0) return completeNodes;
1745
2106
  const newBlock = {
1746
2107
  children: incompleteNodes,
1747
2108
  type: getPluginType(editor, KEYS.p)
@@ -1931,5 +2292,4 @@ const remarkMention = () => (tree) => {
1931
2292
  };
1932
2293
 
1933
2294
  //#endregion
1934
- export { MarkdownPlugin, REMARK_MDX_TAG, basicMarkdownMarks, buildMdastNode, buildRules, buildSlateNode, columnRules, convertChildrenDeserialize, convertNodesDeserialize, convertNodesSerialize, convertTextsDeserialize, convertTextsSerialize, customMdxDeserialize, defaultRules, deserializeInlineMd, deserializeMd, fontRules, getCustomMark, getDeserializerByKey, getMergedOptionsDeserialize, getMergedOptionsSerialize, getRemarkPluginsWithoutMdx, getSerializerByKey, getStyleValue, htmlToJsx, listToMdastTree, markdownToAstProcessor, markdownToSlateNodes, markdownToSlateNodesSafely, mdastToPlate, mdastToSlate, mediaRules, parseAttributes, parseMarkdownBlocks, plateToMdast, propsToAttributes, remarkMdx, remarkMention, serializeInlineMd, serializeMd, splitIncompleteMdx, stripMarkdown, stripMarkdownBlocks, stripMarkdownInline, tagRemarkPlugin, unreachable, wrapWithBlockId };
1935
- //# sourceMappingURL=index.js.map
2295
+ export { MarkdownPlugin, REMARK_MDX_TAG, basicMarkdownMarks, buildMdastNode, buildRules, buildSlateNode, columnRules, convertChildrenDeserialize, convertNodesDeserialize, convertNodesSerialize, convertTextsDeserialize, convertTextsSerialize, customMdxDeserialize, defaultRules, deserializeInlineMd, deserializeMd, fontRules, getCustomMark, getDeserializerByKey, getMergedOptionsDeserialize, getMergedOptionsSerialize, getRemarkPluginsWithoutMdx, getSerializerByKey, getStyleValue, htmlToJsx, listToMdastTree, markdownToAstProcessor, markdownToSlateNodes, markdownToSlateNodesSafely, mdastToPlate, mdastToSlate, mediaRules, parseAttributes, parseMarkdownBlocks, plateToMdast, propsToAttributes, remarkMdx, remarkMention, serializeInlineMd, serializeMd, serializeMdWithSourceMap, splitIncompleteMdx, stripMarkdown, stripMarkdownBlocks, stripMarkdownInline, tagRemarkPlugin, unreachable, wrapWithBlockId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lofcz/platejs-markdown",
3
- "version": "52.3.5",
3
+ "version": "52.3.8",
4
4
  "description": "Markdown serializer plugin for Plate",
5
5
  "keywords": [
6
6
  "markdown",
@@ -33,6 +33,7 @@
33
33
  "dependencies": {
34
34
  "lodash": "^4.17.23",
35
35
  "marked": "^15.0.12",
36
+ "mdast-util-to-markdown": "^2.1.2",
36
37
  "mdast-util-math": "3.0.0",
37
38
  "mdast-util-mdx": "3.0.0",
38
39
  "react-compiler-runtime": "^1.0.0",
@@ -48,7 +49,8 @@
48
49
  "@types/unist": "^3.0.3",
49
50
  "remark-gfm": "4.0.1",
50
51
  "remark-math": "6.0.0",
51
- "@plate/scripts": "1.0.0"
52
+ "@plate/scripts": "1.0.0",
53
+ "platejs": "npm:@lofcz/platejs@52.3.6"
52
54
  },
53
55
  "peerDependencies": {
54
56
  "platejs": ">=52.0.11",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/deserializer/utils/customMdxDeserialize.ts","../src/lib/deserializer/utils/deserializeInlineMd.ts","../src/lib/deserializer/utils/getDeserializerByKey.ts","../src/lib/deserializer/utils/getMergedOptionsDeserialize.ts","../src/lib/deserializer/utils/getStyleValue.ts","../src/lib/deserializer/utils/htmlToJsx.ts","../src/lib/deserializer/utils/markdownToSlateNodesSafely.ts","../src/lib/deserializer/utils/parseMarkdownBlocks.ts","../src/lib/deserializer/utils/splitIncompleteMdx.ts","../src/lib/deserializer/utils/stripMarkdown.ts","../src/lib/deserializer/deserializeMd.ts","../src/lib/deserializer/convertChildrenDeserialize.ts","../src/lib/deserializer/convertNodesDeserialize.ts","../src/lib/deserializer/convertTextsDeserialize.ts","../src/lib/deserializer/mdastToSlate.ts","../src/lib/serializer/serializeMd.ts","../src/lib/serializer/convertNodesSerialize.ts","../src/lib/serializer/convertTextsSerialize.ts","../src/lib/serializer/listToMdastTree.ts","../src/lib/serializer/serializeInlineMd.ts","../src/lib/serializer/wrapWithBlockId.ts","../src/lib/serializer/utils/getCustomMark.ts","../src/lib/serializer/utils/getMergedOptionsSerialize.ts","../src/lib/serializer/utils/getSerializerByKey.ts","../src/lib/serializer/utils/unreachable.ts","../src/lib/types.ts","../src/lib/MarkdownPlugin.ts","../src/lib/plugins/remarkMdx.ts","../src/lib/plugins/remarkMention.ts","../src/lib/rules/columnRules.ts","../src/lib/rules/defaultRules.ts","../src/lib/rules/fontRules.ts","../src/lib/rules/mediaRules.ts","../src/lib/rules/utils/parseAttributes.ts","../src/lib/utils/getRemarkPluginsWithoutMdx.ts"],"sourcesContent":[],"mappings":"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"}