add markdown with greentext

This commit is contained in:
plebeius.eth
2024-03-26 15:07:28 +01:00
parent 5620a68337
commit 736e404575
6 changed files with 865 additions and 815 deletions
+1
View File
@@ -0,0 +1 @@
export { default } from './markdown';
@@ -0,0 +1,17 @@
.markdown a {
color: var(--post-link-text-color);
text-decoration: none;
}
.markdown a:hover {
color: var(--post-link-text-color-hover);
text-decoration: none;
}
.markdown ol {
padding-left: 15px;
}
.markdown ul {
padding-left: 40px;
}
+76
View File
@@ -0,0 +1,76 @@
import { useMemo } from 'react';
import styles from './markdown.module.css';
import ReactMarkdown from 'react-markdown';
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
import remarkGfm from 'remark-gfm';
import supersub from 'remark-supersub';
import { visit } from 'unist-util-visit';
interface MarkdownProps {
content: string;
}
const MAX_LENGTH_FOR_GFM = 10000; // remarkGfm lags with large content
const blockquoteToGreentext = () => (tree: any) => {
tree.children.forEach((node: any) => {
if (node.type === 'blockquote') {
node.children.forEach((child: any) => {
if (child.type === 'paragraph' && child.children.length > 0) {
const prefix = {
type: 'text',
value: '>',
};
child.children.unshift(prefix);
}
});
node.type = 'div';
node.data = {
hName: 'div',
hProperties: {
className: 'greentext',
},
};
}
});
};
const Markdown = ({ content }: MarkdownProps) => {
const remarkPlugins: any[] = [[supersub]];
if (content.length <= MAX_LENGTH_FOR_GFM) {
remarkPlugins.push([remarkGfm, { singleTilde: false }]);
}
const customSchema = useMemo(
() => ({
...defaultSchema,
tagNames: [...(defaultSchema.tagNames || []), 'div'],
attributes: {
...defaultSchema.attributes,
div: ['className'],
},
}),
[],
);
remarkPlugins.push([blockquoteToGreentext]);
return (
<span className={styles.markdown}>
<ReactMarkdown
children={content}
remarkPlugins={remarkPlugins}
rehypePlugins={[[rehypeSanitize, customSchema]]}
components={{
img: ({ src }) => <span>{src}</span>,
video: ({ src }) => <span>{src}</span>,
iframe: ({ src }) => <span>{src}</span>,
source: ({ src }) => <span>{src}</span>,
}}
/>
</span>
);
};
export default Markdown;