feat: black + improvement
This commit is contained in:
parent
db53c752dc
commit
1701d317d4
8 changed files with 691 additions and 478 deletions
40
pyproject.toml
Normal file
40
pyproject.toml
Normal file
|
@ -0,0 +1,40 @@
|
|||
[build-system]
|
||||
build-backend = "flit_core.buildapi"
|
||||
requires = ["flit_core >=3.8.0,<4"]
|
||||
|
||||
[project]
|
||||
name = "rougail.output_doc"
|
||||
version = "0.1.0rc0"
|
||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||
readme = "README.md"
|
||||
description = "Rougail output doc"
|
||||
requires-python = ">=3.8"
|
||||
license = {file = "LICENSE"}
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
"Natural Language :: English",
|
||||
"Natural Language :: French",
|
||||
|
||||
]
|
||||
dependencies = [
|
||||
"rougail ~= 1.1.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Home = "https://forge.cloud.silique.fr/stove/rougail-output-exporter"
|
||||
|
||||
[tool.commitizen]
|
||||
name = "cz_conventional_commits"
|
||||
tag_format = "$version"
|
||||
version_scheme = "pep440"
|
||||
version_provider = "pep621"
|
||||
update_changelog_on_bump = true
|
||||
changelog_merge_prerelease = true
|
|
@ -1,25 +1,22 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2022-2024
|
||||
Copyright (C) 2024
|
||||
|
||||
distribued with GPL-2 or later license
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
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/>.
|
||||
"""
|
||||
#FIXME si plusieurs example dont le 1er est none tester les autres : tests/dictionaries/00_8test_none
|
||||
# FIXME si plusieurs example dont le 1er est none tester les autres : tests/dictionaries/00_8test_none
|
||||
from tiramisu import Calculation
|
||||
from tiramisu.error import display_list
|
||||
import tabulate as tabulate_module
|
||||
|
@ -27,62 +24,62 @@ from tabulate import tabulate
|
|||
from warnings import warn
|
||||
from typing import Optional
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
from rougail.error import display_xmlfiles
|
||||
from rougail import RougailConfig, Rougail, CONVERT_OPTION
|
||||
from rougail.object_model import PROPERTY_ATTRIBUTE
|
||||
|
||||
from .config import OutPuts
|
||||
from .i18n import _
|
||||
|
||||
ENTER = "\n\n"
|
||||
|
||||
|
||||
DocTypes = {
|
||||
'domainname': {
|
||||
'params': {
|
||||
'allow_startswith_dot': _('the domain name can starts by a dot'),
|
||||
'allow_without_dot': _('the domain name can be only a hostname'),
|
||||
'allow_ip': _('the domain name can be an IP'),
|
||||
'allow_cidr_network': _('the domain name can be network in CIDR format'),
|
||||
"domainname": {
|
||||
"params": {
|
||||
"allow_startswith_dot": _("the domain name can starts by a dot"),
|
||||
"allow_without_dot": _("the domain name can be a hostname"),
|
||||
"allow_ip": _("the domain name can be an IP"),
|
||||
"allow_cidr_network": _("the domain name can be network in CIDR format"),
|
||||
},
|
||||
},
|
||||
'number': {
|
||||
'params': {
|
||||
'min_number': _('the minimum value is {value}'),
|
||||
'max_number': _('the maximum value is {value}'),
|
||||
"number": {
|
||||
"params": {
|
||||
"min_number": _("the minimum value is {value}"),
|
||||
"max_number": _("the maximum value is {value}"),
|
||||
},
|
||||
},
|
||||
'ip': {
|
||||
'msg': 'IP',
|
||||
'params': {
|
||||
'cidr': _('IP must be in CIDR format'),
|
||||
'private_only': _('private IP are allowed'),
|
||||
'allow_reserved': _('reserved IP are allowed'),
|
||||
"ip": {
|
||||
"msg": "IP",
|
||||
"params": {
|
||||
"cidr": _("IP must be in CIDR format"),
|
||||
"private_only": _("private IP are allowed"),
|
||||
"allow_reserved": _("reserved IP are allowed"),
|
||||
},
|
||||
},
|
||||
'hostname': {
|
||||
'params': {
|
||||
'allow_ip': _('the host name can be an IP'),
|
||||
"hostname": {
|
||||
"params": {
|
||||
"allow_ip": _("the host name can be an IP"),
|
||||
},
|
||||
},
|
||||
'web_address': {
|
||||
'params': {
|
||||
'allow_ip': _('the domain name in web address can be an IP'),
|
||||
'allow_without_dot': _('the domain name in web address can be only a hostname'),
|
||||
"web_address": {
|
||||
"params": {
|
||||
"allow_ip": _("the domain name in web address can be an IP"),
|
||||
"allow_without_dot": _(
|
||||
"the domain name in web address can be only a hostname"
|
||||
),
|
||||
},
|
||||
},
|
||||
'port': {
|
||||
'params': {
|
||||
'allow_range': _('can be range of port'),
|
||||
'allow_protocol': _('can have the protocol'),
|
||||
'allow_zero': _('port 0 is allowed'),
|
||||
'allow_wellknown': _('ports 1 to 1023 are allowed'),
|
||||
'allow_registred': _('ports 1024 to 49151 are allowed'),
|
||||
'allow_private': _('ports greater than 49152 are allowed'),
|
||||
"port": {
|
||||
"params": {
|
||||
"allow_range": _("can be range of port"),
|
||||
"allow_protocol": _("can have the protocol"),
|
||||
"allow_zero": _("port 0 is allowed"),
|
||||
"allow_wellknown": _("ports 1 to 1023 are allowed"),
|
||||
"allow_registred": _("ports 1024 to 49151 are allowed"),
|
||||
"allow_private": _("ports greater than 49152 are allowed"),
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,36 +89,48 @@ ROUGAIL_VARIABLE_TYPE = (
|
|||
|
||||
|
||||
class RougailOutputDoc:
|
||||
def __init__(self,
|
||||
*,
|
||||
config: 'Config'=None,
|
||||
rougailconfig: RougailConfig=None,
|
||||
):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
config: "Config" = None,
|
||||
rougailconfig: RougailConfig = None,
|
||||
**kwarg,
|
||||
):
|
||||
if rougailconfig is None:
|
||||
rougailconfig = RougailConfig
|
||||
if rougailconfig["step.output"] != "doc":
|
||||
rougailconfig["step.output"] = "doc"
|
||||
if rougailconfig["step.output"] != "doc":
|
||||
raise Exception("doc is not set as step.output")
|
||||
self.rougailconfig = rougailconfig
|
||||
outputs = OutPuts().get()
|
||||
output = self.rougailconfig['doc.output_format']
|
||||
output = self.rougailconfig["doc.output_format"]
|
||||
if output not in outputs:
|
||||
raise Exception(f'cannot find output "{output}", available outputs: {list(outputs)}')
|
||||
raise Exception(
|
||||
f'cannot find output "{output}", available outputs: {list(outputs)}'
|
||||
)
|
||||
if config is None:
|
||||
rougail = Rougail(self.rougailconfig)
|
||||
rougail.converted.plugins.append('output_doc')
|
||||
rougail.converted.plugins.append("output_doc")
|
||||
config = rougail.get_config()
|
||||
self.conf = config
|
||||
self.conf.property.setdefault(frozenset({'advanced'}), 'read_write', 'append')
|
||||
self.conf.property.setdefault(frozenset({"advanced"}), "read_write", "append")
|
||||
self.conf.property.read_write()
|
||||
self.conf.property.remove("cache")
|
||||
self.dynamic_paths = {}
|
||||
self.formater = outputs[output]()
|
||||
self.level = self.rougailconfig['doc.title_level']
|
||||
#self.property_to_string = [('mandatory', 'obligatoire'), ('hidden', 'cachée'), ('disabled', 'désactivée'), ('unique', 'unique'), ('force_store_value', 'modifié automatiquement')]
|
||||
self.property_to_string = [('mandatory', _('mandatory')),
|
||||
('hidden', _('hidden')),
|
||||
('disabled', _('disabled')),
|
||||
('unique', _('unique')),
|
||||
('force_store_value', _('auto modified')),
|
||||
]
|
||||
self.level = self.rougailconfig["doc.title_level"]
|
||||
# self.property_to_string = [('mandatory', 'obligatoire'), ('hidden', 'cachée'), ('disabled', 'désactivée'), ('unique', 'unique'), ('force_store_value', 'modifié automatiquement')]
|
||||
self.property_to_string = [
|
||||
("mandatory", _("mandatory")),
|
||||
("hidden", _("hidden")),
|
||||
("disabled", _("disabled")),
|
||||
("unique", _("unique")),
|
||||
("force_store_value", _("auto modified")),
|
||||
]
|
||||
|
||||
def run(self):
|
||||
print(self.gen_doc())
|
||||
|
||||
def gen_doc(self):
|
||||
tabulate_module.PRESERVE_WHITESPACE = True
|
||||
|
@ -133,51 +142,62 @@ class RougailOutputDoc:
|
|||
name = namespace.name()
|
||||
examples_mini[name] = {}
|
||||
examples_all[name] = {}
|
||||
doc = self._display_doc(
|
||||
self.display_families(
|
||||
namespace,
|
||||
self.level + 1,
|
||||
examples_mini[name],
|
||||
examples_all[name],
|
||||
),
|
||||
[],
|
||||
) + '\n'
|
||||
doc = (
|
||||
self._display_doc(
|
||||
self.display_families(
|
||||
namespace,
|
||||
self.level + 1,
|
||||
examples_mini[name],
|
||||
examples_all[name],
|
||||
),
|
||||
[],
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
if not examples_mini[name]:
|
||||
del examples_mini[name]
|
||||
if not examples_all[name]:
|
||||
del examples_all[name]
|
||||
else:
|
||||
return_string += self.formater.title(_(f'Variables for "{namespace.name()}"'), self.level)
|
||||
return_string += self.formater.title(
|
||||
_(f'Variables for "{namespace.name()}"'), self.level
|
||||
)
|
||||
return_string += doc
|
||||
else:
|
||||
doc = self._display_doc(
|
||||
self.display_families(
|
||||
self.conf.unrestraint,
|
||||
self.level + 1,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
),
|
||||
[],
|
||||
) + '\n'
|
||||
doc = (
|
||||
self._display_doc(
|
||||
self.display_families(
|
||||
self.conf.unrestraint,
|
||||
self.level + 1,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
),
|
||||
[],
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
if examples_all:
|
||||
return_string += self.formater.title(_(f'Variables'), self.level)
|
||||
return_string += self.formater.title(_(f"Variables"), self.level)
|
||||
return_string += doc
|
||||
if not examples_all:
|
||||
return ''
|
||||
if examples_mini:
|
||||
#"Exemple avec les variables obligatoires non renseignées"
|
||||
return_string += self.formater.title(
|
||||
_("Example with mandatory variables not filled in"), self.level
|
||||
)
|
||||
return_string += self.formater.yaml(examples_mini)
|
||||
if examples_all:
|
||||
#"Exemple avec tous les variables modifiables"
|
||||
return_string += self.formater.title("Example with all variables modifiable", self.level)
|
||||
return_string += self.formater.yaml(examples_all)
|
||||
return ""
|
||||
if self.rougailconfig["doc.with_example"]:
|
||||
if examples_mini:
|
||||
# "Exemple avec les variables obligatoires non renseignées"
|
||||
return_string += self.formater.title(
|
||||
_("Example with mandatory variables not filled in"), self.level
|
||||
)
|
||||
return_string += self.formater.yaml(examples_mini)
|
||||
if examples_all:
|
||||
# "Exemple avec tous les variables modifiables"
|
||||
return_string += self.formater.title(
|
||||
"Example with all variables modifiable", self.level
|
||||
)
|
||||
return_string += self.formater.yaml(examples_all)
|
||||
return return_string
|
||||
|
||||
def _display_doc(self, variables, add_paths):
|
||||
return_string = ''
|
||||
return_string = ""
|
||||
for variable in variables:
|
||||
typ = variable["type"]
|
||||
path = variable["path"]
|
||||
|
@ -189,21 +209,50 @@ class RougailOutputDoc:
|
|||
else:
|
||||
for idx, path in enumerate(variable["paths"]):
|
||||
if path in self.dynamic_paths:
|
||||
paths_msg = display_list([self.formater.bold(path_) for path_ in self.dynamic_paths[path]['paths']], separator='or')
|
||||
variable["objects"][idx][0] = variable["objects"][idx][0].replace('{{ ROUGAIL_PATH }}', paths_msg)
|
||||
suffixes = self.dynamic_paths[path]['suffixes']
|
||||
paths_msg = display_list(
|
||||
[
|
||||
self.formater.bold(path_)
|
||||
for path_ in self.dynamic_paths[path]["paths"]
|
||||
],
|
||||
separator="or",
|
||||
)
|
||||
variable["objects"][idx][0] = variable["objects"][idx][
|
||||
0
|
||||
].replace("{{ ROUGAIL_PATH }}", paths_msg)
|
||||
identifiers = self.dynamic_paths[path]["identifiers"]
|
||||
description = variable["objects"][idx][1][0]
|
||||
if "{{ suffix }}" in description:
|
||||
if description.endswith('.'):
|
||||
if "{{ identifier }}" in description:
|
||||
if description.endswith("."):
|
||||
description = description[:-1]
|
||||
comment_msg = self.to_phrase(display_list([description.replace('{{ suffix }}', self.formater.italic(suffix)) for suffix in suffixes], separator='or', add_quote=True))
|
||||
comment_msg = self.to_phrase(
|
||||
display_list(
|
||||
[
|
||||
description.replace(
|
||||
"{{ identifier }}",
|
||||
self.formater.italic(identifier),
|
||||
)
|
||||
for identifier in identifiers
|
||||
],
|
||||
separator="or",
|
||||
add_quote=True,
|
||||
)
|
||||
)
|
||||
variable["objects"][idx][1][0] = comment_msg
|
||||
variable["objects"][idx][1] = self.formater.join(variable["objects"][idx][1])
|
||||
return_string += self.formater.table(tabulate(
|
||||
variable["objects"],
|
||||
headers=self.formater.table_header(['Variable', 'Description']),
|
||||
tablefmt=self.formater.name,
|
||||
)) + '\n\n'
|
||||
variable["objects"][idx][1] = self.formater.join(
|
||||
variable["objects"][idx][1]
|
||||
)
|
||||
return_string += (
|
||||
self.formater.table(
|
||||
tabulate(
|
||||
variable["objects"],
|
||||
headers=self.formater.table_header(
|
||||
["Variable", "Description"]
|
||||
),
|
||||
tablefmt=self.formater.name,
|
||||
)
|
||||
)
|
||||
+ "\n\n"
|
||||
)
|
||||
add_paths.append(path)
|
||||
return return_string
|
||||
|
||||
|
@ -236,8 +285,12 @@ class RougailOutputDoc:
|
|||
continue
|
||||
path = child.path(uncalculated=True)
|
||||
if child.isdynamic():
|
||||
self.dynamic_paths.setdefault(path, {'paths': [], 'suffixes': []})['paths'].append(child.path())
|
||||
self.dynamic_paths[path]['suffixes'].append(child.suffixes()[-1])
|
||||
self.dynamic_paths.setdefault(
|
||||
path, {"paths": [], "identifiers": []}
|
||||
)["paths"].append(child.path())
|
||||
self.dynamic_paths[path]["identifiers"].append(
|
||||
child.identifiers()[-1]
|
||||
)
|
||||
if not variables or variables[-1]["type"] != "variables":
|
||||
variables.append(
|
||||
{
|
||||
|
@ -298,9 +351,18 @@ class RougailOutputDoc:
|
|||
title = f"{family.path()}"
|
||||
isdynamic = family.isdynamic(only_self=True)
|
||||
if isdynamic:
|
||||
suffixes = family.suffixes(only_self=True)
|
||||
if '{{ suffix }}' in title:
|
||||
title = display_list([title.replace('{{ suffix }}', self.formater.italic(suffix)) for suffix in suffixes], separator='or', add_quote=True)
|
||||
identifiers = family.identifiers(only_self=True)
|
||||
if "{{ identifier }}" in title:
|
||||
title = display_list(
|
||||
[
|
||||
title.replace(
|
||||
"{{ identifier }}", self.formater.italic(identifier)
|
||||
)
|
||||
for identifier in identifiers
|
||||
],
|
||||
separator="or",
|
||||
add_quote=True,
|
||||
)
|
||||
msg = self.formater.title(title, level)
|
||||
subparameter = []
|
||||
self.manage_properties(family, subparameter)
|
||||
|
@ -309,8 +371,8 @@ class RougailOutputDoc:
|
|||
comment = []
|
||||
self.subparameter_to_parameter(subparameter, comment)
|
||||
if comment:
|
||||
msg += '\n'.join(comment) + ENTER
|
||||
help = self.to_phrase(family.information.get('help', ""))
|
||||
msg += "\n".join(comment) + ENTER
|
||||
help = self.to_phrase(family.information.get("help", ""))
|
||||
if help:
|
||||
msg += "\n" + help + ENTER
|
||||
if family.isleadership():
|
||||
|
@ -318,39 +380,43 @@ class RougailOutputDoc:
|
|||
help = "This family contains lists of variable blocks."
|
||||
msg += "\n" + help + ENTER
|
||||
if isdynamic:
|
||||
suffixes = family.suffixes(only_self=True , uncalculated=True)
|
||||
if isinstance(suffixes, Calculation):
|
||||
suffixes = self.to_string(family, 'dynamic')
|
||||
if isinstance(suffixes, list):
|
||||
for idx, val in enumerate(suffixes):
|
||||
identifiers = family.identifiers(only_self=True, uncalculated=True)
|
||||
if isinstance(identifiers, Calculation):
|
||||
identifiers = self.to_string(family, "dynamic")
|
||||
if isinstance(identifiers, list):
|
||||
for idx, val in enumerate(identifiers):
|
||||
if not isinstance(val, Calculation):
|
||||
continue
|
||||
suffixes[idx] = self.to_string(family, 'dynamic', f'_{idx}')
|
||||
suffixes = self.formater.list(suffixes)
|
||||
#help = f"Cette famille construit des familles dynamiquement.\n\n{self.formater.bold('Suffixes')}: {suffixes}"
|
||||
help = f"This family builds families dynamically.\n\n{self.formater.bold('Suffixes')}: {suffixes}"
|
||||
identifiers[idx] = self.to_string(family, "dynamic", f"_{idx}")
|
||||
identifiers = self.formater.list(identifiers)
|
||||
# help = f"Cette famille construit des familles dynamiquement.\n\n{self.formater.bold('Identifiers')}: {identifiers}"
|
||||
help = f"This family builds families dynamically.\n\n{self.formater.bold('Identifiers')}: {identifiers}"
|
||||
msg += "\n" + help + ENTER
|
||||
return msg
|
||||
|
||||
def manage_properties(self,
|
||||
variable,
|
||||
subparameter,
|
||||
):
|
||||
def manage_properties(
|
||||
self,
|
||||
variable,
|
||||
subparameter,
|
||||
):
|
||||
properties = variable.property.get(uncalculated=True)
|
||||
for mode in self.rougailconfig['modes_level']:
|
||||
for mode in self.rougailconfig["modes_level"]:
|
||||
if mode in properties:
|
||||
subparameter.append((self.formater.prop(mode), None, None))
|
||||
break
|
||||
for prop, msg in self.property_to_string:
|
||||
if prop in properties:
|
||||
subparameter.append((self.formater.prop(msg), None, None))
|
||||
elif variable.information.get(f'{prop}_calculation', False):
|
||||
subparameter.append((self.formater.prop(msg), msg, self.to_string(variable, prop)))
|
||||
elif variable.information.get(f"{prop}_calculation", False):
|
||||
subparameter.append(
|
||||
(self.formater.prop(msg), msg, self.to_string(variable, prop))
|
||||
)
|
||||
|
||||
def subparameter_to_string(self,
|
||||
subparameter,
|
||||
):
|
||||
subparameter_str = ''
|
||||
def subparameter_to_string(
|
||||
self,
|
||||
subparameter,
|
||||
):
|
||||
subparameter_str = ""
|
||||
for param in subparameter:
|
||||
if param[1]:
|
||||
subparameter_str += f"_{param[0]}_ "
|
||||
|
@ -358,10 +424,11 @@ class RougailOutputDoc:
|
|||
subparameter_str += f"{param[0]} "
|
||||
return subparameter_str[:-1]
|
||||
|
||||
def subparameter_to_parameter(self,
|
||||
subparameter,
|
||||
comment,
|
||||
):
|
||||
def subparameter_to_parameter(
|
||||
self,
|
||||
subparameter,
|
||||
comment,
|
||||
):
|
||||
for param in subparameter:
|
||||
if not param[1]:
|
||||
continue
|
||||
|
@ -370,10 +437,10 @@ class RougailOutputDoc:
|
|||
|
||||
def to_phrase(self, msg):
|
||||
if not msg:
|
||||
return ''
|
||||
return ""
|
||||
msg = str(msg).strip()
|
||||
if not msg.endswith('.'):
|
||||
msg += '.'
|
||||
if not msg.endswith("."):
|
||||
msg += "."
|
||||
return msg[0].upper() + msg[1:]
|
||||
|
||||
def display_variable(
|
||||
|
@ -389,16 +456,18 @@ class RougailOutputDoc:
|
|||
subparameter = []
|
||||
description = variable.description(uncalculated=True)
|
||||
comment = [self.to_phrase(description)]
|
||||
help_ = self.to_phrase(variable.information.get("help", ''))
|
||||
help_ = self.to_phrase(variable.information.get("help", ""))
|
||||
if help_:
|
||||
comment.append(help_)
|
||||
self.type_to_string(variable,
|
||||
subparameter,
|
||||
comment,
|
||||
)
|
||||
self.manage_properties(variable,
|
||||
subparameter,
|
||||
)
|
||||
self.type_to_string(
|
||||
variable,
|
||||
subparameter,
|
||||
comment,
|
||||
)
|
||||
self.manage_properties(
|
||||
variable,
|
||||
subparameter,
|
||||
)
|
||||
if variable.ismulti():
|
||||
multi = not variable.isfollower() or variable.issubmulti()
|
||||
else:
|
||||
|
@ -410,127 +479,161 @@ class RougailOutputDoc:
|
|||
if variable.name() == description:
|
||||
warning = f'No attribute "description" for variable "{variable.path()}" in {display_xmlfiles(variable.information.get("dictionaries"))}'
|
||||
warn(warning)
|
||||
default = self.get_default(variable,
|
||||
comment,
|
||||
)
|
||||
default = self.get_default(
|
||||
variable,
|
||||
comment,
|
||||
)
|
||||
default_in_choices = False
|
||||
if variable.information.get("type") == 'choice':
|
||||
if variable.information.get("type") == "choice":
|
||||
choices = variable.value.list(uncalculated=True)
|
||||
if isinstance(choices, Calculation):
|
||||
choices = self.to_string(variable, 'choice')
|
||||
choices = self.to_string(variable, "choice")
|
||||
if isinstance(choices, list):
|
||||
for idx, val in enumerate(choices):
|
||||
if not isinstance(val, Calculation):
|
||||
if default is not None and val == default:
|
||||
choices[idx] = str(val) + ' ← ' + _("(default)")
|
||||
choices[idx] = str(val) + " ← " + _("(default)")
|
||||
default_in_choices = True
|
||||
continue
|
||||
choices[idx] = self.to_string(variable, 'choice', f'_{idx}')
|
||||
choices[idx] = self.to_string(variable, "choice", f"_{idx}")
|
||||
choices = self.formater.list(choices)
|
||||
comment.append(f'{self.formater.bold(_("Choices"))}: {choices}')
|
||||
# choice
|
||||
if default is not None and not default_in_choices:
|
||||
comment.append(f"{self.formater.bold(_('Default'))}: {default}")
|
||||
self.manage_exemples(multi,
|
||||
variable,
|
||||
examples_all,
|
||||
examples_mini,
|
||||
comment,
|
||||
)
|
||||
self.manage_exemples(
|
||||
multi,
|
||||
variable,
|
||||
examples_all,
|
||||
examples_mini,
|
||||
comment,
|
||||
)
|
||||
self.subparameter_to_parameter(subparameter, comment)
|
||||
self.formater.columns(parameter, comment)
|
||||
return [self.formater.join(parameter), comment]
|
||||
|
||||
def get_default(self,
|
||||
variable,
|
||||
comment,
|
||||
):
|
||||
if variable.information.get('fake_default', False):
|
||||
def get_default(
|
||||
self,
|
||||
variable,
|
||||
comment,
|
||||
):
|
||||
if variable.information.get("fake_default", False):
|
||||
default = None
|
||||
else:
|
||||
default = variable.value.get(uncalculated=True)
|
||||
if default in [None, []]:
|
||||
return
|
||||
if isinstance(default, Calculation):
|
||||
default = self.to_string(variable, 'default')
|
||||
default = self.to_string(variable, "default")
|
||||
if isinstance(default, list):
|
||||
for idx, val in enumerate(default):
|
||||
if not isinstance(val, Calculation):
|
||||
continue
|
||||
default[idx] = self.to_string(variable, 'default', f'_{idx}')
|
||||
default[idx] = self.to_string(variable, "default", f"_{idx}")
|
||||
default = self.formater.list(default)
|
||||
return default
|
||||
|
||||
def to_string(self,
|
||||
variable,
|
||||
prop,
|
||||
suffix='',
|
||||
):
|
||||
calculation_type = variable.information.get(f'{prop}_calculation_type{suffix}', None)
|
||||
def to_string(
|
||||
self,
|
||||
variable,
|
||||
prop,
|
||||
identifier="",
|
||||
):
|
||||
calculation_type = variable.information.get(
|
||||
f"{prop}_calculation_type{identifier}", None
|
||||
)
|
||||
if not calculation_type:
|
||||
raise Exception(f'cannot find {prop}_calculation_type{suffix} information, do you have declare doc has a plugins?')
|
||||
calculation = variable.information.get(f'{prop}_calculation{suffix}')
|
||||
if calculation_type == 'jinja':
|
||||
raise Exception(
|
||||
f"cannot find {prop}_calculation_type{identifier} information, do you have declare doc has a plugins?"
|
||||
)
|
||||
calculation = variable.information.get(f"{prop}_calculation{identifier}")
|
||||
if calculation_type == "jinja":
|
||||
if calculation is not True:
|
||||
values = self.formater.to_string(calculation)
|
||||
else:
|
||||
values = "issu d'un calcul"
|
||||
values = "depends on a calculation"
|
||||
warning = f'"{prop}" is a calculation for {variable.path()} but has no description in {display_xmlfiles(variable.information.get("dictionaries"))}'
|
||||
warn(warning)
|
||||
elif calculation_type == 'variable':
|
||||
elif calculation_type == "variable":
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
values = self.formater.to_string(calculation)
|
||||
else:
|
||||
values = _(f'the value of the variable "{calculation}"')
|
||||
elif calculation_type == "identifier":
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
values = self.formater.to_string(calculation)
|
||||
else:
|
||||
values = _(f"value of the {calculation_type}")
|
||||
else:
|
||||
values = _(f"value of the {calculation_type}")
|
||||
if not values.endswith('.'):
|
||||
values += '.'
|
||||
if not values.endswith("."):
|
||||
values += "."
|
||||
return values
|
||||
|
||||
def type_to_string(self,
|
||||
variable,
|
||||
subparameter,
|
||||
comment,
|
||||
):
|
||||
def type_to_string(
|
||||
self,
|
||||
variable,
|
||||
subparameter,
|
||||
comment,
|
||||
):
|
||||
variable_type = variable.information.get("type")
|
||||
doc_type = DocTypes.get(variable_type, {'params': {}})
|
||||
subparameter.append((self.formater.link(doc_type.get('msg', variable_type), ROUGAIL_VARIABLE_TYPE), None))
|
||||
doc_type = DocTypes.get(variable_type, {"params": {}})
|
||||
subparameter.append(
|
||||
(
|
||||
self.formater.link(
|
||||
doc_type.get("msg", variable_type), ROUGAIL_VARIABLE_TYPE
|
||||
),
|
||||
None,
|
||||
)
|
||||
)
|
||||
option = variable.get()
|
||||
validators = []
|
||||
for param, msg in doc_type['params'].items():
|
||||
value = option.impl_get_extra(f'_{param}')
|
||||
for param, msg in doc_type["params"].items():
|
||||
value = option.impl_get_extra(f"_{param}")
|
||||
if value is None:
|
||||
value = option.impl_get_extra(param)
|
||||
if value is not None and value is not False:
|
||||
validators.append(msg.format(value=value))
|
||||
valids = [name for name in variable.information.list() if name.startswith('validators_calculation_type_')]
|
||||
valids = [
|
||||
name
|
||||
for name in variable.information.list()
|
||||
if name.startswith("validators_calculation_type_")
|
||||
]
|
||||
if valids:
|
||||
for idx in range(len(valids)):
|
||||
validators.append(self.to_string(variable,
|
||||
'validators',
|
||||
f'_{idx}',
|
||||
))
|
||||
validators.append(
|
||||
self.to_string(
|
||||
variable,
|
||||
"validators",
|
||||
f"_{idx}",
|
||||
)
|
||||
)
|
||||
if validators:
|
||||
if len(validators) == 1:
|
||||
comment.append(f'{self.formater.bold("Validator")}: ' + validators[0])
|
||||
else:
|
||||
comment.append(f'{self.formater.bold("Validators")}:' + self.formater.list(validators))
|
||||
comment.append(
|
||||
f'{self.formater.bold("Validators")}:'
|
||||
+ self.formater.list(validators)
|
||||
)
|
||||
|
||||
def manage_exemples(self,
|
||||
multi,
|
||||
variable,
|
||||
examples_all,
|
||||
examples_mini,
|
||||
comment,
|
||||
):
|
||||
def manage_exemples(
|
||||
self,
|
||||
multi,
|
||||
variable,
|
||||
examples_all,
|
||||
examples_mini,
|
||||
comment,
|
||||
):
|
||||
example_mini = None
|
||||
example_all = None
|
||||
example = variable.information.get("test", None)
|
||||
example = variable.information.get("examples", None)
|
||||
if example is None:
|
||||
example = variable.information.get("test", None)
|
||||
default = variable.value.get()
|
||||
if isinstance(example, tuple):
|
||||
example = list(example)
|
||||
mandatory = 'mandatory' in variable.property.get(uncalculated=True)
|
||||
mandatory = "mandatory" in variable.property.get(uncalculated=True)
|
||||
if example:
|
||||
if not multi:
|
||||
example = example[0]
|
||||
|
@ -552,9 +655,11 @@ class RougailOutputDoc:
|
|||
elif default not in [None, []]:
|
||||
example_all = default
|
||||
else:
|
||||
example = CONVERT_OPTION.get(variable.information.get("type"), {}).get('example', None)
|
||||
example = CONVERT_OPTION.get(variable.information.get("type"), {}).get(
|
||||
"example", None
|
||||
)
|
||||
if example is None:
|
||||
example = 'xxx'
|
||||
example = "xxx"
|
||||
if multi:
|
||||
example = [example]
|
||||
if mandatory:
|
||||
|
@ -578,3 +683,7 @@ class RougailOutputDoc:
|
|||
if example_mini is not None:
|
||||
examples_mini[variable.name()] = example_mini
|
||||
examples_all[variable.name()] = example_all
|
||||
|
||||
|
||||
RougailOutput = RougailOutputDoc
|
||||
__all__ = ("RougailOutputDoc",)
|
||||
|
|
|
@ -19,14 +19,24 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
"""
|
||||
|
||||
from tiramisu import undefined
|
||||
from rougail.annotator.variable import Walk
|
||||
|
||||
from rougail.i18n import _
|
||||
from rougail.error import DictConsistencyError
|
||||
from rougail.object_model import Calculation, JinjaCalculation, VariableCalculation, \
|
||||
InformationCalculation, IndexCalculation, SuffixCalculation, CONVERT_OPTION, \
|
||||
PROPERTY_ATTRIBUTE
|
||||
from rougail.object_model import (
|
||||
Calculation,
|
||||
JinjaCalculation,
|
||||
VariableCalculation,
|
||||
VariablePropertyCalculation,
|
||||
IdentifierCalculation,
|
||||
IdentifierPropertyCalculation,
|
||||
InformationCalculation,
|
||||
IndexCalculation,
|
||||
CONVERT_OPTION,
|
||||
PROPERTY_ATTRIBUTE,
|
||||
)
|
||||
|
||||
|
||||
class Annotator(Walk):
|
||||
|
@ -45,21 +55,33 @@ class Annotator(Walk):
|
|||
self.populate_family()
|
||||
self.populate_variable()
|
||||
|
||||
def add_default_value(self,
|
||||
family,
|
||||
value,
|
||||
*,
|
||||
inside_list=False,
|
||||
) -> None:
|
||||
def get_examples_values(self, variable):
|
||||
values = self.objectspace.informations.get(variable.path).get("examples", None)
|
||||
if not values:
|
||||
values = self.objectspace.informations.get(variable.path).get("test", None)
|
||||
return values
|
||||
|
||||
def add_default_value(
|
||||
self,
|
||||
family,
|
||||
value,
|
||||
*,
|
||||
inside_list=False,
|
||||
) -> None:
|
||||
if isinstance(value, Calculation):
|
||||
default_values ='example'
|
||||
default_values = "example"
|
||||
if not inside_list:
|
||||
default_values = [default_values]
|
||||
if isinstance(value, VariableCalculation):
|
||||
variable, suffix = self.objectspace.paths.get_with_dynamic(
|
||||
value.variable, value.path_prefix, family.path, value.version, value.namespace, value.xmlfiles
|
||||
if isinstance(value, (VariableCalculation, VariablePropertyCalculation)):
|
||||
variable, identifier = self.objectspace.paths.get_with_dynamic(
|
||||
value.variable,
|
||||
value.path_prefix,
|
||||
family.path,
|
||||
value.version,
|
||||
value.namespace,
|
||||
value.xmlfiles,
|
||||
)
|
||||
values = self.objectspace.informations.get(variable.path).get('test', None)
|
||||
values = self.get_examples_values(variable)
|
||||
if values:
|
||||
if inside_list:
|
||||
default_values = list(values)
|
||||
|
@ -81,11 +103,12 @@ class Annotator(Walk):
|
|||
else:
|
||||
for value in family.dynamic:
|
||||
self.add_default_value(family, value, inside_list=True)
|
||||
self.calculation_to_information(family.path,
|
||||
'dynamic',
|
||||
family.dynamic,
|
||||
family.version,
|
||||
)
|
||||
self.calculation_to_information(
|
||||
family.path,
|
||||
"dynamic",
|
||||
family.dynamic,
|
||||
family.version,
|
||||
)
|
||||
|
||||
def populate_variable(self) -> None:
|
||||
"""convert variables"""
|
||||
|
@ -93,29 +116,31 @@ class Annotator(Walk):
|
|||
if variable.type == "symlink":
|
||||
continue
|
||||
if variable.type == "choice":
|
||||
self.calculation_to_information(variable.path,
|
||||
'choice',
|
||||
variable.choices,
|
||||
variable.version,
|
||||
)
|
||||
self.calculation_to_information(variable.path,
|
||||
'default',
|
||||
variable.default,
|
||||
variable.version,
|
||||
)
|
||||
self.calculation_to_information(variable.path,
|
||||
'validators',
|
||||
variable.validators,
|
||||
variable.version,
|
||||
)
|
||||
if variable.path in self.objectspace.leaders and \
|
||||
not variable.default:
|
||||
values = self.objectspace.informations.get(variable.path).get('test', None)
|
||||
self.calculation_to_information(
|
||||
variable.path,
|
||||
"choice",
|
||||
variable.choices,
|
||||
variable.version,
|
||||
)
|
||||
self.calculation_to_information(
|
||||
variable.path,
|
||||
"default",
|
||||
variable.default,
|
||||
variable.version,
|
||||
)
|
||||
self.calculation_to_information(
|
||||
variable.path,
|
||||
"validators",
|
||||
variable.validators,
|
||||
variable.version,
|
||||
)
|
||||
if variable.path in self.objectspace.leaders and not variable.default:
|
||||
values = self.get_examples_values(variable)
|
||||
if values:
|
||||
variable.default = list(values)
|
||||
else:
|
||||
variable.default = [CONVERT_OPTION[variable.type]['example']]
|
||||
self.objectspace.informations.add(variable.path, 'fake_default', True)
|
||||
variable.default = [CONVERT_OPTION[variable.type]["example"]]
|
||||
self.objectspace.informations.add(variable.path, "fake_default", True)
|
||||
self.objectspace.informations.add(
|
||||
variable.path, "dictionaries", variable.xmlfiles
|
||||
)
|
||||
|
@ -126,58 +151,64 @@ class Annotator(Walk):
|
|||
variable: dict,
|
||||
) -> None:
|
||||
"""convert properties"""
|
||||
for prop in ['hidden', 'disabled', 'mandatory']:
|
||||
for prop in ["hidden", "disabled", "mandatory"]:
|
||||
prop_value = getattr(variable, prop, None)
|
||||
if not prop_value:
|
||||
continue
|
||||
self.calculation_to_information(variable.path,
|
||||
prop,
|
||||
prop_value,
|
||||
variable.version,
|
||||
)
|
||||
self.calculation_to_information(
|
||||
variable.path,
|
||||
prop,
|
||||
prop_value,
|
||||
variable.version,
|
||||
)
|
||||
|
||||
def calculation_to_information(self,
|
||||
path: str,
|
||||
prop: str,
|
||||
values,
|
||||
version: str,
|
||||
):
|
||||
self._calculation_to_information(path,
|
||||
prop,
|
||||
values,
|
||||
version,
|
||||
)
|
||||
def calculation_to_information(
|
||||
self,
|
||||
path: str,
|
||||
prop: str,
|
||||
values,
|
||||
version: str,
|
||||
):
|
||||
self._calculation_to_information(
|
||||
path,
|
||||
prop,
|
||||
values,
|
||||
version,
|
||||
)
|
||||
if isinstance(values, list):
|
||||
for idx, val in enumerate(values):
|
||||
self._calculation_to_information(path,
|
||||
prop,
|
||||
val,
|
||||
version,
|
||||
suffix=f'_{idx}',
|
||||
)
|
||||
self._calculation_to_information(
|
||||
path,
|
||||
prop,
|
||||
val,
|
||||
version,
|
||||
identifier=f"_{idx}",
|
||||
)
|
||||
|
||||
def _calculation_to_information(self,
|
||||
path: str,
|
||||
prop: str,
|
||||
values,
|
||||
version: str,
|
||||
*,
|
||||
suffix: str='',
|
||||
):
|
||||
if not isinstance(values, Calculation):
|
||||
def _calculation_to_information(
|
||||
self,
|
||||
path: str,
|
||||
prop: str,
|
||||
values,
|
||||
version: str,
|
||||
*,
|
||||
identifier: str = "",
|
||||
):
|
||||
if not isinstance(values, Calculation):
|
||||
return
|
||||
values_calculation = True
|
||||
if isinstance(values, JinjaCalculation):
|
||||
if values.description:
|
||||
values_calculation = values.description
|
||||
values_calculation_type = 'jinja'
|
||||
elif isinstance(values, VariableCalculation):
|
||||
values_calculation_type = "jinja"
|
||||
elif isinstance(values, (VariableCalculation, VariablePropertyCalculation)):
|
||||
values_calculation = values.variable
|
||||
paths = self.objectspace.paths
|
||||
if version != '1.0' and paths.regexp_relative.search(values_calculation):
|
||||
calculation_path = paths.get_relative_path(values_calculation,
|
||||
path,
|
||||
)
|
||||
if version != "1.0" and paths.regexp_relative.search(values_calculation):
|
||||
calculation_path = paths.get_full_path(
|
||||
values_calculation,
|
||||
path,
|
||||
)
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
if values.when is not undefined:
|
||||
values_calculation = f'when the variable "{calculation_path}" has the value "{values.when}"'
|
||||
|
@ -187,18 +218,27 @@ class Annotator(Walk):
|
|||
values_calculation = f'when the variable "{calculation_path}" has the value "True"'
|
||||
else:
|
||||
values_calculation = calculation_path
|
||||
values_calculation_type = 'variable'
|
||||
values_calculation_type = "variable"
|
||||
elif isinstance(values, InformationCalculation):
|
||||
values_calculation_type = 'information'
|
||||
elif isinstance(values, SuffixCalculation):
|
||||
values_calculation_type = 'suffix'
|
||||
values_calculation_type = "information"
|
||||
elif isinstance(values, (IdentifierCalculation, IdentifierPropertyCalculation)):
|
||||
if version != "1.0" and prop in PROPERTY_ATTRIBUTE:
|
||||
if values.when is not undefined:
|
||||
values_calculation = f'when the identifier is "{values.when}"'
|
||||
elif values.when_not is not undefined:
|
||||
values_calculation = (
|
||||
f'when the identifier is not "{values.when_not}"'
|
||||
)
|
||||
values_calculation_type = "identifier"
|
||||
elif isinstance(values, IndexCalculation):
|
||||
values_calculation_type = 'index'
|
||||
self.objectspace.informations.add(path,
|
||||
f'{prop}_calculation_type{suffix}',
|
||||
values_calculation_type,
|
||||
)
|
||||
self.objectspace.informations.add(path,
|
||||
f'{prop}_calculation{suffix}',
|
||||
values_calculation,
|
||||
)
|
||||
values_calculation_type = "index"
|
||||
self.objectspace.informations.add(
|
||||
path,
|
||||
f"{prop}_calculation_type{identifier}",
|
||||
values_calculation_type,
|
||||
)
|
||||
self.objectspace.informations.add(
|
||||
path,
|
||||
f"{prop}_calculation{identifier}",
|
||||
values_calculation,
|
||||
)
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
"""
|
||||
Cli code for Rougail-output-doc
|
||||
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
|
||||
distribued with GPL-2 or later license
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
"""
|
||||
from . import RougailOutputDoc
|
||||
|
||||
|
||||
def run(rougailconfig,
|
||||
config,
|
||||
user_data,
|
||||
):
|
||||
inventory = RougailOutputDoc(config=config,
|
||||
rougailconfig=rougailconfig,
|
||||
)
|
||||
print(inventory.gen_doc())
|
||||
|
||||
|
||||
__all__ = ('run',)
|
|
@ -4,43 +4,42 @@ Config file for Rougail-doc
|
|||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
|
||||
distribued with GPL-2 or later license
|
||||
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 free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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.
|
||||
|
||||
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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
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 pathlib import Path
|
||||
from rougail.utils import load_modules
|
||||
# from .utils import _
|
||||
|
||||
|
||||
OUTPUTS = None
|
||||
|
||||
|
||||
def get_outputs() -> None:
|
||||
module_name = 'rougail.doc.output'
|
||||
module_name = "rougail.doc.output"
|
||||
outputs = {}
|
||||
for path in (Path(__file__).parent / 'output').iterdir():
|
||||
for path in (Path(__file__).parent / "output").iterdir():
|
||||
name = path.name
|
||||
if not name.endswith(".py") or name.endswith("__.py"):
|
||||
continue
|
||||
module = load_modules(module_name + '.' + name, str(path))
|
||||
module = load_modules(module_name + "." + name, str(path))
|
||||
if "Formater" not in dir(module):
|
||||
continue
|
||||
level = module.Formater.level
|
||||
if level in outputs:
|
||||
raise Exception(f'duplicated level rougail-doc for output "{level}": {module.Formater.name} and {outputs[level].name}')
|
||||
raise Exception(
|
||||
f'duplicated level rougail-doc for output "{level}": {module.Formater.name} and {outputs[level].name}'
|
||||
)
|
||||
outputs[module.Formater.level] = module.Formater
|
||||
return {outputs[level].name: outputs[level] for level in sorted(outputs)}
|
||||
|
||||
|
@ -59,9 +58,10 @@ class OutPuts: # pylint: disable=R0903
|
|||
return OUTPUTS
|
||||
|
||||
|
||||
def get_rougail_config(*,
|
||||
backward_compatibility=True,
|
||||
) -> dict:
|
||||
def get_rougail_config(
|
||||
*,
|
||||
backward_compatibility=True,
|
||||
) -> dict:
|
||||
outputs = list(OutPuts().get())
|
||||
output_format_default = outputs[0]
|
||||
rougail_options = """
|
||||
|
@ -77,20 +77,28 @@ doc:
|
|||
description: Start title level
|
||||
alternative_name: dt
|
||||
default: 1
|
||||
with_example:
|
||||
description: Display example in documentation
|
||||
negative_description: Hide example in documentation
|
||||
alternative_name: de
|
||||
default: false
|
||||
output_format:
|
||||
description: Generate document in format
|
||||
alternative_name: do
|
||||
default: output_format_default
|
||||
choices:
|
||||
""".replace('output_format_default', output_format_default)
|
||||
""".replace(
|
||||
"output_format_default", output_format_default
|
||||
)
|
||||
for output in outputs:
|
||||
rougail_options += f" - {output}\n"
|
||||
return {'name': 'doc',
|
||||
'process': 'output',
|
||||
'options': rougail_options,
|
||||
'allow_user_data': False,
|
||||
'level': 50,
|
||||
}
|
||||
return {
|
||||
"name": "doc",
|
||||
"process": "output",
|
||||
"options": rougail_options,
|
||||
"allow_user_data": False,
|
||||
"level": 50,
|
||||
}
|
||||
|
||||
|
||||
__all__ = ("OutPuts", 'get_rougail_config')
|
||||
__all__ = ("OutPuts", "get_rougail_config")
|
||||
|
|
|
@ -2,24 +2,16 @@
|
|||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
|
||||
distribued with GPL-2 or later license
|
||||
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 free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 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.
|
||||
|
||||
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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
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/>.
|
||||
"""
|
||||
|
||||
|
||||
def echo(msg):
|
||||
return msg
|
||||
_ = echo
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
|
||||
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 io import BytesIO
|
||||
from typing import List
|
||||
from itertools import chain
|
||||
|
@ -5,7 +23,7 @@ from ruamel.yaml import YAML
|
|||
|
||||
|
||||
class Formater:
|
||||
name = 'asciidoc'
|
||||
name = "asciidoc"
|
||||
level = 40
|
||||
|
||||
def __init__(self):
|
||||
|
@ -13,12 +31,13 @@ class Formater:
|
|||
self._yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
|
||||
def header(self):
|
||||
return ''
|
||||
return ""
|
||||
|
||||
def title(self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
char = "="
|
||||
return f"{char * (level + 1)} {title}\n\n"
|
||||
|
||||
|
@ -30,79 +49,91 @@ class Formater:
|
|||
stable = table.split("\n", 1)
|
||||
return stable[0].replace("<", "a") + "\n" + stable[1]
|
||||
|
||||
def link(self,
|
||||
comment: str,
|
||||
link: str,
|
||||
) -> str:
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
) -> str:
|
||||
return f"`{link}[{comment}]`"
|
||||
|
||||
def prop(self,
|
||||
prop: str,
|
||||
) -> str:
|
||||
return f'`{prop}`'
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
) -> str:
|
||||
return f"`{prop}`"
|
||||
|
||||
def list(self,
|
||||
choices: list,
|
||||
) -> str:
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
) -> str:
|
||||
prefix = "\n\n* "
|
||||
char = "\n* "
|
||||
return prefix + char.join([self.dump(choice) for choice in choices])
|
||||
|
||||
def is_list(self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
return txt.startswith('* ')
|
||||
def is_list(
|
||||
self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
return txt.startswith("* ")
|
||||
|
||||
def columns(self,
|
||||
col1: List[str],
|
||||
col2: List[str],
|
||||
) -> None:
|
||||
def columns(
|
||||
self,
|
||||
col1: List[str],
|
||||
col2: List[str],
|
||||
) -> None:
|
||||
self.max_line = 0
|
||||
for params in chain(col1, col2):
|
||||
for param in params.split('\n'):
|
||||
for param in params.split("\n"):
|
||||
self.max_line = max(self.max_line, len(param))
|
||||
self.max_line += 1
|
||||
|
||||
def join(self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
string = ""
|
||||
previous = ''
|
||||
previous = ""
|
||||
for line in lst:
|
||||
if string:
|
||||
if self.is_list(previous.split('\n')[-1]):
|
||||
if self.is_list(previous.split("\n")[-1]):
|
||||
string += "\n\n"
|
||||
else:
|
||||
string += " +\n"
|
||||
string += line
|
||||
|
||||
|
||||
previous = line
|
||||
return "\n" + string
|
||||
|
||||
def to_string(self,
|
||||
text: str,
|
||||
) -> str:
|
||||
def to_string(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
return text
|
||||
|
||||
def table_header(self,
|
||||
lst,
|
||||
):
|
||||
return lst[0] + " " * (self.max_line - len(lst[0])), lst[1] + " " * (self.max_line - len(lst[1]))
|
||||
def table_header(
|
||||
self,
|
||||
lst,
|
||||
):
|
||||
return lst[0] + " " * (self.max_line - len(lst[0])), lst[1] + " " * (
|
||||
self.max_line - len(lst[1])
|
||||
)
|
||||
|
||||
def bold(self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
return f"**{msg}**"
|
||||
|
||||
def italic(self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
def italic(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
return f"_{msg}_"
|
||||
|
||||
def dump(self, dico):
|
||||
with BytesIO() as ymlfh:
|
||||
self._yaml.dump(dico, ymlfh)
|
||||
ret = ymlfh.getvalue().decode('utf-8').strip()
|
||||
if ret.endswith('...'):
|
||||
ret = ymlfh.getvalue().decode("utf-8").strip()
|
||||
if ret.endswith("..."):
|
||||
ret = ret[:-3].strip()
|
||||
return ret
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
|
||||
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 io import BytesIO
|
||||
from typing import List
|
||||
from itertools import chain
|
||||
|
@ -5,7 +23,7 @@ from ruamel.yaml import YAML
|
|||
|
||||
|
||||
class Formater:
|
||||
name = 'github'
|
||||
name = "github"
|
||||
level = 50
|
||||
|
||||
def __init__(self):
|
||||
|
@ -15,14 +33,15 @@ class Formater:
|
|||
|
||||
def header(self):
|
||||
if self.header_setted:
|
||||
return ''
|
||||
return ""
|
||||
self.header_setted = True
|
||||
return "---\ngitea: none\ninclude_toc: true\n---\n"
|
||||
|
||||
def title(self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
char = "#"
|
||||
return f"{char * level} {title}\n\n"
|
||||
|
||||
|
@ -32,67 +51,77 @@ class Formater:
|
|||
def table(self, table):
|
||||
return table
|
||||
|
||||
def link(self,
|
||||
comment: str,
|
||||
link: str,
|
||||
) -> str:
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
) -> str:
|
||||
return f"[`{comment}`]({link})"
|
||||
|
||||
def prop(self,
|
||||
prop: str,
|
||||
) -> str:
|
||||
return f'`{prop}`'
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
) -> str:
|
||||
return f"`{prop}`"
|
||||
|
||||
def list(self,
|
||||
choices,
|
||||
):
|
||||
def list(
|
||||
self,
|
||||
choices,
|
||||
):
|
||||
prefix = "<br/>- "
|
||||
char = "<br/>- "
|
||||
return prefix + char.join([self.dump(choice) for choice in choices])
|
||||
|
||||
def is_list(self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
return txt.startswith('* ')
|
||||
|
||||
def columns(self,
|
||||
col1: List[str],
|
||||
col2: List[str],
|
||||
) -> None:
|
||||
def is_list(
|
||||
self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
return txt.startswith("* ")
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col1: List[str],
|
||||
col2: List[str],
|
||||
) -> None:
|
||||
self.max_line = 0
|
||||
for params in chain(col1, col2):
|
||||
for param in params.split('\n'):
|
||||
for param in params.split("\n"):
|
||||
self.max_line = max(self.max_line, len(param))
|
||||
self.max_line += 1
|
||||
|
||||
def join(self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
return "<br/>".join(lst)
|
||||
|
||||
def to_string(self,
|
||||
text: str,
|
||||
) -> str:
|
||||
return text.strip().replace('\n', '<br/>')
|
||||
def to_string(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
return text.strip().replace("\n", "<br/>")
|
||||
|
||||
def table_header(self,
|
||||
lst):
|
||||
return lst[0] + " " * (self.max_line - len(lst[0])), lst[1] + " " * (self.max_line - len(lst[1]))
|
||||
def table_header(self, lst):
|
||||
return lst[0] + " " * (self.max_line - len(lst[0])), lst[1] + " " * (
|
||||
self.max_line - len(lst[1])
|
||||
)
|
||||
|
||||
def bold(self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
return f"**{msg}**"
|
||||
|
||||
def italic(self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
def italic(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
return f"*{msg}*"
|
||||
|
||||
def dump(self, dico):
|
||||
with BytesIO() as ymlfh:
|
||||
self._yaml.dump(dico, ymlfh)
|
||||
ret = ymlfh.getvalue().decode('utf-8').strip()
|
||||
if ret.endswith('...'):
|
||||
ret = ymlfh.getvalue().decode("utf-8").strip()
|
||||
if ret.endswith("..."):
|
||||
ret = ret[:-3].strip()
|
||||
return ret
|
||||
|
|
Loading…
Reference in a new issue