close

Блоки кода

Rspress V2 использует Shiki для подсветки синтаксиса на этапе компиляции, что обеспечивает лучшую производительность во время выполнения.

При использовании блоков кода на нескольких языках соответствующий язык автоматически определяется на этапе компиляции, а размер бандла во время выполнения не увеличивается. Список поддерживаемых языков программирования смотрите в списке языков, поддерживаемых Shiki.

Базовое использование

Вы можете использовать синтаксис ``` для создания блоков кода. Например:

```js
console.log('Привет, мир');
```

Отобразится так:

console.log('Привет, мир');

Заголовок блока кода

Вы можете добавить заголовок к блоку кода с помощью атрибута title="...".

```jsx title="src/components/HelloCodeBlockTitle.tsx"
const HelloCodeBlockTitle = (props) => {
  return <h1>Блок кода с заголовком</h1>;
};
```

Отобразится так:

src/components/HelloCodeBlockTitle.tsx
const HelloCodeBlockTitle = (props) => {
  return <h1>Блок кода с заголовком</h1>;
};

Блок кода из файла

Вы можете использовать атрибут file="./path/to/file" без написания содержимого блока кода — это позволит подгрузить содержимое из внешнего файла.

Относительные пути

Используйте относительные пути, начинающиеся с ./ или ../, чтобы ссылаться на файлы относительно текущего MDX-файла:

foo.mdx
_tsx-component.tsx
```tsx file="./_tsx-component.tsx"

```

Отобразится так:

import { useState } from 'react';

export default () => {
  const [count, setCount] = useState(0);
  return (
    <p>
      Это компонент из tsx{' '}
      <button onClick={() => setCount(count => count + 1)}>{count}</button>
    </p>
  );
};

Абсолютные пути с префиксом <root>/

Используйте префикс <root>/, чтобы ссылаться на файлы по абсолютному пути относительно корневой директории проекта. Это удобно, когда нужно обращаться к общим файлам кода из разных мест в документации:

```tsx file="<root>/src/components/Button.tsx"

```

Например, если корень вашего проекта — /project, то путь <root>/src/components/Button.tsx будет указывать на файл, расположенный по адресу /project/src/components/Button.tsx.

Совет

При использовании блоков кода из внешних файлов их часто комбинируют с соглашениями о маршрутах. Называйте такие файлы с подчёркиванием в начале — _.

Подсветка отдельных строк

Вы можете подсвечивать отдельные строки кода с помощью трансформеров Shiki и специального трансформера transformerNotationHighlight, а также комментариев вида // [!code highlight]:

Code
rspress.config.ts
```ts
console.log('Подсвечено'); // [!code highlight]
console.log('Не подсвечено');
// [!code highlight:2]
console.log('Подсвечено');
console.log('Подсвечено');
```

Отобразится так:

highlight.ts
console.log('Подсвечено'); 
console.log('Не подсвечено');
console.log('Подсвечено');
console.log('Подсвечено');

Подсветка строк через meta-информацию

Предупреждение

При использовании meta-информации для подсветки строк помните, что автоформаттеры и другие инструменты могут менять нумерацию строк. Для лучшей поддержки и удобства рекомендуется использовать подсветку через специальные комментарии.

Вы можете подсвечивать строки кода с помощью трансформера transformerCompatibleMetaHighlight из пакета @rspress/core/shiki-transformers и meta-информации в заголовке блока кода.

Code
rspress.config.ts
```ts {1,3-4}
console.log('Подсвечено');
console.log('Не подсвечено');
console.log('Подсвечено');
console.log('Подсвечено');
```

Отобразится так:

console.log('Подсвечено');
console.log('Не подсвечено');
console.log('Подсвечено');
console.log('Подсвечено');

Нумерация строк

Вы можете включить отображение номеров строк для отдельных блоков кода с помощью мета-атрибута lineNumbers:

```ts lineNumbers
function hello() {
  console.log('Для этого блока включена нумерация строк');
}
```

Отобразится так:

function hello() {
  console.log('Для этого блока включена нумерация строк');
}

Вы также можете включить нумерацию строк глобально, указав опцию showLineNumbers в конфигурации:

rspress.config.ts
export default {
  // ...
  markdown: {
    showLineNumbers: true,
  },
};

Когда опция showLineNumbers включена глобально, все блоки кода по умолчанию будут показывать нумерацию строк.

Перенос длинных строк

Вы можете включить перенос длинных строк в отдельных блоках кода с помощью мета-атрибута wrapCode:

```ts wrapCode
const longLine = 'Это очень длинная строка кода, которая будет переноситься по словам, когда указан мета-атрибут wrapCode';
```

Отобразится так:

const longLine = 'Это очень длинная строка кода, которая будет переноситься по словам, когда указан мета-атрибут wrapCode';

Вы также можете включить перенос длинных строк глобально, указав опцию defaultWrapCode в конфигурации:

rspress.config.ts
export default {
  // ...
  markdown: {
    defaultWrapCode: true,
  },
};

Когда опция defaultWrapCode включена глобально, все блоки кода по умолчанию будут выполнять перенос длинных строк.

Комбинирование мета-атрибутов

Вы можете одновременно использовать несколько мета-атрибутов:

```ts lineNumbers wrapCode title="example.ts"
const longLine =
  'Этот блок кода имеет нумерацию строк, перенос длинных строк и заголовок';
