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

Code before:
]


def compile_tex(tex_file, tex_compiler, output_format):
    """Compiles a tex_file into a .dvi or a .xdv or a .pdf

    Parameters
    ----------
    tex_file : :class:`str`
        File name of TeX file to be typeset.
    tex_compiler : :class:`str`
        String containing the compiler to be used, e.g. ``pdflatex`` or ``lualatex``
    output_format : :class:`str`
        String containing the output format generated by the compiler, e.g. ``.dvi`` or ``.pdf``

    Returns
    -------
    :class:`str`
        Path to generated output file in desired format (DVI, XDV or PDF).
    """
    result = tex_file.replace(".tex", output_format)
    result = Path(result).as_posix()
    tex_file = Path(tex_file).as_posix()
    tex_dir = Path(config.get_dir("tex_dir")).as_posix()
    if not os.path.exists(result):
        command = tex_compilation_command(
            tex_compiler,
            output_format,
            tex_file,
            tex_dir,
        )
        exit_code = os.system(command)
        if exit_code != 0:
            log_file = tex_file.replace(".tex", ".log")
            if not Path(log_file).exists():
                raise RuntimeError(
                    f"{tex_compiler} failed but did not produce a log file. "
                    "Check your LaTeX installation.",
                )
            with open(log_file) as f:
                log = f.readlines()
                error_pos = [
                    index for index, line in enumerate(log) if line.startswith("!")
                ]
                if error_pos:
                    with open(tex_file) as g:
                        tex = g.readlines()
                        for log_index in error_pos:
                            logger.error(
                                f"LaTeX compilation error: {log[log_index][2:]}",
                            )

Review comment (refactor):
imo, error formatting logic doesn't belong in the method `compile_tex`. Instead, extracting out makes it clearer that we want to print the errors on an non-success from TeX, and the dev can look at the logic if that matters and ignore it otherwise

Code after:
        File name of TeX file to be typeset.
    tex_compiler : :class:`str`
        String containing the compiler to be used, e.g. ``pdflatex`` or ``lualatex``
    output_format : :class:`str`
        String containing the output format generated by the compiler, e.g. ``.dvi`` or ``.pdf``

    Returns
    -------
    :class:`str`
        Path to generated output file in desired format (DVI, XDV or PDF).
    """
    result = tex_file.replace(".tex", output_format)
    result = Path(result).as_posix()
    tex_file = Path(tex_file).as_posix()
    tex_dir = Path(config.get_dir("tex_dir")).as_posix()
    if not os.path.exists(result):
        command = tex_compilation_command(
            tex_compiler,
            output_format,
            tex_file,
            tex_dir,
        )
        exit_code = os.system(command)
        if exit_code != 0:
            log_file = tex_file.replace(".tex", ".log")
            print_all_tex_errors(log_file, tex_compiler, tex_file)
            raise ValueError(
                f"{tex_compiler} error converting to"
                f" {output_format[1:]}. See log output above or"
                f" the log file: {log_file}",
            )
    return result


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.
    """