@lofcz/platejs-markdown 52.3.6 → 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.d.ts CHANGED
@@ -43,6 +43,26 @@ declare function listToMdastTree(nodes: TListElement[], options: SerializeMdOpti
43
43
  //#region src/lib/serializer/serializeInlineMd.d.ts
44
44
  declare const serializeInlineMd: (editor: SlateEditor, options?: SerializeMdOptions) => string;
45
45
  //#endregion
46
+ //#region src/lib/serializer/serializeMdWithSourceMap.d.ts
47
+ type SelectionPath = number[];
48
+ type MarkdownSourceMapKind = 'block' | 'blockquote' | 'code_block' | 'heading' | 'list_item' | 'media' | 'paragraph' | 'table_cell';
49
+ type MarkdownSourceMapSegment = {
50
+ containsMdx: boolean;
51
+ endLine: number;
52
+ kind: MarkdownSourceMapKind;
53
+ markdown: string;
54
+ nodeId?: string;
55
+ path: SelectionPath;
56
+ pathKey: string;
57
+ startLine: number;
58
+ text: string;
59
+ };
60
+ type SerializeMdSourceMapResult = {
61
+ markdown: string;
62
+ segments: MarkdownSourceMapSegment[];
63
+ };
64
+ declare const serializeMdWithSourceMap: (editor: SlateEditor, options?: Omit<SerializeMdOptions, "editor">) => SerializeMdSourceMapResult;
65
+ //#endregion
46
66
  //#region src/lib/serializer/wrapWithBlockId.d.ts
47
67
  /**
48
68
  * Wraps an mdast node with a block element containing an ID attribute. Used for
@@ -494,4 +514,4 @@ declare const tagRemarkPlugin: (pluginFn: any, tag: string) => {
494
514
  };
495
515
  declare const getRemarkPluginsWithoutMdx: (plugins: Plugin[]) => Plugin[];
496
516
  //#endregion
497
- export { AllowNodeConfig, DeserializeMdOptions, type MDPhrasingContent, MarkdownConfig, MarkdownPlugin, type MdBlockquote, type MdBreak, type MdCode, type MdContent, MdDecoration, type MdDefinition, type MdDelete, type MdEmphasis, type MdFootnoteDefinition, type MdFootnoteReference, type MdHeading, type MdHtml, type MdImage, type MdImageReference, type MdInlineCode, type MdInlineMath, type MdLink, type MdLinkReference, type MdList, type MdListItem, MdMark, type MdMath, type MdMdxJsxFlowElement, type MdMdxJsxTextElement, MdNodeParser, type MdParagraph, type MdRoot, type MdRootContent, MdRules, type MdStrong, type MdTable, type MdTableCell, type MdTableRow, type MdText, type MdThematicBreak, MdType, type MdYaml, MentionNode, ParseMarkdownBlocksOptions, PlateType, REMARK_MDX_TAG, SerializeMdOptions, StrictPlateType, 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, type unistLib, unreachable, wrapWithBlockId };
517
+ export { AllowNodeConfig, DeserializeMdOptions, type MDPhrasingContent, MarkdownConfig, MarkdownPlugin, MarkdownSourceMapKind, MarkdownSourceMapSegment, type MdBlockquote, type MdBreak, type MdCode, type MdContent, MdDecoration, type MdDefinition, type MdDelete, type MdEmphasis, type MdFootnoteDefinition, type MdFootnoteReference, type MdHeading, type MdHtml, type MdImage, type MdImageReference, type MdInlineCode, type MdInlineMath, type MdLink, type MdLinkReference, type MdList, type MdListItem, MdMark, type MdMath, type MdMdxJsxFlowElement, type MdMdxJsxTextElement, MdNodeParser, type MdParagraph, type MdRoot, type MdRootContent, MdRules, type MdStrong, type MdTable, type MdTableCell, type MdTableRow, type MdText, type MdThematicBreak, MdType, type MdYaml, MentionNode, ParseMarkdownBlocksOptions, PlateType, REMARK_MDX_TAG, SerializeMdOptions, SerializeMdSourceMapResult, StrictPlateType, 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, type unistLib, unreachable, wrapWithBlockId };
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";
@@ -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,6 +694,363 @@ 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/;
@@ -1934,4 +2292,4 @@ const remarkMention = () => (tree) => {
1934
2292
  };
1935
2293
 
1936
2294
  //#endregion
1937
- 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 };
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.6",
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",