""" Silique (https://www.silique.fr) Copyright (C) 2024-2026 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ from typing import Union from tiramisu import groups from rougail.utils import get_properties_to_string from .config import OutPuts from .i18n import _ from .collect import Collect from .changelog import Changelog from .example import Examples class RougailOutputDoc(Collect, Examples, Changelog): """Rougail Output Doc: Generate documentation from rougail description files """ output_name = "doc" def __init__( self, config: Union["Config", "SubConfig"], *, rougailconfig: "RougailConfig" = None, true_config: "Config" = None, root_config: "Config" = None, **kwargs, ): # Import here to avoid circular import from rougail.tiramisu import CONVERT_OPTION self.convert_option = CONVERT_OPTION if rougailconfig is None: from rougail import RougailConfig rougailconfig = RougailConfig if rougailconfig["step.output"] != self.output_name: rougailconfig["step.output"] = self.output_name if rougailconfig["step.output"] != self.output_name: raise Exception(_("{0} is not set as step.output").format(self.output_name)) self.config = config if true_config is None: self.true_config = config else: self.true_config = true_config if root_config is None: self.root_config = self.true_config else: self.root_config = root_config self.rougailconfig = rougailconfig self.informations = None self.formatter = None super().__init__() def run(self) -> str: """Print documentation in stdout""" self.load() self.load_formatter() return_string = "" contents = self.rougailconfig["doc.contents"] if "variables" in contents: return_string += self.formatter.run(self.informations) if "example" in contents: return_string += self.gen_doc_examples() if "changelog" in contents: return_string += self.gen_doc_changelog() return True, return_string def load_formatter(self) -> str: output_format = self.rougailconfig["doc.output_format"] self.formatter = self.outputs[output_format]( self.rougailconfig, support_namespace=self.support_namespace, document_a_type=self.document_a_type ) def print(self) -> None: ret, data = self.run() print(data) return ret def load(self): self.document_a_type = self.rougailconfig["doc.document_a_type"] self.modes_level = self.rougailconfig["modes_level"] self.disabled_modes = [] if self.modes_level: for mode in self.modes_level: for prop in self.true_config.property.get(): if mode != prop: continue self.disabled_modes.append(prop) try: groups.namespace self.support_namespace = True except AttributeError: self.support_namespace = False self.property_to_string = get_properties_to_string() self.outputs = OutPuts().get() self.dynamic_paths = {} if self.config.isoptiondescription(): informations = self.collect_families(self.config.unrestraint) # from pprint import pprint # pprint(informations) else: informations = {} self.collect_variable(self.config, informations) if informations is None: informations = {} if self.true_config != self.config: # build cache for dyn family root_informations = {} infos = root_informations family = self.root_config for path in self.config.path().split("."): family = family.option(path) name = family.name(uncalculated=True) if family.isoptiondescription(): infos[name] = self.get_root_family(family) infos = infos[name]["children"] else: if name not in informations: informations = {} else: infos[name] = informations[name] break else: infos.update(informations) informations = root_informations self.informations = informations def get_root_family(self, family): family_type = self._get_family_type(family) family_informations = self._collect_family( family, family_type, with_identifier=False, current_identifier_only=False, ) if family_informations is not False: return { "type": family_type, "informations": family_informations, "children": {}, }