2024-11-15 08:13:45 +01:00
|
|
|
"""
|
|
|
|
|
Silique (https://www.silique.fr)
|
2026-01-04 19:16:18 +01:00
|
|
|
Copyright (C) 2024-2026
|
2025-04-28 19:34:24 +02:00
|
|
|
|
2024-11-15 08:13:45 +01:00
|
|
|
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/>.
|
|
|
|
|
"""
|
|
|
|
|
|
2026-03-29 11:01:15 +02:00
|
|
|
from typing import Union
|
2024-11-15 08:13:45 +01:00
|
|
|
|
2026-03-29 11:01:15 +02:00
|
|
|
from tiramisu import groups
|
|
|
|
|
from rougail.utils import get_properties_to_string
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
from .config import OutPuts
|
|
|
|
|
from .i18n import _
|
2026-03-29 11:01:15 +02:00
|
|
|
from .collect import Collect
|
2025-10-14 12:58:39 +02:00
|
|
|
from .changelog import Changelog
|
2026-03-29 11:01:15 +02:00
|
|
|
from .example import Examples
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
|
2026-03-29 11:01:15 +02:00
|
|
|
class RougailOutputDoc(Collect, Examples, Changelog):
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Rougail Output Doc:
|
|
|
|
|
Generate documentation from rougail description files
|
|
|
|
|
"""
|
2026-03-29 11:01:15 +02:00
|
|
|
|
2026-01-14 13:56:51 +01:00
|
|
|
output_name = "doc"
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
|
self,
|
2026-01-04 19:16:18 +01:00
|
|
|
config: Union["Config", "SubConfig"],
|
2024-11-15 08:13:45 +01:00
|
|
|
*,
|
|
|
|
|
rougailconfig: "RougailConfig" = None,
|
2026-01-04 19:16:18 +01:00
|
|
|
true_config: "Config" = None,
|
2026-03-29 11:01:15 +02:00
|
|
|
root_config: "Config" = None,
|
2025-11-29 07:59:33 +01:00
|
|
|
**kwargs,
|
2024-11-15 08:13:45 +01:00
|
|
|
):
|
|
|
|
|
# Import here to avoid circular import
|
2025-06-18 15:50:11 +02:00
|
|
|
from rougail.tiramisu import CONVERT_OPTION
|
2024-11-15 08:13:45 +01:00
|
|
|
|
|
|
|
|
self.convert_option = CONVERT_OPTION
|
|
|
|
|
if rougailconfig is None:
|
|
|
|
|
from rougail import RougailConfig
|
|
|
|
|
|
|
|
|
|
rougailconfig = RougailConfig
|
2026-01-14 13:56:51 +01:00
|
|
|
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
|
2026-01-04 19:16:18 +01:00
|
|
|
if true_config is None:
|
|
|
|
|
self.true_config = config
|
|
|
|
|
else:
|
|
|
|
|
self.true_config = true_config
|
2026-03-29 11:01:15 +02:00
|
|
|
if root_config is None:
|
|
|
|
|
self.root_config = self.true_config
|
|
|
|
|
else:
|
|
|
|
|
self.root_config = root_config
|
2025-10-30 21:14:34 +01:00
|
|
|
self.rougailconfig = rougailconfig
|
2024-11-15 08:13:45 +01:00
|
|
|
self.informations = None
|
2025-11-03 09:03:59 +01:00
|
|
|
self.formatter = None
|
2024-11-15 08:13:45 +01:00
|
|
|
super().__init__()
|
|
|
|
|
|
2024-11-28 21:36:45 +01:00
|
|
|
def run(self) -> str:
|
2024-11-15 08:13:45 +01:00
|
|
|
"""Print documentation in stdout"""
|
2025-10-14 13:50:02 +02:00
|
|
|
self.load()
|
2025-11-03 09:03:59 +01:00
|
|
|
self.load_formatter()
|
2025-10-15 09:44:22 +02:00
|
|
|
return_string = ""
|
2025-10-30 21:14:34 +01:00
|
|
|
contents = self.rougailconfig["doc.contents"]
|
|
|
|
|
if "variables" in contents:
|
|
|
|
|
return_string += self.formatter.run(self.informations)
|
|
|
|
|
if "example" in contents:
|
2025-10-14 12:58:39 +02:00
|
|
|
return_string += self.gen_doc_examples()
|
2025-10-30 21:14:34 +01:00
|
|
|
if "changelog" in contents:
|
2025-10-14 12:58:39 +02:00
|
|
|
return_string += self.gen_doc_changelog()
|
2025-02-10 09:52:12 +01:00
|
|
|
return True, return_string
|
2024-11-15 08:13:45 +01:00
|
|
|
|
2025-11-03 09:03:59 +01:00
|
|
|
def load_formatter(self) -> str:
|
|
|
|
|
output_format = self.rougailconfig["doc.output_format"]
|
2026-03-29 11:01:15 +02:00
|
|
|
self.formatter = self.outputs[output_format](
|
2026-04-30 06:58:12 +02:00
|
|
|
self.rougailconfig, support_namespace=self.support_namespace, document_a_type=self.document_a_type
|
2026-03-29 11:01:15 +02:00
|
|
|
)
|
2025-11-03 09:03:59 +01:00
|
|
|
|
2025-01-04 11:52:37 +01:00
|
|
|
def print(self) -> None:
|
2025-02-10 09:52:12 +01:00
|
|
|
ret, data = self.run()
|
|
|
|
|
print(data)
|
|
|
|
|
return ret
|
2025-01-04 11:52:37 +01:00
|
|
|
|
2025-10-18 06:40:23 +02:00
|
|
|
def load(self):
|
2026-01-14 13:56:51 +01:00
|
|
|
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()
|
2025-10-14 12:58:39 +02:00
|
|
|
self.dynamic_paths = {}
|
2026-03-29 11:01:15 +02:00
|
|
|
if self.config.isoptiondescription():
|
|
|
|
|
informations = self.collect_families(self.config.unrestraint)
|
2026-04-30 06:58:12 +02:00
|
|
|
# from pprint import pprint
|
|
|
|
|
# pprint(informations)
|
2026-02-01 21:11:08 +01:00
|
|
|
else:
|
2026-01-19 17:12:20 +01:00
|
|
|
informations = {}
|
2026-03-29 11:01:15 +02:00
|
|
|
self.collect_variable(self.config, informations)
|
2024-11-15 08:13:45 +01:00
|
|
|
if informations is None:
|
|
|
|
|
informations = {}
|
2026-03-29 11:01:15 +02:00
|
|
|
if self.true_config != self.config:
|
|
|
|
|
# build cache for dyn family
|
2026-01-04 19:16:18 +01:00
|
|
|
root_informations = {}
|
|
|
|
|
infos = root_informations
|
2026-03-29 11:01:15 +02:00
|
|
|
family = self.root_config
|
|
|
|
|
for path in self.config.path().split("."):
|
2026-01-04 19:16:18 +01:00
|
|
|
family = family.option(path)
|
|
|
|
|
name = family.name(uncalculated=True)
|
2026-01-19 17:12:20 +01:00
|
|
|
if family.isoptiondescription():
|
2026-03-29 11:01:15 +02:00
|
|
|
infos[name] = self.get_root_family(family)
|
2026-01-19 17:12:20 +01:00
|
|
|
infos = infos[name]["children"]
|
2026-03-29 11:01:15 +02:00
|
|
|
else:
|
|
|
|
|
if name not in informations:
|
|
|
|
|
informations = {}
|
|
|
|
|
else:
|
|
|
|
|
infos[name] = informations[name]
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
infos.update(informations)
|
2026-01-04 19:16:18 +01:00
|
|
|
informations = root_informations
|
2024-11-15 08:13:45 +01:00
|
|
|
self.informations = informations
|
|
|
|
|
|
2026-03-29 11:01:15 +02:00
|
|
|
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,
|
2026-01-04 19:16:18 +01:00
|
|
|
)
|
|
|
|
|
if family_informations is not False:
|
|
|
|
|
return {
|
2026-03-29 11:01:15 +02:00
|
|
|
"type": family_type,
|
2026-01-04 19:16:18 +01:00
|
|
|
"informations": family_informations,
|
|
|
|
|
"children": {},
|
|
|
|
|
}
|