Как отрендерить формулу и не съесть всю память устройства
Представьте, что вам нужно добавить отображение математических формул в мобильное приложение. Казалось бы, задача тривиальная — берем проверенный временем KaTeX и радуемся жизни. Но есть нюанс: KaTeX написан на JavaScript. Чтобы запустить его на iOS или Android, вам придется тащить за собой WebView или целый движок V8. В итоге простая дробь в интерфейсе обходится в лишние 150 МБ оперативной памяти и заметную задержку при холодном старте.
Недавно я наткнулся на проект RaTeX, который решает эту проблему радикально. Разработчики переписали ядро рендеринга на Rust. Теперь формулы рисуются нативно, без участия браузерных движков и DOM.
Что под капотом
RaTeX — это не просто обертка, а полноценный порт KaTeX, работающий на чистом Rust. Проект берет строку в формате LaTeX и превращает её в список команд для рисования (DisplayList). Этот список потом можно передать куда угодно: в системный Canvas на Android, CoreGraphics на iOS или превратить в SVG/PNG на сервере.
Главная фишка здесь в переносимости. Один и тот же код на Rust обеспечивает идентичный рендеринг на всех платформах. Если формула выглядит правильно в веб-демо, она будет выглядеть точно так же в вашем Flutter-приложении или в сгенерированном PDF-отчете на бэкенде.
Чем RaTeX отличается от привычных инструментов
Обычно выбор стоит между MathJax и KaTeX. Оба инструмента прекрасны для веба, но за его пределами начинаются костыли. RaTeX меняет правила игры в нескольких аспектах:
- Никакого мусора в памяти. Вместо тяжелого WebView вы получаете компактный бинарный файл. Управление памятью в Rust предсказуемое, никакого Garbage Collector, который может фризить интерфейс в неподходящий момент.
- Работа в офлайне. Поскольку движку не нужны внешние скрипты или браузерная среда, он работает всегда и везде.
- Скорость. Нативный рендеринг через системные API отрисовки всегда быстрее, чем прогон через дерево DOM элементов.
Интересно, что авторы не пытаются конкурировать с KaTeX в браузере. Они честно признают: в вебе KaTeX оптимизировался годами и там он король. RaTeX нужен там, где браузера нет или он слишком дорог для ресурсов системы.
Химия и физика из коробки
Кроме стандартных математических интегралов и матриц, проект поддерживает расширение mhchem. Это значит, что вы можете писать химические формулы через \ce и физические величины через \pu. Например:
\ce{H2SO4 + 2NaOH -> Na2SO4 + 2H2O}
\ce{Fe^{2+} + 2e- -> Fe}
Для образовательных приложений или научных инструментов это киллер-фича, так как поддержка химии в нативных рендерерах обычно реализована из рук вон плохо.
Архитектура и интеграция
Проект разбит на несколько независимых модулей (крейтов). Есть лексер, парсер, модуль разметки и специфичные рендереры. Такая модульность позволяет собрать только то, что вам нужно.
Если посмотреть на схему работы, она выглядит логично:
- Строка LaTeX попадает в
ratex-parser. - Формируется дерево AST.
ratex-layoutпревращает его в дерево блоков.- На выходе получаем
DisplayList— универсальный набор инструкций для рисования.
Пример того, как это выглядит на iOS. Чисто, четко и нативно.
Для интеграции разработчики подготовили готовые слои:
- iOS: XCFramework для Swift.
- Android: AAR через JNI для Kotlin.
- Flutter: через Dart FFI и CustomPainter.
- React Native: нативные модули для обеих систем.
- Web: WASM-модуль, который рисует прямо на Canvas 2D.
Как попробовать в деле
Если у вас установлен Rust, пощупать рендеринг можно прямо из терминала. Например, генерация PNG из формулы делается парой команд:
echo '\frac{1}{2} + \sqrt{x}' | cargo run --release -p ratex-render
А если нужен SVG, который не развалится без установленных шрифтов, можно использовать режим standalone. В этом случае RaTeX заберет контуры глифов из шрифтов KaTeX и встроит их прямо в векторный файл:
echo '\int_0^\infty e^{-x^2} dx' | cargo run --release -p ratex-svg --features cli -- --font-dir ./fonts --output-dir ./out
Кому это пригодится
Я бы советовал присмотреться к RaTeX в трех случаях. Во-первых, если вы делаете мобильное приложение с обилием математики и не хотите, чтобы оно тормозило на бюджетных устройствах. Во-вторых, если вам нужно генерировать превью формул на сервере (например, для мессенджера или бота) без запуска тяжелого headless-браузера. В-третьих, если вы пишете на Rust и вам нужен надежный инструмент для отрисовки математики в десктопном GUI.
Проект еще молодой, и документация местами заставляет лезть в исходники, но само наличие полноценного порта KaTeX на Rust — это большой шаг вперед для кроссплатформенной разработки. Степень покрытия синтаксиса в 99% внушает оптимизм, а отсутствие зависимости от JS делает его отличным кандидатом для встраиваемых систем.
