I am having issues with my pylatex code could anyone give guidance. Its not test wrapping( I would prefer if a new line is created as well) and and Im having issues handing the # sign in the code. Currently the output looks like a straight line that runs out of the table dimensions. every # is seen as /#. My code is: import json import subprocess from datetime import datetime from pylatex import Document, Section, Subsection, Command, Tabular, NewPage, Itemize, Tabularx from pylatex.utils import NoEscape, bold class ReportGenerator: def __init__(self, json_path, output_name): self.json_path = json_path self.output_name = output_name self.doc = Document(output_name) self.load_data() self.add_preamble() def load_data(self): with open(self.json_path, "r") as f: self.data = json.load(f) def add_preamble(self): """Configure document preamble and styling""" self.doc.preamble.append(Command('usepackage', 'textcomp')) self.doc.preamble.append(Command('usepackage', 'lastpage')) self.doc.preamble.append(NoEscape(r'\usepackage{makecell}')) self.doc.preamble.append(NoEscape(r'\usepackage{parskip}')) self.doc.preamble.append(NoEscape(r'\usepackage{xcolor}')) self.doc.preamble.append(NoEscape(r'\usepackage{tabularx}')) self.doc.preamble.append(NoEscape(r'\setlength{\parindent}{0pt}')) self.doc.preamble.append(NoEscape(r'\setlength{\parskip}{1em}')) self.doc.preamble.append(Command('title', 'Test Report')) self.doc.preamble.append(Command('author', 'Automated Test System')) self.doc.preamble.append(Command('date', datetime.now().strftime("%Y-%m-%d"))) self.doc.append(NoEscape(r'\maketitle')) def sanitize_text(self, text): """Escape special LaTeX characters""" replacements = { '#': r'\#', '_': r'\_', '%': r'\%', '{': r'\{', '}': r'\}', '[': r'\[', ']': r'\]', '@': r'\@', '&': r'\&', '~': r'\textasciitilde{}', '^': r'\textasciicircum{}', '\\': r'\textbackslash{}' } return ''.join([replacements.get(c, c) for c in str(text)]) def format_measurement(self, value): """Format measurement values with units""" if isinstance(value, dict): if 'Units' in value: return f"{value['Measurement']} {self.sanitize_text(value['Units'])}" return ', '.join([f"{self.sanitize_text(k)}: {self.sanitize_text(v)}" for k, v in value.items()]) return self.sanitize_text(value) def create_test_table(self, data, section_name): """Create a table for test results with nested measurements""" with self.doc.create(Section(self.sanitize_text(section_name))): content = self.data[section_name] headers=('Property', 'Value') if section_name in ["Introduction", "Conclusion"]: if isinstance(content, dict): # Convert dict to formatted text text_content = '\n\n'.join([f"{bold(k)}: {v}" for k, v in content.items()]) self.doc.append(NoEscape(text_content)) else: self.doc.append(NoEscape(content.replace('\n', '\par\n'))) elif section_name == "Result": for test_name, test_data in content.items(): with self.doc.create(Subsection(test_name)): with self.doc.create(Tabular('|l|l|')) as table: table.add_hline() table.add_row([bold(headers[0]), bold(headers[1])]) table.add_hline() for key, value in data.items(): formatted_value = str(value).replace('\n', r' \\ ') table.add_row([key, NoEscape(r'\makecell[l]{' + formatted_value + '}')]) table.add_hline() else: with self.doc.create(Tabular('|l|l|')) as table: table.add_hline() table.add_row([bold('Parameter'), bold('Value')]) table.add_hline() for param, value in data.items(): if param == 'Pass/Fail': continue safe_param = self.sanitize_text(param) formatted_value = self.format_measurement(value) # Handle special cases for complex parameters if '[N]' in param: formatted_value = formatted_value.replace('(', r'\(').replace(')', r'\)') table.add_row([safe_param, NoEscape(r'\makecell[l]{' + formatted_value + '}')]) table.add_hline() if 'Pass/Fail' in data: pf_value = data['Pass/Fail'] color = r'\textcolor{green}{Pass}' if pf_value == 'Pass' else r'\textcolor{red}{Fail}' table.add_row([bold('Pass/Fail'), NoEscape(color)]) table.add_hline() def handle_test_info(self): """Special handler for complex Test Info section""" test_info = self.data.get("Test Info", {}) line_delimiter = " • " with self.doc.create(Tabular('|p{4cm}|p{10cm}|')) as table: table.add_hline() table.add_row([bold('Field'), bold('Value')]) table.add_hline() for field, value in test_info.items(): if field == 'Notes': continue # Handle notes separately safe_field = self.sanitize_text(field) if isinstance(value, dict): sub_values = '\n'.join( [f"{self.sanitize_text(k)}: {self.sanitize_text(v)}" for k, v in value.items()] ) table.add_row([safe_field, NoEscape(r'\makecell[l]{' + sub_values + '}')]) else: table.add_row([safe_field, self.sanitize_text(value)]) table.add_hline() # Handle Notes with proper LaTeX list formatting if 'Notes' in test_info: notes = test_info['Notes'] items = '\n'.join([r'\item ' + self.sanitize_text(v) for v in notes.values()]) notes_latex = ( r'\begin{minipage}[t]{0.9\textwidth}' r'\begin{itemize}' + '\n' + items + '\n' + r'\end{itemize}' + r'\end{minipage}' ) table.add_row([bold('Notes'), NoEscape(notes_latex)]) table.add_hline() # Rest of the class remains the same as previous version... def generate_report(self): """Main report generation workflow""" # Add Test Info section self.handle_test_info() self.doc.append(NewPage()) # Add Table of Contents self.doc.append(Command('tableofcontents')) self.doc.append(NewPage()) # Process all test sections test_sections = [k for k in self.data.keys() if k != "Test Info"] for section in test_sections: self.create_test_table(self.data[section], section) # Generate output files self.generate_tex() self.compile_pdf() def generate_tex(self): """Generate LaTeX source file""" try: self.doc.generate_tex(self.output_name) print(f"Generated LaTeX file: {self.output_name}.tex") except Exception as e: print(f"Error generating LaTeX: {str(e)}") def compile_pdf(self): """Compile LaTeX to PDF with multiple runs for TOC""" try: for _ in range(2): # Run twice to generate TOC subprocess.run(['pdflatex', f"{self.output_name}.tex"], check=True) print(f"PDF generated successfully: {self.output_name}.pdf") except subprocess.CalledProcessError as e: print(f"PDF compilation failed: {str(e)}") except FileNotFoundError: print("Error: pdflatex not found. Ensure LaTeX is installed.") if __name__ == "__main__": # Configuration JSON_PATH = r"C:\Users\Ariela\Desktop\draft\test2.json" OUTPUT_NAME = 'test_report2' # Generate report report = ReportGenerator(JSON_PATH, OUTPUT_NAME) report.generate_report() Continue reading...