程式區塊
文件中程式區塊超強大💪。
程式標題
您可以在程式區塊後加上一個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>;
}
語法高亮
程式區塊是由 3 個反引號字串包覆的文字區塊。您可以在 此參考 中查看 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。您可以透過傳入 docasaurus.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
佈景,以提供更豐富的醒目提示,您可以查看我們的實作中 淺色 和 深色 程式碼區塊佈景。
支援的語言
預設情況下,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';
}
支援的註解語法
樣式 | 語法 |
---|---|
C 樣式 | /* ... */ 和 // ... |
JSX 樣式 | {/* ... */} |
Bash 樣式 | # ... |
HTML 樣式 | <!-- ... --> |
我們會盡力根據語言來推論要使用哪一組註解樣式,並預設允許所有註解樣式。如果有目前不支援的註解樣式,我們很樂意新增!歡迎提交 Pull Request。請注意,不同的註解樣式沒有語義差異,只有其內容不同。
您可以為突顯的程式碼行在 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 class。
使用元資料字串突顯
您也可以在語言元資料字串中指定突顯的程式碼列範圍 (語言後面留一個空格)。要突顯多行,以逗號分隔行號或使用範圍語法選擇一行區塊。此功能使用 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';
}
```
以下是我們將介紹魔法註解系統如何擴充以定義自訂指令及其功能。如果不存在標記 metastring,系統才會分析魔法註解。
自訂魔法註解
// 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());
// Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase')
如果您在 metastring 中使用數字範圍({1,3-4}
語法),Docusaurus 會套用**第一個 magicComments
條目的**類別名稱。預設情況下為 theme-code-block-highlighted-line
,但如果您變更 magicComments
設定檔,並將不同的項目設為第一個項目,則 metastring 範圍的意義也會跟著變更。
您可以使用 magicComments: []
來停用預設的行標記註解。如果沒有魔法註解設定檔,但 Docusaurus 遇到包含 metastring 範圍的程式碼區塊,會出錯,因為沒有類別名稱可以套用——畢竟,標記類別名稱只是一個魔法註解項目。
每個魔法註解項目都會包含三個鍵:className
(必要)、line
,套用至直接的下一行,或 block
(包含 start
和 end
),套用至由兩個註解括住的整個區塊。
使用 CSS 來鎖定類別本身已經能夠完成很多事,但您可以透過動態化解鎖此功能的全部潛力。
- 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>
標籤、<code>
標籤或 <CodeBlock>
元件。
<pre>
<b>Input: </b>1 2 3 4{'\n'}
<b>Output: </b>"366300745"{'\n'}
</pre>
Input: 1 2 3 4 Output: "366300745"
MDX 適用於 JSX 行為:換行字元,即使在 <pre>
內部,也會轉換為空格。你必須明確地寫入換行字元才能列印出來。
語法突顯只適用於一般字串。Docusaurus 不會嘗試剖析包含 JSX 子項的程式碼區塊內容。
多語言支援程式碼區塊
透過 MDX,你可以輕鬆地於文件內建立互動元件,例如,以標籤元件在多種程式語言中顯示程式碼並在它們之間切換。
我們不是為多語言支援程式碼區塊實作一個專屬元件,而是在經典佈景主題中實作一個通用的 <Tabs>
元件,讓你也可以用於其他非程式碼情境。
以下範例說明你如何於文件中使用多語言程式碼標籤。請注意,每一種程式語言區塊上下方的空白行是故意的。這是 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 remark 外掛程式
以 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
```
設定
選項 | 類型 | 預設值 | 說明 |
---|---|---|---|
sync | 布林值 | false | 是否在所有程式碼區塊同步所選的轉換器。 |
converters | 陣列 | 'yarn' 、'pnpm' | 使用的轉換器清單。轉換器的順序很重要,因為第一個轉換器將會作為預設選擇。 |
在 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 程式碼區塊在幕後處理的方式。但是,我們建議您使用註解來突顯行。
如同先前所述,只有當內容是一個簡單的字串時,才會套用語法突顯。