import React, { useEffect } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import rehypeHighlight from 'rehype-highlight'; import hljs from 'highlight.js'; interface MarkdownRendererProps { content: string; className?: string; summaryMode?: boolean; onContentChange?: (newContent: string) => void; noteColor?: string; } const MarkdownRenderer: React.FC = ({ content, className = '', summaryMode = false, onContentChange, noteColor, }) => { // Determine text color based on background const getTextColor = () => { if (!noteColor) return undefined; const hex = noteColor.replace('#', ''); const r = parseInt(hex.substr(0, 2), 16); const g = parseInt(hex.substr(2, 2), 16); const b = parseInt(hex.substr(4, 2), 16); const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255; return luminance < 0.4 ? '#ffffff' : '#333333'; }; const textColor = getTextColor(); useEffect(() => { // Configure highlight.js hljs.configure({ languages: [ 'javascript', 'typescript', 'python', 'java', 'css', 'html', 'json', 'bash', 'sql', 'yaml', 'xml', 'dockerfile', 'nginx', 'apache', ], }); // Manual highlighting for any missed code blocks const timer = setTimeout(() => { const codeBlocks = document.querySelectorAll('pre code:not(.hljs)'); codeBlocks.forEach((block) => { hljs.highlightElement(block as HTMLElement); }); }, 100); return () => clearTimeout(timer); }, [content]); // Track checkbox index for toggling const checkboxIndexRef = React.useRef(-1); // Reset on each render checkboxIndexRef.current = -1; // Function to toggle checkbox at a specific index const toggleCheckbox = (checkboxIndex: number) => { if (!onContentChange) return; const lines = content.split('\n'); let currentCheckboxIndex = -1; const newLines = lines.map((line) => { // Match task list items: - [ ] or - [x] or - [X] const match = line.match(/^(\s*-\s*)\[([ xX])\](.*)$/); if (match) { currentCheckboxIndex++; if (currentCheckboxIndex === checkboxIndex) { const indent = match[1]; const isChecked = match[2].toLowerCase() === 'x'; const rest = match[3]; return `${indent}[${isChecked ? ' ' : 'x'}]${rest}`; } } return line; }); onContentChange(newLines.join('\n')); }; return (
summaryMode ? ( ) : (

), h2: ({ ...props }) => summaryMode ? ( ) : (

), h3: ({ ...props }) => summaryMode ? ( ) : (

), h4: ({ ...props }) => summaryMode ? ( ) : (

), h5: ({ ...props }) => summaryMode ? ( ) : (
), h6: ({ ...props }) => summaryMode ? ( ) : (
), // Customize paragraph styles p: ({ ...props }) => (

), // Customize list styles ul: ({ ...props }) => (