ADR 0023: Markdown + диаграммы (Mermaid/PlantUML) — first-class опыт через LSP и workflow¶
Статус: Proposed
Дата: 2026-04-08
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0015 | TextMate подсветка как быстрый baseline |
| 0008 | внешние процессы и тестируемые абстракции |
| 0021 | модель внимания кокпита |
| 0026 | где монтируется виджет превью Markdown — workspace.toml; канон по размещению превью |
Резюме¶
- Markdown + Mermaid/PlantUML — first-class через LSP и workflow.
- Kroki, export expanded, authoring — ортогонально preview (0069).
Контекст¶
В repo и в рабочих сценариях много *.md, а также Mermaid/PlantUML диаграмм (часто прямо в fenced-блоках). Комфорт работы с ними обычно хуже, чем с C# (диагностики, completion, навигация, rename ссылок, быстрый цикл “редактирую → вижу результат”).
Важные ограничения:
- Markdown — контейнер: внутри fenced-блоков живут “вложенные языки”, но LSP обычно работает по файлу, а не по диапазонам.
- “Сделать как C#” для fenced-блоков требует сложной инфраструктуры: виртуальные документы, двусторонний маппинг координат/диагностик, синхронизация edits.
- Для диаграмм есть разные бэкенды рендера (локально, PlantUML Server, Kroki). Для части команд (например, Kroki/PlantUML server) исходник диаграммы уходит на внешний сервер — это влияет на приватность.
Решение¶
Принять инкрементальный путь “80% ценности быстро”:
-
Markdown становится first-class через Markdown LSP (
marksman) как внешний процесс.
Цель: ссылки/якоря/викилинки, go-to-definition, references, rename, базовые диагностики — на всём массиве*.md. -
PlantUML получает LSP на уровне отдельного файла (
*.puml/*.plantuml) черезplantuml-lspкак внешний процесс.
Цель: completion/hover/diagnostics в “настоящем” документе PlantUML, без инъекции в Markdown на v1. -
Mermaid (и PlantUML внутри Markdown) на v1 обеспечиваются через:
- baseline: TextMate подсветка, snippets/шаблоны (при необходимости),
- превью/рендер в Markdown (встроенный workflow IDE),
-
workflow-команды для извлечения диаграмм из Markdown в отдельные
*.mmd/*.pumlфайлы, когда нужен “языковой” опыт (LSP, навигация, диагностики). -
Инъекцию LSP в fenced-блоки Markdown (виртуальные документы) — отложить как отдельный ADR/фаза, после того как:
- Markdown LSP стабилен,
- выделены UX-правила (как показывать диагностики внутри Markdown, как делать quick-fix),
- решены вопросы приватности/офлайна для рендера диаграмм.
Канон хранения диаграмм + include-директива¶
Каноничный формат хранения диаграмм — отдельные файлы рядом с документацией:
- Mermaid:
*.mmd(или*.mermaid) - PlantUML:
*.puml/*.plantuml
Markdown (*.md) использует fenced-блоки по необходимости, но предпочитает встраивание через include для:
- реюза диаграмм,
- более чистых диффов,
- включения LSP на уровне “настоящего файла” (
plantuml-lspдля*.puml), - возможности “как C# rename” (обновление ссылок/путей).
Синтаксис include (одна строка, совместим с паттерном из repo resume):
{{ INCLUDE: example.mmd }}
{{ INCLUDE: example.puml }}
Опционально (необязательно для MVP, но полезно для больших разделов): INCLUDE_MANIFEST, INCLUDE_GLOB — как в resume.
Правила (v1, ориентир):
- директива case-insensitive (
INCLUDE/include) и допускает пробелы; - путь по умолчанию считается relative к файлу
*.md, в котором находится fenced-блок (в отличие отresume, где пути от корня репо); - ограничить глубину include (например, max depth 5) и детектить циклы;
- ошибки include (файл не найден, цикл, слишком глубоко) должны отображаться в превью как понятная диагностика.
Публикация (чтобы не “сломать внешний Markdown”)¶
Include-директивы ({{ INCLUDE: ... }} и варианты) — не являются стандартом Markdown и вне CascadeIDE могут ломать рендер диаграмм.
Принцип:
- Внутри CascadeIDE / в исходниках можно держать include-структуру (authoring convenience).
- Публиковать/шарить наружу (GitHub/GitLab/Confluence/…): только собранные/развёрнутые варианты Markdown, где include уже заменён на реальный текст диаграмм/фрагментов.
Следствие (требование к продукту):
- IDE должна предоставлять явный путь “Export / Build expanded Markdown” (команда/операция), чтобы пользователь мог получить переносимую версию документа для публикации.
Детали UX (ориентир)¶
- Размещение виджета превью Markdown (forward / окно / MFD, TOML) — 0026; здесь — только язык, диаграммы и workflow-команды.
- Для диаграмм — явный “порог доверия”:
- если рендер идёт через сервер (Kroki/PlantUML server), в настройках есть выключатель и URL;
- офлайн/приватный режим — через свой инстанс (или отключение сетевого рендера).
- Команды workflow (MVP):
- “Extract diagram to file…” (из fenced
mermaid/plantuml→*.mmd/*.puml+ ссылка/инклюд обратно), - “Open diagram in dedicated editor” (как быстрый переход к отдельному файлу или к виртуальному документу в будущем),
- “Render diagram” (обновить превью/картинку по требованию, без постоянного polling).
Последствия¶
- Markdown станет комфортнее сразу (LSP на уровне файлов).
- PlantUML получит “как язык” опыт там, где это реально нужно — в
*.puml. - Для fenced-блоков останется разрыв (нет полноценного LSP внутри Markdown), но появится быстрый путь “вынести и жить нормально”.
- Появится инфраструктура внешних LSP-процессов, которую можно расширять на другие языки.
Отклонённые альтернативы¶
- Сразу делать LSP-инъекцию в fenced-блоки Markdown — отклонено как слишком большой объём/риск для v1 (сложная синхронизация и маппинг диагностик).
- Опереться только на превью диаграмм без LSP — отклонено: цель не только “видеть картинку”, но и “набирать как язык”.
- Встраивать LSP как библиотеку in-process — отклонено: легче обновлять/заменять внешние LSP-серверы, и ниже риск раздувания зависимостей IDE.
Открытые вопросы¶
- Где хранить и как настраивать пути к
marksman/plantuml-lsp(system PATH vs встроенный менеджер инструментов). - Поддержка
.mmdкак отдельного документа: нужен ли отдельный “Mermaid mode” (подсветка/snippets/валидация) без полноценного LSP. - Какой формат ссылки из Markdown на вынесенную диаграмму (обычная ссылка на файл, embed-картинка, include-pragma).