Torben
Torben

Reputation: 61

Custom sympy MathJax attributes in jupyter

I'm trying to make sympy render expressions with custom attributes in the resulting MathJax under Jupyter. I can make it work if I explicitly render it using IPython.display.HTML however I wish to make this the default way sympy renders expressions.

from sympy.printing.mathml import MathMLPresentationPrinter
from sympy import init_printing,Symbol,Function
from sympy.abc import x,y,z
from IPython.display import HTML


class MyMathMLPresentationPrinter(MathMLPresentationPrinter):
    def _print(self,expr):
        res=super()._print(expr)
        res.attributes['myattrib']='myvalue'
        return(res)

    def doprint(self, expr):
        mathML = self._print(expr)
        unistr = mathML.toxml()
        xmlbstr = unistr.encode('ascii', 'xmlcharrefreplace')
        res = xmlbstr.decode()
        return res


F=Function('F')
expr=F(x).diff(x)

The result I wish can be generated using (You'll need to use the Inspector in Firefox, or the like, to see it).

ml=MyMathMLPresentationPrinter()._print(expr).toxml()
HTML('<math>'+ml+'</math>')

I tried to do the following, but that did not solve the problem.

def my_print(expr, **settings):
    ml= MyMathMLPresentationPrinter().doprint(expr)
    return ml
sympy.init_printing(pretty_printer=my_print,pretty_print=True,use_latex=False)

expr

Any suggestions on how to make this work?

Thanks

Upvotes: 1

Views: 132

Answers (1)

Torben
Torben

Reputation: 61

In case anybody else need this, the following will do what I wanted

from sympy.printing.mathml import MathMLPresentationPrinter
from sympy import init_printing,Symbol,Function
from sympy.abc import x,y
from IPython.display import HTML
from sympy.core.basic import Basic

class MyMathMLPresentationPrinter(MathMLPresentationPrinter):
    def _print(self,expr):
        res=super()._print(expr)
        res.attributes['sympyclass']=type(expr).__name__
        return(res)

    def _print_AppliedUndef(self, e):
        mrow = self.dom.createElement('mrow')
        x = self.dom.createElement('mi')
        x.appendChild(self.dom.createTextNode(e.__class__.__name__))
        y = self.dom.createElement('mfenced')
        for arg in e.args:
            y.appendChild(self._print(arg))
        mrow.appendChild(x)
        mrow.appendChild(y)
        return mrow

    def doprint(self, expr):
        mathML = self._print(expr)
        unistr = mathML.toxml()
        xmlbstr = unistr.encode('ascii', 'xmlcharrefreplace')
        res = xmlbstr.decode()
        return res


def basic_html(obj):
    ml=MyMathMLPresentationPrinter()._print(obj).toxml()
    return '<math>'+ml+'</math>'

html_formatter = get_ipython().display_formatter.formatters['text/html']
html_formatter.for_type(Basic, basic_html)

init_printing()
F=Function('F')
expr=F(x).diff(x)
expr

Upvotes: 1

Related Questions