Discourse Math был значительно обновлён в январе 2026 года до новой официальной версии, включённой в ядро, с MathJax 4.1 по умолчанию и KaTeX в качестве альтернативы. В документации к плагину также отмечается, что KaTeX включает расширение CopyTex для копирования исходного кода LaTeX.
Стоит ли добавить небольшой патч темы, улучшающий выделение цитат в постах с большим количеством математики?
Для сайтов, heavily использующих MathJax, таких как «Physics with Ethan», наиболее практичное решение выглядит так:
1. перехватить выделенный HTML до того, как Discourse преобразует его обратно в Markdown,
2. найти элементы-обёртки для математики,
3. заменить их исходным TeX-кодом, заключённым в $...$ или $$...$$,
4. затем позволить Discourse продолжить формирование цитаты.
Вот возможный скрипт компонента темы, с которого можно начать, если стоит задача модифицировать раздел <head> или область JS темы Horizon (или Default).
<script type="text/discourse-plugin" version="1.0">
apiInitializer("1.34.0", (api) => {
function texFromMathElement(el) {
// MathJax v3/v4 обычно хранит исходный код в дочернем элементе annotation.
const annotation =
el.querySelector('annotation[encoding="application/x-tex"]') ||
el.querySelector('annotation');
if (annotation?.textContent?.trim()) {
const tex = annotation.textContent.trim();
// Эвристика: блочные обёртки математики часто являются контейнерами отображения.
const isBlock =
el.tagName === "MJX-CONTAINER" &&
(el.getAttribute("display") === "true" ||
el.getAttribute("display") === "block");
return isBlock ? `$$\n${tex}\n$$` : `$${tex}$`;
}
return null;
}
function patchMathInFragment(fragment) {
const candidates = fragment.querySelectorAll(
"mjx-container, .math, .katex, .MathJax"
);
candidates.forEach((node) => {
const replacement = texFromMathElement(node);
if (!replacement) {
return;
}
const textNode = document.createTextNode(replacement);
node.replaceWith(textNode);
});
return fragment;
}
api.modifyClass("component:quote-button", {
pluginId: "ethan-math-quote-fix",
_selectionChanged() {
this._super(...arguments);
try {
const selection = window.getSelection();
if (!selection || selection.rangeCount === 0) {
return;
}
const range = selection.getRangeAt(0);
const fragment = range.cloneContents();
patchMathInFragment(fragment);
const container = document.createElement("div");
container.appendChild(fragment);
// Заменяем буфер, который Discourse позже преобразует в Markdown цитаты.
if (this.quoteState) {
this.quoteState.buffer = container.innerHTML;
}
} catch (e) {
// Тихо игнорируем ошибки, чтобы обычное цитирование продолжало работать.
console.warn("Math quote patch failed:", e);
}
},
});
});
</script>
Несколько важных оговорок:
• Это практический патч, а не решение, уже опубликованное Meta. Основная стратегия выведена из пути цитирования, проходящего через выделенный HTML и функцию toMarkdown.
• Наиболее вероятно, что он поможет при использовании провайдера MathJax, который сейчас является провайдером по умолчанию в Discourse Math и тем, который я обычно использую.
• Скрипту могут потребоваться небольшие корректировки селекторов в зависимости от того, как отрендеренная математика оказывается в виде mjx-container, .MathJax или другой обёртки. Я бы протестировал это на тестовом сайте — это была бы новая стандартная установка.
• Вряд ли он будет идеален для каждого краевого случая, особенно при смешанных выделениях inline/block или вложенных цитируемых материалах.
Поскольку Discourse теперь официально поддерживает KaTeX с CopyTex, другой путь — сменить провайдера, если моя главная проблема — копирование исходного кода LaTeX, а не точность рендеринга. Это не решит автоматически проблему выделения при цитировании, но означает, что для отрендеренной математики уже есть более удобный для копирования путь.
Для моего сайта с большим количеством MathJax, «Physics with Ethan», я сейчас думаю так:
• оставить MathJax, если кто-то не предложит перейти на KaTeX?,
• возможно, добавить патч для выделения цитат в тему Horizon, используя код выше (на тестовом сайте).
• рассматривать это как локальное улучшение удобства использования до тех пор, пока не появится официальное решение на стороне upstream. Тот факт, что тема функции 2020 года всё ещё открыта в 2026 году, говорит о том, что upstream может оставаться медленным в этом вопросе.