Markdown: Полное руководство по блокам кода с синтаксисом, языками и примерами

Закодированные фрагменты, языковые теги, диффы и имена файлов.

Содержимое страницы

Ограниченные блоки кода содержат многострочный исходный код в Markdown. Токен после открывающего маркера — это языковой тег, и только рендерер решает, что именно этот тег выделяет цветом.

Это руководство является частью раздела Инструменты для документирования в 2026 году: Markdown, LaTeX, PDF и рабочие процессы печати.

пример вики-страницы с блоком кода

GitHub определяет языковой тег с помощью Linguist и ключевых слов в файле languages.yml. Hugo 0.164 передает тот же тег в Chroma. Тег, который Chroma не знает, все равно остается блоком кода, отображаемым как обычный текст. Заголовки, таблицы и другие типы блоков описаны в Шпаргалке по Markdown.

Обзор блоков кода в Markdown

В Markdown существует три способа разметки кода. Строки кода — это диапазон внутри абзаца. Блок с отступом и ограниченный блок (fenced block) — это оба варианта для многострочного кода, и только ограниченный блок несет языковой тег.

Тип Синтаксис Подсветка Примечания
Строки кода `код` Нет Один диапазон внутри предложения
Блок с отступом 4 пробела или 1 табуляция на каждой строке Нет Нет информационной строки, поэтому нет языкового тега
Ограниченный блок ```язык … ``` или ~~~ Да, если рендерер знает язык Формат, задокументированный GitHub

Блок с отступом не может содержать язык. CommonMark считает строку с отступом в четыре пробела кодом и не дает выделяющему цвету ничего, с чем можно было бы сопоставить. Именно поэтому для образцов, которые должны быть цветными, следует использовать ограничивающие маркеры.

Ограничивающий маркер — это строка из минимум трех обратных кавычек или трех тильд, затем код, а затем закрывающая строка из того же символа длиной не меньше открывающей. Закрывающая строка не имеет информационной строки. Чтобы показать ограничивающий маркер из трех обратных кавычек внутри образца, открывайте и закрывайте его четырьмя обратными кавычками. В документации GitHub по блокам кода рекомендуется оставлять пустую строку до и после маркера, чтобы исходный файл было легче читать; однако маркер будет распознан и без этой пустой строки.

Когда следующий исходный код хранится в Markdown:

```python
def hello():
    print("Hello, world!")
```

этот сайт Hugo отображает его так:

def hello():
    print("Hello, world!")

Строки кода используют то же правило обратных кавычек, но в меньшем масштабе. Для git status достаточно пары одиночных обратных кавычек. Если сам диапазон содержит обратную кавычку, используйте две кавычки с каждой стороны:

`` `код` ``

Подсветка синтаксиса Diff

Ограничивающий маркер с тегом diff — это способ показать изменения в текстовом виде. Лексер Chroma в Hugo принимает diff и udiff. GitHub выделяет цветом тот же идентификатор из своего списка языков.

- старая строка, которая будет удалена
+ новая строка, которая будет добавлена
  неизмененная строка

Строки, начинающиеся с -, получают стиль удаления, а строки, начинающиеся с +, — стиль добавления. Строка без префикса — это обычный текст в этом лексере. Окрашивается вся строка. Измененное слово посередине строки не помечается отдельно.

Идентификаторы языков

Первое слово в информационной строке — это язык. В документации Hugo это слово считается без учета регистра. Если у Chroma нет лексера для него, Hugo 0.164 выводит обычный <pre><code class="language-…"> без обертки для подсветки. Локальный рендер notalang сделал именно это. guessSyntax по умолчанию имеет значение false, и в документации Hugo указано, что только пять лексеров реализуют автоматическое определение, поэтому отсутствующий тег остается обычным текстом, а не угаданным языком.

HTML, созданный из этих маркеров, использует класс language-python и тот же токен. Именно этот класс конвертер должен сохранить, когда он превращает страницу с подсветкой обратно в Markdown, что является темой, рассмотренной в статье Конвертация HTML в Markdown с помощью Python.

Ниже приведены идентификаторы, перечисленные для этих языков в таблице Chroma Hugo. При рендере Hugo 0.164 cs, yml и markdown также были выделены цветом, даже если в опубликованной таблице напечатано csharp, yaml и md.

Язык Идентификаторы Hugo Chroma
Python python, py
JavaScript javascript, js
TypeScript typescript, ts, tsx
Java java
C c
C++ cpp, c++
C# csharp, c#
Go go, golang
Ruby ruby, rb
PHP php
Rust rust, rs
Swift swift
Kotlin kotlin
HTML html
CSS css
Shell bash, sh, shell, zsh
SQL sql
JSON json
YAML yaml
Markdown md, mkd
Perl perl
Lua lua
R r
Matlab matlab
Makefile make, makefile
Diff diff, udiff

