CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-breathe

Sphinx extension that beautifully integrates Doxygen-generated documentation into Sphinx-based documentation systems

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

parsers.mddocs/

Parser System

Breathe's parser system processes Doxygen's XML output format, providing cached access to parsed XML data with comprehensive error handling. The system handles both index files (project overview) and compound files (detailed element documentation).

Capabilities

DoxygenParserFactory Class

Factory for creating XML parsers with shared caching to improve performance across multiple parsing operations.

class DoxygenParserFactory:
    def __init__(self, app: Sphinx):
        """
        Initialize parser factory with Sphinx application.
        
        Args:
            app: Sphinx application instance
        """
    
    def create_index_parser(self) -> DoxygenIndexParser:
        """
        Create parser for Doxygen index.xml files.
        
        Returns:
            DoxygenIndexParser instance with shared cache
        """
    
    def create_compound_parser(self, project_info: ProjectInfo) -> DoxygenCompoundParser:
        """
        Create parser for Doxygen compound XML files.
        
        Args:
            project_info: Project configuration for XML location
            
        Returns:
            DoxygenCompoundParser instance for the specified project
        """

DoxygenIndexParser Class

Parses Doxygen's index.xml files which contain the project-wide overview and references to all documented elements.

class DoxygenIndexParser(Parser):
    def parse(self, project_info: ProjectInfo):
        """
        Parse the index.xml file for a project.
        
        Handles caching and file state tracking. The index.xml file contains
        the master list of all documented compounds (classes, files, etc.)
        with their reference IDs.
        
        Args:
            project_info: Project configuration specifying XML location
            
        Returns:
            Parsed index data structure
            
        Raises:
            ParserError: If XML parsing fails
            FileIOError: If file cannot be read
        """

DoxygenCompoundParser Class

Parses individual compound XML files containing detailed documentation for specific elements (classes, files, namespaces, etc.).

class DoxygenCompoundParser(Parser):
    def __init__(self, app: Sphinx, cache: dict, project_info: ProjectInfo):
        """
        Initialize compound parser for specific project.
        
        Args:
            app: Sphinx application instance
            cache: Shared parser cache
            project_info: Project configuration for XML location
        """
    
    def parse(self, refid: str):
        """
        Parse a compound XML file by reference ID.
        
        Compound files contain detailed documentation for specific elements
        like classes, files, namespaces, etc. Each compound has a unique
        reference ID used as the filename (e.g., "classMyClass.xml").
        
        Args:
            refid: Reference ID of the compound to parse
            
        Returns:
            Parsed compound data structure
            
        Raises:
            ParserError: If XML parsing fails
            FileIOError: If file cannot be read
        """

Base Parser Class

Common functionality shared by all parser types.

class Parser:
    def __init__(self, app: Sphinx, cache: dict):
        """
        Initialize base parser functionality.
        
        Args:
            app: Sphinx application instance  
            cache: Shared cache for parsed results
        """

Exception Classes

Comprehensive error handling for XML parsing operations.

class ParserError(Exception):
    def __init__(self, error: Exception, filename: Path):
        """
        XML parsing error with file context.
        
        Args:
            error: Underlying parsing exception
            filename: Path to file that failed to parse
        """
    
    def __str__(self) -> str:
        """Return string representation including filename and error."""
    
    @property
    def error(self) -> Exception:
        """Get the underlying parsing error."""
    
    @property  
    def filename(self) -> Path:
        """Get the path to file that failed to parse."""

class FileIOError(Exception):
    def __init__(self, error: Exception, filename: Path):
        """
        File I/O error with file context.
        
        Args:
            error: Underlying I/O exception
            filename: Path to file that couldn't be accessed
        """
    
    def __str__(self) -> str:
        """Return string representation including filename and error."""
    
    @property
    def error(self) -> Exception:
        """Get the underlying I/O error."""
    
    @property
    def filename(self) -> Path:
        """Get the path to file that couldn't be accessed."""

XML File Structure

The parser system works with Doxygen's standard XML output structure:

Index File (index.xml)

Contains project overview and compound references:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygenindex>
  <compound refid="classMyClass" kind="class">
    <name>MyClass</name>
    <member refid="classMyClass_1a123" kind="function">
      <name>myMethod</name>
    </member>
  </compound>
  <compound refid="namespaceMyNamespace" kind="namespace">
    <name>MyNamespace</name>
  </compound>
