'use client'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import rehypeSanitize from 'rehype-sanitize'
import rehypeRaw from 'rehype-raw'
import { OptimizedImage } from './OptimizedImage'
import { CodeBlock } from './code-block'
import Link from 'next/link'
interface MarkdownRendererProps {
content: string
className?: string
}
export default function MarkdownRenderer({ content, className = '' }: MarkdownRendererProps) {
return (
{
if (!src || typeof src !== 'string') return null
const isExternal = src.startsWith('http://') || src.startsWith('https://')
if (isExternal) {
return (
)
}
// Ensure absolute path for Next Image
const absoluteSrc = src.startsWith('/') ? src : `/${src}`
const titleStr = typeof title === 'string' ? title : ''
const [altText, caption] = titleStr?.includes('|')
? titleStr.split('|').map(s => s.trim())
: [alt, undefined]
const url = new URL(absoluteSrc, 'http://localhost')
const width = url.searchParams.get('w') ? parseInt(url.searchParams.get('w')!) : 800
const height = url.searchParams.get('h') ? parseInt(url.searchParams.get('h')!) : 600
const cleanSrc = absoluteSrc.split('?')[0]
return (
)
},
code: ({ node, className, children, ...props }) => {
const inline = !className && typeof children === 'string' && !children.includes('\n')
const match = /language-(\w+)/.exec(className || '')
const language = match ? match[1] : ''
if (inline) {
return (
{children}
)
}
return
},
a: ({ node, href, children, ...props }) => {
if (!href) return {children}
const isExternal = href.startsWith('http://') || href.startsWith('https://')
const isAnchor = href.startsWith('#')
if (isExternal) {
return (
{children}
)
}
if (isAnchor) {
return (
{children}
)
}
return (
{children}
)
},
h1: ({ node, children, ...props }) => {
const text = String(children)
const id = text
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')
return (
{children}
)
},
h2: ({ node, children, ...props }) => {
const text = String(children)
const id = text
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')
return (
{children}
)
},
h3: ({ node, children, ...props }) => {
const text = String(children)
const id = text
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/(^-|-$)/g, '')
return (
{children}
)
},
ul: ({ node, children, ...props }) => (
),
ol: ({ node, children, ...props }) => (
{children}
),
blockquote: ({ node, children, ...props }) => (
{children}
),
table: ({ node, children, ...props }) => (
),
th: ({ node, children, ...props }) => (
{children}
|
),
td: ({ node, children, ...props }) => (
{children}
|
),
}}
>
{content}
)
}