Skip to main content
Version: Canary 🚧

代码块

文档中的代码块具有超级功能 💪。

代码标题

你可以通过在语言后面添加一个title键来为代码块添加标题(在它们之间留一个空格)。

```jsx title="/src/components/HelloCodeTitle.js"
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
```
http://localhost:3000
/src/components/HelloCodeTitle.js
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}

语法高亮

代码块是由三个反引号包围的文本块。您可以查看此参考以了解MDX的规范。

```js
console.log('Every repo must come with a mascot.');
```

为你的代码块使用匹配的语言元字符串,Docusaurus 将自动进行语法高亮,由 Prism React Renderer 提供支持。

http://localhost:3000
console.log('Every repo must come with a mascot.');

主题

默认情况下,我们使用的Prism 语法高亮主题Palenight。你可以通过在docusaurus.config.js中的prism中传递theme字段作为themeConfig来将其更改为另一个主题。

例如,如果您更喜欢使用dracula高亮主题:

docusaurus.config.js
import {themes as prismThemes} from 'prism-react-renderer';

export default {
themeConfig: {
prism: {
theme: prismThemes.dracula,
},
},
};

因为Prism主题只是一个JS对象,如果你对默认主题不满意,你也可以编写自己的主题。Docusaurus增强了githubvsDark主题以提供更丰富的代码高亮,你可以查看我们在lightdark代码块主题上的实现。

支持的语言

默认情况下,Docusaurus 附带了一组常用语言

warning

一些流行的语言如Java、C#或PHP默认情况下未启用。

要为任何其他Prism支持的语言添加语法高亮,请在附加语言的数组中定义它。

note

每种额外的语言必须是一个有效的Prism组件名称。例如,Prism会将语言 cs映射到csharp,但只有prism-csharp.js作为组件存在,因此你需要使用additionalLanguages: ['csharp']。你可以查看node_modules/prismjs/components以找到所有可用的组件(语言)。

例如,如果你想为PowerShell语言添加高亮显示:

docusaurus.config.js
export default {
// ...
themeConfig: {
prism: {
additionalLanguages: ['powershell'],
},
// ...
},
};

添加additionalLanguages后,重新启动Docusaurus。

如果你想为Prism尚未支持的语言添加高亮显示,你可以使用prism-include-languages

npm run swizzle @docusaurus/theme-classic prism-include-languages

它将在你的src/theme文件夹中生成prism-include-languages.js。你可以通过编辑prism-include-languages.js来添加对自定义语言的高亮支持:

src/theme/prism-include-languages.js
const prismIncludeLanguages = (Prism) => {
// ...

additionalLanguages.forEach((lang) => {
require(`prismjs/components/prism-${lang}`);
});

require('/path/to/your/prism-language-definition');

// ...
};

在编写自己的语言定义时,可以参考Prism的官方语言定义

当添加自定义语言定义时,您不需要将语言添加到additionalLanguages配置数组中,因为Docusaurus仅在Prism提供的语言中查找additionalLanguages字符串。在prism-include-languages.js中添加语言导入就足够了。

行高亮

使用注释进行高亮显示

你可以使用highlight-next-linehighlight-starthighlight-end的注释来选择哪些行被高亮显示。

```js
function HighlightSomeText(highlight) {
if (highlight) {
// highlight-next-line
return 'This text is highlighted!';
}

return 'Nothing highlighted';
}

function HighlightMoreText(highlight) {
// highlight-start
if (highlight) {
return 'This range is highlighted!';
}
// highlight-end

return 'Nothing highlighted';
}
```
http://localhost:3000
function HighlightSomeText(highlight) {
if (highlight) {
return 'This text is highlighted!';
}

return 'Nothing highlighted';
}

function HighlightMoreText(highlight) {
if (highlight) {
return 'This range is highlighted!';
}

return 'Nothing highlighted';
}

支持的注释语法:

