8000 Support inverted parentheses in mathtext. · matplotlib/matplotlib@1231898 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1231898

Browse files
committed
Support inverted parentheses in mathtext.
TeX is perfectly happy to start with a closing parenthesis and end with an opening one; no need to distinguish them. Also fix a bug with old pyparsing versions for empty `\left\right` blocks.
1 parent 37cf8e4 commit 1231898

File tree

2 files changed

+21
-20
lines changed

2 files changed

+21
-20
lines changed

lib/matplotlib/_mathtext.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,13 +1701,12 @@ class _MathStyle(enum.Enum):
17011701
liminf sin cos exp limsup sinh cosh gcd ln sup cot hom log tan
17021702
coth inf max tanh""".split())
17031703

1704-
_ambi_delim = set(r"""
1704+
_ambi_delims = set(r"""
17051705
| \| / \backslash \uparrow \downarrow \updownarrow \Uparrow
17061706
\Downarrow \Updownarrow . \vert \Vert""".split())
1707-
1708-
_left_delim = set(r"( [ \{ < \lfloor \langle \lceil".split())
1709-
1710-
_right_delim = set(r") ] \} > \rfloor \rangle \rceil".split())
1707+
_left_delims = set(r"( [ \{ < \lfloor \langle \lceil".split())
1708+
_right_delims = set(r") ] \} > \rfloor \rangle \rceil".split())
1709+
_delims = _left_delims | _right_delims | _ambi_delims
17111710

17121711
def __init__(self):
17131712
p = types.SimpleNamespace()
@@ -1742,9 +1741,7 @@ def set_names_and_parse_actions():
17421741
Optional(r"\math" + oneOf(self._fontnames)("font")) + "{")
17431742
p.end_group = Literal("}")
17441743

1745-
p.ambi_delim = oneOf(self._ambi_delim)
1746-
p.left_delim = oneOf(self._left_delim)
1747-
p.right_delim = oneOf(self._right_delim)
1744+
p.delim = oneOf(self._delims)
17481745

17491746
set_names_and_parse_actions() # for root definitions.
17501747

@@ -1799,8 +1796,8 @@ def set_names_and_parse_actions():
17991796

18001797
p.genfrac <<= cmd(
18011798
r"\genfrac",
1802-
"{" + Optional(p.ambi_delim | p.left_delim)("ldelim") + "}"
1803-
+ "{" + Optional(p.ambi_delim | p.right_delim)("rdelim") + "}"
1799+
"{" + Optional(p.delim)("ldelim") + "}"
1800+
+ "{" + Optional(p.delim)("rdelim") + "}"
18041801
+ "{" + p.float_literal("rulesize") + "}"
18051802
+ p.optional_group("style")
18061803
+ p.required_group("num")
@@ -1861,13 +1858,9 @@ def set_names_and_parse_actions():
18611858
)
18621859

18631860
p.auto_delim <<= (
1864-
r"\left"
1865-
- ((p.left_delim | p.ambi_delim)("left")
1866-
| Error("Expected a delimiter"))
1861+
r"\left" - (p.delim("left") | Error("Expected a delimiter"))
18671862
+ ZeroOrMore(p.simple | p.auto_delim)("mid")
1868-
+ r"\right"
1869-
- ((p.right_delim | p.ambi_delim)("right")
1870-
| Error("Expected a delimiter"))
1863+
+ r"\right" - (p.delim("right") | Error("Expected a delimiter"))
18711864
)
18721865

18731866
# Leaf definitions.
@@ -2001,7 +1994,7 @@ def symbol(self, s, loc, toks):
20011994
# Binary operators at start of string should not be spaced
20021995
if (c in self._binary_operators and
20031996
(len(s[:loc].split()) == 0 or prev_char == '{' or
2004-
prev_char in self._left_delim)):
1997+
prev_char in self._left_delims)):
20051998
return [char]
20061999
else:
20072000
return [Hlist([self._make_space(0.2),
@@ -2106,8 +2099,7 @@ def operatorname(self, s, loc, toks):
21062099
if isinstance(name, ParseResults):
21072100
next_char_loc += len('operatorname{}')
21082101
next_char = next((c for c in s[next_char_loc:] if c != ' '), '')
2109-
delimiters = self._left_delim | self._ambi_delim | self._right_delim
2110-
delimiters |= {'^', '_'}
2102+
delimiters = self._delims | {'^', '_'}
21112103
if (next_char not in delimiters and
21122104
name not in self._overunder_functions):
21132105
# Add thin space except when followed by parenthesis, bracket, etc.
@@ -2502,4 +2494,7 @@ def _auto_sized_delimiter(self, front, middle, back):
25022494

25032495
def auto_delim(self, s, loc, toks):
25042496
return self._auto_sized_delimiter(
2505-
toks["left"], toks["mid"].asList(), toks["right"])
2497+
toks["left"],
2498+
# if "mid" in toks ... can be removed when requiring pyparsing 3.
2499+
toks["mid"].asList() if "mid" in toks else [],
2500+
toks["right"])

lib/matplotlib/tests/test_mathtext.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,12 @@ def test_operator_space(fig_test, fig_ref):
361361
fig_ref.text(0.1, 0.9, r"$\mathrm{sin}^2 \mathrm{\,cos}$")
362362

363363

364+
@check_figures_equal(extensions=["png"])
365+
def test_inverted_delimiters(fig_test, fig_ref):
366+
fig_test.text(.5, .5, r"$\left)\right($", math_fontfamily="dejavusans")
367+
fig_ref.text(.5, .5, r"$)($", math_fontfamily="dejavusans")
368+
369+
364370
def test_mathtext_fallback_valid():
365371
for fallback in ['cm', 'stix', 'stixsans', 'None']:
366372
mpl.rcParams['mathtext.fallback'] = fallback

0 commit comments

Comments
 (0)
0