v0.5.5
Example document / build (push) Has been cancelled
Python application / build (push) Has been cancelled

Update Promt
Updata to-do
This commit is contained in:
2026-09-19 13:59:55 +03:00
parent 5fb5010571
commit 7fc112e2ce
50 changed files with 3305 additions and 3829 deletions
+459
View File
@@ -0,0 +1,459 @@
# Диалект 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 с.
~~~