[Open source, Разработка веб-сайтов, Обработка изображений, Математика] Конвертируем TeX в SVG: опенсорс-решение в помощь образовательным проектам

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
10-Сен-2020 15:30


Привет! Меня зовут Костя Мамаев, я занимаюсь фронтенд-разработкой в поиске Яндекса. Некоторое время назад мы вместе с другими ребятами из команды помогали образовательным проектам компании. Среди прочего пришлось решить, казалось бы, простую задачку: отображать на экране и распечатывать на бумаге формулы, закодированные в популярном формате TeX. Звучит, как дело пяти минут, но в результате трёх подходов к снаряду появился полноценный микросервис для серверного рендеринга формул в svg и png. В статье расскажу, зачем мы пошли этим путём и почему ни один из существующих проектов не подошёл «из коробки».Результаты нашей работы могут быть полезны и другим разработчикам, помогающим школьникам и учителям, поэтому готовый микросервис ждёт вас на гитхабе Яндекса. По ссылке весь джентльменский набор: Docker-контейнер, документация, открытый код.В математических, физических и химических задачах (например, в материалах для подготовки к ЕГЭ и ОГЭ) много формул. Мы хотели, чтобы работать с ними было удобно. Качество отображения должно быть высоким, а формат — универсальным: мог выразить любую формулу, был простым в хранении и понятным за пределами Яндекса. Ещё важно, чтобы формулы выглядели одинаково и не «ехали» на разных экранах, а их обработка не перегружала CPU и расходовала энергию экономично — это особенно актуально для мобильных устройств. Подход первый: фронтендерский. KaTeXПоказывать сырую TeX-разметку опрометчиво — вряд ли её сможет прочесть пользователь без кандидатской степени, поэтому сначала нужно её приготовить. Первое решение, которое приходит на ум — конвертировать на стороне клиента, будь то что-то встроенное или библиотека для рендеринга TeX.Немногие вспомнят, что в браузерах уже есть поддержка математических формул — MathML. Но, как показало беглое исследование, формат давно забыт и пользователями, и вендорами браузеров. Пришлось двигаться дальше. Оказалось, выбор инструментов не так уж велик: монструозный, но всеядный и расширяемый MathJaX или относительно молодой и быстрый KaTeX. Как говорится, из двух зол — выбирай меньшее. Решили попробовать KaTeX.Плюсы:
  • Realtime-отрисовка формул. Пользователь пишет формулу и сразу видит, что будет на выходе.
  • Формирование разметки на клиентской стороне — не нужно ничего хранить.
Минусы:
  • Каким бы легковесным ни был KaTeX по сравнению MathJaX, он всё равно оставался слишком большим по стандартам Яндекса.
  • Артефакты realtime-генерации: мигание на странице и долгий рендеринг, особенно на мобильных устройствах.
  • Проблемы при печати (о них поговорим чуть позже).
  • KaTeX отдаёт html-разметку, так что скопировать формулу как формулу не получится.
  • Двойная работа при использовании SSR. Сначала генерируем html на сервере, а потом на клиенте.
Подход второй: браузерный. PuppeteerРезультат, полученный с KaTeX, не устроил — хотелось избавиться от недостатков первой реализации. Пришла идея сделать всё на сервере без realtime-генерации формул. В этом случае можно выбрать более мощную библиотеку — MathJaX. Она умеет «из коробки» превращать TeX в разметку, MathML и svg. Здорово, не правда ли? Оставалось написать обвязку в виде сервера, парочки web-хуков для добавления заданий на обработку и сложить всё в s3. Это оказалось не так просто. Возникли проблемы с печатью:
  • выяснилось, что svg не копируется через ctrl+c ctrl+v в Microsoft Word,
  • ломалось выравнивание формул в тексте.
