Подсветка синтаксиса
Для подсветки синтаксиса Nextra использует Shiki (opens in a new tab). Это удобно для восприятия кода пользователем. Например, если в Markdown-файле написать:
```js
console.log('hello, world')
```
то результат будет выглядеть вот так:
console.log('hello, world')
Возможности
Подсветка внутри текста
Для выделения кода внутри текста допустимо использовать {:}
.
Например, чтобы в этой строке подсветить let x = 1
,
в Markdown-файле мы написали:
Например, чтобы в этой строке подсветить `let x = 1{:jsx}`, в Markdown-файле мы написали:
Подсветка строк
Для того, чтобы подсветить определенные строки, используйте атрибут {}
.
Внутри фигурных скобок укажите номера или диапазон строк, которые нужно выделить:
```js {1,4-5}
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
```
В результате получится такое выделение:
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
Подстветка слов
Для того, чтобы в блоке с кодом выделить определенные слова, используйте //
:
```js /useState/
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
```
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
Также вы можете выделить только часть вхождений слов. Для этого добавьте номера вхождений или их диапазон: /str/1
, or multiple: /str/1-3
, /str/1,3
.
Кнопка "Скопировать код"
Если в блок кода добавить атрибут copy
, то при наведении мышкой на код справа будет появляться кнопка "Скопировать код":
```js copy
console.log('hello, world')
```
Попробуйте навести мышкой на этот блок кода:
console.log('hello, world')
Эту возможность вы можете установить на глобальном уровне. Для этого в конфигурационном файле Nextra (next.config.js
) укажите defaultShowCopyCode: true
. А чтобы затем отключить эту фичу в конкретном блоке с кодом, примените атрибут copy=false
.
Нумерация строк
Атрибут showLineNumbers
позволяет отобразить в блоке с кодом нумерацию строк:
```js showLineNumbers
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
```
Вот результат:
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
Имена файлов и заголовки
В блок кода можно добавить имена файлов и заголовки. Для этого используйте атрибут filename
:
```js filename="example.js"
console.log('hello, world')
```
Вот результат:
console.log('hello, world')
ANSI подсветка
Управляющие последовательности ANSI (англ. ANSI escape codes (opens in a new tab)) можно выделить атрибутом ansi
:
```ansi
[0m [0;32m✓[0m [0;2msrc/[0mindex[0;2m.test.ts (1)[0m
[0;2m Test Files [0m [0;1;32m1 passed[0;98m (1)[0m
[0;2m Tests [0m [0;1;32m1 passed[0;98m (1)[0m
[0;2m Start at [0m 23:32:41
[0;2m Duration [0m 11ms
[42;1;39;0m PASS [0;32m Waiting for file changes...[0m
[0;2mpress [0;1mh[0;2m to show help, press [0;1mq[0;2m to quit
```
Результат:
✓ src/index.test.ts (1)
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 23:32:41
Duration 11ms
PASS Waiting for file changes...
press h to show help, press q to quit
Поддержка языков
В этом списке (opens in a new tab) перечислены все поддерживаемые языки.
Кастомизация темы
Nextra использует CSS переменные для определения цвета токенов. Вы можете установить глобальный CSS (global CSS (opens in a new tab)), чтобы кастомизировать их под светлую/темную темы. Например, по умолчанию применяются следующие токены. Вы можете переопределить любой из них:
:root {
--shiki-color-text: #414141;
--shiki-color-background: transparent;
--shiki-token-constant: #1976d2;
--shiki-token-string: #22863a;
--shiki-token-comment: #aaa;
--shiki-token-keyword: #d32f2f;
--shiki-token-parameter: #ff9800;
--shiki-token-function: #6f42c1;
--shiki-token-string-expression: #22863a;
--shiki-token-punctuation: #212121;
--shiki-token-link: #22863a;
}
.dark {
--shiki-color-text: #d1d1d1;
--shiki-token-constant: #79b8ff;
--shiki-token-string: #ffab70;
--shiki-token-comment: #6b737c;
--shiki-token-keyword: #f97583;
--shiki-token-parameter: #ff9800;
--shiki-token-function: #b392f0;
--shiki-token-string-expression: #4bb74a;
--shiki-token-punctuation: #bbb;
--shiki-token-link: #ffab70;
}
Блок кода с динамическим контентом
Поскольку подсветка синтаксиса выполняется во время сборки, вы не можете использовать динамический контент в своих блоках кода. Однако MDX предоставляет обходной путь с помощью клиентского JS. Вот пример:
function hello () {
const x = 2 + 3
console.log(1)
}
Это решение имеет ограничение. Оно заключается в том, что обновленный контент не будет выделен повторно. Например, если мы изменим число на 1 + 1, оно будет подсвечено неправильно.
Посмотрите этот код (opens in a new tab), чтобы понять, как это работает.
Отключение подсветки синтаксиса
Вы можете отключить предустановленную подстветку синтаксиса и установить свою собственную. Для этого на глобальном уровне в конфигурационном файле Nextra (next.config.js
) пропишите атрибут: codeHighlight: false
.
Option | Type | Description |
---|---|---|
codeHighlight | boolean | Enable or disable syntax highlighting. Defaults to 'true'. |
Пользовательская грамматика
Shiki поддерживает VSCode TextMate Grammar (opens in a new tab) для подсветки синтаксиса с пользовательской грамматикой языка.
Вы можете настроить грамматику, переопределив параметры функции getHighlighter
в mdxOptions.rehypePrettyCodeOptions
. Это делается в конфигурационном файле Nextra (next.config.js
):
import { BUNDLED_LANGUAGES } from 'shiki'
nextra({
// ... other options
mdxOptions: {
rehypePrettyCodeOptions: {
getHighlighter: options =>
getHighlighter({
...options,
langs: [
...BUNDLED_LANGUAGES,
// настройки грамматики (custom grammar options). Как их переопределить смотрите в документации по Shiki.
{
id: 'my-lang',
scopeName: 'source.my-lang',
aliases: ['mylang'], // Наряду с идентификатором, псевдонимы будут включены в список разрешенных имен, которые вы можете использовать при написании Markdown.
path: '../../public/syntax/grammar.tmLanguage.json'
}
]
})
}
}
})
Пользовательская тема
С помощью mdxOptions.rehypePrettyCodeOptions
вы также можете перенастроить пользовательскую тему вместо CSS переменных (CSS Variables):
nextra({
// ... other options
mdxOptions: {
rehypePrettyCodeOptions: {
// VSCode тема или встроенная тема Shiki. Подробности смотрите в документации по Shiki
theme: JSON.parse(
readFileSync('./public/syntax/arctis_light.json', 'utf8')
)
}
}
})
Несколько тем
В настоящее время Nextra не поддерживает одновременное использование нескольких тем. Причина этого в том, что Shiki отображает несколько блоков кода для каждой темы и помечает их атрибутом data-theme
, например: data-theme="dark"
.
Тем не менее в будущем такая возможность будет реализована. Вы сможете отслеживать эти изменения в shikiji (newly fork of Shiki) https://github.com/antfu/shikiji#multiple-themes (opens in a new tab), который уже поддерживает использование нескольких тем без рендеринга нескольких блоков кода.