Любой более-менее живой репозиторий уже давно перестал быть просто директорией с исходным кодом. Помимо файлов с исходниками там теперь живут инструкции, архитектурные заметки, спецификации, техническая документация и отчёты, которые должны одинаково хорошо читаться и в IDE, и в веб-интерфейсе платформы. Даже сейчас в процессе написания этой статьи я использую Markdown-разметку, которая стала де-факто стандартом для ведения документации в проектах, но давайте обо всем по порядку.
Когда таких форматов становится много, возникает закономерный вопрос: как показать их пользователю удобно, быстро и без необходимости скачивать файл к себе на компьютер? У нас в GitVerse этот вопрос постепенно вырос в отдельную продуктовую и инженерную задачу. Так появилась поддержка просмотра разных типов файлов — от упомянутого выше Markdown до более специализированных форматов.
Я расскажу, почему вообще человечество пришло к идее текстовых форматов для оформления документов, как Markdown стал фактическим стандартом индустрии, зачем нужен Typst и как мы внедряли его поддержку на платформе с помощью WebAssembly.
От ASCII-графики к языкам разметки
Если обратиться к истории, то станет понятно, что желание «красиво оформить текст» появилось задолго до современных редакторов. И поначалу это желание удовлетворяли буквально подручными средствами.
В ранних вычислительных системах и терминалах разработчики и инженеры пользовались обычным текстом, дополненным символами, псевдографиками. Таблицы собирали из дефисов и вертикальных черт, схемы — из символов вроде \ | / - _. Это то, что сегодня мы называем ASCII-art.
Но по мере усложнения документов стало ясно: одного лишь «оформленного текста» недостаточно. Нужно описывать его структуру формально: где у нас заголовок, где абзац, где список, где ссылка, где врезка, где формула. Так постепенно возникла идея разметки: текст хранится как текст, а специальные конструкции объясняют, как его интерпретировать.
Отсюда и выросли языки разметки. Сначала — более тяжеловесные и академические подходы, затем — решения для обмена документами, публикаций и веба. Одним из ключевых поворотных моментов стало появление SGML, а затем и HTML, который фактически сделал гипертекст массовым явлением. Документ перестал быть просто последовательностью строк: он стал структурой, по которой можно перемещаться, которую можно стилизовать, связывать ссылками и отображать в разных средах.
Дальше началось естественное расслоение инструментов. Для одних задач были нужны строгие формальные языки, для других — максимально простые и человекочитаемые форматы. Для научных и издательских сценариев закрепились мощные системы вроде Te и LaTeX. Для веба — HTML и его экосистема. Для повседневной инженерной документации индустрия в итоге пришла к более лёгкому компромиссу: нужна разметка, которую можно писать руками, читать в исходном виде и без боли хранить рядом с кодом в Git.
Так на первый план вышел Markdown.
Markdown как язык инженерной повседневности
Популярность Markdown объясняется очень просто: он решает ровно ту задачу, которая нужна инженерам каждый день. В отличие от тяжёлых форматов, Markdown не требует от автора думать как типограф или верстальщик. В большинстве случаев достаточно помнить несколько базовых конструкций: заголовки, списки, ссылки, кодовые блоки, таблицы, цитаты. Да и помнить не обязательно, достаточно держать под рукой шпаргалку, например, я вечно забываю, как правильно оформить гиперссылку.
Главное преимущество Markdown в том, что исходный текст остаётся читаемым даже без рендеринга. Если файл открыт в терминале, просмотрщике диффов или просто в сыром виде в репозитории, он всё равно понятен человеку. Для инженерной среды это критично: документация должна быть не только красивой, но и удобной в сопровождении.
Именно поэтому Markdown давно стал де-факто стандартом индустрии. Он используется практически везде:
в (README)-файлах репозиториев;
в описаниях pull request’ов, задач и комментариях к ним;
в проектной документации;
в wiki;
в генераторах статических сайтов;
в заметках, RFC и внутренних инженерных документах;
в developer portal и документации API.
Markdown оказался тем самым «базовым минимумом» для повседневной документации. Он достаточно выразительный, чтобы описывать структуру текста, и достаточно простой, чтобы не отпугивать пользователя.
Поэтому неудивительно, что Markdown занимает важное место и на GitVerse. Когда мы работаем с репозиториями, поддержка Markdown — это, так сказать, база. Люди приходят в репозиторий и хотят сразу увидеть README, инструкции по запуску, архитектурные заметки, changelog и прочие документы в нормальном читаемом виде. Для удобства разметки ваших репозиториев мы даже ввели такое понятие, как соответствие стандартам. По сути, это наполненность репозитория основными типами документов: README, changelog, contributing и другими.
Но чем дальше развивается платформа, тем заметнее становится следующий шаг: Markdown охватывает далеко не все сценарии.
Когда Markdown уже недостаточно
Markdown хорош там, где нужна простая и быстрая документация. Но как только задача выходит за рамки «заголовок, список, ссылка, кусок кода», начинаются компромиссы.
Например, трудно управлять сложной типографикой. Ограничены возможности для гибкой вёрстки. Научные и формально оформленные документы быстро упираются в потолок выразительности. Да, экосистема Markdown умеет многое за счёт расширений, плагинов и конвертеров, но за это приходится платить: совместимость становится хрупкой, поведение разных рендереров расходится, а итоговый результат всё сильнее зависит от конкретного инструмента.
Именно здесь на сцену выходят языки и системы, ориентированные не просто на заметки, а на полноценную документную вёрстку.
Долгое время в этой нише доминировал LaTeX: мощный, уважаемый, но местами тяжёлый для входа и не всегда дружелюбный к современным сценариям разработки. Новым поколениям пользователей хочется получить сопоставимую выразительность, но с более современным синтаксисом, быстрой обратной связью и лучшей эргономикой. Один из самых интересных ответов на этот запрос — Typst.
Typst: что за зверь
Typst — это современная система вёрстки и язык разметки для создания документов. Проще всего описать его как попытку переосмыслить идеи LaTeX для нынешней инженерной среды: сделать инструмент мощным, но при этом значительно более понятным, предсказуемым и удобным в использовании.
Если Markdown — это язык для «лёгкой документации», то Typst — это уже инструмент для документов, где важны структура, стиль, формулы, шаблоны и качество итогового представления. Он подходит для:
статей и отчётов;
технической документации повышенной сложности;
научных текстов;
презентационных и шаблонных документов;
материалов, где важны формулы, ссылки, нумерация, оформление и повторное использование макросов.
Одно из сильных качеств Typst — баланс между выразительностью и современным синтаксисом. Это не очередная попытка в Markdown, но отдельный язык со своей моделью описания документа. При этом порог входа у него заметно ниже, чем у «классических» тяжёлых систем вёрстки, особенно для разработчиков, привыкших к конфигурационным языкам.
Для GitVerse, как для платформы, работающей с репозиториями, появление интереса к Typst вполне закономерно: пользователи начинают хранить в Git не только код, но и содержательные документы. Люди хотят открывать файл в браузере и сразу понимать, что в нём находится, не поднимая локальную среду и не устанавливая дополнительные инструменты.
Именно так мы пришли к идее поддержки просмотра Typst-файлов на GitVerse.
Зачем вообще делать просмотр файлов на платформе
На первый взгляд может показаться, что просмотр файла — это приятная, но не самая критичная возможность. Всегда же можно скачать исходник. На практике всё наоборот.
Если пользователю приходится скачивать документ только для того, чтобы понять, что внутри, то это ломает естественный сценарий работы с репозиторием. Просмотр в веб-интерфейсе нужен потому, что он:
сокращает путь до содержимого;
ускоряет навигацию по проекту;
делает код и документы частью единого рабочего пространства;
помогает в code review и совместной работе;
снижает порог входа для новых участников команды.
Для Markdown это давно стало нормой, для изображений, PDF и текстовых файлов — тоже. Но с Typst ситуация сложнее: исходный файл сам по себе не всегда даёт пользователю представление о том, как документ будет выглядеть после рендеринга. Значит, нужен не просто text viewer, а полноценная система предпросмотра.
И вот здесь начинается уже не продуктовая, а инженерная история.
Что мы хотели получить
Перед внедрением поддержки Typst мы сформулировали несколько практических требований.
Во-первых, просмотр должен работать прямо в интерфейсе GitVerse, без необходимости скачивания файла и локальной компиляции.
Во-вторых, рендеринг должен быть достаточно быстрым, чтобы не превращать открытие файла в «ожидание загрузки документа».
В-третьих, решение должно быть изолированным и безопасным. Когда платформа начинает исполнять логику обработки сложных пользовательских файлов, вопрос sandboxing и контроля ресурсов становится обязательным.
В-четвёртых, интеграция не должна радикально усложнять текущую архитектуру платформы. Нам было важно встроить новую возможность в уже существующую модель просмотра файлов, а не городить для одного формата отдельный мир.
И наконец, хотелось сохранить масштабируемость подхода. То есть сделать не точечный «рендерер под Typst», а задел системы поддержки разных файловых форматов.
Почему мы пошли в сторону WebAssembly
Когда речь заходит о рендеринге нетривиального формата внутри веб-приложения, почти сразу возникает несколько вариантов: рендерить всё на сервере; использовать внешний сервис конвертации; запускать логику обработки на клиенте; комбинировать подходы.
Серверный рендеринг кажется естественным: пользователь открывает файл, сервер компилирует его и отдаёт результат. Но у такого подхода быстро проявляются недостатки. Во-первых, это дополнительная вычислительная нагрузка на бэкенд. Во-вторых, нужно особенно внимательно контролировать безопасность, таймауты, ограничения по памяти и изоляцию исполнения. В-третьих, возрастает задержка: для каждого открытия файла нужно дождаться серверной обработки.
Внешний сервис конвертации добавляет ещё один слой сложности: интеграцию, сетевые задержки, зависимость от отдельного компонента и дополнительные требования к отказоустойчивости.
Поэтому для нашего сценария особенно привлекательным оказался WebAssembly. По сути, он позволяет взять достаточно сложную логику, написанную не обязательно на JavaScript, собрать её в компактный исполняемый модуль и запускать в браузере в контролируемой среде.
Почему это хорошо с инженерной точки зрения:
вычисления можно вынести на клиент;
уменьшается нагрузка на бэкенд;
снижается количество промежуточных сервисов;
логика остаётся достаточно производительной;
модуль можно встроить в существующий фронтенд-конвейер;
пользователь получает более отзывчивый просмотр.
Для формата вроде Typst это особенно полезно: задача рендеринга сама по себе вычислительная, но хорошо ложится на модель «загрузи модуль, передай входной текст, получи результат для отображения».
Техническая часть: как происходил рендеринг
Общий конвейер можно описать так.
Сначала фронтенд получает содержимое файла из репозитория. На этом этапе важно было не усложнить контракт бэкенда: по возможности использовать уже существующие API выдачи содержимого и метаданных. Это снижает стоимость внедрения и уменьшает количество новых точек отказа.
Дальше по расширению файла и его MIME-типу выбирается просмотрщик. Для Markdown это один сценарий, для кода — другой, для Adoc — третий. Для Typst мы добавили отдельный обработчик.
После этого инициализируется WASM-модуль. Тут есть важный нюанс: инициализация не должна происходить «в лоб» при каждом открытии страницы. Если тяжёлый модуль загружать и поднимать заново каждый раз, то пользовательский опыт быстро ухудшится. Поэтому на практике важен ленивый импорт, повторное использование уже инициализированного экземпляра и кеширование ресурсов.
Когда модуль готов, ему передаётся исходный текст документа. На выходе фронтенд получает артефакт, пригодный для отображения в браузере в виде SVG-изображения. Дальше результат вставляется во viewer-компонент и отображается пользователю.
С инженерной точки зрения одна из главных задач здесь — сделать весь процесс детерминированным и устойчивым. Пользователь не должен видеть внутреннюю кухню в виде «мигающих» состояний, повторных инициализаций, зависающих спиннеров и неочевидных ошибок.
Что нам дал такой подход
Работа с репозиториями стала естественнее. Документы в нестандартных, но полезных форматах перестали быть «слепой зоной» интерфейса.
Typst-файлы стали полноценной частью платформы, а не просто вложением, которое нужно отдельно скачивать и где-то открывать.
Сам архитектурный подход дал задел на будущее. Благодаря обновлённому конвейеру просмотра файлов нам станет легче расширять варианты просмотра разных документов, обладающих собственным рендерингом.
Что дальше
Поддержка Typst для нас — это новый этап в развитии системы предпросмотра файлов. За одной фичей скрывается более общий вопрос: «Как сделать так, чтобы репозиторий был удобным окном ко всему содержимому проекта, а не только к исходному коду?»
Если вы уже работаете с Markdown, документацией и более сложными форматами в репозиториях, то приходите смотреть, как это устроено на GitVerse. А если давно хотели попробовать Typst в реальном инженерном процессе, то сейчас для этого как раз подходящий момент.
Заходите на gitverse.ru и попробуйте сами.
nin-jin
Вот вам, для сравнения, MarkedText:
Не хотите его поддержать?
Ну и вот на Typst, если не полениться нормально отформатировать:
tungstenmoon Автор
Спасибо, за идею! Следите за обновлениями
amcured
Не нужно обвинять маркдаун в том, что вы не способны настроить пейджер.
nin-jin
Не знаю, что за пейджер там у вас, но раз вы способны его настроить, то не поленитесь похвастать своими успехами.
amcured
`export LESS=“-R -S -# 10”`
nin-jin
amcured
Таблицы, юноша, нужны для того, чтобы отображать информацию в формате, позволяющем более-менее внятную навигацию (прокрутку) и по столбцам тоже.
MarkedText, кто бы он ни был, отображает всё так, что в реальной жизни ни разобрать, ни тем паче отредактировать, эту кашу невозможно. «Удобно читать» — это (в том числе) означает: пробежать глазами значения в пятнадцатом столбце. В том перегное, которое продемонстрировано выше, это в принципе невозможно.Но куцый мозг запрограммировавшего эту гадость не отдупляет, что «няшненько и на экранчик помещается» — это вообще не то, что нужно тем, кто документ будет читать без конвертации, в исходниках.