Skip to content

Commit e952f23

Browse files
authored
Merge pull request matplotlib#30715 from anntzer/opspace
Fix spacing in r"$\max f$".
2 parents 707f384 + 17428e3 commit e952f23

File tree

2 files changed

+17
-21
lines changed

2 files changed

+17
-21
lines changed

lib/matplotlib/_mathtext.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ def csnames(group: str, names: Iterable[str]) -> Regex:
21322132
self._math_expression = p.math
21332133

21342134
# To add space to nucleus operators after sub/superscripts
2135-
self._in_subscript_or_superscript = False
2135+
self._needs_space_after_subsuper = False
21362136

21372137
def parse(self, s: str, fonts_object: Fonts, fontsize: float, dpi: float) -> Hlist:
21382138
"""
@@ -2150,7 +2150,7 @@ def parse(self, s: str, fonts_object: Fonts, fontsize: float, dpi: float) -> Hli
21502150
# explain becomes a plain method on pyparsing 3 (err.explain(0)).
21512151
raise ValueError("\n" + ParseException.explain(err, 0)) from None
21522152
self._state_stack = []
2153-
self._in_subscript_or_superscript = False
2153+
self._needs_space_after_subsuper = False
21542154
# prevent operator spacing from leaking into a new expression
21552155
self._em_width_cache = {}
21562156
ParserElement.reset_cache()
@@ -2260,7 +2260,7 @@ def symbol(self, s: str, loc: int,
22602260
prev_char = next((c for c in s[:loc][::-1] if c != ' '), '')
22612261
# Binary operators at start of string should not be spaced
22622262
# Also, operators in sub- or superscripts should not be spaced
2263-
if (self._in_subscript_or_superscript or (
2263+
if (self._needs_space_after_subsuper or (
22642264
c in self._binary_operators and (
22652265
len(s[:loc].split()) == 0 or prev_char in {
22662266
'{', *self._left_delims, *self._relation_symbols}))):
@@ -2362,18 +2362,13 @@ def operatorname(self, s: str, loc: int, toks: ParseResults) -> T.Any:
23622362
next_char_loc += len('operatorname{}')
23632363
next_char = next((c for c in s[next_char_loc:] if c != ' '), '')
23642364
delimiters = self._delims | {'^', '_'}
2365-
if (next_char not in delimiters and
2366-
name not in self._overunder_functions):
2365+
if next_char not in delimiters:
23672366
# Add thin space except when followed by parenthesis, bracket, etc.
23682367
hlist_list += [self._make_space(self._space_widths[r'\,'])]
23692368
self.pop_state()
2370-
# if followed by a super/subscript, set flag to true
2371-
# This flag tells subsuper to add space after this operator
2372-
if next_char in {'^', '_'}:
2373-
self._in_subscript_or_superscript = True
2374-
else:
2375-
self._in_subscript_or_superscript = False
2376-
2369+
# If followed by a sub/superscript, set flag to true to tell subsuper
2370+
# to add space after this operator.
2371+
self._needs_space_after_subsuper = next_char in {'^', '_'}
23772372
return Hlist(hlist_list)
23782373

23792374
def start_group(self, toks: ParseResults) -> T.Any:
@@ -2483,7 +2478,10 @@ def subsuper(self, s: str, loc: int, toks: ParseResults) -> T.Any:
24832478
shift = hlist.height + vgap + nucleus.depth
24842479
vlt = Vlist(vlist)
24852480
vlt.shift_amount = shift
2486-
result = Hlist([vlt])
2481+
optional_spacing = ([self._make_space(self._space_widths[r'\,'])]
2482+
if self._needs_space_after_subsuper else [])
2483+
self._needs_space_after_subsuper = False
2484+
result = Hlist([vlt, *optional_spacing])
24872485
return [result]
24882486

24892487
# We remove kerning on the last character for consistency (otherwise
@@ -2575,12 +2573,10 @@ def subsuper(self, s: str, loc: int, toks: ParseResults) -> T.Any:
25752573

25762574
# Do we need to add a space after the nucleus?
25772575
# To find out, check the flag set by operatorname
2578-
spaced_nucleus: list[Node] = [nucleus, x]
2579-
if self._in_subscript_or_superscript:
2580-
spaced_nucleus += [self._make_space(self._space_widths[r'\,'])]
2581-
self._in_subscript_or_superscript = False
2582-
2583-
result = Hlist(spaced_nucleus)
2576+
optional_spacing = ([self._make_space(self._space_widths[r'\,'])]
2577+
if self._needs_space_after_subsuper else [])
2578+
self._needs_space_after_subsuper = False
2579+
result = Hlist([nucleus, x, *optional_spacing])
25842580
return [result]
25852581

25862582
def _genfrac(self, ldelim: str, rdelim: str, rule: float | None, style: _MathStyle,

lib/matplotlib/tests/test_mathtext.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ def test_operator_space(fig_test, fig_ref):
400400
fig_test.text(0.1, 0.6, r"$\operatorname{op}[6]$")
401401
fig_test.text(0.1, 0.7, r"$\cos^2$")
402402
fig_test.text(0.1, 0.8, r"$\log_2$")
403-
fig_test.text(0.1, 0.9, r"$\sin^2 \cos$") # GitHub issue #17852
403+
fig_test.text(0.1, 0.9, r"$\sin^2 \max \cos$") # GitHub issue #17852
404404

405405
fig_ref.text(0.1, 0.1, r"$\mathrm{log\,}6$")
406406
fig_ref.text(0.1, 0.2, r"$\mathrm{log}(6)$")
@@ -410,7 +410,7 @@ def test_operator_space(fig_test, fig_ref):
410410
fig_ref.text(0.1, 0.6, r"$\mathrm{op}[6]$")
411411
fig_ref.text(0.1, 0.7, r"$\mathrm{cos}^2$")
412412
fig_ref.text(0.1, 0.8, r"$\mathrm{log}_2$")
413-
fig_ref.text(0.1, 0.9, r"$\mathrm{sin}^2 \mathrm{\,cos}$")
413+
fig_ref.text(0.1, 0.9, r"$\mathrm{sin}^2 \mathrm{\,max} \mathrm{\,cos}$")
414414

415415

416416
@check_figures_equal()

0 commit comments

Comments
 (0)