Skip to navigation

语法高亮

¥Syntax highlighting

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

¥This guide explores how to apply syntax highlighting to code blocks. MDX supports standard markdown syntax (CommonMark). It does not apply syntax highlighting to code blocks by default.

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

¥There are two ways to accomplish syntax highlighting: at compile time or at runtime. Doing it at compile time means the effort is spent upfront so that readers will have a fast experience as no extra code is sent to them (syntax highlighting needs a lot of code to work). Doing it at runtime gives more flexibility by moving the work to the client. This can result in a slow experience for readers though. It also depends on what framework you use (as in it’s specific to React, Preact, Vue, etc.)

编译时语法高亮

¥Syntax highlighting at compile time

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

¥Use either rehype-highlight (highlight.js) or @mapbox/rehype-prism (Prism) by doing something like this:

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]}))
)
Expand equivalent 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:

¥Important: If you chose rehype-highlight, then you should also use a highlight.js theme somewhere on the page. For example, to get GitHub Dark from cdnjs:

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:

¥If you chose @mapbox/rehype-prism, include something like this instead to get Prism Dark:

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

运行时语法高亮

¥Syntax highlighting at run time

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

¥Use for example react-syntax-highlighter, by doing something like this:

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, ...properties}) {
  const match = /language-(\w+)/.exec(className || '')
  return match
    ? <SyntaxHighlighter language={match[1]} PreTag="div" {...properties} />
    : <code className={className} {...properties} />
}
Expand equivalent 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 字段进行语法高亮显示

¥Syntax highlighting with the meta field

Markdown 支持代码的元字符串:

¥Markdown supports a meta string for code:

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

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

¥The meta part is everything after the language (in this case, js). This is a hidden part of markdown: it’s normally ignored. But as the above example shows, it’s a useful place to put some extra fields.

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

¥@mdx-js/mdx doesn’t know whether you’re handling code as a component or what the format of that meta string is, so it defaults to how markdown handles it: meta is ignored.

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

¥But what if you want to access meta at runtime? That’s exactly what the remark plugin remark-mdx-code-meta does. It lets you type JSX attributes in the meta part which you can access by with a component for pre.

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

¥That plugin, like all remark plugins, can be passed as remarkPlugins in ProcessorOptions. More info on plugins is available in § Extending MDX

MDX 中文网 - 粤ICP备13048890号