MathJax внутри SVG

Я пишу, где использую MathJax для рендеринга математики. Я также иногда включаю диаграммы SVG, которые динамически генерируются javascript. Эти диаграммы SVG иногда включают математику.

Я бы хотел, чтобы текстовые элементы на этих диаграммах SVG отображались с использованием MathJax. Я знаю, как отобразить динамическую математику. Однако вывод mathjax находится в формате <span>s, который не является допустимым SVG и не отображается.

Это сохраняется, когда я настраиваю MathJax для использования режима вывода SVG, хотя, возможно, это связано с неправильным использованием режима вывода SVG. Я изменил ссылку MathJax CDN на http://cdn.mathjax.org/mathjax/2.1-latest/MathJax.js?config=TeX-AMS-MML_SVG, которая не производила вывод SVG. Мне пока не удалось уговорить MathJax на самом деле выводить элементы SVG.

Я подумал об использовании тега SVG <foreignObject>, который не идеален, потому что (насколько мне известно) я должен указать ширину и высоту, что неудобно.

Есть ли лучший способ включить визуализированный текст MathJax внутри SVG внутри HTML?


person So8res    schedule 12.04.2013    source источник
comment
Примечание из будущего: срок службы cdn.mathjax.org подходит к концу, проверьте mathjax .org/cdn-shutting-down для советов по миграции.   -  person Peter Krautzberger    schedule 12.04.2017


Ответы (3)


В настоящее время единственный способ включить MathJax в диаграмму SVG — это <foreignObject>. Да, это не идеально не только потому, что вам нужно указать размер, но и потому, что IE9+ не поддерживает <foreignObject>.

Что касается вывода SVG, если вы использовали контекстное меню MathJax для выбора математического рендеринга, это переопределит выбор средства рендеринга в документе, поэтому по этой причине вы все еще можете видеть вывод HTML-CSS. Значение сохраняется в файле cookie, поэтому оно будет запоминаться от сеанса к сеансу. Вы можете удалить файл cookie, чтобы удалить настройку, или снова использовать меню MathJax, чтобы выбрать рендеринг SVG.

Обратите внимание, однако, что это также не поможет вам, поскольку выходные данные MathJax в формате SVG — это не просто фрагмент SVG, который можно включить в более крупный файл SVG, но он включает в себя некоторый HTML и сам элемент <svg>. Более того, MathJax нуждается в окружающем HTML для определения таких вещей, как используемый размер шрифта и некоторые другие факторы, поэтому он не сможет разместить его непосредственно в вашей диаграмме SVG.

Подход <foreignObject> действительно единственный надежный способ на данный момент.

Изменить: вот полный пример:

<!DOCTYPE html>
<html>
<head>
<title>MathJax in SVG diagram</title>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG"></script>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="500">
  <circle cx="100" cy="100" r="99" fill="yellow" stroke="red" />
  <circle cx="100" cy="100" r="3" fill="blue" />
  <foreignObject x="100" y="100" width="100" height="100">
    <div xmlns="http://www.w3.org/1999/xhtml" style="font-family:Times; font-size:15px">
    \(\displaystyle{x+1\over y-1}\)
    </div>
  </foreignObject>
