Making a text box function for Manim, but Tex objects insert automatic line breaks

Question:

I wrote the following code, which attempts to take a list of strings, and fit them inside of a bounding box of a specified width and height. It does this by inserting line breaks in appropriate places, and if the height is still exceeded, then it scales the text down by half the size and then attempts to fit it again — and so on, until eventually the text fits.

def tbox(slst, width, height):
    if width < 0.01 or height < 0.01: raise ("  Error: Box too small  ")
    if slst == []: raise("  Error: empty string list  ")

    nlst = [] # Word width list
    t_height = 0 # Max word height
    for s in slst: 
        t = Tex(s+" ")
        nlst.append(t.width)
        t_height = max(t_height, t.height)
    
    t_ind = 0
    size = 1
    cur_line = ""
    line_len = 0
    out = []

    while t_ind < len(slst): # While there are strings to process
        # If a single string is too large or the height outside the max
        if nlst[t_ind]*size > width or len(out)*t_height*size > height:
            # then reset with a smaller text size.
            t_ind, cur_line, line_len, out = 0, "", 0, []
            size *= 0.5
            continue
        # If the current string fits, add it
        if (line_len + nlst[t_ind])*size <= width:
            cur_line += slst[t_ind]+" "
            line_len += nlst[t_ind]
        # otherwise log the line and start a fresh line
        else:
            out.append(cur_line)
            cur_line = ""
            line_len = 0
            continue
        
        t_ind += 1
    # Log any line that remains at the end.
    if line_len > 0:
        out.append(cur_line)
        
    # Fit the resulting strings into a scaled VGroup
    vg = VGroup()
    for s in out:
        t = Tex(s).scale(size)
        vg.add(t)
    vg.arrange(DOWN)

    return vg

Now when I try to use this on a long string, and allow it to have a wide bounding box, it seems that Manim somehow automatically adds line breaks for strings that are too long. (At least I think so — I don’t know what else could be causing the occurrence of line breaks that don’t show up before passing the strings into the Tex constructor.)

Is there a way to turn this off? I tried parsing through the source code for Tex and its superclass, but can’t identify a part of the code that would be inserting these line breaks.

Asked By: Addem

||

Answers:

You could not find the piece of code responsible for these line breaks because Manim does not insert them either: when Tex or MathTex is rendered, Manim basically compiles a LaTeX document, converts it to an SVG, and imports the result.

Just as every other LaTeX document, the one that Manim compiles also has a page width — and if your string is too long, LaTeX breaks the line accordingly.

Take a look at these lines: https://github.com/behackl/manim-content/blob/dad382e6843700cf9afa64675d2be1d3cdb10bca/2022-06_four-gf-problems.py#L9-L13 — I’ve modified the default LaTeX page width there to make some text break automatically in my video, and you can likely adapt that approach.

Answered By: Benjamin Hackl
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.