import React, { useState, useEffect, useMemo } from 'react'; import { unified } from 'unified'; import remarkParse from 'remark-parse'; import remarkMath from 'remark-math'; import remarkRehype from 'remark-rehype'; import rehypeMathjax from 'rehype-mathjax'; import rehypeReact from 'rehype-react'; import rehypePrism from 'rehype-prism'; import * as prod from 'react/jsx-runtime'; import { notifications } from '@mantine/notifications'; import { remarkWikiLinks } from '../../utils/remarkWikiLinks'; import { useWorkspace } from '../../contexts/WorkspaceContext'; const MarkdownPreview = ({ content, handleFileSelect }) => { const [processedContent, setProcessedContent] = useState(null); const baseUrl = window.API_BASE_URL; const { currentWorkspace } = useWorkspace(); const handleLinkClick = (e, href) => { e.preventDefault(); if (href.startsWith(`${baseUrl}/internal/`)) { // For existing files, extract the path and directly select it const [filePath] = decodeURIComponent( href.replace(`${baseUrl}/internal/`, '') ).split('#'); handleFileSelect(filePath); } else if (href.startsWith(`${baseUrl}/notfound/`)) { // For non-existent files, show a notification const fileName = decodeURIComponent( href.replace(`${baseUrl}/notfound/`, '') ); notifications.show({ title: 'File Not Found', message: `The file "${fileName}" does not exist.`, color: 'red', }); } }; const processor = useMemo( () => unified() .use(remarkParse) .use(remarkWikiLinks, currentWorkspace?.name) .use(remarkMath) .use(remarkRehype) .use(rehypeMathjax) .use(rehypePrism) .use(rehypeReact, { production: true, jsx: prod.jsx, jsxs: prod.jsxs, Fragment: prod.Fragment, components: { img: ({ src, alt, ...props }) => ( {alt} { console.error('Failed to load image:', event.target.src); event.target.alt = 'Failed to load image'; }} {...props} /> ), a: ({ href, children, ...props }) => ( handleLinkClick(e, href)} {...props} > {children} ), code: ({ children, className, ...props }) => { const language = className ? className.replace('language-', '') : null; return (
                  {children}
                
); }, }, }), [baseUrl, handleFileSelect, currentWorkspace?.name] ); useEffect(() => { const processContent = async () => { if (!currentWorkspace) { return; } try { const result = await processor.process(content); setProcessedContent(result.result); } catch (error) { console.error('Error processing markdown:', error); } }; processContent(); }, [content, processor, currentWorkspace]); return
{processedContent}
; }; export default MarkdownPreview;