Kano001's picture
Upload 3077 files
6a86ad5 verified
raw
history blame
3.39 kB
"""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')