语法高亮
¥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:
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
<>
<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:
<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:
<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:
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
<>
<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:
```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 插件一样,可以作为 remarkPlugins
于 ProcessorOptions
传递。有关插件的更多信息可在 § 扩展 MDX 中找到
¥That plugin, like all remark plugins, can be passed as remarkPlugins
in ProcessorOptions
. More info on plugins is available in § Extending MDX