Search code examples
sympypython-sphinx

Capturing sympy math output in sphinx-gallery


I am trying to write an sphinx-gallery example for a module that uses sympy. I cannot find a way to get the output formatted like math. For example, in jupyter notebooks, the output of a sympy expression is rendered in mathmode. In an example rendered with sphinx using sphinx-gallery, just the string is shown.

I tried using the functions in sympy.printing.mathml and monkey patching the expressions to show, e.g.

#%%
# Should show this
#
# .. math::
#     \dot{x} = x y^2 - \frac{\sqrt{x}}{y}
#
from sympy.printing.mathml import mathml
from sympy.core.evalf import EvalfMixin

def print_html(expr):
    return f'<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">{mathml(expr)}</math>'
    
EvalfMixin._repr_html_ = print_html

from sympy import symbols, Symbol, Eq, sqrt
x, y = symbols("x y")

expr = Eq(Symbol(r"\dot{x}"), x*y**2 - sqrt(x)/y)
expr

screen capture of code above generated by sphinx-gallery

The error is

<math xmlns="http://www.w3.org/1998/Math/MathML">
  <merror data-mjx-error="Unknown node type &quot;apply&quot;" title="Unknown node type &quot;apply&quot;">
    <mtext>Math input error</mtext>
  </merror>
</math>

So it would seem the MathML is not correct.

The html generated by my hack is this

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><apply><eq></eq><ci>\dot{x}</ci><apply><plus></plus><apply><minus></minus><apply><divide></divide><apply><root></root><ci>x</ci></apply><ci>y</ci></apply></apply><apply><times></times><ci>x</ci><apply><power></power><ci>y</ci><cn>2</cn></apply></apply></apply></apply></math>

and the one generated by the cell before it is

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <mrow data-mjx-texclass="ORD">
    <mover>
      <mi>x</mi>
      <mo>&#x2D9;</mo>
    </mover>
  </mrow>
  <mo>=</mo>
  <mi>x</mi>
  <msup>
    <mi>y</mi>
    <mn>2</mn>
  </msup>
  <mo>&#x2212;</mo>
  <mfrac>
    <msqrt>
      <mi>x</mi>
    </msqrt>
    <mi>y</mi>
  </mfrac>
</math>

Definitely not the same.

Is there a known way to do this properly?


Solution

  • The following solution renders latex code with mathjax. I still cannot generate svg math, but this works with internet access

    """
    Testing sympy mathml
    ====================
    """
    # %%
    # Should show this
    #
    # .. math::
    #     \dot{x} = x y^2 - \frac{\sqrt{x}}{y}
    #
    from sympy import latex
    from sympy.core.evalf import EvalfMixin
    from sympy.matrices.repmatrix import MutableRepMatrix
    
    
    def print_html(expr):
        return f'{latex(expr, mode="equation*", itex=True)}'
    
    
    EvalfMixin._repr_html_ = print_html
    MutableRepMatrix._repr_html_ = print_html
    
    from sympy import symbols, Symbol, Eq, sqrt
    
    x, y = symbols("x y")
    
    expr = Eq(Symbol(r"\dot{x}"), x * y ** 2 - sqrt(x) / y)
    expr
    

    The results is

    enter image description here