import { Image, Input, Select, Form, Checkbox, Radio, ColorPicker, DatePicker, TimePicker, InputNumber, Slider } from 'antd' import ReactMarkdown from 'react-markdown' import RemarkGfm from 'remark-gfm' import RemarkMath from 'remark-math' import RemarkBreaks from 'remark-breaks' import RehypeKatex from 'rehype-katex' import RehypeRaw from 'rehype-raw' import type { FC } from 'react' import { useState, useRef, useEffect } from 'react' import Code from './Code' import VideoBlock from './VideoBlock' import AudioBlock from './AudioBlock' import Link from './Link' import RbButton from './RbButton' interface RbMarkdownProps { content: string; showHtmlComments?: boolean; // 是否显示 HTML 注释,默认为 false(隐藏) editable?: boolean; // 是否可编辑,默认为 false onContentChange?: (content: string) => void; // 内容变化回调 } const components = { h1: ({ children, ...props }: any) =>

{children}

, h2: ({ children, ...props }: any) =>

{children}

, h3: ({ children, ...props }: any) =>

{children}

, h4: ({ children, ...props }: any) =>

{children}

, h5: ({ children, ...props }: any) =>
{children}
, h6: ({ children, ...props }: any) =>
{children}
, ul: ({ children, ...props }: any) => , ol: ({ children, ...props }: any) =>
    {children}
, li: ({ children, ...props }: any) =>
  • {children}
  • , blockquote: ({ children, ...props }: any) =>
    {children}
    , p: ({ children, ...props }: any) =>

    {children}

    , strong: ({ children, ...props }: any) => {children}, em: ({ children, ...props }: any) => {children}, del: ({ children, ...props }: any) => {children}, span: ({ children, style, ...restProps }: any) => { // 如果是 HTML 注释的 span,应用特殊样式 if (style?.color === '#999') { return {children} } return {children} }, code: ({ children, className, ...props }: any) => , img: ({ src, alt, ...props }: any) => {alt}, video: ({ src, ...props }: any) => , audio: ({ src, ...props }: any) => , a: ({ href, children, ...props }: any) => {children}, button: ({ children }: any) => {[children]}, table: ({ children, ...props }: any) => {children}
    , tr: ({ children, ...props }: any) => {children}, th: ({ children, ...props }: any) => {children}, td: ({ children, ...props }: any) => {children}, input: ({ children, ...props }: any) => { switch (props.type) { case 'color': return case 'time': return case 'date': return case 'datetime': case 'datetime-local': return case 'week': return case 'month': return case 'number': return case 'search': return case 'range': return case 'submit': case 'button': return {[props.value || children]} case 'checkbox': return {children} case 'password': return case 'radio': return {children} default: return } }, select: ({ children, ...props }: any) => , textarea: ({ children, ...props }: any) => {children}, form: ({ children, ...props }: any) =>
    {children}
    , } const RbMarkdown: FC = ({ content, showHtmlComments = false, editable = false, onContentChange, }) => { const [editContent, setEditContent] = useState(content) const textareaRef = useRef(null) // 当外部 content 变化时,同步更新编辑内容 useEffect(() => { setEditContent(content) }, [content]) // 处理 textarea 内容变化 const handleTextareaChange = (e: React.ChangeEvent) => { const newContent = e.target.value setEditContent(newContent) // 实时回调内容变化 onContentChange?.(newContent) } // 根据参数决定是否将 HTML 注释转换为可见文本 // 使用特殊的 markdown 语法来显示注释,避免被 rehype-raw 过滤 const processedContent = showHtmlComments ? (editable ? editContent : content).replace(//g, (_match, commentContent) => { // 转换为带样式的文本,使用 标记 const escaped = commentContent.trim().replace(//g, '>') return `<!-- ${escaped} -->` }) : (editable ? editContent : content) // 如果是编辑模式,显示 textarea if (editable) { return (
    {/* 编辑区域 */}
    ) } // 处理键盘快捷键 const handleKeyDown = (e: React.KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key === 'c') { const selection = window.getSelection() if (selection && selection.toString()) { navigator.clipboard.writeText(selection.toString()) } } } // 预览模式 return (
    { // return (tree) => { // const iterate = (node: any) => { // if (node.type === 'element' && !node.properties?.src && node.properties?.ref && node.properties.ref.startsWith('{') && node.properties.ref.endsWith('}')) // delete node.properties.ref // if (node.children) // node.children.forEach(iterate) // } // tree.children.forEach(iterate) // } // }, ]} remarkPlugins={[RemarkGfm, RemarkMath, RemarkBreaks]} remarkRehypeOptions={{ allowDangerousHtml: true, }} > {processedContent}
    ) } export default RbMarkdown