</doxygenindex>

Compound Files (e.g., classMyClass.xml)

Contain detailed documentation for specific elements:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen>
  <compounddef id="classMyClass" kind="class">
    <name>MyClass</name>
    <briefdescription>Brief description of MyClass</briefdescription>
    <detaileddescription>Detailed description...</detaileddescription>
    <sectiondef kind="public-func">
      <memberdef kind="function" id="classMyClass_1a123">
        <name>myMethod</name>
        <type>void</type>
        <definition>void MyClass::myMethod</definition>
      </memberdef>
    </sectiondef>
  </compounddef>
</doxygen>

Caching System

The parser system implements intelligent caching to improve performance:

File State Tracking

  • Monitors XML file modification times
  • Invalidates cache when files change
  • Automatically re-parses updated files

Shared Cache

  • Single cache shared across all parser instances
  • Keyed by absolute file path
  • Stores parsed data structures, not raw XML

Cache Integration

# Cache is automatically managed
factory = DoxygenParserFactory(app)
parser = factory.create_index_parser()

# First parse - loads and caches
result1 = parser.parse(project_info)

# Second parse - returns cached result
result2 = parser.parse(project_info)  # Fast cached access

# If XML file changes, cache is invalidated automatically

Usage Examples

Basic Parsing Setup

from breathe.parser import DoxygenParserFactory
from breathe.project import ProjectInfo

# Create factory
factory = DoxygenParserFactory(app)

# Parse project index
index_parser = factory.create_index_parser()
index_data = index_parser.parse(project_info)

# Parse specific compound
compound_parser = factory.create_compound_parser(project_info)
class_data = compound_parser.parse("classMyClass")

Error Handling

from breathe.parser import ParserError, FileIOError

try:
    index_data = index_parser.parse(project_info)
except ParserError as e:
    print(f"XML parsing failed: {e.error}")
    print(f"File: {e.filename}")
except FileIOError as e:
    print(f"File I/O error: {e.error}")
    print(f"File: {e.filename}")

Integration with Directives

# In directive implementation
try:
    parser = self.parser_factory.create_compound_parser(project_info)
    compound_data = parser.parse(refid)
    # Process parsed data...
except ParserError as e:
    return format_parser_error(
        self.name, e.error, e.filename, self.state, self.lineno, True
    )

Custom Parser Usage

# Access parser factory from directive
factory = self.env.temp_data["breathe_parser_factory"]

# Create parsers as needed
index_parser = factory.create_index_parser()
compound_parser = factory.create_compound_parser(project_info)

# Parse XML data
index_data = index_parser.parse(project_info)
for compound in index_data.compounds:
    compound_data = compound_parser.parse(compound.refid)
    # Process compound data...

Generated Parser Modules

The parser system includes generated modules for XML schema handling:

breathe.parser.index

  • Generated parser for index.xml schema
  • Handles project-wide compound listings
  • Provides structured access to compound references

breathe.parser.compound

  • Generated parser for compound XML schema
  • Handles detailed element documentation
  • Supports all Doxygen compound types (class, file, namespace, etc.)

breathe.parser.indexsuper

  • Base classes for index parsing
  • Common functionality for index operations

breathe.parser.compoundsuper

  • Base classes for compound parsing
  • Common functionality for compound operations

Performance Considerations

Caching Strategy

  • Parse results cached by absolute file path
  • File modification time tracking prevents stale data
  • Shared cache across all parser instances reduces memory usage

Lazy Loading

  • XML files only parsed when specifically requested
  • Compound files parsed on-demand, not in bulk
  • Index parsed once per project, compounds as needed

Memory Management

  • Cache stores parsed data structures, not raw XML
  • Automatic cache invalidation prevents memory leaks
  • Shared cache reduces duplicate parsed data

Optimization Tips

  • Use same ProjectInfoFactory across directives
  • Let caching handle repeated access to same files
  • Monitor XML file sizes - very large files may impact performance

Install with Tessl CLI

npx tessl i tessl/pypi-breathe

docs

cli.md

directives.md

index.md

parsers.md

project-management.md

tile.json