Navigation

Source code for sympy.interactive.printing

"""Tools for setting up printing in interactive sessions. """from__future__importprint_function,divisionimportsysfromdistutils.versionimportLooseVersionasVfromioimportBytesIOfromsympyimportlatexasdefault_latexfromsympyimportpreviewfromsympy.core.compatibilityimportinteger_typesfromsympy.utilities.miscimportdebugdef_init_python_printing(stringify_func,**settings):"""Setup printing in Python interactive session. """importsysfromsympy.core.compatibilityimportbuiltinsdef_displayhook(arg):"""Python's pretty-printer display hook. This function was adapted from: http://www.python.org/dev/peps/pep-0217/ """ifargisnotNone:builtins._=Noneprint(stringify_func(arg,**settings))builtins._=argsys.displayhook=_displayhookdef_init_ipython_printing(ip,stringify_func,use_latex,euler,forecolor,backcolor,fontsize,latex_mode,print_builtin,latex_printer,**settings):"""Setup printing in IPython interactive session. """try:fromIPython.lib.latextoolsimportlatex_to_pngexceptImportError:passpreamble="\\documentclass[%s]{article}\n" \
"\\pagestyle{empty}\n" \
"\\usepackage{amsmath,amsfonts}%s\\begin{document}"ifeuler:addpackages='\\usepackage{euler}'else:addpackages=''preamble=preamble%(fontsize,addpackages)imagesize='tight'offset="0cm,0cm"resolution=150dvi=r"-T %s -D %d -bg %s -fg %s -O %s"%(imagesize,resolution,backcolor,forecolor,offset)dvioptions=dvi.split()debug("init_printing: DVIOPTIONS:",dvioptions)debug("init_printing: PREAMBLE:",preamble)latex=latex_printerordefault_latexdef_print_plain(arg,p,cycle):"""caller for pretty, for use in IPython 0.11"""if_can_print_latex(arg):p.text(stringify_func(arg))else:p.text(IPython.lib.pretty.pretty(arg))def_preview_wrapper(o):exprbuffer=BytesIO()try:preview(o,output='png',viewer='BytesIO',outputbuffer=exprbuffer,preamble=preamble,dvioptions=dvioptions)exceptExceptionase:# IPython swallows exceptionsdebug("png printing:","_preview_wrapper exception raised:",repr(e))raisereturnexprbuffer.getvalue()def_matplotlib_wrapper(o):# mathtext does not understand certain latex flags, so we try to# replace them with suitable subso=o.replace(r'\operatorname','')o=o.replace(r'\overline',r'\bar')# mathtext can't render some LaTeX commands. For example, it can't# render any LaTeX environments such as array or matrix. So here we# ensure that if mathtext fails to render, we return None.try:returnlatex_to_png(o)exceptValueErrorase:debug('matplotlib exception caught:',repr(e))returnNonedef_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. """try:fromsympyimportBasicfromsympy.matricesimportMatrixBasefromsympy.physics.vectorimportVector,Dyadicfromsympy.tensor.arrayimportNDimArray# If you're adding another type, make sure you add it to printable_types# later in this file as wellifisinstance(o,(list,tuple,set,frozenset)):returnall(_can_print_latex(i)foriino)elifisinstance(o,dict):returnall(_can_print_latex(i)and_can_print_latex(o[i])foriino)elifisinstance(o,bool):returnFalse# TODO : Investigate if "elif hasattr(o, '_latex')" is more useful# to use here, than these explicit imports.elifisinstance(o,(Basic,MatrixBase,Vector,Dyadic,NDimArray)):returnTrueelifisinstance(o,(float,integer_types))andprint_builtin:returnTruereturnFalseexceptRuntimeError:returnFalse# This is in case maximum recursion depth is reached.# Since RecursionError is for versions of Python 3.5+# so this is to guard against RecursionError for older versions.def_print_latex_png(o):""" A function that returns a png rendered by an external latex distribution, falling back to matplotlib rendering """if_can_print_latex(o):s=latex(o,mode=latex_mode,**settings)try:return_preview_wrapper(s)exceptRuntimeErrorase:debug('preview failed with:',repr(e),' Falling back to matplotlib backend')iflatex_mode!='inline':s=latex(o,mode='inline',**settings)return_matplotlib_wrapper(s)def_print_latex_matplotlib(o):""" A function that returns a png rendered by mathtext """if_can_print_latex(o):s=latex(o,mode='inline',**settings)return_matplotlib_wrapper(s)def_print_latex_text(o):""" A function to generate the latex representation of sympy expressions. """if_can_print_latex(o):s=latex(o,mode='plain',**settings)s=s.replace(r'\dag',r'\dagger')s=s.strip('$')return'$$%s$$'%sdef_result_display(self,arg):"""IPython's pretty-printer display hook, for use in IPython 0.10 This function was adapted from: ipython/IPython/hooks.py:155 """ifself.rc.pprint:out=stringify_func(arg)if'\n'inout:printprint(out)else:print(repr(arg))importIPythonifV(IPython.__version__)>='0.11':fromsympy.core.basicimportBasicfromsympy.matrices.matricesimportMatrixBasefromsympy.physics.vectorimportVector,Dyadicfromsympy.tensor.arrayimportNDimArrayprintable_types=[Basic,MatrixBase,float,tuple,list,set,frozenset,dict,Vector,Dyadic,NDimArray]+list(integer_types)plaintext_formatter=ip.display_formatter.formatters['text/plain']forclsinprintable_types:plaintext_formatter.for_type(cls,_print_plain)png_formatter=ip.display_formatter.formatters['image/png']ifuse_latexin(True,'png'):debug("init_printing: using png formatter")forclsinprintable_types:png_formatter.for_type(cls,_print_latex_png)elifuse_latex=='matplotlib':debug("init_printing: using matplotlib formatter")forclsinprintable_types:png_formatter.for_type(cls,_print_latex_matplotlib)else:debug("init_printing: not using any png formatter")forclsinprintable_types:# Better way to set this, but currently does not work in IPython#png_formatter.for_type(cls, None)ifclsinpng_formatter.type_printers:png_formatter.type_printers.pop(cls)latex_formatter=ip.display_formatter.formatters['text/latex']ifuse_latexin(True,'mathjax'):debug("init_printing: using mathjax formatter")forclsinprintable_types:latex_formatter.for_type(cls,_print_latex_text)else:debug("init_printing: not using text/latex formatter")forclsinprintable_types:# Better way to set this, but currently does not work in IPython#latex_formatter.for_type(cls, None)ifclsinlatex_formatter.type_printers:latex_formatter.type_printers.pop(cls)else:ip.set_hook('result_display',_result_display)def_is_ipython(shell):"""Is a shell instance an IPython shell?"""# shortcut, so we don't import IPython if we don't have toif'IPython'notinsys.modules:returnFalsetry:fromIPython.core.interactiveshellimportInteractiveShellexceptImportError:# IPython < 0.11try:fromIPython.iplibimportInteractiveShellexceptImportError:# Reaching this points means IPython has changed in a backward-incompatible way# that we don't know about. Warn?returnFalsereturnisinstance(shell,InteractiveShell)

