import { useEffect, useState, useMemo } from "react"; import ReactMarkdown from "react-markdown"; import rehypeRaw from "rehype-raw"; const toRawUrl = (repoUrl) => { if (!repoUrl) return repoUrl; if ( repoUrl.includes("github.com") && !repoUrl.includes("raw.githubusercontent.com") ) { return repoUrl .replace("github.com", "raw.githubusercontent.com") .replace("/blob/", "/"); } if (repoUrl.includes("/src/branch/")) { return repoUrl.replace("/src/branch/", "/raw/branch/"); } return repoUrl; }; const getRepoRawBase = (repoUrl) => { const rawUrl = toRawUrl(repoUrl); if (!rawUrl) return null; try { const url = new URL(rawUrl); const parts = url.pathname.split("/").filter(Boolean); if (url.hostname.includes("raw.githubusercontent.com")) { return `${url.origin}/${parts.slice(0, 3).join("/")}`; } const rawIndex = parts.indexOf("raw"); if (rawIndex !== -1) { return `${url.origin}/${parts.slice(0, rawIndex + 2).join("/")}`; } return null; } catch { return null; } }; const resolveImageSrc = (src, base) => { if (!src) return src; if (src.startsWith("http")) return src; if (src.includes("/blob/")) { return src .replace("github.com", "raw.githubusercontent.com") .replace("/blob/", "/"); } if (!base) return src; const clean = src.replace(/^.\//, ""); if (src.startsWith("/")) { return base + src; } return `${base}/${clean}`; }; const fetchREADME = async (repoUrl) => { try { const rawUrl = toRawUrl(repoUrl); const response = await fetch(rawUrl); if (!response.ok) { throw new Error("Failed to fetch README"); } return await response.text(); } catch (error) { console.error(error); return "Error fetching README. Make sure the URL points to a raw markdown file."; } }; export default function ProjectsReadme({ repoUrl }) { const [readmeContent, setReadmeContent] = useState(""); const [isLoading, setIsLoading] = useState(true); const base = useMemo(() => getRepoRawBase(repoUrl), [repoUrl]); useEffect(() => { fetchREADME(repoUrl).then((content) => { setReadmeContent(content); setIsLoading(false); }); }, [repoUrl]); return (
{children}
);
},
pre({ children, ...props }) {
return (
{children}
);
},
h1: ({ children }) => (
{children}
), ul: ({ children }) => ({children}), img: ({ src, alt }) => { const resolved = resolveImageSrc(src, base); return (