StyleSyntax
C-style/* ... */ and // ...
JSX-style{/* ... */}
Bash-style# ...
HTML-style<!-- ... -->

我们将尽力根据语言推断使用哪种注释风格,并默认允许所有注释风格。如果有目前不支持的注释风格,我们愿意添加它们!欢迎提交拉取请求。请注意,不同的注释风格没有语义上的区别,只有它们的内容有区别。

您可以在src/css/custom.css中为高亮显示的代码行设置自己的背景颜色,这将更好地适应您选择的语法高亮主题。下面给出的颜色适用于默认的高亮主题(Palenight),因此如果您使用其他主题,您需要相应地调整颜色。

/src/css/custom.css
:root {
--docusaurus-highlighted-code-line-bg: rgb(72, 77, 91);
}

/* If you have a different syntax highlighting theme for dark mode. */
[data-theme='dark'] {
/* Color which works with dark mode syntax highlighting theme */
--docusaurus-highlighted-code-line-bg: rgb(100, 100, 100);
}

如果你还需要以其他方式为高亮的代码行设置样式,你可以针对theme-code-block-highlighted-line CSS类进行操作。

使用元数据字符串高亮显示

您还可以在语言元字符串中指定高亮的行范围(在语言后留一个空格)。要突出显示多行,可以用逗号分隔行号,或使用范围语法选择一组行。此功能使用parse-number-range库,您可以在他们的项目详情中找到更多语法

```jsx {1,4-6,11}
import React from 'react';

function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}

return <div>Foo</div>;
}

export default MyComponent;
```
http://localhost:3000
import React from 'react';

function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}

return <div>Foo</div>;
}

export default MyComponent;
prefer comments

在可能的情况下,优先使用注释进行高亮显示。通过在代码中内联高亮,如果代码块变长,您不必手动计算行数。如果您添加/删除行,也不必调整行范围。

- ```jsx {3}
+ ```jsx {4}
function HighlightSomeText(highlight) {
if (highlight) {
+ console.log('Highlighted text found');
return 'This text is highlighted!';
}

return 'Nothing highlighted';
}
```

下面,我们将介绍如何扩展魔法注释系统以定义自定义指令及其功能。只有在不存在高亮元字符串时,才会解析魔法注释。

自定义魔法注释

// highlight-next-line// highlight-start 等被称为“魔法注释”,因为它们会被解析并移除,其目的是为下一行或这对开始和结束注释所包围的部分添加元数据。

你可以通过主题配置声明自定义魔法注释。例如,你可以注册另一个魔法注释,添加一个code-block-error-line类名:

export default {
themeConfig: {
prism: {
magicComments: [
// Remember to extend the default highlight class name as well!
{
className: 'theme-code-block-highlighted-line',
line: 'highlight-next-line',
block: {start: 'highlight-start', end: 'highlight-end'},
},
{
className: 'code-block-error-line',
line: 'This will error',
},
],
},
},
};
http://localhost:3000

在 JavaScript 中,尝试访问 null 的属性会出错。

const name = null;
console.log(name.toUpperCase());
// 未捕获的类型错误:无法读取 null 的属性(读取 'toUpperCase')

如果你在元字符串中使用数字范围({1,3-4} 语法),Docusaurus 将应用第一个 magicComments 条目的类名。默认情况下,这是 theme-code-block-highlighted-line,但如果你更改了 magicComments 配置并使用不同的条目作为第一个条目,元字符串范围的含义也会随之改变。

你可以使用magicComments: []来禁用默认的行高亮注释。如果没有魔法注释配置,但Docusaurus遇到包含元字符串范围的代码块,它会报错,因为没有类名可以应用——毕竟,高亮类名只是一个魔法注释条目。

每个魔法注释条目将包含三个键:className(必需),line,适用于紧接着的下一行,或block(包含startend),适用于由两个注释包围的整个块。

使用CSS来定位类已经可以做很多事情,但你可以通过swizzling来解锁这个功能的全部潜力。

npm run swizzle @docusaurus/theme-classic CodeBlock/Line

Line 组件将接收类名列表,基于此你可以有条件地渲染不同的标记。

行号

你可以通过在语言元字符串中使用showLineNumbers键来为你的代码块启用行号(别忘了在键前直接添加空格)。

```jsx {1,4-6,11} showLineNumbers
import React from 'react';

