92c0a9a4a9
Раньше препроцессинг сканировал файл ДВАЖДЫ: index_lines считал точки переноса (forward-сканеры scan_join_stream/inline_scan), а отдельный render_line_to_cache заново сканировал каждый сегмент для сборки (char,attr)-ячеек. Профилирование показало, что всё время — в этих двух посимвольных проходах (bank I/O и cont-walk ≈ 0). Теперь forward-сканер собирает ячейки в g_cells ПО ХОДУ единственного прохода; emit_seg флашит ячейки предыдущего сегмента в кэш (lag-1), последний — после цикла. Перенос строки усекает буфер до снимка на последнем пробеле (g_ncells_at_space), continuation-сегменты получают префикс (отступ списка / маркер цитаты 0xB3 / title только в 1-й строке заголовка). Прямые типы (код verbatim, HR, таблица через nowrap-inline, blank/fence) строят ячейки на месте. Миграция шла по типам блоков с dual-verify (старый render строил эталон, merge сверял ячейки) — найдены и согласованы расхождения forward-сканера со старым рендером: backtick внутри эмфазиса = литерал; одиночный маркер закрывает ЛЮБОЙ активный эмфазис; soft-join пропускает ведущие пробелы строки-продолжения; хвостовые пробелы нерелевантны. Все типы дали 0 расхождений, после чего render_line_to_cache / cc_put / cc_fill / handle_inline_marker и verify-каркас удалены (−185 строк). Итог на 52КБ README: 22→11с (2×). Совокупно с прошлым коммитом 24→11с. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>