@hywax/mdc-tiptap 0.1.0 → 0.1.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.cjs +559 -537
- package/dist/index.d.cts +51 -30
- package/dist/index.d.mts +51 -30
- package/dist/index.d.ts +51 -30
- package/dist/index.mjs +558 -529
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -11713,603 +11713,625 @@ function normalizeProps(nodeProps, extraProps) {
|
|
|
11713
11713
|
}).filter(([key]) => Boolean(String(key).trim()));
|
|
11714
11714
|
}
|
|
11715
11715
|
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
const defaultMDCToTiptapMap = {
|
|
11724
|
-
...Object.fromEntries(Object.entries(tagToMark).map(([key, value]) => [key, (node) => createMark(node, value)])),
|
|
11725
|
-
root: (node) => ({ type: "doc", content: (node.children || []).flatMap((child) => mdcNodeToTiptap(child, node)) }),
|
|
11726
|
-
text: (node) => createTextNode(node),
|
|
11727
|
-
comment: (node) => createTipTapNode(node, "comment", { attrs: { text: node.value } }),
|
|
11728
|
-
img: (node) => createTipTapNode(node, "image", { attrs: { props: node.props || {}, src: node.props?.src, alt: node.props?.alt } }),
|
|
11729
|
-
video: (node) => createTipTapNode(node, "video"),
|
|
11730
|
-
template: (node) => createTemplateNode(node),
|
|
11731
|
-
pre: (node) => createPreNode(node),
|
|
11732
|
-
p: (node) => createParagraphNode(node),
|
|
11733
|
-
span: (node) => createSpanStyleNode(node),
|
|
11734
|
-
h1: (node) => createTipTapNode(node, "heading", { attrs: { level: 1 } }),
|
|
11735
|
-
h2: (node) => createTipTapNode(node, "heading", { attrs: { level: 2 } }),
|
|
11736
|
-
h3: (node) => createTipTapNode(node, "heading", { attrs: { level: 3 } }),
|
|
11737
|
-
h4: (node) => createTipTapNode(node, "heading", { attrs: { level: 4 } }),
|
|
11738
|
-
h5: (node) => createTipTapNode(node, "heading", { attrs: { level: 5 } }),
|
|
11739
|
-
h6: (node) => createTipTapNode(node, "heading", { attrs: { level: 6 } }),
|
|
11740
|
-
ul: (node) => createTipTapNode(node, "bulletList"),
|
|
11741
|
-
ol: (node) => createTipTapNode(node, "orderedList", { attrs: { start: node.props?.start } }),
|
|
11742
|
-
li: (node) => createTipTapNode(node, "listItem", { children: [{ type: "element", tag: "p", children: node.children }] }),
|
|
11743
|
-
blockquote: (node) => createTipTapNode(node, "blockquote"),
|
|
11744
|
-
binding: (node) => createTipTapNode(node, "binding", { attrs: { value: node.props?.value, defaultValue: node.props?.defaultValue } }),
|
|
11745
|
-
hr: (node) => createTipTapNode(node, "horizontalRule")
|
|
11746
|
-
};
|
|
11747
|
-
function mdcToTiptap(body, options) {
|
|
11748
|
-
body.children = (body.children || []).filter((child) => child.type !== "text");
|
|
11749
|
-
const tree = mdcNodeToTiptap(body, void 0, options?.mdcToTiptapMap);
|
|
11750
|
-
tree.content = isEmpty(tree.content) ? [{ type: "paragraph", content: [] }] : tree.content;
|
|
11751
|
-
return tree;
|
|
11752
|
-
}
|
|
11753
|
-
function mdcNodeToTiptap(node, parent, mdcToTiptapMap) {
|
|
11754
|
-
const type = node.type === "element" ? node.tag : node.type;
|
|
11755
|
-
const nodes = {
|
|
11756
|
-
...mdcToTiptapMap,
|
|
11757
|
-
...defaultMDCToTiptapMap || {}
|
|
11716
|
+
function createMDCToTiptap(options) {
|
|
11717
|
+
const tagToMark = {
|
|
11718
|
+
strong: "bold",
|
|
11719
|
+
em: "italic",
|
|
11720
|
+
del: "strike",
|
|
11721
|
+
code: "code",
|
|
11722
|
+
a: "link"
|
|
11758
11723
|
};
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
node
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
|
|
11770
|
-
|
|
11771
|
-
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
|
|
11777
|
-
|
|
11778
|
-
}
|
|
11724
|
+
const mdcToTiptapMap = {
|
|
11725
|
+
...Object.fromEntries(Object.entries(tagToMark).map(([key, value]) => [key, (node) => createMark(node, value)])),
|
|
11726
|
+
root: (node) => ({ type: "doc", content: (node.children || []).flatMap((child) => mdcNodeToTiptap(child, node)) }),
|
|
11727
|
+
text: (node) => createTextNode(node),
|
|
11728
|
+
comment: (node) => createTipTapNode(node, "comment", { attrs: { text: node.value } }),
|
|
11729
|
+
img: (node) => createTipTapNode(node, "image", { attrs: { props: node.props || {}, src: node.props?.src, alt: node.props?.alt } }),
|
|
11730
|
+
video: (node) => createTipTapNode(node, "video"),
|
|
11731
|
+
template: (node) => createTemplateNode(node),
|
|
11732
|
+
pre: (node) => createPreNode(node),
|
|
11733
|
+
p: (node) => createParagraphNode(node),
|
|
11734
|
+
span: (node) => createSpanStyleNode(node),
|
|
11735
|
+
h1: (node) => createTipTapNode(node, "heading", { attrs: { level: 1 } }),
|
|
11736
|
+
h2: (node) => createTipTapNode(node, "heading", { attrs: { level: 2 } }),
|
|
11737
|
+
h3: (node) => createTipTapNode(node, "heading", { attrs: { level: 3 } }),
|
|
11738
|
+
h4: (node) => createTipTapNode(node, "heading", { attrs: { level: 4 } }),
|
|
11739
|
+
h5: (node) => createTipTapNode(node, "heading", { attrs: { level: 5 } }),
|
|
11740
|
+
h6: (node) => createTipTapNode(node, "heading", { attrs: { level: 6 } }),
|
|
11741
|
+
ul: (node) => createTipTapNode(node, "bulletList"),
|
|
11742
|
+
ol: (node) => createTipTapNode(node, "orderedList", { attrs: { start: node.props?.start } }),
|
|
11743
|
+
li: (node) => createTipTapNode(node, "listItem", { children: [{ type: "element", tag: "p", children: node.children }] }),
|
|
11744
|
+
blockquote: (node) => createTipTapNode(node, "blockquote"),
|
|
11745
|
+
binding: (node) => createTipTapNode(node, "binding", { attrs: { value: node.props?.value, defaultValue: node.props?.defaultValue } }),
|
|
11746
|
+
hr: (node) => createTipTapNode(node, "horizontalRule"),
|
|
11747
|
+
...options?.customMap || {}
|
|
11748
|
+
};
|
|
11749
|
+
function mdcToTiptap(body) {
|
|
11750
|
+
body.children = (body.children || []).filter((child) => child.type !== "text");
|
|
11751
|
+
const tree = mdcNodeToTiptap(body);
|
|
11752
|
+
tree.content = [
|
|
11753
|
+
...isEmpty(tree.content) ? [{ type: "paragraph", content: [] }] : tree.content
|
|
11754
|
+
];
|
|
11755
|
+
return tree;
|
|
11779
11756
|
}
|
|
11780
|
-
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
11784
|
-
const attrs = { ...node.props };
|
|
11785
|
-
if (mark === "link" && attrs.href) {
|
|
11786
|
-
if (attrs.rel && Array.isArray(attrs.rel)) {
|
|
11787
|
-
attrs.rel = attrs.rel.join(" ");
|
|
11757
|
+
function mdcNodeToTiptap(node, parent) {
|
|
11758
|
+
const type = node.type === "element" ? node.tag : node.type;
|
|
11759
|
+
if (mdcToTiptapMap[type]) {
|
|
11760
|
+
return mdcToTiptapMap[type](node);
|
|
11788
11761
|
}
|
|
11789
|
-
|
|
11790
|
-
|
|
11791
|
-
if (isExternal) {
|
|
11792
|
-
attrs.target = attrs.target || "_blank";
|
|
11793
|
-
attrs.rel = attrs.rel || "noopener noreferrer nofollow";
|
|
11762
|
+
if (parent?.tag === "p") {
|
|
11763
|
+
return createTipTapNode(node, "inline-element", { attrs: { tag: type } });
|
|
11794
11764
|
}
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11765
|
+
if (node.type === "element" && node.children?.[0]?.type === "text") {
|
|
11766
|
+
node = {
|
|
11767
|
+
...node,
|
|
11768
|
+
props: {
|
|
11769
|
+
...node.props,
|
|
11770
|
+
__tiptapWrap: true
|
|
11771
|
+
},
|
|
11772
|
+
children: [{
|
|
11773
|
+
type: "element",
|
|
11774
|
+
tag: "p",
|
|
11775
|
+
children: node.children,
|
|
11776
|
+
props: {}
|
|
11777
|
+
}]
|
|
11778
|
+
};
|
|
11800
11779
|
}
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
content += getNodeContent(childNode);
|
|
11804
|
-
});
|
|
11805
|
-
return content;
|
|
11806
|
-
}
|
|
11807
|
-
if (node.type === "element" && node.tag === "code") {
|
|
11808
|
-
return [{
|
|
11809
|
-
type: "text",
|
|
11810
|
-
text: getNodeContent(node),
|
|
11811
|
-
marks: marks.slice().reverse()
|
|
11812
|
-
}];
|
|
11780
|
+
const children = wrapChildrenWithinSlot(node.children || []);
|
|
11781
|
+
return createTipTapNode(node, "element", { attrs: { tag: type }, children });
|
|
11813
11782
|
}
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11783
|
+
function createMark(node, mark, accumulatedMarks = []) {
|
|
11784
|
+
const attrs = { ...node.props };
|
|
11785
|
+
if (mark === "link" && attrs.href) {
|
|
11786
|
+
if (attrs.rel && Array.isArray(attrs.rel)) {
|
|
11787
|
+
attrs.rel = attrs.rel.join(" ");
|
|
11788
|
+
}
|
|
11789
|
+
const href = String(attrs.href);
|
|
11790
|
+
const isExternal = href.startsWith("http://") || href.startsWith("https://");
|
|
11791
|
+
if (isExternal) {
|
|
11792
|
+
attrs.target = attrs.target || "_blank";
|
|
11793
|
+
attrs.rel = attrs.rel || "noopener noreferrer nofollow";
|
|
11794
|
+
}
|
|
11795
|
+
}
|
|
11796
|
+
const marks = [...accumulatedMarks, { type: mark, attrs }];
|
|
11797
|
+
function getNodeContent(node2) {
|
|
11798
|
+
if (node2.type === "text") {
|
|
11799
|
+
return node2.value;
|
|
11800
|
+
}
|
|
11801
|
+
let content = "";
|
|
11802
|
+
node2.children?.forEach((childNode) => {
|
|
11803
|
+
content += getNodeContent(childNode);
|
|
11804
|
+
});
|
|
11805
|
+
return content;
|
|
11806
|
+
}
|
|
11807
|
+
if (node.type === "element" && node.tag === "code") {
|
|
11808
|
+
return [{
|
|
11817
11809
|
type: "text",
|
|
11818
|
-
text: getNodeContent(
|
|
11810
|
+
text: getNodeContent(node),
|
|
11819
11811
|
marks: marks.slice().reverse()
|
|
11820
|
-
};
|
|
11821
|
-
}
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11812
|
+
}];
|
|
11813
|
+
}
|
|
11814
|
+
return (node.children || []).map((child) => {
|
|
11815
|
+
if (child.type === "text") {
|
|
11816
|
+
return {
|
|
11817
|
+
type: "text",
|
|
11818
|
+
text: getNodeContent(child),
|
|
11819
|
+
marks: marks.slice().reverse()
|
|
11820
|
+
};
|
|
11821
|
+
} else if (child.type === "element" && tagToMark[child.tag]) {
|
|
11822
|
+
return createMark(child, tagToMark[child.tag], marks);
|
|
11823
|
+
} else if (child.type === "element") {
|
|
11824
|
+
const tiptapNode = mdcNodeToTiptap(child, node);
|
|
11825
|
+
if (tiptapNode.content?.length) {
|
|
11826
|
+
tiptapNode.content.forEach((c) => {
|
|
11827
|
+
if (c.type === "text") {
|
|
11828
|
+
c.marks = marks.slice().reverse();
|
|
11829
|
+
}
|
|
11830
|
+
});
|
|
11831
|
+
}
|
|
11832
|
+
return tiptapNode;
|
|
11833
|
+
}
|
|
11834
|
+
return mdcNodeToTiptap(child, node);
|
|
11835
|
+
}).flat();
|
|
11836
|
+
}
|
|
11837
|
+
function createTipTapNode(node, type, extra = {}) {
|
|
11838
|
+
const { attrs = {}, children, ...rest } = extra;
|
|
11839
|
+
const cleanProps = Object.entries({ ...attrs.props || {}, ...node.props || {} }).map(([key, value]) => {
|
|
11840
|
+
if (key.startsWith("__mdc_")) {
|
|
11841
|
+
return void 0;
|
|
11831
11842
|
}
|
|
11832
|
-
return
|
|
11843
|
+
return ["className", "class"].includes(key.trim()) ? ["class", typeof value === "string" ? value : value.join(" ")] : [key.trim(), value];
|
|
11844
|
+
}).filter(Boolean);
|
|
11845
|
+
const tiptapNode = {
|
|
11846
|
+
type,
|
|
11847
|
+
...rest,
|
|
11848
|
+
attrs
|
|
11849
|
+
};
|
|
11850
|
+
if (cleanProps.length) {
|
|
11851
|
+
tiptapNode.attrs.props = Object.fromEntries(cleanProps);
|
|
11833
11852
|
}
|
|
11834
|
-
|
|
11835
|
-
|
|
11836
|
-
}
|
|
11837
|
-
function createTipTapNode(node, type, extra = {}) {
|
|
11838
|
-
const { attrs = {}, children, ...rest } = extra;
|
|
11839
|
-
const cleanProps = Object.entries({ ...attrs.props || {}, ...node.props || {} }).map(([key, value]) => {
|
|
11840
|
-
if (key.startsWith("__mdc_")) {
|
|
11841
|
-
return void 0;
|
|
11853
|
+
if (children || node.children) {
|
|
11854
|
+
tiptapNode.content = (children || node.children || []).flatMap((child) => mdcNodeToTiptap(child, node));
|
|
11842
11855
|
}
|
|
11843
|
-
return
|
|
11844
|
-
}).filter(Boolean);
|
|
11845
|
-
const tiptapNode = {
|
|
11846
|
-
type,
|
|
11847
|
-
...rest,
|
|
11848
|
-
attrs
|
|
11849
|
-
};
|
|
11850
|
-
if (cleanProps.length) {
|
|
11851
|
-
tiptapNode.attrs.props = Object.fromEntries(cleanProps);
|
|
11856
|
+
return tiptapNode;
|
|
11852
11857
|
}
|
|
11853
|
-
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
11861
|
-
|
|
11862
|
-
|
|
11863
|
-
|
|
11864
|
-
children: node.children,
|
|
11865
|
-
props: {}
|
|
11866
|
-
}];
|
|
11858
|
+
function createTemplateNode(node) {
|
|
11859
|
+
const name = Object.keys(node.props || {}).find((prop) => prop?.startsWith("v-slot:"))?.replace("v-slot:", "") || "default";
|
|
11860
|
+
if (node.children?.[0]?.type === "text") {
|
|
11861
|
+
node.children = [{
|
|
11862
|
+
type: "element",
|
|
11863
|
+
tag: "p",
|
|
11864
|
+
children: node.children,
|
|
11865
|
+
props: {}
|
|
11866
|
+
}];
|
|
11867
|
+
}
|
|
11868
|
+
return createTipTapNode(node, "slot", { attrs: { name } });
|
|
11867
11869
|
}
|
|
11868
|
-
|
|
11869
|
-
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
|
|
11870
|
+
function createPreNode(node) {
|
|
11871
|
+
const tiptapNode = createTipTapNode(node, "codeBlock", {
|
|
11872
|
+
attrs: {
|
|
11873
|
+
language: node.props?.language || "text",
|
|
11874
|
+
filename: node.props?.filename
|
|
11875
|
+
}
|
|
11876
|
+
});
|
|
11877
|
+
if (tiptapNode.content.length === 1 && tiptapNode.content[0].text === "") {
|
|
11878
|
+
tiptapNode.content = [];
|
|
11875
11879
|
}
|
|
11876
|
-
|
|
11877
|
-
|
|
11878
|
-
|
|
11880
|
+
tiptapNode.content.forEach((child) => {
|
|
11881
|
+
delete child.marks;
|
|
11882
|
+
});
|
|
11883
|
+
return tiptapNode;
|
|
11879
11884
|
}
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11885
|
+
function createParagraphNode(node) {
|
|
11886
|
+
if (node.children?.length && node.children?.every((child) => child.tag === "img")) {
|
|
11887
|
+
return node.children?.map((child) => mdcToTiptapMap.img(child));
|
|
11888
|
+
}
|
|
11889
|
+
node.children = node.children?.filter((child) => !(child.type === "text" && !child.value)) || [];
|
|
11890
|
+
const content = node.children.map((child) => mdcNodeToTiptap(child, node)).flat();
|
|
11891
|
+
return {
|
|
11892
|
+
type: "paragraph",
|
|
11893
|
+
content,
|
|
11894
|
+
attrs: isEmpty(node.props) ? void 0 : node.props
|
|
11895
|
+
};
|
|
11888
11896
|
}
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
|
|
11900
|
-
|
|
11901
|
-
text.replace(EMOJI_REGEXP, (match, offset) => {
|
|
11902
|
-
if (lastIndex < offset) {
|
|
11897
|
+
function createTextNode(node) {
|
|
11898
|
+
const text = node.value;
|
|
11899
|
+
const nodes = [];
|
|
11900
|
+
let lastIndex = 0;
|
|
11901
|
+
text.replace(EMOJI_REGEXP, (match, offset) => {
|
|
11902
|
+
if (lastIndex < offset) {
|
|
11903
|
+
nodes.push({
|
|
11904
|
+
type: "text",
|
|
11905
|
+
text: text.slice(lastIndex, offset)
|
|
11906
|
+
});
|
|
11907
|
+
}
|
|
11908
|
+
const emojiUnicode = getEmojiUnicode(match.substring(1, match.length - 1));
|
|
11903
11909
|
nodes.push({
|
|
11904
11910
|
type: "text",
|
|
11905
|
-
text:
|
|
11911
|
+
text: emojiUnicode || match
|
|
11906
11912
|
});
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
nodes.push({
|
|
11910
|
-
type: "text",
|
|
11911
|
-
text: emojiUnicode || match
|
|
11912
|
-
});
|
|
11913
|
-
lastIndex = offset + match.length;
|
|
11914
|
-
return "";
|
|
11915
|
-
});
|
|
11916
|
-
if (lastIndex < text.length) {
|
|
11917
|
-
nodes.push({
|
|
11918
|
-
type: "text",
|
|
11919
|
-
text: text.slice(lastIndex)
|
|
11913
|
+
lastIndex = offset + match.length;
|
|
11914
|
+
return "";
|
|
11920
11915
|
});
|
|
11916
|
+
if (lastIndex < text.length) {
|
|
11917
|
+
nodes.push({
|
|
11918
|
+
type: "text",
|
|
11919
|
+
text: text.slice(lastIndex)
|
|
11920
|
+
});
|
|
11921
|
+
}
|
|
11922
|
+
return nodes.length === 0 ? { type: "text", text } : nodes;
|
|
11921
11923
|
}
|
|
11922
|
-
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
}
|
|
11949
|
-
children
|
|
11950
|
-
}
|
|
11951
|
-
children
|
|
11924
|
+
function createSpanStyleNode(node) {
|
|
11925
|
+
const spanStyle = node.props?.style;
|
|
11926
|
+
const spanClass = node.props?.class || node.props?.className;
|
|
11927
|
+
const spanAttrs = {
|
|
11928
|
+
style: isValidAttr(spanStyle) ? String(spanStyle).trim() : void 0,
|
|
11929
|
+
class: isValidAttr(spanClass) ? String(spanClass).trim() : void 0
|
|
11930
|
+
};
|
|
11931
|
+
const cleanedNode = { ...node, props: { ...node.props } };
|
|
11932
|
+
delete cleanedNode.props.style;
|
|
11933
|
+
delete cleanedNode.props.class;
|
|
11934
|
+
delete cleanedNode.props.className;
|
|
11935
|
+
return createTipTapNode(cleanedNode, "span-style", { attrs: spanAttrs });
|
|
11936
|
+
}
|
|
11937
|
+
function wrapChildrenWithinSlot(children) {
|
|
11938
|
+
const noneSlotChildren = children.filter((child) => child.tag !== "template");
|
|
11939
|
+
if (noneSlotChildren.length) {
|
|
11940
|
+
children = children.filter((child) => child.tag === "template");
|
|
11941
|
+
let defaultSlot = children.find((child) => child.props?.["v-slot:default"]);
|
|
11942
|
+
if (!defaultSlot) {
|
|
11943
|
+
defaultSlot = {
|
|
11944
|
+
type: "element",
|
|
11945
|
+
tag: "template",
|
|
11946
|
+
props: {
|
|
11947
|
+
"v-slot:default": ""
|
|
11948
|
+
},
|
|
11949
|
+
children: []
|
|
11950
|
+
};
|
|
11951
|
+
children.unshift(defaultSlot);
|
|
11952
|
+
}
|
|
11953
|
+
defaultSlot.children = [
|
|
11954
|
+
...defaultSlot.children || [],
|
|
11955
|
+
...noneSlotChildren
|
|
11956
|
+
];
|
|
11952
11957
|
}
|
|
11953
|
-
|
|
11954
|
-
...defaultSlot.children || [],
|
|
11955
|
-
...noneSlotChildren
|
|
11956
|
-
];
|
|
11958
|
+
return children;
|
|
11957
11959
|
}
|
|
11958
|
-
return
|
|
11960
|
+
return {
|
|
11961
|
+
mdcToTiptap,
|
|
11962
|
+
createMark,
|
|
11963
|
+
createTipTapNode,
|
|
11964
|
+
createTemplateNode,
|
|
11965
|
+
createPreNode,
|
|
11966
|
+
createParagraphNode,
|
|
11967
|
+
createTextNode,
|
|
11968
|
+
createSpanStyleNode
|
|
11969
|
+
};
|
|
11959
11970
|
}
|
|
11960
11971
|
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
const defaultTiptapToMDCMap = {
|
|
11968
|
-
"doc": (node) => ({ type: "root", children: (node.content || []).flatMap((child) => tiptapNodeToMDC(child)) }),
|
|
11969
|
-
"element": createElement,
|
|
11970
|
-
"inline-element": createElement,
|
|
11971
|
-
"span-style": (node) => createElement(node, "span", { props: cleanSpanProps(node.attrs) }),
|
|
11972
|
-
"link": createLinkElement,
|
|
11973
|
-
// 'link-element': createElement,
|
|
11974
|
-
// 'link-block-element': createElement,
|
|
11975
|
-
"text": createTextElement,
|
|
11976
|
-
"comment": (node) => ({ type: "comment", value: node.attrs.text }),
|
|
11977
|
-
"listItem": createListItemElement,
|
|
11978
|
-
"slot": (node) => createElement(node, "template", { props: { [`v-slot:${node.attrs?.name}`]: "" } }),
|
|
11979
|
-
"paragraph": (node) => createElement(node, "p"),
|
|
11980
|
-
"bulletList": (node) => createElement(node, "ul"),
|
|
11981
|
-
"orderedList": (node) => createElement(node, "ol", { props: { start: node.attrs?.start } }),
|
|
11982
|
-
"heading": (node) => createHeadingElement(node),
|
|
11983
|
-
"blockquote": (node) => createElement(node, "blockquote"),
|
|
11984
|
-
"horizontalRule": (node) => createElement(node, "hr"),
|
|
11985
|
-
"bold": (node) => createElement(node, "strong"),
|
|
11986
|
-
"italic": (node) => createElement(node, "em"),
|
|
11987
|
-
"strike": (node) => createElement(node, "del"),
|
|
11988
|
-
"code": (node) => createElement(node, "code", { props: node.attrs }),
|
|
11989
|
-
"codeBlock": (node) => createCodeBlockElement(node),
|
|
11990
|
-
"image": (node) => createImageElement(node),
|
|
11991
|
-
"video": (node) => createElement(node, "video"),
|
|
11992
|
-
"binding": (node) => {
|
|
11993
|
-
const defaultValue = node.attrs?.defaultValue;
|
|
11994
|
-
const value = node.attrs?.value;
|
|
11995
|
-
return { type: "element", tag: "binding", props: { defaultValue, value }, children: [] };
|
|
11996
|
-
},
|
|
11997
|
-
"br": (node) => createElement(node, "br")
|
|
11998
|
-
};
|
|
11999
|
-
let slugs = new Slugger__default();
|
|
12000
|
-
let shikiHighlighter;
|
|
12001
|
-
async function tiptapToMdc(node, options) {
|
|
12002
|
-
slugs = new Slugger__default();
|
|
12003
|
-
const mdc = {
|
|
12004
|
-
body: {},
|
|
12005
|
-
data: {}
|
|
11972
|
+
function createTiptapToMDC(options) {
|
|
11973
|
+
const markToTag = {
|
|
11974
|
+
bold: "strong",
|
|
11975
|
+
italic: "em",
|
|
11976
|
+
strike: "del",
|
|
11977
|
+
code: "code"
|
|
12006
11978
|
};
|
|
12007
|
-
const
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
11979
|
+
const tiptapToMDCMap = {
|
|
11980
|
+
"doc": (node) => ({ type: "root", children: (node.content || []).flatMap(tiptapNodeToMDC) }),
|
|
11981
|
+
"element": createElement,
|
|
11982
|
+
"inline-element": createElement,
|
|
11983
|
+
"span-style": (node) => createElement(node, "span", { props: cleanSpanProps(node.attrs) }),
|
|
11984
|
+
"link": createLinkElement,
|
|
11985
|
+
// 'link-element': createElement,
|
|
11986
|
+
// 'link-block-element': createElement,
|
|
11987
|
+
"text": createTextElement,
|
|
11988
|
+
"comment": (node) => ({ type: "comment", value: node.attrs.text }),
|
|
11989
|
+
"listItem": createListItemElement,
|
|
11990
|
+
"slot": (node) => createElement(node, "template", { props: { [`v-slot:${node.attrs?.name}`]: "" } }),
|
|
11991
|
+
"paragraph": (node) => createElement(node, "p"),
|
|
11992
|
+
"bulletList": (node) => createElement(node, "ul"),
|
|
11993
|
+
"orderedList": (node) => createElement(node, "ol", { props: { start: node.attrs?.start } }),
|
|
11994
|
+
"heading": (node) => createHeadingElement(node),
|
|
11995
|
+
"blockquote": (node) => createElement(node, "blockquote"),
|
|
11996
|
+
"horizontalRule": (node) => createElement(node, "hr"),
|
|
11997
|
+
"bold": (node) => createElement(node, "strong"),
|
|
11998
|
+
"italic": (node) => createElement(node, "em"),
|
|
11999
|
+
"strike": (node) => createElement(node, "del"),
|
|
12000
|
+
"code": (node) => createElement(node, "code", { props: node.attrs }),
|
|
12001
|
+
"codeBlock": (node) => createCodeBlockElement(node),
|
|
12002
|
+
"image": (node) => createImageElement(node),
|
|
12003
|
+
"video": (node) => createElement(node, "video"),
|
|
12004
|
+
"binding": (node) => {
|
|
12005
|
+
const defaultValue = node.attrs?.defaultValue;
|
|
12006
|
+
const value = node.attrs?.value;
|
|
12007
|
+
return { type: "element", tag: "binding", props: { defaultValue, value }, children: [] };
|
|
12008
|
+
},
|
|
12009
|
+
"br": (node) => createElement(node, "br"),
|
|
12010
|
+
...options?.customMap || {}
|
|
12011
|
+
};
|
|
12012
|
+
let slugs = new Slugger__default();
|
|
12013
|
+
let shikiHighlighter;
|
|
12014
|
+
async function tiptapToMdc(node, options2) {
|
|
12015
|
+
slugs = new Slugger__default();
|
|
12016
|
+
const mdc = {
|
|
12017
|
+
body: {},
|
|
12018
|
+
data: {}
|
|
12019
|
+
};
|
|
12020
|
+
const nodeCopy = JSON.parse(JSON.stringify(node));
|
|
12021
|
+
const fmIndex = nodeCopy.content?.findIndex((child) => child.type === "frontmatter");
|
|
12022
|
+
if (fmIndex > -1) {
|
|
12023
|
+
const fm = nodeCopy.content?.[fmIndex];
|
|
12024
|
+
nodeCopy.content?.splice(fmIndex, 1);
|
|
12025
|
+
try {
|
|
12026
|
+
if (fm.attrs?.frontmatter && typeof fm.attrs.frontmatter === "object") {
|
|
12027
|
+
mdc.data = fm.attrs.frontmatter;
|
|
12028
|
+
} else {
|
|
12029
|
+
mdc.data = {};
|
|
12030
|
+
}
|
|
12031
|
+
} catch (error) {
|
|
12032
|
+
mdc.data = {
|
|
12033
|
+
__error__: error
|
|
12034
|
+
};
|
|
12017
12035
|
}
|
|
12018
|
-
} catch (error) {
|
|
12019
|
-
mdc.data = {
|
|
12020
|
-
__error__: error
|
|
12021
|
-
};
|
|
12022
12036
|
}
|
|
12037
|
+
mdc.body = tiptapNodeToMDC(nodeCopy);
|
|
12038
|
+
await applyShikiSyntaxHighlighting(mdc.body, options2?.highlightTheme);
|
|
12039
|
+
return mdc;
|
|
12023
12040
|
}
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12041
|
+
function tiptapNodeToMDC(node) {
|
|
12042
|
+
if (!node) {
|
|
12043
|
+
return {
|
|
12044
|
+
type: "element",
|
|
12045
|
+
tag: "p",
|
|
12046
|
+
children: [],
|
|
12047
|
+
props: {}
|
|
12048
|
+
};
|
|
12049
|
+
}
|
|
12050
|
+
if (tiptapToMDCMap[node.type]) {
|
|
12051
|
+
return tiptapToMDCMap[node.type](node);
|
|
12052
|
+
}
|
|
12053
|
+
if (node.type === "emoji") {
|
|
12054
|
+
return { type: "text", value: getEmojiUnicode(node.attrs?.name || "") };
|
|
12055
|
+
}
|
|
12030
12056
|
return {
|
|
12031
12057
|
type: "element",
|
|
12032
12058
|
tag: "p",
|
|
12033
|
-
children: [
|
|
12059
|
+
children: [
|
|
12060
|
+
{
|
|
12061
|
+
type: "text",
|
|
12062
|
+
value: `--- Unknown node: ${node.type} ---`
|
|
12063
|
+
}
|
|
12064
|
+
],
|
|
12034
12065
|
props: {}
|
|
12035
12066
|
};
|
|
12036
12067
|
}
|
|
12037
|
-
|
|
12038
|
-
...
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
if (node.type === "emoji") {
|
|
12045
|
-
return { type: "text", value: getEmojiUnicode(node.attrs?.name || "") };
|
|
12046
|
-
}
|
|
12047
|
-
return {
|
|
12048
|
-
type: "element",
|
|
12049
|
-
tag: "p",
|
|
12050
|
-
children: [
|
|
12051
|
-
{
|
|
12052
|
-
type: "text",
|
|
12053
|
-
value: `--- Unknown node: ${node.type} ---`
|
|
12068
|
+
function createElement(node, tag, extra = {}) {
|
|
12069
|
+
const { props = {}, ...rest } = extra;
|
|
12070
|
+
let children = node.content || [];
|
|
12071
|
+
if (node.attrs?.props?.__tiptapWrap) {
|
|
12072
|
+
if (children.length === 1 && children[0]?.type === "slot") {
|
|
12073
|
+
const slot = children[0];
|
|
12074
|
+
slot.content = unwrapParagraph(slot.content || []);
|
|
12054
12075
|
}
|
|
12055
|
-
|
|
12056
|
-
props: {}
|
|
12057
|
-
};
|
|
12058
|
-
}
|
|
12059
|
-
function createElement(node, tag, extra = {}) {
|
|
12060
|
-
const { props = {}, ...rest } = extra;
|
|
12061
|
-
let children = node.content || [];
|
|
12062
|
-
if (node.attrs?.props?.__tiptapWrap) {
|
|
12063
|
-
if (children.length === 1 && children[0]?.type === "slot") {
|
|
12064
|
-
const slot = children[0];
|
|
12065
|
-
slot.content = unwrapParagraph(slot.content || []);
|
|
12066
|
-
}
|
|
12067
|
-
delete node.attrs.props.__tiptapWrap;
|
|
12068
|
-
}
|
|
12069
|
-
children = unwrapParagraph(children);
|
|
12070
|
-
const propsArray = normalizeProps(node.attrs?.props || {}, props);
|
|
12071
|
-
if (node.type === "paragraph") {
|
|
12072
|
-
if (!children || children.length === 0) {
|
|
12073
|
-
return { type: "element", tag: "p", children: [], props: {} };
|
|
12076
|
+
delete node.attrs.props.__tiptapWrap;
|
|
12074
12077
|
}
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
tag: tag || node.attrs?.tag,
|
|
12081
|
-
children: node.children || children.flatMap((child) => tiptapNodeToMDC(child)),
|
|
12082
|
-
...rest,
|
|
12083
|
-
props: Object.fromEntries(propsArray)
|
|
12084
|
-
};
|
|
12085
|
-
}
|
|
12086
|
-
function createParagraphElement(node, propsArray, rest = {}) {
|
|
12087
|
-
const blocks = [];
|
|
12088
|
-
let currentBlockContent = [];
|
|
12089
|
-
let currentBlockMark = null;
|
|
12090
|
-
const getMarkInfo = (child) => {
|
|
12091
|
-
if (child.type === "text" && child.marks?.length === 1 && child.marks?.[0]?.type) {
|
|
12092
|
-
return child.marks[0];
|
|
12093
|
-
}
|
|
12094
|
-
if (child.type === "link-element" && child.content && child.content.length === 1 && child.content[0].type === "text" && child.content[0].marks?.length === 1 && child.content[0].marks?.[0]?.type) {
|
|
12095
|
-
return child.content[0].marks?.[0];
|
|
12096
|
-
}
|
|
12097
|
-
return null;
|
|
12098
|
-
};
|
|
12099
|
-
const sameMark = (markA, markB) => {
|
|
12100
|
-
if (!markA && !markB) {
|
|
12101
|
-
return true;
|
|
12102
|
-
}
|
|
12103
|
-
if (!markA || !markB) {
|
|
12104
|
-
return false;
|
|
12105
|
-
}
|
|
12106
|
-
return markA.type === markB.type && JSON.stringify(markA.attrs || {}) === JSON.stringify(markB.attrs || {});
|
|
12107
|
-
};
|
|
12108
|
-
node.content.forEach((child) => {
|
|
12109
|
-
const mark = getMarkInfo(child);
|
|
12110
|
-
if (!sameMark(mark, currentBlockMark)) {
|
|
12111
|
-
if (currentBlockContent.length > 0) {
|
|
12112
|
-
blocks.push({ mark: currentBlockMark, content: currentBlockContent });
|
|
12078
|
+
children = unwrapParagraph(children);
|
|
12079
|
+
const propsArray = normalizeProps(node.attrs?.props || {}, props);
|
|
12080
|
+
if (node.type === "paragraph") {
|
|
12081
|
+
if (!children || children.length === 0) {
|
|
12082
|
+
return { type: "element", tag: "p", children: [], props: {} };
|
|
12113
12083
|
}
|
|
12114
|
-
|
|
12115
|
-
currentBlockMark = mark;
|
|
12084
|
+
return createParagraphElement(node, propsArray, rest);
|
|
12116
12085
|
}
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12086
|
+
children = unwrapDefaultSlot(children);
|
|
12087
|
+
return {
|
|
12088
|
+
type: "element",
|
|
12089
|
+
tag: tag || node.attrs?.tag,
|
|
12090
|
+
children: node.children || children.flatMap(tiptapNodeToMDC),
|
|
12091
|
+
...rest,
|
|
12092
|
+
props: Object.fromEntries(propsArray)
|
|
12093
|
+
};
|
|
12121
12094
|
}
|
|
12122
|
-
|
|
12123
|
-
|
|
12124
|
-
|
|
12125
|
-
|
|
12126
|
-
|
|
12127
|
-
|
|
12128
|
-
|
|
12095
|
+
function createParagraphElement(node, propsArray, rest = {}) {
|
|
12096
|
+
const blocks = [];
|
|
12097
|
+
let currentBlockContent = [];
|
|
12098
|
+
let currentBlockMark = null;
|
|
12099
|
+
const getMarkInfo = (child) => {
|
|
12100
|
+
if (child.type === "text" && child.marks?.length === 1 && child.marks?.[0]?.type) {
|
|
12101
|
+
return child.marks[0];
|
|
12102
|
+
}
|
|
12103
|
+
if (child.type === "link-element" && child.content && child.content.length === 1 && child.content[0].type === "text" && child.content[0].marks?.length === 1 && child.content[0].marks?.[0]?.type) {
|
|
12104
|
+
return child.content[0].marks?.[0];
|
|
12105
|
+
}
|
|
12106
|
+
return null;
|
|
12107
|
+
};
|
|
12108
|
+
const sameMark = (markA, markB) => {
|
|
12109
|
+
if (!markA && !markB) {
|
|
12110
|
+
return true;
|
|
12111
|
+
}
|
|
12112
|
+
if (!markA || !markB) {
|
|
12113
|
+
return false;
|
|
12114
|
+
}
|
|
12115
|
+
return markA.type === markB.type && JSON.stringify(markA.attrs || {}) === JSON.stringify(markB.attrs || {});
|
|
12116
|
+
};
|
|
12117
|
+
node.content.forEach((child) => {
|
|
12118
|
+
const mark = getMarkInfo(child);
|
|
12119
|
+
if (!sameMark(mark, currentBlockMark)) {
|
|
12120
|
+
if (currentBlockContent.length > 0) {
|
|
12121
|
+
blocks.push({ mark: currentBlockMark, content: currentBlockContent });
|
|
12129
12122
|
}
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
};
|
|
12123
|
+
currentBlockContent = [];
|
|
12124
|
+
currentBlockMark = mark;
|
|
12125
|
+
}
|
|
12126
|
+
currentBlockContent.push(child);
|
|
12127
|
+
});
|
|
12128
|
+
if (currentBlockContent.length > 0) {
|
|
12129
|
+
blocks.push({ mark: currentBlockMark, content: currentBlockContent });
|
|
12138
12130
|
}
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
}
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
return mdcNode;
|
|
12167
|
-
}
|
|
12168
|
-
function createImageElement(node) {
|
|
12169
|
-
if (["nuxt-img", "nuxt-picture"].includes(node.attrs?.tag)) {
|
|
12170
|
-
return createElement(node, node.attrs?.tag, { props: { alt: node.attrs?.alt, src: node.attrs?.src } });
|
|
12171
|
-
} else {
|
|
12172
|
-
return createElement(node, "img", { props: { alt: node.attrs?.alt, src: node.attrs?.src } });
|
|
12131
|
+
const children = blocks.map((block) => {
|
|
12132
|
+
if (block.content.length > 1 && block.mark && markToTag[block.mark.type]) {
|
|
12133
|
+
block.content.forEach((child) => {
|
|
12134
|
+
if (child.type === "text") {
|
|
12135
|
+
delete child.marks;
|
|
12136
|
+
} else if (child.type === "link-element") {
|
|
12137
|
+
delete child.content[0].marks;
|
|
12138
|
+
}
|
|
12139
|
+
});
|
|
12140
|
+
const props = block.mark.attrs && Object.keys(block.mark.attrs).length > 0 ? { props: block.mark.attrs } : {};
|
|
12141
|
+
return {
|
|
12142
|
+
type: "element",
|
|
12143
|
+
tag: markToTag[block.mark.type],
|
|
12144
|
+
children: block.content.flatMap(tiptapNodeToMDC),
|
|
12145
|
+
...props
|
|
12146
|
+
};
|
|
12147
|
+
}
|
|
12148
|
+
return block.content.flatMap(tiptapNodeToMDC);
|
|
12149
|
+
});
|
|
12150
|
+
const mergedChildren = mergeSiblingsWithSameTag(children.flat(), Object.values(markToTag));
|
|
12151
|
+
return {
|
|
12152
|
+
type: "element",
|
|
12153
|
+
tag: "p",
|
|
12154
|
+
...rest,
|
|
12155
|
+
props: Object.fromEntries(propsArray),
|
|
12156
|
+
children: mergedChildren
|
|
12157
|
+
};
|
|
12173
12158
|
}
|
|
12174
|
-
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
12178
|
-
if (href) {
|
|
12179
|
-
linkProps.href = href;
|
|
12159
|
+
function createHeadingElement(node) {
|
|
12160
|
+
const mdcNode = createElement(node, `h${node.attrs?.level}`);
|
|
12161
|
+
mdcNode.props.id = slugs.slug(getNodeContent(node)).replace(/-+/g, "-").replace(/^-|-$/g, "").replace(/^(\d)/, "_$1");
|
|
12162
|
+
return mdcNode;
|
|
12180
12163
|
}
|
|
12181
|
-
|
|
12182
|
-
|
|
12164
|
+
function createCodeBlockElement(node) {
|
|
12165
|
+
const mdcNode = createElement(node, "pre");
|
|
12166
|
+
mdcNode.props.code = node.attrs?.code || getNodeContent(node);
|
|
12167
|
+
mdcNode.props.language = node.attrs.language;
|
|
12168
|
+
mdcNode.props.filename = node.attrs.filename;
|
|
12169
|
+
mdcNode.children = [{
|
|
12170
|
+
type: "element",
|
|
12171
|
+
tag: "code",
|
|
12172
|
+
props: { __ignoreMap: "" },
|
|
12173
|
+
children: [{ type: "text", value: mdcNode.props.code }]
|
|
12174
|
+
}];
|
|
12175
|
+
return mdcNode;
|
|
12183
12176
|
}
|
|
12184
|
-
|
|
12185
|
-
if (
|
|
12186
|
-
|
|
12177
|
+
function createImageElement(node) {
|
|
12178
|
+
if (["nuxt-img", "nuxt-picture"].includes(node.attrs?.tag)) {
|
|
12179
|
+
return createElement(node, node.attrs?.tag, { props: { alt: node.attrs?.alt, src: node.attrs?.src } });
|
|
12187
12180
|
} else {
|
|
12188
|
-
|
|
12181
|
+
return createElement(node, "img", { props: { alt: node.attrs?.alt, src: node.attrs?.src } });
|
|
12189
12182
|
}
|
|
12190
12183
|
}
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
|
|
12196
|
-
}
|
|
12197
|
-
function createTextElement(node) {
|
|
12198
|
-
const prefix = node.text?.match(/^\s+/)?.[0] || "";
|
|
12199
|
-
const suffix = node.text?.match(/\s+$/)?.[0] || "";
|
|
12200
|
-
const text = node.text?.trim() || "";
|
|
12201
|
-
if (!node.marks?.length) {
|
|
12202
|
-
return { type: "text", value: node.text };
|
|
12203
|
-
}
|
|
12204
|
-
const res = node.marks.reduce((acc, mark) => {
|
|
12205
|
-
if (defaultTiptapToMDCMap[mark.type]) {
|
|
12206
|
-
return defaultTiptapToMDCMap[mark.type]({ ...mark, children: [acc] });
|
|
12184
|
+
function createLinkElement(node) {
|
|
12185
|
+
const { href, target, rel, class: className, ...otherAttrs } = node.attrs || {};
|
|
12186
|
+
const linkProps = {};
|
|
12187
|
+
if (href) {
|
|
12188
|
+
linkProps.href = href;
|
|
12207
12189
|
}
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
return [
|
|
12211
|
-
prefix ? { type: "text", value: prefix } : null,
|
|
12212
|
-
res,
|
|
12213
|
-
suffix ? { type: "text", value: suffix } : null
|
|
12214
|
-
].filter(Boolean);
|
|
12215
|
-
}
|
|
12216
|
-
function createListItemElement(node) {
|
|
12217
|
-
node.content = (node.content || []).flatMap((child) => {
|
|
12218
|
-
if (child.type === "paragraph") {
|
|
12219
|
-
return child.content;
|
|
12190
|
+
if (target) {
|
|
12191
|
+
linkProps.target = target;
|
|
12220
12192
|
}
|
|
12221
|
-
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
}
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12193
|
+
if (rel) {
|
|
12194
|
+
if (Array.isArray(rel)) {
|
|
12195
|
+
linkProps.rel = rel.join(" ");
|
|
12196
|
+
} else {
|
|
12197
|
+
linkProps.rel = rel;
|
|
12198
|
+
}
|
|
12199
|
+
}
|
|
12200
|
+
if (className) {
|
|
12201
|
+
linkProps.class = className;
|
|
12202
|
+
}
|
|
12203
|
+
Object.assign(linkProps, otherAttrs);
|
|
12204
|
+
return { type: "element", tag: "a", props: linkProps, children: node.children || [] };
|
|
12229
12205
|
}
|
|
12230
|
-
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
(
|
|
12235
|
-
|
|
12236
|
-
Object.assign(n, { tag: n.tagName, props: n.properties, tagName: void 0, properties: void 0 });
|
|
12206
|
+
function createTextElement(node) {
|
|
12207
|
+
const prefix = node.text?.match(/^\s+/)?.[0] || "";
|
|
12208
|
+
const suffix = node.text?.match(/\s+$/)?.[0] || "";
|
|
12209
|
+
const text = node.text?.trim() || "";
|
|
12210
|
+
if (!node.marks?.length) {
|
|
12211
|
+
return { type: "text", value: node.text };
|
|
12237
12212
|
}
|
|
12238
|
-
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12213
|
+
const res = node.marks.reduce((acc, mark) => {
|
|
12214
|
+
if (tiptapToMDCMap[mark.type]) {
|
|
12215
|
+
return tiptapToMDCMap[mark.type]({ ...mark, children: [acc] });
|
|
12216
|
+
}
|
|
12217
|
+
return acc;
|
|
12218
|
+
}, { type: "text", value: text });
|
|
12219
|
+
return [
|
|
12220
|
+
prefix ? { type: "text", value: prefix } : null,
|
|
12221
|
+
res,
|
|
12222
|
+
suffix ? { type: "text", value: suffix } : null
|
|
12223
|
+
].filter(Boolean);
|
|
12224
|
+
}
|
|
12225
|
+
function createListItemElement(node) {
|
|
12226
|
+
node.content = (node.content || []).flatMap((child) => {
|
|
12227
|
+
if (child.type === "paragraph") {
|
|
12228
|
+
return child.content;
|
|
12229
|
+
}
|
|
12230
|
+
return child;
|
|
12231
|
+
});
|
|
12232
|
+
return createElement(node, "li");
|
|
12233
|
+
}
|
|
12234
|
+
async function applyShikiSyntaxHighlighting(mdc, theme = { default: "github-light", dark: "github-dark" }) {
|
|
12235
|
+
unistUtilVisit.visit(mdc, (n) => n.tag !== void 0, (n) => Object.assign(n, { tagName: n.tag, properties: n.props }));
|
|
12236
|
+
if (!shikiHighlighter) {
|
|
12237
|
+
shikiHighlighter = shiki.createShikiHighlighter({ bundledThemes: shiki$1.bundledThemes, bundledLangs: shiki$1.bundledLanguages, engine: shiki$1.createJavaScriptRegexEngine({ forgiving: true }) });
|
|
12244
12238
|
}
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12239
|
+
const shikit = rehypeShiki__default({ theme, highlighter: shikiHighlighter });
|
|
12240
|
+
await shikit(mdc);
|
|
12241
|
+
unistUtilVisit.visit(
|
|
12242
|
+
mdc,
|
|
12243
|
+
(n) => n.tagName !== void 0,
|
|
12244
|
+
(n) => {
|
|
12245
|
+
Object.assign(n, { tag: n.tagName, props: n.properties, tagName: void 0, properties: void 0 });
|
|
12246
|
+
}
|
|
12247
|
+
);
|
|
12248
|
+
unistUtilVisit.visit(
|
|
12249
|
+
mdc,
|
|
12250
|
+
(n) => n.tag === "pre",
|
|
12251
|
+
(n) => {
|
|
12252
|
+
n.children[0].children = n.children[0].children.filter((child) => child.type !== "text" || child.value.trim());
|
|
12253
|
+
}
|
|
12254
|
+
);
|
|
12250
12255
|
}
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
return content
|
|
12256
|
+
function unwrapParagraph(content) {
|
|
12257
|
+
if (content.length === 1 && content[0]?.type === "paragraph") {
|
|
12258
|
+
return content[0].content || [];
|
|
12259
|
+
}
|
|
12260
|
+
return content;
|
|
12256
12261
|
}
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
return
|
|
12262
|
+
function unwrapDefaultSlot(content) {
|
|
12263
|
+
if (content.length === 1 && content[0]?.type === "slot" && content[0].attrs?.name === "default") {
|
|
12264
|
+
return content[0].content || [];
|
|
12265
|
+
}
|
|
12266
|
+
return content;
|
|
12262
12267
|
}
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
const
|
|
12268
|
-
|
|
12269
|
-
|
|
12270
|
-
|
|
12271
|
-
|
|
12272
|
-
|
|
12273
|
-
|
|
12274
|
-
|
|
12275
|
-
...
|
|
12276
|
-
|
|
12277
|
-
|
|
12278
|
-
|
|
12279
|
-
|
|
12280
|
-
|
|
12281
|
-
|
|
12268
|
+
function mergeSiblingsWithSameTag(children, allowedTags) {
|
|
12269
|
+
if (!Array.isArray(children)) {
|
|
12270
|
+
return children;
|
|
12271
|
+
}
|
|
12272
|
+
const merged = [];
|
|
12273
|
+
let i = 0;
|
|
12274
|
+
while (i < children.length) {
|
|
12275
|
+
const current = children[i];
|
|
12276
|
+
const next = children[i + 1];
|
|
12277
|
+
const afterNext = children[i + 2];
|
|
12278
|
+
if (current && afterNext && current.type === "element" && afterNext.type === "element" && current.tag === afterNext.tag && allowedTags.includes(current.tag) && JSON.stringify(current.props || {}) === JSON.stringify(afterNext.props || {}) && next && next.type === "text" && next.value === " ") {
|
|
12279
|
+
merged.push({
|
|
12280
|
+
...current,
|
|
12281
|
+
children: [
|
|
12282
|
+
...current.children || [],
|
|
12283
|
+
{ type: "text", value: " " },
|
|
12284
|
+
...afterNext.children || []
|
|
12285
|
+
]
|
|
12286
|
+
});
|
|
12287
|
+
i += 3;
|
|
12288
|
+
} else {
|
|
12289
|
+
merged.push(current);
|
|
12290
|
+
i++;
|
|
12291
|
+
}
|
|
12282
12292
|
}
|
|
12293
|
+
return merged;
|
|
12283
12294
|
}
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12295
|
+
function getNodeContent(node) {
|
|
12296
|
+
if (node.type === "text") {
|
|
12297
|
+
return node.text;
|
|
12298
|
+
}
|
|
12299
|
+
let content = "";
|
|
12300
|
+
node.content?.forEach((childNode) => {
|
|
12301
|
+
content += getNodeContent(childNode);
|
|
12302
|
+
});
|
|
12303
|
+
return content;
|
|
12289
12304
|
}
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
|
|
12305
|
+
return {
|
|
12306
|
+
tiptapToMdc,
|
|
12307
|
+
tiptapNodeToMDC,
|
|
12308
|
+
createParagraphElement,
|
|
12309
|
+
createHeadingElement,
|
|
12310
|
+
createCodeBlockElement,
|
|
12311
|
+
createImageElement,
|
|
12312
|
+
createLinkElement,
|
|
12313
|
+
createTextElement,
|
|
12314
|
+
createListItemElement
|
|
12315
|
+
};
|
|
12295
12316
|
}
|
|
12296
12317
|
|
|
12297
|
-
|
|
12298
|
-
const
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
|
|
12302
|
-
|
|
12303
|
-
|
|
12318
|
+
function createMarkdown(options) {
|
|
12319
|
+
const mdcToTiptap = createMDCToTiptap(options?.mdcToTiptap);
|
|
12320
|
+
const tiptapToMDC = createTiptapToMDC(options?.tiptapToMDC);
|
|
12321
|
+
async function tiptapToMarkdown(node) {
|
|
12322
|
+
const mdc = await tiptapToMDC.tiptapToMdc(node);
|
|
12323
|
+
return runtime.stringifyMarkdown(mdc.body, mdc.data);
|
|
12324
|
+
}
|
|
12325
|
+
async function markdownToTiptap(markdown) {
|
|
12326
|
+
const mdc = await runtime.parseMarkdown(markdown);
|
|
12327
|
+
return mdcToTiptap.mdcToTiptap(mdc.body);
|
|
12328
|
+
}
|
|
12329
|
+
return {
|
|
12330
|
+
tiptapToMarkdown,
|
|
12331
|
+
markdownToTiptap
|
|
12332
|
+
};
|
|
12304
12333
|
}
|
|
12305
12334
|
|
|
12306
|
-
exports.
|
|
12307
|
-
exports.
|
|
12308
|
-
exports.
|
|
12309
|
-
exports.createTipTapNode = createTipTapNode;
|
|
12310
|
-
exports.markdownToTiptap = markdownToTiptap;
|
|
12311
|
-
exports.mdcNodeToTiptap = mdcNodeToTiptap;
|
|
12312
|
-
exports.mdcToTiptap = mdcToTiptap;
|
|
12313
|
-
exports.tiptapNodeToMDC = tiptapNodeToMDC;
|
|
12314
|
-
exports.tiptapToMarkdown = tiptapToMarkdown;
|
|
12315
|
-
exports.tiptapToMdc = tiptapToMdc;
|
|
12335
|
+
exports.createMDCToTiptap = createMDCToTiptap;
|
|
12336
|
+
exports.createMarkdown = createMarkdown;
|
|
12337
|
+
exports.createTiptapToMDC = createTiptapToMDC;
|