""" Silique (https://www.silique.fr) Copyright (C) 2024-2025 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 pathlib import Path from rougail.utils import load_modules from .i18n import _ ROUGAIL_VARIABLE_TYPE = ( "https://rougail.readthedocs.io/en/latest/variable.html#variables-types" ) OUTPUTS = None TABLES = None def get_outputs_or_tables(type_) -> None: """Load all outputs or tables""" module_name = f"rougail.output_doc.{type_}" outputs = {} names = [] for path in (Path(__file__).parent / type_).iterdir(): name = path.name if not name.endswith(".py") or name.endswith("__.py"): continue module = load_modules(module_name + "." + name[:-3], str(path)) if type_ == "output": if "Formatter" not in dir(module): continue obj_class = module.Formatter elif type_ == "table": if "Table" not in dir(module): continue obj_class = module.Table level = obj_class.level if level in outputs: raise ImportError( _('duplicated level rougail-output-doc for {0} "{1}": {2} and {3}').format( type_, level, obj_class.name, outputs[level].name ) ) if obj_class.name in names: raise ImportError( _('duplicated name "{0}" in rougail-output-doc').format( obj_class.name ) ) names.append(obj_class.name) outputs[level] = obj_class return {outputs[level].name: outputs[level] for level in sorted(outputs)} class OutPuts: # pylint: disable=R0903 """Transformations applied on a object instance""" def __init__( self, ) -> None: global OUTPUTS if OUTPUTS is None: OUTPUTS = get_outputs_or_tables("output") def get(self) -> dict: """Get all outputs""" return OUTPUTS class Tables: # pylint: disable=R0903 """Transformations applied on a object instance""" def __init__( self, ) -> None: global TABLES if TABLES is None: TABLES = get_outputs_or_tables("table") def get(self) -> dict: """Get all tables""" return TABLES def get_rougail_config( *, backward_compatibility=True, # pylint: disable=unused-argument ) -> dict: """Get documentation for output_doc modules""" outputs = list(OutPuts().get()) output_format_default = outputs[0] tables = list(Tables().get()) table_default = tables[0] rougail_options = f""" doc: description: {_('Generate documentation')} disabled: jinja: | {{% if step.output is propertyerror or step.output != 'doc' %}} disabled {{% endif %}} description: {_('when "doc" is not set in "step.output"')} title_level: description: {_('Starting title level')} alternative_name: dt default: 1 contents: description: {_('Generated content')} alternative_name: dc choices: - variables - example - changelog default: - variables previous_json_file: description: {_('Previous description file in JSON format')} alternative_name: dp disabled: jinja: |- {{{{ "changelog" not in _.contents }}}} return_type: boolean description: {_('changelog is not selected in "_.contents"')} without_family: description: {_('Do not add families in documentation')} default: false alternative_name: df disabled: jinja: |- {{{{ _.output_format == "json" or ("variables" not in _.contents and "changelog" not in _.contents) }}}} return_type: boolean description: {_('if "_.output_format" is json or "_.contents" hasn\'t variable or changelog')} root: description: {_('Document the variables from this family')} alternative_name: dr mandatory: false with_commandline: description: {_('Add command line informations in documentation')} alternative_name: dw default: false disabled: jinja: |- {{{{ _.output_format == "json" or ("variables" not in _.contents and "changelog" not in _.contents) }}}} return_type: boolean description: {_('if "_.output_format" is json or "_.contents" hasn\'t variable or changelog')} with_environment: description: {_('Add environment variable informations in documentation')} alternative_name: de default: false disabled: jinja: |- {{{{ _.output_format == "json" or ("variables" not in _.contents and "changelog" not in _.contents) }}}} return_type: boolean description: {_('if "_.output_format" is json or "_.contents" hasn\'t variable or changelog')} environment_default_environment_name: description: {_("Name of the default environment prefix")} alternative_name: dd default: ROUGAIL validators: - jinja: |- {{{{ (_.environment_default_environment_name | upper) != _.environment_default_environment_name }}}} return_type: boolean description: {_("should only user uppercase characters")} disabled: jinja: |- {{{{ __.main_namespace == none or _.with_environment is false }}}} return_type: boolean description: {_('when "__.main_namespace" is not set or "_.with_environment" is false')} other_root_filenames: description: {_("Families or variables for this family are in an other file name")} type: leadership disabled: jinja: |- {{% if not _.root %}} Documents are not splitted {{% endif %}} description: {_('documentation must be splitted')} root_path: description: {_("Root family name")} mandatory: false filename: description: {_("Name of the file")} type: unix_filename params: allow_relative: true disabled_modes: description: {_('Disable documentation for variables with those modes')} multi: true mandatory: false disabled: jinja: | {{% if not modes_level %}} there is no mode {{% endif %}} description: {_('disabled when there is no mode available')} validators: - jinja: | {{% if _.disabled_modes not in modes_level %}} this mode is not available {{% endif %}} description: {_('verify if disable modes already exists')} change_default_value: true # {_('Modify values to document leaderships and dynamics families')} comment_examples: description: {_('Add description of variables and families when generate examples')} alternative_name: dx default: false disabled: jinja: |- {{{{ "example" not in _.contents }}}} return_type: boolean description: {_('disabled when example in not in contents')} comment_examples_column: description: {_('Comment in examples starts at column')} default: 30 disabled: variable: _.comment_examples propertyerror: false when: false output_format: description: {_('Generate document in format')} alternative_name: do default: { output_format_default } validators: - jinja: |- {{% if _.output_format == 'json' %}} {{% if "changelog" in _.contents or "example" in _.contents %}} cannot add to contents "{{{{ _.contents }}}}" with output_format "json" {{% endif %}} {{% endif %}} description: {_('json output_format is not compatible with "changelog" and "example" contents')} choices: """ for output in outputs: rougail_options += f" - {output}\n" rougail_options += f""" table_model: description: {_('Generate document inside table model')} alternative_name: dm default: { table_default } validators: - jinja: |- {{% if _.output_format == 'json' %}} {{% if "changelog" in _.contents or "example" in _.contents %}} cannot add to contents "{{{{ _.contents }}}}" with output_format "json" {{% endif %}} {{% endif %}} description: {_('json output_format is not compatible with "changelog" and "example" contents')} choices: """ for table in tables: rougail_options += f" - {table}\n" rougail_options += f""" force_true_color_terminal: description: {_('Force true color terminal')} default: false """ return { "name": "doc", "process": "output", "options": rougail_options, "allow_user_data": False, "level": 50, } __all__ = ("OutPuts", "get_rougail_config")