MDX 外掛
有時候,您可能想擴充或微調您的 Markdown 語法。例如
- 我如何使用圖片語法 (

) 嵌入 YouTube 影片? - 我如何將位於其自己獨立行的連結設定不同的樣式,例如,做成一張社群卡片?
- 我如何讓每個頁面從版權聲明開始?
答案是:建立一個 MDX 外掛!MDX 有建置的 外掛系統,可以用於自訂將 Markdown 檔案轉換至 JSX 的方式。以下有三種常見的 MDX 外掛使用情境
- 使用現有的 remark 外掛 或 rehype 外掛;
- 建立 remark/rehype 外掛元件以轉換現有 MDX 語法產生的元素;
- 建立 remark/rehype 外掛元件,把新語法引入 MDX。
玩過 MDX 播放器 的話,你應該會注意到 MDX 轉譯有兩個中間步驟:Markdown AST (MDAST) 和超文字 AST (HAST),最後才會產生 JSX 成果。MDX 外掛元件也有兩種形式
使用外掛元件,可以對專案中最常使用的 JSX 元素使用更簡潔的語法。我們提供的 注意事項 語法也是由 Remark 外掛元件產生的,你也可以這樣做,符合自己的使用案例。
預設外掛元件
在處理 Markdown 時,Docusaurus 會注入 一些預設的 Remark 外掛元件。這些外掛元件會
- 產生目錄;
- 針對每個標題加入錨點連結;
- 轉換圖片和連結到
require()
呼叫。 - …
這些都是 Remark 外掛元件常見的用例,如果你想實做你自己的外掛元件的話,也可以當成靈感來源。
安裝外掛元件
MDX 外掛元件通常是 npm 套件,所以安裝方式和其他 npm 套件一樣,使用 npm。以 數學外掛元件 為例。
- npm
- Yarn
- pnpm
npm install --save remark-math@5 rehype-katex@6
yarn add remark-math@5 rehype-katex@6
pnpm add remark-math@5 rehype-katex@6
remark-math
和 rehype-katex
有什麼不同?
如果你好奇 Remark 和 Rehype 的不同之處,以下是個很好的範例。remark-math
操作 Markdown AST,在此它看到 $...$
等文字,所做的操作就是將它轉換為 JSX <span class="math math-inline">...</span>
,而不會對內容進行太多處理。此舉能將數學公式的提取與其渲染相互分離,這表示你可以透過替換 Rehype 外掛程式,使用其他數學渲染程式,例如 MathJax(使用 rehype-mathjax
)。
接著,rehype-katex
操作 Hypertext AST,其中所有內容都已轉換為類似的 HTML 標籤。它會遍歷所有 Math 類別的元素,並使用 來剖析並將內容渲染為實際 HTML。
接著,匯入外掛並透過「docusaurus.config.js」中的外掛或預設值設定,將其新增至外掛選項
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
path: 'docs',
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
},
},
],
],
};
使用 CommonJS 設定檔?
如果您決定使用 CommonJS 設定檔,可以藉由動態匯入和非同步設定函式建構器函式,載入這些 ES 模組外掛
module.exports = async function createConfigAsync() {
return {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
path: 'docs',
remarkPlugins: [(await import('remark-math')).default],
rehypePlugins: [(await import('rehype-katex')).default],
},
},
],
],
};
};
設定外掛
某些外掛可設定,並接受自身的選項。此時,請使用「[外掛,外掛選項]
」語法,如下所示
import rehypeKatex from 'rehype-katex';
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
rehypePlugins: [
[rehypeKatex, {strict: false}],
],
},
},
],
],
};
您應該查看外掛的文件,了解其支援的選項。
建立新的 rehype/remark 外掛
如果沒有現有的套件能滿足您的自訂需求,您可以建立自己的 MDX 外掛。
例如,我們製作一個外掛,拜訪每個 h2
標題,並加上 第 X 節
字首。首先,在任何地方建立您的外掛原始檔,您甚至可以將其發布為獨立的 npm 套件,並依照上述說明進行安裝。我們會將外掛放在 src/remark/section-prefix.js
。remark/rehype 外掛只是接收 選項
並傳回一個執行 AST 的 轉換器
的函式。
import {visit} from '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;
};
export default plugin;
現在,您可以在 docusaurus.config.js
中匯入您的外掛,並像安裝的外掛一樣使用它!
import sectionPrefix from './src/remark/section-prefix';
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [sectionPrefix],
},
},
],
],
};
轉換器
有第二個參數 vfile
,如果您需要存取目前 Markdown 檔案的路徑,此參數會很有用。
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()
呼叫。
Docusaurus 的預設外掛程式會在自訂 remark 外掛程式之前執行,這表示圖片或連結已經透過 require()
呼叫轉換為 JSX。例如,在上面的範例中,即使所有 h2
標題現在都加上 Section X.
前綴,產生的目錄仍然相同,因為產生目錄的外掛程式是在我們的自訂外掛程式之前呼叫。如果您需要在預設外掛程式處理之前處理 MDAST,請使用 beforeDefaultRemarkPlugins
和 beforeDefaultRehypePlugins
。
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
beforeDefaultRemarkPlugins: [sectionPrefix],
},
},
],
],
};
這樣產生的目錄也會包含 Section X.
前綴。