Spaces:
Running
Running
File size: 3,388 Bytes
6a86ad5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
"""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')
|