Как стать автором
Обновить

TeX в SVG: опенсорс-решение в помощь веб-разработчикам образовательных проектов

Время на прочтение 4 мин
Количество просмотров 8.8K
Всего голосов 58: ↑56 и ↓2 +54
Комментарии 23

Комментарии 23

В финале так и есть, но не на клиенте, а на сервере. На клиенте это, увы, дорого. Про pdf интереснее, по ссылке которую ты указан, не совсем понятно как она генерируется.
Спасибо за тестирование на слабых компьютерах!
Но, как только появился браузер, сервис стал тормозить: генерация одной формулы занимала секунды

Именно генерация формулы, а не запуск Puppeteer? А то как раз на это секунды требуются.


Сам недавно для сохранения в pdf поднял express сервер с мини-очередью — чтобы держать браузер запущенным, с одной вкладкой — убрал оверхед ~3.5 секунды. Бонусом получил кэширование и отсутствие параллельно запущенных нод

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

p.s. кстати если тебя интересует рендеринг в pdf, то рекомендую посмотреть в сторону wkhtmltopdf. Но пусть и старый, но работает сильно быстрее. У нас есть отдельное решение для этого, но это тема отдельного поста :)

Для меня ограничение в одну вкладку было необходимо. Для вашей же задачи, возможно, вполне подойдёт ограничение в N вкладок, которые смогут параллельно обрабатывать очередь, размер N будет зависеть только от конфигурации железа. Масштабировать можно будет и горизонтально — через балансировщик.


А насчёт wkhtml, mpdf, phantomjs — спасибо, но нет, если требуется что-то большее, чем "картинка + текст хоть как-нибудь", я лучше заверстаю нормально для современного браузера — со всеми его плюшками и любыми фронтенд-либами — и получу 1-в-1 то, что вижу при ctrl+p -> print to pdf

Ты прав, все зависит от того что именно тебе необходимо и какие есть требования по скорости. Кстати был неплохой доклад на RND.JS 8 от Виталия Слободина на эту тему, возможно, уже есть какие-нибудь классные результаты ;)

Можно ещё было глянуть как это делается в MediaWiki (движке Википедии) — там же тоже можно вставлять формулы на TeX'е и показываются они как рисунки.

Да и мы сделали это :) Решение от Wikimedia использует внутри себя PhantomJs, что было слишком медленно для нас. Но некоторые решения там интересные, при желании можно посмотреть, вот репозиторий

Недостаёт картинок отрисовки формул «до» и «после». Что значит «сломалось выравнивание»? И не все знают, как выглядят артефакты при «сломе головки струйного принтера».

Резонно :)
Выравнивание ломалось примерно так:
поломанное выравнивание
Про «слом головки струйного принтера», увы, не удалось найти оригинальной иллюстрации, но основной смысл в том, что svg'ка разлеталась в разные стороны из-за коллизий названий symbols разных формул. И, естественно, чем больше формул на странице, тем вероятнее коллизии.

Когда мне нужно было решить подобную задачу (преобразовать LaTeX-формулу в SVG), то я воспользовался библиотекой, которую сейчас мейнтейню — WPF-Math.


Причём функция, генерирующая SVG, у нас там получилась вообще в качестве одного из случайных побочных результатов разработки.

Формулы в png умеет делать Гугл. Вот пример:
http://chart.apis.google.com/chart?cht=tx&chl=\displaystyle \int_{-\infty}^{\infty}e^{-x^{2}} \;dx={\pi}

Кстати, html с такими формулами «открывается вордом».

Генерация формул на стороне сервера в swg и png уже реализована тут http://i.upmath.me/. Там открытый исходный код и всё такое.

Автор этого есть на Хабре: parpalak.

Выглядит здорово, но я не нашел репозиторий, чтобы это можно было использовать у себя и накрутить что-то свое, типа кэширования, предпроцессинга и прочих штук.


Если проект действительно опенсоурсный, то было бы интересно как это работает там.

Действительно интересное решение.
Есть несколько моментов которые необходимо проверить и один который неприменим в Яндексе :)


