diff --git a/doc/mkdocstrings_handlers/cxx/__init__.py b/doc/mkdocstrings_handlers/cxx/__init__.py new file mode 100644 index 00000000..36d84a2e --- /dev/null +++ b/doc/mkdocstrings_handlers/cxx/__init__.py @@ -0,0 +1,107 @@ +# A basic mkdocstrings handler for C++. +# Copyright (c) 2012 - present, Victor Zverovich + +import os +import xml.etree.ElementTree as et +from mkdocstrings.handlers.base import BaseHandler +from typing import Any, Mapping, Optional +from subprocess import CalledProcessError, PIPE, Popen, STDOUT + +class Definition: + pass + +class CxxHandler(BaseHandler): + def __init__(self, **kwargs: Any) -> None: + super().__init__(handler='cxx', **kwargs) + + # Run doxygen. + cmd = ['doxygen', '-'] + doc_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + include_dir = os.path.join(os.path.dirname(doc_dir), 'include', 'fmt') + doxyxml_dir = 'doxyxml' + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT) + out, _ = p.communicate(input=r''' + PROJECT_NAME = fmt + GENERATE_LATEX = NO + GENERATE_MAN = NO + GENERATE_RTF = NO + CASE_SENSE_NAMES = NO + INPUT = {0}/args.h {0}/base.h {0}/chrono.h {0}/color.h \ + {0}/core.h {0}/compile.h {0}/format.h {0}/os.h \ + {0}/ostream.h {0}/printf.h {0}/ranges.h {0}/xchar.h + QUIET = YES + JAVADOC_AUTOBRIEF = YES + AUTOLINK_SUPPORT = NO + GENERATE_HTML = NO + GENERATE_XML = YES + XML_OUTPUT = {1} + ALIASES = "rst=\verbatim embed:rst" + ALIASES += "endrst=\endverbatim" + MACRO_EXPANSION = YES + PREDEFINED = _WIN32=1 \ + __linux__=1 \ + FMT_ENABLE_IF(...)= \ + FMT_USE_VARIADIC_TEMPLATES=1 \ + FMT_USE_RVALUE_REFERENCES=1 \ + FMT_USE_USER_DEFINED_LITERALS=1 \ + FMT_USE_ALIAS_TEMPLATES=1 \ + FMT_USE_NONTYPE_TEMPLATE_ARGS=1 \ + FMT_API= \ + "FMT_BEGIN_NAMESPACE=namespace fmt {{" \ + "FMT_END_NAMESPACE=}}" \ + "FMT_STRING_ALIAS=1" \ + "FMT_VARIADIC(...)=" \ + "FMT_VARIADIC_W(...)=" \ + "FMT_DOC=1" + EXCLUDE_SYMBOLS = fmt::formatter fmt::printf_formatter fmt::arg_join \ + fmt::basic_format_arg::handle + '''.format(include_dir, doxyxml_dir).encode('utf-8')) + if p.returncode != 0: + raise CalledProcessError(p.returncode, cmd) + + # Load XML. + with open(os.path.join(doxyxml_dir, 'namespacefmt.xml')) as f: + self._doxyxml = et.parse(f) + + def collect(self, identifier: str, + config: Mapping[str, Any]) -> list[Definition]: + paren = identifier.find('(') + args = None + if paren > 0: + identifier, args = identifier[:paren], identifier[paren:] + + nodes = self._doxyxml.findall( + f"./compounddef/sectiondef/memberdef/name[.='{identifier}']/..") + defs = [] + for n in nodes: + node_args = n.find('argsstring').text + if args != None and args != node_args: + continue + d = Definition() + d.type = n.find('type').text + d.name = identifier + d.args = node_args + desc = n.find('detaileddescription/para/verbatim') + d.desc = desc.text if desc != None else '' + defs.append(d) + return defs + + def render(self, defs: list[Definition], config: dict) -> str: + text = '' + for d in defs: + text += '
'
+      text += d.type + ' ' + d.name + d.args
+      text += '
\n' + text += d.desc + return text + +def get_handler(theme: str, custom_templates: Optional[str] = None, + **config: Any) -> CxxHandler: + '''Return an instance of `CxxHandler`. + + Arguments: + theme: The theme to use when rendering contents. + custom_templates: Directory containing custom templates. + **config: Configuration passed to the handler. + ''' + return CxxHandler(theme=theme, custom_templates=custom_templates) diff --git a/doc/mkdocstrings_handlers/cxx/templates/README b/doc/mkdocstrings_handlers/cxx/templates/README new file mode 100644 index 00000000..7da18db5 --- /dev/null +++ b/doc/mkdocstrings_handlers/cxx/templates/README @@ -0,0 +1 @@ +mkdocsstrings requires a handler to have a templates directory.