Skip to content

File generatorAuto.py

File List > mkdoxy > generatorAuto.py

Go to the documentation of this file

import logging
import os

from mkdocs.structure import files

from mkdoxy.constants import Kind
from mkdoxy.doxygen import Doxygen
from mkdoxy.generatorBase import GeneratorBase
from mkdoxy.node import Node

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

ADDITIONAL_FILES = {
    "Namespace ListNamespace List": "namespaces.md",
    "Namespace Members": "namespace_members.md",
    "Namespace Member Functions": "namespace_member_functions.md",
    "Namespace Member Variables": "namespace_member_variables.md",
    "Namespace Member Typedefs": "namespace_member_typedefs.md",
    "Namespace Member Enumerations": "namespace_member_enums.md",
    "Class Index": "classes.md",
    "Class Hierarchy": "hierarchy.md",
    "Class Members": "class_members.md",
    "Class Member Functions": "class_member_functions.md",
    "Class Member Variables": "class_member_variables.md",
    "Class Member Typedefs": "class_member_typedefs.md",
    "Class Member Enumerations": "class_member_enums.md",
}


def generate_link(name, url, end="\n") -> str:
    def normalize(name):
        return "\\" + name if name.startswith("__") else name

    return f"- [{normalize(name)}]({url}){end}"


# def generate_link(name, url) -> str:
#   return f"\t\t- '{name}': '{url}'\n"


