Skip to content

Commit 963561b

Browse files
authored
ENH: add long and short captions to Styler.to_latex (#41659)
1 parent 169cc10 commit 963561b

File tree

7 files changed

+32
-12
lines changed

7 files changed

+32
-12
lines changed

doc/source/whatsnew/v1.3.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ One also has greater control of the display through separate sparsification of t
143143
Render trimming has also been added for large numbers of data elements to avoid browser overload (:issue:`40712`).
144144

145145
We have added an extension to allow LaTeX styling as an alternative to CSS styling and a method :meth:`.Styler.to_latex`
146-
which renders the necessary LaTeX format including built-up styles. An additional file io function :meth:`.Styler.to_html` has been added for convenience (:issue:`40312`).
146+
which renders the necessary LaTeX format including built-up styles (:issue:`21673`, :issue:`41659`). An additional file io function :meth:`Styler.to_html` has been added for convenience (:issue:`40312`).
147147

148148
Documentation has also seen major revisions in light of new features (:issue:`39720` :issue:`39317` :issue:`40493`)
149149

pandas/io/formats/style.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ class Styler(StylerRenderer):
8787
List of {selector: (attr, value)} dicts; see Notes.
8888
uuid : str, default None
8989
A unique identifier to avoid CSS collisions; generated automatically.
90-
caption : str, default None
91-
Caption to attach to the table.
90+
caption : str, tuple, default None
91+
String caption to attach to the table. Tuple only used for LaTeX dual captions.
9292
table_attributes : str, default None
9393
Items that show up in the opening ``<table>`` tag
9494
in addition to automatic (by default) id.
@@ -175,7 +175,7 @@ def __init__(
175175
precision: int | None = None,
176176
table_styles: CSSStyles | None = None,
177177
uuid: str | None = None,
178-
caption: str | None = None,
178+
caption: str | tuple | None = None,
179179
table_attributes: str | None = None,
180180
cell_ids: bool = True,
181181
na_rep: str | None = None,
@@ -419,7 +419,7 @@ def to_latex(
419419
position_float: str | None = None,
420420
hrules: bool = False,
421421
label: str | None = None,
422-
caption: str | None = None,
422+
caption: str | tuple | None = None,
423423
sparse_index: bool | None = None,
424424
sparse_columns: bool | None = None,
425425
multirow_align: str = "c",
@@ -460,8 +460,10 @@ def to_latex(
460460
label : str, optional
461461
The LaTeX label included as: \\label{<label>}.
462462
This is used with \\ref{<label>} in the main .tex file.
463-
caption : str, optional
464-
The LaTeX table caption included as: \\caption{<caption>}.
463+
caption : str, tuple, optional
464+
If string, the LaTeX table caption included as: \\caption{<caption>}.
465+
If tuple, i.e ("full caption", "short caption"), the caption included
466+
as: \\caption[<caption[1]>]{<caption[0]>}.
465467
sparse_index : bool, optional
466468
Whether to sparsify the display of a hierarchical index. Setting to False
467469
will display each explicit level element in a hierarchical key for each row.
@@ -1344,13 +1346,16 @@ def set_uuid(self, uuid: str) -> Styler:
13441346
self.uuid = uuid
13451347
return self
13461348

1347-
def set_caption(self, caption: str) -> Styler:
1349+
def set_caption(self, caption: str | tuple) -> Styler:
13481350
"""
13491351
Set the text added to a ``<caption>`` HTML element.
13501352
13511353
Parameters
13521354
----------
1353-
caption : str
1355+
caption : str, tuple
1356+
For HTML output either the string input is used or the first element of the
1357+
tuple. For LaTeX the string input provides a caption and the additional
1358+
tuple input allows for full captions and short captions, in that order.
13541359
13551360
Returns
13561361
-------

pandas/io/formats/style_render.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def __init__(
7575
uuid_len: int = 5,
7676
table_styles: CSSStyles | None = None,
7777
table_attributes: str | None = None,
78-
caption: str | None = None,
78+
caption: str | tuple | None = None,
7979
cell_ids: bool = True,
8080
):
8181

pandas/io/formats/templates/html_table.tpl

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
<table id="T_{{uuid}}"{% if table_attributes %} {{table_attributes}}{% endif %}>
77
{% endif %}
88
{% block caption %}
9-
{% if caption %}
9+
{% if caption and caption is string %}
1010
<caption>{{caption}}</caption>
11+
{% elif caption and caption is sequence %}
12+
<caption>{{caption[0]}}</caption>
1113
{% endif %}
1214
{% endblock caption %}
1315
{% block thead %}

pandas/io/formats/templates/latex.tpl

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
{% if position_float is not none%}
1010
\{{position_float}}
1111
{% endif %}
12-
{% if caption %}
12+
{% if caption and caption is string %}
1313
\caption{% raw %}{{% endraw %}{{caption}}{% raw %}}{% endraw %}
1414

15+
{% elif caption and caption is sequence %}
16+
\caption[{{caption[1]}}]{% raw %}{{% endraw %}{{caption[0]}}{% raw %}}{% endraw %}
17+
1518
{% endif %}
1619
{% for style in table_styles %}
1720
{% if style['selector'] not in ['position', 'position_float', 'caption', 'toprule', 'midrule', 'bottomrule', 'column_format'] %}

pandas/tests/io/formats/style/test_html.py

+5
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,8 @@ def test_from_custom_template(tmpdir):
231231
assert result.template_html is not Styler.template_html
232232
styler = result(DataFrame({"A": [1, 2]}))
233233
assert styler.render()
234+
235+
236+
def test_caption_as_sequence(styler):
237+
styler.set_caption(("full cap", "short cap"))
238+
assert "<caption>full cap</caption>" in styler.render()

pandas/tests/io/formats/style/test_to_latex.py

+5
Original file line numberDiff line numberDiff line change
@@ -438,3 +438,8 @@ def test_parse_latex_table_wrapping(styler):
438438
overwrite=False,
439439
)
440440
assert _parse_latex_table_wrapping(styler.table_styles, None) is True
441+
442+
443+
def test_short_caption(styler):
444+
result = styler.to_latex(caption=("full cap", "short cap"))
445+
assert "\\caption[short cap]{full cap}" in result

0 commit comments

Comments
 (0)