import type { CSSProperties } from "react"; import ReactMarkdown, { type Components } from "react-markdown"; import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter"; import remarkGfm from "remark-gfm"; import { ErrorBoundary } from "./ErrorBoundary"; import { Prose } from "./Prose"; interface Props { children: string | null; className?: string; } export function Markdown({ children, className }: Props) { if (children == null) return null; return ( {children} ); } const prismTheme = { 'pre[class*="language-"]': { // Needs to be here, so the lib doesn't add its own }, // Syntax tokens comment: { color: "var(--textSubtle)" }, prolog: { color: "var(--textSubtle)" }, doctype: { color: "var(--textSubtle)" }, cdata: { color: "var(--textSubtle)" }, punctuation: { color: "var(--textSubtle)" }, property: { color: "var(--primary)" }, "attr-name": { color: "var(--primary)" }, string: { color: "var(--notice)" }, char: { color: "var(--notice)" }, number: { color: "var(--info)" }, constant: { color: "var(--info)" }, symbol: { color: "var(--info)" }, boolean: { color: "var(--warning)" }, "attr-value": { color: "var(--warning)" }, variable: { color: "var(--success)" }, tag: { color: "var(--info)" }, operator: { color: "var(--danger)" }, keyword: { color: "var(--danger)" }, function: { color: "var(--success)" }, "class-name": { color: "var(--primary)" }, builtin: { color: "var(--danger)" }, selector: { color: "var(--danger)" }, inserted: { color: "var(--success)" }, deleted: { color: "var(--danger)" }, regex: { color: "var(--warning)" }, important: { color: "var(--danger)", fontWeight: "bold" }, italic: { fontStyle: "italic" }, bold: { fontWeight: "bold" }, entity: { cursor: "help" }, }; const lineStyle: CSSProperties = { paddingRight: "1.5em", paddingLeft: "0", opacity: 0.5, }; const markdownComponents: Partial = { // Ensure links open in external browser by adding target="_blank" a: ({ href, children, ...rest }) => { if (href && !href.match(/https?:\/\//)) { href = `http://${href}`; } return ( {children} ); }, code(props) { const { children, className, ref, ...extraProps } = props; extraProps.node = undefined; const match = /language-(\w+)/.exec(className || ""); return match ? ( {String(children as string).replace(/\n$/, "")} ) : ( {children} ); }, };