|
|
"""
|
|
|
A print function that pretty prints sympy Basic objects.
|
|
|
|
|
|
:moduleauthor: Brian Granger
|
|
|
|
|
|
Usage
|
|
|
=====
|
|
|
|
|
|
Once the extension is loaded, Sympy Basic objects are automatically
|
|
|
pretty-printed.
|
|
|
|
|
|
"""
|
|
|
#-----------------------------------------------------------------------------
|
|
|
# Copyright (C) 2008 The IPython Development Team
|
|
|
#
|
|
|
# Distributed under the terms of the BSD License. The full license is in
|
|
|
# the file COPYING, distributed as part of this software.
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
# Imports
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
|
|
from IPython.lib.latextools import latex_to_png
|
|
|
from IPython.testing import decorators as dec
|
|
|
# use @dec.skipif_not_sympy to skip tests requiring sympy
|
|
|
|
|
|
try:
|
|
|
from sympy import pretty, latex
|
|
|
except ImportError:
|
|
|
pass
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
# Definitions of special display functions for use with IPython
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
|
|
def print_basic_unicode(o, p, cycle):
|
|
|
"""A function to pretty print sympy Basic objects."""
|
|
|
if cycle:
|
|
|
return p.text('Basic(...)')
|
|
|
out = pretty(o, use_unicode=True)
|
|
|
if '\n' in out:
|
|
|
p.text(u'\n')
|
|
|
p.text(out)
|
|
|
|
|
|
|
|
|
def print_png(o):
|
|
|
"""
|
|
|
A function to display sympy expression using inline style LaTeX in PNG.
|
|
|
"""
|
|
|
s = latex(o, mode='inline')
|
|
|
# mathtext does not understand certain latex flags, so we try to replace
|
|
|
# them with suitable subs.
|
|
|
s = s.replace('\\operatorname','')
|
|
|
s = s.replace('\\overline', '\\bar')
|
|
|
png = latex_to_png(s)
|
|
|
return png
|
|
|
|
|
|
|
|
|
def print_display_png(o):
|
|
|
"""
|
|
|
A function to display sympy expression using display style LaTeX in PNG.
|
|
|
"""
|
|
|
s = latex(o, mode='plain')
|
|
|
s = s.strip('$')
|
|
|
# As matplotlib does not support display style, dvipng backend is
|
|
|
# used here.
|
|
|
png = latex_to_png(s, backend='dvipng', wrap=True)
|
|
|
return png
|
|
|
|
|
|
|
|
|
def can_print_latex(o):
|
|
|
"""
|
|
|
Return True if type o can be printed with LaTeX.
|
|
|
|
|
|
If o is a container type, this is True if and only if every element of o
|
|
|
can be printed with LaTeX.
|
|
|
"""
|
|
|
import sympy
|
|
|
if isinstance(o, (list, tuple, set, frozenset)):
|
|
|
return all(can_print_latex(i) for i in o)
|
|
|
elif isinstance(o, dict):
|
|
|
return all((isinstance(i, basestring) or can_print_latex(i)) and can_print_latex(o[i]) for i in o)
|
|
|
elif isinstance(o,(sympy.Basic, sympy.matrices.Matrix, int, long, float)):
|
|
|
return True
|
|
|
return False
|
|
|
|
|
|
def print_latex(o):
|
|
|
"""A function to generate the latex representation of sympy
|
|
|
expressions."""
|
|
|
if can_print_latex(o):
|
|
|
s = latex(o, mode='plain')
|
|
|
s = s.replace('\\dag','\\dagger')
|
|
|
s = s.strip('$')
|
|
|
return '$$%s$$' % s
|
|
|
# Fallback to the string printer
|
|
|
return None
|
|
|
|
|
|
_loaded = False
|
|
|
|
|
|
def load_ipython_extension(ip):
|
|
|
"""Load the extension in IPython."""
|
|
|
import sympy
|
|
|
global _loaded
|
|
|
if not _loaded:
|
|
|
plaintext_formatter = ip.display_formatter.formatters['text/plain']
|
|
|
|
|
|
for cls in (object, str):
|
|
|
plaintext_formatter.for_type(cls, print_basic_unicode)
|
|
|
|
|
|
printable_containers = [list, tuple]
|
|
|
|
|
|
# set and frozen set were broken with SymPy's latex() function, but
|
|
|
# was fixed in the 0.7.1-git development version. See
|
|
|
# http://code.google.com/p/sympy/issues/detail?id=3062.
|
|
|
if sympy.__version__ > '0.7.1':
|
|
|
printable_containers += [set, frozenset]
|
|
|
else:
|
|
|
plaintext_formatter.for_type(cls, print_basic_unicode)
|
|
|
|
|
|
plaintext_formatter.for_type_by_name(
|
|
|
'sympy.core.basic', 'Basic', print_basic_unicode
|
|
|
)
|
|
|
plaintext_formatter.for_type_by_name(
|
|
|
'sympy.matrices.matrices', 'Matrix', print_basic_unicode
|
|
|
)
|
|
|
|
|
|
png_formatter = ip.display_formatter.formatters['image/png']
|
|
|
|
|
|
png_formatter.for_type_by_name(
|
|
|
'sympy.core.basic', 'Basic', print_png
|
|
|
)
|
|
|
png_formatter.for_type_by_name(
|
|
|
'sympy.matrices.matrices', 'Matrix', print_display_png
|
|
|
)
|
|
|
for cls in [dict, int, long, float] + printable_containers:
|
|
|
png_formatter.for_type(cls, print_png)
|
|
|
|
|
|
latex_formatter = ip.display_formatter.formatters['text/latex']
|
|
|
latex_formatter.for_type_by_name(
|
|
|
'sympy.core.basic', 'Basic', print_latex
|
|
|
)
|
|
|
latex_formatter.for_type_by_name(
|
|
|
'sympy.matrices.matrices', 'Matrix', print_latex
|
|
|
)
|
|
|
|
|
|
for cls in printable_containers:
|
|
|
# Use LaTeX only if every element is printable by latex
|
|
|
latex_formatter.for_type(cls, print_latex)
|
|
|
|
|
|
_loaded = True
|
|
|
|