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