```

Отобразится так:

example.ts
const longLine =
  'Этот блок кода имеет нумерацию строк, перенос длинных строк и заголовок';

Блок кода с подсветкой различий

```diff
function test() {
- console.log('удалено');
+ console.log('добавлено');
  console.log('без изменений');
}
```

Отобразится так:

function test() {
- console.log('удалено');
+ console.log('добавлено');
  console.log('без изменений');
}

Трансформеры Shiki

Rspress V2 использует Shiki для подсветки кода на этапе компиляции, что даёт широкие возможности по кастомизации блоков кода.

Вы можете подключать собственные трансформеры Shiki через опцию markdown.shiki.transformers — это позволяет получать более богатые эффекты в блоках кода.

Помимо уже упомянутого выше transformerNotationHighlight, Rspress по умолчанию включает следующие трансформеры из пакета @shikijs/transformers:

transformerNotationDiff

Syntax
rspress.config.ts
```ts
console.log('удалено'); // [!code --]
console.log('добавлено'); // [!code ++]
console.log('без изменений');
```

Отобразится так:

console.log('удалено'); 
console.log('добавлено'); 
console.log('без изменений');

transformerNotationErrorLevel

Syntax
rspress.config.ts
```ts
console.log('Без ошибок и предупреждений');
console.error('Ошибка'); // [!code error]
console.warn('Предупреждение'); // [!code warning]
```

Отобразится так:

console.log('Без ошибок и предупреждений');
console.error('Ошибка'); 
console.warn('Предупреждение'); 

transformerNotationFocus

Syntax
rspress.config.ts
```ts
console.log('Без фокуса');
console.log('С фокусом'); // [!code focus]
console.log('Без фокуса');
```

Отобразится так:

console.log('Без фокуса');
console.log('С фокусом'); 
console.log('Без фокуса');

Twoslash

Twoslash — это формат разметки для кода на TypeScript, который позволяет создавать полностью автономные примеры кода, автоматически дополняя их информацией о типах и подсказками от компилятора TypeScript. Он широко используется на официальном сайте TypeScript.

Rspress предоставляет плагин @rspress/plugin-twoslash, который включает поддержку Twoslash в Rspress. Подробности — в документации @rspress/plugin-twoslash.

// @noErrorValidation
const str: string = 1;

Подсветка синтаксиса во время выполнения

Когда нужно динамически отображать блоки кода во время выполнения — например, в интерактивной документации или при подгрузке кода с сервера, — Rspress предоставляет компонент CodeBlockRuntime.

Пример использования:

foo.mdx
import { CodeBlockRuntime } from '@rspress/core/theme';
import { transformerNotationHighlight } from '@shikijs/transformers';

<CodeBlockRuntime
  lang="ts"
  title="highlight.ts"
  code={`console.log('Подсвечено'); // [!code highlight]
// [!code highlight:1]
console.log('Подсвечено');
console.log('Не подсвечено');`}
  shikiOptions={{
    transformers: [transformerNotationHighlight()],
  }}
/>
highlight.ts
console.log('Подсвечено'); // [!code highlight]
// [!code highlight:1]
console.log('Подсвечено');
console.log('Не подсвечено');
Предупреждение

Рекомендуется использовать CodeBlockRuntime только в случаях, когда это действительно необходимо, поскольку он увеличивает размер бандла во время выполнения и лишает возможности воспользоваться преимуществами подсветки синтаксиса на этапе компиляции.