Обзор функций: магия автоматического форматирования
Что вы узнаете
- О 8 ключевых функциях плагина
- В каких сценариях подходит этот плагин
- Границы возможностей плагина (что он не может делать)
Ваша текущая проблема
Информация о плагине
Полное название плагина — @franlol/opencode-md-table-formatter, далее — "плагин форматирования таблиц".
Markdown-таблицы, созданные AI, часто выглядят так:
| 名称 | 描述 | 状态 |
|--- | --- | ---|
| **用户管理** | 管理系统用户 | ✅ 完成 |
| API | 接口文档 | 🚧 进行中 |Ширина столбцов неравномерна, выглядит некрасиво. Настраивать вручную? Каждый раз, когда AI создаёт новую таблицу, нужно настраивать заново — слишком утомительно.
Когда использовать этот метод
- AI создал Markdown-таблицу, и вы хотите сделать её аккуратнее
- Вы включили режим скрытия (Concealment Mode) в OpenCode, и выравнивание таблиц постоянно ломается
- Вам лень вручную настраивать ширину столбцов таблиц
Основная идея
Принцип работы плагина прост:
AI генерирует текст → Плагин обнаруживает таблицу → Проверяет структуру → Форматирует → Возвращает улучшенный текстПлагин подключается к хуку experimental.text.complete в OpenCode. Каждый раз, когда AI завершает генерацию текста, плагин автоматически обрабатывает его. Вам не нужно запускать вручную — всё происходит незаметно.
8 ключевых функций
1. Автоматическое форматирование таблиц
Плагин автоматически обнаруживает Markdown-таблицы в тексте, созданном AI, выравнивает ширину столбцов, делая таблицы аккуратными и красивыми.
До форматирования:
| 名称 | 描述 | 状态 |
|--- | --- | ---|
| **用户管理** | 管理系统用户 | ✅ 完成 |
| API | 接口文档 | 🚧 进行中 |После форматирования:
| 名称 | 描述 | 状态 |
|--- | --- | ---|
| **用户管理** | 管理系统用户 | ✅ 完成 |
| API | 接口文档 | 🚧 进行中 |Условие запуска
Плагин подключён к хуку experimental.text.complete и автоматически запускается после завершения генерации текста AI, ручное действие не требуется.
2. Совместимость с режимом скрытия
OpenCode по умолчанию включает режим скрытия (Concealment Mode), который скрывает Markdown-символы (например, **, *, ~~).
Обычные инструменты форматирования таблиц не учитывают это, при расчёте ширины они учитывают и **, что приводит к неправильному выравниванию.
Этот плагин специально оптимизирован для режима скрытия:
- При расчёте ширины удаляются символы
**жирный**,*курсив*,~~зачёркнутый~~и другие - При выводе сохраняется исходный Markdown-синтаксис
- Итоговый эффект: таблицы идеально выравнены в режиме скрытия
Технические детали: логика расчёта ширины
// Удаление Markdown-символов (для расчёта ширины)
visualText = visualText
.replace(/\*\*\*(.+?)\*\*\*/g, "$1") // ***жирный курсив*** → текст
.replace(/\*\*(.+?)\*\*/g, "$1") // **жирный** → жирный
.replace(/\*(.+?)\*/g, "$1") // *курсив* → курсив
.replace(/~~(.+?)~~/g, "$1") // ~~зачёркнутый~~ → зачёркнутыйРасположение в исходном коде: index.ts:181-185
3. Поддержка выравнивания
Поддерживаются три способа выравнивания Markdown-таблиц:
| Синтаксис | Выравнивание | Эффект |
|---|---|---|
--- или :--- | По левому краю | Текст слева (оба синтаксиса дают одинаковый эффект) |
:---: | По центру | Текст по центру |
---: | По правому краю | Текст справа |
Пример:
| По левому краю | По центру | По правому краю |
|--- | --- | ---|
| Текст | Текст | Текст |После форматирования каждый столбец будет выровнен указанным способом, строка-разделитель будет пересоздана в соответствии с выравниванием.
4. Обработка вложенного Markdown
В ячейках таблицы может быть вложенный Markdown-синтаксис, например ***жирный курсив***.
Плагин использует многоэтапный алгоритм регулярных выражений, поэтапно удаляя символы снаружи внутрь:
***жирный курсив*** → **жирный курсив** → *жирный курсив* → жирный курсивТаким образом, даже при многоуровневом вложении расчёт ширины остаётся точным.
5. Защита кода
Markdown-символы в строковом коде (обёрнутом обратными кавычками) должны оставаться без изменений, не удаляться.
Например, `**bold**` — пользователь видит 8 символов **bold**, а не 4 символа bold.
Плагин сначала извлекает содержимое кода, удаляет Markdown-символы из других частей, затем возвращает содержимое кода обратно.
Технические детали: логика защиты кода
// Шаг 1: извлечение и защита строкового кода
const codeBlocks: string[] = []
let textWithPlaceholders = text.replace(/`(.+?)`/g, (match, content) => {
codeBlocks.push(content)
return `\x00CODE${codeBlocks.length - 1}\x00`
})
// Шаг 2: удаление Markdown-символов из некодовых частей
// ...
// Шаг 3: восстановление содержимого строкового кода
visualText = visualText.replace(/\x00CODE(\d+)\x00/g, (match, index) => {
return codeBlocks[parseInt(index)]
})Расположение в исходном коде: index.ts:168-193
6. Обработка граничных случаев
Плагин корректно обрабатывает различные граничные случаи:
| Сценарий | Способ обработки |
|---|---|
| Emoji-эмодзи | Использует Bun.stringWidth для правильного расчёта ширины отображения |
| Unicode-символы | Китайские, японские и другие моноширинные символы выравниваются корректно |
| Пустые ячейки | Заполняются пробелами до минимальной ширины (3 символа) |
| Слишком длинное содержимое | Обрабатывается нормально, не обрезается |
7. Тихая работа
Плагин работает тихо в фоновом режиме:
- Без вывода логов: не выводит никакой информации в консоль
- Ошибки не прерывают: даже если форматирование не удалось, это не влияет на нормальный вывод AI
Если во время форматирования происходит ошибка, плагин сохраняет исходный текст и добавляет в конце HTML-комментарий:
<!-- table formatting failed: [информация об ошибке] -->8. Проверка и обратная связь
Плагин проверяет, является ли структура таблицы допустимой. Недопустимые таблицы не форматируются, а сохраняются как есть с добавлением подсказки:
<!-- table not formatted: invalid structure -->Требования к допустимой таблице:
- Минимум 2 строки (включая строку-разделитель)
- Количество столбцов во всех строках одинаковое
- Обязательна строка-разделитель (формат:
|---|---|)
Границы плагина
Неподдерживаемые сценарии
- HTML-таблицы: обрабатываются только Markdown-таблицы с каналами (
| ... |) - Многострочные ячейки: ячейки с тегом
<br>не поддерживаются - Таблицы без разделителя: обязательна строка-разделитель
|---|---| - Таблицы без заголовка: обязательна строка заголовка
Контрольные точки
После завершения этого урока вы должны уметь ответить:
- [ ] Как плагин запускается автоматически? (Ответ: хук
experimental.text.complete) - [ ] Зачем нужна "совместимость с режимом скрытия"? (Ответ: режим скрытия скрывает Markdown-символы, что влияет на расчёт ширины)
- [ ] Удаляются ли Markdown-символы в строковом коде? (Ответ: нет, Markdown-символы внутри кода полностью сохраняются)
- [ ] Как обрабатываются недопустимые таблицы? (Ответ: сохраняются как есть, добавляется комментарий об ошибке)
Итог урока
| Функция | Описание |
|---|---|
| Автоматическое форматирование | Автоматически запускается после генерации текста AI, ручное действие не требуется |
| Совместимость с режимом скрытия | Правильный расчёт ширины отображения после скрытия Markdown-символов |
| Поддержка выравнивания | По левому краю, по центру, по правому краю |
| Вложенный Markdown | Многоэтапное удаление регулярными выражениями, поддержка вложенного синтаксиса |
| Защита кода | Символы в строковом коде остаются без изменений |
| Граничные случаи | Emoji, Unicode, пустые ячейки, слишком длинное содержимое |
| Тихая работа | Без логов, ошибки не прерывают |
| Проверка и обратная связь | Недопустимые таблицы получают комментарий об ошибке |
Предварительный обзор следующего урока
В следующем уроке мы углубимся в принцип работы режима скрытия.
Вы узнаете:
- Как работает режим скрытия в OpenCode
- Как плагин правильно рассчитывает ширину отображения
- Роль
Bun.stringWidth
Приложение: ссылки на исходный код
Нажмите, чтобы раскрыть расположение исходного кода
Время обновления: 2026-01-26
| Функция | Путь к файлу | Номер строки |
|---|---|---|
| Точка входа плагина | index.ts | 9-23 |
| Обнаружение таблиц | index.ts | 58-61 |
| Проверка таблиц | index.ts | 70-88 |
| Расчёт ширины (режим скрытия) | index.ts | 161-196 |
| Парсинг выравнивания | index.ts | 141-149 |
| Защита кода | index.ts | 168-173 |
Ключевые константы:
colWidths[col] = 3:минимальная ширина столбца — 3 символа (index.ts:115)
Ключевые функции:
formatMarkdownTables():основная функция обработки, форматирует все таблицы в текстеgetStringWidth():рассчитывает ширину отображения строки, удаляет Markdown-символыisValidTable():проверяет, является ли структура таблицы допустимой