/* Copyright 2026 Marimo. All rights reserved. */ import { marked } from "marked"; import { useState } from "react"; import { MarkdownRenderer } from "@/components/markdown/markdown-renderer"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Events } from "@/utils/events"; import type { ContentPart } from "@/utils/url-parser"; const ImageWithFallback = ({ url }: { url: string }) => { const [error, setError] = useState(false); const [open, setOpen] = useState(false); if (error) { return ; } return ( setOpen(true)} onMouseLeave={() => setOpen(false)} > setError(true)} /> setError(true)} /> ); }; export function isMarkdown(text: string): boolean { const tokens = marked.lexer(text); const commonMarkdownIndicators = new Set([ "space", "code", "fences", "heading", "hr", "link", "blockquote", "list", "html", "def", "table", "lheading", "escape", "tag", "reflink", "strong", "codespan", "url", ]); return tokens.some((token) => commonMarkdownIndicators.has(token.type)); } // Wrapper component so that we call isMarkdown only on trigger export const MarkdownUrlDetector = ({ content, parts, }: { content: string; parts: ContentPart[]; }) => { if (isMarkdown(content)) { return ; } return ; }; export const UrlDetector = ({ parts }: { parts: ContentPart[] }) => { const markup = parts.map((part, idx) => { if (part.type === "url") { return ; } if (part.type === "image") { return ; } return part.value; }); return markup; }; const URLAnchor = ({ url }: { url: string }) => { return ( {url} ); };