Skip to content

Commit 4fb4d86

Browse files
committed
ENH: add math mode to formatter escape=latex-math I
1 parent fabdd5d commit 4fb4d86

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

pandas/io/formats/style_render.py

+39-1
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,9 @@ def format(
989989
Use 'latex' to replace the characters ``&``, ``%``, ``$``, ``#``, ``_``,
990990
``{``, ``}``, ``~``, ``^``, and ``\`` in the cell display string with
991991
LaTeX-safe sequences.
992+
Use 'latex-math' to replace the characters ``&``, ``%``, ``#``, ``_``,
993+
``{``, ``}``, ``~``, ``^``, and ``\``
994+
in the cell display string with LaTeX-safe sequences.
992995
Escaping is done before ``formatter``.
993996
994997
.. versionadded:: 1.3.0
@@ -1742,9 +1745,12 @@ def _str_escape(x, escape):
17421745
return escape_html(x)
17431746
elif escape == "latex":
17441747
return _escape_latex(x)
1748+
elif escape == "latex-math":
1749+
return _escape_latex_math(x)
17451750
else:
17461751
raise ValueError(
1747-
f"`escape` only permitted in {{'html', 'latex'}}, got {escape}"
1752+
f"`escape` only permitted in {{'html', 'latex', 'latex-math'}}, \
1753+
got {escape}"
17481754
)
17491755
return x
17501756

@@ -2343,3 +2349,35 @@ def _escape_latex(s):
23432349
.replace("^", "\\textasciicircum ")
23442350
.replace("ab2§=§8yz", "\\textbackslash ")
23452351
)
2352+
2353+
2354+
def _escape_latex_math(s):
2355+
r"""
2356+
Replace the characters ``&``, ``%``, ``#``, ``_``, ``{``, ``}``,
2357+
``~``, ``^``, and ``\`` in the string with LaTeX-safe sequences.
2358+
2359+
Parameters
2360+
----------
2361+
s : str
2362+
Input to be escaped
2363+
2364+
Return
2365+
------
2366+
str :
2367+
Escaped string
2368+
"""
2369+
return (
2370+
s.replace("\\", "ab2§=§8yz") # rare string for final conversion: avoid \\ clash
2371+
.replace("ab2§=§8yz ", "ab2§=§8yz\\space ") # since \backslash gobbles spaces
2372+
.replace("&", "\\&")
2373+
.replace("%", "\\%")
2374+
.replace("#", "\\#")
2375+
.replace("_", "\\_")
2376+
.replace("{", "\\{")
2377+
.replace("}", "\\}")
2378+
.replace("~ ", "~\\space ") # since \textasciitilde gobbles spaces
2379+
.replace("~", "\\textasciitilde ")
2380+
.replace("^ ", "^\\space ") # since \textasciicircum gobbles spaces
2381+
.replace("^", "\\textasciicircum ")
2382+
.replace("ab2§=§8yz", "\\textbackslash ")
2383+
)

pandas/tests/io/formats/style/test_format.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ def test_format_clear(styler, func, attr, kwargs):
169169
"\\textbackslash \\textasciitilde \\space \\textasciicircum \\space "
170170
"\\textbackslash \\space ",
171171
),
172+
(
173+
"latex-math",
174+
'<>\\&"\\%$\\#\\_\\{\\}\\textasciitilde \\textasciicircum '
175+
"\\textbackslash \\textasciitilde \\space \\textasciicircum \\space "
176+
"\\textbackslash \\space ",
177+
),
172178
],
173179
)
174180
def test_format_escape_html(escape, exp):
@@ -359,7 +365,7 @@ def test_format_decimal(formatter, thousands, precision, func, col):
359365

360366

361367
def test_str_escape_error():
362-
msg = "`escape` only permitted in {'html', 'latex'}, got "
368+
msg = "`escape` only permitted in {'html', 'latex', 'latex-math'}, got "
363369
with pytest.raises(ValueError, match=msg):
364370
_str_escape("text", "bad_escape")
365371

0 commit comments

Comments
 (0)