MathJax inside SVG

前端 未结 3 1428
春和景丽
春和景丽 2021-02-03 23:59

I\'m doing some writing where I use MathJax to render the math. I also occasionally include SVG diagrams which are generated dynamically by javascript. Those SVG diagrams occasi

相关标签:
3条回答
  • 2021-02-04 00:12

    Currently, the only way to include MathJax within an SVG diagram is through <foreignObject>. Yes, it is not ideal, not only because you need to provide a size, but also because IE9+ doesn't support <foreignObject>.

    As for the SVG output, if you have used the MathJax contextual menu to select a math render, that will override the renderer choice in the document, so you may still be seeing HTML-CSS output for that reason. The value is stored in a cookie, so that it will be remembered from session to session. You can delete the cookie to remove the setting, or use the MathJax menu again to select SVG rendering.

    Note, however, that this isn't going to help you either, as MathJax's SVG output is not just an SVG snippet that can be included into a larger SVG file, but include some HTML and the <svg> element itself. Moreover, MathJax needs the surrounding HTML to determine things like the font-size to use, and some other factors, so it is not going to be able to placed directly into your SVG diagram.

    The <foreignObject> approach is really the only reliable way at the moment.

    Edit: Here is a full example:

    <!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>
    
    0 讨论(0)
  • 2021-02-04 00:15

    I've used the following, which defines a function that takes latex code as input and appends the MathJax processed svg to a target SVG element.

    // 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 = "";
      });
    };
    

    In the above, I'm assuming an html host document with svg elements within. It should also work in a svg host document too.

    0 讨论(0)
  • 2021-02-04 00:19

    There is a way to include MathJax SVG elements in an SVG diagram, without requiring foreignObject. A full demonstration of the technique is at http://puzlet.com/m/b00b3.

    Say you have an SVG diagram like this (and containing any SVG elements) in your web page:

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

    and the following MathJax:

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

    Use this CoffeeScript (plus jQuery) to integrate the MathJax element into your SVG diagram:

    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
    

    You can also use the width() and height() methods for centering and vertical alignment.

    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
    
    0 讨论(0)
提交回复
热议问题