Skip to content

Commit 63136ef

Browse files
committed
Extract html representation from cube module
1 parent 8074245 commit 63136ef

3 files changed

Lines changed: 183 additions & 161 deletions

File tree

lib/iris/cube.py

Lines changed: 2 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import iris.coord_systems
5151
import iris.coords
5252
import iris.exceptions
53+
from iris.experimental.representation import CubeRepresentation
5354
import iris.util
5455

5556

@@ -603,161 +604,6 @@ def _is_single_item(testee):
603604
not isinstance(testee, collections.Iterable))
604605

605606

606-
class _CubeRepresentation(object):
607-
"""
608-
Produce representations of a :class:`~iris.cube.Cube`.
609-
610-
This includes:
611-
612-
* ``_html_repr_``: a representation of the cube as an html object,
613-
available in jupyter notebooks.
614-
615-
"""
616-
_template = """
617-
<style>
618-
a.iris {{
619-
text-decoration: none !important;
620-
}}
621-
.iris {{
622-
white-space: pre;
623-
}}
624-
.iris-panel-group {{
625-
display: block;
626-
overflow: visible;
627-
width: max-content;
628-
font-family: monaco, monospace;
629-
}}
630-
.iris-panel-body {{
631-
padding-top: 0px;
632-
}}
633-
.iris-panel-title {{
634-
padding-left: 3em;
635-
}}
636-
.iris-panel-title {{
637-
margin-top: 7px;
638-
}}
639-
</style>
640-
<div class="panel-group iris-panel-group">
641-
<div class="panel panel-default">
642-
<div class="panel-heading">
643-
<h4 class="panel-title">
644-
<a class="iris" data-toggle="collapse" href="#collapse1-{obj_id}">
645-
{summary}
646-
</a>
647-
</h4>
648-
</div>
649-
<div id="collapse1-{obj_id}" class="panel-collapse collapse in">
650-
{content}
651-
</div>
652-
</div>
653-
</div>
654-
"""
655-
656-
# Need to format the keywords:
657-
# `emt_id`, `obj_id`, `str_heading`, `opened`, `content`.
658-
_insert_content = """
659-
<div class="panel-body iris-panel-body">
660-
<h4 class="panel-title iris-panel-title">
661-
<a class="iris" data-toggle="collapse" href="#{emt_id}-{obj_id}">
662-
{str_heading}
663-
</a>
664-
</h4>
665-
</div>
666-
<div id="{emt_id}-{obj_id}" class="panel-collapse collapse{opened}">
667-
<div class="panel-body iris-panel-body">
668-
<p class="iris">{content}</p>
669-
</div>
670-
</div>
671-
"""
672-
673-
def __init__(self, cube):
674-
"""
675-
Produce different representations of a :class:`~iris.cube.Cube`.
676-
677-
Args:
678-
679-
* cube
680-
the cube to produce representations of.
681-
682-
"""
683-
684-
self.cube = cube
685-
self.cube_id = id(self.cube)
686-
self.cube_str = str(self.cube)
687-
688-
self.summary = None
689-
self.str_headings = {
690-
'Dimension coordinates:': None,
691-
'Auxiliary coordinates:': None,
692-
'Derived coordinates:': None,
693-
'Scalar coordinates:': None,
694-
'Attributes:': None,
695-
'Cell methods:': None,
696-
}
697-
self.major_headings = ['Dimension coordinates:',
698-
'Auxiliary coordinates:',
699-
'Attributes:']
700-
701-
def _get_bits(self):
702-
"""
703-
Parse the str representation of the cube to retrieve the elements
704-
to add to an html representation of the cube.
705-
706-
"""
707-
bits = self.cube_str.split('\n')
708-
self.summary = bits[0]
709-
left_indent = bits[1].split('D')[0]
710-
711-
# Get heading indices within the printout.
712-
start_inds = []
713-
for hdg in self.str_headings.keys():
714-
heading = '{}{}'.format(left_indent, hdg)
715-
try:
716-
start_ind = bits.index(heading)
717-
except ValueError:
718-
continue
719-
else:
720-
start_inds.append(start_ind)
721-
# Make sure the indices are in order.
722-
start_inds = sorted(start_inds)
723-
# Mark the end of the file.
724-
start_inds.append(None)
725-
726-
# Retrieve info for each heading from the printout.
727-
for i0, i1 in zip(start_inds[:-1], start_inds[1:]):
728-
str_heading_name = bits[i0].strip()
729-
if i1 is not None:
730-
content = bits[i0 + 1: i1]
731-
else:
732-
content = bits[i0 + 1:]
733-
self.str_headings[str_heading_name] = content
734-
735-
def _make_content(self):
736-
elements = []
737-
for k, v in self.str_headings.items():
738-
if v is not None:
739-
html_id = k.split(' ')[0].lower().strip(':')
740-
content = '\n'.join(line for line in v)
741-
collapse = ' in' if k in self.major_headings else ''
742-
element = self._insert_content.format(emt_id=html_id,
743-
obj_id=self.cube_id,
744-
str_heading=k,
745-
opened=collapse,
746-
content=content)
747-
elements.append(element)
748-
return '\n'.join(element for element in elements)
749-
750-
def repr_html(self):
751-
"""Produce an html representation of a cube and return it."""
752-
self._get_bits()
753-
summary = self.summary
754-
content = self._make_content()
755-
return self._template.format(summary=summary,
756-
content=content,
757-
obj_id=self.cube_id,
758-
)
759-
760-
761607
class Cube(CFVariableMixin):
762608
"""
763609
A single Iris cube of data and metadata.
@@ -2220,7 +2066,7 @@ def __repr__(self):
22202066
name_padding=1)
22212067

22222068
def _repr_html_(self):
2223-
representer = _CubeRepresentation(self)
2069+
representer = CubeRepresentation(self)
22242070
return representer.repr_html()
22252071

22262072
def __iter__(self):
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# (C) British Crown Copyright 2018, Met Office
2+
#
3+
# This file is part of Iris.
4+
#
5+
# Iris is free software: you can redistribute it and/or modify it under
6+
# the terms of the GNU Lesser General Public License as published by the
7+
# Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# Iris is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public License
16+
# along with Iris. If not, see <http://www.gnu.org/licenses/>.
17+
18+
"""
19+
Definitions of how Iris objects should be represented.
20+
21+
"""
22+
23+
24+
class CubeRepresentation(object):
25+
"""
26+
Produce representations of a :class:`~iris.cube.Cube`.
27+
28+
This includes:
29+
30+
* ``_html_repr_``: a representation of the cube as an html object,
31+
available in jupyter notebooks.
32+
33+
"""
34+
_template = """
35+
<style>
36+
a.iris {{
37+
text-decoration: none !important;
38+
}}
39+
.iris {{
40+
white-space: pre;
41+
}}
42+
.iris-panel-group {{
43+
display: block;
44+
overflow: visible;
45+
width: max-content;
46+
font-family: monaco, monospace;
47+
}}
48+
.iris-panel-body {{
49+
padding-top: 0px;
50+
}}
51+
.iris-panel-title {{
52+
padding-left: 3em;
53+
}}
54+
.iris-panel-title {{
55+
margin-top: 7px;
56+
}}
57+
</style>
58+
<div class="panel-group iris-panel-group">
59+
<div class="panel panel-default">
60+
<div class="panel-heading">
61+
<h4 class="panel-title">
62+
<a class="iris" data-toggle="collapse" href="#collapse1-{obj_id}">
63+
{summary}
64+
</a>
65+
</h4>
66+
</div>
67+
<div id="collapse1-{obj_id}" class="panel-collapse collapse in">
68+
{content}
69+
</div>
70+
</div>
71+
</div>
72+
"""
73+
74+
# Need to format the keywords:
75+
# `emt_id`, `obj_id`, `str_heading`, `opened`, `content`.
76+
_insert_content = """
77+
<div class="panel-body iris-panel-body">
78+
<h4 class="panel-title iris-panel-title">
79+
<a class="iris" data-toggle="collapse" href="#{emt_id}-{obj_id}">
80+
{str_heading}
81+
</a>
82+
</h4>
83+
</div>
84+
<div id="{emt_id}-{obj_id}" class="panel-collapse collapse{opened}">
85+
<div class="panel-body iris-panel-body">
86+
<p class="iris">{content}</p>
87+
</div>
88+
</div>
89+
"""
90+
91+
def __init__(self, cube):
92+
"""
93+
Produce different representations of a :class:`~iris.cube.Cube`.
94+
95+
Args:
96+
97+
* cube
98+
the cube to produce representations of.
99+
100+
"""
101+
102+
self.cube = cube
103+
self.cube_id = id(self.cube)
104+
self.cube_str = str(self.cube)
105+
106+
self.summary = None
107+
self.str_headings = {
108+
'Dimension coordinates:': None,
109+
'Auxiliary coordinates:': None,
110+
'Derived coordinates:': None,
111+
'Scalar coordinates:': None,
112+
'Attributes:': None,
113+
'Cell methods:': None,
114+
}
115+
self.major_headings = ['Dimension coordinates:',
116+
'Auxiliary coordinates:',
117+
'Attributes:']
118+
119+
def _get_bits(self):
120+
"""
121+
Parse the str representation of the cube to retrieve the elements
122+
to add to an html representation of the cube.
123+
124+
"""
125+
bits = self.cube_str.split('\n')
126+
self.summary = bits[0]
127+
left_indent = bits[1].split('D')[0]
128+
129+
# Get heading indices within the printout.
130+
start_inds = []
131+
for hdg in self.str_headings.keys():
132+
heading = '{}{}'.format(left_indent, hdg)
133+
try:
134+
start_ind = bits.index(heading)
135+
except ValueError:
136+
continue
137+
else:
138+
start_inds.append(start_ind)
139+
# Make sure the indices are in order.
140+
start_inds = sorted(start_inds)
141+
# Mark the end of the file.
142+
start_inds.append(None)
143+
144+
# Retrieve info for each heading from the printout.
145+
for i0, i1 in zip(start_inds[:-1], start_inds[1:]):
146+
str_heading_name = bits[i0].strip()
147+
if i1 is not None:
148+
content = bits[i0 + 1: i1]
149+
else:
150+
content = bits[i0 + 1:]
151+
self.str_headings[str_heading_name] = content
152+
153+
def _make_content(self):
154+
elements = []
155+
for k, v in self.str_headings.items():
156+
if v is not None:
157+
html_id = k.split(' ')[0].lower().strip(':')
158+
content = '\n'.join(line for line in v)
159+
collapse = ' in' if k in self.major_headings else ''
160+
element = self._insert_content.format(emt_id=html_id,
161+
obj_id=self.cube_id,
162+
str_heading=k,
163+
opened=collapse,
164+
content=content)
165+
elements.append(element)
166+
return '\n'.join(element for element in elements)
167+
168+
def repr_html(self):
169+
"""Produce an html representation of a cube and return it."""
170+
self._get_bits()
171+
summary = self.summary
172+
content = self._make_content()
173+
return self._template.format(summary=summary,
174+
content=content,
175+
obj_id=self.cube_id,
176+
)

0 commit comments

Comments
 (0)