From dba8f5997e9669f7b0110e2bfc957b79decfa1fc Mon Sep 17 00:00:00 2001 From: Nicolas Kruse Date: Wed, 21 May 2025 16:46:40 +0200 Subject: [PATCH] latex backend can be selected now --- src/pyladoc/__init__.py | 6 ++++-- src/pyladoc/latex.py | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/pyladoc/__init__.py b/src/pyladoc/__init__.py index b2c0be7..dfe0d53 100644 --- a/src/pyladoc/__init__.py +++ b/src/pyladoc/__init__.py @@ -673,7 +673,8 @@ class DocumentWriter(): def to_pdf(self, file_path: str, font_family: Literal[None, 'serif', 'sans-serif'] = None, table_renderer: TRenderer = 'simple', - latex_template_path: str = '') -> bool: + latex_template_path: str = '', + engine: latex.LatexEngine = 'pdflatex') -> bool: """ Export the document to a PDF file using LaTeX. @@ -683,6 +684,7 @@ class DocumentWriter(): latex_template_path: Path to a LaTeX template file. The expression will be replaced by the generated content. If no path is provided a default template is used. + engine: LaTeX engine (pdflatex, lualatex, xelatex or tectonic) Returns: True if the PDF file was successfully created @@ -693,7 +695,7 @@ class DocumentWriter(): if font_family == 'sans-serif': latex_code = latex.inject_latex_command(latex_code, '\\renewcommand{\\familydefault}{\\sfdefault}') - success, errors, warnings = latex.compile(latex_code, file_path) + success, errors, warnings = latex.compile(latex_code, file_path, engine=engine) if not success: print('Errors:') diff --git a/src/pyladoc/latex.py b/src/pyladoc/latex.py index ef0b3e3..80c57df 100644 --- a/src/pyladoc/latex.py +++ b/src/pyladoc/latex.py @@ -1,5 +1,5 @@ from html.parser import HTMLParser -from typing import Generator, Any +from typing import Generator, Any, Literal, get_args from pandas.io.formats.style import Styler import re import os @@ -9,6 +9,9 @@ import tempfile from .latex_escaping import unicode_to_latex_dict, latex_escape_dict +LatexEngine = Literal['pdflatex', 'lualatex', 'xelatex', 'tectonic'] + + def basic_formatter(value: Any) -> str: return escape_text(str(value)) @@ -248,7 +251,7 @@ def from_html(html_code: str) -> str: return ''.join(parser.latex_code) -def compile(latex_code: str, output_file: str = '', encoding: str = 'utf-8') -> tuple[bool, list[str], list[str]]: +def compile(latex_code: str, output_file: str = '', encoding: str = 'utf-8', engine: LatexEngine = 'pdflatex') -> tuple[bool, list[str], list[str]]: """ Compiles LaTeX code to a PDF file. @@ -256,6 +259,7 @@ def compile(latex_code: str, output_file: str = '', encoding: str = 'utf-8') -> latex_code: The LaTeX code to compile. output_file: The output file path. encoding: The encoding of the LaTeX code. + engine: LaTeX engine (pdflatex, lualatex, xelatex or tectonic) Returns: A tuple with three elements: @@ -264,8 +268,13 @@ def compile(latex_code: str, output_file: str = '', encoding: str = 'utf-8') -> - A list of warnings. """ + assert engine in get_args(LatexEngine), "engine must be pdflatex, lualatex, xelatex or tectonic" + with tempfile.TemporaryDirectory() as tmp_path: - command = ['pdflatex', '-halt-on-error', '--output-directory', tmp_path] + if engine == 'tectonic': + command = ['tectonic', '--outdir', tmp_path, '-'] + else: + command = [engine, '--halt-on-error', '--output-directory', tmp_path] errors: list[str] = [] warnings: list[str] = []