manim icon indicating copy to clipboard operation
manim copied to clipboard

IndexError on long code blocks

Open DocJade opened this issue 1 year ago • 8 comments

Long code blocks cause an error in _gen_chars

When using large blocks of code, I experienced an issue where i could not get a string to be accepted, after a bit of experimenting, it seems that after a certain point, indexing breaks.

Expected behavior

indexing should not break

How to reproduce the issue

Code for reproducing the problem
from manim import *
inp_code = '''ccccccccccc
cccccc

cccccccccccccccccc
ccc

cccccccccccccc
cccccccccccccccccccccccc

ccccccccccccccccccc
ccccccccccccccccccccc
cccccccccccccccccccccccccc

ccccccccccccccccccccccccccccc

cccccccccccccc
cccccccccccccccccccccccc

ccccccccccccccccccccccccccc
ccccccccccccccccccccccccccc
cccccccccc

ccccccccccccccccccccccc
cccccccccccccc
cccccccccccccccc
cccccccccccc

cccccccccccccccccccccc
cccccccccccccccccccccccccccc
ccccccccccccccccc

cccccccccccccccccc

cccccccccccccccccccc
ccccccccccccccccccccccc

ccccccccccccccc
ccccccccccccccccccc
ccccccccccccccccccccc

cccccccccccccccccccc
cccccc
ccccccccc
ccccccc
cccccccc
cccccccc

cccccccccccccc
cccccccccccccccccccccccccc

cccccccccccccccccccccccccccc
ccccccccccccccccc
cccccccccc
ccccccccccccccc

cccccccccccccccccccccccccc
cccccccccccc

cccccccccccccccccccccc
cccccccccccccccccccccccccc
ccccccccccccccc

cccccccccccccc
cccccccccccccccccccccccccc

ccccccccccccccccccccccc
ccccccccccccccccccccccc
ccccc

cccccccccccccccccccccc
ccccccccccccccccccccccc
ccccccccccccc

cccccccccccccc
cccccccccccccccccccccccccc

cccccccccccccccccccccccc
cccccccccccccccccccccccc
ccccccccccccccc

cccccccccccccccccccccc
cccccccccccccccccccccc
cccccccccccc

ccccccccccccccccccccccc
ccccccccccccccccccc
ccccccccccccccccccc

cccccccccccccccccccccccccc
cccccccc
cccccccccccccccccccccc

cccccccccccccccccccccc
ccccccccccc

cccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccc
cccccccccccccccccccccc
ccccccccccccccccccccccccccc
cccccccccccccccccccc
ccccccccccccccccccc

cccccccccccccccccccc

cccccccccccccc
ccccccccccccccccccccccc

cccccccccccccccc
cccccccccc
cccccccccc

cccccccccccccccccccccc
cccccccccccccccc
ccccccccccc

cccccccccccccccccccc
cccccccccccc
ccccccc

cccccccccccccccccccccccc
cccccccccccccccccc
ccccccccccccc
ccccccccccccccccccccccc
cccccccccccccccccccccccc
ccccccccccccccccccccccccc
ccccccccccccccccccccccc
cccccccccccc

ccccccccccccccccccccc
ccccccccccccccccccccc
ccccccccccccccccccccccccc
ccccccccccccccccccccc
cccccccccccccc
cccccccccccccc

ccccccccccccccccccccccccc
ccccccccc
cccccccccc
ccccccccc

ccccccccccccccccc
cccccccccccccccccccc
ccccccccccccccc

cccccccccccccc
ccccccccccccccccccccccc

ccccccccccccc
ccccccccccc

cccccccccccccccccccccccc
ccccc

cccccccccccccc
ccccccccccccccccccccccccc

cccccccccc
cccccccccccccccccccccccc
cccccccccccccccc
ccccccccccc
ccccccccccccccccccc
ccccccccccccccccccccc

c
'''

class Main(Scene):
    def construct(self):
        code_box = Code(code=inp_code,language="asm")
        self.add(code_box)

