Files
md_to_gost/AIV2/context/syntax.md
T
Igor20264 5fb5010571
Example document / build (push) Has been cancelled
Python application / build (push) Has been cancelled
v0.5.4
NewPromt
- small fix
2026-09-19 10:53:19 +03:00

460 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Диалект Markdown md2gost — полная спецификация
Справочник синтаксиса конвертера md2gost (Markdown → DOCX по ГОСТ 7.32-2017 и ТЗ РТУ МИРЭА). Всё, что здесь описано, извлечено из кода парсера, нумератора и проверки, а не из пользовательских инструкций.
Базовый парсер — Marko с расширением GFM. Всё, что не перечислено ниже как расширение, работает как обычный GitHub Flavored Markdown.
---
## 1. Расширения относительно обычного Markdown
| Конструкция | Смысл |
|-------------|-------|
| `# *ЗАГОЛОВОК` | раздел без автоматической нумерации |
| `[TOC]` | точка сборки содержания |
| `%id Подпись` | метка и подпись следующего объекта |
| `![alt](path "%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]*$`
**Звёздочка** первым непробельным символом текста заголовка делает раздел ненумерованным и удаляется из видимого текста:
```markdown
# *ВВЕДЕНИЕ → раздел без номера
# 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` | объект размещается на альбомной странице |
Важные следствия из регулярных выражений:
1. Плюс необязателен: `listing` без плюса тоже сработает как флаг.
2. Регистр не важен: `+Landscape` = `+landscape`.
3. Флаги вырезаются из текста подписи в любом месте строки. **Поэтому подпись не должна содержать самостоятельных слов `listing` и `landscape`** — они исчезнут из подписи, а объект получит нежелательное оформление.
### Метка рисунка-файла
Метка задаётся в title изображения:
```markdown
![Архитектура системы](images/arch.png "%fig_arch Архитектура информационной системы")
```
Тот же шаблон `%(\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`).
```markdown
%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-блок с языком, который **не** является языком диаграммы, становится Листингом.
~~~markdown
%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$` |
```markdown
%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*$` — то есть «СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ» или «СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ».
```markdown
# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
[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], [3]` |
| с указанием страниц | `[2, c. 21-25]`, `[2.18, с. 21–25]` — буква `c` латинская или русская |
В DOCX номер становится внутренней гиперссылкой на запись списка.
Сноски `[^1]` запрещены (`footnote`).
---
## 11. Приложения
```markdown
# *ПРИЛОЖЕНИЯ
Приложение А — Листинг модуля обработки заявок
Приложение Б — Схема базы данных
## Приложение А Листинг модуля обработки заявок
## Приложение Б Схема базы данных
```
- Заголовок приложения распознаётся шаблоном `^ПРИЛОЖЕНИЕ\s+([А-ЯA-ZЁ])(?:\s+(.+))?$` без учёта регистра. Оформляется как Heading 3 по центру с разрывом страницы; название — отдельной строкой под ним.
- Допустимые буквы: `АБВГДЕЖИКЛМНПРСТУФХЦШЩЭЮЯ`. Запрещённые: `Ё З Й О Ч Ь Ы Ъ` (ошибка `appendix.letter`).
- Если букву не указать или указать запрещённую, конвертер подставит следующую допустимую по порядку.
- При двух и более приложениях после `# *ПРИЛОЖЕНИЯ` нужен перечень обычным текстом, иначе предупреждение `appendix.toc`. Если перечня нет, конвертер вставит его сам, но лучше писать явно.
- Объекты внутри приложения нумеруются с буквой приложения: `Рисунок Б.1`.
---
## 12. Блок ` ```title `
Первый блок с оградкой `title` в файле вырезается до разбора markdown и используется для автогенерации титульного листа (только при `--auto-title`).
````markdown
```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. Полный минимальный пример
~~~markdown
# *СОДЕРЖАНИЕ
[TOC]
# *ВВЕДЕНИЕ
Цель работы — спроектировать модуль учёта заявок.
# 1 Анализ предметной области
Обобщённая архитектура приведена на @Рисунок:fig_arch.
![Архитектура](images/arch.png "%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 с.
~~~