Skip to content

File doxygen.py

File List > mkdoxy > doxygen.py

Go to the documentation of this file

import logging
import os
from xml.etree import ElementTree

from mkdoxy.cache import Cache
from mkdoxy.constants import Kind, Visibility
from mkdoxy.node import Node
from mkdoxy.project import ProjectContext
from mkdoxy.xml_parser import XmlParser

log: logging.Logger = logging.getLogger("mkdocs")


class Doxygen:
    def __init__(self, index_path: str, parser: XmlParser, cache: Cache):
        self.debugdebug = parser.debug
        path_xml = os.path.join(index_path, "index.xml")
        if self.debugdebug:
            log.info(f"Loading XML from: {path_xml}")
        xml = ElementTree.parse(path_xml).getroot()

        self.parserparser = parser
        self.ctxctx = ProjectContext(cache)

        self.rootroot = Node("root", None, self.ctxctx, self.parserparser, None)
        self.groupsgroups = Node("root", None, self.ctxctx, self.parserparser, None)
        self.filesfiles = Node("root", None, self.ctxctx, self.parserparser, None)
        self.pagespages = Node("root", None, self.ctxctx, self.parserparser, None)
        self.examplesexamples = Node("root", None, self.ctxctx, self.parserparser, None)

        for compound in xml.findall("compound"):
            kind = Kind.from_str(compound.get("kind"))
            refid = compound.get("refid")
            if kind.is_language():
                node = Node(
                    os.path.join(index_path, f"{refid}.xml"),
                    None,
                    self.ctxctx,
                    self.parserparser,
                    self.rootroot,
                )
                node._visibility = Visibility.PUBLIC
                self.rootroot.add_child(node)
            if kind == Kind.GROUP:
                node = Node(
                    os.path.join(index_path, f"{refid}.xml"),
                    None,
                    self.ctxctx,
                    self.parserparser,
                    self.rootroot,
                )
                node._visibility = Visibility.PUBLIC
                self.groupsgroups.add_child(node)
            if kind in [Kind.FILE, Kind.DIR]:
                node = Node(
                    os.path.join(index_path, f"{refid}.xml"),
                    None,
                    self.ctxctx,
                    self.parserparser,
                    self.rootroot,
                )
                node._visibility = Visibility.PUBLIC
                self.filesfiles.add_child(node)
            if kind == Kind.PAGE:
                node = Node(
                    os.path.join(index_path, f"{refid}.xml"),
                    None,
                    self.ctxctx,
                    self.parserparser,
                    self.rootroot,
                )
                node._visibility = Visibility.PUBLIC
                self.pagespages.add_child(node)
            if kind == Kind.EXAMPLE:
                node = Node(
                    os.path.join(index_path, f"{refid}.xml"),
                    None,
                    self.ctxctx,
                    self.parserparser,
                    self.rootroot,
                )
                node._visibility = Visibility.PUBLIC
                self.examplesexamples.add_child(node)

        if self.debugdebug:
            log.info("Deduplicating data... (may take a minute!)")
        for child in self.rootroot.children.copy():
            self._fix_duplicates_fix_duplicates(child, self.rootroot, [])

        for child in self.groupsgroups.children.copy():
            self._fix_duplicates_fix_duplicates(child, self.groupsgroups, [Kind.GROUP])

        for child in self.filesfiles.children.copy():
            self._fix_duplicates_fix_duplicates(child, self.filesfiles, [Kind.FILE, Kind.DIR])

        for child in self.examplesexamples.children.copy():
            self._fix_duplicates_fix_duplicates(child, self.examplesexamples, [Kind.EXAMPLE])

        self._fix_parents_fix_parents(self.filesfiles)

        if self.debugdebug:
            log.info("Sorting...")
        self._recursive_sort_recursive_sort(self.rootroot)
        self._recursive_sort_recursive_sort(self.groupsgroups)
        self._recursive_sort_recursive_sort(self.filesfiles)
        self._recursive_sort_recursive_sort(self.pagespages)
        self._recursive_sort_recursive_sort(self.examplesexamples)

    def _fix_parents(self, node: Node):
        if node.is_dir or node.is_root:
            for child in node.children:
                if child.is_file:
                    child._parent = node
                if child.is_dir:
                    self._fix_parents_fix_parents(child)

    def _recursive_sort(self, node: Node):
        node.sort_children()
        for child in node.children:
            self._recursive_sort_recursive_sort(child)

    def _is_in_root(self, node: Node, root: Node):
        return any(node.refid == child.refid for child in root.children)

    def _remove_from_root(self, refid: str, root: Node):
        for i, child in enumerate(root.children):
            if child.refid == refid:
                root.children.pop(i)
                return

    def _fix_duplicates(self, node: Node, root: Node, filter: [Kind]):
        for child in node.children:
            if len(filter) > 0 and child.kind not in filter:
                continue
            if self._is_in_root_is_in_root(child, root):
                self._remove_from_root_remove_from_root(child.refid, root)
            self._fix_duplicates_fix_duplicates(child, root, filter)

    def printStructure(self):
        if not self.debugdebug:
            return
        print("\n")
        log.info("Print root")
        for node in self.rootroot.children:
            self.print_nodeprint_node(node, "")
        print("\n")

        log.info("Print groups")
        for node in self.groupsgroups.children:
            self.print_nodeprint_node(node, "")
        print("\n")

        log.info("Print files")
        for node in self.filesfiles.children:
            self.print_nodeprint_node(node, "")

    def print_node(self, node: Node, indent: str):
        if self.debugdebug:
            log.info(f"{indent} {node.kind} {node.name}")
        for child in node.children:
            self.print_nodeprint_node(child, f"{indent}  ")