24 KiB
Диалект Markdown md2gost — полная спецификация
Справочник синтаксиса конвертера md2gost (Markdown → DOCX по ГОСТ 7.32-2017 и ТЗ РТУ МИРЭА). Всё, что здесь описано, извлечено из кода парсера, нумератора и проверки, а не из пользовательских инструкций.
Базовый парсер — Marko с расширением GFM. Всё, что не перечислено ниже как расширение, работает как обычный GitHub Flavored Markdown.
1. Расширения относительно обычного Markdown
| Конструкция | Смысл |
|---|---|
# *ЗАГОЛОВОК |
раздел без автоматической нумерации |
[TOC] |
точка сборки содержания |
%id Подпись |
метка и подпись следующего объекта |
 |
метка и подпись рисунка-файла |
@Тип:id |
перекрёстная ссылка с автоподстановкой номера |
[1]: описание |
запись списка источников |
[1], [2, 3], [2, c. 21-25] |
ссылка на источник в тексте |
^ / > в ячейке таблицы |
объединение ячеек |
```uml, ```mermaid, ```idef0, ```dfd, ```uml-<схема> |
диаграмма, отрисовываемая конвертером |
```title |
данные для автогенерации титульного листа |
+listing, +landscape в строке % |
флаги оформления объекта |
2. Заголовки
Синтаксис: от нуля до трёх ведущих пробелов, затем #…######, пробел, текст.
Регулярное выражение парсера: ^ {0,3}(#{1,6})((?=\s)[^\n]*?|[^\n\S]*)(?:(?<=\s)(?<!\\)#+)?[^\n\S]*$
Звёздочка первым непробельным символом текста заголовка делает раздел ненумерованным и удаляется из видимого текста:
# *ВВЕДЕНИЕ → раздел без номера
# 1 Анализ → нумерованный раздел
Пробел после # обязателен для корректной работы проверки (^(#{1,6})\s+(\*?)(.+)$).
Спецразделы
Распознаются по тексту заголовка, приведённому к прописным. Список из кода проверки:
СОДЕРЖАНИЕ, ВВЕДЕНИЕ, ЗАКЛЮЧЕНИЕ, СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ, СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ, ПРИЛОЖЕНИЕ, ПРИЛОЖЕНИЯ, а также любой заголовок, начинающийся на ПРИЛОЖЕН.
Для H1 из этого набора звёздочка обязательна — иначе ошибка heading.numbered_special.
Оформление в DOCX:
| Заголовок H1 | Выравнивание |
|---|---|
СОДЕРЖАНИЕ, СПИСОК ИСПОЛЬЗОВАННЫХ/ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ |
по центру |
ВВЕДЕНИЕ, ЗАКЛЮЧЕНИЕ, ПРИЛОЖЕНИЯ, нумерованные разделы |
слева с абзацным отступом |
СОДЕРЖАНИЕ исключается из собираемого оглавления.
Нумерация заголовков
| Режим CLI | Поведение |
|---|---|
--heading-numbering manual (по умолчанию) |
цифры остаются из markdown: # 1 …, ## 1.1 …; автонумерация Word отключена |
--heading-numbering auto |
ведущие цифры (^\d+(?:\.\d+)*\.?\s+) снимаются с текста заголовка, номера ставит многоуровневый список Word |
При manual номера пиши сам. При auto их можно не писать — но безопаснее всегда писать и запускать конвертер в manual.
[TOC]
Блочный элемент, шаблон \[(TOC)\]+. Только прописными — [toc] не распарсится (хотя проверка его увидит и замечания не выдаст). Ставится отдельной строкой, обычно сразу под # *СОДЕРЖАНИЕ.
Режимы сборки: --toc native (по умолчанию, поле Word, обновляется при открытии документа) и --toc manual (md2gost сам считает страницы).
3. Метки объектов: строка %
Шаблон: \%(\w+)( (.+))? — блочный элемент, прерывает открытый абзац.
id=\w+: буквы, цифры,_. Дефис, точка, пробел внутриidнедопустимы. Практическое правило:[A-Za-z][A-Za-z0-9_]*.- Подпись необязательна:
%eq1— валидная строка. - Метка применяется к следующему непустому блоку. Пустые строки между меткой и объектом допустимы.
- Если подряд идут две метки, к объекту привяжется вторая.
%в середине абзаца — обычный текст, не метка.
Флаги в строке подписи
Шаблоны: (?i)(?:^|\s)\+?listing\b и (?i)(?:^|\s)\+?landscape\b.
| Флаг | Действие |
|---|---|
+listing |
у диаграммы дополнительно выводится Листинг с её исходником (получает свой номер) |
+landscape |
объект размещается на альбомной странице |
Важные следствия из регулярных выражений:
- Плюс необязателен:
listingбез плюса тоже сработает как флаг. - Регистр не важен:
+Landscape=+landscape. - Флаги вырезаются из текста подписи в любом месте строки. Поэтому подпись не должна содержать самостоятельных слов
listingиlandscape— они исчезнут из подписи, а объект получит нежелательное оформление.
Метка рисунка-файла
Метка задаётся в title изображения:

Тот же шаблон %(\w+)( (.+))? и те же флаги.
Куда попадает подпись
| Объект | Положение подписи в DOCX |
|---|---|
| Рисунок и диаграмма | под объектом |
| Таблица | надпись над таблицей |
| Листинг | надпись над листингом |
| Формула | номер в скобках справа от формулы |
4. Перекрёстные ссылки @Тип:id
Шаблон: @(\w+):(\w+). Пробелы вокруг двоеточия недопустимы. Знаки препинания после ссылки не съедаются, поэтому @Рисунок:arch. и @Таблица:cmp, работают корректно.
Принимаемые типы (регистр не важен при разрешении ссылки):
| Тип | Синонимы |
|---|---|
Рисунок |
figure |
Таблица |
table |
Листинг |
listing |
Формула |
formula, equation |
В документе ссылка разворачивается в «Тип Номер», например Рисунок 1.1. Неизвестная метка даёт в тексте Рисунок? — визуальный маркер ошибки; проверка сообщает ref.dangling.
Каноническая форма — русские названия: @Рисунок:id, @Таблица:id, @Листинг:id, @Формула:id.
Соответствие меток и ссылок
Проверка сверяет два множества:
- метки — из
^%(\w+)и из title картинок; - ссылки — из
@[\wА-Яа-я]+:(\w+).
Метка без ссылки → предупреждение ref.unused. Ссылка без метки → ошибка ref.dangling. Правило простое: сколько меток, столько и адресатов ссылок.
5. Нумерация объектов
Области нумерации задаются профилем --type:
| Область | Профили | Вид номера |
|---|---|---|
section |
practice, coursework, vkr, APID_coursework |
1.1, 2.3; в приложении — Б.1 |
continuous |
PIS_custom |
1, 2, 3 на весь документ |
Счётчик раздела увеличивается только на нумерованных H1 (то есть на # 1 …, а не на # *ВВЕДЕНИЕ).
Номер получают все объекты кроме формул: формуле номер присваивается, только если в исходном тексте есть @Формула:id (или @Formula:id) с её меткой. Формула без ссылки остаётся без номера.
Диаграмма с флагом +listing получает два номера под одной меткой: номер Рисунка и номер Листинга. Ссылки @Рисунок:id и @Листинг:id разрешатся каждая в свой номер.
6. Таблицы
Синтаксис GFM: строка заголовков, строка-разделитель, строки данных. Выравнивание через :---, :---:, ---: поддерживается. Экранированный \| не считается границей столбца.
Объединение ячеек
| Маркер | Смысл |
|---|---|
^ или ^^ |
ячейка — продолжение ячейки сверху (rowspan) |
> или >> |
ячейка — продолжение ячейки слева (colspan) |
Маркер должен быть единственным содержимым ячейки после обрезки пробелов. Ограничения проверки: маркеры запрещены в строке заголовков (table.merge_header), > запрещён в первом столбце (table.merge_col).
%tab_req Требования к системе
| Категория | Требование |
|-----------|------------|
| Производительность | обработка 1000 заявок в час |
| ^ | время отклика не более 2 с |
| Надёжность | доступность 99,5 % |
Правила ТЗ
- Графа «№ п/п» запрещена (
table.nopp, шаблон№\s*п\s*/\s*п). - Таблицу из одной строки данных не оформляют таблицей.
- Таблицы и рисунки не размещают внутри списков.
Продолжение на следующей странице
DOCX не умеет сам подписывать «Продолжение Таблицы N». Режимы --table-continuation и --listing-continuation: word (по умолчанию; после сохранения Word COM режет по реальной пагинации), off, soft, legacy, caption. Режим word требует Windows, Microsoft Word и пакет pywin32.
7. Листинги
Любой fenced-блок с языком, который не является языком диаграммы, становится Листингом.
%code_volume Процедура расчёта объёма
```python
def volume(count: int, size: float) -> float:
return count * size
```
Подсветка синтаксиса включается ключом --syntax-highlighting (по умолчанию выключена).
Ловушка: автозамена внутри кода
Препроцессор применяет типографские правки ко всему тексту, исключая только блоки диаграмм. Блоки кода не защищены:
| В исходнике | В DOCX |
|---|---|
print("hello") |
print(«hello») |
x = a - b |
x = a — b |
Обход: одинарные кавычки в примерах кода и вычитание без пробелов (a-b). Ключ --emdash-to-hyphen меняет направление замены тире, но кавычки правит всегда.
8. Формулы
| Форма | Шаблон | Назначение |
|---|---|---|
| Выключная | \$\$([\S\s]*?)\$\$ |
отдельный блок, нумеруемая формула |
| Инлайновая | \$(.*?)\$ |
обозначения в тексте: $N$ |
%eq_volume
$$
V = N \times S
$$
где $N$ — число записей; $S$ — средний размер записи, байт.
Оценка по (@Формула:eq_volume) используется при выборе хранилища.
Номер присваивается только при наличии ссылки. Расшифровка обозначений начинается со слова «где» без двоеточия.
9. Диаграммы
Fenced-блок с языком диаграммы превращается в Рисунок; исходник отрисовывается конвертером.
Встроенные языки
| Оградка | Движок |
|---|---|
uml, plantuml |
PlantUML (java + plantuml.jar, иначе Kroki) |
mermaid, mmd |
локальный Mermaid (браузер / QuickJS), иначе Kroki |
idef0, uml-idef0 |
локальный рендер на Pillow, без Java и сети |
dfd, uml-dfd, data-flow-diagram, yourdon, uml-yourdon |
пакет data-flow-diagram + Graphviz, иначе Kroki |
Схемы из md2gost.schemes.json
Оградка uml-<id> или просто <id>, где <id> — идентификатор схемы (^[a-z][a-z0-9_]*$). Встроенные схемы:
| id | Что это | Оградка |
|---|---|---|
c4 |
C4 Container | ```uml-c4 / ```c4 |
c4context |
C4 System Context | ```uml-c4context |
c4component |
C4 Component | ```uml-c4component |
usecase |
UML Use Case | ```uml-usecase / ```usecase |
archimate |
ArchiMate 3.2 | ```uml-archimate / ```archimate |
В теле схемы пишутся только макросы: обёртку @startuml … @enduml и !include подставляет схема. В блоке ```uml наоборот — @startuml … @enduml обязательны.
Неизвестный uml-<id> даёт ошибку рендера: Схема диаграммы «<id>» не найдена.
Подробный синтаксис всех нотаций — в diagrams.md, ArchiMate — в archimate.md.
10. Источники
Запись списка
Шаблон строки: ^\[(\d+(?:\.\d+)?)\]:\s*(.+)$
Записи размещаются под заголовком, совпадающим с ^#\s*\*?\s*СПИСОК\s+ИСПОЛЬЗОВАНН?ЫХ\s+ИСТОЧНИКОВ\s*$ — то есть «СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ» или «СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ».
# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
[1]: Иванов И. И. Проектирование информационных систем: учебник. — М.: Инфра-М, 2023. — 320 с.
[2]: ГОСТ 7.32-2017. Отчёт о научно-исследовательской работе. — М.: Стандартинформ, 2018. — 32 с.
Препроцессор сам расставит пустые строки между записями, но безопаснее писать их сразу.
Для ВКР список делится подразделами ##; ключ записи получает вид [1.5] — номер раздела и номер внутри раздела.
Ссылка в тексте
Шаблон: \[(\d+(?:\.\d+)?(?:\s*,\s*\d+(?:\.\d+)?)*)(?:\s*,\s*[cс]\.\s*[\d\-–]+)?\]
| Форма | Пример |
|---|---|
| одиночная | [1], [1.5] |
| перечисление | [2, 3], [2,3] |
| с указанием страниц | [2, c. 21-25], [2.18, с. 21–25] — буква c латинская или русская |
В DOCX номер становится внутренней гиперссылкой на запись списка.
Сноски [^1] запрещены (footnote).
11. Приложения
# *ПРИЛОЖЕНИЯ
Приложение А — Листинг модуля обработки заявок
Приложение Б — Схема базы данных
## Приложение А Листинг модуля обработки заявок
## Приложение Б Схема базы данных
- Заголовок приложения распознаётся шаблоном
^ПРИЛОЖЕНИЕ\s+([А-ЯA-ZЁ])(?:\s+(.+))?$без учёта регистра. Оформляется как Heading 3 по центру с разрывом страницы; название — отдельной строкой под ним. - Допустимые буквы:
АБВГДЕЖИКЛМНПРСТУФХЦШЩЭЮЯ. Запрещённые:Ё З Й О Ч Ь Ы Ъ(ошибкаappendix.letter). - Если букву не указать или указать запрещённую, конвертер подставит следующую допустимую по порядку.
- При двух и более приложениях после
# *ПРИЛОЖЕНИЯнужен перечень обычным текстом, иначе предупреждениеappendix.toc. Если перечня нет, конвертер вставит его сам, но лучше писать явно. - Объекты внутри приложения нумеруются с буквой приложения:
Рисунок Б.1.
12. Блок ```title
Первый блок с оградкой title в файле вырезается до разбора markdown и используется для автогенерации титульного листа (только при --auto-title).
```title
number: 1
year: 2026
```
# *СОДЕРЖАНИЕ
[TOC]
Тело — плоские строки ключ: значение. Принимаемые ключи:
| Поле | Ключи |
|---|---|
| Институт | institute, институт, инститиут |
| Кафедра | department, кафедра |
| Дисциплина | discipline, дисциплина |
| Преподаватель | teacher, преподаватель, преподователь |
| Должность преподавателя | teacher_position, должность, должность преподавателя |
| Номер работы | number, номер, №, n — по умолчанию 1 |
| Год | year, год — по умолчанию текущий |
ФИО и группа студента из блока не читаются: они берутся из профиля приложения или ключей --student / --group.
Остальные академические поля можно держать в файле info_conv.yaml рядом с .md; значения из блока ```title сильнее.
13. Автоматические правки текста
Препроцессор применяет ко всему тексту, кроме блоков диаграмм:
| Правило | Было | Стало |
|---|---|---|
| Русские кавычки | "текст" |
«текст» |
| Тире вместо дефиса между словами | слово - слово |
слово — слово |
| Разделение записей списка источников | склеенные строки [n]: |
каждая записью-абзацем |
Кавычки не заменяются, если содержимое начинается с % (защита строк подписей).
Ключ --emdash-to-hyphen включает обратную замену: все — становятся -.
14. Прочее
| Конструкция | Поведение |
|---|---|
---, ***, ___ |
по умолчанию игнорируются; с ключом --hr-pagebreak дают разрыв страницы |
Обычные **жирный**, *курсив*, `код`, ссылки, списки |
работают как в GFM |
| HTML-блоки | не поддерживаются, вставляются как предупреждение в документ |
| Комментарии | синтаксиса комментариев нет |
Заголовок глубже ### |
парсится, но в оформлении ТЗ не предусмотрен |
| Дефис в обычном тексте | превращается в неразрывный дефис |
15. Полный минимальный пример
# *СОДЕРЖАНИЕ
[TOC]
# *ВВЕДЕНИЕ
Цель работы — спроектировать модуль учёта заявок.
# 1 Анализ предметной области
Обобщённая архитектура приведена на @Рисунок:fig_arch.

Сравнение подходов сведено в @Таблица:tab_cmp.
%tab_cmp Сравнение подходов к реализации
| Подход | Трудоёмкость | Гибкость |
|--------|--------------|----------|
| Монолит | низкая | низкая |
| Микросервисы | высокая | высокая |
Модульная структура описана в источнике [1].
# 2 Проектирование
Оценка объёма данных выполняется по (@Формула:eq_volume).
%eq_volume
$$
V = N \times S
$$
где $N$ — число записей; $S$ — средний размер записи, байт.
Реализация приведена в @Листинг:code_volume.
%code_volume Процедура расчёта объёма
```python
def volume(count: int, size: float) -> float:
return count * size
```
# *ЗАКЛЮЧЕНИЕ
Спроектирован модуль учёта заявок, оценён объём хранилища.
# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
[1]: Иванов И. И. Проектирование информационных систем: учебник. — М.: Инфра-М, 2023. — 320 с.