Module src.PyOghma_ML.Latex
This module provides a class for programmatically generating LaTeX documents.
The Document class simplifies the creation of LaTeX files by providing methods to define document structure, add sections, figures, tables, and compile the document into a PDF. It is designed to automate the process of generating reports and visualizations in a LaTeX-compatible format.
Classes
class Document (document_class: str,
document_properties: List[str],
packages: List[str],
**kwargs: Any)-
Expand source code
class Document: """ A class for generating LaTeX documents programmatically. This class provides methods for creating LaTeX documents, adding sections, figures, tables, and compiling the document into a PDF. """ def __init__(self, document_class: str, document_properties: List[str], packages: List[str], **kwargs: Any) -> None: """ Initialize a Document instance. Args: document_class (str): The LaTeX document class (e.g., 'article'). document_properties (list): List of properties for the document class (e.g., ['12pt']). packages (list): List of LaTeX packages to include (e.g., ['graphicx']). **kwargs: Additional keyword arguments. """ self.file = io.StringIO() self.tab = 0 self.newline = True self.document_class(document_class, document_properties) self.usepakage(packages) self.file_header() self.write(self.header) def document_class(self, document_class: str, document_properties: List[str]) -> None: """ Define the LaTeX document class and its properties. Args: document_class (str): The LaTeX document class. document_properties (list): List of properties for the document class. """ options = ["[" + str(dp) + "]" for dp in document_properties] options = ''.join(options) self.dc = '\\documentclass' + options + '{' + document_class + '}\n' def usepakage(self, packages: List[str]) -> None: """ Include LaTeX packages in the document. Args: packages (list): List of LaTeX packages to include. """ up = ['\\usepackage{' + str(p) + '}\n' for p in packages] self.up = ''.join(up) def geometry(self, left: str = '2cm', right: str = '2cm', top: str = '1cm', bottom: str = '2cm', paper: str = 'a4paper') -> None: """ Set the page geometry for the document. Args: left (str): Left margin (default: '2cm'). right (str): Right margin (default: '2cm'). top (str): Top margin (default: '1cm'). bottom (str): Bottom margin (default: '2cm'). paper (str): Paper size (default: 'a4paper'). """ x = 'geometry' y = 'left=' + str(left) + ',right=' + str(right) + ',top=' + str(top) + ',bottom=' + str( bottom) + ',paper=' + str(paper) self.write(self.command(x, y)) def file_header(self) -> None: """ Generate the LaTeX file header, including the document class and packages. """ header = ''.join([self.dc, self.up]) self.header = header def write(self, x: str) -> None: """ Write content to the LaTeX document. Args: x (str): The content to write. """ tabs = '\t' * self.tab self.file.write(tabs+x) if self.newline: self.file.write('\n') def save_tex(self) -> None: """ Save the LaTeX document to a temporary .tex file. This method writes the accumulated LaTeX content to a file named 'tempfile.tex' in the current working directory. The file can then be compiled to PDF or edited manually. Note: The file is saved as 'tempfile.tex' and will overwrite any existing file with the same name. """ temp_tex = 'tempfile.tex' f = open(temp_tex, 'w') f.write(self.file.getvalue()) f.close() def compile(self) -> None: """ Compile the LaTeX document into a PDF using pdflatex. This method executes the pdflatex command to compile the temporary LaTeX file into a PDF document. The compilation output is suppressed to avoid cluttering the console. Note: Requires pdflatex to be installed and available in the system PATH. The compiled PDF will be named 'tempfile.pdf' in the working directory. Raises: OSError: If pdflatex is not found or compilation fails. """ os.system("pdflatex tempfile.tex #> /dev/null 2>&1") def title(self, title: str) -> None: """ Set the title of the document. Args: title (str): The title text. """ self.write('\\title{'+title+'}\n') def date(self, date: str = '\\today') -> None: """ Set the date of the document. Args: date (str): The date text (default: '\\today'). """ self.write('\\date{'+date+'}\n') def author(self, author: str = 'T.H. Parry-Williams') -> None: """ Set the author of the document. Args: author (str): The author name (default: 'T.H. Parry-Williams'). """ self.write('\\author{'+author+'}\n') def begin_document(self) -> None: """ Begin the LaTeX document environment. """ self.write('\\begin{document}\n') def end_document(self) -> None: """ End the LaTeX document environment. """ self.write('\\end{document}\n') def make_title(self) -> None: """ Add the title, author, and date to the document. """ self.write(self.command('maketitle')) def section(self, x: str) -> None: """ Add a section to the document. Args: x (str): The section title. """ self.write('\\section{'+str(x)+'}\n') def subsection(self, x: str) -> None: """ Add a subsection to the document. Args: x (str): The subsection title. """ self.write('\\subsection{'+str(x)+'}\n') def subsubsection(self, x: str) -> None: """ Add a subsubsection to the document. Args: x (str): The subsubsection title. """ self.write('\\subsubsection{'+str(x)+'}\n') def begin(self, x: str, options: Optional[List[str]] = None, options1: Optional[List[str]] = None) -> None: """ Begin a LaTeX environment. Args: x (str): The environment name. options (list, optional): List of options for the environment. options1 (list, optional): Additional options for the environment. """ if options is not None: option = ['['+o+']' for o in options] option = ''.join(option) if options1 is not None: option1 = '{' + ''.join(options1) + '}' if options is not None: if options1 is not None: self.write('\\begin{'+str(x)+'}'+option+option1+'\n') else: self.write('\\begin{'+str(x)+'}'+option+'\n') else: if options1 is not None: self.write('\\begin{'+str(x)+'}'+option1+'\n') else: self.write('\\begin{'+str(x)+'}\n') def end(self, x: str) -> None: """ End a LaTeX environment. Args: x (str): The environment name. """ self.write('\\end{'+str(x)+'}\n') def newpage(self) -> None: """ Add a new page to the document. """ self.write(self.command('newpage')) @staticmethod def command(x: str, y: Optional[str] = None) -> str: """ Generate a LaTeX command. Args: x (str): The command name. y (str, optional): The command argument. Returns: str: The formatted LaTeX command. """ if y is None: x = '\\' + x + '\n' else: x = '\\' + x + '{' + y + '}\n' return x def includegraphics(self, x: str, width: str, newline: bool = True) -> None: """ Include a graphic in the document. Args: x (str): The path to the graphic file. width (str): The width of the graphic. newline (bool): Whether to add a newline after the graphic (default: True). """ command = '\\includegraphics' w = '[width=' + str(width) + ']' if newline: command = command + w + '{' + str(x) + '}\n' else: command = command + w + '{' + str(x) + '}' self.write(command) def figure(self, arg: str, centering: bool = True, position: str = 'h', width: str = '\\textwidth', caption: str = '') -> None: """ Add a figure to the document. Args: arg (str): The path to the figure file. centering (bool): Whether to center the figure (default: True). position (str): The position specifier (default: 'h'). width (str): The width of the figure (default: '\\textwidth'). caption (str): The caption for the figure (default: ''). """ self.begin('figure', options=[position]) self.tab = 1 if centering: self.write(self.command('centering')) self.includegraphics(arg, width=width, newline=False) if caption != '': self.write(self.command('caption', caption)) self.tab = 0 self.end('figure') def subfigure(self, *args: str, centering: bool = True, position: str = 'h', caption: str = '', width: float = 0.5) -> None: """ Add subfigures to the document. Args: *args: Paths to the subfigure files. centering (bool): Whether to center the subfigures (default: True). position (str): The position specifier (default: 'h'). caption (str): The caption for the subfigures (default: ''). width (float): The width of each subfigure as a fraction of the text width (default: 0.5). """ self.newline = False self.begin('figure', options=['H']) self.tab = 1 self.write(self.command('centering')) for i in range(len(args)): self.tab = 1 self.begin('subfigure', options1=[str(width) + '\\textwidth']) self.tab = 2 if centering: self.write(self.command('centering')) self.includegraphics(args[i], width='1\\linewidth', newline=True) self.newline = False self.tab = 1 self.end('subfigure') self.write(self.command('hfill')) self.tab = 0 if caption != '': self.write(self.command('caption', caption)) self.end('figure') self.newline = True def table(self, df: Any, centering: bool = True, position: str = 'H', caption: str = '', highlight: bool = False) -> None: """ Add a table to the document. Args: df (pandas.DataFrame): The data to include in the table. centering (bool): Whether to center the table (default: True). position (str): The position specifier (default: 'H'). caption (str): The caption for the table (default: ''). highlight (bool): Whether to highlight specific cells (default: False). """ col_num = len(df.columns) col_format = 'l' + 'c' * (col_num) if highlight: df = df.style.background_gradient(cmap='RdYlGn_r', subset='MAPE (\%)', vmin=0, vmax=100).hide(axis="index") else: df = df.style.hide(axis="index") if caption != '': self.write( df.to_latex(column_format=col_format, caption=caption, position=position, position_float='centering', hrules=True, convert_css=True)) else: self.write(df.to_latex(column_format=col_format, position=position, position_float='centering', hrules=True, convert_css=True))
A class for generating LaTeX documents programmatically.
This class provides methods for creating LaTeX documents, adding sections, figures, tables, and compiling the document into a PDF.
Initialize a Document instance.
Args
document_class
:str
- The LaTeX document class (e.g., 'article').
document_properties
:list
- List of properties for the document class (e.g., ['12pt']).
packages
:list
- List of LaTeX packages to include (e.g., ['graphicx']).
**kwargs
- Additional keyword arguments.
Static methods
def command(x: str, y: str | None = None) ‑> str
-
Expand source code
@staticmethod def command(x: str, y: Optional[str] = None) -> str: """ Generate a LaTeX command. Args: x (str): The command name. y (str, optional): The command argument. Returns: str: The formatted LaTeX command. """ if y is None: x = '\\' + x + '\n' else: x = '\\' + x + '{' + y + '}\n' return x
Generate a LaTeX command.
Args
x
:str
- The command name.
y
:str
, optional- The command argument.
Returns
str
- The formatted LaTeX command.
Methods
-
Expand source code
def author(self, author: str = 'T.H. Parry-Williams') -> None: """ Set the author of the document. Args: author (str): The author name (default: 'T.H. Parry-Williams'). """ self.write('\\author{'+author+'}\n')
Set the author of the document.
Args
author
:str
- The author name (default: 'T.H. Parry-Williams').
def begin(self, x: str, options: List[str] | None = None, options1: List[str] | None = None) ‑> None
-
Expand source code
def begin(self, x: str, options: Optional[List[str]] = None, options1: Optional[List[str]] = None) -> None: """ Begin a LaTeX environment. Args: x (str): The environment name. options (list, optional): List of options for the environment. options1 (list, optional): Additional options for the environment. """ if options is not None: option = ['['+o+']' for o in options] option = ''.join(option) if options1 is not None: option1 = '{' + ''.join(options1) + '}' if options is not None: if options1 is not None: self.write('\\begin{'+str(x)+'}'+option+option1+'\n') else: self.write('\\begin{'+str(x)+'}'+option+'\n') else: if options1 is not None: self.write('\\begin{'+str(x)+'}'+option1+'\n') else: self.write('\\begin{'+str(x)+'}\n')
Begin a LaTeX environment.
Args
x
:str
- The environment name.
options
:list
, optional- List of options for the environment.
options1
:list
, optional- Additional options for the environment.
def begin_document(self) ‑> None
-
Expand source code
def begin_document(self) -> None: """ Begin the LaTeX document environment. """ self.write('\\begin{document}\n')
Begin the LaTeX document environment.
def compile(self) ‑> None
-
Expand source code
def compile(self) -> None: """ Compile the LaTeX document into a PDF using pdflatex. This method executes the pdflatex command to compile the temporary LaTeX file into a PDF document. The compilation output is suppressed to avoid cluttering the console. Note: Requires pdflatex to be installed and available in the system PATH. The compiled PDF will be named 'tempfile.pdf' in the working directory. Raises: OSError: If pdflatex is not found or compilation fails. """ os.system("pdflatex tempfile.tex #> /dev/null 2>&1")
Compile the LaTeX document into a PDF using pdflatex.
This method executes the pdflatex command to compile the temporary LaTeX file into a PDF document. The compilation output is suppressed to avoid cluttering the console.
Note
Requires pdflatex to be installed and available in the system PATH. The compiled PDF will be named 'tempfile.pdf' in the working directory.
Raises
OSError
- If pdflatex is not found or compilation fails.
def date(self, date: str = '\\today') ‑> None
-
Expand source code
def date(self, date: str = '\\today') -> None: """ Set the date of the document. Args: date (str): The date text (default: '\\today'). """ self.write('\\date{'+date+'}\n')
Set the date of the document.
Args
date
:str
- The date text (default: '\today').
def document_class(self, document_class: str, document_properties: List[str]) ‑> None
-
Expand source code
def document_class(self, document_class: str, document_properties: List[str]) -> None: """ Define the LaTeX document class and its properties. Args: document_class (str): The LaTeX document class. document_properties (list): List of properties for the document class. """ options = ["[" + str(dp) + "]" for dp in document_properties] options = ''.join(options) self.dc = '\\documentclass' + options + '{' + document_class + '}\n'
Define the LaTeX document class and its properties.
Args
document_class
:str
- The LaTeX document class.
document_properties
:list
- List of properties for the document class.
def end(self, x: str) ‑> None
-
Expand source code
def end(self, x: str) -> None: """ End a LaTeX environment. Args: x (str): The environment name. """ self.write('\\end{'+str(x)+'}\n')
End a LaTeX environment.
Args
x
:str
- The environment name.
def end_document(self) ‑> None
-
Expand source code
def end_document(self) -> None: """ End the LaTeX document environment. """ self.write('\\end{document}\n')
End the LaTeX document environment.
def figure(self,
arg: str,
centering: bool = True,
position: str = 'h',
width: str = '\\textwidth',
caption: str = '') ‑> None-
Expand source code
def figure(self, arg: str, centering: bool = True, position: str = 'h', width: str = '\\textwidth', caption: str = '') -> None: """ Add a figure to the document. Args: arg (str): The path to the figure file. centering (bool): Whether to center the figure (default: True). position (str): The position specifier (default: 'h'). width (str): The width of the figure (default: '\\textwidth'). caption (str): The caption for the figure (default: ''). """ self.begin('figure', options=[position]) self.tab = 1 if centering: self.write(self.command('centering')) self.includegraphics(arg, width=width, newline=False) if caption != '': self.write(self.command('caption', caption)) self.tab = 0 self.end('figure')
Add a figure to the document.
Args
arg
:str
- The path to the figure file.
centering
:bool
- Whether to center the figure (default: True).
position
:str
- The position specifier (default: 'h').
width
:str
- The width of the figure (default: '\textwidth').
caption
:str
- The caption for the figure (default: '').
def file_header(self) ‑> None
-
Expand source code
def file_header(self) -> None: """ Generate the LaTeX file header, including the document class and packages. """ header = ''.join([self.dc, self.up]) self.header = header
Generate the LaTeX file header, including the document class and packages.
def geometry(self,
left: str = '2cm',
right: str = '2cm',
top: str = '1cm',
bottom: str = '2cm',
paper: str = 'a4paper') ‑> None-
Expand source code
def geometry(self, left: str = '2cm', right: str = '2cm', top: str = '1cm', bottom: str = '2cm', paper: str = 'a4paper') -> None: """ Set the page geometry for the document. Args: left (str): Left margin (default: '2cm'). right (str): Right margin (default: '2cm'). top (str): Top margin (default: '1cm'). bottom (str): Bottom margin (default: '2cm'). paper (str): Paper size (default: 'a4paper'). """ x = 'geometry' y = 'left=' + str(left) + ',right=' + str(right) + ',top=' + str(top) + ',bottom=' + str( bottom) + ',paper=' + str(paper) self.write(self.command(x, y))
Set the page geometry for the document.
Args
left
:str
- Left margin (default: '2cm').
right
:str
- Right margin (default: '2cm').
top
:str
- Top margin (default: '1cm').
bottom
:str
- Bottom margin (default: '2cm').
paper
:str
- Paper size (default: 'a4paper').
def includegraphics(self, x: str, width: str, newline: bool = True) ‑> None
-
Expand source code
def includegraphics(self, x: str, width: str, newline: bool = True) -> None: """ Include a graphic in the document. Args: x (str): The path to the graphic file. width (str): The width of the graphic. newline (bool): Whether to add a newline after the graphic (default: True). """ command = '\\includegraphics' w = '[width=' + str(width) + ']' if newline: command = command + w + '{' + str(x) + '}\n' else: command = command + w + '{' + str(x) + '}' self.write(command)
Include a graphic in the document.
Args
x
:str
- The path to the graphic file.
width
:str
- The width of the graphic.
newline
:bool
- Whether to add a newline after the graphic (default: True).
def make_title(self) ‑> None
-
Expand source code
def make_title(self) -> None: """ Add the title, author, and date to the document. """ self.write(self.command('maketitle'))
Add the title, author, and date to the document.
def newpage(self) ‑> None
-
Expand source code
def newpage(self) -> None: """ Add a new page to the document. """ self.write(self.command('newpage'))
Add a new page to the document.
def save_tex(self) ‑> None
-
Expand source code
def save_tex(self) -> None: """ Save the LaTeX document to a temporary .tex file. This method writes the accumulated LaTeX content to a file named 'tempfile.tex' in the current working directory. The file can then be compiled to PDF or edited manually. Note: The file is saved as 'tempfile.tex' and will overwrite any existing file with the same name. """ temp_tex = 'tempfile.tex' f = open(temp_tex, 'w') f.write(self.file.getvalue()) f.close()
Save the LaTeX document to a temporary .tex file.
This method writes the accumulated LaTeX content to a file named 'tempfile.tex' in the current working directory. The file can then be compiled to PDF or edited manually.
Note
The file is saved as 'tempfile.tex' and will overwrite any existing file with the same name.
def section(self, x: str) ‑> None
-
Expand source code
def section(self, x: str) -> None: """ Add a section to the document. Args: x (str): The section title. """ self.write('\\section{'+str(x)+'}\n')
Add a section to the document.
Args
x
:str
- The section title.
def subfigure(self,
*args: str,
centering: bool = True,
position: str = 'h',
caption: str = '',
width: float = 0.5) ‑> None-
Expand source code
def subfigure(self, *args: str, centering: bool = True, position: str = 'h', caption: str = '', width: float = 0.5) -> None: """ Add subfigures to the document. Args: *args: Paths to the subfigure files. centering (bool): Whether to center the subfigures (default: True). position (str): The position specifier (default: 'h'). caption (str): The caption for the subfigures (default: ''). width (float): The width of each subfigure as a fraction of the text width (default: 0.5). """ self.newline = False self.begin('figure', options=['H']) self.tab = 1 self.write(self.command('centering')) for i in range(len(args)): self.tab = 1 self.begin('subfigure', options1=[str(width) + '\\textwidth']) self.tab = 2 if centering: self.write(self.command('centering')) self.includegraphics(args[i], width='1\\linewidth', newline=True) self.newline = False self.tab = 1 self.end('subfigure') self.write(self.command('hfill')) self.tab = 0 if caption != '': self.write(self.command('caption', caption)) self.end('figure') self.newline = True
Add subfigures to the document.
Args
*args
- Paths to the subfigure files.
centering
:bool
- Whether to center the subfigures (default: True).
position
:str
- The position specifier (default: 'h').
caption
:str
- The caption for the subfigures (default: '').
width
:float
- The width of each subfigure as a fraction of the text width (default: 0.5).
def subsection(self, x: str) ‑> None
-
Expand source code
def subsection(self, x: str) -> None: """ Add a subsection to the document. Args: x (str): The subsection title. """ self.write('\\subsection{'+str(x)+'}\n')
Add a subsection to the document.
Args
x
:str
- The subsection title.
def subsubsection(self, x: str) ‑> None
-
Expand source code
def subsubsection(self, x: str) -> None: """ Add a subsubsection to the document. Args: x (str): The subsubsection title. """ self.write('\\subsubsection{'+str(x)+'}\n')
Add a subsubsection to the document.
Args
x
:str
- The subsubsection title.
def table(self,
df: Any,
centering: bool = True,
position: str = 'H',
caption: str = '',
highlight: bool = False) ‑> None-
Expand source code
def table(self, df: Any, centering: bool = True, position: str = 'H', caption: str = '', highlight: bool = False) -> None: """ Add a table to the document. Args: df (pandas.DataFrame): The data to include in the table. centering (bool): Whether to center the table (default: True). position (str): The position specifier (default: 'H'). caption (str): The caption for the table (default: ''). highlight (bool): Whether to highlight specific cells (default: False). """ col_num = len(df.columns) col_format = 'l' + 'c' * (col_num) if highlight: df = df.style.background_gradient(cmap='RdYlGn_r', subset='MAPE (\%)', vmin=0, vmax=100).hide(axis="index") else: df = df.style.hide(axis="index") if caption != '': self.write( df.to_latex(column_format=col_format, caption=caption, position=position, position_float='centering', hrules=True, convert_css=True)) else: self.write(df.to_latex(column_format=col_format, position=position, position_float='centering', hrules=True, convert_css=True))
Add a table to the document.
Args
df
:pandas.DataFrame
- The data to include in the table.
centering
:bool
- Whether to center the table (default: True).
position
:str
- The position specifier (default: 'H').
caption
:str
- The caption for the table (default: '').
highlight
:bool
- Whether to highlight specific cells (default: False).
def title(self, title: str) ‑> None
-
Expand source code
def title(self, title: str) -> None: """ Set the title of the document. Args: title (str): The title text. """ self.write('\\title{'+title+'}\n')
Set the title of the document.
Args
title
:str
- The title text.
def usepakage(self, packages: List[str]) ‑> None
-
Expand source code
def usepakage(self, packages: List[str]) -> None: """ Include LaTeX packages in the document. Args: packages (list): List of LaTeX packages to include. """ up = ['\\usepackage{' + str(p) + '}\n' for p in packages] self.up = ''.join(up)
Include LaTeX packages in the document.
Args
packages
:list
- List of LaTeX packages to include.
def write(self, x: str) ‑> None
-
Expand source code
def write(self, x: str) -> None: """ Write content to the LaTeX document. Args: x (str): The content to write. """ tabs = '\t' * self.tab self.file.write(tabs+x) if self.newline: self.file.write('\n')
Write content to the LaTeX document.
Args
x
:str
- The content to write.