Пару лет назад я презентовал на Хабре первую концепцию полнофункциональной текстовой разметки Маркван. Которая позволяет создавать достаточно сложные художественные и технические тексты, а заодно и генерировать статические сайты.
За это время накопилось несколько замечаний, которые необходимо было быстренько поправить. Изначально я планировал уделить проекту всего пару недель. Но, как это часто бывает в разработке, незаметно испарились три месяца. Много времени ушло на перепродумывание самой спецификации и на реализацию нового конвертера. Зато теперь Маркван превратился в строгую, логичную и предсказуемую экосистему.

Изменения в спецификации
Какие-то разделы остались неизменны, а какие-то сильно преобразились.
Например, заголовки остались те же, только добавилась возможность их строчного применения для особых случаем, например, при документировании в коде.
Выделения слов в тексте пришлось изменить, чтобы добиться единства концепции:
~~Курсив~~ **Полужирный** ~_Мелкий_~ ~^Крупный^~ ^^Надстрочный^^ __Подстрочный__ Преформатированный ~-Иностранное слово-~ *-Термин-* -*Упоминание термина*- !-Удалено-! !+Добавлено+!
Списки остались те же, чуть упростились. Комментарии совсем без изменений.
Пришлось ввести такое понятие как Контекстная пара (Context Pair)
Контекстная пара — это монолитная совокупность двух контекстно связанных элементов текста: двух последовательных абзацев, абзаца и последующего за ним списка, либо абзаца и блочного включения. Первый элемент контекстной пары является предикатом, который предсказывает, заявляет и раскрывает содержание второй, зависимой части.
К сноскам звёздочками и цифрами добавились автонумерующиеся сноски [*#].
Ссылки тоже немного расширились:
|>> — ссылка для перехода на внешний ресурс, |> — ссылка для перехода на страницы проекта (или указание исходника изображения), |-> — ссылка для скачивания файла с нашего проекта.
Введение |> #intro
Включений стало больше:
[( … )] — универсальный текстовый блок с поддержкой вложенности; [/ … /] — комментарии; [` … `] — преформатированный текст; [& … &] — программный код; [% … %] — формулы; [| … |] — таблицы; [[ … ]] — медиа (изображения, видео, аудио, файлы для скачивания). [. … .] — группирующее включение (альтернатива таблицам); [_ … _] — включение скрытия (спойлер); [$ … $] — включение ввода данных (интерактивное включение).
Появилась отдельная возможность автоматического агрегирования сущностей, чтобы получить: оглавление, глоссарий или другие сборники.
{§toc Оглавление §}
Появились механизмы встраивания:
1. Импорт нод (модульное слияние файлов, крупных разделов или блоков контента):
{{ |> link#id }}
2. Вставка значений ключей из метаданных в строку, например, для заполнения шаблона договора:
{{key}}
Появилась инъекция кода.
{& Код &}
Подсветка кода
Благодаря Джемини удалось сделать подсветку кода для VSCode. Полагаю, теперь несложно будет написать код подсветки и для других редакторов.
Помимо общей наглядности текста, в этой подсветке есть несколько полезностей. Например, при указании ссылки система проверяет есть ли такой файл и подчёркивает адрес. Прямо в редакторе можно кликать по путям и переходить по ссылкам, прыгать по якорям #id, а при наведении на изображения видеть превью.

Для установки подсветки маркван-кода достаточно поместить папку с кодом в ...vscode\extensions.
Маркван конвертер
Конвертер пришлось переписать с нуля. Теперь он работает примерно так:
1. Есть файл конфигурации в котором указано откуда взять, что сделать и куда положить. (В будущем можно прикрутить и графический интерфейс). Основная функция просто отправляет на сборку книги либо на создание сайта.
2. Скоростью и экономией памяти в этот раз решено было пренебречь, как это не прискорбно. Поэтому все текстовые файлы сохраняются в виртуальное дерево, а на прочие оставляем ссылки.
3. Последовательно обрабатываем каждый .text файл. Разделяем метаданные и сам текст, докачиваем информацию из внешних файлов при наличии команд импорта или встройке данных.
4. Ядро конвертера изолировано от всей этой глобальной суеты и работает только с текстом. Его задача преобразовать маркван-разметку в дерево абстрактных объектов:
Иерархия классов:
Document: — Документ - Metadata — Метаданные - Title — Титульный блок - Section: — Раздел - Node: — Нода - Heading(Node): — Структурирующий аголовок - Paragraph(Node): — Абзац - InlineElement: - и т.д. … - ListBlock(Node): — Блок списка - ListItem(Node): — Элемент списка - ContextPair(Node): — Контекстная пара - Attachment(Node): — Сноски и ссылки - Inclusion(Node): — Включение и т.д. …
5. После парсинга по дереву проходит агрегатор документа и, например, превращает относительные ссылки в корневые, перенумеровывает списки, сноски и прочее подобное. Заодно считаем сколько и каких включений у нас есть — это для оптимизации стилей.
6. Результат конвертации не спешим сохранять на диск. У нас появилось результирующее дерево страниц из абстрактных нод. Затем нужно пройтись агрегатору уровня сайта и собрать данные, например, для меню.
7. Теперь можем преобразовывать полученное в html или другой формат. Потом накатываем тему и сохраняем в будущий сайт файлы изображений и других документов, причём только тех, что были упомянуты в тексте, чтобы не отдавать мусор, который может накопиться во время творческих метаний автора. Важное примечание: при генерации веб-страниц в шаблон записываем стили только тех объектов, которые присутствуют в нём. Например, если нет на странице формул, то и незачем грузить яваскрипт их обрабатывающий.
Результат можно посмотреть на самом сайте https://markvan.mudrium.ru/. Он создан из простых текстовых файлов, положенных в папки. Есть и другие сайта, но о них я расскажу позже.



Что дальше?
Скоро сказка сказалась, но на деле не сразу всё придумалось. Это был реальный труд, хоть и интересный. Уделю внимание другим проектам.
Полная обновленная спецификация со всеми примерами, скриншотами и исходным кодом живет на официальном сайте проекта: markvan.mudrium.ru.
Код конвертера ещё сыроват, но я волевым решением приостановил разработку, отложив рефакторинг, чтобы дать проекту отлежаться. Исходники конвертера и расширение VS Code также опубликованы на GitHub.
Проект открыт для обратной связи. Буду рад вашим мыслям по поводу спецификации маркван-разметки. Пишите на почту, в телеграм или прямо здесь в комментариях. В идеале нужно несколько экспериментаторов, у которых есть реальные задачи превратить простой текст в сайт.
