Skip to content

Commit

Permalink
Enhance ipython#11328 convert height and width parameters to string s…
Browse files Browse the repository at this point in the history
…o percentages and other units can be passed
  • Loading branch information
Nestor Arias committed Oct 19, 2018
1 parent 194d1d7 commit b77fcb2
Showing 1 changed file with 66 additions and 26 deletions.
92 changes: 66 additions & 26 deletions IPython/core/display.py
Expand Up @@ -238,16 +238,22 @@ def display(*objs, include=None, exclude=None, metadata=None, transient=None, di
want to use. Here is a list of the names of the special methods and the
values they must return:
- `_repr_html_`: return raw HTML as a string
- `_repr_json_`: return a JSONable dict
- `_repr_jpeg_`: return raw JPEG data
- `_repr_png_`: return raw PNG data
- `_repr_svg_`: return raw SVG data as a string
- `_repr_latex_`: return LaTeX commands in a string surrounded by "$".
- `_repr_html_`: return raw HTML as a string, or a tuple (see below).
- `_repr_json_`: return a JSONable dict, or a tuple (see below).
- `_repr_jpeg_`: return raw JPEG data, or a tuple (see below).
- `_repr_png_`: return raw PNG data, or a tuple (see below).
- `_repr_svg_`: return raw SVG data as a string, or a tuple (see below).
- `_repr_latex_`: return LaTeX commands in a string surrounded by "$",
or a tuple (see below).
- `_repr_mimebundle_`: return a full mimebundle containing the mapping
from all mimetypes to data.
Use this for any mime-type not listed above.
The above functions may also return the object's metadata alonside the
data. If the metadata is available, the functions will return a tuple
containing the data and metadata, in that order. If there is no metadata
available, then the functions will return the data only.
When you are directly writing your own classes, you can adapt them for
display in IPython by following the above approach. But in practice, you
often need to work with existing classes that you can't easily modify.
Expand All @@ -268,12 +274,12 @@ def display(*objs, include=None, exclude=None, metadata=None, transient=None, di
"""
from IPython.core.interactiveshell import InteractiveShell

if not InteractiveShell.initialized():
# Directly print objects.
print(*objs)
return

raw = kwargs.pop('raw', False)
if transient is None:
transient = {}
Expand Down Expand Up @@ -353,10 +359,10 @@ def __repr__(self):

def display(self, obj, **kwargs):
"""Make a new display with my id, updating existing instances.
Parameters
----------
obj:
object to display
**kwargs:
Expand All @@ -366,10 +372,10 @@ def display(self, obj, **kwargs):

def update(self, obj, **kwargs):
"""Update existing displays with my id
Parameters
----------
obj:
object to display
**kwargs:
Expand Down Expand Up @@ -666,6 +672,23 @@ def _repr_pretty_(self, pp, cycle):

class HTML(TextDisplayObject):

def __init__(self, data=None, url=None, filename=None, metadata=None):
def warn():
if not data:
return False

#
# Avoid calling lower() on the entire data, because it could be a
# long string and we're only interested in its beginning and end.
#
prefix = data[:10].lower()
suffix = data[-10:].lower()
return prefix.startswith("<iframe ") and suffix.endswith("</iframe>")

if warn():
warnings.warn("Consider using IPython.display.IFrame instead")
super(HTML, self).__init__(data=data, url=url, filename=filename, metadata=metadata)

def _repr_html_(self):
return self._data_and_metadata()

Expand All @@ -687,7 +710,7 @@ def _repr_markdown_(self):
class Math(TextDisplayObject):

def _repr_latex_(self):
s = "$$%s$$" % self.data.strip('$')
s = "$\displaystyle %s$" % self.data.strip('$')
if self.metadata:
return s, deepcopy(self.metadata)
else:
Expand Down Expand Up @@ -729,16 +752,16 @@ def data(self, svg):
pass
svg = cast_unicode(svg)
self._data = svg

def _repr_svg_(self):
return self._data_and_metadata()

class ProgressBar(DisplayObject):
"""Progressbar supports displaying a progressbar like element
"""Progressbar supports displaying a progressbar like element
"""
def __init__(self, total):
"""Creates a new progressbar
Parameters
----------
total : int
Expand Down Expand Up @@ -818,7 +841,7 @@ def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=
metadata: dict
Specify extra metadata to attach to the json display object.
root : str
The name of the root element of the JSON tree
The name of the root element of the JSON tree
"""
self.metadata = {
'expanded': expanded,
Expand Down Expand Up @@ -878,7 +901,7 @@ class GeoJSON(JSON):
Scalar types (None, number, string) are not allowed, only dict containers.
"""

def __init__(self, *args, **kwargs):
"""Create a GeoJSON display object given raw data.
Expand Down Expand Up @@ -927,7 +950,7 @@ def __init__(self, *args, **kwargs):
the GeoJSON object.
"""

super(GeoJSON, self).__init__(*args, **kwargs)


Expand Down Expand Up @@ -1159,7 +1182,7 @@ def __init__(self, data=None, url=None, filename=None, format=None,
self.height = height
self.retina = retina
self.unconfined = unconfined
super(Image, self).__init__(data=data, url=url, filename=filename,
super(Image, self).__init__(data=data, url=url, filename=filename,
metadata=metadata)

if self.width is None and self.metadata.get('width', {}):
Expand Down Expand Up @@ -1256,7 +1279,8 @@ def _find_ext(self, s):

class Video(DisplayObject):

def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
def __init__(self, data=None, url=None, filename=None, embed=False,
mimetype=None, width=None, height=None):
"""Create a video object given raw data or an URL.
When this object is returned by an input cell or passed to the
Expand Down Expand Up @@ -1288,6 +1312,14 @@ def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=Non
mimetype: unicode
Specify the mimetype for embedded videos.
Default will be guessed from file extension, if available.
width : str
Width of the video element in HTML.
It accepts percentage, rems and other valid units
If not supplied, defaults to the width of the video.
height : str
Height of the video element in html.
It accepts percentage, rems and other valid units
If not supplied, defaults to the height of the video.
Examples
--------
Expand All @@ -1314,16 +1346,24 @@ def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=Non

self.mimetype = mimetype
self.embed = embed
self.width = width
self.height = height
super(Video, self).__init__(data=data, url=url, filename=filename)

def _repr_html_(self):
width = height = ''
if self.width:
width = ' width="%d"' % self.width
if self.height:
height = ' height="%d"' % self.height

# External URLs and potentially local files are not embedded into the
# notebook output.
if not self.embed:
url = self.url if self.url is not None else self.filename
output = """<video src="{0}" controls>
output = """<video src="{0}" controls {1} {2}>
Your browser does not support the <code>video</code> element.
</video>""".format(url)
</video>""".format(url, width, height)
return output

# Embedded videos are base64-encoded.
Expand All @@ -1342,10 +1382,10 @@ def _repr_html_(self):
else:
b64_video = b2a_base64(video).decode('ascii').rstrip()

output = """<video controls>
<source src="data:{0};base64,{1}" type="{0}">
output = """<video controls {0} {1}>
<source src="data:{2};base64,{3}" type="{2}">
Your browser does not support the video tag.
</video>""".format(mimetype, b64_video)
</video>""".format(width, height, mimetype, b64_video)
return output

def reload(self):
Expand Down

0 comments on commit b77fcb2

Please sign in to comment.