Gatsby MDX 블로그에 Prism Syntax Highlighting 적용하는 방법

Gatsby MDX 블로그에 Prism Syntax Highlighting 적용하는 방법

2023-04-05

안녕하세요. 이번 포스트에서는 Gatsby MDX 블로그에 Prism Syntax Highlighting 적용하는 방법에 대해서 알아보겠습니다.

Gatsby 공식사이트에서 MDX를 사용하여 블로그를 만드는 방법을 소개하고 있습니다. 그리고 gatsby-remark-prismjs 플러그인을 제공하지만, 막상 플러그인 문서를 따라해 보면 작동하지 않는 것을 확인할 수 있었습니다. 이번 포스트에서는 Gatsby MDX 블로그에 Prism Syntax Highlighting 적용하는 방법을 소개하겠습니다.

prism-react-renderer 플러그인을 설치합니다.

$ npm install prism-react-renderer

styled-components 플러그인을 설치합니다.

$ npm install gatsby-plugin-styled-components styled-components babel-plugin-styled-components

그리고 gatsby-config.js 파일에 방금 설치한 플러그인을 추가합니다.

module.exports = {
  plugins: [
    ...,
    `gatsby-plugin-styled-components`,
    ...,
    ],
}

/src/components/codeblock.js 파일을 만들고 아래 코드를 작성합니다.

import React from 'react'
import styled from 'styled-components'
import Highlight, { defaultProps } from 'prism-react-renderer'
import theme from 'prism-react-renderer/themes/dracula'

const Pre = styled.pre`  
text-align: left;
margin: 1em 0;
padding: 0.5em;
overflow-x: scroll;`

const Line = styled.div`
display: table-row;`

const LineNo = styled.span`
display: table-cell;
text-align: right;
padding-right: 1em;
user-select: none;
opacity: 0.5;`

const LineContent = styled.span`
display: table-cell;`

const CodeBlock = (props) => {
const className = props.children.props.className || ''
const matches = className.match(/language-(?<lang>.*)/)

return (

<Highlight
  {...defaultProps}
  code={props.children.props.children.trim()}
  language={
    matches && matches.groups && matches.groups.lang ? matches.groups.lang : ''
  }
  theme={theme}
>
  {({ className, style, tokens, getLineProps, getTokenProps }) => (
    <Pre className={className} style={style}>
      {tokens.map((line, i) => (
        <Line key={i} {...getLineProps({ line, key: i })}>
          <LineNo>{i + 1}</LineNo>
          <LineContent>
            {line.map((token, key) => (
              <span key={key} {...getTokenProps({ token, key })} />
            ))}
          </LineContent>
        </Line>
      ))}
    </Pre>
  )}
</Highlight>
) }

export default CodeBlock

그리고 `{mdx.frontmatter__slug}.js` 파일을 수정합니다.

import { MDXProvider } from '@mdx-js/react'
import CodeBlock from '../../components/codeblock'

const BlogPost = ({ data, children }) => {
return (

<Layout pageTitle={data.mdx.frontmatter.title}>
  ...
  <MDXProvider components={{ pre: CodeBlock }}>{children}</MDXProvider>
</Layout>
) } 

이렇게 코드를 작성하면, mdx로 작성된 코드블럭 부분 pre 코드가 CodeBlock 컴포넌트로 렌더링됩니다.

한가지 주의할 점은 MDX 파일에서 비어있는 코드블럭이 있을때 에러를 발생시키는 점이 있으니 참고 부탁 드립니다.

이렇게 prism syntax highlighting을 적용하는 방법에 대해서 알아봤습니다.

감사합니다.

참조:

< 목록으로 돌아가기