11import React , { useState , useEffect , useRef } from 'react' ;
22import { useParams , Link } from 'react-router-dom' ;
33import ReactMarkdown from 'react-markdown' ;
4+ import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' ;
5+ import { customTheme } from '../utils/customTheme' ;
46import PostMetadata from '../components/PostMetadata' ;
57import { ArrowLeftIcon , ArrowSquareOutIcon } from '@phosphor-icons/react' ;
68
@@ -13,6 +15,27 @@ const LinkRenderer = ({ href, children }) => {
1315 ) ;
1416} ;
1517
18+
19+
20+ const CodeBlock = ( { node, inline, className, children, ...props } ) => {
21+ const match = / l a n g u a g e - ( \w + ) / . exec ( className || '' ) ;
22+ return ! inline && match ? (
23+ < SyntaxHighlighter
24+ style = { customTheme }
25+ language = { match [ 1 ] }
26+ PreTag = "div"
27+ { ...props }
28+ codeTagProps = { { style : { fontFamily : "'JetBrains Mono', monospace" } } }
29+ >
30+ { String ( children ) . replace ( / \n $ / , '' ) }
31+ </ SyntaxHighlighter >
32+ ) : (
33+ < code className = { `${ className } font-mono bg-gray-800` } { ...props } >
34+ { children }
35+ </ code >
36+ ) ;
37+ } ;
38+
1639const BlogPostPage = ( ) => {
1740 const { slug } = useParams ( ) ;
1841 const [ post , setPost ] = useState ( null ) ;
@@ -121,7 +144,7 @@ const BlogPostPage = () => {
121144 < ArrowLeftIcon size = { 24 } /> Back to Home
122145 </ Link >
123146 < div ref = { contentRef } className = "prose prose-xl prose-dark max-w-none" >
124- < ReactMarkdown components = { { a : LinkRenderer } } > { post . body } </ ReactMarkdown >
147+ < ReactMarkdown components = { { a : LinkRenderer , code : CodeBlock } } > { post . body } </ ReactMarkdown >
125148 </ div >
126149 </ div >
127150 < div className = "hidden lg:block" >
0 commit comments