"""Module with some functions for MathML, like transforming MathML content in MathML presentation. To use this module, you will need lxml. """ from pathlib import Path from sympy.utilities.decorator import doctest_depends_on __doctest_requires__ = {('apply_xsl', 'c2p'): ['lxml']} def add_mathml_headers(s): return """<math xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/1998/Math/MathML http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd">""" + s + "</math>" def _read_binary(pkgname, filename): import sys if sys.version_info >= (3, 10): # files was added in Python 3.9 but only seems to work here in 3.10+ from importlib.resources import files return files(pkgname).joinpath(filename).read_bytes() else: # read_binary was deprecated in Python 3.11 from importlib.resources import read_binary return read_binary(pkgname, filename) def _read_xsl(xsl): # Previously these values were allowed: if xsl == 'mathml/data/simple_mmlctop.xsl': xsl = 'simple_mmlctop.xsl' elif xsl == 'mathml/data/mmlctop.xsl': xsl = 'mmlctop.xsl' elif xsl == 'mathml/data/mmltex.xsl': xsl = 'mmltex.xsl' if xsl in ['simple_mmlctop.xsl', 'mmlctop.xsl', 'mmltex.xsl']: xslbytes = _read_binary('sympy.utilities.mathml.data', xsl) else: xslbytes = Path(xsl).read_bytes() return xslbytes @doctest_depends_on(modules=('lxml',)) def apply_xsl(mml, xsl): """Apply a xsl to a MathML string. Parameters ========== mml A string with MathML code. xsl A string giving the name of an xsl (xml stylesheet) file which can be found in sympy/utilities/mathml/data. The following files are supplied with SymPy: - mmlctop.xsl - mmltex.xsl - simple_mmlctop.xsl Alternatively, a full path to an xsl file can be given. Examples ======== >>> from sympy.utilities.mathml import apply_xsl >>> xsl = 'simple_mmlctop.xsl' >>> mml = '<apply> <plus/> <ci>a</ci> <ci>b</ci> </apply>' >>> res = apply_xsl(mml,xsl) >>> print(res) <?xml version="1.0"?> <mrow xmlns="http://www.w3.org/1998/Math/MathML"> <mi>a</mi> <mo> + </mo> <mi>b</mi> </mrow> """ from lxml import etree parser = etree.XMLParser(resolve_entities=False) ac = etree.XSLTAccessControl.DENY_ALL s = etree.XML(_read_xsl(xsl), parser=parser) transform = etree.XSLT(s, access_control=ac) doc = etree.XML(mml, parser=parser) result = transform(doc) s = str(result) return s @doctest_depends_on(modules=('lxml',)) def c2p(mml, simple=False): """Transforms a document in MathML content (like the one that sympy produces) in one document in MathML presentation, more suitable for printing, and more widely accepted Examples ======== >>> from sympy.utilities.mathml import c2p >>> mml = '<apply> <exp/> <cn>2</cn> </apply>' >>> c2p(mml,simple=True) != c2p(mml,simple=False) True """ if not mml.startswith('<math'): mml = add_mathml_headers(mml) if simple: return apply_xsl(mml, 'mathml/data/simple_mmlctop.xsl') return apply_xsl(mml, 'mathml/data/mmlctop.xsl')
Memory