Skip to content

Commit adc71b4

Browse files
Fix MathTex substring extraction to correctly handle bases with existing scripts, ensuring both subscript and superscript limits are displayed for integrals
1 parent 5e11f49 commit adc71b4

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

manim/mobject/text/tex_mobject.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def _break_up_by_substrings(self) -> Self:
362362
new_submobjects.append(sub_tex_mob)
363363
curr_index = new_index
364364
i += 1
365-
elif tex_string.strip().startswith(("^", "_")):
365+
elif self._is_pure_script(tex_string):
366366
# Handle consecutive scripts as a group, matching by Y-position
367367
script_group, j = self._group_consecutive_scripts(i)
368368
total_script_submobs = self._total_submobs_for_scripts(script_group)
@@ -376,11 +376,12 @@ def _break_up_by_substrings(self) -> Self:
376376
i = j
377377
else:
378378
# Base element processing: check if followed by scripts
379-
next_is_script = i + 1 < len(self.tex_strings) and self.tex_strings[
380-
i + 1
381-
].strip().startswith(("^", "_"))
379+
# But skip if this element already has scripts attached (e.g., \int^b)
380+
has_scripts_already = '^' in tex_string or '_' in tex_string
381+
next_is_script = (i + 1 < len(self.tex_strings) and
382+
self._is_pure_script(self.tex_strings[i + 1]))
382383

383-
if next_is_script and num_submobs > 0:
384+
if next_is_script and num_submobs > 0 and not has_scripts_already:
384385
script_group, j = self._group_consecutive_scripts(i + 1)
385386
total_script_submobs = self._total_submobs_for_scripts(script_group)
386387
total_needed = num_submobs + total_script_submobs
@@ -422,6 +423,20 @@ def _break_up_by_substrings(self) -> Self:
422423
self.submobjects = new_submobjects
423424
return self
424425

426+
def _is_pure_script(self, tex_string: str) -> bool:
427+
"""Check if a tex_string is a pure script (only ^ or _ with its content).
428+
429+
A pure script should not contain spaces or other content beyond the script itself.
430+
For example: '^n', '_1', '^{abc}' are pure scripts.
431+
But '^b dx' is not a pure script (has additional content).
432+
"""
433+
stripped = tex_string.strip()
434+
if not stripped.startswith(("^", "_")):
435+
return False
436+
# Pure scripts shouldn't have spaces (which indicate additional content)
437+
# They should be compact like '^n', '_1', '^{...}', etc.
438+
return ' ' not in stripped
439+
425440
def _group_consecutive_scripts(self, start_index: int) -> tuple[list[str], int]:
426441
"""Collect consecutive script tex_strings starting at ``start_index``.
427442
@@ -430,9 +445,7 @@ def _group_consecutive_scripts(self, start_index: int) -> tuple[list[str], int]:
430445
"""
431446
script_group = [self.tex_strings[start_index]]
432447
j = start_index + 1
433-
while j < len(self.tex_strings) and self.tex_strings[j].strip().startswith(
434-
("^", "_")
435-
):
448+
while j < len(self.tex_strings) and self._is_pure_script(self.tex_strings[j]):
436449
script_group.append(self.tex_strings[j])
437450
j += 1
438451
return script_group, j

0 commit comments

Comments
 (0)