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