Skip to content

ENH: add long and short captions to Styler.to_latex #41659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 4, 2021
20 changes: 12 additions & 8 deletions pandas/io/formats/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ class Styler(StylerRenderer):
List of {selector: (attr, value)} dicts; see Notes.
uuid : str, default None
A unique identifier to avoid CSS collisions; generated automatically.
caption : str, default None
Caption to attach to the table.
caption : str, tuple, default None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would emphasize here and below tht this is (full caption, short caption)

String caption to attach to the table. Tuple only used for LaTeX dual captions.
table_attributes : str, default None
Items that show up in the opening ``<table>`` tag
in addition to automatic (by default) id.
Expand Down Expand Up @@ -175,7 +175,7 @@ def __init__(
precision: int | None = None,
table_styles: CSSStyles | None = None,
uuid: str | None = None,
caption: str | None = None,
caption: str | tuple | None = None,
table_attributes: str | None = None,
cell_ids: bool = True,
na_rep: str | None = None,
Expand Down Expand Up @@ -419,7 +419,7 @@ def to_latex(
position_float: str | None = None,
hrules: bool = False,
label: str | None = None,
caption: str | None = None,
caption: str | tuple | None = None,
sparse_index: bool | None = None,
sparse_columns: bool | None = None,
multirow_align: str = "c",
Expand Down Expand Up @@ -460,8 +460,9 @@ def to_latex(
label : str, optional
The LaTeX label included as: \\label{<label>}.
This is used with \\ref{<label>} in the main .tex file.
caption : str, optional
The LaTeX table caption included as: \\caption{<caption>}.
caption : str, tuple, optional
If string, the LaTeX table caption included as: \\caption{<caption>}.
If tuple, the caption included as: \\caption[<caption[1]>]{<caption[0]>}.
sparse_index : bool, optional
Whether to sparsify the display of a hierarchical index. Setting to False
will display each explicit level element in a hierarchical key for each row.
Expand Down Expand Up @@ -1344,13 +1345,16 @@ def set_uuid(self, uuid: str) -> Styler:
self.uuid = uuid
return self

def set_caption(self, caption: str) -> Styler:
def set_caption(self, caption: str | tuple) -> Styler:
"""
Set the text added to a ``<caption>`` HTML element.

Parameters
----------
caption : str
caption : str, tuple
For HTML output either the string input is used or the first element of the
tuple. For LaTeX the string input provides a caption and the additional
tuple input allows for full captions and short captions, in that order.

Returns
-------
Expand Down
2 changes: 1 addition & 1 deletion pandas/io/formats/style_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def __init__(
uuid_len: int = 5,
table_styles: CSSStyles | None = None,
table_attributes: str | None = None,
caption: str | None = None,
caption: str | tuple | None = None,
cell_ids: bool = True,
):

Expand Down
4 changes: 3 additions & 1 deletion pandas/io/formats/templates/html_table.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
<table id="T_{{uuid}}"{% if table_attributes %} {{table_attributes}}{% endif %}>
{% endif %}
{% block caption %}
{% if caption %}
{% if caption and caption is string %}
<caption>{{caption}}</caption>
{% elif caption and caption is sequence %}
<caption>{{caption[0]}}</caption>
{% endif %}
{% endblock caption %}
{% block thead %}
Expand Down
5 changes: 4 additions & 1 deletion pandas/io/formats/templates/latex.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
{% if position_float is not none%}
\{{position_float}}
{% endif %}
{% if caption %}
{% if caption and caption is string %}
\caption{% raw %}{{% endraw %}{{caption}}{% raw %}}{% endraw %}

{% elif caption and caption is sequence %}
\caption[{{caption[1]}}]{% raw %}{{% endraw %}{{caption[0]}}{% raw %}}{% endraw %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep in mind that the same behavior should be implemented for longtable (once the longtables are implemented through the styler).


{% endif %}
{% for style in table_styles %}
{% if style['selector'] not in ['position', 'position_float', 'caption', 'toprule', 'midrule', 'bottomrule', 'column_format'] %}
Expand Down
5 changes: 5 additions & 0 deletions pandas/tests/io/formats/style/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,8 @@ def test_from_custom_template(tmpdir):
assert result.template_html is not Styler.template_html
styler = result(DataFrame({"A": [1, 2]}))
assert styler.render()


def test_caption_as_sequence(styler):
styler.set_caption(("full cap", "short cap"))
assert "<caption>full cap</caption>" in styler.render()
5 changes: 5 additions & 0 deletions pandas/tests/io/formats/style/test_to_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,8 @@ def test_parse_latex_table_wrapping(styler):
overwrite=False,
)
assert _parse_latex_table_wrapping(styler.table_styles, None) is True


def test_short_caption(styler):
result = styler.to_latex(caption=("full cap", "short cap"))
assert "\\caption[short cap]{full cap}" in result