コードブロック
ドキュメント内のコードブロックは、強力な機能を備えています 💪。
コードタイトル
言語の後に 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です。docusaurus.config.jsのthemeConfig
で、prism
にtheme
フィールドを渡すことで、別のテーマに変更できます。
たとえば、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スタイル | <!-- ... --> |
言語に基づいて、使用するコメントスタイルのセットを推測し、デフォルトですべてのコメントスタイルを許可するように最善を尽くします。現在サポートされていないコメントスタイルがある場合は、追加を検討します。プルリクエストは大歓迎です。異なるコメントスタイルは意味的な違いはなく、その内容だけが重要であることに注意してください。
`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());
// Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase')
メタ文字列で数値範囲(`{1,3-4}`構文)を使用する場合、Docusaurusは**最初の`magicComments`エントリ**のクラス名を適用します。これはデフォルトでは`theme-code-block-highlighted-line`ですが、`magicComments`設定を変更して最初のエントリとして別のエントリを使用すると、メタ文字列範囲の意味も変更されます。
デフォルトの行強調表示コメントは、magicComments: []
で無効にできます。マジックコメントの設定がない場合、Docusaurus はメタ文字列範囲を含むコードブロックに遭遇するとエラーを発生させます。これは、適用するクラス名が存在しないためです。強調表示クラス名は、結局のところマジックコメントのエントリに過ぎません。
すべてのマジックコメントエントリには、3 つのキーが含まれます。className
(必須)、次の行に直接適用される line
、または 2 つのコメントで囲まれたブロック全体に適用される 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 の現在の制限 です。MDX パーサーが Markdown 構文を JSX ではなく Markdown 構文として認識するには、Markdown 構文の周囲に空行を残す必要があります。
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` で、この機能が必要なプラグイン(doc、blog、pages など)について、`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 | boolean | false | すべてのコードブロックで選択したコンバーターを同期するかどうか。 |
converters | array | '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>;
}
受け入れられる props は、Markdown コードブロックを記述するのと同じ方法で、language
、title
、showLineNumbers
です。
推奨されませんが、metastring='{1-2} title="/src/components/HelloCodeTitle.js" showLineNumbers'
のように `metastring` prop を渡すこともできます。これは、Markdown コードブロックが内部で処理される方法です。ただし、行の強調表示にはコメントを使用する ことをお勧めします。
前述のとおり、構文の強調表示は、子が単純な文字列の場合にのみ適用されます。