Forge
markdowndeeb25a2
1# ADR 0023: Markdown + диаграммы (Mermaid/PlantUML) — first-class опыт через LSP и workflow
2
3**Статус:** Proposed
4**Дата:** 2026-04-08
5
6## Связанные ADR
7
8| ADR | Роль |
9|-----|------|
10| [0015](0015-editor-toml-syntax-highlighting.md) | TextMate подсветка как быстрый baseline |
11| [0008](0008-mcp-contracts-and-testable-infrastructure.md) | внешние процессы и тестируемые абстракции |
12| [0021](0021-pfd-mfd-cockpit-attention-model.md) | модель внимания кокпита |
13| [0026](0026-markdown-preview-surfaces-and-placement.md) | **где** монтируется виджет превью Markdown — `workspace.toml`; канон по размещению превью |
14
15## Резюме
16
17- Markdown + **Mermaid/PlantUML** — first-class через LSP и workflow.
18- Kroki, export expanded, authoring — **ортогонально** preview ([0069](0069-markdown-preview-tool-surface-and-renderer-decoupling.md)).
19
20---
21## Контекст
22
23В repo и в рабочих сценариях много `*.md`, а также Mermaid/PlantUML диаграмм (часто прямо в fenced-блоках). Комфорт работы с ними обычно хуже, чем с C# (диагностики, completion, навигация, rename ссылок, быстрый цикл “редактирую → вижу результат”).
24
25Важные ограничения:
26
27- Markdown — контейнер: внутри fenced-блоков живут “вложенные языки”, но LSP обычно работает по файлу, а не по диапазонам.
28- “Сделать как C#” для fenced-блоков требует сложной инфраструктуры: виртуальные документы, двусторонний маппинг координат/диагностик, синхронизация edits.
29- Для диаграмм есть разные бэкенды рендера (локально, PlantUML Server, Kroki). Для части команд (например, Kroki/PlantUML server) исходник диаграммы уходит на внешний сервер — это влияет на приватность.
30
31---
32
33## Решение
34
35Принять инкрементальный путь “80% ценности быстро”:
36
371. **Markdown становится first-class через Markdown LSP (`marksman`) как внешний процесс.**
38 Цель: ссылки/якоря/викилинки, go-to-definition, references, rename, базовые диагностики — на всём массиве `*.md`.
39
402. **PlantUML получает LSP на уровне отдельного файла (`*.puml` / `*.plantuml`) через `plantuml-lsp` как внешний процесс.**
41 Цель: completion/hover/diagnostics в “настоящем” документе PlantUML, без инъекции в Markdown на v1.
42
433. **Mermaid (и PlantUML внутри Markdown) на v1 обеспечиваются через:**
44 - baseline: **TextMate подсветка**, snippets/шаблоны (при необходимости),
45 - **превью/рендер** в Markdown (встроенный workflow IDE),
46 - **workflow-команды** для извлечения диаграмм из Markdown в отдельные `*.mmd`/`*.puml` файлы, когда нужен “языковой” опыт (LSP, навигация, диагностики).
47
484. **Инъекцию LSP в fenced-блоки Markdown (виртуальные документы) — отложить** как отдельный ADR/фаза, после того как:
49 - Markdown LSP стабилен,
50 - выделены UX-правила (как показывать диагностики внутри Markdown, как делать quick-fix),
51 - решены вопросы приватности/офлайна для рендера диаграмм.
52
53---
54
55## Канон хранения диаграмм + include-директива
56
57**Каноничный формат хранения диаграмм — отдельные файлы** рядом с документацией:
58
59- Mermaid: `*.mmd` (или `*.mermaid`)
60- PlantUML: `*.puml` / `*.plantuml`
61
62Markdown (`*.md`) использует fenced-блоки **по необходимости**, но предпочитает **встраивание через include** для:
63
64- реюза диаграмм,
65- более чистых диффов,
66- включения LSP на уровне “настоящего файла” (`plantuml-lsp` для `*.puml`),
67- возможности “как C# rename” (обновление ссылок/путей).
68
69**Синтаксис include (одна строка, совместим с паттерном из repo `resume`):**
70
71```mermaid
72{{ INCLUDE: example.mmd }}
73```
74
75```plantuml
76{{ INCLUDE: example.puml }}
77```
78
79Опционально (необязательно для MVP, но полезно для больших разделов): `INCLUDE_MANIFEST`, `INCLUDE_GLOB` — как в `resume`.
80
81Правила (v1, ориентир):
82
83- директива **case-insensitive** (`INCLUDE`/`include`) и допускает пробелы;
84- путь по умолчанию считается **relative к файлу `*.md`**, в котором находится fenced-блок (в отличие от `resume`, где пути от корня репо);
85- ограничить глубину include (например, max depth 5) и детектить циклы;
86- ошибки include (файл не найден, цикл, слишком глубоко) должны отображаться в превью как понятная диагностика.
87
88---
89
90## Публикация (чтобы не “сломать внешний Markdown”)
91
92Include-директивы (`{{ INCLUDE: ... }}` и варианты) — **не являются стандартом Markdown** и вне CascadeIDE могут ломать рендер диаграмм.
93
94Принцип:
95
96- **Внутри CascadeIDE / в исходниках** можно держать include-структуру (authoring convenience).
97- **Публиковать/шарить наружу** (GitHub/GitLab/Confluence/…): только **собранные/развёрнутые** варианты Markdown, где include уже заменён на реальный текст диаграмм/фрагментов.
98
99Следствие (требование к продукту):
100
101- IDE должна предоставлять явный путь “**Export / Build expanded Markdown**” (команда/операция), чтобы пользователь мог получить переносимую версию документа для публикации.
102
103---
104
105## Детали UX (ориентир)
106
107- **Размещение виджета превью Markdown** (forward / окно / MFD, TOML) — **[0026](0026-markdown-preview-surfaces-and-placement.md)**; здесь — только язык, диаграммы и workflow-команды.
108- Для диаграмм — явный “порог доверия”:
109 - если рендер идёт через сервер (Kroki/PlantUML server), в настройках есть выключатель и URL;
110 - офлайн/приватный режим — через свой инстанс (или отключение сетевого рендера).
111- **Команды workflow (MVP):**
112 - “Extract diagram to file…” (из fenced `mermaid`/`plantuml` → `*.mmd`/`*.puml` + ссылка/инклюд обратно),
113 - “Open diagram in dedicated editor” (как быстрый переход к отдельному файлу или к виртуальному документу в будущем),
114 - “Render diagram” (обновить превью/картинку по требованию, без постоянного polling).
115
116---
117
118## Последствия
119
120- Markdown станет комфортнее сразу (LSP на уровне файлов).
121- PlantUML получит “как язык” опыт там, где это реально нужно — в `*.puml`.
122- Для fenced-блоков останется разрыв (нет полноценного LSP внутри Markdown), но появится быстрый путь “вынести и жить нормально”.
123- Появится инфраструктура внешних LSP-процессов, которую можно расширять на другие языки.
124
125---
126
127## Отклонённые альтернативы
128
129- **Сразу делать LSP-инъекцию в fenced-блоки Markdown** — отклонено как слишком большой объём/риск для v1 (сложная синхронизация и маппинг диагностик).
130- **Опереться только на превью диаграмм без LSP** — отклонено: цель не только “видеть картинку”, но и “набирать как язык”.
131- **Встраивать LSP как библиотеку in-process** — отклонено: легче обновлять/заменять внешние LSP-серверы, и ниже риск раздувания зависимостей IDE.
132
133---
134
135## Открытые вопросы
136
137- Где хранить и как настраивать пути к `marksman` / `plantuml-lsp` (system PATH vs встроенный менеджер инструментов).
138- Поддержка `.mmd` как отдельного документа: нужен ли отдельный “Mermaid mode” (подсветка/snippets/валидация) без полноценного LSP.
139- Какой формат ссылки из Markdown на вынесенную диаграмму (обычная ссылка на файл, embed-картинка, include-pragma).
140
141
View only · write via MCP/CIDE