""" Input parser factory for auto-detecting and creating appropriate parsers. This module provides centralized parser creation with auto-detection support for determining the most appropriate parser based on input source. """ import os from typing import Union, List from ..core.interfaces import Parser class InputParserFactory: """ Factory for creating input parsers based on source content. This factory provides centralized parser creation with support for: - Auto-detection based on file extension or content - Explicit parser selection by type - Clear error messages for unsupported formats """ @staticmethod def create_parser(source: str, parser_type: Union[str, None] = None) -> Parser: """ Create an appropriate parser for the input source. Args: source: Input source (file path or content string) parser_type: Optional explicit parser type ("docx", "omml", "mathml", or None for auto-detection) Returns: Parser instance appropriate for the source Raises: ValueError: If input format cannot be determined or is unsupported Examples: >>> factory = InputParserFactory() >>> parser = factory.create_parser("equations.docx") >>> isinstance(parser, DocxParser) True >>> parser = factory.create_parser("x") >>> isinstance(parser, MathMLParser) True >>> parser = factory.create_parser(xml_content, parser_type="omml") >>> isinstance(parser, OmmlParser) True """ # Import here to avoid circular dependencies from .docx_parser import DocxParser from .omml_parser import OmmlParser from .mathml_parser import MathMLParser # Explicit parser type specified if parser_type: parser_type = parser_type.lower() if parser_type == "docx": return DocxParser() elif parser_type == "omml": return OmmlParser() elif parser_type == "mathml": return MathMLParser() else: raise ValueError(f"Unknown parser type: {parser_type}") # Auto-detection based on source # Check file extension first (most common case) if source.endswith('.docx') or (os.path.exists(source) and source.lower().endswith('.docx')): return DocxParser() # Check content for XML markers # Strip whitespace for reliable detection content_start = source.strip()[:200] # Check first 200 chars # Check for OMML namespace if ' str: """ Detect the parser type needed for the input source. Args: source: Input source (file path or content string) Returns: Parser type string ("docx", "omml", or "mathml") Raises: ValueError: If input format cannot be determined Examples: >>> factory = InputParserFactory() >>> factory.detect_parser_type("equations.docx") 'docx' >>> factory.detect_parser_type("x") 'mathml' """ parser = InputParserFactory.create_parser(source) return parser.parser_type @staticmethod def get_supported_formats() -> List[str]: """ Get list of supported input formats. Returns: List of format identifiers that can be parsed """ return ["docx", "omml", "mathml"] def __repr__(self) -> str: """String representation for debugging.""" return "InputParserFactory(docx, omml, mathml)"