home · Posts · Archive · Tags

使用react syntax highlighter及useClipboard強化程式碼區塊

react syntax highlighter + clipboard

  1. 先去讀 postsDirectory 的markdownfile交給matter將markdown轉成object
--- title: Hello slug: home --- # Hello world!

結果

{ content: '# Hello world!', data: { title: 'Hello', slug: 'home' } }
const fullPath = path.join(postsDirectory, `${id}.md`); const fileContents = fs.readFileSync(fullPath, 'utf8'); const matterResult = matter(fileContents); ...
  1. 將matterResult的markdown語法顯示出來 註:remarkGfm 讓他可以接受github的神奇markdown語法
import remarkGfm from 'remark-gfm' import ReactMarkdown from "react-markdown"; ... <ReactMarkdown components={components} remarkPlugins={[remarkGfm]}> {postData.contentHtml} </ReactMarkdown>
  1. 讓產生出來的程式需要有顏色的語法提示及複製功能 註:這裡是透過指定ReactMarkdown的components及使用chakra ui的useClipboard hook,如果codeblock有指定的程式語言就使用react-syntax-highlighter將他顯示語法提示
import { Container, Heading, Link, Code, useClipboard, Flex, Button } from "@chakra-ui/react"; import { PrismAsync as SyntaxHighlighter } from "react-syntax-highlighter"; function CodeBlock({ node, inline, className, children, ...props }: any) { const { onCopy, value, setValue, hasCopied } = useClipboard(children); const match = /language-(\w+)/.exec(className || ''); return !inline && match ? ( <Flex mb={2}> <SyntaxHighlighter style={darcula as { [key: string]: CSSProperties }} language={match[1]} PreTag="div" {...props} > {String(children).replace(/\n$/, '')} </SyntaxHighlighter> <Button ml={2} onClick={onCopy}colorScheme='blue' variant='outline'>{hasCopied ? "Copied!" : "Copy"}</Button> </Flex> ) : ( <Flex mb={2}> <Code {...props} colorScheme="blackAlpha"> {children} </Code> <Button ml={2} onClick={onCopy} colorScheme='blue' variant='outline'>{hasCopied ? "Copied!" : "Copy"}</Button> </Flex> ); } const components = { code: CodeBlock, };

ref:

👈Go Back

@alanhc