manim icon indicating copy to clipboard operation
manim copied to clipboard

Tex splitting issue with \frac numerator

Open fcrozatier opened this issue 2 years ago • 2 comments

Description of bug / unexpected behavior

We cannot use tex splitting in the numerator of a \frac. It works in the denominator though.

Expected behavior

We should be able to split the numerator of a tex string

How to reproduce the issue

class Test(Scene):
    def construct(self):
        n = MathTex("{{n}}").shift(LEFT)
        denominator = MathTex(r"\frac{ 2 }{ {{n}} + 1 }")
        self.add(n)
        # This works
        self.play(TransformMatchingTex(n, denominator))

        # This does not work
        numerator = MathTex(r"\frac{ {{n}} + 1 }{ 2 }")
        self.play(TransformMatchingTex(n, numerator))

Logs

Manim Community v0.16.0.post0

[07/17/22 15:38:06] INFO     Animation 0 : Using cached data (hash : 3163782288_490174298_2358810818)                        cairo_renderer.py:75
[07/17/22 15:38:07] ERROR    LaTeX compilation error: Missing } inserted.                                                 tex_file_writing.py:280
                                                                                                                                                 
                    ERROR    Context of error:                                                                            tex_file_writing.py:314
                                                                                                                                                 
                             \begin{align*}                                                                                                      
                             -> \frac{}                                                                                                          
                             \end{align*}                                                                                                        
                                                                                                                                                 
                             \end{document}                                                                                                      
                                                                                                                                                 
                    ERROR    A group of double braces, {{ ... }}, was detected in                                              tex_mobject.py:291
                             your string. Manim splits TeX strings at the double                                                                 
                             braces, which might have caused the current                                                                         
                             compilation error. If you didn't use the double brace                                                               
                             split intentionally, add spaces between the braces to                                                               
                             avoid the automatic splitting: {{ ... }} --> { { ... } }.                                                           
                                                                                                                                                 
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/cli/render/commands.py:121 in    │
│ render                                                                                           │
│                                                                                                  │
│   118 │   │   │   try:                                                                           │
│   119 │   │   │   │   with tempconfig(config):                                                   │
│   120 │   │   │   │   │   scene = SceneClass()                                                   │
│ ❱ 121 │   │   │   │   │   scene.render()                                                         │
│   122 │   │   │   except Exception:                                                              │
│   123 │   │   │   │   error_console.print_exception()                                            │
│   124 │   │   │   │   sys.exit(1)                                                                │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/scene/scene.py:222 in render     │
│                                                                                                  │
│    219 │   │   """                                                                               │
│    220 │   │   self.setup()                                                                      │
│    221 │   │   try:                                                                              │
│ ❱  222 │   │   │   self.construct()                                                              │
│    223 │   │   except EndSceneEarlyException:                                                    │
│    224 │   │   │   pass                                                                          │
│    225 │   │   except RerunSceneException as e:                                                  │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/test.py:13 in construct                                                 │
│                                                                                                  │
│   10 │   │   self.play(TransformMatchingTex(n, denominator))                                     │
│   11 │   │                                                                                       │
│   12 │   │   # This does not work                                                                │
│ ❱ 13 │   │   numerator = MathTex(r"\frac{ {{n}} + 1 }{ 2 }")                                     │
│   14 │   │   self.play(TransformMatchingTex(n, numerator))                                       │
│   15                                                                                             │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:303  │
│ in __init__                                                                                      │
│                                                                                                  │
│   300 │   │   │   │   │   │   """,                                                               │
│   301 │   │   │   │   │   ),                                                                     │
│   302 │   │   │   │   )                                                                          │
│ ❱ 303 │   │   │   raise compilation_error                                                        │
│   304 │   │   self.set_color_by_tex_to_color_map(self.tex_to_color_map)                          │
│   305 │   │                                                                                      │
│   306 │   │   if self.organize_left_to_right:                                                    │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:288  │
│ in __init__                                                                                      │
│                                                                                                  │
│   285 │   │   │   │   tex_template=self.tex_template,                                            │
│   286 │   │   │   │   **kwargs,                                                                  │
│   287 │   │   │   )                                                                              │
│ ❱ 288 │   │   │   self._break_up_by_substrings()                                                 │
│   289 │   │   except ValueError as compilation_error:                                            │
│   290 │   │   │   if self.brace_notation_split_occurred:                                         │
│   291 │   │   │   │   logger.error(                                                              │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:347  │
│ in _break_up_by_substrings                                                                       │
│                                                                                                  │
│   344 │   │   new_submobjects = []                                                               │
│   345 │   │   curr_index = 0                                                                     │
│   346 │   │   for tex_string in self.tex_strings:                                                │
│ ❱ 347 │   │   │   sub_tex_mob = SingleStringMathTex(                                             │
│   348 │   │   │   │   tex_string,                                                                │
│   349 │   │   │   │   tex_environment=self.tex_environment,                                      │
│   350 │   │   │   │   tex_template=self.tex_template,                                            │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:93   │
│ in __init__                                                                                      │
│                                                                                                  │
│    90 │   │                                                                                      │
│    91 │   │   assert isinstance(tex_string, str)                                                 │
│    92 │   │   self.tex_string = tex_string                                                       │
│ ❱  93 │   │   file_name = tex_to_svg_file(                                                       │
│    94 │   │   │   self._get_modified_expression(tex_string),                                     │
│    95 │   │   │   environment=self.tex_environment,                                              │
│    96 │   │   │   tex_template=self.tex_template,                                                │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/utils/tex_file_writing.py:48 in  │
│ tex_to_svg_file                                                                                  │
│                                                                                                  │
│    45 │   if tex_template is None:                                                               │
│    46 │   │   tex_template = config["tex_template"]                                              │
│    47 │   tex_file = generate_tex_file(expression, environment, tex_template)                    │
│ ❱  48 │   dvi_file = compile_tex(                                                                │
│    49 │   │   tex_file,                                                                          │
│    50 │   │   tex_template.tex_compiler,                                                         │
│    51 │   │   tex_template.output_format,                                                        │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/utils/tex_file_writing.py:192 in │
│ compile_tex                                                                                      │
│                                                                                                  │
│   189 │   │   if exit_code != 0:                                                                 │
│   190 │   │   │   log_file = tex_file.replace(".tex", ".log")                                    │
│   191 │   │   │   print_all_tex_errors(log_file, tex_compiler, tex_file)                         │
│ ❱ 192 │   │   │   raise ValueError(                                                              │
│   193 │   │   │   │   f"{tex_compiler} error converting to"                                      │
│   194 │   │   │   │   f" {output_format[1:]}. See log output above or"                           │
│   195 │   │   │   │   f" the log file: {log_file}",                                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: latex error converting to dvi. See log output above or the log file: media/Tex/c20ec527bd31a301.log

fcrozatier avatar Jul 17 '22 13:07 fcrozatier

Description of bug / unexpected behavior

We cannot use tex splitting in the numerator of a \frac. It works in the denominator though.

Expected behavior

We should be able to split the numerator of a tex string

How to reproduce the issue

class Test(Scene):
    def construct(self):
        n = MathTex("{{n}}").shift(LEFT)
        denominator = MathTex(r"\frac{ 2 }{ {{n}} + 1 }")
        self.add(n)
        # This works
        self.play(TransformMatchingTex(n, denominator))

        # This does not work
        numerator = MathTex(r"\frac{ {{n}} + 1 }{ 2 }")
        self.play(TransformMatchingTex(n, numerator))

Logs

Manim Community v0.16.0.post0

[07/17/22 15:38:06] INFO     Animation 0 : Using cached data (hash : 3163782288_490174298_2358810818)                        cairo_renderer.py:75
[07/17/22 15:38:07] ERROR    LaTeX compilation error: Missing } inserted.                                                 tex_file_writing.py:280
                                                                                                                                                 
                    ERROR    Context of error:                                                                            tex_file_writing.py:314
                                                                                                                                                 
                             \begin{align*}                                                                                                      
                             -> \frac{}                                                                                                          
                             \end{align*}                                                                                                        
                                                                                                                                                 
                             \end{document}                                                                                                      
                                                                                                                                                 
                    ERROR    A group of double braces, {{ ... }}, was detected in                                              tex_mobject.py:291
                             your string. Manim splits TeX strings at the double                                                                 
                             braces, which might have caused the current                                                                         
                             compilation error. If you didn't use the double brace                                                               
                             split intentionally, add spaces between the braces to                                                               
                             avoid the automatic splitting: {{ ... }} --> { { ... } }.                                                           
                                                                                                                                                 
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/cli/render/commands.py:121 in    │
│ render                                                                                           │
│                                                                                                  │
│   118 │   │   │   try:                                                                           │
│   119 │   │   │   │   with tempconfig(config):                                                   │
│   120 │   │   │   │   │   scene = SceneClass()                                                   │
│ ❱ 121 │   │   │   │   │   scene.render()                                                         │
│   122 │   │   │   except Exception:                                                              │
│   123 │   │   │   │   error_console.print_exception()                                            │
│   124 │   │   │   │   sys.exit(1)                                                                │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/scene/scene.py:222 in render     │
│                                                                                                  │
│    219 │   │   """                                                                               │
│    220 │   │   self.setup()                                                                      │
│    221 │   │   try:                                                                              │
│ ❱  222 │   │   │   self.construct()                                                              │
│    223 │   │   except EndSceneEarlyException:                                                    │
│    224 │   │   │   pass                                                                          │
│    225 │   │   except RerunSceneException as e:                                                  │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/test.py:13 in construct                                                 │
│                                                                                                  │
│   10 │   │   self.play(TransformMatchingTex(n, denominator))                                     │
│   11 │   │                                                                                       │
│   12 │   │   # This does not work                                                                │
│ ❱ 13 │   │   numerator = MathTex(r"\frac{ {{n}} + 1 }{ 2 }")                                     │
│   14 │   │   self.play(TransformMatchingTex(n, numerator))                                       │
│   15                                                                                             │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:303  │
│ in __init__                                                                                      │
│                                                                                                  │
│   300 │   │   │   │   │   │   """,                                                               │
│   301 │   │   │   │   │   ),                                                                     │
│   302 │   │   │   │   )                                                                          │
│ ❱ 303 │   │   │   raise compilation_error                                                        │
│   304 │   │   self.set_color_by_tex_to_color_map(self.tex_to_color_map)                          │
│   305 │   │                                                                                      │
│   306 │   │   if self.organize_left_to_right:                                                    │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:288  │
│ in __init__                                                                                      │
│                                                                                                  │
│   285 │   │   │   │   tex_template=self.tex_template,                                            │
│   286 │   │   │   │   **kwargs,                                                                  │
│   287 │   │   │   )                                                                              │
│ ❱ 288 │   │   │   self._break_up_by_substrings()                                                 │
│   289 │   │   except ValueError as compilation_error:                                            │
│   290 │   │   │   if self.brace_notation_split_occurred:                                         │
│   291 │   │   │   │   logger.error(                                                              │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:347  │
│ in _break_up_by_substrings                                                                       │
│                                                                                                  │
│   344 │   │   new_submobjects = []                                                               │
│   345 │   │   curr_index = 0                                                                     │
│   346 │   │   for tex_string in self.tex_strings:                                                │
│ ❱ 347 │   │   │   sub_tex_mob = SingleStringMathTex(                                             │
│   348 │   │   │   │   tex_string,                                                                │
│   349 │   │   │   │   tex_environment=self.tex_environment,                                      │
│   350 │   │   │   │   tex_template=self.tex_template,                                            │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/mobject/text/tex_mobject.py:93   │
│ in __init__                                                                                      │
│                                                                                                  │
│    90 │   │                                                                                      │
│    91 │   │   assert isinstance(tex_string, str)                                                 │
│    92 │   │   self.tex_string = tex_string                                                       │
│ ❱  93 │   │   file_name = tex_to_svg_file(                                                       │
│    94 │   │   │   self._get_modified_expression(tex_string),                                     │
│    95 │   │   │   environment=self.tex_environment,                                              │
│    96 │   │   │   tex_template=self.tex_template,                                                │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/utils/tex_file_writing.py:48 in  │
│ tex_to_svg_file                                                                                  │
│                                                                                                  │
│    45 │   if tex_template is None:                                                               │
│    46 │   │   tex_template = config["tex_template"]                                              │
│    47 │   tex_file = generate_tex_file(expression, environment, tex_template)                    │
│ ❱  48 │   dvi_file = compile_tex(                                                                │
│    49 │   │   tex_file,                                                                          │
│    50 │   │   tex_template.tex_compiler,                                                         │
│    51 │   │   tex_template.output_format,                                                        │
│                                                                                                  │
│ /Users/fcrz/Movies/manim/venv/lib/python3.9/site-packages/manim/utils/tex_file_writing.py:192 in │
│ compile_tex                                                                                      │
│                                                                                                  │
│   189 │   │   if exit_code != 0:                                                                 │
│   190 │   │   │   log_file = tex_file.replace(".tex", ".log")                                    │
│   191 │   │   │   print_all_tex_errors(log_file, tex_compiler, tex_file)                         │
│ ❱ 192 │   │   │   raise ValueError(                                                              │
│   193 │   │   │   │   f"{tex_compiler} error converting to"                                      │
│   194 │   │   │   │   f" {output_format[1:]}. See log output above or"                           │
│   195 │   │   │   │   f" the log file: {log_file}",                                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: latex error converting to dvi. See log output above or the log file: media/Tex/c20ec527bd31a301.log

Check this now it works.

from manim import *


class Test(Scene):
    def construct(self):
        n = MathTex("{{n}}").shift(LEFT)
        denominator = MathTex("{2} \\over { {{n}} + 1 }")
        self.add(n)
        
        self.play(TransformMatchingTex(n, denominator), rate_func = smooth)
        self.wait(2)
        self.clear()

        numerator = MathTex("{ {{n}} + 1 } \\over {2}")
        self.play(TransformMatchingTex(n, numerator), rate_func = smooth)
        self.wait()

https://user-images.githubusercontent.com/76210541/184091028-2989f7f7-1d89-4cd2-a892-5a08d6b38226.mp4

saudzahirr avatar Aug 11 '22 08:08 saudzahirr

Thanks it's a nice workaround ! In the future I'll use this \over syntax instead of the \frac syntax.

For now I'll leave this issue open though because the \frac syntax is still buggy when it should work as expected

fcrozatier avatar Aug 11 '22 12:08 fcrozatier