Repository: ManimCommunity/manim
File: manim/utils/tex_file_writing.py (Python)

Code before:

def convert_to_svg(dvi_file, extension, page=1):
    """Converts a .dvi, .xdv, or .pdf file into an svg using dvisvgm.

    Parameters
    ----------
    dvi_file : :class:`str`
        File name of the input file to be converted.
    extension : :class:`str`
        String containing the file extension and thus indicating the file type, e.g. ``.dvi`` or ``.pdf``
    page : Optional[:class:`int`], optional
        Page to be converted if input file is multi-page.

    Returns
    -------
    :class:`str`
        Path to generated SVG file.
    """
    result = dvi_file.replace(extension, ".svg")
    result = Path(result).as_posix()
    dvi_file = Path(dvi_file).as_posix()
    if not os.path.exists(result):
        commands = [
            "dvisvgm",
            "--pdf" if extension == ".pdf" else "",
            "-p " + str(page),
            f'"{dvi_file}"',
            "-n",
            "-v 0",
            "-o " + f'"{result}"',
            ">",
            os.devnull,
        ]
        os.system(" ".join(commands))

    # if the file does not exist now, this means conversion failed
    if not os.path.exists(result):
        raise ValueError(
            f"Your installation does not support converting {extension} files to SVG."
            f" Consider updating dvisvgm to at least version 2.4."
            f" If this does not solve the problem, please refer to our troubleshooting guide at:"
            f" https://docs.manim.community/en/stable/installation/troubleshooting.html",
        )

    return result


Review comment (refactor):
is this formatting ok? `pre-compile` did this. Wonder if a comment might be worth it to show that we are trying to extract the TeX source from next log line beginning:
```
l.xx ...
```

Code after:
            for index, line in enumerate(tex_compilation_log)
            if line.startswith("!")
        ]
        if error_indices:
            with open(tex_file) as g:
                tex = g.readlines()
                for error_index in error_indices:
                    print_tex_error(tex_compilation_log, error_index, tex)


LATEX_ERROR_INSIGHTS = [
    (
        r"inputenc Error: Unicode character (?:.*) \(U\+([0-9a-fA-F]+)\)",
        insight_inputenc_error,
    ),
]


def print_tex_error(tex_compilation_log, error_start_index, tex_source):
    logger.error(
        f"LaTeX compilation error: {tex_compilation_log[error_start_index][2:]}",
    )

    # TeX errors eventually contain a line beginning 'l.xxx` where xxx is the line number that caused the compilation
    # failure. This code finds the next such line after the error current error message
    line_of_tex_error = (
        int(
            [
                log_line
                for log_line in tex_compilation_log[error_start_index:]
                if log_line.startswith("l.")
            ][0]
            .split(" ")[0]
            .split(".")[1],
        )
        - 1
    )
    # our tex error may be on a line outside our user input because of post-processing
    if line_of_tex_error >= len(tex_source):
        return None

    # all lines numbers containing '\begin{' or '\end{' - except the Manim added center and document tags
    env_markers_indices = [
        idx
        for idx, log_line in enumerate(tex_source)
        if any(marker in log_line for marker in [r"\begin{", r"\end{"])
    ][2:-2]

    context = "Context of error:\n\n"
    if line_of_tex_error in env_markers_indices:
        context += "".join(tex_source[line_of_tex_error - 1 : line_of_tex_error + 1])