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