Skip to content

Commit 49992e9

Browse files
committed
ENH: pandas-dev#2679 - DataFrame.to_html() urls_as_links parameter.
New urls_as_links boolean paramater that will output urls as href html links. ref pandas-dev#2679
1 parent 6c4d2c7 commit 49992e9

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

pandas/core/format.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from pandas.core.base import PandasObject
99
from pandas.core.common import adjoin, notnull
10+
from pandas.io.common import _is_url
1011
from pandas.core.index import Index, MultiIndex, _ensure_index
1112
from pandas import compat
1213
from pandas.compat import(StringIO, lzip, range, map, zip, reduce, u,
@@ -341,7 +342,8 @@ def __init__(self, frame, buf=None, columns=None, col_space=None,
341342
header=True, index=True, na_rep='NaN', formatters=None,
342343
justify=None, float_format=None, sparsify=None,
343344
index_names=True, line_width=None, max_rows=None,
344-
max_cols=None, show_dimensions=False, **kwds):
345+
max_cols=None, show_dimensions=False, urls_as_links=False,
346+
**kwds):
345347
self.frame = frame
346348
self.buf = buf if buf is not None else StringIO()
347349
self.show_index_names = index_names
@@ -363,6 +365,7 @@ def __init__(self, frame, buf=None, columns=None, col_space=None,
363365
self.max_rows_displayed = min(max_rows or len(self.frame),
364366
len(self.frame))
365367
self.show_dimensions = show_dimensions
368+
self.urls_as_links = urls_as_links
366369

367370
if justify is None:
368371
self.justify = get_option("display.colheader_justify")
@@ -863,6 +866,7 @@ def __init__(self, formatter, classes=None, max_rows=None, max_cols=None,
863866
self.max_rows = max_rows or len(self.fmt.frame)
864867
self.max_cols = max_cols or len(self.fmt.columns)
865868
self.show_dimensions = self.fmt.show_dimensions
869+
self.urls_as_links = self.fmt.urls_as_links
866870
self.is_truncated = (self.max_rows < len(self.fmt.frame) or
867871
self.max_cols < len(self.fmt.columns))
868872
self.notebook = notebook
@@ -896,6 +900,11 @@ def _write_cell(self, s, kind='td', indent=0, tags=None):
896900
else:
897901
esc = {}
898902
rs = com.pprint_thing(s, escape_chars=esc).strip()
903+
if self.urls_as_links and isinstance(s, compat.string_types):
904+
s = s.strip()
905+
if _is_url(s):
906+
rs = '<a href="{url}">{escaped_url}</a>'.format(url=s,
907+
escaped_url=rs)
899908
self.write(
900909
'%s%s</%s>' % (start_tag, rs, kind), indent)
901910

pandas/core/frame.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,7 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
14791479
float_format=None, sparsify=None, index_names=True,
14801480
justify=None, bold_rows=True, classes=None, escape=True,
14811481
max_rows=None, max_cols=None, show_dimensions=False,
1482-
notebook=False):
1482+
notebook=False, urls_as_links=False):
14831483
"""
14841484
Render a DataFrame as an HTML table.
14851485
@@ -1497,6 +1497,8 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
14971497
max_cols : int, optional
14981498
Maximum number of columns to show before truncating. If None, show
14991499
all.
1500+
urls_as_links : boolean, default False
1501+
Convert urls to HTML links.
15001502
15011503
"""
15021504

@@ -1517,7 +1519,8 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
15171519
escape=escape,
15181520
max_rows=max_rows,
15191521
max_cols=max_cols,
1520-
show_dimensions=show_dimensions)
1522+
show_dimensions=show_dimensions,
1523+
urls_as_links=urls_as_links)
15211524
formatter.to_html(classes=classes, notebook=notebook)
15221525

15231526
if buf is None:

pandas/tests/test_format.py

+71
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,77 @@ def test_to_html_multiindex_sparsify_false_multi_sparse(self):
949949
</table>"""
950950
self.assertEqual(result, expected)
951951

952+
def test_to_html_with_hyperlinks(self):
953+
data = [
954+
{
955+
'foo': 0,
956+
'bar': 'http://pandas.pydata.org/',
957+
None: 'pydata.org',
958+
},
959+
{
960+
'foo': 0,
961+
'bar': 'http://pandas.pydata.org/?q1=a&q2=b',
962+
None: 'pydata.org',
963+
},
964+
]
965+
df = DataFrame(data, columns=['foo', 'bar', None],
966+
index=range(len(data)))
967+
968+
result_no_links = df.to_html()
969+
result_with_links = df.to_html(urls_as_links=True)
970+
expected_no_links = """\
971+
<table border="1" class="dataframe">
972+
<thead>
973+
<tr style="text-align: right;">
974+
<th></th>
975+
<th>foo</th>
976+
<th>bar</th>
977+
<th>None</th>
978+
</tr>
979+
</thead>
980+
<tbody>
981+
<tr>
982+
<th>0</th>
983+
<td>0</td>
984+
<td>http://pandas.pydata.org/</td>
985+
<td>pydata.org</td>
986+
</tr>
987+
<tr>
988+
<th>1</th>
989+
<td>0</td>
990+
<td>http://pandas.pydata.org/?q1=a&amp;q2=b</td>
991+
<td>pydata.org</td>
992+
</tr>
993+
</tbody>
994+
</table>"""
995+
expected_with_links = """\
996+
<table border="1" class="dataframe">
997+
<thead>
998+
<tr style="text-align: right;">
999+
<th></th>
1000+
<th>foo</th>
1001+
<th>bar</th>
1002+
<th>None</th>
1003+
</tr>
1004+
</thead>
1005+
<tbody>
1006+
<tr>
1007+
<th>0</th>
1008+
<td>0</td>
1009+
<td><a href="http://pandas.pydata.org/">http://pandas.pydata.org/</a></td>
1010+
<td>pydata.org</td>
1011+
</tr>
1012+
<tr>
1013+
<th>1</th>
1014+
<td>0</td>
1015+
<td><a href="http://pandas.pydata.org/?q1=a&q2=b">http://pandas.pydata.org/?q1=a&amp;q2=b</a></td>
1016+
<td>pydata.org</td>
1017+
</tr>
1018+
</tbody>
1019+
</table>"""
1020+
self.assertEqual(result_with_links, expected_with_links)
1021+
self.assertEqual(result_no_links, expected_no_links)
1022+
9521023
def test_to_html_multiindex_sparsify(self):
9531024
index = MultiIndex.from_arrays([[0, 0, 1, 1], [0, 1, 0, 1]],
9541025
names=['foo', None])

0 commit comments

Comments
 (0)