Надо проверить:


  1. Надо проверить насколько это будет быстро, потому что если я правильно понял, то это решение напрямую обращается к TexLive, потом преобразует из DVI в SVG и так далее.
  2. Понять какое есть точки расширения, к примеру для добавления возможности добавить доступность формуле

Неприменимо для нас:


  1. Это поддержка inline формул. Да, это решение поддерживает такие формулы, но только для современных браузеров с поддержкой css переменных как минимум.

Да, обращается напрямую к TeX Live.


Про css-переменные, вы имеете в виду последний коммит? Он относится только к js-скрипту, который подменяет разметку формул в html-коде страниц через двойные доллары на сами картинки. Фича нужна только для небольшого масштабирования формул, чтобы размер шрифта на картинке соответствовал размеру шрифта на странице.


Серверная часть, которая генерирует svg- и png-картинки, такие как эта, работает без каких-либо css-переменных.

Всё так, но MathJax, в свою очередь, имеет еще и выравнивать формулы относительно baseline текста, что как никак кстати подходит для inline-формул. Если я правильно понял в Вашем решении выравнивание работает тоже через css переменные.


Плюс заметил артефакты в IE 11, что для нас очень важно.

Для выравнивания задается vertical-align. Переменные тут не нужны. Svg-картинки знают о положении базовой линии. Раньше я использовал встраивание картинок через object и передачу информации о базовой линии через postMessage. Потом переделал на fetch, потому что вставка через object стала тормозить в Хроме. Fetch не поддерживается в IE11, но старая реализация работает в IE11, для кроссбраузерности можно использовать ее: https://github.com/parpalak/i.upmath.me/commit/ec56935f904caffdcba11509c3353fc24881a2a6


Или пойти по истории вглубь, старые версии скрипта работают и на IE8.


Выше уже приводили, кстати, ссылку на описание того, как это всё работает: https://written.ru/articles/technologies/site_building/latex_for_web

Сталкивался с подобной задачей.


  • Попробовал KaTeX. Синхронный и очень быстрый. Всё замечательно, но мало что умеет. Пришлось сразу отказаться. ЕМНИП оно только в HTML умеет. Но могу ошибаться, это было пару лет назад. Мне нужен был SVG
  • Попробовал MathJax. Ужасное API, отсутствие поддержки es6 модулей (во всяком случае на тот момент). И вообще опыт преимущественно негативный был. Однако он умеет в HTML-инъекции (мне нужно было через <ForeignObject/> вставлять в формулы <input/>-ы. А MathJax это умеет
  • Попробовал TexLive на стороне сервера в отдельном докер-контейнере. Это было тяжко. Там около 1.5 GiB одна только его сборка. Зато она просто всемогущая. И химические формулые разных видов, и разные математические расширения и чего там только нет. Всё кроме <ForeignObject/>-ов.

В итоге пришёл к гибридной схеме:


  • Потребитель получает готовые SVG избавленные от неуникальных ID. Копирование в буфер обмена не требовалось.
  • В админке используется и TexLive (запрос к backend-у) и MathJax. MathJax для интерактивных вставок, а TexLive для всего остального (в особенности для хитрого LaTeX синтаксиса вроде химических формул).
  • При сохранении документа всё принудительно конвертируется в SVG и сохраняется на диск. Сами LaTeX формулы, разумеется, не теряются.
  • Для размера используется единица измерения ex. Это очень удобно когда формула должна выглядеть однородно с текстом в inline-режиме.

Сборка TexLive была вынесена в отдельный репозиторий, т.к. одна только сборка docker контейнера отнимала легко 40+ минут.

Судя по алгоритму очень похоже на то что предлагает aafin, возможно имеет смысл подумать о использовании решения i.upmath.me :) Ну за исключением динамики — тут видимо альтернатив для MathJax немного.

Посмотрел — там внутри как раз TexLive :) Правда с PHP. У меня вместо PHP был простенький express.js server на 150 строчек. Эдакий wrapper поверх texlive и ещё пару cli-утилит.

Зарегистрируйтесь на Хабре , чтобы оставить комментарий