MDX 플러그인
간혹 마크다운 구문을 확장하거나 변경할 수 있습니다. 예를 들면 아래와 같은 형식입니다.
- image 구문(

)을 사용해 유튜브 동영상을 삽입하려면 어떻게 해야 하나요? - 소셜 카드처럼 자체 라인에 있는 링크 스타일을 다르게 지정하려면 어떻게 해야 하나요?
- 모든 페이지에 저작권 표시를 하려면 어떻게 하나요?
해결책은 MDX 플러그인을 만드는 겁니다! MDX는 마크다운 파일을 구문분석하고 JSX로 변환하는 방식을 사용자가 지정할 수 있는 내장 플러그인 시스템이 있습니다. MDX 플러그인의 세 가지 일반적인 사용 사례는 다음과 같습니다.
- 기존 remark plugins 또는 rehype plugins을 사용합니다.
- 기존 MDX 구문으로 생성된 요소를 변환하기 위한 remark/rehype 플러그인을 만듭니다.
- MDX에 새로운 구문을 도입하기 위한 remark/rehype 플러그인을 만듭니다.
MDX 플레이그라운드에서 확인하고 있다면 MDX를 JSX로 변환 시 마크다운 AST(MDAST), 하이퍼텍스트 AST(HAST) 두 개의 중간 단계가 있다는 것을 확인할 수 있습니다. MDX 플러그인 또한 두 가지 형태입니다.
플러그인을 사용해 프로젝트에서 가장 일반적으로 사용하는 JSX 요소를 좀 더 짧은 구문으로 만들 수 있습니다. 도큐사우루스에서 사용하는 준수 사항 구문은 Remark 플러그인으로 만들어지며 여러분도 여러분만의 준수 사항을 위한 플러그인을 사용할 수 있습니다.
기본 플러그인
도큐사우루스는 마크다운 처리를 위해 몇 가지 기본 Remark 플러그인을 사용합니다. 이런 플러그인은 다음 작업을 처리합니다.
- 컨텐츠 테이블 생성
- 각 제목에 링크 추가
- 이미지와 링크를
require()
호출로 변환 - …
이들은 모두 Remark 플러그인의 일반적인 사용 사례이며 여러분이 원하는 형태의 플러그인 개발 시 참고할 수 있습니다.
플러그인 설치하기
MDX 플러그인은 npm 패키지 형태로 제공됩니다. npm을 사용해 다른 npm 패키지처럼 설치할 수 있습니다. math 플러그인이라면 아래와 같이 설치합니다.
- npm
- Yarn
- pnpm
npm install --save remark-math@3 rehype-katex@4
yarn add remark-math@3 rehype-katex@4
pnpm add remark-math@3 rehype-katex@4
최근 Remark/Rehype 생태계는 도큐사우루스에서 아직 지원하지 않는 새로운 자바스크립트 모듈 시스템인 ES 모듈로 마이그레이션하는 추세가 있습니다. ESM을 공식적으로 지원하기 전에는 설치된 플러그인 버전이 CommonJS와 호환되는지 확인하세요. 또는 rehype-katex
설치 튜토리얼에서 해결책으로 동적 import()
사용에 대한 가이드를 찾아볼 수 있습니다.
How are remark-math
and rehype-katex
different?
In case you are wondering how Remark and Rehype are different, here is a good example. remark-math
operates on the Markdown AST, where it sees text like $...$
, and all it does is transform that to the JSX <span class="math math-inline">...</span>
without doing too much with the content. This decouples the extraction of math formulae from their rendering, which means you can swap out with other math renderers, like MathJax (with rehype-mathjax
), just by replacing the Rehype plugin.
Next, the rehype-katex
operates on the Hypertext AST where everything has been converted to HTML-like tags already. It traverses all the elements with math
class and uses to parse and render the content to actual HTML.
그런 다음 docusaurus.config.js
에서 플러그인 또는 사전 설정 구성을 플러그인 옵션에 추가합니다.
const math = require('remark-math');
const katex = require('rehype-katex');
module.exports = {
title: 'Docusaurus',
tagline: 'Build optimized websites quickly, focus on your content',
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [math],
rehypePlugins: [katex],
},
},
],
],
};
플러그인 설정하기
일부 플러그인은 설정이나 옵션 기능을 지원합니다. 아래 설정에서 [plugin, pluginOptions]
구문이 그러한 항목입니다.
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [math],
rehypePlugins: [
[katex, {strict: false}],
],
},
},
],
],
};
플러그인이 지원하는 옵션에 대해서는 플러그인 문서를 참고해야 합니다.
새로운 rehype/remark 플러그인 만들기
요구사항을 충족하는 기존 패키지가 없다면 새로운 MDX 플러그인을 만들 수 있습니다.
예를 들어 h2
로 작성한 항목 앞에 Section X.
형태의 접두사를 붙이도록 플러그인을 만들 수 있습니다. 먼저 플러그인 소스 파일을 생성합니다. 별도의 npm 패키지로 배포하고 위에서 설명한 대로 설치할 수 있습니다. src/remark/section-prefix.js
파일로 작성할 겁니다. remark/rehype 플러그인은 options
값을 받아서 AST에서 처리한 transformer
를 반환하는 함수일 뿐입니다.
const visit = require('unist-util-visit');
const plugin = (options) => {
const transformer = async (ast) => {
let number = 1;
visit(ast, 'heading', (node) => {
if (node.depth === 2 && node.children.length > 0) {
node.children.unshift({
type: 'text',
value: `Section ${number}. `,
});
number++;
}
});
};
return transformer;
};
module.exports = plugin;
이제 docusaurus.config.js
에서 플러그인을 가져와 다른 설치된 플러그인처럼 사용할 수 있습 니다!
const sectionPrefix = require('./src/remark/section-prefix');
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [sectionPrefix],
},
},
],
],
};
transformer
에는 현재 마크다운 파일 경로에 접근해야 하는 경우 유용한 두 번째 매개변수 vfile
이 있습니다.
const plugin = (options) => {
const transformer = async (ast, vfile) => {
ast.children.unshift({
type: 'text',
value: `The current file path is ${vfile.path}`,
});
};
return transformer;
};
예를 들어 우리의 transformImage
플러그인은 해당 매개변수를 사용해 상대 이미지 참조를 require()
호출로 변환합니다.
도큐사우루스의 기본 플러그인은 사용자 정의 remark 플러그인보다 먼저 동작합니다. 때문에 require()
호출 시 이미지 또는 링크는 JSX로 변환됩니다. 예를 들어 위의 예에서 모든 h2
제목에 Section X.
접두사가 붙더라도 생성된 목차는 달라지지 않습니다. 사용자 정의 플러그인보다 TOC-generating 플러그인이 호출되기 때문입니다. 기본 플러그인보다 먼저 MDAST를 처리해야 한다면 beforeDefaultRemarkPlugins
와 beforeDefaultRehypePlugins
를 사용하세요.
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
beforeDefaultRemarkPlugins: [sectionPrefix],
},
},
],
],
};
이렇게 하면 생성된 목차에 Section X.
접두사가 포함됩니다.