47 KiB
GhostEditor / md2gost — полное описание проекта
Версия пакета: 0.1.0. Python ≥ 3.10.
Репозиторий: конвертер учебных отчётов Markdown → DOCX по методичке РТУ МИРЭА (ГОСТ 7.32-2017) и профилям ПИС / АПИД. Рядом — два дополнительных пайплайна: FODT (LibreOffice) и LaTeX → PDF.
Этот файл — карта всего репозитория: что уже работает, как устроен код, какие функции есть в CLI/GUI и какие модули за что отвечают. Пользовательская документация по разделам лежит в docs/.
1. Зачем проект существует
Студент пишет отчёт в расширенном Markdown (диалект md2gost). Конвертер сам:
- оформляет DOCX стилями Times New Roman, полями 30/10/20/20 мм, интервалом 1.5;
- нумерует рисунки, таблицы, листинги, формулы;
- собирает содержание и список источников;
- рисует UML / C4 / Mermaid;
- проверяет структуру по ТЗ (
--check); - при необходимости режет длинные таблицы и листинги через Microsoft Word и пишет «Продолжение…».
Исходный форк: benzlokzik/md2gost. Здесь — своя линия: профили МИРЭА/ПИС/АПИД, GUI, схемы, стили JSON, Word COM, FODT, LaTeX.
2. Три продукта в одном репозитории
| Пакет | Entry point | Результат | Когда |
|---|---|---|---|
| md2gost | python -m md2gost / md2gost-gui |
.docx |
основной путь, Word |
| md2fodt | python -m md2fodt |
.fodt |
LibreOffice, без Word |
| md2latex | python -m md2latex |
каталог XeLaTeX (+ --pdf) |
PDF через шаблон МИРЭА |
| word2md | python -m word2md / md2gost файл.docx |
.md |
импорт DOCX → диалект md2gost |
Общий диалект разметки: спецразделы # *ВВЕДЕНИЕ, метки %id, ссылки @Рисунок:id, таблицы с ^/>, формулы $$, библиография [n]: ….
Полнота реализации не одинаковая:
- md2gost — полный конвейер (стили, профили, диаграммы, checker, GUI, Word COM).
- md2fodt — v1: текст, заголовки, списки, таблицы с merge, картинки, листинги, простые ссылки, библиография. Нет PlantUML, нет «Продолжение таблицы», нет полного паритета PIS/АПИД.
- md2latex — тот же диалект →
content.tex+ копияlatex/mirea/. Таблицы идут вlongtableс настоящим «Продолжение таблицы N» (это умеет LaTeX, не Word). - word2md — эвристический DOCX → диалект md2gost (стили Caption/Heading, подписи, таблицы, Code, формулы OMML). Не восстанавливает UML/Mermaid и исходные
%id.
3. Как запустить
pip install -e .
python -m md2gost # GUI
python -m md2gost report.md -o report.docx --type coursework --check
python -m word2md report.docx -o report.md
python -m md2fodt report.md -o report.fodt
python -m md2latex report.md -o report_latex --pdf
Windows exe: build-exe.bat → dist\md2gost.exe (двойной клик — GUI; из консоли работает как CLI; перед сборкой тянет plantuml.jar и portable Graphviz).
Быстрая сборка: build-exe-fast.bat + md2gost.fast.spec.
Для режима продолжения таблиц/листингов word (по умолчанию): Windows + Microsoft Word + pip install pywin32 (опциональная группа [word]).
4. Архитектура md2gost (главный конвейер)
Один движок на CLI и GUI. GUI только собирает ConvertRequest и зовёт convert().
.md
│
├─ checker.check_markdown() # если --check / --check-only
│
├─ profiles.preprocess_markdown() # «ёлочки», тире; не трогает UML/Mermaid
│
├─ Parser (marko + extended_markdown)
│ └─ RenderableFactory → список Renderable
│
├─ biblio_processor.fold_bibliography()
├─ Heading / ToC / Table / Listing: режимы нумерации и continuation
├─ label_pass.assign_numbers() + resolve @Тип:id
│
├─ Renderer.process() # LayoutTracker, секции, альбом, колонтитулы
├─ TocProcessor.process() # native TOC field или ручная сборка
│
├─ [опционально] docxcompose: титул + задание + тело
├─ document.save()
├─ [если word] word_fix.fix_continuations() # COM: реальные разрывы страниц
└─ [если --check-pages] page_fill_check # эвристика полупустых страниц
Ключевые типы:
ConvertRequest/ConvertResult— контракт CLI↔GUI (md2gost/pipeline.py).DocProfile— правила типа работы (md2gost/profiles.py).StyleConfig— поля страницы + стили абзацев (md2gost/style_config.py).Renderable— элемент, который умеет себя нарисовать в DOCX с учётом высоты страницы.
5. Что уже умеет пользователь (функции продукта)
5.1. Типы документов (--type)
| Тип | Стили | Нумерация объектов | Источники | Структура |
|---|---|---|---|---|
practice |
mirea | по разделам 1.1, 2.1 |
5–7, ≤5 лет | Введение, разделы, заключение, список, приложения |
coursework |
mirea | то же | 5–7, ≤5 лет | то же |
vkr |
mirea | то же | ≥10 в каждом разделе списка, ссылки [1.5] |
+ приложение «Графический материал» |
PIS_custom |
pis_custom | сквозная 1, 2, 3 |
не обязательны | H1 = «Практическая работа №N. …»; H1 по центру ПРОПИСНЫМИ; H2 с абзацным отступом |
APID_coursework |
mirea | по разделам | 7–20, ≤5 лет | обязательные главы «Теоретические…» / «Прикладные…» и пункты 2.1–2.4 |
Реализация: PROFILES и get_profile() в profiles.py. Стили пресетов: preset_mirea(), preset_pis_custom().
5.2. CLI (все флаги)
Точка входа: md2gost/__main__.py → build_parser(), request_from_args(), main().
| Флаг | По умолчанию | Что делает |
|---|---|---|
filename |
нет → GUI | .md или .docx с --check-pages |
--gui |
открыть окно (можно сразу передать .md) |
|
-o / --output |
рядом с md, то же имя | выходной DOCX |
-t / --template |
md2gost/Template.docx |
шаблон Word |
--type |
practice |
профиль документа |
--heading-numbering |
manual |
manual — цифры из md, автонумерация Word выкл.; auto — нумерует Word, цифры в начале заголовка снимаются |
--toc |
native |
native — поле Word TOC; manual — сборка по LayoutTracker |
--table-continuation |
word |
word / off / soft / legacy / caption |
--listing-continuation |
word |
то же для листингов |
--table-repeat-header |
выкл. | шапка на фрагментах после word-split |
--emdash-to-hyphen |
выкл. | «—» → «-» |
--hr-pagebreak |
выкл. | --- / *** / ___ → разрыв страницы |
--title / --assignment |
DOCX титула и бланка задания (склейка через docxcompose) | |
--auto-title / --no-auto-title |
автотитул из yaml/```title (по умолчанию выкл.) |
|
--student / --group |
ФИО и группа для автотитула (иначе md2gost.user.json) |
|
--doc-author-from / --doc-author |
os / профиль |
автор в свойствах DOCX: os (имя ОС), student, custom |
--doc-title / --doc-subject / --doc-keywords / --doc-comments / --doc-category / --doc-last-modified-by |
см. профиль | остальные поля File → сведения; пустые comments — без штампа md2gost |
--check / --check-only / --strict |
проверка ТЗ; --strict → код выхода 1 при ошибках |
|
--check-pages |
полупустые страницы через Word COM (эвристика, не влияет на --strict) |
|
--syntax-highlighting |
Pygments в листингах | |
--plantuml-jar / --kroki-url |
локальный рендер диаграмм | |
--diagram-fallback |
remote |
remote / local / off |
--diagram-format |
png |
png или svg (svgBlip + PNG-запасной) |
--diagram-scale |
2.0 |
качество PNG PlantUML (размер на странице как при 1) |
--schemes |
авто | путь к md2gost.schemes.json |
--styles |
авто | оверлей md2gost.styles.json |
--debug |
отладочная сетка в документе + открыть файл |
Занятый выходной файл: timestamped_output_path() пишет имя_ГГГГ-ММ-ДД-ЧЧ-ММ.docx.
Windowed exe: _argv_needs_console() + _enable_windows_console() — консоль появляется только для CLI/--help, не для GUI.
5.3. GUI (Tkinter)
Модуль md2gost/gui.py, класс Md2GostApp. Entry: md2gost-gui / python -m md2gost без файла / --gui.
Уже есть:
- зона Drop: перетаскивание
.md(tkinterdnd2, иначе Win32WM_DROPFILES, иначе клик → диалог); - основные параметры: тип, нумерация заголовков, TOC, continuation таблиц/листингов, тире,
---→ разрыв, проверки ТЗ, вёрстка, открыть после сборки; - Настройки → Файлы: шаблон, титул, задание, стили JSON, выходной путь;
- Настройки → Студент…: ФИО и группа (первый запуск);
- Настройки → Метаданные…: свойства DOCX (автор, название, тема, теги, примечание) в
md2gost.user.json; - Настройки → Диаграммы: jar, Kroki, fallback, формат, масштаб, статус движка, скачать PlantUML, сброс кэша includes;
- Шаблоны UML: CRUD схем (
md2gost.schemes.json) — добавить / дублировать / удалить / сохранить / открыть JSON; - Справка: Инструкция, Документация (вшитые
docs/*.md), Схемы, Промпт для ИИ (каталогprompts/+ кнопки схем); - конвертация в фоне (
threading), лог в окне, тултипы, меню «Дебаг» на одну следующую сборку; - если выходной DOCX занят — timestamp-имя, как в CLI.
Конвертация не блокирует окно: _convert() → поток → _on_done().
5.4. Диалект Markdown
Реализовано в extended_markdown/ (расширение Marko + GFM) и RenderableFactory.
| Элемент | Синтаксис | Поведение |
|---|---|---|
| Спецраздел без номера | # *ВВЕДЕНИЕ |
ПРОПИСНЫЕ, без автономера раздела |
| Содержание | # *СОДЕРЖАНИЕ + [TOC] |
native поле Word или ручная сборка |
| Рисунок-файл |  |
нумерация + @Рисунок:id |
| Таблица | %id Подпись перед таблицей |
подпись «Таблица N — …» |
| Merge ячеек | ^ rowspan, > colspan |
OOXML vMerge / gridSpan; через разрыв страницы merge не переносится |
| Листинг | %id + code fence |
Courier New, опционально Pygments |
| Диаграмма | %id + ```uml / uml-c4 / mermaid / idef0 / dfd |
Рисунок; флаги +listing, +landscape |
| Формула | %eq1 + $$…$$ + @Формула:eq1 |
номер только если есть ссылка |
| Инлайн-формула | $…$ |
OMML в абзаце |
| Ссылка на объект | @Рисунок:id, @Таблица:id, @Листинг:id, @Формула:id |
подстановка номера |
| Источник | [1] в тексте, [1]: … в списке |
ВКР: [1.5], цитата [2.18, c. 21-25] |
| Разрыв страницы | --- + --hr-pagebreak |
иначе HR игнорируется |
| Жирный / курсив / зачёркивание / ссылки / списки | обычный MD | поддерживается |
Автоправки текста (preprocess_markdown):
"..."→ «…» (эвристика, не внутри%…);слово - слово→слово — слово(если не--emdash-to-hyphen);- внутри оград UML/Mermaid/схем не трогает кавычки и тире;
- в списке источников каждый
[n]:выносится в отдельный абзац (separate_biblio_lines).
5.5. Схемы и диаграммы
Встроенные id (md2gost/diagrams/schemes.json): c4, c4context, c4component, usecase.
Слои загрузки (позже побеждает): встроенный шаблон → md2gost.schemes.json рядом с приложением (создаётся при первом запуске, не перезаписывается) → рядом с .md → --schemes.
Рендер UML:
- Java +
plantuml.jar(вшитый /%LOCALAPPDATA%\md2gost\/--plantuml-jar); - локальный Kroki (
KROKI_URL/--kroki-url); https://kroki.ioпри--diagram-fallback remote.
Mermaid — локально (браузер / QuickJS) или Kroki. IDEF0 — оградка ```idef0, локальный Pillow (рамка NIST). DFD — оградка ```dfd, пакет data-flow-diagram → вшитый/кэш/PATH Graphviz (scripts/fetch_graphviz.py, GUI «Скачать Graphviz») или Kroki.
Кэш картинок: {каталог_md}/.md2gost-cache/.
Кэш !include URL: md2gost.include-cache.json + include-cache/.
Альбомная страница: флаг +landscape у подписи — отдельная секция A4 landscape с вертикальным центрированием, затем снова книжная. Один section break (без пустой книжной страницы перед альбомом).
5.6. Кастомные стили JSON
Файл md2gost.styles.json (рядом с .md и/или --styles). Deep-merge поверх пресета типа. Неизвестный ключ или имя стиля — ошибка (StyleConfigError).
Можно менять поля page (мм) и поля стилей абзацев: шрифт, кегль, жирный/курсив/прописные, выравнивание, отступы, интервал 1.0/1.5, page_break_before, keep_with_next, widow_control.
Не в JSON: табы оглавления (считаются от ширины полосы), отступы списков, цвет (всегда чёрный), формулы из шаблона.
5.7. Проверка ТЗ (--check)
Модуль md2gost/checker/__init__.py. Возвращает Issue(id, severity, message, line).
Уже проверяется:
- обязательные разделы по профилю (СОДЕРЖАНИЕ, ВВЕДЕНИЕ, ЗАКЛЮЧЕНИЕ, список; для ПИС — практические работы; для ВКР — «Графический материал»; для АПИД — 6 обязательных заголовков);
[TOC];- спецразделы должны быть
# *…, лучше ПРОПИСНЫМИ; - запрет «рис.», «табл.», сносок
[^1], графы «№ п/п»; - ссылки
[n]во введении/заключении запрещены; - число и возраст источников; для ВКР — по разделам списка; порядок первого упоминания;
- висячие / неиспользованные метки
%id/@Тип:id; - запрещённые буквы приложений (Ё З Й О Ч Ь Ы Ъ);
- перечень приложений после
# *ПРИЛОЖЕНИЯ, если приложений ≥ 2; - маркеры merge
^/>в шапке и>в первом столбце; - подсказка про «Продолжение…», если continuation =
off/soft.
--strict падает только на severity == "error". --check-pages — отдельная эвристика, в strict не входит.
5.8. Продолжение таблиц и листингов
DOCX сам не умеет писать «Продолжение Таблицы N» только со 2-й страницы.
| Режим | Поведение |
|---|---|
word (по умолчанию) |
После save Word COM режет по реальной пагинации, вставляет подпись |
off / soft |
Одна таблица/листинг, пагинацию делает Word, без автоподписи |
legacy |
Резка по оценке высоты LayoutTracker + page_break_before (могут быть дыры) |
caption |
То же + явный PageBreak |
Оценка высоты ≠ вёрстка Word — поэтому legacy/caption помечены как неточные.
5.9. Титул, задание, колонтитулы
--title / --assignment: пустая оболочка из шаблона + docxcompose (титул, разрыв, задание, разрыв, тело).
На секциях титула/задания колонтитул без номера страницы; дальше — сквозная нумерация, поле PAGE, TNR 12 по центру. После TOC начинается секция тела с номерами.
Если в документе нет TOC — номер ставится на единственную секцию.
Автотитул (по умолчанию выкл.; CLI --auto-title / галочка в GUI; явный --title отключает генератор): см. docs/title.md. Кратко: md2gost/title_page.py заполняет bundled TitleTemplate.docx из info_conv.yaml и/или блока ```title, ФИО/группа — md2gost.user.json или --student/--group. GUI: первый запуск и Настройки → Студент….
Свойства DOCX (после склейки титула, перед save): doc_metadata.apply_document_metadata. По умолчанию автор = getuser(), примечание «Создано при помощи md2gost (ТЗ МИРЭА)», created/modified = сейчас, revision = 1. GUI Настройки → Метаданные… / флаги --doc-*. Профиль — блок metadata в md2gost.user.json.
5.10. Приложения
- Буквы: А Б В Г Д Е Ж И К … (без Ё З Й О Ч Ь Ы Ъ) —
APPENDIX_LETTERSвnumberer.py. ## Приложение А Названиеоформляется как приложение.- Если после
# *ПРИЛОЖЕНИЯнет перечня, а приложений несколько — Renderer сам вставляет список «Приложение А — …». Если автор уже написал перечень — не дублирует.
5.11. Промпты для ИИ
| Файл | Назначение |
|---|---|
prompts/generate-md.md |
диалект md2gost vs обычный MD |
prompts/generate-mirea-report.md |
полный отчёт ГОСТ / МИРЭА |
prompts/generate-pis-custom-report.md |
итоговый отчёт ПИС |
prompts/emulate-student.md |
голос: человечный текст, не отчёт ИИ |
В GUI: выбор промпта + чекбоксы схем → в конец дописываются ai-prompt и макросы из md2gost.schemes.json (compose_prompt()).
5.12. Сборка и поставка
pyproject.toml: hatchling, пакетыmd2gost,md2latex,md2fodt; в wheel вшиваются Template.docx, mml2omml, diagrams, latex/mirea, prompts, docs.md2gost.spec/md2gost.fast.spec— PyInstaller (вшиваютplantuml.jarи при наличииvendor/graphviz).scripts/fetch_plantuml.py— скачать jar.scripts/fetch_graphviz.py— скачать portable Graphviz вmd2gost/vendor/graphviz(для DFD в exe).scripts/md2gost_exe.py— обёртка exe.scripts/pyi_rth_mplbackend.py— runtime hook matplotlib для PyInstaller.scripts/check_page_fill.bas— макрос Word для той же эвристики вёрстки.scripts/md2pdf.ps1/md2pdf.sh— обёртки LaTeX→PDF.- CI:
.github/workflows/pytest.yml(Python 3.11, flake8, pytest);example-generator.yml.
6. Карта модулей md2gost и функции кода
Ниже — публичные и важные внутренние функции уже реализованные. Приватные _foo указаны, если без них не понять модуль.
6.1. Точки входа и пайплайн
md2gost/__init__.py
package_dir()— каталог пакета (и_MEIPASSв frozen exe).
md2gost/__main__.py
build_parser()— argparse.request_from_args(args)→ConvertRequest._argv_needs_console(argv),_enable_windows_console().main().
md2gost/pipeline.py
ConvertRequest,ConvertResult.default_output_path(filename),timestamped_output_path(path),default_template_path().open_document(path)— macOSopen/ Windowsstartfile/xdg-open._fix_front_matter_after_compose(...)— сброс PAGE на титуле/задании, сквозная нумерация.convert(req, log=None)— весь конвейер, ошибки вConvertResult, не пробрасывает исключение наружу. Перед save —apply_document_metadata.should_launch_gui(filename, gui_flag)._CallbackLogHandler— логи md2gost в GUI/CLI.
md2gost/doc_metadata.py
DocumentMetadata,DEFAULT_DOC_COMMENTS,AUTHOR_SOURCES.os_user(),clip_core()(лимит 255 символов python-docx).resolve_document_metadata(...)— профиль + CLI/request.apply_document_metadata(document, meta)— core properties + даты + revision=1.
md2gost/user_profile.py
UserProfile(student, group, metadata),load_user_profile/save_user_profile→md2gost.user.json.
md2gost/converter.py
- класс
Converter: читает md, применяет стили, парсит, нумерует, рендерит. convert(), свойстваdocument,style_config,raw_markdown,doc_type,heading_numbering.
6.2. Профили и стили
md2gost/profiles.py
- константы:
DOC_TYPES,HEADING_NUMBERING_MODES,TOC_MODES,TABLE_CONTINUATION_MODES,LISTING_CONTINUATION_MODES,NUMBERING_SCOPES,STYLE_PRESETS. DocProfile— поля min/max источников, sectional_biblio, require_graphic_appendix, style_preset, numbering_scope, флаги структуры,require_apid_kr_structure.get_profile(doc_type).fix_russian_quotes,fix_dashes,replace_emdash_with_hyphen.set_emdash_to_hyphen,emdash_to_hyphen_enabled,dash_separator.preprocess_markdown,separate_biblio_lines.find_formula_refs—@Формула:/@Formula:.current_year().
md2gost/style_config.py
StyleConfigError.PageSpec.merge/to_dict/require_complete.ParagraphStyleSpec.merge/to_dict.StyleConfig.merge/to_dict.preset_mirea(),preset_pis_custom(),get_preset(name).style_config_from_dict,load_styles_file,resolve_style_config(пресет ← рядом с md ←--styles).
md2gost/styles.py
apply_style_config(document, config)— поля, секции, табы TOC, стили абзацев.apply_mirea_styles,apply_pis_custom_styles.apply_document_styles(...)— пресет + оверлей, возвращает итоговыйStyleConfig.- Внутри:
_set_run_font(блокирует тему Word: Calibri/синий),_ensure_style,_fix_toc_tab_stops.
md2gost/page_geometry.py
- глобальные поля
MARGIN_*,MARGIN_PRESETS,apply_margin_preset. is_landscape_section,apply_section_geometry,content_size.apply_centered_page_footer,clear_section_footer,ensure_continuous_page_numbers.
6.3. Разбор Markdown
md2gost/extended_markdown/
__init__.py— Marko + GFM + Extension: Equation, Reference, Caption, Table, TOC, Heading, InlineEquation, Image.heading.py—# *→ ненумерованный.caption.py— строка%id текст +listing +landscape.table.py— GFM-таблица +^/>+_resolve_merge_restarts.image.py—%idв title картинки.equation.py— блочная$$.inline_formula.py—$…$.reference.py—@Тип:id.toc.py—[TOC].
md2gost/parser_.py
Parser.parse()— пропускает пустые строки; копитCaptionInfo; HR без флага игнорирует; иначеfactory.create.
md2gost/renderable_factory.py
RenderableFactory.create(singledispatch): Paragraph, Heading, FencedCode/CodeBlock → Listing или DiagramFigure, Equation, List, Table, TOC, ThematicBreak → PageBreak._create_runs— жирный/курсив/зачёркивание, код, картинки, инлайн-формулы,@ссылки, гиперссылки.
6.4. Нумерация и ссылки
md2gost/numberer.py
Numberer(mode="section"|"continuous"):enter_section,enter_appendix,next_number,resolve,register_label.- Режим section:
1.1/Б.1, счётчики сбрасываются на разделе/приложении. - Режим continuous:
1, 2, 3на весь документ (ПИС).
md2gost/label_pass.py
LabelRegistry.put/get/get_display(алиасы Рисунок/Figure/Таблица/…).assign_numbers(renderables, numbered_equations, numbering_scope).resolve_pending_in_renderables,set_active_registry,resolve_reference.
Формулы нумеруются только если на них есть @Формула:… в исходнике.
6.5. Рендер в DOCX
md2gost/renderer.py — класс Renderer
process(renderables)— основной цикл.- Секции: фронт без номеров → после TOC тело с PAGE;
_enter_landscape/_exit_landscape. _ensure_appendix_index— автоперечень приложений.- Нумерация объектов через
Numberer(если неskip_numbering— в Converter нумерация уже в label_pass). - Спецзаголовки: СОДЕРЖАНИЕ / СПИСОК — по центру; Введение / Заключение / ПРИЛОЖЕНИЯ — слева как H1.
md2gost/layout_tracker.py
LayoutState— текущая/оставшаяся высота, номер страницы.LayoutTracker—add_height,can_fit_to_page,new_page,set_page_size(книга ↔ альбом).
md2gost/renderable/
| Класс | Файл | Роль |
|---|---|---|
Renderable |
renderable.py |
абстрактный render() |
Paragraph / Link |
paragraph.py |
абзац, runs, картинки, ссылки, инлайн-формулы |
Heading |
heading.py |
уровни 1–9, manual/auto, снятие Word numbering, strip ведущих цифр |
Table |
table.py |
сетка, merge, continuation, +landscape |
Listing |
listing.py |
код, Pygments (DocxParagraphPygmentsFormatter), continuation |
Image |
image.py |
файл-рисунок + подпись |
DiagramFigure |
diagram.py |
рендер схемы + опциональный Listing исходника |
Equation |
equation.py |
блочная формула OMML + номер справа |
Caption / CaptionInfo |
caption.py |
«Рисунок 1.1 — …» |
List |
list.py |
маркированные/нумерованные, вложенность |
ToC |
toc.py |
native field TOC \o "1-3" \h \z \u или ручные строки с табами |
PageBreak |
page_break.py |
явный разрыв |
RequiresNumbering |
requires_numbering.py |
интерфейс нумеруемых объектов |
ParagraphSizer / шрифты |
paragraph_sizer.py, find_font.py |
оценка высоты абзаца (FreeType) |
md2gost/docx_elements.py
create_table,create_table_row,create_table_cell,apply_cell_merge,set_table_box_borders, фиксация ширины в twips.
md2gost/docx_svg.py
attach_svg_blip(run, inline_shape, svg_path)— вектор + PNG fallback.
md2gost/latex_math.py
latex_to_omml(latex)— latex2mathml + XSLTmml2omml.inline_omml(omml)— дроби в линейный вид для инлайна.
md2gost/toc_processor.py
TocProcessor.process— native:updateFieldsпри открытии Word; manual: страницы изHeading.rendered_page(СОДЕРЖАНИЕ в оглавление не попадает).
md2gost/debugger.py
- плавающая сетка страниц в документе (
--debug):Debugger,add_float_picture,new_pic_anchor.
md2gost/util.py
create_element— низкоуровневый OOXML.
6.6. Библиография
md2gost/bibliography.py
BiblioEntry,extract_year,parse_biblio_block,find_citations.Bibliography(...)— ленивая обёртка над renderable (чтобы checker не тянул docx).
md2gost/biblio_processor.py
entries_from_text— несколько[n]:внутри одного абзаца (Marko склеивает строки).extract_bibliography_from_markdown— плоский список или секции для ВКР.fold_bibliography(renderables, parent, raw_markdown)— заменяет абзацы списка наBibliography.
md2gost/bibliography_renderable.py — отрисовка пунктов списка стилем Bibliography.
6.7. Диаграммы
md2gost/diagram_schemes.py
DiagramScheme(id, title, docs, ai-prompt, includes, prefix/postfix, theme).bundled_schemes_path,user_schemes_path,ensure_user_schemes.load_schemes_from_path,save_schemes,load_merged_schemes.scheme_id_from_lang,is_diagram_lang,get_scheme,get_schemes,reload_schemes,configure_schemes.apply_scheme,prepare_with_schemes.
md2gost/diagram_includes.py
- кэш HTTP
!include:resolve_url,resolve_include_ref,rewrite_http_includes_in_source,reset_include_cache,cache_entry_count.
md2gost/diagram_renderer.py
configure_diagrams(...),DiagramConfig,DiagramRenderResult.prepare_source,render_diagram.resolve_plantuml_jar,fetch_plantuml_jar,iter_plantuml_candidates,diagram_engine_status.- рендер jar / Kroki / пара png+svg; масштаб
scaleв исходник PlantUML. - локальные типы
LOCAL_ONLY_TYPES(idef0,dfd): Pillow, без jar/Kroki.
md2gost/idef0.py — DSL IDEF0 + Pillow/SVG.
md2gost/dfd.py — обёртка pbauermeister/dfd: DSL → DOT → vendor/system Graphviz / Kroki (write_dfd_outputs, fetch_graphviz).
md2gost/diagrams/ — schemes.json, C4 *.puml.
6.8. Word COM и вёрстка
md2gost/word_fix.py
parse_caption_text,find_page_break_row,continuation_label,caption_style_name.fix_continuations(path, tables, listings, repeat_header)→FixResult.- Внутри: до 5 проходов
Repaginate+Split, рамки листингов, опциональный повтор шапки.
md2gost/page_fill_check.py
PageMetric,PageFillIssue.evaluate_page_fill(pages)— чистая эвристика (порог пустого низа 40%, пропускает альбом, последнюю страницу, фронт, конец раздела, «в основном рисунок/таблица»).check_docx_page_fill(path),format_page_fill_report.
6.9. Checker (функции проверок)
md2gost/checker/__init__.py:
check_structure,check_apid_kr_structure,check_pis_headings,check_special_headings.check_forbidden_abbreviations,check_citations_in_intro_conclusion.check_bibliography,check_object_refs,check_appendices.check_continuation_hints,check_table_merge.check_markdown(...)— оркестратор.format_report(issues).
6.10. GUI, DnD, справка
md2gost/gui.py
_make_root,_combo_values/_combo_key/_display,_Tooltip,_tip.Md2GostApp: меню, окна файлов/студента/метаданных/диаграмм/схем/справки, браузер docs, сборка промпта, DnD,_collect()→ConvertRequest,_convert.run_gui(initial),main().
md2gost/dnd.py
parse_tkdnd_files,normalize_drop_paths,first_markdown,enable_file_drop.- Win32:
_WinDropHook,_Win32DropApi,_query_drop_files.
md2gost/help_content.py
- константы
USAGE_HELP,SCHEMES_HELP. prompt_search_dirs,load_prompt_catalog,scheme_prompt_block,compose_prompt.docs_search_dirs,load_docs_catalog.
7. md2fodt — что уже есть
Пакет md2fodt/.
| Файл | Функции |
|---|---|
__main__.py |
main() — CLI: файл, -o, --emdash-to-hyphen |
converter.py |
convert_md_to_fodt(md, output, emdash_to_hyphen) |
emitter.py |
emit_body, emit_fodt; эмиттеры heading/paragraph/image/table/code/list/equation; merge ^/> |
styles.py |
styles_xml(), automatic_styles_xml() — TNR 14, поля ГОСТ |
escape.py |
escape_text, xml_id |
Картинки встраиваются base64. Нет диаграмм PlantUML и нет «Продолжение таблицы».
8. md2latex — что уже есть
Пакет md2latex/ + шаблон latex/mirea/ (вендор mirea-ninja/Latex-Template-for-Report-Diploma-Thesis).
| Файл | Функции |
|---|---|
__main__.py |
main(), _run_xelatex (latexmk или 2 прохода xelatex) |
converter.py |
package_template_dir(), convert_md_to_latex_project(md, out, titlepage) — копирует шаблон, пишет content.tex |
emitter.py |
emit_document; _emit_longtable с \endfirsthead / \endhead и «Продолжение таблицы N» |
escape.py |
escape_text, escape_verbatim_for_listing, latex_label |
Флаги: -o каталог, --titlepage PDF титула, --pdf, --xelatex-passes.
8.1. word2md — импорт DOCX
Пакет word2md/. Эвристика: стили md2gost, иначе ГОСТ-текст подписей/заголовков.
| Файл | Роль |
|---|---|
__main__.py |
CLI: .docx, -o, --media-dir, --keep-toc-pages, --pagebreaks |
pipeline.py |
ImportRequest / ImportResult / convert_docx() |
walker.py |
обход body, склейка Code/списков, postprocess_blocks (продолжения) |
classify.py |
Heading / Caption / Code / библио / спецразделы |
captions.py |
Рисунок / Таблица / Листинг + parse_caption_text из md2gost |
tables.py |
merge → ^/>, детект формульной таблицы |
omml.py |
OMML → читаемая формула |
media.py |
выгрузка word/media |
emit.py |
IR → диалект md2gost |
refs.py |
Рисунок 1.1 → @Рисунок:fig1_1 |
Точки входа также: python -m md2gost report.docx, GUI «Импорт DOCX→MD».
9. Тесты — что покрыто
Каталог tests/, CI гоняет pytest.
| Файл | Что проверяет |
|---|---|
test_pipeline.py |
GUI/CLI развилка, пути, DnD, argparse, HR→pagebreak, промпты, docs catalog, listing continuation |
test_mirea_tz.py |
Numberer, checker (coursework/PIS/ВКР/АПИД), препроцесс, TOC, заголовки, приложения, библио, page-fill эвристика, стили H1 |
test_style_config.py |
merge оверлея, неизвестные ключи, CLI побеждает файл рядом с md, применение к Document |
test_table_merge.py |
^/>, OOXML merge, checker merge, режимы continuation |
test_word_fix.py |
разбор подписей, индекс разрыва, COM smoke (если нет Word — мягко) |
test_landscape.py |
геометрия альбома, секции, картинки/таблицы/листинги, один section break |
test_layout_tracker.py |
страницы и остаток высоты |
test_paragraph.py / test_paragraph_sizer.py |
абзацы и измерение шрифта |
test_diagram_renderer.py |
схемы, кэш, mermaid, svg, jar, +listing/+landscape |
test_idef0.py |
DSL IDEF0, PNG/SVG, интеграция render_diagram |
test_dfd.py |
DFD data-flow-diagram, mock Graphviz/Kroki, интеграция render_diagram |
test_md2fodt.py |
escape, каркас FODT, запись файла |
test_md2latex.py |
longtable continuation, генерация проекта |
test_word2md.py |
подписи, спецзаголовки, @ссылки, продолжения таблиц, DOCX→MD, round-trip |
extended_mardown/formula.py |
формулы (unittest) |
Нет полного e2e «открыть Word и сравнить каждую страницу» в Linux CI (шрифты ставятся, Word COM — нет).
10. Документация и примеры
Пользовательские страницы (те же вшиты в exe, GUI: Справка → Документация):
| Файл | Содержание |
|---|---|
ReadMe.md |
краткий старт репозитория |
docs/README.md |
оглавление docs |
docs/quickstart.md |
установка, exe, типы |
docs/markdown.md |
диалект |
docs/schemes.md |
UML/Mermaid, JSON схем |
docs/types.md |
профили работ |
docs/cli-gui.md |
флаги ↔ GUI |
docs/styles.md |
JSON стилей |
docs/prompts.md |
ИИ-промпты |
docs/word2md.md |
импорт DOCX → Markdown |
md2gost/README.md |
справка пакета (подробнее про continuation и диаграммы) |
prompts/README.md |
как копировать промпты |
examples/example.md, examples/pis_custom.md |
образцы |
examples/md2gost.styles.json |
пример оверлея стилей |
11. Зависимости
Обязательные (pyproject.toml): python-docx, marko, docxcompose, freetype-py, pillow, requests, latex2mathml, pygments, lxml.
Опционально: pywin32 (Word COM), matplotlib (сборка exe / отладка), tkinterdnd2 (удобный DnD в GUI).
Внешние рантаймы: Java + plantuml.jar или Kroki; Graphviz (вшитый/кэш/PATH) для DFD; для PDF — XeLaTeX / latexmk и шрифт Times New Roman.
12. Что в репозитории, но не продукт
Черновики и чужой код рядом с пакетами. Это не часть pip install / exe:
- корень:
main.py,main12.py,mm2.py…mm5.py,asd.py,parser.py,font.py,_audit_tmp.py,tmp_listing_word.md,todo.txt; ad/— черновые отчёты;_paco_extract/— выгрузки методичек ПАЦО;Other_Code/— справка OOXML, docx-js, скрипты pack/unpack/validate (не импортируется md2gost);- артефакты сборки
build-fast/, кэши диаграмм.
todo.txt сейчас: «оценки с текстом через сам Word, а не предугадывание» — частично закрыто режимом word.
13. Чего нет / ограничения (честно)
- DFD: пакет
data-flow-diagramв зависимостях; картинка — вшитый/кэш/PATH Graphviz или Kroki; балансировка уровней не проверяется. - FODT и LaTeX не догоняют md2gost по GUI, checker, схемам, профилям PIS/АПИД, Word COM.
- «Продолжение таблицы» в чистом DOCX без Word невозможно точно (нет longtable). Без Word —
offили неточныйlegacy/caption. --check-pagesдаёт ложные срабатывания; это эвристика.- Merge ячеек не живёт через границу разрезанной таблицы.
- Цвет текста в стилях не настраивается (всегда чёрный).
- Профиль
paco_customупомянут в комментарииpage_geometry, отдельного типа вDOC_TYPESнет. - Нумерация заголовков H4+ в стилях JSON не описана (в Word уровни 1–9 у Heading есть).
14. Типичные сценарии «уже работает»
- Практика / курсовая МИРЭА:
# *ВВЕДЕНИЕ…# 1 …… список[1]:→--type practice|coursework --check --strict. - ВКР: раздельный список, ссылки
[1.5], приложение «Графический материал». - ПИС:
# Практическая работа №1. …→--type PIS_custom, сквозные Рисунок 1, 2, 3. - АПИД: обязательные 2 главы и 2.1–2.4, источники 7–20.
- UML в отчёте:
%id Подпись+```uml-c4— PNG/SVG в Word, опционально+listingи+landscape. - Широкая таблица:
%id … +landscape. - Длинная таблица на Windows: режим
word→ COM режет и пишет «Продолжение Таблицы N». - Свой вуз/кафедра:
md2gost.styles.jsonменяет поля и H1 без правки кода. - Своя схема: GUI «Шаблоны UML» или JSON с
includes/prefix/ai-prompt. - Черновик через ИИ: промпт из GUI + схемы →
.md→ конвертер. - Только проверить готовый DOCX:
python -m md2gost report.docx --check-pages. - Без Word:
python -m md2fodtилиpython -m md2latex --pdf.
15. Поток данных одним абзацем
Пользователь кладёт .md (и опционально титул/задание/JSON стилей/схем). convert() читает текст, при необходимости гоняет checker, препроцессит кавычки/тире, парсит Marko-расширением в дерево, фабрика делает Renderable, библиография сворачивается в особые абзацы, объектам раздаются номера по профилю, @ссылки заменяются на «Рисунок 2.1», Renderer кладёт OOXML в очищенный Template.docx с оценкой высоты страницы, TocProcessor дописывает содержание, pipeline склеивает титул, сохраняет DOCX, при режиме word открывает файл в Word и режет таблицы/листинги по настоящей пагинации. GUI делает ровно то же, только параметры собирает из формы.
16. Где править, если добавлять функцию
| Хочешь | Куда |
|---|---|
| Новый тип работы | profiles.PROFILES + checker + стили пресета |
| Новое поле CLI/GUI | __main__.build_parser, ConvertRequest, gui._collect/_apply_request |
| Новый элемент Markdown | extended_markdown/ + RenderableFactory + класс в renderable/ |
| Новая проверка ТЗ | checker/__init__.py → вызов из check_markdown |
| Новая UML-схема «из коробки» | md2gost/diagrams/schemes.json (+ .puml при необходимости) |
| Новое поле стиля | style_config.STYLE_FIELD_KEYS + ParagraphStyleSpec + _apply_paragraph_spec |
| Паритет FODT/LaTeX | md2fodt/emitter.py / md2latex/emitter.py |
Файл сгенерирован по состоянию исходников репозитория (пакет 0.1.0). Пользовательские howto — в docs/. Этот файл — инвентарь возможностей и кода.