feat: support multiple TeX compilers in TexTemplate (#4810)

* feat: support multiple compilations

Allow `tex_compiler` to be a `str | list[str]` instead of just
`str`. When a list is given, document will be compiled sequentially.

* fix: suppress compilation progress log when only one compiler is used

* fix: updated docstrings and variable naming
This commit is contained in:
Caffein3 2026-06-17 10:35:14 +08:00 committed by GitHub
commit 4c4622df54
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 18 deletions

View file

@ -33,8 +33,10 @@ class TexTemplate:
_body: str = field(default="", init=False)
"""A custom body, can be set from a file."""
tex_compiler: str = "latex"
"""The TeX compiler to be used, e.g. ``latex``, ``pdflatex`` or ``lualatex``."""
tex_compiler: str | list[str] = "latex"
"""The TeX compiler(s) to be used. Can be a single compiler (e.g. ``"latex"``,
``"pdflatex"``, ``"lualatex"``) or a list of compilers to compile in order
(e.g. ``["lualatex", "pdflatex"]``)."""
description: str = ""
"""A description of the template"""

View file

@ -178,7 +178,9 @@ def insight_package_not_found_error(matching: Match[str]) -> Generator[str]:
yield f"Install {matching[1]} it using your LaTeX package manager, or check for typos."
def compile_tex(tex_file: Path, tex_compiler: str, output_format: str) -> Path:
def compile_tex(
tex_file: Path, tex_compiler: str | list[str], output_format: str
) -> Path:
"""Compiles a tex_file into a .dvi or a .xdv or a .pdf
Parameters
@ -186,7 +188,8 @@ def compile_tex(tex_file: Path, tex_compiler: str, output_format: str) -> Path:
tex_file
File name of TeX file to be typeset.
tex_compiler
String containing the compiler to be used, e.g. ``pdflatex`` or ``lualatex``
The TeX compiler(s) to be used.
Can be a single compiler (e.g. ``"latex"``, ``"pdflatex"`` ``"lualatex"``) or a list of compilers to compile in order (e.g. ``["lualatex", "pdflatex"]``).
output_format
String containing the output format generated by the compiler, e.g. ``.dvi`` or ``.pdf``
@ -197,22 +200,26 @@ def compile_tex(tex_file: Path, tex_compiler: str, output_format: str) -> Path:
"""
result = tex_file.with_suffix(output_format)
tex_dir = config.get_dir("tex_dir")
tex_compilers = [tex_compiler] if isinstance(tex_compiler, str) else tex_compiler
if not result.exists():
command = make_tex_compilation_command(
tex_compiler,
output_format,
tex_file,
tex_dir,
)
cp = subprocess.run(command, stdout=subprocess.DEVNULL)
if cp.returncode != 0:
log_file = tex_file.with_suffix(".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}",
for i, compiler in enumerate(tex_compilers, start=1):
if len(tex_compilers) > 1:
logger.info(f"Compiling {i} of {len(tex_compilers)}: {compiler}")
command = make_tex_compilation_command(
compiler,
output_format,
tex_file,
tex_dir,
)
cp = subprocess.run(command, stdout=subprocess.DEVNULL)
if cp.returncode != 0:
log_file = tex_file.with_suffix(".log")
print_all_tex_errors(log_file, compiler, tex_file)
raise ValueError(
f"{compiler} error converting to"
f" {output_format[1:]}. See log output above or"
f" the log file: {log_file}",
)
return result