mdview2: фоновая сборка второго набора кодировки в паузах между клавишами; версия v1.0 (b3)

- индексатор порезан на резюмируемые шаги index_begin/index_step/index_finish;
  межшаговое состояние в статиках модуля, в docset_t не входит
- bg_build_start/bg_step: второй набор (UTF-8 при 8-битном первичном и
  наоборот) строится в idle главного цикла; холдаун после клавиш, спиннер
  погашен (g_bg_building) — фон незаметен
- F8 до готовности докручивает начатое фоном (ветка resume в build_doc),
  а не строит заново; общий setup вынесен в doc_setup
- кодировка в статус-баре показывается сразу (детект/F8), не дожидаясь
  конца индексации
- побочный фикс: UTF-конвертация впереди проверки останова — >4КБ абзац
  больше не обрывает конвертацию остатка
- README.md (новый, v1.0 b3), CHANGELOG.md; дискета: README/DEMO/CHANGES
  в трёх кодировках (пути автодетекта)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-05 19:33:34 +03:00
parent ae23d2dea2
commit 46553f4e07
8 changed files with 484 additions and 89 deletions
+153
View File
@@ -0,0 +1,153 @@
# MDView v1.0 (b3) — просмотрщик Markdown для Sprinter
**MDView** — программа просмотра документов Markdown для компьютера
**Sprinter-2000** (Z80, ОС ESTEX). Файл загружается в расширенную память (EMM)
и один раз «прогоняется» через парсер: готовые к показу строки (пары
символ+атрибут) складываются в **рендер-кэш** в EMM, после чего прокрутка в
любую сторону — это просто копирование готовых строк на экран, без повторного
парсинга. Даже на файлах в сотни килобайт листание остаётся мгновенным.
Текстовый режим 80×32, цветное оформление элементов разметки, три режима
просмотра (MD / RAW / HEX) и четыре кодировки с автоопределением.
---
## Возможности
* **Markdown-рендеринг** с цветовым оформлением:
* заголовки `#``######` (H5/H6 отображаются как H4);
* **жирный** (`**текст**`), *курсив* (`*текст*`), подчёркнутый (`_текст_`),
~~зачёркнутый~~ (`~~текст~~`), `встроенный код` (`` `текст` ``);
* экранирование `\*`, `\_`, `` \` `` и любой ASCII-пунктуации;
* чекбоксы `[x]` / `[ ]` в списках;
* ненумерованные (`-`, `*`, `+`) и нумерованные (`1.`, `1)`) списки
с базовой вложенностью по отступам;
* цитаты `>` (склейка многострочных, маркер │ на переносах);
* fenced-блоки кода ` ``` ` (без переносов, горизонтальный скролл);
* таблицы `| … | … |` — рисуются псевдографической рамкой, ширины колонок
вычисляются по содержимому (до 16 колонок);
* горизонтальные разделители `---` / `***` / `___`;
* жёсткие переносы (два пробела или `\` в конце строки);
* мягкая склейка абзацев с переносом по словам под ширину экрана.
* **Кодировки: CP866, CP1251, KOI8-R, UTF-8.**
* автоопределение при открытии (BOM → UTF-8; валидность multibyte-структуры;
частотный анализ ходовых русских букв для 8-битных);
* переключение по кругу клавишей **F8** в любой момент;
* 8-битные кодировки отличаются только перекодировкой глифов на отрисовке —
переключение мгновенно;
* UTF-8 декодируется в CP866 в **отдельный набор** (файл + индекс + кэш);
второй набор готовится **в фоне**, пока вы читаете документ, — обычно
к первому нажатию F8 он уже построен и переключение мгновенно,
с сохранением позиции. Если фон не успел, F8 докручивает начатую
сборку (со спиннером), а не начинает её заново.
* **Три режима просмотра:**
* **MD** — форматированный Markdown (по умолчанию);
* **RAW** (**F2**) — исходный текст без разметки: перенос строк кратно 80
(**F3** — режим панорамы с горизонтальным скроллом);
* **HEX** (**F4**) — дамп *оригинального* файла:
`0x012340 │ 16 байт hex │ 16 печатных символов`. Печатная колонка
интерпретируется текущей кодировкой; для UTF-8 глиф ставится на позиции
лид-байта, continuation-байты показываются точкой.
* **Единая позиция** при любых переключениях: MD ↔ RAW ↔ HEX и смена
кодировки сохраняют текущее место в документе (между наборами разного
размера — пропорционально, с точностью до строки).
* **Прогрессивная загрузка**: первый экран показывается сразу, индексация
продолжается в фоне; по готовой части документа уже можно листать,
**Esc**/**F10** прерывают загрузку.
* **Фоновая работа незаметна**: второй набор кодировки строится только в
паузах между клавишами (после нажатия выдерживается пауза), поэтому
скролл — в том числе с автоповтором — не теряет плавности.
---
## Запуск
```
MDVIEW2.EXE <файл.md>
```
Без аргумента открывается `README.MD` из текущего каталога.
## Клавиши
| Клавиша | Действие |
|--------------|-------------------------------------------------------------|
| ↑ / ↓ | прокрутка на одну строку |
| PgUp / PgDn | прокрутка на экран (30 строк) |
| Home / End | в начало / в конец документа |
| ← / → | горизонтальный сдвиг: код/таблицы в MD, панорама в RAW |
| F1 | справка |
| F2 | RAW-режим ↔ MD |
| F3 | в RAW: перенос строк ↔ панорама |
| F4 | HEX-режим ↔ прежний вид |
| F8 | кодировка: CP866 → CP1251 → KOI8-R → UTF-8 → … |
| Esc / F10 | выход (во время загрузки — прервать её) |
Статус-бар (верхняя строка): имя файла, кодировка, диапазон видимых строк
и процент прокрутки. Нижняя строка — меню доступных F-клавиш.
---
## Ограничения
| Параметр | Значение |
|---------------------------------|-------------------------------------------|
| Размер файла | до 256 КБ (больший — обрезается с предупреждением) |
| Логических строк (после переносов) | до 18 432 |
| Длина строки в рендер-кэше | 255 ячеек (RAW/HEX ограничения не имеют) |
| Колонок в таблице | до 16 |
| Шаг табуляции | 4 |
При исчерпании любого лимита документ завершается строкой-сообщением
с указанием причины обрыва; всё, что вошло, доступно для просмотра.
## Требования
* Sprinter-2000 с ОС ESTEX;
* расширенная память (EMM): в худшем случае (файл 256 КБ + оба набора
кодировок) — до ~150 страниц по 16 КБ (~2,4 МБ). Для типичных файлов
в десятки килобайт достаточно нескольких десятков страниц.
Код, данные, стек и куча программы занимают окна W1+W2 (32 КБ, режим
памяти `small`); окно W3 используется только для доступа к EMM-страницам.
---
## Сборка
Требуется тулчейн этого репозитория (обёртка `sprinter-cc` над SDCC 4.5).
Из каталога `examples/mdview2`:
```
make # собрать mdview2.exe
make floppy # собрать и упаковать дискету для MAME (mc.img)
make run # floppy + запуск MAME
```
На дискету кладутся: `MDVIEW2.EXE` и три документа, каждый в своей кодировке
(заодно покрывают все пути автодетекта): `README.MD` — этот файл, как есть
(UTF-8); `DEMO.MD` — демонстрация всех элементов разметки (CP1251);
`CHANGES.MD` — история версий (CP866).
## Структура исходников
| Файл | Назначение |
|------------------|--------------------------------------------------------------|
| `mdview2.c` | ядро: EMM-аллокации, рендер-кэш, наборы кодировок, загрузка файла, главный цикл |
| `mdview2_index.c`| парсер/индексатор Markdown — единственный проход по файлу |
| `mdview2_md.c` | MD-вид: отрисовка из кэша, прокрутка |
| `mdview2_raw.c` | RAW-вид (F2/F3) |
| `mdview2_hex.c` | HEX-вид (F4) |
| `mdview2_enc.c` | кодировки: детект, ремап-таблицы, конвертер UTF-8 → CP866 |
| `mdview2_table.c`| отрисовка таблиц |
| `mdview2_status.c`| статус-бар, меню, спиннер |
| `mdview2_help.c` | справка (F1) |
| `mdview2_conf.h` | конфигурация: `WITH_RAW` / `WITH_HEX` (модули отключаемы) |
| `mdview2.h` | общие константы, атрибуты, межмодульный API |
Подробности архитектуры — в `docs/mdview2-plan.md`.
## Лицензия и авторы
© 2026 Петров А.Г. Часть проекта Sprinter C Compiler
(см. LICENSE в корне репозитория).