Как отображается документ

Что происходит между вашим Markdown и страницей читателя, почему формулы набирает KaTeX, чего он не умеет и почему предпросмотр совпадает со страницей.

Сохраняете вы исходный текст в Markdown, а читатель получает страницу HTML с уже набранными формулами. Между ними — один рендерер, один и тот же везде, где появляется ваш текст. Если примерно знать, что он делает, становятся понятны большинство правил диалекта и большинство сюрпризов из решения проблем.

Хранится исходный текст

Текст работы хранится как написанный вами Markdown, а не как HTML. Визуальный редактор тоже пишет Markdown: то, что он показывает отформатированным, он сохраняет как исходник. Это и делает документ переносимым. Его можно экспортировать, конвертировать, править вручную или клиентом командной строки, и ничего не теряется в формате, который читает только одна программа.

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

От исходника к странице

Рендерер работает в четыре этапа.

  1. Исправления в сыром тексте. Кое-что нужно уладить до разбора текста, иначе парсер Markdown это разрушит: \(…\) и \[…\] переписываются в форму с долларами, потому что CommonMark читает \( как экранированную скобку; начальные пробелы строки стихов сохраняются; строка атрибутов блока вроде {align=center} привязывается к блоку под ней; вложенным блокам ::: даётся нужная глубина двоеточий.
  2. Разбор. Текст читается как CommonMark с расширениями GitHub, математикой и директивами — в дерево из абзацев, заголовков, списков, директив и так далее.
  3. Присвоение. Каждая конструкция диалекта забирает свою часть дерева: утверждения забирают :::theorem и родственные блоки, выноски — :::note, рисунок — :::figure. Всё, что после них осталось незабранным, превращается обратно в набранные вами символы, поэтому директива с опечаткой видна на странице, а не пропадает. Здесь же заголовки опускаются ниже уровня заголовка работы.
  4. Запись страницы. Дерево становится HTML. Формулы набираются, код подсвечивается, каждый заголовок получает якорь, а результат проходит через санитайзер, описанный ниже.

Страница, которую получает читатель, уже содержит всё это. Формулы, метки, подписи и цвета кода — в HTML, поэтому текст читается без скриптов, в читалке лент, на печати и экранным диктором. Скрипты добавляют только то, что требует браузера: переключение вкладок, полноэкранный просмотр изображений и запуск видеоплеера.

Почему математика на KaTeX

Формулы набирает KaTeX: он читает математику LaTeX и пишет HTML. Его выбрали за то, что он позволяет странице обещать:

  • Формула уже на странице. KaTeX набирает формулы при сборке страницы, а не в браузере читателя, поэтому формула появляется вместе с текстом — без мелькания сырого LaTeX и без ожидания скрипта.
  • Одинаковый вход — одинаковый результат. Формула выглядит одинаково на каждой странице, в предпросмотре редактора и в результатах поиска.
  • Он не может навредить. KaTeX отображает математику и ничего больше. Он не может загрузить файл, выполнить команду или открыть ссылку, поэтому формула от незнакомца так же безопасна, как его проза.

Чего он не умеет

У последнего пункта есть цена. KaTeX реализует большую часть математического режима LaTeX, но не весь, и кое-что он не делает намеренно:

  • Никаких пакетов. \usepackage нет. То, что поддерживает KaTeX, — это список на его странице поддерживаемых функций; команда из другого места, например \norm или \abs из physics, показывается красным. Пишите её полностью: \lVert x \rVert, \lvert x \rvert.
  • Никаких ссылок в формулах. \href и \url отклоняются. Формула может порождать математику и ничего больше: ни ссылки, ни класса, ни идентификатора, которые могли бы куда-то увести читателя или изменить страницу вокруг. Ставьте ссылку в предложение рядом с формулой.
  • Макросы живут одну формулу. \newcommand или \def забываются в конце формулы, которая их определяет.
  • Никаких рисунков. Кроме прямоугольного коммутативного квадрата, который рисует \begin{CD} в KaTeX, диаграммы и графики — не математический режим. Рисуйте их в блоке TikZ, который компилирует настоящий LaTeX при сохранении работы.
  • Выключной формуле нужны свои строки. Окружение, работающее только в выключном режиме, например align* или \tag, ломается, если его ограничители $$ стоят с ним на одной строке: тогда формула строчная.

Формула, которую KaTeX не может прочитать, никогда не ломает страницу. Она показывается на своём месте, красным, вместе с вашим исходником, чтобы было видно, что исправить.

Почему предпросмотр и есть страница

Предпросмотр редактора, опубликованная страница и этот сайт документации отображаются одним и тем же рендерером с одними и теми же настройками. Поэтому предпросмотру можно доверять: документ, который выглядит правильно там, правилен для каждого читателя.

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

Что делает санитайзер

Документ Markdown может содержать сырой HTML, а HTML может нести скрипты, стили и фреймы. Поэтому последний этап оставляет только разрешённый список элементов и атрибутов и молча удаляет всё остальное:

  • никаких <script>, <style> и атрибутов событий on…;
  • никаких ссылок и изображений с адресами, кроме https, http и, для ссылок, mailto;
  • никаких фреймов, кроме двух видеоплееров;
  • никаких свободных атрибутов style, так что документ не может перекрасить страницу вокруг себя;
  • любой id, который вы пишете, получает спереди user-content-, так что он никогда не может захватить часть самой страницы.

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

Что происходит при сохранении

Две вещи делаются не при каждом просмотре страницы, потому что они медленные или зависят от чужих данных, а готовятся при сохранении работы:

  • Диаграммы TikZ компилируются LaTeX в изображения — одно для светлой страницы и одно для тёмной, — и страница показывает изображение. Пока диаграмма не скомпилирована, на её месте написано Diagram not rendered.
  • Упоминания сопоставляются с профилями, так что @handle ведёт к существующему человеку и продолжает вести к нему, если он сменит хэндл. Хэндл, который ни с кем не совпал, остаётся простым текстом. В предпросмотре редактора сопоставлять не с чем, поэтому там ссылкой становится каждый правильно записанный хэндл.