Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/api/next_api_changes/behavior/23315-AM.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
mathtext no longer spaces operators at the edges of an expression
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

mathtext puts a space on each side of relation, binary and arrow operators.
Following TeX, which discards the glue at the boundaries of a math list, such an
operator is no longer spaced on a side that abuts the start or end of the
expression (or of a ``{...}`` group or delimiter).

For example, in ``"a$=b$"`` there is now no space before the ``=`` (only after
it), matching ``usetex``, and a lone operator such as ``$\doteq$`` no longer has
surrounding space. This slightly changes the horizontal metrics of math strings
that begin or end with such an operator.
34 changes: 23 additions & 11 deletions lib/matplotlib/_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -2452,21 +2452,33 @@ def symbol(self, s: str, loc: int,
"Unknown symbol: %s" % c) from err

if c in self._spaced_symbols:
# iterate until we find previous character, needed for cases
# such as $=-2$, ${ -2}$, $ -2$, or $ -2$.
# Find the previous and next characters (skipping spaces), needed
# for cases such as $=-2$, ${ -2}$, $ -2$, or $ -2$. loc points
# at the start of this symbol, so the next character is looked for
# after its source token, which may be a multi-character command
# such as "\doteq".
prev_char = next((c for c in s[:loc][::-1] if c != ' '), '')
# Binary operators at start of string should not be spaced
# Also, operators in sub- or superscripts should not be spaced
next_char = next(
(c for c in s[loc + len(toks["sym"]):] if c != ' '), '')
# A binary operator acting as a unary operator -- at the start of
# the string, or following another operator or an opening delimiter
# -- is not spaced. Operators in sub- or superscripts are not
# spaced either.
if (self._needs_space_after_subsuper or (
c in self._binary_operators and (
len(s[:loc].split()) == 0 or prev_char in {
'{', *self._left_delims, *self._relation_symbols}))):
prev_char in {'', '{', *self._left_delims,
*self._relation_symbols}))):
return [char]
else:
return [Hlist([self._make_space(0.2),
char,
self._make_space(0.2)],
do_kern=True)]
# Otherwise a spaced symbol gets a space on each side, except on a
# side where it abuts the start or end of the (sub-)expression: TeX
# discards the glue at the boundaries of a math list, so e.g. in
# "a$=b$" there is no space before the "=" (gh-23315).
left_space = prev_char not in {'', '{', *self._left_delims}
right_space = next_char not in {'', '}', *self._right_delims}
return [Hlist([*([self._make_space(0.2)] if left_space else []),
char,
*([self._make_space(0.2)] if right_space else [])],
do_kern=True)]
elif c in self._punctuation_symbols:
prev_char = next((c for c in s[:loc][::-1] if c != ' '), '')
next_char = next((c for c in s[loc + 1:] if c != ' '), '')
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 19 additions & 1 deletion lib/matplotlib/tests/test_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
r'$\mathring{A} \AA$',
r'$M \, M \thinspace M \/ M \> M \: M \; M \ M \enspace M \quad M \qquad M \! M$',
r'$\Cap$ $\Cup$ $\leftharpoonup$ $\barwedge$ $\rightharpoonup$',
r'$\hspace{-0.2}\dotplus\hspace{-0.2}$ $\hspace{-0.2}\doteq\hspace{-0.2}$ $\hspace{-0.2}\doteqdot\hspace{-0.2}$ $\ddots$',
r'$\dotplus$ $\doteq$ $\doteqdot$ $\ddots$', # github issue #23315
r'$xyz^kx_kx^py^{p-2} d_i^jb_jc_kd x^j_i E^0 E^0_u$', # github issue #4873
r'${xyz}^k{x}_{k}{x}^{p}{y}^{p-2} {d}_{i}^{j}{b}_{j}{c}_{k}{d} {x}^{j}_{i}{E}^{0}{E}^0_u$',
r'${\int}_x^x x\oint_x^x x\int_{X}^{X}x\int_x x \int^x x \int_{x} x\int^{x}{\int}_{x} x{\int}^{x}_{x}x$',
Expand Down Expand Up @@ -596,6 +596,24 @@ def test_text_escaped_braces(fig_test, fig_ref):
fig_ref.text(0.1, 0.2, r"$\text{\{example\}}$")


@check_figures_equal()
def test_spaced_operator_at_boundary(fig_test, fig_ref):
# A spaced operator (relation, binary, or arrow) at the start or end of a
# math expression is not spaced on the boundary side, matching TeX, which
# discards glue at the boundaries of a math list (gh-23315). The reference
# cancels the would-be boundary space with a matching negative \hspace.
fig_test.text(0.5, 0.1, r"$=b$") # relation at start
fig_test.text(0.5, 0.3, r"$b=$") # relation at end
fig_test.text(0.5, 0.5, r"$\doteq$") # named relation, both ends
fig_test.text(0.5, 0.7, r"$b\doteq$") # named relation at end
fig_test.text(0.5, 0.9, r"$\leftharpoonup$") # arrow, both ends
fig_ref.text(0.5, 0.1, r"$\hspace{-0.2}=b$")
fig_ref.text(0.5, 0.3, r"$b=\hspace{-0.2}$")
fig_ref.text(0.5, 0.5, r"$\hspace{-0.2}\doteq\hspace{-0.2}$")
fig_ref.text(0.5, 0.7, r"$b\doteq\hspace{-0.2}$")
fig_ref.text(0.5, 0.9, r"$\hspace{-0.2}\leftharpoonup\hspace{-0.2}$")


@check_figures_equal()
def test_boldsymbol(fig_test, fig_ref):
fig_test.text(0.1, 0.2, r"$\boldsymbol{\mathrm{abc0123\alpha}}$")
Expand Down
Loading