Fix mathtext spacing of operators at expression boundaries - #32331
Open
ahmed5145 wants to merge 3 commits into
Open
Fix mathtext spacing of operators at expression boundaries#32331ahmed5145 wants to merge 3 commits into
ahmed5145 wants to merge 3 commits into
Conversation
Relation, binary and arrow operators are "spaced symbols": mathtext puts
a space on each side of them. TeX, however, discards the glue at the
boundaries of a math list, so an operator at the very start or end of an
expression (or of a {...} group) is not spaced on that side -- e.g. in
"a$=b$" there is no space before the "=", only after it. mathtext
instead spaced both sides, and only binary operators were special-cased
at the start of the string.
Decide the left and right spacing of a spaced symbol independently, and
drop the space on any side that abuts the start/end of the expression or
an opening/closing delimiter. The lookahead for the next character now
skips over the source token (which may be a multi-character command such
as "\doteq") instead of just loc + 1.
This restores the simpler \ddots test that had to be worked around with
negative \hspace, and adds a check_figures_equal regression test.
Closes matplotlib#23315
ahmed5145
force-pushed
the
fix-relation-operator-spacing
branch
from
September 10, 2026 18:13
da76485 to
9a143d7
Compare
Document the behavior change from matplotlib#23315: spaced operators (relation, binary, arrow) are no longer spaced on a side that abuts the start or end of a math expression.
Regenerate the baseline images that change now that spaced operators are not padded at the boundaries of an expression: index 71 of test_mathtext_rendering (a lone \leftharpoonup / \rightharpoonup) and index 1 of test_mathtext_rendering_lightweight (\rightarrow / \leftarrow inside \overset / \underset). PNGs are optimized with oxipng.
ahmed5145
force-pushed
the
fix-relation-operator-spacing
branch
from
September 11, 2026 17:14
54942d2 to
6abfb08
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR summary
Closes #23315.
Relation, binary and arrow operators are "spaced symbols", mathtext puts a space on both sides of them. But TeX drops the glue at the boundaries of a math list, so an operator at the very start or end of an expression (or of a
{...}group) shouldn't be spaced on that side. For example, ina$=b$there's no space before the=, only after it. mathtext spaced both sides, and only binary operators were special-cased, and only at the start of the string.I now decide the left and right spacing of each spaced symbol independently, and drop the space on any side that touches the start/end of the expression or an opening/closing delimiter. I also fixed the next-character lookahead so it skips past the whole source token (e.g. a multi-character command like
\doteq) instead of justloc + 1, which is what made named relations at the end still get a stray space.This lets me restore the simpler
\ddotstest that previously needed a negative\hspaceworkaround, and I added acheck_figures_equalregression test.Two existing image tests change, and I've regenerated their baselines (built locally with matplotlib's bundled FreeType, the same one the image tests use):
test_mathtext_renderingindex 71 ($\Cap$ $\Cup$ $\leftharpoonup$ $\barwedge$ $\rightharpoonup$): the harpoons, alone in$...$, no longer get edge spacing.test_mathtext_rendering_lightweightindex 1: the\rightarrow/\leftarrowinside\overset/\undersetno longer get edge spacing.Both are correct changes. I verified index 72 (the
\ddotstest) renders pixel-identically to its existing baseline across all fontsets, so it does not need regeneration.AI Disclosure
I used Claude Code to explore and navigate the mathtext parser and scaffold the regression test. I decided on the approach, edited the code and made the changes. Then, I checked the result against TeX's spacing: compared rendered output before and after the change and confirmed the restored
\ddotstest matches its existing baseline.doc/api/next_api_changes/behavior/23315-AM.rst.