diff --git a/frontend/src/components/MdProcessor.tsx b/frontend/src/components/MdProcessor.tsx index c38951e..29132ef 100644 --- a/frontend/src/components/MdProcessor.tsx +++ b/frontend/src/components/MdProcessor.tsx @@ -4,12 +4,13 @@ import { useMemo, type ComponentPropsWithoutRef, type ReactElement, + type ReactNode, } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import rehypeRaw from "rehype-raw"; import rehypeSanitize from "rehype-sanitize"; -import highlighter from "../utils/highlighter"; +import { getHighlighter } from "../utils/highlighter"; function CopyButton({ code }: { code: string }): ReactElement { return ( @@ -23,13 +24,59 @@ function CopyButton({ code }: { code: string }): ReactElement { }, 1500); }); }} - className="absolute top-1 right-1 px-2 py-1 text-base font-mono text-ctp-subtext0 hover:text-ctp-green transition-colors cursor-pointer select-none z-10 font-[NerdFontSymbols]" + className="absolute top-1 right-1 px-2 py-1 text-base leading-none text-ctp-subtext0 hover:text-ctp-green transition-colors cursor-pointer select-none z-10 font-[NerdFontSymbols]" >  ); } +function HighlightedBlock({ + code, + lang, + children, +}: { + code: string; + lang: string; + children: ReactNode; +}): ReactElement { + const [html, setHtml] = useState(null); + + useEffect(() => { + getHighlighter().then((hl) => { + setHtml( + hl.codeToHtml(code, { + lang, + themes: { + dark: "catppuccin-macchiato", + light: "catppuccin-latte", + }, + defaultColor: false, + }), + ); + }); + }, [code, lang]); + + return ( +
+ + {lang} + + + {html ? ( +
+ ) : ( +
+                    {children}
+                
+ )} +
+ ); +} + const toRawUrl = (repoUrl: string): string => { if (!repoUrl) return repoUrl; @@ -180,34 +227,11 @@ export default function MdProcessor({ } } - const highlighted = - lang && code - ? highlighter.codeToHtml(code, { - lang, - themes: { - dark: "catppuccin-macchiato", - light: "catppuccin-latte", - }, - defaultColor: false, - }) - : null; - - if (highlighted) { + if (lang && code) { return ( -
- {lang && ( - - {lang} - - )} - -
-
+ + {children} + ); } diff --git a/frontend/src/utils/highlighter.ts b/frontend/src/utils/highlighter.ts index f35a5ee..38ec57a 100644 --- a/frontend/src/utils/highlighter.ts +++ b/frontend/src/utils/highlighter.ts @@ -1,6 +1,6 @@ -import { createHighlighter } from "shiki"; +import { createHighlighter, type Highlighter } from "shiki"; -export default await createHighlighter({ +const highlighterPromise = createHighlighter({ themes: ["catppuccin-macchiato", "catppuccin-latte"], langs: [ "javascript", @@ -69,3 +69,7 @@ export default await createHighlighter({ "tex", ], }); + +export function getHighlighter(): Promise { + return highlighterPromise; +}