Сайты GitHub Pages, которые по-прежнему используют Jekyll для подсветки, требуют, чтобы идентификатор был в нижнем регистре. Собственная документация GitHub отдельно указывает на это требование в отличие от рендеринга на github.com.

GitHub также рассматривает несколько маркеров как диаграммы, а не как подсвеченный исходный код: mermaid, geojson, topojson и stl. В таблице Chroma для Hugo нет записи mermaid. На сайте с Hugo маркер остается текстом исходного кода до тех пор, пока хук рендеринга, шорткод или скрипт не отрисует его. Настройка описана в Быстрый старт и шпаргалка по диаграммам Mermaid.

Указание имени файла

Ни в CommonMark, ни в документации GitHub по блокам кода нет механизма, превращающего информационную строку в имя файла. Варианты подсветки Hugo — это пары фигурных скобок, такие как {linenos=inline}. Они не включают поле имени файла.

Двоеточие после языка

Некоторые генераторы трактуют js:app.js как язык плюс имя:

```js:app.js
console.log("Hello, world!");
```

GitHub так не делает. Hugo 0.164 сохраняет весь токен как класс элемента кода (language-js:app.js) и не выводит имя файла. То, какие диалекты добавляют смысл после первого слова, — это сравнение, представленное в статье GFM vs CommonMark vs Pandoc Markdown.

Имя над маркером

Строка жирного кода над маркером показывает имя на GitHub, на этом сайте и в других рендерерах CommonMark:

**`app.js`**

```js
console.log("Hello, world!");
```

Заголовок работает так же:

#### `app.js`

```js
console.log("Hello, world!");
```

Имя внутри образца

Комментарий в первой строке переносится вместе с кодом, когда кто-то копирует блок:

```js
// app.js
console.log("Hello, world!");
```
Метод GitHub Hugo 0.164 Показывает имя при копировании
js:app.js в информационной строке Нет имени файла Нет имени файла; класс — весь токен Нет
Жирный код или заголовок над маркером Да Да Нет
Комментарий на первой строке Да Да Да

Экранирование обратных кавычек

Четыре обратные кавычки снаружи отображают маркер из трех кавычек. Это тот паттерн, который используется на страницах, документирующих Markdown:

````markdown
```python
# Этот маркер из трех обратных кавычек находится внутри маркера из четырех кавычек
print("hello")
```
````

Закрывающий маркер должен иметь тот же символ, что и открывающий, и быть не короче его. Более короткий закрывающий маркер завершает блок раньше времени, а остальная часть образца остается обычными абзацами.

Опции подсветки Hugo

В файле config.toml этого сайта нет блока [markup.highlight], поэтому действуют значения Hugo по умолчанию: блоки с маркерами подсвечиваются, стиль — monokai, стили записаны в стиле инлайна (noClasses true), а номера строк выключены. Hugo 0.164 по-прежнему выделяет цветом маркер, даже если он требует только языка, как в приведенном выше примере на Python.

Номера строк и выделенные строки — это опции в фигурных скобках после языка. Этот маркер запрашивает инлайн-номера и помечает вторую строку:

```python {linenos=inline hl_lines=[2]}
def hello():
    print("Hello, world!")
```
1def hello():
2    print("Hello, world!")

linenos принимает значения inline, table, true или false. hl_lines — это список номеров строк или диапазонов. linenostart устанавливает первый отображаемый номер. Эти же ключи нечувствительны к регистру. Шорткод highlight принимает их как одну строку в кавычках, и эта строка все еще отображала номера строк в Hugo 0.164:

{{< highlight python "linenos=true,hl_lines=2" >}}
def hello():
    print("Hello, world!")
{{< /highlight >}}

Чтобы перенести цвета в файл стилей, установите noClasses в false и сгенерируйте CSS. Hugo 0.164 принимает --mode и --modeSelector для этой команды:

hugo gen chromastyles --style=monokai --mode=light > assets/css/highlight.css
hugo gen chromastyles --style=monokai --mode=dark --modeSelector > assets/css/highlight-dark.css

--modeSelector ограничивает каждое правило верхнеуровневым классом, таким как .dark .chroma. Список флагов доступен через hugo gen chromastyles --help.

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

Проверьте сгенерированный элемент, прежде чем изменять образец. В этой версии Hugo известный язык — это div.highlight, у которого элемент кода имеет установленное data-lang с идентификатором. Неизвестный идентификатор — это голый pre и code с class="language-…", что и было получено для notalang.

Если имя app.js отсутствует, а класс равен language-js:app.js, значит, была использована форма с двоеточием. Переместите имя на строку выше маркера.

Если собственные маркеры из туториала отображаются как свободные абзацы, внешний маркер такой же длины, как внутренний. Удлините внешний маркер.

Если короткая команда «проглатывает» обратную кавычку в середине предложения, диапазону нужна пара обратных кавычек длиннее, чем символ, который он содержит.

Полезные ссылки

Подписаться

Получайте новые материалы про системы, инфраструктуру и AI engineering.