代码块
文档中的代码块具有超级功能 💪。
代码标题
你可以通过在语言后面添加一个title键来为代码块添加标题(在它们之间留一个空格)。
```jsx title="/src/components/HelloCodeTitle.js"
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
```
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
语法高亮
代码块是由三个反引号包围的文本块。您可以查看此参考以了解MDX的规范。
```js
console.log('Every repo must come with a mascot.');
```
为你的代码块使用匹配的语言元字符串,Docusaurus 将自动进行语法高亮,由 Prism React Renderer 提供支持。
console.log('Every repo must come with a mascot.');
主题
默认情况下,我们使用的Prism 语法高亮主题是Palenight。你可以通过在docusaurus.config.js中的prism中传递theme字段作为themeConfig来将其更改为另一个主题。
例如,如果您更喜欢使用dracula高亮主题:
import {themes as prismThemes} from 'prism-react-renderer';
export default {
themeConfig: {
prism: {
theme: prismThemes.dracula,
},
},
};
因为Prism主题只是一个JS对象,如果你对默认主题不满意,你也可以编写自己的主题。Docusaurus增强了github和vsDark主题以提供更丰富的代码高亮,你可以查看我们在light和dark代码块主题上的实现。
支持的语言
默认情况下,Docusaurus 附带了一组常用语言。
一些流行的语言如Java、C#或PHP默认情况下未启用。
要为任何其他Prism支持的语言添加语法高亮,请在附加语言的数组中定义它。
每种额外的语言必须是一个有效的Prism组件名称。例如,Prism会将语言 cs映射到csharp,但只有prism-csharp.js作为组件存在,因此你需要使用additionalLanguages: ['csharp']。你可以查看node_modules/prismjs/components以找到所有可用的组件(语言)。
例如,如果你想为PowerShell语言添加高亮显示:
export default {
// ...
themeConfig: {
prism: {
additionalLanguages: ['powershell'],
},
// ...
},
};
添加additionalLanguages后,重新启动Docusaurus。
如果你想为Prism尚未支持的语言添加高亮显示,你可以使用prism-include-languages:
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic prism-include-languages
yarn swizzle @docusaurus/theme-classic prism-include-languages
pnpm run swizzle @docusaurus/theme-classic prism-include-languages
它将在你的src/theme文件夹中生成prism-include-languages.js。你可以通过编辑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-line、highlight-start和highlight-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';
}
```
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';
}
支持的注释语法:
| Style | Syntax |
|---|---|
| C-style | /* ... */ and // ... |
| JSX-style | {/* ... */} |
| Bash-style | # ... |
| HTML-style | <!-- ... --> |
我们将尽力根据语言推断使用哪种注释风格,并默认允许所有注释风格。如果有目前不支持的注释风格,我们愿意添加它们!欢迎提交拉取请求。请注意,不同的注释风格没有语义上的区别,只有它们的内容有区别。
您可以在src/css/custom.css中为高亮显示的代码行设置自己的背景颜色,这将更好地适应您选择的语法高亮主题。下面给出的颜色适用于默认的高亮主题(Palenight),因此如果您使用其他主题,您需要相应地调整颜色。
: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;
```
import React from 'react';
function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
return <div>Foo</div>;
}
export default MyComponent;
在可能的情况下,优先使用注释进行高亮显示。通过在代码中内联高亮,如果代码块变长,您不必手动计算行数。如果您添加/删除行,也不必调整行范围。
- ```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类名:
- docusaurus.config.js
- src/css/custom.css
- myDoc.md
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',
},
],
},
},
};
.code-block-error-line {
background-color: #ff000020;
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
border-left: 3px solid #ff000080;
}
In JavaScript, trying to access properties on `null` will error.
```js
const name = null;
// This will error
console.log(name.toUpperCase());
// Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase')
```
在 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(包含start和end),适用于由两个注释包围的整个块。
使用CSS来定位类已经可以做很多事情,但你可以通过swizzling来解锁这个功能的全部潜力。
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic CodeBlock/Line
yarn swizzle @docusaurus/theme-classic CodeBlock/Line
pnpm 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;
```
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
- Yarn
- pnpm
npm install --save @docusaurus/theme-live-codeblock
yarn add @docusaurus/theme-live-codeblock
pnpm add @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>
);
}
```
代码块将呈现为交互式编辑器。代码的更改将实时反映在结果面板上。
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> ); }
导入
无法直接从 react-live 代码编辑器导入组件,您必须预先定义可用的导入。
默认情况下,所有 React 导入都是可用的。如果您需要更多可用的导入,请自定义 react-live 范围:
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope -- --eject
yarn swizzle @docusaurus/theme-live-codeblock ReactLiveScope --eject
pnpm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope --eject
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 组件现在可以使用:
function MyPlayground(props) { return ( <div> <ButtonExample onClick={() => alert('hey!')}>Click me</ButtonExample> </div> ); }
命令式渲染 (noInline)
当你的代码跨越多个组件或变量时,应使用noInline选项以避免错误。
```jsx live noInline
const project = 'Docusaurus';
const Greeting = () => <p>Hello {project}!</p>;
render(<Greeting />);
```
与普通的交互式代码块不同,当使用noInline时,React Live 不会将你的代码包装在内联函数中进行渲染。
你需要在代码末尾显式调用render()来显示输出。
const project = "Docusaurus"; const Greeting = () => ( <p>Hello {project}!</p> ); render( <Greeting /> );
在代码块中使用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>
Input: 1 2 3 4 Output: "366300745"
MDX 与 JSX 行为一致:换行符,即使在 标签内,也会被转换为空格。你必须显式地写入换行符才能将其打印出来。
语法高亮仅适用于纯字符串。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>
你将得到以下内容:
- JavaScript
- Python
- Java
function helloWorld() {
console.log('Hello, world!');
}
def hello_world():
print("Hello, world!")
class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello, World");
}
}
如果您有多个这样的多语言代码标签,并且您想要在标签实例之间同步选择,请参考同步标签选择部分。
Docusaurus npm2yarn 备注插件
在npm和Yarn中显示CLI命令是一个非常常见的需求,例如:
- npm
- Yarn
- pnpm
npm install @docusaurus/remark-plugin-npm2yarn
yarn add @docusaurus/remark-plugin-npm2yarn
pnpm add @docusaurus/remark-plugin-npm2yarn
Docusaurus 提供了一个开箱即用的实用工具,使您无需每次使用 Tabs 组件。要启用此功能,首先按照上述方式安装 @docusaurus/remark-plugin-npm2yarn 包,然后在 docusaurus.config.js 中,在需要此功能的插件(文档、博客、页面等)中,将其注册到 remarkPlugins 选项中。(有关配置格式的更多详细信息,请参阅 文档配置)
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
```
配置
| Option | Type | Default | Description |
|---|---|---|---|
sync | boolean | false | Whether to sync the selected converter across all code blocks. |
converters | array | '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>
);
}
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
接受的属性是 language、title 和 showLineNumbers,就像你写 Markdown 代码块一样。
虽然不推荐,但你也可以传入一个metastring属性,如metastring='{1-2} title="/src/components/HelloCodeTitle.js" showLineNumbers',这是Markdown代码块在底层处理的方式。然而,我们建议你使用注释来高亮显示行。
如之前所述,语法高亮仅在子元素为简单字符串时应用。