function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}

return <div>Foo</div>;
}

export default MyComponent;
```
http://localhost:3000
import React from 'react';

function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}

return <div>Foo</div>;
}

export default MyComponent;

交互式代码编辑器

(由 React Live 提供支持)

你可以使用@docusaurus/theme-live-codeblock插件创建一个交互式代码编辑器。首先,将插件添加到你的包中。

npm install --save @docusaurus/theme-live-codeblock

您还需要将插件添加到您的docusaurus.config.js中。

export default {
// ...
themes: ['@docusaurus/theme-live-codeblock'],
// ...
};

要使用该插件,请创建一个带有live附加到语言元字符串的代码块。

```jsx live
function Clock(props) {
const [date, setDate] = useState(new Date());
useEffect(() => {
const timerID = setInterval(() => tick(), 1000);

return function cleanup() {
clearInterval(timerID);
};
});

function tick() {
setDate(new Date());
}

return (
<div>
<h2>It is {date.toLocaleTimeString()}.</h2>
</div>
);
}
```

代码块将呈现为交互式编辑器。代码的更改将实时反映在结果面板上。

http://localhost:3000
Live Editor
function Clock(props) {
  const [date, setDate] = useState(new Date());
  useEffect(() => {
    const timerID = setInterval(() => tick(), 1000);

    return function cleanup() {
      clearInterval(timerID);
    };
  });

  function tick() {
    setDate(new Date());
  }

  return (
    <div>
      <h2>It is {date.toLocaleTimeString()}.</h2>
    </div>
  );
}
Result
Loading...

导入

react-live and imports

无法直接从 react-live 代码编辑器导入组件,您必须预先定义可用的导入。

默认情况下,所有 React 导入都是可用的。如果您需要更多可用的导入,请自定义 react-live 范围:

npm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope -- --eject
src/theme/ReactLiveScope/index.js
import React from 'react';

const ButtonExample = (props) => (
<button
{...props}
style={{
backgroundColor: 'white',
color: 'black',
border: 'solid red',
borderRadius: 20,
padding: 10,
cursor: 'pointer',
...props.style,
}}
/>
);

// Add react-live imports you need here
const ReactLiveScope = {
React,
...React,
ButtonExample,
};

export default ReactLiveScope;

ButtonExample 组件现在可以使用:

http://localhost:3000
Live Editor
function MyPlayground(props) {
  return (
    <div>
      <ButtonExample onClick={() => alert('hey!')}>Click me</ButtonExample>
    </div>
  );
}
Result
Loading...

命令式渲染 (noInline)

当你的代码跨越多个组件或变量时,应使用noInline选项以避免错误。

```jsx live noInline
const project = 'Docusaurus';

const Greeting = () => <p>Hello {project}!</p>;

