@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 +21 -1
- package/dist/index.js +363 -5
- package/package.json +2 -1
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$
|
|
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$
|
|
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.
|
|
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",
|