From 2a84de286b5ba29e625dc4e8f881b34b52265ae0 Mon Sep 17 00:00:00 2001 From: Bjorn Arneson Date: Tue, 21 Jan 2014 14:36:21 -0600 Subject: [PATCH] Escape special characters in to_latex() --- doc/source/release.rst | 1 + pandas/core/format.py | 9 ++++++++- pandas/tests/test_format.py | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/doc/source/release.rst b/doc/source/release.rst index a3792ae74b023..f58620020d254 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -87,6 +87,7 @@ Improvements to existing features - perf improvments in ``dtypes/ftypes`` methods (:issue:`5968`) - perf improvments in indexing with object dtypes (:issue:`5968`) - improved dtype inference for ``timedelta`` like passed to constructors (:issue:`5458`,:issue:`5689`) + - escape special characters when writing to latex (:issue: `5374`) .. _release.bug_fixes-0.13.1: diff --git a/pandas/core/format.py b/pandas/core/format.py index 24b0554755ead..fce0ef6a27889 100644 --- a/pandas/core/format.py +++ b/pandas/core/format.py @@ -468,8 +468,15 @@ def write(buf, frame, column_format, strcols): for i, row in enumerate(zip(*strcols)): if i == nlevels: buf.write('\\midrule\n') # End of header - crow = [(x.replace('_', '\\_') + crow = [(x.replace('\\', '\\textbackslash') # escape backslashes first + .replace('_', '\\_') .replace('%', '\\%') + .replace('$', '\\$') + .replace('#', '\\#') + .replace('{', '\\{') + .replace('}', '\\}') + .replace('~', '\\textasciitilde') + .replace('^', '\\textasciicircum') .replace('&', '\\&') if x else '{}') for x in row] buf.write(' & '.join(crow)) buf.write(' \\\\\n') diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py index a9855c4e73c6e..d0c783725f8bb 100644 --- a/pandas/tests/test_format.py +++ b/pandas/tests/test_format.py @@ -1654,6 +1654,30 @@ def test_to_latex(self): \end{tabular} """ self.assertEqual(withoutindex_result, withoutindex_expected) + + def test_to_latex_escape_special_chars(self): + special_characters = ['&','%','$','#','_', + '{','}','~','^','\\'] + df = DataFrame(data=special_characters) + observed = df.to_latex() + expected = r"""\begin{tabular}{ll} +\toprule +{} & 0 \\ +\midrule +0 & \& \\ +1 & \% \\ +2 & \$ \\ +3 & \# \\ +4 & \_ \\ +5 & \{ \\ +6 & \} \\ +7 & \textasciitilde \\ +8 & \textasciicircum \\ +9 & \textbackslash \\ +\bottomrule +\end{tabular} +""" + self.assertEqual(observed, expected) class TestSeriesFormatting(tm.TestCase): _multiprocess_can_split_ = True