| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- """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')
|