class GeneratorAuto:
    def __init__(
        self,
        generatorBase: GeneratorBase,
        tempDoxyDir: str,
        siteDir: str,
        apiPath: str,
        doxygen: Doxygen,
        useDirectoryUrls: bool,
    ):
        self.generatorBasegeneratorBase = generatorBase
        self.tempDoxyDirtempDoxyDir = tempDoxyDir
        self.siteDirsiteDir = siteDir
        self.apiPathapiPath = apiPath
        self.doxygendoxygen = doxygen
        self.useDirectoryUrlsuseDirectoryUrls = useDirectoryUrls
        self.fullDocFilesfullDocFiles = []
        self.debugdebug = generatorBase.debug
        os.makedirs(os.path.join(self.tempDoxyDirtempDoxyDir, self.apiPathapiPath), exist_ok=True)

    def save(self, path: str, output: str):
        pathRel = os.path.join(self.apiPathapiPath, path)
        self.fullDocFilesfullDocFiles.append(files.File(pathRel, self.tempDoxyDirtempDoxyDir, self.siteDirsiteDir, self.useDirectoryUrlsuseDirectoryUrls))
        with open(os.path.join(self.tempDoxyDirtempDoxyDir, pathRel), "w", encoding="utf-8") as file:
            file.write(output)

    def fullDoc(self, defaultTemplateConfig: dict):
        self.annotatedannotated(self.doxygendoxygen.root.children, defaultTemplateConfig)
        self.fileindexfileindex(self.doxygendoxygen.files.children, defaultTemplateConfig)
        self.membersmembers(self.doxygendoxygen.root.children, defaultTemplateConfig)
        self.membersmembers(self.doxygendoxygen.groups.children, defaultTemplateConfig)
        self.filesfiles(self.doxygendoxygen.files.children, defaultTemplateConfig)
        self.namespacesnamespaces(self.doxygendoxygen.root.children, defaultTemplateConfig)
        self.classesclasses(self.doxygendoxygen.root.children, defaultTemplateConfig)
        self.hierarchyhierarchy(self.doxygendoxygen.root.children, defaultTemplateConfig)
        self.modulesmodules(self.doxygendoxygen.groups.children, defaultTemplateConfig)
        self.pagespages(self.doxygendoxygen.pages.children, defaultTemplateConfig)
        # self.examples(self.doxygen.examples.children) # TODO examples
        self.relatedpagesrelatedpages(self.doxygendoxygen.pages.children)
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.FUNCTION, Kind.VARIABLE, Kind.TYPEDEF, Kind.ENUM],
            [Kind.CLASS, Kind.STRUCT, Kind.INTERFACE],
            "Class Members",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.FUNCTION],
            [Kind.CLASS, Kind.STRUCT, Kind.INTERFACE],
            "Class Member Functions",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.VARIABLE],
            [Kind.CLASS, Kind.STRUCT, Kind.INTERFACE],
            "Class Member Variables",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.TYPEDEF],
            [Kind.CLASS, Kind.STRUCT, Kind.INTERFACE],
            "Class Member Typedefs",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.ENUM],
            [Kind.CLASS, Kind.STRUCT, Kind.INTERFACE],
            "Class Member Enums",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.FUNCTION, Kind.VARIABLE, Kind.TYPEDEF, Kind.ENUM],
            [Kind.NAMESPACE],
            "Namespace Members",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.FUNCTION],
            [Kind.NAMESPACE],
            "Namespace Member Functions",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.VARIABLE],
            [Kind.NAMESPACE],
            "Namespace Member Variables",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.TYPEDEF],
            [Kind.NAMESPACE],
            "Namespace Member Typedefs",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.root.children,
            [Kind.ENUM],
            [Kind.NAMESPACE],
            "Namespace Member Enums",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.files.children,
            [Kind.FUNCTION],
            [Kind.FILE],
            "Functions",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.files.children,
            [Kind.DEFINE],
            [Kind.FILE],
            "Macros",
            defaultTemplateConfig,
        )
        self.indexindex(
            self.doxygendoxygen.files.children,
            [Kind.VARIABLE, Kind.UNION, Kind.TYPEDEF, Kind.ENUM],
            [Kind.FILE],
            "Variables",
            defaultTemplateConfig,
        )

    def annotated(self, nodes: [Node], config: dict = None):
        path = "annotated.md"
        output = self.generatorBasegeneratorBase.annotated(nodes, config)
        self.savesave(path, output)

    def programlisting(self, node: [Node], config: dict = None):
        path = f"{node.refid}_source.md"

        output = self.generatorBasegeneratorBase.programlisting(node, config)
        self.savesave(path, output)

    def fileindex(self, nodes: [Node], config: dict = None):
        path = "files.md"

        output = self.generatorBasegeneratorBase.fileindex(nodes, config)
        self.savesave(path, output)

    def namespaces(self, nodes: [Node], config: dict = None):
        path = "namespaces.md"

        output = self.generatorBasegeneratorBase.namespaces(nodes, config)
        self.savesave(path, output)

    def page(self, node: Node, config: dict = None):
        path = f"{node.name}.md"

        output = self.generatorBasegeneratorBase.page(node, config)
        self.savesave(path, output)

    def pages(self, nodes: [Node], config: dict = None):
        for node in nodes:
            self.pagepage(node, config)

    def relatedpages(self, nodes: [Node], config: dict = None):
        path = "pages.md"

        output = self.generatorBasegeneratorBase.relatedpages(nodes)
        self.savesave(path, output)

    def example(self, node: Node, config: dict = None):
        path = f"{node.refid}.md"

        output = self.generatorBasegeneratorBase.example(node, config)
        self.savesave(path, output)

    def examples(self, nodes: [Node], config: dict = None):
        for node in nodes:
            if node.is_example:
                if node.has_programlisting:
                    print(f"Generating example {node.name}...")
                self.exampleexample(node, config)

        path = "examples.md"

        output = self.generatorBasegeneratorBase.examples(nodes, config)
        self.savesave(path, output)

    def classes(self, nodes: [Node], config: dict = None):
        path = "classes.md"

        output = self.generatorBasegeneratorBase.classes(nodes, config)
        self.savesave(path, output)

    def modules(self, nodes: [Node], config: dict = None):
        path = "modules.md"

        output = self.generatorBasegeneratorBase.modules(nodes, config)
        self.savesave(path, output)

    def hierarchy(self, nodes: [Node], config: dict = None):
        path = "hierarchy.md"

        output = self.generatorBasegeneratorBase.hierarchy(nodes, config)
        self.savesave(path, output)

    def member(self, node: Node, config: dict = None):
        path = node.filename

        output = self.generatorBasegeneratorBase.member(node, config)
        self.savesave(path, output)

        if node.is_language or node.is_group or node.is_file or node.is_dir:
            self.membersmembers(node.children, config)

    def file(self, node: Node, config: dict = None):
        path = node.filename

        output = self.generatorBasegeneratorBase.file(node, config)
        self.savesave(path, output)

        if node.is_file and node.has_programlisting:
            self.programlistingprogramlisting(node, config)

        if node.is_file or node.is_dir:
            self.filesfiles(node.children, config)

    def members(self, nodes: [Node], config: dict = None):
        for node in nodes:
            if node.is_parent or node.is_group or node.is_file or node.is_dir:
                self.membermember(node, config)

    def files(self, nodes: [Node], config: dict = None):
        for node in nodes:
            if node.is_file or node.is_dir:
                self.filefile(node, config)

    def index(
        self,
        nodes: [Node],
        kind_filters: Kind,
        kind_parents: [Kind],
        title: str,
        config: dict = None,
    ):
        path = title.lower().replace(" ", "_") + ".md"

        output = self.generatorBasegeneratorBase.index(nodes, kind_filters, kind_parents, title, config)
        self.savesave(path, output)

    def _generate_recursive(self, output_summary: str, node: Node, level: int):
        if node.kind.is_parent():
            output_summary += str(" " * level + generate_link(f"{node.kind.value} {node.name}", f"{node.refid}.md"))
            for child in node.children:
                self._generate_recursive_generate_recursive(output_summary, child, level + 2)

    def _generate_recursive_files(self, output_summary: str, node: Node, level: int, config: dict = None):
        if config is None:
            config = []
        if node.kind.is_file() or node.kind.is_dir():
            output_summary += str(" " * int(level + 2) + generate_link(node.name, f"{node.refid}.md", end=""))

            if node.kind.is_file():
                output_summary += f" [[source code]]({node.refid}_source.md) \n"
            else:
                output_summary += "\n"

            for child in node.children:
                self._generate_recursive_files_generate_recursive_files(output_summary, child, level + 2, config)

    def _generate_recursive_examples(self, output_summary: str, node: Node, level: int):
        if node.kind.is_example():
            output_summary += str(" " * level + generate_link(node.name, f"{node.refid}.md"))
            for child in node.children:
                self._generate_recursive_examples_generate_recursive_examples(output_summary, child, level + 2)

    def _generate_recursive_groups(self, output_summary: str, node: Node, level: int):
        if node.kind.is_group():
            output_summary += str(" " * level + generate_link(node.title, f"{node.refid}.md"))
            for child in node.children:
                self._generate_recursive_groups_generate_recursive_groups(output_summary, child, level + 2)

    def _generate_recursive_pages(self, output_summary: str, node: Node, level: int):
        if node.kind.is_page():
            output_summary += str(" " * level + generate_link(node.title, f"{node.refid}.md"))
            for child in node.children:
                self._generate_recursive_pages_generate_recursive_pages(output_summary, child, level + 2)

    def summary(self, defaultTemplateConfig: dict):
        offset = 0
        output_summary = "" + str(" " * (offset + 2) + generate_link("Related Pages", "pages.md"))
        for node in self.doxygendoxygen.pages.children:
            self._generate_recursive_pages_generate_recursive_pages(output_summary, node, offset + 4)

        output_summary += str(" " * (offset + 2) + generate_link("Modules", "modules.md"))
        for node in self.doxygendoxygen.groups.children:
            self._generate_recursive_groups_generate_recursive_groups(output_summary, node, offset + 4)

        output_summary += str(" " * (offset + 2) + generate_link("Class List", "annotated.md"))
        for node in self.doxygendoxygen.root.children:
            self._generate_recursive_generate_recursive(output_summary, node, offset + 4)

        for key, val in ADDITIONAL_FILES.items():
            output_summary += str(" " * (offset + 2) + generate_link(key, val))

        output_summary += str(" " * (offset + 2) + generate_link("Files", "files.md", end="\n"))
        for node in self.doxygendoxygen.files.children:
            self._generate_recursive_files_generate_recursive_files(output_summary, node, offset + 4, defaultTemplateConfig)

        # output_summary += str(' ' * (offset + 2) + generate_link('Examples', 'examples.md'))
        # for node in self.doxygen.examples.children:
        #   self._generate_recursive_examples(node, offset + 4)

        output_summary += str(" " * (offset + 2) + generate_link("File Variables", "variables.md"))
        output_summary += str(" " * (offset + 2) + generate_link("File Functions", "functions.md"))
        output_summary += str(" " * (offset + 2) + generate_link("File Macros", "macros.md"))

        self.savesave("links.md", output_summary)