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
21 changes: 20 additions & 1 deletion manim/mobject/text/tex_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from textwrap import dedent
from typing import Any

import numpy as np
from typing_extensions import Self

from manim import config, logger
Expand Down Expand Up @@ -356,7 +357,25 @@ def _break_up_by_substrings(self) -> Self:
last_submob_index = min(curr_index, len(self.submobjects) - 1)
sub_tex_mob.move_to(self.submobjects[last_submob_index], RIGHT)
else:
sub_tex_mob.submobjects = self.submobjects[curr_index:new_index]
is_script = tex_string.strip().startswith(("^", "_"))
remaining = self.submobjects[curr_index:new_index]

if is_script and len(remaining) >= num_submobs:
matched_submobs = []
for target_submob in sub_tex_mob.submobjects:
if not remaining:
break
target_center = target_submob.get_center()
best_match_idx = min(
range(len(remaining)),
key=lambda i: np.linalg.norm(
remaining[i].get_center() - target_center
),
)
matched_submobs.append(remaining.pop(best_match_idx))
sub_tex_mob.submobjects = matched_submobs
else:
sub_tex_mob.submobjects = self.submobjects[curr_index:new_index]
new_submobjects.append(sub_tex_mob)
curr_index = new_index
self.submobjects = new_submobjects
Expand Down
28 changes: 28 additions & 0 deletions tests/module/mobject/text/test_texmobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,31 @@ def test_tex_garbage_collection(tmpdir, monkeypatch, config):

tex_with_log = Tex("Hello World, again!") # da27670a37b08799.tex
assert Path("media", "Tex", "da27670a37b08799.log").exists()


def test_tex_strings_with_subscripts_and_superscripts():
"""Check that MathTex submobjects match their tex_strings when using
subscripts and superscripts in different orders.

This is a regression test for issue #3548. LaTeX may reorder subscripts
and superscripts in the compiled output, but the submobjects should still
correspond to their original tex_strings.
"""
# Test with superscript before subscript
eq1 = MathTex("A", "^n", "_1")
assert eq1.submobjects[0].get_tex_string() == "A"
assert eq1.submobjects[1].get_tex_string() == "^n"
assert eq1.submobjects[2].get_tex_string() == "_1"

# Test with subscript before superscript (reversed order)
eq2 = MathTex("A", "_1", "^n")
assert eq2.submobjects[0].get_tex_string() == "A"
assert eq2.submobjects[1].get_tex_string() == "_1"
assert eq2.submobjects[2].get_tex_string() == "^n"

# Test with summation and multiple terms
eq3 = MathTex("\\sum", "^n", "_1", "x")
assert eq3.submobjects[0].get_tex_string() == "\\sum"
assert eq3.submobjects[1].get_tex_string() == "^n"
assert eq3.submobjects[2].get_tex_string() == "_1"
assert eq3.submobjects[3].get_tex_string() == "x"
Loading