diff --git a/src/app/components/code-highlighter.tsx b/src/app/components/code-highlighter.tsx index ec0b246..93785f5 100644 --- a/src/app/components/code-highlighter.tsx +++ b/src/app/components/code-highlighter.tsx @@ -14,12 +14,62 @@ type CodeHighlighterProps = { rounded?: boolean; }; +import createElement from "react-syntax-highlighter/dist/esm/create-element"; + +/** + * Render the rows with the ability to render links. + * + * @param rows the rows to render + * @param stylesheet the stylesheet to use + * @param useInlineStyles should inline styles be used + * @returns the rendered rows + */ +function rowRenderer({ + rows, + stylesheet, + useInlineStyles, +}: { + rows: any; + stylesheet: { [key: string]: React.CSSProperties }; + useInlineStyles: boolean; +}) { + return rows.map((node: any, i: number) => { + node.children = node.children.map((children: any) => { + const text = children?.children?.[0]?.value; + + if (typeof text === "string" && text.startsWith('"http')) { + return { + ...children, + tagName: "a", + properties: { + ...children.properties, + href: text.slice(1, -1), // in JSON strings are enclosed with ", they need to be removed + target: "_blank", + // Tailwind CSS classes + class: "underline !text-primary hover:!text-muted-foreground transition-all", + }, + }; + } + + return children; + }); + + return createElement({ + node, + stylesheet, + useInlineStyles, + key: `code-segement${i}`, + }); + }); +} + export function CodeHighlighter({ code, rounded = true }: CodeHighlighterProps): ReactElement { return (