From 268a2239cb3e4ac7f68e1b3795030b3b7b2e9ccc Mon Sep 17 00:00:00 2001 From: Vladimir Shabalin Date: Fri, 8 May 2026 09:32:50 +0300 Subject: [PATCH 1/4] feat: support mermaid-cloud plugin --- ADR/001-mermaid-native-confluence-macro.md | 154 +++++++++++++++++ move-in-process.md | 68 ++++++++ move-in-process.md:Zone.Identifier | Bin 0 -> 25 bytes renderer/fencedcodeblock.go | 41 +++++ renderer/fencedcodeblock_test.go | 190 +++++++++++++++++++++ stdlib/stdlib.go | 11 ++ util/flags.go | 2 +- 7 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 ADR/001-mermaid-native-confluence-macro.md create mode 100644 move-in-process.md create mode 100644 move-in-process.md:Zone.Identifier create mode 100644 renderer/fencedcodeblock_test.go diff --git a/ADR/001-mermaid-native-confluence-macro.md b/ADR/001-mermaid-native-confluence-macro.md new file mode 100644 index 00000000..10d22d2a --- /dev/null +++ b/ADR/001-mermaid-native-confluence-macro.md @@ -0,0 +1,154 @@ +# ADR-001: Нативная поддержка Mermaid диаграмм через плагин Mermaid Diagrams for Confluence + +**Статус:** Реализовано + +**Дата:** 2025-05-07 + +## Контекст + +В текущей реализации mark (fork kovetskiy/mark) mermaid-диаграммы обрабатываются следующим образом: +1. Парсер обнаруживает fenced code block с языком `mermaid` +2. Вызывается `mermaid.ProcessMermaidLocally()` — локальный рендеринг в PNG через библиотеку `mermaid.go` +3. PNG загружается как attachment на страницу Confluence +4. В тело страницы вставляется тег `` с ссылкой на attachment + +**Проблема:** На нашем Confluence установлен плагин **Mermaid Diagrams for Confluence** (макрос `mermaid-cloud`), который поддерживает нативное отображение mermaid-диаграмм (интерактивность, SVG, масштабирование). Локальный рендеринг в PNG не использует эти возможности. + +## Исследование + +### Как работает плагин mermaid-cloud + +Из анализа API Confluence (страница "Enterprise Service Bus и Data LakeHouse [Current State]"): + +```xml + + bottom + Current State + svg + fit + 2 + +``` + +**Ключевое ограничение:** Плагин НЕ поддерживает inline-диаграммы через ``. Диаграмма должна быть загружена как **attachment-файл** (параметр `filename` указывает имя attachment). + +### Анализ возможности использования Custom Macro + +Custom macros (определяемые через HTML-комментарии ``) выполняют только текстовую замену в markdown. Они **не могут** загружать attachment-файлы через API. Поэтому чистый Custom Macro подход невозможен — требуется изменение кода mark. + +## Решение + +Добавить новый feature flag `mermaid-cloud`, который при включении: +1. Берёт **сырой текст** mermaid-диаграммы из fenced code block +2. Создаёт attachment-файл `.md` с текстом диаграммы +3. Загружает его на страницу через существующий механизм attachment +4. Генерирует XML макроса `mermaid-cloud` с `filename` → имя attachment + +### Использование в markdown + +```markdown +```mermaid title My Diagram +graph TD; + A-->B; + B-->C; +``` +``` + +### Результат на Confluence + +1. Загружен attachment `My Diagram.md` с текстом диаграммы +2. В тело страницы вставлен макрос: + +```xml + + My Diagram.md + svg + fit + bottom + +``` + +## Внесённые изменения + +### 1. `stdlib/stdlib.go` — Добавлен шаблон `ac:mermaid-cloud` + +```go +`ac:mermaid-cloud`: text( + ``, + `{{ .Filename | xmlesc }}`, + `{{ or .Format "svg" }}`, + `{{ or .Zoom "fit" }}`, + `{{ or .Toolbar "bottom" }}`, + ``, +), +``` + +### 2. `renderer/fencedcodeblock.go` — Добавлена ветка для `mermaid-cloud` + +Новая ветка **перед** существующей `mermaid` веткой (приоритет mermaid-cloud > mermaid). +При отсутствии `title` генерируется уникальное имя по SHA-256 хэшу содержимого (первые 8 символов): + +```go +} else if lang == "mermaid" && slices.Contains(r.MarkConfig.Features, "mermaid-cloud") { + diagramName := title + if diagramName == "" { + hash := sha256.Sum256(lval) + diagramName = "mermaid-" + hex.EncodeToString(hash[:])[:8] + } + att := attachment.Attachment{ + Name: diagramName, + Filename: diagramName + ".md", + FileBytes: lval, + Replace: diagramName, + } + r.Attachments.Attach(att) + + err := r.Stdlib.Templates.ExecuteTemplate(writer, "ac:mermaid-cloud", ...) +``` + +### 3. `util/flags.go` — Обновлено описание features + +``` +"Enables optional features. Current features: d2, mermaid, mermaid-cloud, mention, mkdocsadmonitions" +``` + +### 4. `renderer/fencedcodeblock_test.go` — Добавлены unit-тесты + +5 тестов покрывающих: +- Диаграмма с `title` → имя из title +- Диаграмма без `title` → хэш-имя +- Несколько безымянных диаграмм → разные имена +- Одинаковое содержимое → одинаковый хэш +- Feature `mermaid` (без `-native`) → не генерирует `mermaid-cloud` + +## Запуск + +```bash +mark --features mermaid-cloud,mention ... +``` + +Или через конфиг: + +```toml +features = ["mermaid-cloud", "mention"] +``` + +## Выполненные работы + +- [x] Сборка и проверка компиляции (`go build ./...`) — ✅ успешно +- [x] Исправлена ошибка компиляции: `err =` → `err :=` в mermaid-cloud ветке +- [x] Запуск существующих тестов (`go test ./...`) — ✅ все проходят (кроме d2/mermaid из-за отсутствия chrome) +- [x] Добавление unit-теста для нового функционала — ✅ 5 тестов в `renderer/fencedcodeblock_test.go` +- [x] Проверка: при `mermaid-cloud` без `title` — генерируется хэш-имя `mermaid-` +- [x] Генерация уникального имени по SHA-256 хэшу содержимого при отсутствии title + +## Остаток работы + +- [ ] Проверка на реальной Confluence странице (ручное тестирование) +- [ ] Рассмотреть: кастомизация параметров макроса (`format`, `zoom`, `toolbar`) через metadata или опции fenced block + +## Риски + +1. ~~**Конфликт имён attachment**~~ — **РЕШЕНО**: при отсутствии `title` генерируется уникальное имя по SHA-256 хэшу содержимого (`mermaid-.md`). Одинаковое содержимое → одинаковый хэш (content-addressable). +2. **Совместимость плагина** — параметры макроса (`format`, `zoom`, `toolbar`) захардкожены. Если нужны другие значения — потребуется расширение (через metadata или опции fenced block). +3. **Порядок feature flags** — `mermaid-cloud` проверяется перед `mermaid`. Если включены оба, `mermaid-cloud` имеет приоритет. Это задуманное поведение. diff --git a/move-in-process.md b/move-in-process.md new file mode 100644 index 00000000..d3dd3035 --- /dev/null +++ b/move-in-process.md @@ -0,0 +1,68 @@ + + + + + +# Процесс заселения в Glorax [07.05.26] + +## 1. Схема процесса + + + +```mermaid +sequenceDiagram + + participant PR as PlanRadar + participant XLS as Excel
Google sheet + participant CRM as Dynamics CRM + participant CC as Колл-центр / ЛК + participant Client as Клиент + participant УК as Управляющая компания + + Note over PR: За 3 месяца до РНВ — Подготовка + PR->>PR: Дефектовка помещений
проектной группой + + Note over XLS, Client: Получение РНВ + + par Клиентский сервис + CRM->>XLS: Формирование реестра + XLS->>CC: Получение реестра жильцов + CC->>Client: Отправка уведомлений почтой России + CC->>Client: СМС-уведомление + CC->>Client: Телефония + end + + Client->>CC: Запись на приёмку (ЛК / колл-центр) + + Note over PR, Client: Приёмка на объекте + + alt Стандартный путь + PR<<->>Client: Акт осмотра (дефекты: текст + фото) + CRM<<->>Client: Акт приёма-передачи (скан) + else Жёсткие сроки — клиент не отвечает + CRM->>Client: Алгоритм «одностороннего акта» + end + + Note over PR, Client: Выдача ключей + CRM->>XLS: Бумажный реестр ключей + Client->>CRM: Подпись клиента + + XLS->>УК: Данные жильцов (Excel) + УК->>УК: Ручной ввод: домофон, паркинг (Domiline) +``` + +## 2. Хранение данных и системы + +| Данные / процесс | Где хранится / ведётся | +|---|---| +| Дефекты, акты осмотра | **PlanRadar** | +| Статусы готовности, АПП, сканы | **CRM Dynamics** | +| История контактов с клиентом (обзвон, СМС) | **Excel / Google Таблицы** (ручной ввод) | \ No newline at end of file diff --git a/move-in-process.md:Zone.Identifier b/move-in-process.md:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xB;\n```\n") + // Use goldmark to parse and render + md := newGoldmarkWithRenderer(renderer) + var buf bytes.Buffer + err = md.Convert(source, &buf) + require.NoError(t, err) + + output := buf.String() + + // Verify mermaid-cloud macro is generated + assert.Contains(t, output, `My Diagram.md`) + assert.Contains(t, output, `svg`) + assert.Contains(t, output, `fit`) + assert.Contains(t, output, `bottom`) + + // Verify attachment was created + require.Len(t, attacher.attachments, 1) + assert.Equal(t, "My Diagram", attacher.attachments[0].Name) + assert.Equal(t, "My Diagram.md", attacher.attachments[0].Filename) + assert.Equal(t, "graph TD;\n A-->B;\n", string(attacher.attachments[0].FileBytes)) +} + +func TestMermaidNative_WithoutTitle(t *testing.T) { + lib, err := stdlib.New(nil) + require.NoError(t, err) + + attacher := &mockAttacher{} + cfg := types.MarkConfig{ + Features: []string{"mermaid-cloud"}, + } + + r := NewConfluenceFencedCodeBlockRenderer(lib, attacher, cfg) + + diagramContent := []byte("graph TD;\n C-->D;\n") + // Compute expected hash + hash := sha256.Sum256(diagramContent) + expectedName := "mermaid-" + hex.EncodeToString(hash[:])[:8] + expectedFilename := expectedName + ".md" + + source := []byte("```mermaid\ngraph TD;\n C-->D;\n```\n") + md := newGoldmarkWithRenderer(r) + var buf bytes.Buffer + err = md.Convert(source, &buf) + require.NoError(t, err) + + output := buf.String() + + // Verify mermaid-cloud macro uses hash-based filename + assert.Contains(t, output, ``+expectedFilename+``) + + // Verify attachment was created with hash-based name + require.Len(t, attacher.attachments, 1) + assert.Equal(t, expectedName, attacher.attachments[0].Name) + assert.Equal(t, expectedFilename, attacher.attachments[0].Filename) +} + +func TestMermaidNative_MultipleUntitled(t *testing.T) { + lib, err := stdlib.New(nil) + require.NoError(t, err) + + attacher := &mockAttacher{} + cfg := types.MarkConfig{ + Features: []string{"mermaid-cloud"}, + } + + r := NewConfluenceFencedCodeBlockRenderer(lib, attacher, cfg) + + // Two different untitled diagrams + source := []byte("```mermaid\ngraph TD;\n A-->B;\n```\n\n```mermaid\ngraph TD;\n C-->D;\n```\n") + md := newGoldmarkWithRenderer(r) + var buf bytes.Buffer + err = md.Convert(source, &buf) + require.NoError(t, err) + + // Verify two attachments were created with different names + require.Len(t, attacher.attachments, 2) + assert.NotEqual(t, attacher.attachments[0].Name, attacher.attachments[1].Name, + "Multiple untitled mermaid diagrams should have unique hash-based names") + assert.NotEqual(t, attacher.attachments[0].Filename, attacher.attachments[1].Filename) + + // Verify both are .md files + assert.True(t, strings.HasSuffix(attacher.attachments[0].Filename, ".md")) + assert.True(t, strings.HasSuffix(attacher.attachments[1].Filename, ".md")) +} + +func TestMermaidNative_SameContentSameHash(t *testing.T) { + lib, err := stdlib.New(nil) + require.NoError(t, err) + + attacher := &mockAttacher{} + cfg := types.MarkConfig{ + Features: []string{"mermaid-cloud"}, + } + + r := NewConfluenceFencedCodeBlockRenderer(lib, attacher, cfg) + + // Two identical untitled diagrams should produce the same hash + source := []byte("```mermaid\ngraph TD;\n A-->B;\n```\n\n```mermaid\ngraph TD;\n A-->B;\n```\n") + md := newGoldmarkWithRenderer(r) + var buf bytes.Buffer + err = md.Convert(source, &buf) + require.NoError(t, err) + + // Same content = same hash = same name (content-addressable) + require.Len(t, attacher.attachments, 2) + assert.Equal(t, attacher.attachments[0].Name, attacher.attachments[1].Name, + "Identical untitled mermaid diagrams should produce the same hash-based name") +} + +func TestMermaidNative_NotActiveWhenFeatureDisabled(t *testing.T) { + lib, err := stdlib.New(nil) + require.NoError(t, err) + + attacher := &mockAttacher{} + // Only "mermaid" feature, NOT "mermaid-cloud" + cfg := types.MarkConfig{ + Features: []string{"mermaid"}, + } + + r := NewConfluenceFencedCodeBlockRenderer(lib, attacher, cfg) + + source := []byte("```mermaid\ngraph TD;\n A-->B;\n```\n") + md := newGoldmarkWithRenderer(r) + var buf bytes.Buffer + // This will fail because mermaid.ProcessMermaidLocally requires chrome, + // but the key point is that it does NOT produce mermaid-cloud macro + err = md.Convert(source, &buf) + + // If chrome is not available, the mermaid branch will error. + // But we should NOT see mermaid-cloud in the output + if err == nil { + assert.NotContains(t, buf.String(), `ac:name="mermaid-cloud"`, + "mermaid-cloud macro should NOT be generated when mermaid-cloud feature is disabled") + } +} \ No newline at end of file diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index f5bdf467..2e7b4a16 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -440,6 +440,17 @@ func templates(api *confluence.API) (*template.Template, error) { ``, ), + /* Mermaid Diagrams for Confluence (mermaid-cloud macro) */ + /* Uses attachment filename to reference the diagram source */ + `ac:mermaid-cloud`: text( + ``, + `{{ .Filename | xmlesc }}`, + `{{ or .Format "text/plain" }}`, + `{{ or .Zoom "fit" }}`, + `{{ or .Toolbar "bottom" }}`, + ``, + ), + // TODO(seletskiy): more templates here } { templates, err = templates.New(name).Parse(body) diff --git a/util/flags.go b/util/flags.go index ad7e0b9c..0a3941af 100644 --- a/util/flags.go +++ b/util/flags.go @@ -210,7 +210,7 @@ var Flags = []cli.Flag{ &cli.StringSliceFlag{ Name: "features", Value: []string{"mermaid", "mention"}, - Usage: "Enables optional features. Current features: d2, mermaid, mention, mkdocsadmonitions", + Usage: "Enables optional features. Current features: d2, mermaid, mermaid-cloud, mention, mkdocsadmonitions", Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FEATURES"), altsrctoml.TOML("features", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ From 040f18495f467a3f4711b90adc1aa79d0120cd93 Mon Sep 17 00:00:00 2001 From: Vladimir Shabalin Date: Mon, 29 Jun 2026 17:25:16 +0300 Subject: [PATCH 2/4] Delete move-in-process.md:Zone.Identifier --- move-in-process.md:Zone.Identifier | Bin 25 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 move-in-process.md:Zone.Identifier diff --git a/move-in-process.md:Zone.Identifier b/move-in-process.md:Zone.Identifier deleted file mode 100644 index d6c1ec682968c796b9f5e9e080cc6f674b57c766..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2x Date: Mon, 29 Jun 2026 17:26:12 +0300 Subject: [PATCH 3/4] clean up --- ADR/001-mermaid-native-confluence-macro.md | 154 --------------------- move-in-process.md | 68 --------- 2 files changed, 222 deletions(-) delete mode 100644 ADR/001-mermaid-native-confluence-macro.md delete mode 100644 move-in-process.md diff --git a/ADR/001-mermaid-native-confluence-macro.md b/ADR/001-mermaid-native-confluence-macro.md deleted file mode 100644 index 10d22d2a..00000000 --- a/ADR/001-mermaid-native-confluence-macro.md +++ /dev/null @@ -1,154 +0,0 @@ -# ADR-001: Нативная поддержка Mermaid диаграмм через плагин Mermaid Diagrams for Confluence - -**Статус:** Реализовано - -**Дата:** 2025-05-07 - -## Контекст - -В текущей реализации mark (fork kovetskiy/mark) mermaid-диаграммы обрабатываются следующим образом: -1. Парсер обнаруживает fenced code block с языком `mermaid` -2. Вызывается `mermaid.ProcessMermaidLocally()` — локальный рендеринг в PNG через библиотеку `mermaid.go` -3. PNG загружается как attachment на страницу Confluence -4. В тело страницы вставляется тег `` с ссылкой на attachment - -**Проблема:** На нашем Confluence установлен плагин **Mermaid Diagrams for Confluence** (макрос `mermaid-cloud`), который поддерживает нативное отображение mermaid-диаграмм (интерактивность, SVG, масштабирование). Локальный рендеринг в PNG не использует эти возможности. - -## Исследование - -### Как работает плагин mermaid-cloud - -Из анализа API Confluence (страница "Enterprise Service Bus и Data LakeHouse [Current State]"): - -```xml - - bottom - Current State - svg - fit - 2 - -``` - -**Ключевое ограничение:** Плагин НЕ поддерживает inline-диаграммы через ``. Диаграмма должна быть загружена как **attachment-файл** (параметр `filename` указывает имя attachment). - -### Анализ возможности использования Custom Macro - -Custom macros (определяемые через HTML-комментарии ``) выполняют только текстовую замену в markdown. Они **не могут** загружать attachment-файлы через API. Поэтому чистый Custom Macro подход невозможен — требуется изменение кода mark. - -## Решение - -Добавить новый feature flag `mermaid-cloud`, который при включении: -1. Берёт **сырой текст** mermaid-диаграммы из fenced code block -2. Создаёт attachment-файл `.md` с текстом диаграммы -3. Загружает его на страницу через существующий механизм attachment -4. Генерирует XML макроса `mermaid-cloud` с `filename` → имя attachment - -### Использование в markdown - -```markdown -```mermaid title My Diagram -graph TD; - A-->B; - B-->C; -``` -``` - -### Результат на Confluence - -1. Загружен attachment `My Diagram.md` с текстом диаграммы -2. В тело страницы вставлен макрос: - -```xml - - My Diagram.md - svg - fit - bottom - -``` - -## Внесённые изменения - -### 1. `stdlib/stdlib.go` — Добавлен шаблон `ac:mermaid-cloud` - -```go -`ac:mermaid-cloud`: text( - ``, - `{{ .Filename | xmlesc }}`, - `{{ or .Format "svg" }}`, - `{{ or .Zoom "fit" }}`, - `{{ or .Toolbar "bottom" }}`, - ``, -), -``` - -### 2. `renderer/fencedcodeblock.go` — Добавлена ветка для `mermaid-cloud` - -Новая ветка **перед** существующей `mermaid` веткой (приоритет mermaid-cloud > mermaid). -При отсутствии `title` генерируется уникальное имя по SHA-256 хэшу содержимого (первые 8 символов): - -```go -} else if lang == "mermaid" && slices.Contains(r.MarkConfig.Features, "mermaid-cloud") { - diagramName := title - if diagramName == "" { - hash := sha256.Sum256(lval) - diagramName = "mermaid-" + hex.EncodeToString(hash[:])[:8] - } - att := attachment.Attachment{ - Name: diagramName, - Filename: diagramName + ".md", - FileBytes: lval, - Replace: diagramName, - } - r.Attachments.Attach(att) - - err := r.Stdlib.Templates.ExecuteTemplate(writer, "ac:mermaid-cloud", ...) -``` - -### 3. `util/flags.go` — Обновлено описание features - -``` -"Enables optional features. Current features: d2, mermaid, mermaid-cloud, mention, mkdocsadmonitions" -``` - -### 4. `renderer/fencedcodeblock_test.go` — Добавлены unit-тесты - -5 тестов покрывающих: -- Диаграмма с `title` → имя из title -- Диаграмма без `title` → хэш-имя -- Несколько безымянных диаграмм → разные имена -- Одинаковое содержимое → одинаковый хэш -- Feature `mermaid` (без `-native`) → не генерирует `mermaid-cloud` - -## Запуск - -```bash -mark --features mermaid-cloud,mention ... -``` - -Или через конфиг: - -```toml -features = ["mermaid-cloud", "mention"] -``` - -## Выполненные работы - -- [x] Сборка и проверка компиляции (`go build ./...`) — ✅ успешно -- [x] Исправлена ошибка компиляции: `err =` → `err :=` в mermaid-cloud ветке -- [x] Запуск существующих тестов (`go test ./...`) — ✅ все проходят (кроме d2/mermaid из-за отсутствия chrome) -- [x] Добавление unit-теста для нового функционала — ✅ 5 тестов в `renderer/fencedcodeblock_test.go` -- [x] Проверка: при `mermaid-cloud` без `title` — генерируется хэш-имя `mermaid-` -- [x] Генерация уникального имени по SHA-256 хэшу содержимого при отсутствии title - -## Остаток работы - -- [ ] Проверка на реальной Confluence странице (ручное тестирование) -- [ ] Рассмотреть: кастомизация параметров макроса (`format`, `zoom`, `toolbar`) через metadata или опции fenced block - -## Риски - -1. ~~**Конфликт имён attachment**~~ — **РЕШЕНО**: при отсутствии `title` генерируется уникальное имя по SHA-256 хэшу содержимого (`mermaid-.md`). Одинаковое содержимое → одинаковый хэш (content-addressable). -2. **Совместимость плагина** — параметры макроса (`format`, `zoom`, `toolbar`) захардкожены. Если нужны другие значения — потребуется расширение (через metadata или опции fenced block). -3. **Порядок feature flags** — `mermaid-cloud` проверяется перед `mermaid`. Если включены оба, `mermaid-cloud` имеет приоритет. Это задуманное поведение. diff --git a/move-in-process.md b/move-in-process.md deleted file mode 100644 index d3dd3035..00000000 --- a/move-in-process.md +++ /dev/null @@ -1,68 +0,0 @@ - - - - - -# Процесс заселения в Glorax [07.05.26] - -## 1. Схема процесса - - - -```mermaid -sequenceDiagram - - participant PR as PlanRadar - participant XLS as Excel
Google sheet - participant CRM as Dynamics CRM - participant CC as Колл-центр / ЛК - participant Client as Клиент - participant УК as Управляющая компания - - Note over PR: За 3 месяца до РНВ — Подготовка - PR->>PR: Дефектовка помещений
проектной группой - - Note over XLS, Client: Получение РНВ - - par Клиентский сервис - CRM->>XLS: Формирование реестра - XLS->>CC: Получение реестра жильцов - CC->>Client: Отправка уведомлений почтой России - CC->>Client: СМС-уведомление - CC->>Client: Телефония - end - - Client->>CC: Запись на приёмку (ЛК / колл-центр) - - Note over PR, Client: Приёмка на объекте - - alt Стандартный путь - PR<<->>Client: Акт осмотра (дефекты: текст + фото) - CRM<<->>Client: Акт приёма-передачи (скан) - else Жёсткие сроки — клиент не отвечает - CRM->>Client: Алгоритм «одностороннего акта» - end - - Note over PR, Client: Выдача ключей - CRM->>XLS: Бумажный реестр ключей - Client->>CRM: Подпись клиента - - XLS->>УК: Данные жильцов (Excel) - УК->>УК: Ручной ввод: домофон, паркинг (Domiline) -``` - -## 2. Хранение данных и системы - -| Данные / процесс | Где хранится / ведётся | -|---|---| -| Дефекты, акты осмотра | **PlanRadar** | -| Статусы готовности, АПП, сканы | **CRM Dynamics** | -| История контактов с клиентом (обзвон, СМС) | **Excel / Google Таблицы** (ручной ввод) | \ No newline at end of file From 345fed0429aee1bdb58e59337b53c5c8281be5a6 Mon Sep 17 00:00:00 2001 From: Vladimir Shabalin Date: Mon, 29 Jun 2026 17:48:23 +0300 Subject: [PATCH 4/4] fix --- README.md | 5 +++++ stdlib/stdlib.go | 3 +++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index a732485a..dc1bb450 100644 --- a/README.md +++ b/README.md @@ -782,6 +782,11 @@ graph TD; A-->B; ``` +#### Render Mermaid Diagram in browser +Optionally you can enable mermaid diagram storing as text content and rendering in browser via `--features="mermaid-cloud"`. + +But this requires the [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226567/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview) macro to be installed in your Confluence instance. + ### Render D2 Diagram Optionally you can enable [D2](https://github.com/terrastruct/d2) rendering via `--features="d2"`. diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index 90366470..d4e52920 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -448,6 +448,9 @@ func templates(api *confluence.API) (*template.Template, error) { `{{ or .Format "text/plain" }}`, `{{ or .Zoom "fit" }}`, `{{ or .Toolbar "bottom" }}`, + `
`, + ), + `ac:plantuml`: text( ``, ``,