Skip to content

Commit 542b20a

Browse files
authored
Refactor tables latex (#35649)
1 parent e530066 commit 542b20a

File tree

2 files changed

+33
-73
lines changed

2 files changed

+33
-73
lines changed

pandas/io/formats/latex.py

Lines changed: 31 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,7 @@ def pad_empties(x):
121121
else:
122122
column_format = self.column_format
123123

124-
if self.longtable:
125-
self._write_longtable_begin(buf, column_format)
126-
else:
127-
self._write_tabular_begin(buf, column_format)
124+
self._write_tabular_begin(buf, column_format)
128125

129126
buf.write("\\toprule\n")
130127

@@ -190,10 +187,7 @@ def pad_empties(x):
190187
if self.multirow and i < len(strrows) - 1:
191188
self._print_cline(buf, i, len(strcols))
192189

193-
if self.longtable:
194-
self._write_longtable_end(buf)
195-
else:
196-
self._write_tabular_end(buf)
190+
self._write_tabular_end(buf)
197191

198192
def _format_multicolumn(self, row: List[str], ilevels: int) -> List[str]:
199193
r"""
@@ -288,7 +282,7 @@ def _write_tabular_begin(self, buf, column_format: str):
288282
for 3 columns
289283
"""
290284
if self._table_float:
291-
# then write output in a nested table/tabular environment
285+
# then write output in a nested table/tabular or longtable environment
292286
if self.caption is None:
293287
caption_ = ""
294288
else:
@@ -304,12 +298,27 @@ def _write_tabular_begin(self, buf, column_format: str):
304298
else:
305299
position_ = f"[{self.position}]"
306300

307-
buf.write(f"\\begin{{table}}{position_}\n\\centering{caption_}{label_}\n")
301+
if self.longtable:
302+
table_ = f"\\begin{{longtable}}{position_}{{{column_format}}}"
303+
tabular_ = "\n"
304+
else:
305+
table_ = f"\\begin{{table}}{position_}\n\\centering"
306+
tabular_ = f"\n\\begin{{tabular}}{{{column_format}}}\n"
307+
308+
if self.longtable and (self.caption is not None or self.label is not None):
309+
# a double-backslash is required at the end of the line
310+
# as discussed here:
311+
# https://tex.stackexchange.com/questions/219138
312+
backlash_ = "\\\\"
313+
else:
314+
backlash_ = ""
315+
buf.write(f"{table_}{caption_}{label_}{backlash_}{tabular_}")
308316
else:
309-
# then write output only in a tabular environment
310-
pass
311-
312-
buf.write(f"\\begin{{tabular}}{{{column_format}}}\n")
317+
if self.longtable:
318+
tabletype_ = "longtable"
319+
else:
320+
tabletype_ = "tabular"
321+
buf.write(f"\\begin{{{tabletype_}}}{{{column_format}}}\n")
313322

314323
def _write_tabular_end(self, buf):
315324
"""
@@ -323,62 +332,12 @@ def _write_tabular_end(self, buf):
323332
a string.
324333
325334
"""
326-
buf.write("\\bottomrule\n")
327-
buf.write("\\end{tabular}\n")
328-
if self._table_float:
329-
buf.write("\\end{table}\n")
330-
else:
331-
pass
332-
333-
def _write_longtable_begin(self, buf, column_format: str):
334-
"""
335-
Write the beginning of a longtable environment including caption and
336-
label if provided by user.
337-
338-
Parameters
339-
----------
340-
buf : string or file handle
341-
File path or object. If not specified, the result is returned as
342-
a string.
343-
column_format : str
344-
The columns format as specified in `LaTeX table format
345-
<https://en.wikibooks.org/wiki/LaTeX/Tables>`__ e.g 'rcl'
346-
for 3 columns
347-
"""
348-
if self.caption is None:
349-
caption_ = ""
350-
else:
351-
caption_ = f"\\caption{{{self.caption}}}"
352-
353-
if self.label is None:
354-
label_ = ""
355-
else:
356-
label_ = f"\\label{{{self.label}}}"
357-
358-
if self.position is None:
359-
position_ = ""
335+
if self.longtable:
336+
buf.write("\\end{longtable}\n")
360337
else:
361-
position_ = f"[{self.position}]"
362-
363-
buf.write(
364-
f"\\begin{{longtable}}{position_}{{{column_format}}}\n{caption_}{label_}"
365-
)
366-
if self.caption is not None or self.label is not None:
367-
# a double-backslash is required at the end of the line
368-
# as discussed here:
369-
# https://tex.stackexchange.com/questions/219138
370-
buf.write("\\\\\n")
371-
372-
@staticmethod
373-
def _write_longtable_end(buf):
374-
"""
375-
Write the end of a longtable environment.
376-
377-
Parameters
378-
----------
379-
buf : string or file handle
380-
File path or object. If not specified, the result is returned as
381-
a string.
382-
383-
"""
384-
buf.write("\\end{longtable}\n")
338+
buf.write("\\bottomrule\n")
339+
buf.write("\\end{tabular}\n")
340+
if self._table_float:
341+
buf.write("\\end{table}\n")
342+
else:
343+
pass

pandas/tests/io/formats/test_to_latex.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,8 @@ def test_to_latex_longtable_caption_label(self):
555555
result_cl = df.to_latex(longtable=True, caption=the_caption, label=the_label)
556556

557557
expected_cl = r"""\begin{longtable}{lrl}
558-
\caption{a table in a \texttt{longtable} environment}\label{tab:longtable}\\
558+
\caption{a table in a \texttt{longtable} environment}
559+
\label{tab:longtable}\\
559560
\toprule
560561
{} & a & b \\
561562
\midrule

0 commit comments

Comments
 (0)