-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
ENH: add LaTeX math mode with parentheses #51903
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
Changes from 5 commits
ba72f26
0801f6a
2320fb3
c20e795
2e283a7
29e357c
849bf36
9be5c22
7b4b53a
25e6b1f
ed27582
3daf4d5
78dcdf8
c06695e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1117,7 +1117,8 @@ def format( | |
2 & \textbf{\$\%\#} \\ | ||
\end{tabular} | ||
|
||
Using ``escape`` in 'latex-math' mode. | ||
Applying ``escape`` in 'latex-math' mode. In the example below | ||
we enter math mode using the character ``$``. | ||
|
||
>>> df = pd.DataFrame([[r"$\sum_{i=1}^{10} a_i$ a~b $\alpha \ | ||
... = \frac{\beta}{\zeta^2}$"], ["%#^ $ \$x^2 $"]]) | ||
|
@@ -1129,6 +1130,20 @@ def format( | |
1 & \%\#\textasciicircum \space $ \$x^2 $ \\ | ||
\end{tabular} | ||
|
||
We can use the character ``\(`` to enter math mode and the character ``\)`` | ||
to close math mode. | ||
|
||
>>> df = pd.DataFrame([[r"\(\sum_{i=1}^{10} a_i\) a~b \(\alpha \ | ||
... = \frac{\beta}{\zeta^2}\)"], ["%#^ \( \$x^2 \)"]]) | ||
>>> df.style.format(escape="latex-math").to_latex() | ||
... # doctest: +SKIP | ||
\begin{tabular}{ll} | ||
& 0 \\ | ||
0 & \(\sum_{i=1}^{10} a_i\) a\textasciitilde b \(\alpha | ||
= \frac{\beta}{\zeta^2}\) \\ | ||
1 & \%\#\textasciicircum \space \( \$x^2 \) \\ | ||
\end{tabular} | ||
|
||
Pandas defines a `number-format` pseudo CSS attribute instead of the `.format` | ||
method to create `to_excel` permissible formatting. Note that semi-colons are | ||
CSS protected characters but used as separators in Excel's format string. | ||
|
@@ -2344,7 +2359,8 @@ def _escape_latex(s): | |
Escaped string | ||
""" | ||
return ( | ||
s.replace("\\", "ab2§=§8yz") # rare string for final conversion: avoid \\ clash | ||
s.replace("\\ ", "ab2§=§8yz") | ||
.replace("\\", "ab2§=§8yz") # rare string for final conversion: avoid \\ clash | ||
.replace("ab2§=§8yz ", "ab2§=§8yz\\space ") # since \backslash gobbles spaces | ||
.replace("&", "\\&") | ||
.replace("%", "\\%") | ||
|
@@ -2363,11 +2379,11 @@ def _escape_latex(s): | |
|
||
def _escape_latex_math(s): | ||
r""" | ||
All characters between two characters ``$`` are preserved. | ||
All characters in LaTeX math mode are preserved. | ||
|
||
The substrings in LaTeX math mode, which start with the character ``$`` | ||
and end with ``$``, are preserved without escaping. Otherwise | ||
regular LaTeX escaping applies. See ``_escape_latex()``. | ||
The substrings in LaTeX math mode, which either are surrounded | ||
by two characters ``$`` or start with the character ``\(`` and end with ``\)``, | ||
are preserved without escaping. Otherwise regular LaTeX escaping applies. | ||
|
||
Parameters | ||
---------- | ||
|
@@ -2379,16 +2395,55 @@ def _escape_latex_math(s): | |
str : | ||
Escaped string | ||
""" | ||
s = s.replace(r"\$", r"rt8§=§7wz") | ||
pattern = re.compile(r"\$.*?\$") | ||
pos = 0 | ||
ps = pattern.search(s, pos) | ||
res = [] | ||
while ps: | ||
res.append(_escape_latex(s[pos : ps.span()[0]])) | ||
res.append(ps.group()) | ||
pos = ps.span()[1] | ||
|
||
def _math_mode_with_dollar(s): | ||
attack68 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
s = s.replace(r"\$", r"rt8§=§7wz") | ||
pattern = re.compile(r"\$.*?\$") | ||
pos = 0 | ||
ps = pattern.search(s, pos) | ||
res = [] | ||
while ps: | ||
res.append(_escape_latex(s[pos : ps.span()[0]])) | ||
res.append(ps.group()) | ||
pos = ps.span()[1] | ||
ps = pattern.search(s, pos) | ||
|
||
res.append(_escape_latex(s[pos : len(s)])) | ||
return "".join(res).replace(r"rt8§=§7wz", r"\$") | ||
|
||
def _math_mode_with_parentheses(s): | ||
s = s.replace(r"\(", r"LEFT§=§6yzLEFT").replace(r"\)", r"RIGHTab5§=§RIGHT") | ||
res = [] | ||
for item in re.split(r"LEFT§=§6yz|ab5§=§RIGHT", s): | ||
if item.startswith("LEFT") and item.endswith("RIGHT"): | ||
res.append(item.replace("LEFT", r"\(").replace("RIGHT", r"\)")) | ||
elif "LEFT" in item and "RIGHT" in item: | ||
res.append( | ||
_escape_latex(item).replace("LEFT", r"\(").replace("RIGHT", r"\)") | ||
) | ||
else: | ||
res.append( | ||
_escape_latex(item) | ||
.replace("LEFT", r"\textbackslash (") | ||
.replace("RIGHT", r"\textbackslash )") | ||
) | ||
return "".join(res) | ||
|
||
res.append(_escape_latex(s[pos : len(s)])) | ||
return "".join(res).replace(r"rt8§=§7wz", r"\$") | ||
s = s.replace(r"\$", r"rt8§=§7wz") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this code. Then in line 2490 you are replacing the same string There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the comment. I can explain what I am trying to do. When I checked the function I corrected my mistake a made a new commit. I also added an example for this case in the test. |
||
pattern_d = re.compile(r"\$.*?\$") | ||
pattern_p = re.compile(r"\\(.*?\\)") | ||
pos_d = 0 | ||
pos_p = 0 | ||
ps_d = pattern_d.search(s, pos_d) | ||
ps_p = pattern_p.search(s, pos_p) | ||
mode = [] | ||
if ps_d: | ||
mode.append(ps_d.span()[0]) | ||
if ps_p: | ||
mode.append(ps_p.span()[0]) | ||
if len(mode) == 0: | ||
return _escape_latex(s.replace(r"\$", r"rt8§=§7wz")) | ||
if s[min(mode)] == r"$": | ||
return _math_mode_with_dollar(s.replace(r"\$", r"rt8§=§7wz")) | ||
else: | ||
return _math_mode_with_parentheses(s.replace(r"\$", r"rt8§=§7wz")) |
Uh oh!
There was an error while loading. Please reload this page.