manim
manim copied to clipboard
Tex splitting issue with \frac numerator
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
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
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