</svg>
</body>
</html>
person Davide Cervone    schedule 12.04.2013
comment
у вас есть полный пример где-нибудь? Я попробовал это внутри блокнота IPython и не смог обработать математическую часть (хотя другие формулы на той же странице обрабатываются правильно). ТИА! - person akim; 23.05.2014
comment
@akim, я добавил пример в свой ответ. - person Davide Cervone; 25.05.2014
comment
Большое спасибо. На самом деле я уже нашел этот точно такой же пример :) Но я не могу заставить его работать внутри блокнота IPython :( LaTeX(), $...$ и т. д. остаются. На самом деле, это работает, если я создаю полный HTML виджет, но он не работает, когда я пытаюсь создать виджет SVG Любая подсказка? - person akim; 26.05.2014
comment
На самом деле, если быть более точным, моя цель — визуализировать исходный код GraphViz внутри IPython с метками LaTeX для обработки MathJax. Я знаю, что это неправильно, поскольку точка будет использовать размер исходного кода вместо размера отображаемых формул, но в любом случае это лучше, чем обычный текст. - person akim; 26.05.2014
comment
Извините, я никогда не использовал IPython, поэтому не могу дать вам совет. Это может быть связано с тем, когда вызывается MathJax, по сравнению с тем, когда создается SVG (MathJax нужно будет вызывать после того, как SVG будет на месте). Также может быть, что SVG защищен от MathJax элементом tex2jax_ignore. Вам, вероятно, придется поработать с людьми из IPython, чтобы понять это. - person Davide Cervone; 27.05.2014
comment
Не забудьте использовать TeX-AMS-MML_SVG, а не стандартную конфигурацию TeX-AMS-MML_HTMLorMML для MathJax. - person herrlich10; 31.01.2015
comment
один из способов решить проблему предоставления ширины и высоты, которую я использую, - всегда устанавливать размер ForeignObject так, чтобы он покрывал весь svg, и размещать текст внутри html (или css), который находится внутри него. - person qbolec; 16.07.2015
comment
Примечание из будущего: срок службы cdn.mathjax.org подходит к концу, проверьте mathjax. org/cdn-shutting-down для советов по миграции (и, возможно, обновите свой пост для будущих читателей). - person Peter Krautzberger; 21.04.2017
comment
Кажется, это больше не работает? Копирование и вставка предоставленного кода работает в mathjax 2.5, но не в 2.6 и 2.7. - person R D; 03.05.2017
comment
@RD, у меня все еще работает в 2.7. Какие браузеры вы используете? - person Davide Cervone; 03.05.2017
comment
@DavideCervone Chrome 58 64-битная Win10 без расширений: он показывает предварительный просмотр уравнения в течение нескольких миллисекунд, затем предварительный просмотр скрывается и ничего не отображается. Работает должным образом в Firefox с Mathjax 2.7 или в Chrome с версиями ‹= 2.5. - person R D; 03.05.2017
comment
@RD, не знаю, что тебе сказать. У меня это работает в 64-разрядной версии Chrome 58 Win10 с MathJax 2.7. Можете ли вы очистить файлы cookie и посмотреть, будет ли это иметь значение? - person Davide Cervone; 03.05.2017

Существует способ включить элементы MathJax SVG в диаграмму SVG, не требуя foreignObject. Полная демонстрация метода находится на http://puzlet.com/m/b00b3.

Допустим, у вас есть подобная диаграмма SVG (и содержащая любые элементы SVG) на вашей веб-странице:

<svg id="diagram" xmlns='http://www.w3.org/2000/svg' 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    version='1.1' width='720' height='100'>
</svg>

и следующий MathJax:

<div id="mathjaxSource">
$\Omega$
</div>

Используйте этот CoffeeScript (плюс jQuery) для интеграции элемента MathJax в вашу диаграмму SVG:

diagram = $("#diagram")  # SVG diagram
obj = new MathJaxObject "mathjaxSource"  # MathJax object (see class definition below)
obj.appendTo diagram  # Append MathJax object to diagram
obj.translate 100, 200  # Position MathJax object within diagram

Вы также можете использовать методы width() и height() для центрирования и вертикального выравнивания.

class MathJaxObject

    constructor: (@divId, @scale=0.02) ->
        @source = $("##{@divId}").find ".MathJax_SVG"
        @svg = @source.find "svg"
        g = @svg.find "g"
        @group = $(g[0]).clone()
        @translate 0, 0

    viewBox: -> @svg[0].viewBox

    width: -> @scale * @viewBox().baseVal.width

    height: -> @scale * @viewBox().baseVal.height

    translate: (@dx, @dy) ->
        dy = @dy + (-@scale * @viewBox().baseVal.y)
        @group[0].setAttribute "transform", 
            "translate(#{@dx} #{dy}) scale(#{@scale}) matrix(1 0 0 -1 0 0)"

    appendTo: (diagram) ->
        diagram.append @group
person martinc    schedule 21.02.2014
comment
Не могли бы вы объяснить, что здесь происходит? Я действительно хотел бы избежать зависимости от CoffeeScript и jQuery, просто чтобы сделать это, если это простая задача. - person Jason S; 22.05.2014
comment
nm, я понял это, я опубликую развязанное решение, когда у меня будет шанс - person Jason S; 22.05.2014
comment
вы также можете прочитать этот embeddedrelated.com/showarticle/599.php (от @JasonS Я полагаю) - person yota; 04.09.2019

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

// First create a new element to hold the initial Latex code
// and eventual MathJax generated SVG. This element isn't added
// to the main docuemnt, so it's never seen.
let mathBuffer = document.createElement("div");

// Then define a function that takes LaTeX source code
// and places the resulting generated SVG in a target SVG element.
mathSVG = function (latex, target) {
  // Update the buffer with the source latex.
  mathBuffer.textContent = latex;
  // Get MathJax to process and typeset.
  MathJax.Hub.Queue(["Typeset", MathJax.Hub, mathBuffer]);
  // Queue a callback function that will execute once it's finished typesetting.
  MathJax.Hub.Queue(function () {
    // This (svg) is the generated graphics.
    const svg = mathBuffer.childNodes[1].childNodes[0];
    // The next line is optional, play with positioning as you see fit.
    svg.setAttribute("y", "-11pt");
    // Move the generated svg from the buffer to the target element.
    target.appendChild(svg);
    // Clear the buffer.
    mathBuffer.textContent = "";
  });
};

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

person Freddie Page    schedule 24.08.2018
comment
Есть ли шанс, что вы знаете, как перевести это в MathJax 3? Выглядит довольно красиво, но я бы хотел использовать более чистый асинхронный интерфейс MathJax 3. - person David Roundy; 26.08.2020