Skip to content

Commit d5c7ca2

Browse files
simonjayhawkinsPingviinituutti
authored andcommitted
REF: io/formats/html.py (and io/formats/format.py) (pandas-dev#24651)
1 parent d4432f7 commit d5c7ca2

File tree

2 files changed

+71
-59
lines changed

2 files changed

+71
-59
lines changed

pandas/io/formats/format.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -730,15 +730,14 @@ def to_html(self, classes=None, notebook=False, border=None):
730730
731731
.. versionadded:: 0.19.0
732732
"""
733-
from pandas.io.formats.html import HTMLFormatter
734-
html_renderer = HTMLFormatter(self, classes=classes, notebook=notebook,
735-
border=border, table_id=self.table_id,
736-
render_links=self.render_links)
733+
from pandas.io.formats.html import HTMLFormatter, NotebookFormatter
734+
Klass = NotebookFormatter if notebook else HTMLFormatter
735+
html = Klass(self, classes=classes, border=border).render()
737736
if hasattr(self.buf, 'write'):
738-
html_renderer.write_result(self.buf)
737+
buffer_put_lines(self.buf, html)
739738
elif isinstance(self.buf, compat.string_types):
740739
with open(self.buf, 'w') as f:
741-
html_renderer.write_result(f)
740+
buffer_put_lines(f, html)
742741
else:
743742
raise TypeError('buf is not a file name and it has no write '
744743
' method')

pandas/io/formats/html.py

+66-53
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,23 @@
1616
from pandas.core.config import get_option
1717

1818
from pandas.io.common import _is_url
19-
from pandas.io.formats.format import (
20-
TableFormatter, buffer_put_lines, get_level_lengths)
19+
from pandas.io.formats.format import TableFormatter, get_level_lengths
2120
from pandas.io.formats.printing import pprint_thing
2221

2322

2423
class HTMLFormatter(TableFormatter):
24+
"""
25+
Internal class for formatting output data in html.
26+
This class is intended for shared functionality between
27+
DataFrame.to_html() and DataFrame._repr_html_().
28+
Any logic in common with other output formatting methods
29+
should ideally be inherited from classes in format.py
30+
and this class responsible for only producing html markup.
31+
"""
2532

2633
indent_delta = 2
2734

28-
def __init__(self, formatter, classes=None, notebook=False, border=None,
29-
table_id=None, render_links=False):
35+
def __init__(self, formatter, classes=None, border=None):
3036
self.fmt = formatter
3137
self.classes = classes
3238

@@ -36,12 +42,11 @@ def __init__(self, formatter, classes=None, notebook=False, border=None,
3642
self.bold_rows = self.fmt.kwds.get('bold_rows', False)
3743
self.escape = self.fmt.kwds.get('escape', True)
3844
self.show_dimensions = self.fmt.show_dimensions
39-
self.notebook = notebook
4045
if border is None:
4146
border = get_option('display.html.border')
4247
self.border = border
43-
self.table_id = table_id
44-
self.render_links = render_links
48+
self.table_id = self.fmt.table_id
49+
self.render_links = self.fmt.render_links
4550

4651
@property
4752
def show_row_idx_names(self):
@@ -137,48 +142,7 @@ def write_tr(self, line, indent=0, indent_delta=0, header=False,
137142
indent -= indent_delta
138143
self.write('</tr>', indent)
139144

140-
def write_style(self):
141-
# We use the "scoped" attribute here so that the desired
142-
# style properties for the data frame are not then applied
143-
# throughout the entire notebook.
144-
template_first = """\
145-
<style scoped>"""
146-
template_last = """\
147-
</style>"""
148-
template_select = """\
149-
.dataframe %s {
150-
%s: %s;
151-
}"""
152-
element_props = [('tbody tr th:only-of-type',
153-
'vertical-align',
154-
'middle'),
155-
('tbody tr th',
156-
'vertical-align',
157-
'top')]
158-
if isinstance(self.columns, ABCMultiIndex):
159-
element_props.append(('thead tr th',
160-
'text-align',
161-
'left'))
162-
if self.show_row_idx_names:
163-
element_props.append(('thead tr:last-of-type th',
164-
'text-align',
165-
'right'))
166-
else:
167-
element_props.append(('thead th',
168-
'text-align',
169-
'right'))
170-
template_mid = '\n\n'.join(map(lambda t: template_select % t,
171-
element_props))
172-
template = dedent('\n'.join((template_first,
173-
template_mid,
174-
template_last)))
175-
self.write(template)
176-
177-
def write_result(self, buf):
178-
if self.notebook:
179-
self.write('<div>')
180-
self.write_style()
181-
145+
def render(self):
182146
self._write_table()
183147

184148
if self.should_show_dimensions:
@@ -188,10 +152,7 @@ def write_result(self, buf):
188152
by=by,
189153
cols=len(self.frame.columns)))
190154

191-
if self.notebook:
192-
self.write('</div>')
193-
194-
buffer_put_lines(buf, self.elements)
155+
return self.elements
195156

196157
def _write_table(self, indent=0):
197158
_classes = ['dataframe'] # Default class.
@@ -516,3 +477,55 @@ def _write_hierarchical_rows(self, fmt_values, indent):
516477
row.insert(self.row_levels + self.fmt.tr_col_num, '...')
517478
self.write_tr(row, indent, self.indent_delta, tags=None,
518479
nindex_levels=frame.index.nlevels)
480+
481+
482+
class NotebookFormatter(HTMLFormatter):
483+
"""
484+
Internal class for formatting output data in html for display in Jupyter
485+
Notebooks. This class is intended for functionality specific to
486+
DataFrame._repr_html_() and DataFrame.to_html(notebook=True)
487+
"""
488+
489+
def write_style(self):
490+
# We use the "scoped" attribute here so that the desired
491+
# style properties for the data frame are not then applied
492+
# throughout the entire notebook.
493+
template_first = """\
494+
<style scoped>"""
495+
template_last = """\
496+
</style>"""
497+
template_select = """\
498+
.dataframe %s {
499+
%s: %s;
500+
}"""
501+
element_props = [('tbody tr th:only-of-type',
502+
'vertical-align',
503+
'middle'),
504+
('tbody tr th',
505+
'vertical-align',
506+
'top')]
507+
if isinstance(self.columns, ABCMultiIndex):
508+
element_props.append(('thead tr th',
509+
'text-align',
510+
'left'))
511+
if self.show_row_idx_names:
512+
element_props.append(('thead tr:last-of-type th',
513+
'text-align',
514+
'right'))
515+
else:
516+
element_props.append(('thead th',
517+
'text-align',
518+
'right'))
519+
template_mid = '\n\n'.join(map(lambda t: template_select % t,
520+
element_props))
521+
template = dedent('\n'.join((template_first,
522+
template_mid,
523+
template_last)))
524+
self.write(template)
525+
526+
def render(self):
527+
self.write('<div>')
528+
self.write_style()
529+
super(NotebookFormatter, self).render()
530+
self.write('</div>')
531+
return self.elements

0 commit comments

Comments
 (0)