admin管理员组

文章数量:1356413

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()
        selfpile_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()

本文标签: pythonHow to create a new line in pylatexStack Overflow