Skip to navigation

语法高亮

本指南探讨如何将语法高亮应用于代码块。 MDX 支持标准 Markdown 语法 (CommonMark)。 默认情况下,它不对代码块应用语法高亮。

有两种方法可以实现语法高亮: 在编译时或运行时。 在编译时执行此操作意味着预先花费精力,以便读者能够获得快速的体验,因为不会向他们发送额外的代码(语法高亮需要大量代码才能工作)。 在运行时执行此操作可以将工作转移给客户端,从而提供更大的灵活性。 但这可能会导致读者体验缓慢。 它还取决于你使用的框架(例如特定于 React、Preact、Vue 等)

编译时语法高亮

通过执行以下操作来使用 rehype-highlight (highlight.js) 或 @mapbox/rehype-prism (Prism):

example.js
import {compile} from '@mdx-js/mdx'
import rehypeHighlight from 'rehype-highlight'

const code = `~~~js
console.log(1)
~~~`

console.log(
  String(await compile(code, {rehypePlugins: [rehypeHighlight]}))
)
展开等效的 JSX
output.jsx
<>
  <pre>
    <code className="hljs language-js">
      <span className="hljs-variable language_">console</span>.
      <span className="hljs-title function_">log</span>(
      <span className="hljs-number">1</span>)
    </code>
  </pre>
</>

重要的: 如果你选择 rehype-highlight,那么你还应该在页面上的某个位置使用 highlight.js 主题。 例如,要从 cdnjs 获取 GitHub Dark:

HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">

如果你选择 @mapbox/rehype-prism,请添加类似以下内容来获取 Prism Dark:

HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/themes/prism-dark.min.css">

运行时语法高亮

例如使用 react-syntax-highlighter,执行如下操作:

example.jsx
import SyntaxHighlighter from 'react-syntax-highlighter'
import Post from './example.mdx' // Assumes an integration is used to compile MDX -> JS.

<Post components={{code}} />

function code({className, ...props}) {
  const match = /language-(\w+)/.exec(className || '')
  return match
    ? <SyntaxHighlighter language={match[1]} PreTag="div" {...props} />
    : <code className={className} {...props} />
}
展开等效的 JSX
output.jsx
<>
  <pre>
    <div
      className="language-js"
      style={{
        background: '#F0F0F0',
        color: '#444',
        display: 'block',
        overflowX: 'auto',
        padding: '0.5em'
      }}
    >
      <code style={{whiteSpace: 'pre'}}>
        <span>console.</span>
        <span style={{color: '#397300'}}>log</span>
        <span>(</span>
        <span style={{color: '#880000'}}>1</span>
        <span>)</span>
      </code>
    
</div>
  </pre>
</>

使用 meta 字段进行语法高亮显示

Markdown 支持代码的元字符串:

example.mdx
```js filename="index.js"
console.log(1)
```

meta 部分是语言之后的所有内容(在本例中为 js)。 这是 Markdown 的隐藏部分: 它通常被忽略。 但如上面的示例所示,这是放置一些额外字段的有用位置。

@mdx-js/mdx 不知道你是否将代码作为组件处理,也不知道该元字符串的格式是什么,因此它默认为 markdown 处理它的方式: meta 被忽略。

但是如果你想在运行时访问 meta 怎么办? 这正是 remark 插件 remark-mdx-code-meta 的作用。 它允许你在 meta 部分中键入 JSX 属性,你可以使用 pre 的组件来访问该属性。

该插件与所有备注插件一样,可以作为 remarkPluginsProcessorOptions 传递。 有关插件的更多信息可在 § 扩展 MDX 中找到

MDX 中文网 - 粤ICP备13048890号