Skip to content

BUG: fix duplicate entries in LaTeX List of Tables when using longtable environments #36297

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
Sep 19, 2020
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ Other
^^^^^
- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` incorrectly raising ``AssertionError`` instead of ``ValueError`` when invalid parameter combinations are passed (:issue:`36045`)
- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` with numeric values and string ``to_replace`` (:issue:`34789`)
-
- Bug in :func:`LongTableBuilder.middle_separator` was duplicating LaTeX longtable entires in the List of Tables of a LaTeX document (:issue:`34360`)

.. ---------------------------------------------------------------------------

Expand Down
9 changes: 9 additions & 0 deletions pandas/io/formats/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,16 @@ def _caption_and_label(self) -> str:
@property
def middle_separator(self) -> str:
iterator = self._create_row_iterator(over="header")

# the content between \endfirsthead and \endhead commands
# mitigates repeated List of Tables entries in the final LaTeX
# document when dealing with longtable environments; GH #34360
elements = [
"\\midrule",
"\\endfirsthead",
f"\\caption[]{{{self.caption}}} \\\\" if self.caption else "",
self.top_separator,
self.header,
"\\midrule",
"\\endhead",
"\\midrule",
Expand Down
33 changes: 33 additions & 0 deletions pandas/tests/io/formats/test_to_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ def test_to_latex_longtable(self):
df = DataFrame({"a": [1, 2], "b": ["b1", "b2"]})
withindex_result = df.to_latex(longtable=True)
withindex_expected = r"""\begin{longtable}{lrl}
\toprule
{} & a & b \\
\midrule
\endfirsthead

\toprule
{} & a & b \\
\midrule
Expand All @@ -430,6 +435,11 @@ def test_to_latex_longtable(self):

withoutindex_result = df.to_latex(index=False, longtable=True)
withoutindex_expected = r"""\begin{longtable}{rl}
\toprule
a & b \\
\midrule
\endfirsthead

\toprule
a & b \\
\midrule
Expand Down Expand Up @@ -525,6 +535,9 @@ def test_to_latex_longtable_caption_label(self):

df = DataFrame({"a": [1, 2], "b": ["b1", "b2"]})

# test when no caption and no label is provided
# is performed by test_to_latex_longtable()

# test when only the caption is provided
result_c = df.to_latex(longtable=True, caption=the_caption)

Expand All @@ -533,6 +546,11 @@ def test_to_latex_longtable_caption_label(self):
\toprule
{} & a & b \\
\midrule
\endfirsthead
\caption[]{a table in a \texttt{longtable} environment} \\
\toprule
{} & a & b \\
\midrule
\endhead
\midrule
\multicolumn{3}{r}{{Continued on next page}} \\
Expand All @@ -552,6 +570,11 @@ def test_to_latex_longtable_caption_label(self):

expected_l = r"""\begin{longtable}{lrl}
\label{tab:longtable}\\
\toprule
{} & a & b \\
\midrule
\endfirsthead

\toprule
{} & a & b \\
\midrule
Expand All @@ -578,6 +601,11 @@ def test_to_latex_longtable_caption_label(self):
\toprule
{} & a & b \\
\midrule
\endfirsthead
\caption[]{a table in a \texttt{longtable} environment} \\
\toprule
{} & a & b \\
\midrule
\endhead
\midrule
\multicolumn{3}{r}{{Continued on next page}} \\
Expand Down Expand Up @@ -623,6 +651,11 @@ def test_to_latex_longtable_position(self):
result_p = df.to_latex(longtable=True, position=the_position)

expected_p = r"""\begin{longtable}[t]{lrl}
\toprule
{} & a & b \\
\midrule
\endfirsthead

\toprule
{} & a & b \\
\midrule
Expand Down