Files
everyone-can-use-english/enjoy/src/renderer/components/misc/markdown-wrapper.tsx
2024-09-03 20:03:07 +08:00

52 lines
1.2 KiB
TypeScript

import Markdown from "react-markdown";
import { visitParents } from "unist-util-visit-parents";
import { Sentence } from "@renderer/components";
function rehypeWrapText() {
return function wrapTextTransform(tree: any) {
visitParents(tree, "text", (node, ancestors) => {
const parent = ancestors.at(-1);
if (parent.tagName !== "vocabulary") {
node.type = "element";
node.tagName = "vocabulary";
node.properties = { text: node.value };
node.children = [{ type: "text", value: node.value }];
}
});
};
}
export const MarkdownWrapper = ({
children,
className,
...props
}: {
children: string;
className?: string;
}) => {
return (
<Markdown
className={className}
rehypePlugins={[rehypeWrapText]}
components={{
a({ node, children, ...props }) {
try {
new URL(props.href ?? "");
props.target = "_blank";
props.rel = "noopener noreferrer";
} catch (e) {}
return <a {...props}>{children}</a>;
},
vocabulary({ node, children, ...props }) {
return <Sentence sentence={props.text} />;
},
}}
{...props}
>
{children}
</Markdown>
);
};