sympyprinting.py
171 lines
| 5.5 KiB
| text/x-python
|
PythonLexer
Pauli Virtanen
|
r4888 | """ | ||
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. | ||||
Brian Granger
|
r3278 | |||
Sean Vig
|
r8574 | As of SymPy 0.7.2, maintenance of this extension has moved to SymPy under | ||
sympy.interactive.ipythonprinting, any modifications to account for changes to | ||||
SymPy should be submitted to SymPy rather than changed here. This module is | ||||
maintained here for backwards compatablitiy with old SymPy versions. | ||||
Brian Granger
|
r3278 | """ | ||
#----------------------------------------------------------------------------- | ||||
Takafumi Arakaki
|
r7311 | # Copyright (C) 2008 The IPython Development Team | ||
Brian Granger
|
r3278 | # | ||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
Brian Granger
|
r3279 | from IPython.lib.latextools import latex_to_png | ||
Paul Ivanov
|
r3504 | from IPython.testing import decorators as dec | ||
Paul Ivanov
|
r3507 | # use @dec.skipif_not_sympy to skip tests requiring sympy | ||
Paul Ivanov
|
r3504 | |||
try: | ||||
from sympy import pretty, latex | ||||
except ImportError: | ||||
pass | ||||
Brian Granger
|
r3279 | |||
Sean Vig
|
r8574 | import warnings | ||
Brian Granger
|
r3278 | #----------------------------------------------------------------------------- | ||
Fernando Perez
|
r6934 | # Definitions of special display functions for use with IPython | ||
Brian Granger
|
r3278 | #----------------------------------------------------------------------------- | ||
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) | ||||
Brian Granger
|
r3279 | def print_png(o): | ||
Takafumi Arakaki
|
r7310 | """ | ||
A function to display sympy expression using inline style LaTeX in PNG. | ||||
""" | ||||
Brian Granger
|
r3283 | s = latex(o, mode='inline') | ||
Brian Granger
|
r3285 | # mathtext does not understand certain latex flags, so we try to replace | ||
# them with suitable subs. | ||||
Brian Granger
|
r3284 | s = s.replace('\\operatorname','') | ||
Brian Granger
|
r3285 | s = s.replace('\\overline', '\\bar') | ||
Brian Granger
|
r3880 | png = latex_to_png(s) | ||
Brian Granger
|
r3279 | return png | ||
Takafumi Arakaki
|
r7307 | |||
def print_display_png(o): | ||||
Takafumi Arakaki
|
r7310 | """ | ||
A function to display sympy expression using display style LaTeX in PNG. | ||||
""" | ||||
Takafumi Arakaki
|
r7307 | s = latex(o, mode='plain') | ||
s = s.strip('$') | ||||
Takafumi Arakaki
|
r7310 | # As matplotlib does not support display style, dvipng backend is | ||
# used here. | ||||
Takafumi Arakaki
|
r7852 | png = latex_to_png(s, backend='dvipng', wrap=True) | ||
Takafumi Arakaki
|
r7307 | return png | ||
Aaron Meurer
|
r6297 | 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 | ||||
Aaron Meurer
|
r7039 | if isinstance(o, (list, tuple, set, frozenset)): | ||
Aaron Meurer
|
r6297 | 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 | ||||
Brian Granger
|
r4316 | |||
def print_latex(o): | ||||
Aaron Meurer
|
r6297 | """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 | ||||
Brian Granger
|
r4316 | |||
Brian Granger
|
r3278 | _loaded = False | ||
def load_ipython_extension(ip): | ||||
"""Load the extension in IPython.""" | ||||
Aaron Meurer
|
r7039 | import sympy | ||
Sean Vig
|
r8574 | |||
# sympyprinting extension has been moved to SymPy as of 0.7.2, if it | ||||
# exists there, warn the user and import it | ||||
try: | ||||
import sympy.interactive.ipythonprinting | ||||
except ImportError: | ||||
pass | ||||
else: | ||||
warnings.warn("The sympyprinting extension in IPython is deprecated, " | ||||
Aaron Meurer
|
r11066 | "use 'from sympy import init_printing; init_printing()'") | ||
Sean Vig
|
r8574 | ip.extension_manager.load_extension('sympy.interactive.ipythonprinting') | ||
return | ||||
Brian Granger
|
r3278 | global _loaded | ||
if not _loaded: | ||||
plaintext_formatter = ip.display_formatter.formatters['text/plain'] | ||||
Brian E. Granger
|
r4270 | |||
Aaron Meurer
|
r7039 | for cls in (object, str): | ||
plaintext_formatter.for_type(cls, print_basic_unicode) | ||||
printable_containers = [list, tuple] | ||||
Aaron Meurer
|
r7092 | # 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': | ||||
Aaron Meurer
|
r7039 | printable_containers += [set, frozenset] | ||
Aaron Meurer
|
r7092 | else: | ||
plaintext_formatter.for_type(cls, print_basic_unicode) | ||||
Brian E. Granger
|
r4270 | |||
Brian Granger
|
r3278 | plaintext_formatter.for_type_by_name( | ||
'sympy.core.basic', 'Basic', print_basic_unicode | ||||
) | ||||
Brian Granger
|
r3285 | plaintext_formatter.for_type_by_name( | ||
'sympy.matrices.matrices', 'Matrix', print_basic_unicode | ||||
) | ||||
Brian Granger
|
r3279 | png_formatter = ip.display_formatter.formatters['image/png'] | ||
Brian E. Granger
|
r4270 | |||
Brian Granger
|
r3279 | png_formatter.for_type_by_name( | ||
'sympy.core.basic', 'Basic', print_png | ||||
) | ||||
Takafumi Arakaki
|
r7307 | png_formatter.for_type_by_name( | ||
'sympy.matrices.matrices', 'Matrix', print_display_png | ||||
) | ||||
Aaron Meurer
|
r7039 | for cls in [dict, int, long, float] + printable_containers: | ||
Aaron Meurer
|
r6110 | png_formatter.for_type(cls, print_png) | ||
Brian Granger
|
r4316 | |||
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 | ||||
) | ||||
Aaron Meurer
|
r6297 | |||
Aaron Meurer
|
r7039 | for cls in printable_containers: | ||
Aaron Meurer
|
r6297 | # Use LaTeX only if every element is printable by latex | ||
Aaron Meurer
|
r6110 | latex_formatter.for_type(cls, print_latex) | ||
Brian Granger
|
r3278 | |||
Aaron Meurer
|
r6110 | _loaded = True | ||