From f57c3ad333aad9cebe0a009698219bc740cb5747 Mon Sep 17 00:00:00 2001 From: jeschwar <36767735+jeschwar@users.noreply.github.com> Date: Fri, 11 Sep 2020 15:56:46 -0600 Subject: [PATCH 1/6] TST: revise LaTeX longtable tests for duplicate List of Tables entries (#34360) --- pandas/tests/io/formats/test_to_latex.py | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index a98644250b328..438dbdd98a4b5 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -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 @@ -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 @@ -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) @@ -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}} \\ @@ -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 @@ -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}} \\ @@ -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 From 916d8a26a699adab9b2ae1fc0d6752b1b8966bb0 Mon Sep 17 00:00:00 2001 From: jeschwar <36767735+jeschwar@users.noreply.github.com> Date: Fri, 11 Sep 2020 15:58:55 -0600 Subject: [PATCH 2/6] BUG: fixed LongTableBuilder.middle_separator() for duplicate List of Tables entries (#34360) --- pandas/io/formats/latex.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/io/formats/latex.py b/pandas/io/formats/latex.py index 8080d953da308..a8f712123eaf9 100644 --- a/pandas/io/formats/latex.py +++ b/pandas/io/formats/latex.py @@ -477,6 +477,11 @@ def _caption_and_label(self) -> str: def middle_separator(self) -> str: iterator = self._create_row_iterator(over="header") elements = [ + "\\midrule", + "\\endfirsthead", + f"\\caption[]{{{self.caption}}} \\\\" if self.caption else "", + self.top_separator, + self.header, "\\midrule", "\\endhead", "\\midrule", From 67f105dd1111e47ccaa9f3a099eb6bc423987f58 Mon Sep 17 00:00:00 2001 From: jeschwar <36767735+jeschwar@users.noreply.github.com> Date: Fri, 11 Sep 2020 16:05:38 -0600 Subject: [PATCH 3/6] DOC: added whatsnew entry for fixing LongTableBuilder.middle_separator() (#34360) --- doc/source/whatsnew/v1.1.3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.3.rst b/doc/source/whatsnew/v1.1.3.rst index e3161012da5d1..9e58b4bc55b7d 100644 --- a/doc/source/whatsnew/v1.1.3.rst +++ b/doc/source/whatsnew/v1.1.3.rst @@ -22,7 +22,7 @@ Fixed regressions Bug fixes ~~~~~~~~~ -- +- Fixed bug in :func:`LongTableBuilder.middle_separator` which was duplicating LaTeX longtable entires in the List of Tables of a LaTeX document (:issue:`34360`) .. --------------------------------------------------------------------------- From 9539efd343329f16de165cfbe983f2e78059e153 Mon Sep 17 00:00:00 2001 From: jeschwar <36767735+jeschwar@users.noreply.github.com> Date: Mon, 14 Sep 2020 05:52:22 -0600 Subject: [PATCH 4/6] DOC: moved whatsnew entry (#34360) --- doc/source/whatsnew/v1.1.3.rst | 2 +- doc/source/whatsnew/v1.2.0.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.1.3.rst b/doc/source/whatsnew/v1.1.3.rst index 9e58b4bc55b7d..e3161012da5d1 100644 --- a/doc/source/whatsnew/v1.1.3.rst +++ b/doc/source/whatsnew/v1.1.3.rst @@ -22,7 +22,7 @@ Fixed regressions Bug fixes ~~~~~~~~~ -- Fixed bug in :func:`LongTableBuilder.middle_separator` which was duplicating LaTeX longtable entires in the List of Tables of a LaTeX document (:issue:`34360`) +- .. --------------------------------------------------------------------------- diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index f2f56ee81b8d4..bdd80d804ae03 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -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`) .. --------------------------------------------------------------------------- From 253f31ccbec7af42ef09ab28e0e37ff16bfd85c8 Mon Sep 17 00:00:00 2001 From: jeschwar <36767735+jeschwar@users.noreply.github.com> Date: Tue, 15 Sep 2020 18:35:36 -0600 Subject: [PATCH 5/6] DOC: added comment to LongTableBuilder.middle_separator() (#34360) --- pandas/io/formats/latex.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/io/formats/latex.py b/pandas/io/formats/latex.py index a8f712123eaf9..19e6a00c6da0e 100644 --- a/pandas/io/formats/latex.py +++ b/pandas/io/formats/latex.py @@ -476,6 +476,10 @@ 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", From 0e7fa0ba1b35f06d3c1aa032429abb4556277a8a Mon Sep 17 00:00:00 2001 From: jeschwar <36767735+jeschwar@users.noreply.github.com> Date: Thu, 17 Sep 2020 05:55:58 -0600 Subject: [PATCH 6/6] TST: revised doctest for LongTableBuilder (#34360) --- pandas/io/formats/latex.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pandas/io/formats/latex.py b/pandas/io/formats/latex.py index 19e6a00c6da0e..eb35fff3a4f8e 100644 --- a/pandas/io/formats/latex.py +++ b/pandas/io/formats/latex.py @@ -431,13 +431,18 @@ class LongTableBuilder(GenericTableBuilder): >>> from pandas.io.formats import format as fmt >>> df = DataFrame({"a": [1, 2], "b": ["b1", "b2"]}) >>> formatter = fmt.DataFrameFormatter(df) - >>> builder = LongTableBuilder(formatter, caption='caption', label='lab', - ... column_format='lrl') + >>> builder = LongTableBuilder(formatter, caption='a long table', + ... label='tab:long', column_format='lrl') >>> table = builder.get_result() >>> print(table) \\begin{longtable}{lrl} - \\caption{caption} - \\label{lab}\\\\ + \\caption{a long table} + \\label{tab:long}\\\\ + \\toprule + {} & a & b \\\\ + \\midrule + \\endfirsthead + \\caption[]{a long table} \\\\ \\toprule {} & a & b \\\\ \\midrule