MathJax внутри SVG

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

Я хотел бы, чтобы текстовые элементы в этих SVG-диаграммах отображались с помощью MathJax. Я знаю, как!--6-->причина динамической математики для визуализации. Однако выход 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?

3 ответов


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

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

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

на <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>

существует способ включить элементы 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

я использовал следующее, которое определяет функцию, которая принимает код latex в качестве входных данных и добавляет обработанный 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.