Мы много общались с учителями, репетиторами, готовящими школьников к ЕГЭ и ОГЭ, и преподавателями вузов. Большинство из них распечатывает на бумаге материалы к занятиям. Это подтверждали интервью, проведённые коллегами: все респонденты-репетиторы рассказывали, что печатают задания для учеников. Значит, закрывать глаза на эти проблемы нельзя.Здесь пригодился Puppeteer. Мы добавили конвертацию из svg в png, чтобы реализовать копирование в Word. А это, стоит заметить, один из самых востребованных сценариев среди преподавателей. Но, как только появился браузер, сервис стал тормозить: генерация одной формулы занимала секунды, а пересоздание всех формул (у нас их было 110 469) — дни или даже недели.Подход третий: серверный. MathJax, sharp и немного смекалкиЧтобы получить решение, которое работает быстро, не нагружает даже слабенькие устройства и даёт приемлемое качество изображения, оставалось решить две проблемы:
  • ускорить генерацию png,
  • починить выравнивание формул.
Первая проблема решалась просто, хотя пришлось перепробовать множество вариантов, чтобы получить нужный результат. Puppeteer был безжалостно выпилен, а вместо него — добавлена маленькая и быстрая библиотека sharp. Да, решение породило внешнюю зависимость, но сервис запускается в Docker-контейнере, так что это было приемлемо. Скорость генерации заметно выросла.А вот с «поехавшими» формулами в тексте пришлось побороться. Было предположение, что выравнивание по центру или базовой линии поможет, но оно работало хорошо только для однострочных или идеально симметричных формул. MathJax сам генерирует правильные отступы в svg-файлах (правда, в ex, но это не беда), но для оптимизации отрисовки выносит одинаковые символы в defs. Они конфликтуют между вставленными svg, и выглядит это, будто сломалась головка струйного принтера. Дополнительный минус — раздутая разметка и невозможность повторного использования одинаковых svg на странице. Обращение к png выглядело жестом отчаяния: проблемы примерно те же, а качество графики хуже. Решение оказалось достаточно простым:
  • генерируем svg-файл,
  • получаем из него атрибуты со стилями (это же обычный xml, не так ли?),
  • удаляем атрибуты,
  • генерируем png из svg,
  • сохраняем в метаинформации файла данные о стилях, нужных для корректного отображения картинки.
Готово!Результаты и выводыТеперь формулы копируются, масштабируются, лениво загружаются, идеально выровнены, а CPU пользователя не нагревается до состояния сковородки. Удалось добиться скоростных улучшений. Размер десктопных и тачевых бандлов уменьшился на 64.5кб (37%).Обработка страницы варианта ЕГЭ, на которой нужно было отрендерить 94 формулы:
  • с использованием Katex: 7594 ms
  • без Katex: 6584 ms
  • финальный вариант: 1010 ms
Эта же страница, но на слабом CPU и с медленным 3G:
  • с использованием Katex: 40229 ms
  • без Katex: 37524 ms
  • финальный вариант: 2705 ms
Чему я научился?
  • Даже самая тривиальная задача может оказаться сложнее, чем представлялось вначале.
  • Svg не копируется через буфер обмена.
  • Конвертировать svg в png с помощью браузера — это долго.
  • Не стоит забывать о метаинформации. 
Надеюсь, этот проект принесёт пользу и другим разработчикам, помогающим школьникам, студентам и учителям. Если вы один из них — встретимся на гитхабе.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_open_source, #_razrabotka_vebsajtov (Разработка веб-сайтов), #_obrabotka_izobrazhenij (Обработка изображений), #_matematika (Математика), #_tex, #_komanda_jandeks.poiska (команда яндекс.поиска), #_matematika (математика), #_blog_kompanii_jandeks (
Блог компании Яндекс
)
, #_open_source, #_razrabotka_vebsajtov (
Разработка веб-сайтов
)
, #_obrabotka_izobrazhenij (
Обработка изображений
)
, #_matematika (
Математика
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 21-Май 19:10
Часовой пояс: UTC + 5