语法高亮
¥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-starry-night
(starry-night
)、rehype-highlight
(lowlight
、highlight.js
)或 @mapbox/rehype-prism
(refractor
、prism
):
¥Use for example rehype-starry-night
(starry-night
), rehype-highlight
(lowlight
, highlight.js
), or @mapbox/rehype-prism
(refractor
, prism
) by doing something like this:
import {compile} from '@mdx-js/mdx'
import rehypeStarryNight from 'rehype-starry-night'
const code = `~~~js
console.log(1)
~~~`
console.log(
String(await compile(code, {rehypePlugins: [rehypeStarryNight]}))
)
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
(alias) function rehypeStarryNight(options?: Readonly<Options> | null | undefined): (tree: Root, file: VFile) => Promise<Root>
import rehypeStarryNight
Plugin to highlight code with starry-night
.
- @param options Configuration (optional).
- @returns Transform.
const code: "~~~js\nconsole.log(1)\n~~~"
namespace console
var console: Console
The console
module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such asconsole.log()
,console.error()
andconsole.warn()
that can be used to write to any Node.js stream. - A global
console
instance configured to write toprocess.stdout
andprocess.stderr
. The globalconsole
can be used without callingrequire('console')
.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O
for more information.
Example using the global console
:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console
class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
- @see source
(method) Console.log(message?: any, ...optionalParams: any[]): void
Prints to stdout
with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3)
(the arguments are all passed to util.format()
).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format()
for more information.
- @since v0.1.100
var String: StringConstructor
(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const code: "~~~js\nconsole.log(1)\n~~~"
(property) rehypePlugins?: PluggableList | null | undefined
List of rehype plugins (optional).
(alias) function rehypeStarryNight(options?: Readonly<Options> | null | undefined): (tree: Root, file: VFile) => Promise<Root>
import rehypeStarryNight
Plugin to highlight code with starry-night
.
- @param options Configuration (optional).
- @returns Transform.
Expand equivalent JSX
<>
<pre>
<code className="language-js">
<span className="pl-en">console</span>.<span className="pl-c1">log</span>(<span className="pl-c1">1</span>)
</code>
</pre>
</>
重要的:你可能还必须在页面的某个地方包含 CSS。有关更多信息,请参阅你正在使用的插件的文档。
¥Important: you must likely also include CSS somewhere on the page. See the documentation of the plugin you’re using for more information.
运行时语法高亮
¥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.
console.log(<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
怎么办?这正是 rehype 插件 rehype-mdx-code-props
所做的。它允许你在 meta
部分中键入 JSX 属性,你可以使用 pre
的组件来访问该属性。
¥But what if you want to access meta
at runtime? That’s exactly what the rehype plugin rehype-mdx-code-props
does. It lets you type JSX attributes in the meta
part which you can access by with a component for pre
.
该插件与所有 rehype 插件一样,可以作为 rehypePlugins
于 ProcessorOptions
传递。有关插件的更多信息可在 § 扩展 MDX 中找到
¥That plugin, like all rehype plugins, can be passed as rehypePlugins
in ProcessorOptions
. More info on plugins is available in § Extending MDX