mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
460 lines
12 KiB
Text
460 lines
12 KiB
Text
---
|
|
id: code-blocks
|
|
title: Code blocks
|
|
description: Handling code blocks in Docusaurus Markdown
|
|
slug: /markdown-features/code-blocks
|
|
---
|
|
|
|
Code blocks within documentation are super-powered 💪.
|
|
|
|
## Code title {#code-title}
|
|
|
|
You can add a title to the code block by adding `title` key after the language (leave a space between them).
|
|
|
|
```jsx title="/src/components/HelloCodeTitle.js"
|
|
function HelloCodeTitle(props) {
|
|
return <h1>Hello, {props.name}</h1>;
|
|
}
|
|
```
|
|
|
|
```jsx title="/src/components/HelloCodeTitle.js"
|
|
function HelloCodeTitle(props) {
|
|
return <h1>Hello, {props.name}</h1>;
|
|
}
|
|
```
|
|
|
|
## Syntax highlighting {#syntax-highlighting}
|
|
|
|
Code blocks are text blocks wrapped around by strings of 3 backticks. You may check out [this reference](https://github.com/mdx-js/specification) for specifications of MDX.
|
|
|
|
```jsx
|
|
console.log('Every repo must come with a mascot.');
|
|
```
|
|
|
|
<!-- TODO: We need to allow users to pick syntax highlighting themes (maybe other than swizzling) -->
|
|
|
|
Use the matching language meta string for your code block, and Docusaurus will pick up syntax highlighting automatically, powered by [Prism React Renderer](https://github.com/FormidableLabs/prism-react-renderer).
|
|
|
|
```jsx
|
|
console.log('Every repo must come with a mascot.');
|
|
```
|
|
|
|
### Theming {#theming}
|
|
|
|
By default, the Prism [syntax highlighting theme](https://github.com/FormidableLabs/prism-react-renderer#theming) we use is [Palenight](https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/themes/palenight.js). You can change this to another theme by passing `theme` field in `prism` as `themeConfig` in your docusaurus.config.js.
|
|
|
|
For example, if you prefer to use the `dracula` highlighting theme:
|
|
|
|
```js {4} title="docusaurus.config.js"
|
|
module.exports = {
|
|
themeConfig: {
|
|
prism: {
|
|
theme: require('prism-react-renderer/themes/dracula'),
|
|
},
|
|
},
|
|
};
|
|
```
|
|
|
|
### Supported Languages {#supported-languages}
|
|
|
|
By default, Docusaurus comes with a subset of [commonly used languages](https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/vendor/prism/includeLangs.js).
|
|
|
|
:::caution
|
|
|
|
Some popular languages like Java, C#, or PHP are not enabled by default.
|
|
|
|
:::
|
|
|
|
To add syntax highlighting for any of the other [Prism supported languages](https://prismjs.com/#supported-languages), define it in an array of additional languages.
|
|
|
|
For example, if you want to add highlighting for the `powershell` language:
|
|
|
|
```js {5} title="docusaurus.config.js"
|
|
module.exports = {
|
|
// ...
|
|
themeConfig: {
|
|
prism: {
|
|
additionalLanguages: ['powershell'],
|
|
},
|
|
// ...
|
|
},
|
|
};
|
|
```
|
|
|
|
After adding `additionalLanguages`, restart Docusaurus.
|
|
|
|
If you want to add highlighting for languages not yet supported by Prism, you can swizzle `prism-include-languages`:
|
|
|
|
```bash npm2yarn
|
|
npm run swizzle @docusaurus/theme-classic prism-include-languages
|
|
```
|
|
|
|
It will produce `prism-include-languages.js` in your `src/theme` folder. You can add highlighting support for custom languages by editing `prism-include-languages.js`:
|
|
|
|
```js {8} title="src/theme/prism-include-languages.js"
|
|
const prismIncludeLanguages = (Prism) => {
|
|
// ...
|
|
|
|
additionalLanguages.forEach((lang) => {
|
|
require(`prismjs/components/prism-${lang}`); // eslint-disable-line
|
|
});
|
|
|
|
require('/path/to/your/prism-language-definition');
|
|
|
|
// ...
|
|
};
|
|
```
|
|
|
|
You can refer to [Prism's official language definitions](https://github.com/PrismJS/prism/tree/master/components) when you are writing your own language definitions.
|
|
|
|
## Line highlighting {#line-highlighting}
|
|
|
|
You can bring emphasis to certain lines of code by specifying line ranges after the language meta string (leave a space after the language).
|
|
|
|
```jsx {3}
|
|
function HighlightSomeText(highlight) {
|
|
if (highlight) {
|
|
return 'This text is highlighted!';
|
|
}
|
|
|
|
return 'Nothing highlighted';
|
|
}
|
|
```
|
|
|
|
```jsx {3}
|
|
function HighlightSomeText(highlight) {
|
|
if (highlight) {
|
|
return 'This text is highlighted!';
|
|
}
|
|
|
|
return 'Nothing highlighted';
|
|
}
|
|
```
|
|
|
|
To accomplish this, Docusaurus adds the `docusaurus-highlight-code-line` class to the highlighted lines. You will need to define your own styling for this CSS, possibly in your `src/css/custom.css` with a custom background color which is dependent on your selected syntax highlighting theme. The color given below works for the default highlighting theme (Palenight), so if you are using another theme, you will have to tweak the color accordingly.
|
|
|
|
```css title="/src/css/custom.css"
|
|
.docusaurus-highlight-code-line {
|
|
background-color: rgb(72, 77, 91);
|
|
display: block;
|
|
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
|
padding: 0 var(--ifm-pre-padding);
|
|
}
|
|
|
|
/* If you have a different syntax highlighting theme for dark mode. */
|
|
html[data-theme='dark'] .docusaurus-highlight-code-line {
|
|
/* Color which works with dark mode syntax highlighting theme */
|
|
background-color: rgb(100, 100, 100);
|
|
}
|
|
```
|
|
|
|
### Multiple line highlighting {#multiple-line-highlighting}
|
|
|
|
To highlight multiple lines, separate the line numbers by commas or use the range syntax to select a chunk of lines. This feature uses the `parse-number-range` library and you can find [more syntax](https://www.npmjs.com/package/parse-numeric-range) on their project details.
|
|
|
|
```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;
|
|
```
|
|
|
|
```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;
|
|
```
|
|
|
|
### Highlighting with comments {#highlighting-with-comments}
|
|
|
|
You can also use comments with `highlight-next-line`, `highlight-start`, and `highlight-end` to select which lines are highlighted.
|
|
|
|
```jsx
|
|
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';
|
|
}
|
|
```
|
|
|
|
```jsx
|
|
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';
|
|
}
|
|
```
|
|
|
|
Supported commenting syntax:
|
|
|
|
| Language | Syntax |
|
|
| ---------- | ------------------------ |
|
|
| JavaScript | `/* ... */` and `// ...` |
|
|
| JSX | `{/* ... */}` |
|
|
| Python | `# ...` |
|
|
| HTML | `<!-- ... -->` |
|
|
|
|
If there's a syntax that is not currently supported, we are open to adding them! Pull requests welcome.
|
|
|
|
## Interactive code editor {#interactive-code-editor}
|
|
|
|
(Powered by [React Live](https://github.com/FormidableLabs/react-live))
|
|
|
|
You can create an interactive coding editor with the `@docusaurus/theme-live-codeblock` plugin.
|
|
|
|
First, add the plugin to your package.
|
|
|
|
```bash npm2yarn
|
|
npm install --save @docusaurus/theme-live-codeblock
|
|
```
|
|
|
|
You will also need to add the plugin to your `docusaurus.config.js`.
|
|
|
|
```js {3}
|
|
module.exports = {
|
|
// ...
|
|
themes: ['@docusaurus/theme-live-codeblock'],
|
|
// ...
|
|
};
|
|
```
|
|
|
|
To use the plugin, create a code block with `live` attached to the language meta string.
|
|
|
|
```jsx live
|
|
function Clock(props) {
|
|
const [date, setDate] = useState(new Date());
|
|
useEffect(() => {
|
|
var timerID = setInterval(() => tick(), 1000);
|
|
|
|
return function cleanup() {
|
|
clearInterval(timerID);
|
|
};
|
|
});
|
|
|
|
function tick() {
|
|
setDate(new Date());
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<h2>It is {date.toLocaleTimeString()}.</h2>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
The code block will be rendered as an interactive editor. Changes to the code will reflect on the result panel live.
|
|
|
|
```jsx live
|
|
function Clock(props) {
|
|
const [date, setDate] = useState(new Date());
|
|
useEffect(() => {
|
|
var timerID = setInterval(() => tick(), 1000);
|
|
|
|
return function cleanup() {
|
|
clearInterval(timerID);
|
|
};
|
|
});
|
|
|
|
function tick() {
|
|
setDate(new Date());
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<h2>It is {date.toLocaleTimeString()}.</h2>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Imports {#imports}
|
|
|
|
:::caution react-live and imports
|
|
|
|
It is not possible to import components directly from the react-live code editor, you have to define available imports upfront.
|
|
|
|
:::
|
|
|
|
By default, all React imports are available. If you need more imports available, swizzle the react-live scope:
|
|
|
|
```bash npm2yarn
|
|
npm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope
|
|
```
|
|
|
|
```jsx {3-15,21} title="src/theme/ReactLiveScope/index.js"
|
|
import React from 'react';
|
|
|
|
const ButtonExample = (props) => (
|
|
<button
|
|
{...props}
|
|
style={{
|
|
backgroundColor: 'white',
|
|
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;
|
|
```
|
|
|
|
The `ButtonExample` component is now available to use:
|
|
|
|
```jsx live
|
|
function MyPlayground(props) {
|
|
return (
|
|
<div>
|
|
<ButtonExample onClick={() => alert('hey!')}>Click me</ButtonExample>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
## Multi-language support code blocks {#multi-language-support-code-blocks}
|
|
|
|
With MDX, you can easily create interactive components within your documentation, for example, to display code in multiple programming languages and switching between them using a tabs component.
|
|
|
|
Instead of implementing a dedicated component for multi-language support code blocks, we've implemented a generic Tabs component in the classic theme so that you can use it for other non-code scenarios as well.
|
|
|
|
The following example is how you can have multi-language code tabs in your docs. Note that the empty lines above and below each language block is **intentional**. This is a current limitation of MDX, you have to leave empty lines around Markdown syntax for the MDX parser to know that it's Markdown syntax and not JSX.
|
|
|
|
````jsx
|
|
import Tabs from '@theme/Tabs';
|
|
import TabItem from '@theme/TabItem';
|
|
|
|
<Tabs
|
|
defaultValue="js"
|
|
values={[
|
|
{ label: 'JavaScript', value: 'js', },
|
|
{ label: 'Python', value: 'py', },
|
|
{ label: 'Java', value: 'java', },
|
|
]
|
|
}>
|
|
<TabItem value="js">
|
|
|
|
```js
|
|
function helloWorld() {
|
|
console.log('Hello, world!');
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="py">
|
|
|
|
```py
|
|
def hello_world():
|
|
print 'Hello, world!'
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="java">
|
|
|
|
```java
|
|
class HelloWorld {
|
|
public static void main(String args[]) {
|
|
System.out.println("Hello, World");
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
````
|
|
|
|
And you will get the following:
|
|
|
|
````mdx-code-block
|
|
<Tabs
|
|
defaultValue="js"
|
|
values={[
|
|
{ label: 'JavaScript', value: 'js', },
|
|
{ label: 'Python', value: 'py', },
|
|
{ label: 'Java', value: 'java', },
|
|
]
|
|
}>
|
|
<TabItem value="js">
|
|
|
|
```js
|
|
function helloWorld() {
|
|
console.log('Hello, world!');
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="py">
|
|
|
|
```py
|
|
def hello_world():
|
|
print 'Hello, world!'
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="java">
|
|
|
|
```java
|
|
class HelloWorld {
|
|
public static void main(String args[]) {
|
|
System.out.println("Hello, World");
|
|
}
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
````
|
|
|
|
You may want to implement your own `<MultiLanguageCode />` abstraction if you find the above approach too verbose. We might just implement one in future for convenience.
|
|
|
|
If you have multiple of these multi-language code tabs, and you want to sync the selection across the tab instances, refer to the [Syncing tab choices section](markdown-features-tabs.mdx#syncing-tab-choices).
|