# Откуда брать отрисовку Markdown Готовый рендер Markdown для Compose уже написан и лежит в репозитории **`ai/assistent`**. Писать своё не надо — надо взять это. **Репозиторий:** https://git.binom.pw/ai/assistent (ветка `main`) **Проверено на коммите:** `2c5b3f9` (файлы добавлены в `1acced4`, 2026-08-13) **Важно:** репозиторий приватный. Браузерная ссылка откроется только у залогиненного; для копирования файлов из скрипта — RAW-адреса с логином/паролем (ниже). --- ## Что именно копировать: 4 файла Всё лежит в двух модулях. Модуль `client-shared` — общий, собирается под **JVM + Compose** (то есть ровно наш случай, десктоп), не под Android. ### 1. Модель данных — `MarkdownSegment.kt` (59 строк) ``` client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt ``` Что внутри: типы кусков разметки — текст, блок кода, таблица, картинка, разделитель. Плюс описание стилевого участка: жирный, курсив, код, зачёркнутый, ссылка. Зависимостей от Compose нет вообще — чистые данные. ### 2. Парсер — `MarkdownParserImpl.kt` (353 строки) ``` client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt ``` Точка входа: `parseMarkdown(markdown: String): List`. Единственная внешняя зависимость — библиотека парсера `ru.otpbank.ai:markdown` (см. ниже). От Композа не зависит. ### 3. Отрисовка — `MarkdownRendering.kt` (377 строк) ``` client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt ``` Точка входа: `renderMarkdownSegments(content, textColor, fontSize, isBubbleScrolled, onUrlClick)`. Внутри: текст с inline-стилями, кликабельные ссылки, блоки кода с копированием, таблицы, картинки, разделители. Самый жирный файл и самая нужная часть. ### 4. Десктопная обёртка — `MarkdownRenderer.kt` (25 строк) ``` client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt ``` Открытие ссылок в системном браузере (`Desktop.getDesktop().browse`) и `parseMultiline`. Модуль `client` в assistent — это **десктопный** клиент на Compose Desktop, так что пример использования ровно наш. --- ## Что копировать НЕ надо - `client-shared/src/main/kotlin/pw/binom/client/shared/ui/MessageBubble.kt` (789 строк) — пузырь сообщения целиком. Тянет за собой модуль `chat-common` (модели сообщений), из плюшек — выделение текста и контекстное меню. Для отрисовки разметки не нужен, но полезен, если понадобится пример. --- ## Зависимости Одна, и она есть в нашем Nexus: ```kotlin implementation("ru.otpbank.ai:markdown:0.51.0") ``` Репозиторий в `build.gradle.kts` (без него не соберётся): ```kotlin maven { url = uri("http://192.168.76.117/repository/developerspace-prod-mvn-hosted/") isAllowInsecureProtocol = true } ``` Проверено: в Nexus лежит, версии с `0.1.0` по `0.51.0`, файл `markdown-0.51.0.pom` отдаёт `HTTP 200`. Из Compose нужны: `compose.material3`, `compose.foundation`, `compose.ui`, `compose.materialIconsExtended` (иконка копирования в блоках кода). ## Опубликован ли `client-shared` как библиотека **Нет.** Проверено поиском в Nexus (`pw/binom/client-shared`, `pw/binom/chat-common`) — `HTTP 404`. Поэтому вариантов два: либо копируем исходники к себе (4 файла выше), либо сперва публикуем модуль. Копирование проще. --- ## Как копировать (RAW-адреса, работают с логином) Адрес вида `/raw/branch/main/<путь>` отдаёт файл. Проверено: `HTTP 200`, 1805 байт — совпадает с локальным размером. ```bash BASE=https://git.binom.pw/ai/assistent/raw/branch/main AUTH='subochev:ПАРОЛЬ' # подставить перед запуском for f in \ client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt \ client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt \ client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt \ client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt ; do curl -sS -u "$AUTH" "$BASE/$f" -o "$(basename "$f")" done ``` Браузерные ссылки для чтения глазами (нужен залогиненный git.binom.pw): ``` https://git.binom.pw/ai/assistent/src/branch/main/client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt https://git.binom.pw/ai/assistent/src/branch/main/client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt https://git.binom.pw/ai/assistent/src/branch/main/client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt https://git.binom.pw/ai/assistent/src/branch/main/client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt ``` --- ## Что придётся поправить после копирования 1. **Пакеты.** Файлы лежат в `pw.binom.client.shared.*` — переименовать под наш проект (или оставить как есть, если не смущает). 2. **`openUrl`.** В `MarkdownRenderer` открытие ссылок идёт через `java.awt.Desktop` — на десктопе это работает, ничего менять не надо. 3. **Стиль.** Цвета текста и блоков кода в `MarkdownRendering` берутся из аргументов и `MaterialTheme` — под нашу тёмную тему подставить свои значения. ## Что этот рендер умеет (по коду) - **Текст** с участками: жирный, курсив, код, зачёркнутый, ссылки. - **Блоки кода** — с названием языка и кнопкой копирования. - **Таблицы** — заголовки и строки, с горизонтальной прокруткой. - **Картинки** — `data:`-ссылки и обычные `http(s)`. Первые рисуются сразу из памяти. - **Разделители** (`---`). - **Кликабельные ссылки** — нажатие уходит в `onUrlClick`, оттуда открываем браузер.