"use client"; import { Popover, PopoverTrigger, PopoverContent, } from "@/components/ui/popover"; import { useMemo } from "react"; import ReactMarkdown, { Components } from "react-markdown"; import rehypeRaw from "rehype-raw"; import { useTTS } from "./TTSProvider"; import rehypeHighlight from "@/lib/utils"; import { Database } from "@/utils/supabase/types"; // Utility to escape regex special characters: function escapeRegExp(text: string) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); } export type OCRData = { index: number; images: string[]; markdown: string; citations: Record; dimensions: { dpi: number; width: number; height: number; }; }; export default function MarkdownRenderer({ document, }: { document: Database["public"]["Tables"]["documents"]["Row"]; }) { // Obtain TTS info from context. // TTSProvider is already wrapping this component higher in the tree. const { currentSentence, sentences } = useTTS(); // Determine the text to highlight. const textToHighlight = useMemo(() => { if (!sentences || sentences.length === 0) return ""; return sentences[currentSentence] || ""; }, [sentences, currentSentence]); // Setup rehype plugins including our highlight plugin. const rehypePlugins = useMemo( () => [rehypeRaw, [rehypeHighlight, { textToHighlight }] as any], [textToHighlight] ); const ocr = document?.ocr_data as OCRData[]; const rawContent = ocr.map((page) => page.markdown).join("\n") || ""; const citations: { text: string; page: number; index: string; number: number; }[] = []; const totalPages = ocr.length; const totalSentences = sentences.length; let totalCitations = 0; ocr.forEach((page) => { Object.entries(page.citations).forEach(([key, value]) => { if (value) { totalCitations++; citations.push({ text: value, page: page.index, index: key, number: Number(totalCitations), }); } }); }); const components: Components = { h1: ({ node, ...props }) => (

), h2: ({ node, ...props }) => (

), h3: ({ node, ...props }) => (

), h4: ({ node, ...props }) => (

), p: ({ node, ...props }) => (

), img: ({ node, ...props }) => ( ), a: ({ node, ...props }) => ( ), strong: ({ node, ...props }) => ( ), blockquote: ({ node, ...props }) => (

), code: ({ node, ...props }) => ( ), sup: ({ node, ...props }) => { // Check if the text contains a reference number const text = props.children!.toString(); const referenceNumber = text; if (!referenceNumber) { return ; } const citation = citations.find( (c) => c.index === referenceNumber && c.page === page.index ); if (!citation) { return ; } return ( // TODO: get the references from the document and display them in a popover
{/* Replace with actual reference content */}

{citation.text}

); }, }; return ( ); }