From ba882bf73e0e1974d6fc9e36d59e89ee7d7e7986 2012-04-15 01:39:54 From: Fernando Perez Date: 2012-04-15 01:39:54 Subject: [PATCH] Merge pull request #1399 from asmeurer/sympyprinting Use LaTeX to display, on output, various built-in types with the SymPy printing extension. SymPy's latex() function supports printing lists, tuples, and dicts using latex notation (it uses bmatrix, pmatrix, and Bmatrix, respectively). This provides a more unified experience with SymPy functions that return these types (such as solve()). Also display ints, longs, and floats using LaTeX, to get a more unified printing experience (so that, e.g., x/x will print the same as just 1). The string form can always be obtained by manually calling the actual print function, or 2d unicode printing using pprint(). SymPy's latex() function doesn't treat set() or frosenset() correctly presently (see http://code.google.com/p/sympy/issues /detail?id=3062), so for the present, we leave those alone. --- diff --git a/IPython/extensions/sympyprinting.py b/IPython/extensions/sympyprinting.py index a607ddd..be0cfb9 100644 --- a/IPython/extensions/sympyprinting.py +++ b/IPython/extensions/sympyprinting.py @@ -30,7 +30,6 @@ try: except ImportError: pass - #----------------------------------------------------------------------------- # Definitions of magic functions for use with IPython #----------------------------------------------------------------------------- @@ -55,14 +54,32 @@ def print_png(o): png = latex_to_png(s) 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)): + 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.""" - s = latex(o, mode='plain') - s = s.replace('\\dag','\\dagger') - s = s.strip('$') - return '$$%s$$' % s - + """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 @@ -72,7 +89,9 @@ def load_ipython_extension(ip): if not _loaded: plaintext_formatter = ip.display_formatter.formatters['text/plain'] - for cls in (object, tuple, list, set, frozenset, dict, str): + for cls in (object, set, frozenset, str): + # set and frozen set are currently broken with SymPy's latex() + # function. See http://code.google.com/p/sympy/issues/detail?id=3062. plaintext_formatter.for_type(cls, print_basic_unicode) plaintext_formatter.for_type_by_name( @@ -87,6 +106,8 @@ def load_ipython_extension(ip): png_formatter.for_type_by_name( 'sympy.core.basic', 'Basic', print_png ) + for cls in (list, tuple, dict, int, long, float): + png_formatter.for_type(cls, print_png) latex_formatter = ip.display_formatter.formatters['text/latex'] latex_formatter.for_type_by_name( @@ -95,5 +116,9 @@ def load_ipython_extension(ip): latex_formatter.for_type_by_name( 'sympy.matrices.matrices', 'Matrix', print_latex ) - _loaded = True + for cls in (list, tuple): + # Use LaTeX only if every element is printable by latex + latex_formatter.for_type(cls, print_latex) + + _loaded = True