""" Output formatting for conversion results. This module provides functions to format conversion results in various output formats including LaTeX, JSON, and HTML with MathJax rendering. """ import json from typing import List from .result import ConversionResult from ..utils.text_processing import write_text def format_latex(results: List[ConversionResult], format_type: str = "display", delimiter: str = "dollar") -> str: """Format LaTeX results for output. Args: results: List of conversion results format_type: 'inline', 'display', or 'both' (auto-detect) delimiter: 'dollar', 'bracket', 'mathjax', or 'katex' Returns: Formatted LaTeX string with appropriate delimiters Example: >>> results = [ConversionResult()] >>> results[0].success = True >>> results[0].latex = 'x + y' >>> results[0].display_mode = False >>> output = format_latex(results, 'both', 'dollar') >>> print(output) '$x + y$' """ if delimiter == "dollar": inline_start, inline_end = "$", "$" display_start, display_end = "$$", "$$" elif delimiter == "bracket": inline_start, inline_end = "\\(", "\\)" display_start, display_end = "\\[", "\\]" elif delimiter == "mathjax": inline_start, inline_end = "\\(", "\\)" display_start, display_end = "$$", "$$" elif delimiter == "katex": inline_start, inline_end = "$", "$" display_start, display_end = "$$", "$$" else: inline_start, inline_end = "$", "$" display_start, display_end = "$$", "$$" output_lines = [] for i, result in enumerate(results): if not result.success: output_lines.append(f"% Equation {i+1}: ERROR - {result.error}") continue # Determine if equation should be inline or display if hasattr(result, 'display_mode') and format_type == "both": # Use the detected display mode from OMML structure if result.display_mode: equation = f"{display_start}{result.latex}{display_end}" else: equation = f"{inline_start}{result.latex}{inline_end}" elif format_type == "inline": equation = f"{inline_start}{result.latex}{inline_end}" elif format_type == "display": equation = f"{display_start}{result.latex}{display_end}" else: # format_type == "both" but no display_mode set # Use heuristic: short equations inline, complex ones display if len(result.latex) < 50 and not any(cmd in result.latex for cmd in ["\\frac", "\\sum", "\\int", "\\begin"]): equation = f"{inline_start}{result.latex}{inline_end}" else: equation = f"{display_start}{result.latex}{display_end}" output_lines.append(equation) output_lines.append("") # Empty line between equations return "\n".join(output_lines) def save_results(results: List[ConversionResult], output_path: str, format_type: str = "display", delimiter: str = "dollar", include_context: bool = False, output_format: str = None): """Save conversion results in various formats. Args: results: List of conversion results output_path: Output file path format_type: For LaTeX output - 'inline', 'display', or 'both' delimiter: For LaTeX output - delimiter style include_context: Whether to include context in JSON output output_format: 'latex', 'json', or 'html' (auto-detected from output_path if not provided) Example: >>> results = [ConversionResult()] >>> save_results(results, 'output.json') >>> save_results(results, 'output.tex', format_type='inline', delimiter='dollar') """ # Auto-detect output format from file extension if not provided if output_format is None: if output_path.endswith('.json'): output_format = 'json' elif output_path.endswith('.html'): output_format = 'html' else: # Default to LaTeX for .tex, .md, and any other extension output_format = 'latex' if output_format == "latex": latex_content = format_latex(results, format_type, delimiter) write_text(output_path, latex_content) elif output_format == "json": json_data = { "metadata": { "total_equations": len(results), "successful_conversions": sum(1 for r in results if r.success), "failed_conversions": sum(1 for r in results if not r.success), "format_type": format_type, "delimiter": delimiter, "include_context": include_context }, "equations": [result.to_dict() for result in results] } with open(output_path, 'w', encoding='utf-8') as f: json.dump(json_data, f, indent=2, ensure_ascii=False) elif output_format == "html": html_content = generate_html_preview(results, format_type, delimiter) write_text(output_path, html_content) def generate_html_preview(results: List[ConversionResult], format_type: str, delimiter: str) -> str: """Generate HTML preview with MathJax rendering. Args: results: List of conversion results format_type: 'inline', 'display', or 'both' delimiter: Delimiter style Returns: HTML document string with embedded MathJax Example: >>> results = [ConversionResult()] >>> html = generate_html_preview(results, 'display', 'dollar') >>> '' in html True """ html_template = """
Total equations: {total}
Successful: {successful}
Failed: {failed}
Success rate: {rate:.1f}%