rougail-output-doc/src/rougail/output_doc/doc.py

160 lines
5.5 KiB
Python

"""
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 <http://www.gnu.org/licenses/>.
"""
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": {},
}