@@ -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