Skip to content

Conversation

@henrikmidtiby
Copy link
Contributor

@henrikmidtiby henrikmidtiby commented Dec 17, 2025

Overview: What does this pull request change?

This PR changes a large part of the implementation of the MathTex class.
The reason is to deal with the issues related to splitting the tex string and then try to match the generated objects with parts of the original tex string.
The idea for the PR is based on this discussion on discord.
https://discord.com/channels/581738731934056449/1406977902788218892

Motivation and Explanation: Why and how do your changes improve the library?

This PR changes how MathTex objects are created / rendered.
To illustrate the changes in the process, please look at the following example
of calling MathTex.

exp1 = MathTex("{a}^2+{b}^2", 
               "=", 
               "{c}^2", 
               substrings_to_isolate=["a", "b", "c"])

The first step in rendering the MathTex equation, is to join the three separate strings to a single string and add some markup to the string that will allow manim to extract certain parts of the equation afterwards. Each of the three input strings are put in the following markup.

\special{dvisvgm:raw <g id='unique000'>} < input string > \special{dvisvgm:raw </g>}

This ends up looking like the following:

\special{dvisvgm:raw <g id='unique000'>}{a}^2+{b}^2 \special{dvisvgm:raw </g>}
\special{dvisvgm:raw <g id='unique001'>}= \special{dvisvgm:raw </g>}
\special{dvisvgm:raw <g id='unique002'>}{c}^2\special{dvisvgm:raw </g>}

This allows us to access a named group in the formed svg file corresponding to each of the three tex strings.
For each string, the elements of substrings_to_isolate is also located, and marked up with a similar markup.
E.g. the a in the equation ends up like this, where the element is placed in the named group 'unique000ss'.

\special{dvisvgm:raw <g id='unique000ss'>}a\special{dvisvgm:raw </g>}

All there marked up strings are joined to the following string (newlines were added to increase readability).

\special{dvisvgm:raw <g id='unique000'>}{
\special{dvisvgm:raw <g id='unique000ss'>}a
\special{dvisvgm:raw </g>}}^2+{
\special{dvisvgm:raw <g id='unique001ss'>}b
\special{dvisvgm:raw </g>}}^2 
\special{dvisvgm:raw </g>}
\special{dvisvgm:raw <g id='unique001'>}= 
\special{dvisvgm:raw </g>}
\special{dvisvgm:raw <g id='unique002'>}{
\special{dvisvgm:raw <g id='unique002ss'>}c
\special{dvisvgm:raw </g>}}^2
\special{dvisvgm:raw </g>}

This string is then saved to a tex file and converted to first a .dvi and then a .svg file using the latex and dvisvgm command line tools.
Finally the svg file is loaded by a SVGMobject from which the named groups can be accessed as demonstrated here.

exp1.scale(2)
exp1.set_color_by_tex("a", BLUE)
exp1[2].set_color(ORANGE)
self.add(exp1)

The full code for this example is provided here

class Scene27(Scene):
    def construct(self):
        exp1 = MathTex("{a}^2+{b}^2", 
                       "=", 
                       "{c}^2", 
                       substrings_to_isolate=["a", "b", "c"])
        exp1.scale(2)
        exp1.set_color_by_tex("a", BLUE)
        exp1[2].set_color(ORANGE)
        self.add(exp1)

and it renders as follows
Scene27_ManimCE_v0 19 1

Links to added or changed documentation pages

Further Information and Comments

This PR is an extension of #4473 "Maintain groups when importing svg files"

Reviewer Checklist

  • The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • If applicable: newly added functions and classes are tested

@henrikmidtiby
Copy link
Contributor Author

And here are some example code and the generated output.

class ExampleScene8(Scene):
    def construct(self):
        formula = MathTex(
            r"P(X=k) =",
            r"\binom{12}{k}",
            r"0.5^{k}",
            r"(1-0.5)^{12-k}",
            substrings_to_isolate=["k", "1", "12", "0.5"],
        ).scale(1.3)

        formula.set_color_by_tex("k", GREEN)
        formula.set_color_by_tex("12", RED)
        formula.set_color_by_tex("1", YELLOW)
        formula.set_color_by_tex("0.5", BLUE_D)
        self.add(formula)
ExampleScene8_ManimCE_v0 19 1
class ExampleScene11(Scene):
    def construct(self):
        t2cm = {"n": RED, "1": GREEN, "x": YELLOW}
        eq = MathTex(r"\sum_{1}^{n} x", tex_to_color_map=t2cm).scale(1.3)

        self.add(eq)
ExampleScene11_ManimCE_v0 19 1

@henrikmidtiby
Copy link
Contributor Author

I have located a minor issue related to the "Using text" guide.
https://docs.manim.community/en/stable/guides/using_text.html#substrings-and-parts

In the example IncorrectLaTeXSubstringColoring, the equation is no longer colored as in the current documentation.

@henrikmidtiby henrikmidtiby marked this pull request as ready for review January 13, 2026 08:55
@henrikmidtiby henrikmidtiby linked an issue Jan 13, 2026 that may be closed by this pull request
@henrikmidtiby henrikmidtiby added pr:bugfix Bug fix for use in PRs solving a specific issue:bug refactor Refactor or redesign of existing code maintenance refactoring, typos, removing clutter/dead code, and other code quality improvements issue:bug Something isn't working... For use in issues labels Jan 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

issue:bug Something isn't working... For use in issues maintenance refactoring, typos, removing clutter/dead code, and other code quality improvements pr:bugfix Bug fix for use in PRs solving a specific issue:bug refactor Refactor or redesign of existing code

Projects

Status: 🆕 New

1 participant