diff --git a/IPython/core/display.py b/IPython/core/display.py index 57375c2..d113216 100644 --- a/IPython/core/display.py +++ b/IPython/core/display.py @@ -119,4 +119,12 @@ def display_json(*objs): display(*objs, include=['text/plain','application/json']) +def display_javascript(*objs): + """Display the Javascript representation of an object. + Parameters + ---------- + objs : tuple of objects + The Python objects to display. + """ + display(*objs, include=['text/plain','application/javascript']) diff --git a/IPython/core/formatters.py b/IPython/core/formatters.py index 40afd48..fb09863 100644 --- a/IPython/core/formatters.py +++ b/IPython/core/formatters.py @@ -52,7 +52,8 @@ class DisplayFormatter(Configurable): SVGFormatter, PNGFormatter, LatexFormatter, - JSONFormatter + JSONFormatter, + JavascriptFormatter ] d = {} for cls in formatter_classes: @@ -220,15 +221,14 @@ class BaseFormatter(Configurable): obj_id = id(obj) try: obj_class = getattr(obj, '__class__', None) or type(obj) - if hasattr(obj_class, self.print_method): - printer = getattr(obj_class, self.print_method) - return printer(obj) + # First try to find registered singleton printers for the type. try: printer = self.singleton_printers[obj_id] except (TypeError, KeyError): pass else: return printer(obj) + # Next look for type_printers. for cls in pretty._get_mro(obj_class): if cls in self.type_printers: return self.type_printers[cls](obj) @@ -236,6 +236,10 @@ class BaseFormatter(Configurable): printer = self._in_deferred_types(cls) if printer is not None: return printer(obj) + # Finally look for special method names. + if hasattr(obj_class, self.print_method): + printer = getattr(obj_class, self.print_method) + return printer(obj) return None except Exception: pass @@ -442,66 +446,80 @@ class HTMLFormatter(BaseFormatter): """An HTML formatter. To define the callables that compute the HTML representation of your - objects, define a :meth:`__html__` method or use the :meth:`for_type` + objects, define a :meth:`_repr_html_` method or use the :meth:`for_type` or :meth:`for_type_by_name` methods to register functions that handle this. """ format_type = Str('text/html') - print_method = Str('__html__') + print_method = Str('_repr_html_') class SVGFormatter(BaseFormatter): """An SVG formatter. To define the callables that compute the SVG representation of your - objects, define a :meth:`__svg__` method or use the :meth:`for_type` + objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type` or :meth:`for_type_by_name` methods to register functions that handle this. """ format_type = Str('image/svg+xml') - print_method = Str('__svg__') + print_method = Str('_repr_svg_') class PNGFormatter(BaseFormatter): """A PNG formatter. To define the callables that compute the PNG representation of your - objects, define a :meth:`__png__` method or use the :meth:`for_type` + objects, define a :meth:`_repr_png_` method or use the :meth:`for_type` or :meth:`for_type_by_name` methods to register functions that handle - this. The raw data should be the base64 encoded raw png data. + this. + + The raw data should be the base64 encoded raw png data. """ format_type = Str('image/png') - print_method = Str('__png__') + print_method = Str('_repr_png_') class LatexFormatter(BaseFormatter): """A LaTeX formatter. To define the callables that compute the LaTeX representation of your - objects, define a :meth:`__latex__` method or use the :meth:`for_type` + objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type` or :meth:`for_type_by_name` methods to register functions that handle this. """ format_type = Str('text/latex') - print_method = Str('__latex__') + print_method = Str('_repr_latex_') class JSONFormatter(BaseFormatter): """A JSON string formatter. To define the callables that compute the JSON string representation of - your objects, define a :meth:`__json__` method or use the :meth:`for_type` + your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type` or :meth:`for_type_by_name` methods to register functions that handle this. """ format_type = Str('application/json') - print_method = Str('__json__') + print_method = Str('_repr_json_') + + +class JavascriptFormatter(BaseFormatter): + """A Javascript formatter. + + To define the callables that compute the Javascript representation of + your objects, define a :meth:`_repr_javascript_` method or use the + :meth:`for_type` or :meth:`for_type_by_name` methods to register functions + that handle this. + """ + format_type = Str('application/javascript') + print_method = Str('_repr_javascript_') FormatterABC.register(BaseFormatter) FormatterABC.register(PlainTextFormatter) @@ -510,6 +528,7 @@ FormatterABC.register(SVGFormatter) FormatterABC.register(PNGFormatter) FormatterABC.register(LatexFormatter) FormatterABC.register(JSONFormatter) +FormatterABC.register(JavascriptFormatter) def format_display_data(obj, include=None, exclude=None): diff --git a/IPython/core/usage.py b/IPython/core/usage.py index 01eff9e..b2237f6 100644 --- a/IPython/core/usage.py +++ b/IPython/core/usage.py @@ -458,7 +458,7 @@ Python objects can simply be passed to these functions and the appropriate representations will be displayed in the console as long as the objects know how to compute those representations. The easiest way of teaching objects how to format themselves in various representations is to define special methods -such as: ``__html``, ``__svg__`` and ``__png__``. IPython's display formatters +such as: ``_repr_html_``, ``_repr_svg_`` and ``_repr_png_``. IPython's display formatters can also be given custom formatter functions for various types:: In [6]: ip = get_ipython() diff --git a/IPython/extensions/sympy_printing.py b/IPython/extensions/sympy_printing.py index 3633469..57e2dde 100644 --- a/IPython/extensions/sympy_printing.py +++ b/IPython/extensions/sympy_printing.py @@ -39,7 +39,7 @@ def print_basic_unicode(o, p, cycle): def print_png(o): - """A funciton to display sympy expression using LaTex -> PNG.""" + """A function to display sympy expression using LaTex -> PNG.""" s = latex(o, mode='inline') # mathtext does not understand certain latex flags, so we try to replace # them with suitable subs. diff --git a/IPython/lib/pylabtools.py b/IPython/lib/pylabtools.py index a7afc26..ec03e46 100644 --- a/IPython/lib/pylabtools.py +++ b/IPython/lib/pylabtools.py @@ -60,7 +60,8 @@ def getfigs(*fig_nums): f = Gcf.figs.get(num) if f is None: print('Warning: figure %s not available.' % num) - figs.append(f.canvas.figure) + else: + figs.append(f.canvas.figure) return figs diff --git a/docs/examples/core/display.py b/docs/examples/core/display.py new file mode 100644 index 0000000..c460e70 --- /dev/null +++ b/docs/examples/core/display.py @@ -0,0 +1,26 @@ +"""Code that shows off the IPython display logic. +""" + +from IPython.core.display import ( + display, display_pretty, display_html, + display_svg, display_json +) + +class Circle(object): + + def __init__(self, radius): + self.radius = radius + + def _repr_pretty_(self, p, cycle): + p.text(u"\u25CB") + + __pretty__ = _repr_pretty_ + + def _repr_html_(self): + return "

Cirle: radius=%s

" % self.radius + + def _repr_svg_(self): + return """ + +""" +