r""" Visitor for (string literal) MathML elements. The element represents a string literal, typically displayed with surrounding quotes. It's used for text that should be treated as a literal string rather than mathematical notation. In LaTeX conversion, ms is converted to \text{} with quotes, similar to mtext. """ from lxml import etree as ET from ..core.interfaces import Visitor, Strategy from ..utils import local_name as _local, text_content as _text_content class MsVisitor(Visitor): r""" Handles (string literal) MathML elements. Converts string literals to LaTeX \text{} with optional quotes. Examples: Simple string: hello → \text{"hello"} String without lquote/rquote attributes: world → \text{world} Custom quotes: text → \text{[text]} Empty string: → \text{""} Note: Default quotes are double quotes (") unless overridden by lquote and rquote attributes. """ def __init__(self, strategy: Strategy): """Initialize the Ms visitor.""" super().__init__(strategy) def visit(self, node: ET.Element) -> str: r""" Convert element to LaTeX \text{} with quotes. Args: node: The element to convert Returns: LaTeX string with \text{...} and quotes Raises: ValueError: If node is not a element """ if not self.can_handle(node): raise ValueError(f"MsVisitor cannot handle element '{node.tag}'") # Get quote attributes (default to double quotes) lquote = node.get("lquote", '"') rquote = node.get("rquote", '"') # Get text content content = _text_content(node) # Wrap in \text{} with quotes return f"\\text{{{lquote}{content}{rquote}}}" def can_handle(self, node: ET.Element) -> bool: """Check if this visitor can handle the given node.""" return _local(node.tag) == 'ms' @property def element_name(self) -> str: """Get the element name this visitor handles.""" return 'ms' def __repr__(self) -> str: """String representation for debugging.""" return f"MsVisitor(strategy={self.strategy.name})"