Additional media files

none

Logs

Terminal output
Manim Community v0.18.1
+--------------------- Traceback (most recent call last) ---------------------+
| C:\tools\Manim\Lib\site-packages\manim\cli\render\commands.py:120 in render |
|                                                                             |
|   117             try:                                                      |
|   118                 with tempconfig({}):                                  |
|   119                     scene = SceneClass()                              |
| > 120                     scene.render()                                    |
|   121             except Exception:                                         |
|   122                 error_console.print_exception()                       |
|   123                 sys.exit(1)                                           |
|                                                                             |
| C:\tools\Manim\Lib\site-packages\manim\scene\scene.py:229 in render         |
|                                                                             |
|    226         """                                                          |
|    227         self.setup()                                                 |
|    228         try:                                                         |
| >  229             self.construct()                                         |
|    230         except EndSceneEarlyException:                               |
|    231             pass                                                     |
|    232         except RerunSceneException as e:                             |
|                                                                             |
| c:\Users\Jaden\Desktop\Rust_Projects\one-asm-vis\mvp.py:170 in construct    |
|                                                                             |
|   167                                                                       |
|   168 class Main(Scene):                                                    |
|   169     def construct(self):                                              |
| > 170         code_box = Code(code=inp_code,language="asm")                 |
|   171         self.add(code_box)                                            |
|   172                                                                       |
|                                                                             |
| C:\tools\Manim\Lib\site-packages\manim\mobject\text\code_mobject.py:227 in  |
| __init__                                                                    |
|                                                                             |
|   224         self.background_color = self.html_string[strati + 12 : strati |
|   225         self._gen_code_json()                                         |
|   226                                                                       |
| > 227         self.code = self._gen_colored_lines()                         |
|   228         if self.insert_line_no:                                       |
|   229             self.line_numbers = self._gen_line_numbers()              |
|   230             self.line_numbers.next_to(self.code, direction=LEFT, buff |
|                                                                             |
| C:\tools\Manim\Lib\site-packages\manim\mobject\text\code_mobject.py:350 in  |
| _gen_colored_lines                                                          |
|                                                                             |
|   347             for word_index in range(self.code_json[line_no].__len__() |
|   348                 line_str = line_str + self.code_json[line_no][word_in |
|   349             lines_text.append(self.tab_spaces[line_no] * "\t" + line_ |
| > 350         code = Paragraph(                                             |
|   351             *list(lines_text),                                        |
|   352             line_spacing=self.line_spacing,                           |
|   353             tab_width=self.tab_width,                                 |
|                                                                             |
| C:\tools\Manim\Lib\site-packages\manim\mobject\text\text_mobject.py:163 in  |
| __init__                                                                    |
|                                                                             |
|    160         super().__init__()                                           |
|    161                                                                      |
|    162         lines_str = "\n".join(list(text))                            |
| >  163         self.lines_text = Text(lines_str, line_spacing=line_spacing, |
|    164         lines_str_list = lines_str.split("\n")                       |
|    165         self.chars = self._gen_chars(lines_str_list)                 |
|    166                                                                      |
|                                                                             |
| C:\tools\Manim\Lib\site-packages\manim\mobject\text\text_mobject.py:520 in  |
| __init__                                                                    |
|                                                                             |
|    517         )                                                            |
|    518         self.text = text                                             |
|    519         if self.disable_ligatures:                                   |
| >  520             self.submobjects = [*self._gen_chars()]                  |
|    521         self.chars = self.get_group_class()(*self.submobjects)       |
|    522         self.text = text_without_tabs.replace(" ", "").replace("\n", |
|    523         nppc = self.n_points_per_curve                               |
|                                                                             |
| C:\tools\Manim\Lib\site-packages\manim\mobject\text\text_mobject.py:621 in  |
| _gen_chars                                                                  |
|                                                                             |
|    618                     )                                                |
|    619                 chars.add(space)                                     |
|    620             else:                                                    |
| >  621                 chars.add(self.submobjects[submobjects_char_index])  |
|    622                 submobjects_char_index += 1                          |
|    623         return chars                                                 |
|    624                                                                      |
+-----------------------------------------------------------------------------+
IndexError: list index out of range
[19176] Execution returned code=1 in 2.075 seconds returned signal null

System specifications

System Details
  • OS: Windows 11 (23H2)
  • RAM: 64GB
  • Python version: 3.11.9
  • Installed modules:
click             8.1.7
cloup             3.0.5
colorama          0.4.6
decorator         5.1.1
glcontext         2.5.0
isosurfaces       0.1.2
manim             0.18.1
ManimPango        0.5.0
mapbox-earcut     1.0.1
markdown-it-py    3.0.0
mdurl             0.1.2
moderngl          5.10.0
moderngl-window   2.4.6
multipledispatch  1.0.0
networkx          3.3
numpy             1.26.4
pillow            10.3.0
pip               24.1.1
pycairo           1.26.1
pydub             0.25.1
pyglet            2.0.15
Pygments          2.18.0
pyrr              0.10.3
rich              13.7.1
scipy             1.14.0
screeninfo        0.8.1
setuptools        65.5.0
skia-pathops      0.8.0.post1
srt               3.5.3
svgelements       1.9.6
tqdm              4.66.4
typing_extensions 4.12.2
watchdog          4.0.1
wheel             0.43.0
LaTeX details
  • LaTeX distribution (e.g. TeX Live 2020): ?
  • Installed LaTeX packages: ?

Additional comments

I am unable to get details on latex, but this is a fresh install of manim community, so it should be whatever version / packages are included in the chocolaty package.

Line breaks and charracters seem to effect the indexing issue differently, but in the example code provided, removing the final c will let the script run.

DocJade avatar Jun 30 '24 07:06 DocJade

The code object uses invisible characters for internal formatting. Have a look at this code piece which might help you: https://gist.github.com/abul4fia/b1e49ff695725c38e22969c8b8a0dc3e

uwezi avatar Jun 30 '24 10:06 uwezi

You can try this workaround:

  1. Split your source code file into smaller files.
  2. Define a function to combine these files, dropping the SurroundingRectangle.
  3. Create your own SurroundingRectangle for the new code block.
def BuildLongCodeBlock(*source_files):
    code_files = [Code(f, insert_line_no=False).code for f in source_files]
    code_lines = VGroup(*code_files).arrange(direction=DOWN, aligned_edge=LEFT, buff=0.5).scale(0.3)
    window = SurroundingRectangle(
        code_lines,
        color=WHITE,
        fill_color=WHITE,
        corner_radius=0.2,
        buff=0.3,
        stroke_width=1,
        stroke_color=WHITE,
    )

    return VGroup(window, code_lines)

ahm4dmajid avatar Jul 16 '24 05:07 ahm4dmajid

I have similar problems today In the first time, I want to render a long TeX like the code. After making some changes(maybe removed \array{end}), the problem disappeared. Then I changed tex_template.py, I met the same problems. I'm sure manim works well before changing it. Then I found I lost a line in _3b1b_preamble(\DisableLigatures{encoding = *, family = * }, which can not do the replacement in ctex), after adding it, manim works well again.

│ J:\Videos\manim\main.py:22 in construct                                                          │
│                                                                                                  │
│    19                                                                                            │
│    20 class HelloLaTeX(Scene):                                                                   │
│    21 │   def construct(self):                                                                   │
│ >  22 │   │   tex1 = Tex(r"柯西不等式知道吧", font_size=48, tex_template=TexTemplateLibrary.ct   │
│    23 │   │   tex2 = Tex(                                                                        │
│    24 │   │   │   r"$(a_1b_1+a_2b_2)^2\leq   (a_1^2+a_2^2)(b_1^2+b_2^2)$",                       │
│    25 │   │   │   font_size=48, tex_template=TexFontTemplates.latin_modern_tw                    │
│                                                                                                  │
│ C:\Python310\lib\site-packages\manim\mobject\text\tex_mobject.py:443 in __init__                 │
│                                                                                                  │
│   440 │   def __init__(                                                                          │
│   441 │   │   self, *tex_strings, arg_separator="", tex_environment="center", **kwargs           │
│   442 │   ):                                                                                     │
│ > 443 │   │   super().__init__(                                                                  │
│   444 │   │   │   *tex_strings,                                                                  │
│   445 │   │   │   arg_separator=arg_separator,                                                   │
│   446 │   │   │   tex_environment=tex_environment,                                               │
│                                                                                                  │
│ C:\Python310\lib\site-packages\manim\mobject\text\tex_mobject.py:278 in __init__                 │
│                                                                                                  │
│   275 │   │   │   │   tex_template=self.tex_template,                                            │
│   276 │   │   │   │   **kwargs,                                                                  │
│   277 │   │   │   )                                                                              │
│ > 278 │   │   │   self._break_up_by_substrings()                                                 │
│   279 │   │   except ValueError as compilation_error:                                            │
│   280 │   │   │   if self.brace_notation_split_occurred:                                         │
│   281 │   │   │   │   logger.error(                                                              │
│                                                                                                  │
│ C:\Python310\lib\site-packages\manim\mobject\text\tex_mobject.py:348 in _break_up_by_substrings  │
│                                                                                                  │
│   345 │   │   │   )                                                                              │
│   346 │   │   │   if num_submobs == 0:                                                           │
│   347 │   │   │   │   last_submob_index = min(curr_index, len(self.submobjects) - 1)             │
│ > 348 │   │   │   │   sub_tex_mob.move_to(self.submobjects[last_submob_index], RIGHT)            │
│   349 │   │   │   else:                                                                          │
│   350 │   │   │   │   sub_tex_mob.submobjects = self.submobjects[curr_index:new_index]           │
│   351 │   │   │   new_submobjects.append(sub_tex_mob)                                            │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
IndexError: list index out of range

huolongguo1O avatar Sep 22 '24 08:09 huolongguo1O

The len(self.submobjects) may be zero so it will raise IndexError

huolongguo1O avatar Sep 22 '24 08:09 huolongguo1O

I have similar problems today In the first time, I want to render a long TeX like the code.

  • Is this a new question or a comment about the proposed solution?
  • Why are you referring to 3B1B's preamble when using ManimCE?

uwezi avatar Sep 22 '24 08:09 uwezi

I have similar problems today In the first time, I want to render a long TeX like the code.

  • Is this a new question or a comment about the proposed solution?
  • Why are you referring to 3B1B's preamble when using ManimCE?
  • It's a new question like this issue
  • Well, I used ctex in tex_templates.py, which includes 3B1B's preamble

huolongguo1O avatar Sep 22 '24 10:09 huolongguo1O

If it is a new problem you will need to provide the exact code you used - nobody will be able to reproduce and diagnose your problem from the error messages alone.

Better yet, come over to Discord for discussions. https://docs.manim.community/en/stable/faq/general.html?highlight=discord#where-can-i-find-more-resources-for-learning-manim

uwezi avatar Sep 22 '24 10:09 uwezi

This does not just happen on long code blocks, but also code blocks with ligatures if you are using a font with ligatures. The workaround I found is using a NL font (no ligature) instead of the regular version. E.g. JetBrainsMono -> JetBrainsMonoNL:

# type:ignore
from manim import *


class MyScene(Scene):
    def construct(self):
        c2 = Code(
            code="""macro_rules! my_macro {
    ($wow : tt) => {
        dbg!($wow);
    };
}""",
            language="rust",
            style="gruvbox-light",
            font="JetBrainsMonoNL Nerd Font",
        )

        self.add(c2)
        self.wait(1)

nik-rev avatar Mar 07 '25 18:03 nik-rev