from breathe.finder.factory import FinderFactory from breathe.parser import DoxygenParserFactory from breathe.parser import FileIOError, ParserError from breathe.project import ProjectInfoFactory, ProjectInfo from breathe.renderer import format_parser_error, RenderContext from breathe.renderer.filter import Filter, FilterFactory from breathe.renderer.mask import MaskFactoryBase from breathe.renderer.sphinxrenderer import SphinxRenderer from breathe.renderer.target import TargetHandler from sphinx.directives import SphinxDirective from docutils import nodes from typing import Any, Dict, List, Optional, Sequence class _WarningHandler: def __init__(self, state, context: Dict[str, Any]) -> None: self.state = state self.context = context def warn( self, raw_text: str, *, rendered_nodes: Optional[Sequence[nodes.Node]] = None, unformatted_suffix: str = "" ) -> List[nodes.Node]: raw_text = self.format(raw_text) + unformatted_suffix if rendered_nodes is None: rendered_nodes = [nodes.paragraph("", "", nodes.Text(raw_text))] return [ nodes.warning("", *rendered_nodes), self.state.document.reporter.warning(raw_text, line=self.context["lineno"]), ] def format(self, text: str) -> str: return text.format(**self.context) class BaseDirective(SphinxDirective): @property def directive_args(self) -> list: # the order must be the same as in docutils.parsers.rst.Directive.__init__ return [ self.name, self.arguments, self.options, self.content, self.lineno, self.content_offset, self.block_text, self.state, self.state_machine, ] @property def project_info_factory(self) -> ProjectInfoFactory: return self.env.temp_data["breathe_project_info_factory"] @property def parser_factory(self) -> DoxygenParserFactory: return self.env.temp_data["breathe_parser_factory"] @property def finder_factory(self) -> FinderFactory: return FinderFactory(self.env.app, self.parser_factory) @property def filter_factory(self) -> FilterFactory: return FilterFactory(self.env.app) @property def kind(self) -> str: raise NotImplementedError def create_warning(self, project_info: Optional[ProjectInfo], **kwargs) -> _WarningHandler: if project_info: tail = 'in doxygen xml output for project "{project}" from directory: {path}'.format( project=project_info.name(), path=project_info.project_path() ) else: tail = "" context = dict(lineno=self.lineno, tail=tail, **kwargs) return _WarningHandler(self.state, context) def render( self, node_stack, project_info: ProjectInfo, filter_: Filter, target_handler: TargetHandler, mask_factory: MaskFactoryBase, directive_args, ) -> List[nodes.Node]: "Standard render process used by subclasses" try: object_renderer = SphinxRenderer( self.parser_factory.app, project_info, node_stack, self.state, self.state.document, target_handler, self.parser_factory.create_compound_parser(project_info), filter_, ) except ParserError as e: return format_parser_error( "doxygenclass", e.error, e.filename, self.state, self.lineno, True ) except FileIOError as e: return format_parser_error( "doxygenclass", e.error, e.filename, self.state, self.lineno, True ) context = RenderContext(node_stack, mask_factory, directive_args) return object_renderer.render(node_stack[0], context)