[docs]definit_printing(pretty_print=True,order=None,use_unicode=None,use_latex=None,wrap_line=None,num_columns=None,no_global=False,ip=None,euler=False,forecolor='Black',backcolor='Transparent',fontsize='10pt',latex_mode='equation*',print_builtin=True,str_printer=None,pretty_printer=None,latex_printer=None,**settings):r""" Initializes pretty-printer depending on the environment. Parameters ========== pretty_print: boolean If True, use pretty_print to stringify or the provided pretty printer; if False, use sstrrepr to stringify or the provided string printer. order: string or None There are a few different settings for this parameter: lex (default), which is lexographic order; grlex, which is graded lexographic order; grevlex, which is reversed graded lexographic order; old, which is used for compatibility reasons and for long expressions; None, which sets it to lex. use_unicode: boolean or None If True, use unicode characters; if False, do not use unicode characters. use_latex: string, boolean, or None If True, use default latex rendering in GUI interfaces (png and mathjax); if False, do not use latex rendering; if 'png', enable latex rendering with an external latex compiler, falling back to matplotlib if external compilation fails; if 'matplotlib', enable latex rendering with matplotlib; if 'mathjax', enable latex text generation, for example MathJax rendering in IPython notebook or text rendering in LaTeX documents wrap_line: boolean If True, lines will wrap at the end; if False, they will not wrap but continue as one line. This is only relevant if `pretty_print` is True. num_columns: int or None If int, number of columns before wrapping is set to num_columns; if None, number of columns before wrapping is set to terminal width. This is only relevant if `pretty_print` is True. no_global: boolean If True, the settings become system wide; if False, use just for this console/session. ip: An interactive console This can either be an instance of IPython, or a class that derives from code.InteractiveConsole. euler: boolean, optional, default=False Loads the euler package in the LaTeX preamble for handwritten style fonts (http://www.ctan.org/pkg/euler). forecolor: string, optional, default='Black' DVI setting for foreground color. backcolor: string, optional, default='Transparent' DVI setting for background color. fontsize: string, optional, default='10pt' A font size to pass to the LaTeX documentclass function in the preamble. latex_mode: string, optional, default='equation*' The mode used in the LaTeX printer. Can be one of: {'inline'|'plain'|'equation'|'equation*'}. print_builtin: boolean, optional, default=True If true then floats and integers will be printed. If false the printer will only print SymPy types. str_printer: function, optional, default=None A custom string printer function. This should mimic sympy.printing.sstrrepr(). pretty_printer: function, optional, default=None A custom pretty printer. This should mimic sympy.printing.pretty(). latex_printer: function, optional, default=None A custom LaTeX printer. This should mimic sympy.printing.latex(). Examples ======== >>> from sympy.interactive import init_printing >>> from sympy import Symbol, sqrt >>> from sympy.abc import x, y >>> sqrt(5) sqrt(5) >>> init_printing(pretty_print=True) # doctest: +SKIP >>> sqrt(5) # doctest: +SKIP ___ \/ 5 >>> theta = Symbol('theta') # doctest: +SKIP >>> init_printing(use_unicode=True) # doctest: +SKIP >>> theta # doctest: +SKIP \u03b8 >>> init_printing(use_unicode=False) # doctest: +SKIP >>> theta # doctest: +SKIP theta >>> init_printing(order='lex') # doctest: +SKIP >>> str(y + x + y**2 + x**2) # doctest: +SKIP x**2 + x + y**2 + y >>> init_printing(order='grlex') # doctest: +SKIP >>> str(y + x + y**2 + x**2) # doctest: +SKIP x**2 + x + y**2 + y >>> init_printing(order='grevlex') # doctest: +SKIP >>> str(y * x**2 + x * y**2) # doctest: +SKIP x**2*y + x*y**2 >>> init_printing(order='old') # doctest: +SKIP >>> str(x**2 + y**2 + x + y) # doctest: +SKIP x**2 + x + y**2 + y >>> init_printing(num_columns=10) # doctest: +SKIP >>> x**2 + x + y**2 + y # doctest: +SKIP x + y + x**2 + y**2 """importsysfromsympy.printing.printerimportPrinterifpretty_print:ifpretty_printerisnotNone:stringify_func=pretty_printerelse:fromsympy.printingimportprettyasstringify_funcelse:ifstr_printerisnotNone:stringify_func=str_printerelse:fromsympy.printingimportsstrreprasstringify_func# Even if ip is not passed, double check that not in IPython shellin_ipython=FalseifipisNone:try:ip=get_ipython()exceptNameError:passelse:in_ipython=(ipisnotNone)ifipandnotin_ipython:in_ipython=_is_ipython(ip)ifin_ipythonandpretty_print:try:importIPython# IPython 1.0 deprecates the frontend module, so we import directly# from the terminal module to prevent a deprecation message from being# shown.ifV(IPython.__version__)>='1.0':fromIPython.terminal.interactiveshellimportTerminalInteractiveShellelse:fromIPython.frontend.terminal.interactiveshellimportTerminalInteractiveShellfromcodeimportInteractiveConsoleexceptImportError:passelse:# This will be True if we are in the qtconsole or notebookifnotisinstance(ip,(InteractiveConsole,TerminalInteractiveShell)) \
and'ipython-console'notin''.join(sys.argv):ifuse_unicodeisNone:debug("init_printing: Setting use_unicode to True")use_unicode=Trueifuse_latexisNone:debug("init_printing: Setting use_latex to True")use_latex=Trueifnotno_global:Printer.set_global_settings(order=order,use_unicode=use_unicode,wrap_line=wrap_line,num_columns=num_columns)else:_stringify_func=stringify_funcifpretty_print:stringify_func=lambdaexpr: \
_stringify_func(expr,order=order,use_unicode=use_unicode,wrap_line=wrap_line,num_columns=num_columns)else:stringify_func=lambdaexpr:_stringify_func(expr,order=order)ifin_ipython:mode_in_settings=settings.pop("mode",None)ifmode_in_settings:debug("init_printing: Mode is not able to be set due to internals""of IPython printing")_init_ipython_printing(ip,stringify_func,use_latex,euler,forecolor,backcolor,fontsize,latex_mode,print_builtin,latex_printer,**settings)else:_init_python_printing(stringify_func,**settings)