render(<Greeting />);
```

与普通的交互式代码块不同,当使用noInline时,React Live 不会将你的代码包装在内联函数中进行渲染。

你需要在代码末尾显式调用render()来显示输出。

http://localhost:3000
Live Editor
const project = "Docusaurus";

const Greeting = () => (
  <p>Hello {project}!</p>
);

render(
  <Greeting />
);
Result
Loading...

在代码块中使用JSX标记

Markdown中的代码块始终将其内容保留为纯文本,这意味着你不能做类似以下的事情:

type EditUrlFunction = (params: {
// This doesn't turn into a link (for good reason!)
version: <a href="/docs/versioning">Version</a>;
versionDocsDirPath: string;
docPath: string;
permalink: string;
locale: string;
}) => string | undefined;

如果你想嵌入HTML标记,比如锚链接或粗体类型,你可以使用

标签,标签,或组件。

<pre>
<b>Input: </b>1 2 3 4{'\n'}
<b>Output: </b>"366300745"{'\n'}
</pre>
http://localhost:3000
Input: 1 2 3 4
Output: "366300745"
MDX is whitespace insensitive

MDX 与 JSX 行为一致:换行符,即使在

 标签内,也会被转换为空格。你必须显式地写入换行符才能将其打印出来。

warning

语法高亮仅适用于纯字符串。Docusaurus 不会尝试解析包含 JSX 子元素的代码块内容。

多语言支持代码块

使用MDX,您可以轻松地在文档中创建交互式组件,例如,使用标签组件显示多种编程语言的代码并在它们之间切换。

我们没有为多语言支持代码块实现一个专门的组件,而是在经典主题中实现了一个通用的组件,这样你也可以将其用于其他非代码场景。

以下示例展示了如何在文档中设置多语言代码标签。请注意,每种语言块上方和下方的空行是有意为之的。这是MDX的当前限制:你必须在Markdown语法周围留出空行,以便MDX解析器知道它是Markdown语法而不是JSX。

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<Tabs>
<TabItem value="js" label="JavaScript">

```js
function helloWorld() {
console.log('Hello, world!');
}
```

</TabItem>
<TabItem value="py" label="Python">

```py
def hello_world():
print("Hello, world!")
```

</TabItem>
<TabItem value="java" label="Java">

```java
class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello, World");
}
}
```

</TabItem>
</Tabs>

你将得到以下内容:

http://localhost:3000
function helloWorld() {
console.log('Hello, world!');
}

如果您有多个这样的多语言代码标签,并且您想要在标签实例之间同步选择,请参考同步标签选择部分

Docusaurus npm2yarn 备注插件

在npm和Yarn中显示CLI命令是一个非常常见的需求,例如:

npm install @docusaurus/remark-plugin-npm2yarn

Docusaurus 提供了一个开箱即用的实用工具,使您无需每次使用 Tabs 组件。要启用此功能,首先按照上述方式安装 @docusaurus/remark-plugin-npm2yarn 包,然后在 docusaurus.config.js 中,在需要此功能的插件(文档、博客、页面等)中,将其注册到 remarkPlugins 选项中。(有关配置格式的更多详细信息,请参阅 文档配置

docusaurus.config.js
export default {
// ...
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [
[require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}],
],
},
pages: {
remarkPlugins: [require('@docusaurus/remark-plugin-npm2yarn')],
},
blog: {
remarkPlugins: [
[
require('@docusaurus/remark-plugin-npm2yarn'),
{converters: ['pnpm']},
],
],
// ...
},
},
],
],
};

然后通过在代码块中添加npm2yarn键来使用它:

```bash npm2yarn
npm install @docusaurus/remark-plugin-npm2yarn
```

配置

OptionTypeDefaultDescription
syncbooleanfalseWhether to sync the selected converter across all code blocks.
convertersarray'yarn', 'pnpm'The list of converters to use. The order of the converters is important, as the first converter will be used as the default choice.

在JSX中的使用

在Markdown之外,你可以使用@theme/CodeBlock组件来获得相同的输出。

import CodeBlock from '@theme/CodeBlock';

export default function MyReactPage() {
return (
<div>
<CodeBlock
language="jsx"
title="/src/components/HelloCodeTitle.js"
showLineNumbers>
{`function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}`}
</CodeBlock>
</div>
);
}
http://localhost:3000
/src/components/HelloCodeTitle.js
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}

接受的属性是 languagetitleshowLineNumbers,就像你写 Markdown 代码块一样。

虽然不推荐,但你也可以传入一个metastring属性,如metastring='{1-2} title="/src/components/HelloCodeTitle.js" showLineNumbers',这是Markdown代码块在底层处理的方式。然而,我们建议你使用注释来高亮显示行

之前所述,语法高亮仅在子元素为简单字符串时应用。