feat: changelog for variables

This commit is contained in:
egarette@silique.fr 2025-10-14 12:58:39 +02:00
parent da1519071e
commit 641ab723e0
3214 changed files with 28083 additions and 11090 deletions

View file

@ -5,8 +5,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2025-10-02 08:30+0200\n"
"PO-Revision-Date: 2025-10-02 08:31+0200\n"
"POT-Creation-Date: 2025-10-14 12:54+0200\n"
"PO-Revision-Date: 2025-10-14 12:57+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
@ -16,170 +16,194 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.7\n"
#: src/rougail/output_doc/annotator.py:309
#: src/rougail/output_doc/annotator.py:323
msgid "the value of the information \"{0}\" of the variable \"{1}\""
msgstr "la valeur de l'information \"{0}\" de la variable \"{1}\""
#: src/rougail/output_doc/annotator.py:312
#: src/rougail/output_doc/annotator.py:326
msgid "the value of the global information \"{0}\""
msgstr "la valeur de l'information globale \"{0}\""
#: src/rougail/output_doc/annotator.py:319
#: src/rougail/output_doc/annotator.py:333
msgid "when the identifier is \"{0}\""
msgstr "lorsque l'identifiant est \"{0}\""
#: src/rougail/output_doc/annotator.py:321
#: src/rougail/output_doc/annotator.py:335
msgid "when the identifier is not \"{0}\""
msgstr "lorsque l'identifiant n'est pas \"{0}\""
#: src/rougail/output_doc/config.py:42
#: src/rougail/output_doc/changelog.py:114
msgid "New variable"
msgstr "Nouvelle variable"
#: src/rougail/output_doc/changelog.py:116
msgid "New variables"
msgstr "Nouvelles variables"
#: src/rougail/output_doc/changelog.py:120
msgid "Modified variable"
msgstr "Variable modifiée"
#: src/rougail/output_doc/changelog.py:122
msgid "Modified variables"
msgstr "Variables modifiées"
#: src/rougail/output_doc/changelog.py:126
msgid "Deleted variable"
msgstr "Variable supprimée"
#: src/rougail/output_doc/changelog.py:128
msgid "Deleted variables"
msgstr "Variables supprimées"
#: src/rougail/output_doc/config.py:43
msgid "duplicated level rougail-doc for output \"{0}\": {1} and {2}"
msgstr "niveau dupliqué pour rougail-doc pour la sortie \"{0}\": {1} et {2}"
#: src/rougail/output_doc/config.py:74
#: src/rougail/output_doc/config.py:75
msgid "Configuration rougail-doc"
msgstr "Configuration de rougail-doc"
#: src/rougail/output_doc/config.py:82
#: src/rougail/output_doc/config.py:83
msgid "Starting title level"
msgstr "Niveau de titre de départ"
#: src/rougail/output_doc/config.py:87
msgid "Generate example"
msgstr "Génération de l'exemple"
#: src/rougail/output_doc/config.py:88
msgid "Generated content"
msgstr "Contenu générer"
#: src/rougail/output_doc/config.py:92
#: src/rougail/output_doc/config.py:97
msgid "Previous description file in JSON format"
msgstr "Précédent fichier de description au format JSON"
#: src/rougail/output_doc/config.py:105
msgid "Do not add families in documentation"
msgstr "Ne pas ajouter les familles dans la documentation"
#: src/rougail/output_doc/config.py:96
#: src/rougail/output_doc/config.py:114
msgid "Disable documentation for variables with those modes"
msgstr "Désactiver la documentation des variables avec ces modes"
#: src/rougail/output_doc/config.py:104
#: src/rougail/output_doc/config.py:122
msgid "disabled when there is no mode available"
msgstr "désactiver lorsqu'il n'y a pas de mode valable"
#: src/rougail/output_doc/config.py:110
#: src/rougail/output_doc/config.py:128
msgid "verify if disable modes already exists"
msgstr "vérifier le mode existe déjà"
#: src/rougail/output_doc/config.py:113
#: src/rougail/output_doc/config.py:130
msgid "Modify values to document leaderships and dynamics families"
msgstr "Valeurs modifiées pour documenter les familles leader ou dynamique"
#: src/rougail/output_doc/config.py:117
#: src/rougail/output_doc/config.py:133
msgid "Generate document in format"
msgstr "Générer le document au format"
#: src/rougail/output_doc/doc.py:332
#: src/rougail/output_doc/doc.py:326
msgid "This family contains lists of variable blocks."
msgstr "Cette famille contient des listes de bloc de variable."
#: src/rougail/output_doc/doc.py:340
#: src/rougail/output_doc/doc.py:336
msgid "This family builds families dynamically."
msgstr "Cette famille construit des familles dynamiquement."
#: src/rougail/output_doc/doc.py:354
#: src/rougail/output_doc/doc.py:350
msgid "Default"
msgstr "Défaut"
#: src/rougail/output_doc/doc.py:372
#: src/rougail/output_doc/doc.py:365
msgid "multiple"
msgstr "multiple"
#: src/rougail/output_doc/doc.py:380
#: src/rougail/output_doc/doc.py:373
msgid "Example"
msgstr "Exemple"
#: src/rougail/output_doc/doc.py:383
#: src/rougail/output_doc/doc.py:376
msgid "Examples"
msgstr "Exemples"
#: src/rougail/output_doc/doc.py:401
#: src/rougail/output_doc/doc.py:394
msgid "No attribute \"description\" for \"{0}\" in {1}"
msgstr "Aucun attribut \"description\" pour \"{0}\" dans {1}"
#: src/rougail/output_doc/doc.py:524
#: src/rougail/output_doc/doc.py:531
msgid "text based with regular expressions \"{0}\""
msgstr "texte avec expression rationnelle \"{0}\""
#: src/rougail/output_doc/doc.py:530
#: src/rougail/output_doc/doc.py:537
msgid "Validator"
msgstr "Validateur"
#: src/rougail/output_doc/doc.py:533
#: src/rougail/output_doc/doc.py:540
msgid "Validators"
msgstr "Validateurs"
#: src/rougail/output_doc/doc.py:546
msgid "(default)"
msgstr "(défaut)"
#: src/rougail/output_doc/doc.py:551
#: src/rougail/output_doc/doc.py:549
msgid "Choices"
msgstr "Choix"
#: src/rougail/output_doc/doc.py:640
msgid "depends on a calculation"
msgstr "dépend d'un calcul"
#: src/rougail/output_doc/doc.py:646
msgid "\"{0}\" is a calculation for {1} but has no description in {2}"
msgstr "\"{0}\" est un calcul pour {1} mais n'a pas de description dans {2}"
#: src/rougail/output_doc/doc.py:669 src/rougail/output_doc/doc.py:767
msgid "depends on an undocumented variable"
msgstr "dépends d'une variable non documentée"
#: src/rougail/output_doc/doc.py:672
msgid "when the variable \"{0}\" hasn't the value \"{1}\""
msgstr "lorsque la variable \"{0}\" n'a pas la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:674
msgid "when the variable \"{0}\" is defined and hasn't the value \"{1}\""
msgstr "lorsque la variable \"{0}\" est définie et n'a pas la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:677
msgid "when the variable \"{0}\" has the value \"{1}\""
msgstr "lorsque la variable \"{0}\" a la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:679
msgid "when the variable \"{0}\" is defined and has the value \"{1}\""
msgstr "lorsque la variable \"{0}\" est définie et a la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:695
msgid "the value of the variable \"{0}\""
msgstr "la valeur de la variable \"{0}\""
#: src/rougail/output_doc/doc.py:697
msgid "the value of the variable \"{0}\" if it is defined"
msgstr "la valeur de la variable \"{0}\" si elle est définie"
#: src/rougail/output_doc/doc.py:699
msgid "the value of an undocumented variable"
msgstr "la valeur d'une variable non documentée"
#: src/rougail/output_doc/doc.py:737
msgid "the values of undocumented variables"
msgstr "les valeurs de variables non documentées"
#: src/rougail/output_doc/doc.py:757
msgid "(from an undocumented variable){0}"
msgstr "(issue d'une variable non documentée){0}"
#: src/rougail/output_doc/doc.py:763
msgid "{0} (from an undocumented variable)"
msgstr "{0} (issue d'une variable non documentée)"
#: src/rougail/output_doc/doc.py:776
#: src/rougail/output_doc/doc.py:652
msgid "the value of the identifier"
msgstr "la valeur de l'identifiant"
#: src/rougail/output_doc/doc.py:780
#: src/rougail/output_doc/doc.py:656
msgid "the value of the {0}"
msgstr "la valeur de l'{0}"
#: src/rougail/output_doc/doc.py:665
msgid "depends on a calculation"
msgstr "dépend d'un calcul"
#: src/rougail/output_doc/doc.py:671
msgid "\"{0}\" is a calculation for {1} but has no description in {2}"
msgstr "\"{0}\" est un calcul pour {1} mais n'a pas de description dans {2}"
#: src/rougail/output_doc/doc.py:697 src/rougail/output_doc/doc.py:799
msgid "depends on an undocumented variable"
msgstr "dépends d'une variable non documentée"
#: src/rougail/output_doc/doc.py:708
msgid "when the variable \"{0}\" hasn't the value \"{1}\""
msgstr "lorsque la variable \"{0}\" n'a pas la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:710
msgid "when the variable \"{0}\" is defined and hasn't the value \"{1}\""
msgstr "lorsque la variable \"{0}\" est définie et n'a pas la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:713
msgid "when the variable \"{0}\" has the value \"{1}\""
msgstr "lorsque la variable \"{0}\" a la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:715
msgid "when the variable \"{0}\" is defined and has the value \"{1}\""
msgstr "lorsque la variable \"{0}\" est définie et a la valeur \"{1}\""
#: src/rougail/output_doc/doc.py:731
msgid "the value of the variable \"{0}\""
msgstr "la valeur de la variable \"{0}\""
#: src/rougail/output_doc/doc.py:733
msgid "the value of the variable \"{0}\" if it is defined"
msgstr "la valeur de la variable \"{0}\" si elle est définie"
#: src/rougail/output_doc/doc.py:734
msgid "the value of an undocumented variable"
msgstr "la valeur d'une variable non documentée"
#: src/rougail/output_doc/doc.py:770
msgid "the values of undocumented variables"
msgstr "les valeurs de variables non documentées"
#: src/rougail/output_doc/doc.py:789
msgid "(from an undocumented variable)"
msgstr "(issue d'une variable non documentée)"
#: src/rougail/output_doc/doc.py:795
msgid "{0} (from an undocumented variable)"
msgstr "{0} (issue d'une variable non documentée)"
#: src/rougail/output_doc/example.py:37
msgid "Example with mandatory variables not filled in"
msgstr "Exemple avec des variables obligatoire non renseignée"
@ -188,13 +212,13 @@ msgstr "Exemple avec des variables obligatoire non renseignée"
msgid "Example with all variables modifiable"
msgstr "Exemple avec toutes les variables modifiable"
#: src/rougail/output_doc/output/console.py:145
#: src/rougail/output_doc/utils.py:437
#: src/rougail/output_doc/output/console.py:160
#: src/rougail/output_doc/utils.py:657
msgid "Variable"
msgstr "Variable"
#: src/rougail/output_doc/output/console.py:146
#: src/rougail/output_doc/utils.py:437
#: src/rougail/output_doc/output/console.py:161
#: src/rougail/output_doc/utils.py:657
msgid "Description"
msgstr "Description"
@ -202,120 +226,126 @@ msgstr "Description"
msgid "Informations"
msgstr "Informations"
#: src/rougail/output_doc/utils.py:41
#: src/rougail/output_doc/utils.py:44
msgid "the domain name can starts by a dot"
msgstr "le nom de domaine peut commencer par un point"
#: src/rougail/output_doc/utils.py:42
#: src/rougail/output_doc/utils.py:45
msgid "the domain name can be a hostname"
msgstr "le nom de domaine peut être un nom d'hôte"
#: src/rougail/output_doc/utils.py:43
#: src/rougail/output_doc/utils.py:46
msgid "the domain name can be an IP"
msgstr "le nom de domaine peut être une IP"
#: src/rougail/output_doc/utils.py:44
#: src/rougail/output_doc/utils.py:47
msgid "the domain name can be network in CIDR format"
msgstr "le nom de domaine peut être un réseau au format CIDR"
#: src/rougail/output_doc/utils.py:49 src/rougail/output_doc/utils.py:55
#: src/rougail/output_doc/utils.py:52 src/rougail/output_doc/utils.py:58
msgid "the minimum value is {0}"
msgstr "le valeur minimal est {0}"
#: src/rougail/output_doc/utils.py:50 src/rougail/output_doc/utils.py:56
#: src/rougail/output_doc/utils.py:53 src/rougail/output_doc/utils.py:59
msgid "the maximum value is {0}"
msgstr "le valeur maximal est {0}"
#: src/rougail/output_doc/utils.py:62
#: src/rougail/output_doc/utils.py:65
msgid "IP must be in CIDR format"
msgstr "IP doit être au format CIDR"
#: src/rougail/output_doc/utils.py:63
#: src/rougail/output_doc/utils.py:66
msgid "private IP are allowed"
msgstr "les IP privées sont autorisés"
#: src/rougail/output_doc/utils.py:64
#: src/rougail/output_doc/utils.py:67
msgid "reserved IP are allowed"
msgstr "les IP réservés sont autorisés"
#: src/rougail/output_doc/utils.py:69
#: src/rougail/output_doc/utils.py:72
msgid "network must be in CIDR format"
msgstr "réseau doit être au format CIDR"
#: src/rougail/output_doc/utils.py:74
#: src/rougail/output_doc/utils.py:77
msgid "the host name can be an IP"
msgstr "le nom d'hôte peut être une IP"
#: src/rougail/output_doc/utils.py:79
#: src/rougail/output_doc/utils.py:82
msgid "the domain name in web address can be an IP"
msgstr "le nom de domaine dans l'adresse web peut être une IP"
#: src/rougail/output_doc/utils.py:80
#: src/rougail/output_doc/utils.py:83
msgid "the domain name in web address can be only a hostname"
msgstr "le nom de domaine dans l'adresse web ne peut être qu'un nom d'hôte"
#: src/rougail/output_doc/utils.py:87
#: src/rougail/output_doc/utils.py:90
msgid "can be range of port"
msgstr "peut être un range de port"
#: src/rougail/output_doc/utils.py:88
#: src/rougail/output_doc/utils.py:91
msgid "can have the protocol"
msgstr "peut avoir un protocole"
#: src/rougail/output_doc/utils.py:89
#: src/rougail/output_doc/utils.py:92
msgid "port 0 is allowed"
msgstr "le port 0 est autorisé"
#: src/rougail/output_doc/utils.py:90
#: src/rougail/output_doc/utils.py:93
msgid "well-known ports (1 to 1023) are allowed"
msgstr "les ports connus (de 1 à 1023) sont autorisés"
#: src/rougail/output_doc/utils.py:91
#: src/rougail/output_doc/utils.py:94
msgid "registred ports (1024 to 49151) are allowed"
msgstr "les ports enregistrés (de 1024 à 49151) sont autorisés"
#: src/rougail/output_doc/utils.py:92
#: src/rougail/output_doc/utils.py:95
msgid "private ports (greater than 49152) are allowed"
msgstr "les ports privés (supérieurs à 49152) sont autorisés"
#: src/rougail/output_doc/utils.py:97
#: src/rougail/output_doc/utils.py:100
msgid "minimum length for the secret is {0} characters"
msgstr "longueur minimum pour le secret est de {0} caractères"
#: src/rougail/output_doc/utils.py:98
#: src/rougail/output_doc/utils.py:101
msgid "maximum length for the secret is {0} characters"
msgstr "longueur maximal pour le secret est de {0} caractères"
#: src/rougail/output_doc/utils.py:99
#: src/rougail/output_doc/utils.py:102
msgid "forbidden characters: {0}"
msgstr "caractères interdits: {0}"
#: src/rougail/output_doc/utils.py:104
#: src/rougail/output_doc/utils.py:107
msgid "this filename could be a relative path"
msgstr "ce nom de fichier peut être un chemin relative"
#: src/rougail/output_doc/utils.py:105
#: src/rougail/output_doc/utils.py:108
msgid "this file must exists"
msgstr "ce fichier doit exister"
#: src/rougail/output_doc/utils.py:106
#: src/rougail/output_doc/utils.py:109
msgid "file type allowed: {0}"
msgstr "type de fichier autorisé : {0}"
#: src/rougail/output_doc/utils.py:277
#: src/rougail/output_doc/utils.py:312
msgid "Variables for \"{0}\""
msgstr "Variables pour \"{0}\""
#: src/rougail/output_doc/utils.py:305
#: src/rougail/output_doc/utils.py:336
msgid "Identifiers"
msgstr "Identifiants"
#: src/rougail/output_doc/utils.py:458
#: src/rougail/output_doc/utils.py:561 src/rougail/output_doc/utils.py:568
#: src/rougail/output_doc/utils.py:572 src/rougail/output_doc/utils.py:574
#: src/rougail/output_doc/utils.py:576
msgid "(default)"
msgstr "(défaut)"
#: src/rougail/output_doc/utils.py:697
msgid "{0}: {1}"
msgstr "{0} : {1}"
#~ msgid "Generate documentation"
#~ msgstr "Générer de la documentation"
#~ msgid "Generate example"
#~ msgstr "Génération de l'exemple"
#~ msgid "Add families in documentation"
#~ msgstr "Ajouter les familles dans la documentation"
@ -326,9 +356,6 @@ msgstr "{0} : {1}"
#~ msgid "Hide example in documentation"
#~ msgstr "Cacher l'exemple dans la documentation"
#~ msgid "Variables"
#~ msgstr "Variables"
#, fuzzy
#~| msgid ":"
#~ msgid ": "

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-10-04 16:05+0200\n"
"POT-Creation-Date: 2025-10-14 12:57+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,167 +15,191 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
#: src/rougail/output_doc/annotator.py:309
#: src/rougail/output_doc/annotator.py:323
msgid "the value of the information \"{0}\" of the variable \"{1}\""
msgstr ""
#: src/rougail/output_doc/annotator.py:312
#: src/rougail/output_doc/annotator.py:326
msgid "the value of the global information \"{0}\""
msgstr ""
#: src/rougail/output_doc/annotator.py:319
#: src/rougail/output_doc/annotator.py:333
msgid "when the identifier is \"{0}\""
msgstr ""
#: src/rougail/output_doc/annotator.py:321
#: src/rougail/output_doc/annotator.py:335
msgid "when the identifier is not \"{0}\""
msgstr ""
#: src/rougail/output_doc/config.py:42
#: src/rougail/output_doc/changelog.py:114
msgid "New variable"
msgstr ""
#: src/rougail/output_doc/changelog.py:116
msgid "New variables"
msgstr ""
#: src/rougail/output_doc/changelog.py:120
msgid "Modified variable"
msgstr ""
#: src/rougail/output_doc/changelog.py:122
msgid "Modified variables"
msgstr ""
#: src/rougail/output_doc/changelog.py:126
msgid "Deleted variable"
msgstr ""
#: src/rougail/output_doc/changelog.py:128
msgid "Deleted variables"
msgstr ""
#: src/rougail/output_doc/config.py:43
msgid "duplicated level rougail-doc for output \"{0}\": {1} and {2}"
msgstr ""
#: src/rougail/output_doc/config.py:74
#: src/rougail/output_doc/config.py:75
msgid "Configuration rougail-doc"
msgstr ""
#: src/rougail/output_doc/config.py:82
#: src/rougail/output_doc/config.py:83
msgid "Starting title level"
msgstr ""
#: src/rougail/output_doc/config.py:87
msgid "Generate example"
#: src/rougail/output_doc/config.py:88
msgid "Generated content"
msgstr ""
#: src/rougail/output_doc/config.py:92
#: src/rougail/output_doc/config.py:97
msgid "Previous description file in JSON format"
msgstr ""
#: src/rougail/output_doc/config.py:105
msgid "Do not add families in documentation"
msgstr ""
#: src/rougail/output_doc/config.py:96
#: src/rougail/output_doc/config.py:114
msgid "Disable documentation for variables with those modes"
msgstr ""
#: src/rougail/output_doc/config.py:104
#: src/rougail/output_doc/config.py:122
msgid "disabled when there is no mode available"
msgstr ""
#: src/rougail/output_doc/config.py:110
#: src/rougail/output_doc/config.py:128
msgid "verify if disable modes already exists"
msgstr ""
#: src/rougail/output_doc/config.py:113
#: src/rougail/output_doc/config.py:130
msgid "Modify values to document leaderships and dynamics families"
msgstr ""
#: src/rougail/output_doc/config.py:117
#: src/rougail/output_doc/config.py:133
msgid "Generate document in format"
msgstr ""
#: src/rougail/output_doc/doc.py:334
#: src/rougail/output_doc/doc.py:326
msgid "This family contains lists of variable blocks."
msgstr ""
#: src/rougail/output_doc/doc.py:342
#: src/rougail/output_doc/doc.py:336
msgid "This family builds families dynamically."
msgstr ""
#: src/rougail/output_doc/doc.py:356
#: src/rougail/output_doc/doc.py:350
msgid "Default"
msgstr ""
#: src/rougail/output_doc/doc.py:375
#: src/rougail/output_doc/doc.py:365
msgid "multiple"
msgstr ""
#: src/rougail/output_doc/doc.py:383
#: src/rougail/output_doc/doc.py:373
msgid "Example"
msgstr ""
#: src/rougail/output_doc/doc.py:386
#: src/rougail/output_doc/doc.py:376
msgid "Examples"
msgstr ""
#: src/rougail/output_doc/doc.py:408
#: src/rougail/output_doc/doc.py:394
msgid "No attribute \"description\" for \"{0}\" in {1}"
msgstr ""
#: src/rougail/output_doc/doc.py:534
#: src/rougail/output_doc/doc.py:531
msgid "text based with regular expressions \"{0}\""
msgstr ""
#: src/rougail/output_doc/doc.py:540
#: src/rougail/output_doc/doc.py:537
msgid "Validator"
msgstr ""
#: src/rougail/output_doc/doc.py:543
#: src/rougail/output_doc/doc.py:540
msgid "Validators"
msgstr ""
#: src/rougail/output_doc/doc.py:556
msgid "(default)"
msgstr ""
#: src/rougail/output_doc/doc.py:561
#: src/rougail/output_doc/doc.py:549
msgid "Choices"
msgstr ""
#: src/rougail/output_doc/doc.py:664
#: src/rougail/output_doc/doc.py:652
msgid "the value of the identifier"
msgstr ""
#: src/rougail/output_doc/doc.py:668
#: src/rougail/output_doc/doc.py:656
msgid "the value of the {0}"
msgstr ""
#: src/rougail/output_doc/doc.py:677
#: src/rougail/output_doc/doc.py:665
msgid "depends on a calculation"
msgstr ""
#: src/rougail/output_doc/doc.py:683
#: src/rougail/output_doc/doc.py:671
msgid "\"{0}\" is a calculation for {1} but has no description in {2}"
msgstr ""
#: src/rougail/output_doc/doc.py:709 src/rougail/output_doc/doc.py:814
#: src/rougail/output_doc/doc.py:697 src/rougail/output_doc/doc.py:799
msgid "depends on an undocumented variable"
msgstr ""
#: src/rougail/output_doc/doc.py:720
#: src/rougail/output_doc/doc.py:708
msgid "when the variable \"{0}\" hasn't the value \"{1}\""
msgstr ""
#: src/rougail/output_doc/doc.py:722
#: src/rougail/output_doc/doc.py:710
msgid "when the variable \"{0}\" is defined and hasn't the value \"{1}\""
msgstr ""
#: src/rougail/output_doc/doc.py:725
#: src/rougail/output_doc/doc.py:713
msgid "when the variable \"{0}\" has the value \"{1}\""
msgstr ""
#: src/rougail/output_doc/doc.py:727
#: src/rougail/output_doc/doc.py:715
msgid "when the variable \"{0}\" is defined and has the value \"{1}\""
msgstr ""
#: src/rougail/output_doc/doc.py:743
#: src/rougail/output_doc/doc.py:731
msgid "the value of the variable \"{0}\""
msgstr ""
#: src/rougail/output_doc/doc.py:745
#: src/rougail/output_doc/doc.py:733
msgid "the value of the variable \"{0}\" if it is defined"
msgstr ""
#: src/rougail/output_doc/doc.py:746
#: src/rougail/output_doc/doc.py:734
msgid "the value of an undocumented variable"
msgstr ""
#: src/rougail/output_doc/doc.py:784
#: src/rougail/output_doc/doc.py:770
msgid "the values of undocumented variables"
msgstr ""
#: src/rougail/output_doc/doc.py:804
msgid "(from an undocumented variable){0}"
#: src/rougail/output_doc/doc.py:789
msgid "(from an undocumented variable)"
msgstr ""
#: src/rougail/output_doc/doc.py:810
#: src/rougail/output_doc/doc.py:795
msgid "{0} (from an undocumented variable)"
msgstr ""
@ -187,13 +211,13 @@ msgstr ""
msgid "Example with all variables modifiable"
msgstr ""
#: src/rougail/output_doc/output/console.py:145
#: src/rougail/output_doc/utils.py:437
#: src/rougail/output_doc/output/console.py:160
#: src/rougail/output_doc/utils.py:657
msgid "Variable"
msgstr ""
#: src/rougail/output_doc/output/console.py:146
#: src/rougail/output_doc/utils.py:437
#: src/rougail/output_doc/output/console.py:161
#: src/rougail/output_doc/utils.py:657
msgid "Description"
msgstr ""
@ -201,115 +225,121 @@ msgstr ""
msgid "Informations"
msgstr ""
#: src/rougail/output_doc/utils.py:41
#: src/rougail/output_doc/utils.py:44
msgid "the domain name can starts by a dot"
msgstr ""
#: src/rougail/output_doc/utils.py:42
#: src/rougail/output_doc/utils.py:45
msgid "the domain name can be a hostname"
msgstr ""
#: src/rougail/output_doc/utils.py:43
#: src/rougail/output_doc/utils.py:46
msgid "the domain name can be an IP"
msgstr ""
#: src/rougail/output_doc/utils.py:44
#: src/rougail/output_doc/utils.py:47
msgid "the domain name can be network in CIDR format"
msgstr ""
#: src/rougail/output_doc/utils.py:49 src/rougail/output_doc/utils.py:55
#: src/rougail/output_doc/utils.py:52 src/rougail/output_doc/utils.py:58
msgid "the minimum value is {0}"
msgstr ""
#: src/rougail/output_doc/utils.py:50 src/rougail/output_doc/utils.py:56
#: src/rougail/output_doc/utils.py:53 src/rougail/output_doc/utils.py:59
msgid "the maximum value is {0}"
msgstr ""
#: src/rougail/output_doc/utils.py:62
#: src/rougail/output_doc/utils.py:65
msgid "IP must be in CIDR format"
msgstr ""
#: src/rougail/output_doc/utils.py:63
#: src/rougail/output_doc/utils.py:66
msgid "private IP are allowed"
msgstr ""
#: src/rougail/output_doc/utils.py:64
#: src/rougail/output_doc/utils.py:67
msgid "reserved IP are allowed"
msgstr ""
#: src/rougail/output_doc/utils.py:69
#: src/rougail/output_doc/utils.py:72
msgid "network must be in CIDR format"
msgstr ""
#: src/rougail/output_doc/utils.py:74
#: src/rougail/output_doc/utils.py:77
msgid "the host name can be an IP"
msgstr ""
#: src/rougail/output_doc/utils.py:79
#: src/rougail/output_doc/utils.py:82
msgid "the domain name in web address can be an IP"
msgstr ""
#: src/rougail/output_doc/utils.py:80
#: src/rougail/output_doc/utils.py:83
msgid "the domain name in web address can be only a hostname"
msgstr ""
#: src/rougail/output_doc/utils.py:87
#: src/rougail/output_doc/utils.py:90
msgid "can be range of port"
msgstr ""
#: src/rougail/output_doc/utils.py:88
#: src/rougail/output_doc/utils.py:91
msgid "can have the protocol"
msgstr ""
#: src/rougail/output_doc/utils.py:89
#: src/rougail/output_doc/utils.py:92
msgid "port 0 is allowed"
msgstr ""
#: src/rougail/output_doc/utils.py:90
#: src/rougail/output_doc/utils.py:93
msgid "well-known ports (1 to 1023) are allowed"
msgstr ""
#: src/rougail/output_doc/utils.py:91
#: src/rougail/output_doc/utils.py:94
msgid "registred ports (1024 to 49151) are allowed"
msgstr ""
#: src/rougail/output_doc/utils.py:92
#: src/rougail/output_doc/utils.py:95
msgid "private ports (greater than 49152) are allowed"
msgstr ""
#: src/rougail/output_doc/utils.py:97
#: src/rougail/output_doc/utils.py:100
msgid "minimum length for the secret is {0} characters"
msgstr ""
#: src/rougail/output_doc/utils.py:98
#: src/rougail/output_doc/utils.py:101
msgid "maximum length for the secret is {0} characters"
msgstr ""
#: src/rougail/output_doc/utils.py:99
#: src/rougail/output_doc/utils.py:102
msgid "forbidden characters: {0}"
msgstr ""
#: src/rougail/output_doc/utils.py:104
#: src/rougail/output_doc/utils.py:107
msgid "this filename could be a relative path"
msgstr ""
#: src/rougail/output_doc/utils.py:105
#: src/rougail/output_doc/utils.py:108
msgid "this file must exists"
msgstr ""
#: src/rougail/output_doc/utils.py:106
#: src/rougail/output_doc/utils.py:109
msgid "file type allowed: {0}"
msgstr ""
#: src/rougail/output_doc/utils.py:277
#: src/rougail/output_doc/utils.py:312
msgid "Variables for \"{0}\""
msgstr ""
#: src/rougail/output_doc/utils.py:305
#: src/rougail/output_doc/utils.py:336
msgid "Identifiers"
msgstr ""
#: src/rougail/output_doc/utils.py:458
#: src/rougail/output_doc/utils.py:561 src/rougail/output_doc/utils.py:568
#: src/rougail/output_doc/utils.py:572 src/rougail/output_doc/utils.py:574
#: src/rougail/output_doc/utils.py:576
msgid "(default)"
msgstr ""
#: src/rougail/output_doc/utils.py:697
msgid "{0}: {1}"
msgstr ""

View file

@ -64,6 +64,13 @@ class Annotator(Walk):
self.convert_property(family)
if family.type == "dynamic":
self.populate_family_dynamic(family)
path = family.path
if path in self.objectspace.forced_descriptions:
self.objectspace.informations.add(
path,
"forced_description",
True,
)
def populate_family_dynamic(self, family) -> None:
if self.change_default_value:
@ -130,35 +137,42 @@ class Annotator(Walk):
for variable in self.get_variables():
if variable.type == "symlink":
continue
path = variable.path
if variable.type == "choice":
self.calculation_to_information(
variable.path,
path,
"choice",
variable.choices,
variable.version,
)
default = variable.default
if default is None and variable.path in self.objectspace.default_multi:
default = self.objectspace.default_multi[variable.path]
if default is None and path in self.objectspace.default_multi:
default = self.objectspace.default_multi[path]
self.calculation_to_information(
variable.path,
path,
"default",
default,
variable.version,
)
self.calculation_to_information(
variable.path,
path,
"validators",
variable.validators,
variable.version,
)
if (
self.change_default_value
and variable.path in self.objectspace.leaders
and path in self.objectspace.leaders
and not default
):
self.add_examples_values(variable)
self.convert_property(variable)
if path in self.objectspace.forced_descriptions:
self.objectspace.informations.add(
path,
"forced_description",
True,
)
def convert_property(
self,

View file

@ -0,0 +1,130 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 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 <http://www.gnu.org/licenses/>.
"""
from pathlib import Path
from json import loads
from .config import OutPuts
from .i18n import _
class Changelog: # pylint: disable=no-member,too-few-public-methods
"""Build changelog"""
def gen_doc_changelog(self):
"""Return changelog"""
with Path(self.previous_json_file).open() as outfh:
previous_doc = loads(outfh.read())
self._tiramisu_to_internal_object()
self._added_variables = []
self._modified_variables = []
self._removed_variables = []
self.parser(previous_doc, self.informations)
return self.display()
def parser(self, previous_families, new_families):
def add(new):
self.formater.variable_to_string(new, self._added_variables)
def remove(previous):
self._removed_variables.append(element)
done = []
for element in list(previous_families) + list(new_families):
if element in done:
continue
done.append(element)
previous = previous_families.get(element)
new = new_families.get(element)
if not previous:
if new["type"] == "variable":
add(new)
else:
self.parser({}, new["children"])
elif not new:
if previous["type"] == "variable":
remove(element)
else:
self.parser(previous["children"], {})
elif previous["type"] != new["type"]:
if previous["type"] == "variable":
remove(element)
self.parser({}, new["children"])
else:
add(new)
self.parser(previous["children"], {})
elif previous["type"] != 'variable':
self.parser(previous["children"], new["children"])
else:
modified_attributes = {}
for prop in set(previous) | set(new):
prop_previous = previous.get(prop, [])
prop_new = new.get(prop, [])
if prop_previous != prop_new:
name = None
if isinstance(prop_previous, dict) and "values" in prop_previous:
name = prop_previous["name"]
local_prop_previous = prop_previous = prop_previous["values"]
if not isinstance(prop_previous, list):
if prop == "default":
local_prop_previous = [prop_previous]
else:
local_prop_previous = prop_previous = [prop_previous]
else:
local_prop_previous = prop_previous
if isinstance(prop_new, dict) and "values" in prop_new:
name = prop_new["name"]
prop_new = prop_new["values"]
if not isinstance(prop_new, list):
prop_new = [prop_new]
if isinstance(prop_new, list):
prop_new = prop_new.copy()
else:
prop_new = [prop_new]
if isinstance(prop_previous, list):
prop_previous = [p for p in prop_previous if p not in prop_new]
elif prop_previous in prop_new:
prop_new.remove(prop_previous)
prop_previous = []
prop_new = [p for p in prop_new if p not in local_prop_previous]
if prop_previous not in [None, []] or prop_new not in [None, []]:
modified_attributes[prop] = (name, prop_previous, prop_new)
if not modified_attributes:
continue
self.formater.variable_to_string(new, self._modified_variables, modified_attributes)
def display(self) -> str:
msg = ''
if self._added_variables:
if len(self._added_variables) == 1:
title = _('New variable')
else:
title = _('New variables')
msg += self.formater.run([self.formater.title(title, self.level), self.formater.table(self._added_variables)], self.level, dico_is_already_treated=True)
if self._modified_variables:
if len(self._modified_variables) == 1:
title = _('Modified variable')
else:
title = _('Modified variables')
msg += self.formater.run([self.formater.title(title, self.level), self.formater.table(self._modified_variables)], self.level, dico_is_already_treated=True)
if self._removed_variables:
if len(self._removed_variables) == 1:
title = _('Deleted variable')
else:
title = _('Deleted variables')
msg += self.formater.run([self.formater.title(title, self.level), self.formater.list(self._removed_variables)], self.level, dico_is_already_treated=True)
return msg

View file

@ -19,7 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from pathlib import Path
from rougail.utils import load_modules, _
from rougail.utils import load_modules
from .i18n import _
OUTPUTS = None
@ -83,14 +84,31 @@ doc:
alternative_name: dt
default: 1
example:
description: {_('Generate example')}
alternative_name: de
default: false
contents:
description: {_('Generated content')}
choices:
- variables
- example
- changelog
default:
- variables
without_family:
previous_json_file:
description: {_('Previous description file in JSON format')}
disabled:
jinja: |-
{{{{ "changelog" not in _.contents }}}}
return_type: boolean
description: changelog is not selected
without_family:
description: {_('Do not add families in documentation')}
default: false
disabled:
jinja: |-
{{{{ "variables" not in _.contents and _.output_format != "json" }}}}
return_type: boolean
description: variables is not selected
disabled_modes:
description: {_('Disable documentation for variables with those modes')}
@ -109,14 +127,19 @@ doc:
{{% endif %}}
description: {_('verify if disable modes already exists')}
change_default_value:
description: {_('Modify values to document leaderships and dynamics families')}
default: true
change_default_value: true # {_('Modify values to document leaderships and dynamics families')}
output_format:
description: {_('Generate document in format')}
alternative_name: do
default: output_format_default
validators:
- jinja: |-
{{% if _.output_format == 'json' %}}
{{% if "changelog" in _.contents %}}
cannot add to contents "changelog" with output_format "json"
{{% endif %}}
{{% endif %}}
choices:
""".replace(
"output_format_default", output_format_default

View file

@ -29,8 +29,9 @@ from rougail.error import VariableCalculationDependencyError, RougailWarning
from .config import OutPuts
from .i18n import _
from .utils import DocTypes, get_display_path, dump
from .utils import DocTypes, dump, to_phrase, calc_path
from .example import Examples
from .changelog import Changelog
HIDDEN_PROPERTIES = [
@ -39,7 +40,7 @@ HIDDEN_PROPERTIES = [
]
class RougailOutputDoc(Examples):
class RougailOutputDoc(Examples, Changelog):
"""Rougail Output Doc:
Generate documentation from rougail description files
"""
@ -64,10 +65,10 @@ class RougailOutputDoc(Examples):
if rougailconfig["step.output"] != "doc":
raise Exception("doc is not set as step.output")
outputs = OutPuts().get()
output = rougailconfig["doc.output_format"]
if output not in outputs:
output_format = rougailconfig["doc.output_format"]
if output_format not in outputs:
raise Exception(
f'cannot find output "{output}", available outputs: {list(outputs)}'
f'cannot find output "{output_format}", available outputs: {list(outputs)}'
)
self.conf = config
self.modes_level = rougailconfig["modes_level"]
@ -81,11 +82,17 @@ class RougailOutputDoc(Examples):
self.disabled_modes = []
self.conf.property.read_write()
# self.conf.property.remove("cache")
self.formater = outputs[output]()
self.output_format = output_format
self.level = rougailconfig["doc.title_level"]
self.dynamic_paths = {}
self.example = rougailconfig["doc.example"]
self.with_family = not rougailconfig["doc.without_family"]
self.contents = rougailconfig["doc.contents"]
self.example = "example" in self.contents
if "variables" in self.contents:
self.with_family = not rougailconfig["doc.without_family"]
else:
self.with_family = True
if "changelog" in self.contents:
self.previous_json_file = rougailconfig['doc.previous_json_file']
self.formater = outputs[output_format](self.with_family)
self.informations = None
try:
groups.namespace
@ -98,10 +105,13 @@ class RougailOutputDoc(Examples):
def run(self) -> str:
"""Print documentation in stdout"""
self._tiramisu_to_internal_object()
if not self.example:
return_string = self.formater.run(self.informations, self.level)
else:
return_string = self.gen_doc_examples()
return_string = ''
if "variables" in self.contents:
return_string += self.formater.run(self.informations, self.level)
if "example" in self.contents:
return_string += self.gen_doc_examples()
if "changelog" in self.contents:
return_string += self.gen_doc_changelog()
return True, return_string
def print(self) -> None:
@ -110,6 +120,7 @@ class RougailOutputDoc(Examples):
return ret
def _tiramisu_to_internal_object(self):
self.dynamic_paths = {}
config = self.conf.unrestraint
self._populate_dynamics(config)
informations = self._parse_families(config)
@ -119,28 +130,31 @@ class RougailOutputDoc(Examples):
def _populate_dynamics(self, family) -> None:
for child in family.list():
path = child.path(uncalculated=True)
if not child.isoptiondescription():
func = self._populate_dynamic_variable
if child.isoptiondescription():
type_ = "family"
else:
func = self._populate_dynamic_family
func(child, path)
type_ = "variable"
if child.isdynamic():
self._populate_dynamic(child, child.path(uncalculated=True), type_)
if child.isoptiondescription():
self._populate_dynamics(child)
def _populate_dynamic_variable(self, variable, path) -> None:
if not variable.isdynamic():
return
def _populate_dynamic(self, obj, path, type_) -> None:
if path not in self.dynamic_paths:
self.dynamic_paths[path] = {"paths": [], "names": []}
self._dyn_path_to_italic(self.dynamic_paths[path], variable, path)
self.dynamic_paths[path]["names"].append(variable.name())
def _populate_dynamic_family(self, family, path) -> None:
if family.isdynamic():
if path not in self.dynamic_paths:
self.dynamic_paths[path] = {"paths": [], "names": []}
self._dyn_path_to_italic(self.dynamic_paths[path], family, path)
self.dynamic_paths[path]["names"].append(family.name())
self._populate_dynamics(family)
new_name = True
description = obj.description(uncalculated=True)
name = obj.name(uncalculated=True)
self.dynamic_paths[path] = {"names": [],
"identifiers": [],
"path": path,
}
if not obj.information.get("forced_description", False):
self.dynamic_paths[path]["description"] = self._convert_description(description, obj, type_, its_a_path=False)
elif obj.isoptiondescription():
self.dynamic_paths[path]["description"] = self._convert_description(description, obj, type_, its_a_path=True)
dynamic_obj = self.dynamic_paths[path]
dynamic_obj["names"].append(obj.name())
dynamic_obj["identifiers"].append(obj.identifiers())
def _parse_families(self, family) -> dict:
informations = {}
@ -198,19 +212,19 @@ class RougailOutputDoc(Examples):
sub_informations = self._parse_families(family)
if not sub_informations:
return
if self.with_family:
family_informations = self._populate_family(
family,
path,
)
if family_informations is not False:
informations[name] = {
"type": self._get_family_type(family),
"informations": family_informations,
"children": sub_informations,
}
else:
informations.update(sub_informations)
# if self.with_family:
family_informations = self._populate_family(
family,
path,
)
if family_informations is not False:
informations[name] = {
"type": self._get_family_type(family),
"informations": family_informations,
"children": sub_informations,
}
# else:
# informations.update(sub_informations)
def parse_variable(
self,
@ -274,21 +288,13 @@ class RougailOutputDoc(Examples):
self, variable, leader, name, path, informations, only_one
) -> None:
if path not in self.dynamic_paths:
self._populate_dynamic_variable(variable, path)
self._populate_dynamic(variable, path)
dynamic_variable = self.dynamic_paths[path]
if (not only_one or path in informations) and "type" in dynamic_variable:
if self.example:
dynamic_variable["example"].append(
self._get_example(variable, dynamic_variable, leader)
)
description = self.formater.to_phrase(
variable.description(uncalculated=True)
)
if "{{ identifier }}" in description:
description = self._convert_description(description, variable)
dynamic_variable["descriptions"].append(
self.formater.to_phrase(description)
)
if variable.isleader():
return dynamic_variable
if not only_one:
@ -304,20 +310,6 @@ class RougailOutputDoc(Examples):
return "dynamic"
return "family"
def _dyn_path_to_italic(self, dico, child, path: str) -> str:
display_path = path
for identifier in child.identifiers():
identifier = normalize_family(str(identifier))
display_path = display_path.replace(
"{{ identifier }}", self.formater.italic(identifier), 1
)
path = path.replace("{{ identifier }}", str(identifier), 1)
if display_path != path:
if "display_paths" not in dico:
dico["display_paths"] = {}
dico["display_paths"][len(dico["paths"])] = display_path
dico["paths"].append(path)
def _populate_family(
self,
family,
@ -327,7 +319,7 @@ class RougailOutputDoc(Examples):
informations = self.dynamic_paths[path]
else:
informations = {}
if not self._populate(family, informations):
if not self._populate(family, informations, 'family'):
return False
if family.isleadership():
informations.setdefault("help", []).append(
@ -337,7 +329,9 @@ class RougailOutputDoc(Examples):
identifiers = self._to_string(family, "dynamic", do_not_raise=True)
if identifiers is None:
identifiers = family.identifiers(only_self=True)
informations["identifiers"] = identifiers
if not isinstance(identifiers, list):
identifiers = [identifiers]
informations["identifier"] = identifiers
informations.setdefault("help", []).append(
_("This family builds families dynamically.")
)
@ -358,12 +352,8 @@ class RougailOutputDoc(Examples):
variable,
informations,
)
if not self._populate(variable, informations):
if not self._populate(variable, informations, 'variable'):
return False
if "description" in informations:
informations["descriptions"] = [
self.formater.to_phrase(informations.pop("description"))
]
if variable.ismulti():
multi = not variable.isfollower() or variable.issubmulti()
else:
@ -392,42 +382,49 @@ class RougailOutputDoc(Examples):
self,
child,
informations: dict,
type_: str,
):
need_disabled, properties = self._parse_properties(child)
if not need_disabled:
return False
if not child.isdynamic():
informations["paths"] = [child.path(uncalculated=True)]
informations["names"] = [child.name()]
description = child.description(uncalculated=True)
if child.name(uncalculated=True) == description and (
not child.isoptiondescription()
or (self.support_namespace and child.group_type() is not groups.namespace)
):
if child.isoptiondescription() or not child.isfollower() or not child.index():
warning = _('No attribute "description" for "{0}" in {1}').format(
child.path(uncalculated=True),
display_xmlfiles(child.information.get("ymlfiles")),
)
warn(warning,
RougailWarning,
)
name = child.name(uncalculated=True)
if child.information.get("forced_description", False):
if not child.isoptiondescription() or not self.support_namespace or child.group_type() is not groups.namespace:
if child.isoptiondescription() or not child.isfollower() or not child.index():
warning = _('No attribute "description" for "{0}" in {1}').format(
child.path(uncalculated=True),
display_xmlfiles(child.information.get("ymlfiles")),
)
warn(warning,
RougailWarning,
)
if child.isoptiondescription():
description = self._convert_description(child.description(uncalculated=True), child, type_, its_a_path=True)
else:
description = None
else:
informations["description"] = self._convert_description(description, child)
description = self._convert_description(child.description(uncalculated=True), child, type_, its_a_path=False)
if not child.isdynamic():
informations["path"] = child.path(uncalculated=True)
informations["names"] = [child.name()]
if description is not None:
informations["description"] = description
help_ = child.information.get("help", None)
if help_:
informations["help"] = [self.formater.to_phrase(help_)]
informations["help"] = [to_phrase(help_)]
if "properties" in informations:
informations["properties"].extend(properties)
else:
informations["properties"] = properties
return True
def _convert_description(self, description, obj):
if "{{ identifier }}" in description:
return description.replace(
"{{ identifier }}", self.formater.italic(obj.identifiers()[-1])
)
def _convert_description(self, description, obj, type_, its_a_path=False):
if not its_a_path:
description = to_phrase(description, type_)
# if "{{ identifier }}" in description:
# description = {"description": description,
# "identifier": obj.identifiers()[-1],
# }
return description
def _add_examples(self, variable, informations: dict, leader) -> None:
@ -547,17 +544,8 @@ class RougailOutputDoc(Examples):
if choices is None:
choices = child.value.list()
for idx, val in enumerate(choices):
if not isinstance(val, Calculation):
default = informations.get("default", {}).get("values")
if default is not None and val == default:
choices[idx] = (
str(val)
+ " "
+ self.formater.bold("" + _("(default)"))
)
informations["default_is_already_set"] = True
continue
choices[idx] = self._to_string(child, "choice", f"_{idx}")
if isinstance(val, Calculation):
choices[idx] = self._to_string(child, "choice", f"_{idx}")
informations["choices"] = {"name": _("Choices"), "values": choices}
def _parse_properties(
@ -639,13 +627,13 @@ class RougailOutputDoc(Examples):
if isinstance(calculation, list):
values = []
for cal in calculation:
value = self._calculation_to_string(child, cal, prop)
value = self._calculation_to_string(child, cal, prop, inside_list=True)
if value is not None:
values.append(value)
return values
return self._calculation_to_string(child, calculation, prop)
def _calculation_to_string(self, child, calculation, prop):
def _calculation_to_string(self, child, calculation, prop, inside_list=False):
if "description" in calculation:
values = calculation["description"]
if not values.endswith("."):
@ -666,7 +654,7 @@ class RougailOutputDoc(Examples):
values = calculation["value"]
else:
values = _("the value of the {0}").format(calculation["type"])
if isinstance(values, str) and not values.endswith("."):
if not inside_list and isinstance(values, str) and not values.endswith("."):
values += "."
return values
@ -759,25 +747,23 @@ class RougailOutputDoc(Examples):
values = []
all_is_undocumented = None
for information in informations:
for idx, path in enumerate(information["paths"]):
if regexp and not regexp.search(path):
# if calculation["ori_path"] == information['path']:
path = information["path"]
for identifiers in information["identifiers"]:
cpath = calc_path(path, identifiers=identifiers)
if regexp and not regexp.search(cpath):
continue
if self._is_inaccessible_user_data(self.conf.option(path)):
if self._is_inaccessible_user_data(self.conf.option(cpath)):
if all_is_undocumented is None:
all_is_undocumented = True
msg = hidden_msg
else:
if regexp:
display_path = calculation["ori_path"]
for identifier in regexp.findall(path):
display_path = display_path.replace(
"{{ identifier }}",
self.formater.italic(identifier),
1,
)
if "{{ identifier }}" in path:
msg = {"message": true_msg,
"path": {"path": path, "identifiers": identifiers.copy()},
}
else:
display_path = get_display_path(information, idx)
msg = true_msg.format(display_path)
msg = true_msg.format(path)
all_is_undocumented = False
values.append(msg)
if all_is_undocumented and len(values) > 1:
@ -800,10 +786,9 @@ class RougailOutputDoc(Examples):
uncalculated, Calculation
):
if isinstance(uncalculated, list):
uncalculated = self.formater.list(uncalculated)
true_msg = _(
"(from an undocumented variable){0}"
).format(uncalculated)
true_msg = {"submessage": _("(from an undocumented variable)"),
"values": uncalculated,
}
else:
if not isinstance(uncalculated, str):
uncalculated = dump(uncalculated)
@ -813,7 +798,10 @@ class RougailOutputDoc(Examples):
else:
true_msg = _("depends on an undocumented variable")
if true_msg:
values = true_msg.format(calculation["ori_path"])
if isinstance(true_msg, dict):
values = true_msg
else:
values = true_msg.format(calculation["ori_path"])
else:
values = None
return values

View file

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
from .utils import _
from .utils import _, calc_path
class Examples: # pylint: disable=no-member,too-few-public-methods
@ -70,10 +70,21 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
examples: dict,
examples_mandatories: dict,
) -> None:
for idx, path in enumerate(variable["paths"]):
paths = []
ori_path = variable["path"]
if "identifiers" in variable:
for idx, identifiers in enumerate(variable["identifiers"]):
paths.append(calc_path(ori_path, identifiers=identifiers))
else:
paths.append(ori_path)
for idx, path in enumerate(paths):
path = calc_path(path)
if dyn_parent is not None and not path.startswith(dyn_parent):
continue
name = variable["names"][idx]
if len(variable["names"]) == 1:
name = variable["names"][0]
else:
name = variable["names"][idx]
value = variable["example"][idx]
examples[name] = value
if variable["mandatory_without_value"]:
@ -87,10 +98,14 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
examples: dict,
examples_mandatories: dict,
) -> None:
for idx, path in enumerate(family["informations"]["paths"]):
def _set_example(idx, identifiers):
path = calc_path(ori_path, identifiers=identifiers)
if dyn_parent is not None and not path.startswith(dyn_parent):
continue
name = family["informations"]["names"][idx]
return
if len(family["informations"]["names"]) == 1:
name = family["informations"]["names"][0]
else:
name = family["informations"]["names"][idx]
if family["type"] == "leadership":
func = self._parse_examples_leadership
else:
@ -103,6 +118,12 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
examples_mandatories[name] = ret_m
if ret_e:
examples[name] = ret_e
ori_path = family["informations"]["path"]
if "identifiers" in family["informations"]:
for idx, identifiers in enumerate(family["informations"]["identifiers"]):
_set_example(idx, identifiers)
else:
_set_example(0, None)
def _parse_examples_leadership(
self, leadership, dyn_parent: Optional[str] = None
@ -110,27 +131,36 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
examples = []
examples_mandatories = []
leader = next(iter(leadership.values()))
for path_idx, path in enumerate(leader["paths"]):
paths = []
ori_path = leader["path"]
if "identifiers" in leader:
for idx, identifiers in enumerate(leader["identifiers"]):
paths.append(calc_path(ori_path, identifiers=identifiers))
else:
paths.append(ori_path)
for path_idx, path in enumerate(paths):
path = calc_path(path)
if dyn_parent is not None and not path.startswith(dyn_parent):
continue
for leader_idx in range(len(leader["example"][path_idx])):
examples.append(
{
follower["names"][path_idx]: follower["example"][path_idx][
leader_idx
]
for follower in leadership.values()
}
)
followers = {}
for follower in leadership.values():
if len(follower["names"]) == 1:
name = follower["names"][0]
else:
name = follower["names"][path_idx]
followers[name] = follower["example"][path_idx][leader_idx]
examples.append(followers)
if leader["mandatory_without_value"]:
examples_mandatories.append(
{
follower["names"][path_idx]: follower["example"][path_idx][
leader_idx
]
for follower in leadership.values()
if follower["mandatory_without_value"]
}
)
followers = {}
for follower in leadership.values():
if not follower["mandatory_without_value"]:
continue
if len(follower["names"]) == 1:
name = follower["names"][0]
else:
name = follower["names"][path_idx]
followers[name] = follower["example"][path_idx][leader_idx]
examples_mandatories.append(followers)
break
return examples, examples_mandatories

View file

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from typing import List
from ..utils import CommonFormater, dump, to_phrase
from ..utils import CommonFormater, dump
class Formater(CommonFormater):
@ -68,6 +68,20 @@ class Formater(CommonFormater):
"""Set a text to italic"""
return f"__{msg}__"
def delete(
self,
msg: str,
) -> str:
"""Set a text to deleted"""
return f"+++{msg}+++"
def underline(
self,
msg: str,
) -> str:
"""Set a text to underline"""
return f"#{msg}#"
def stripped(
self,
text: str,
@ -120,6 +134,3 @@ class Formater(CommonFormater):
) -> str:
"""verify if a text is a list"""
return txt.strip().startswith("* ")
def to_phrase(self, text: str) -> str:
return to_phrase(text)

View file

@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import List
from ..i18n import _
from ..utils import dump, CommonFormater, to_phrase, ENTER
from ..utils import dump, CommonFormater, ENTER
class Formater(CommonFormater):
@ -36,21 +36,22 @@ class Formater(CommonFormater):
"title5": "dark_green underline bold",
}
def __init__(self) -> None:
self.max_line = 0
super().__init__()
def run(self, dico: dict, level: int) -> str:
from rich.text import Text
def __init__(self, with_family: bool) -> None:
from rich.table import Table
from rich.theme import Theme
from rich.console import Console
self.rich_table = Table
custom_theme = Theme(self.titles_color)
self.rich_console = Console
self.custom_theme = Theme(self.titles_color)
self.max_line = 0
super().__init__(with_family)
dico = self.dict_to_dict(dico, level)
console = Console(theme=custom_theme)
def run(self, dico: dict, level: int, *, dico_is_already_treated=False) -> str:
if not dico_is_already_treated:
dico = self.dict_to_dict(dico, level)
console = self.rich_console(theme=self.custom_theme)
with console.capture() as capture:
for data in dico:
console.print(data)
@ -86,6 +87,20 @@ class Formater(CommonFormater):
"""Set a text to italic"""
return f"[italic]{msg}[/italic]"
def delete(
self,
msg: str,
) -> str:
"""Set a text to delete"""
return f"[strike]{msg}[/strike]"
def underline(
self,
msg: str,
) -> str:
"""Set a text to underline"""
return f"[underline]{msg}[/underline]"
def stripped(
self,
text: str,
@ -147,6 +162,3 @@ class Formater(CommonFormater):
for data in datas:
table.add_row(str(data[0]), data[1])
return table
def to_phrase(self, text: str) -> str:
return to_phrase(text)

View file

@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import List
from html import escape
from ..utils import dump, CommonFormater, to_phrase
from ..utils import dump, CommonFormater
class Formater(CommonFormater):
@ -30,10 +30,10 @@ class Formater(CommonFormater):
level = 50
enter_table = "<br/>"
def __init__(self) -> None:
def __init__(self, with_family: bool) -> None:
self.max_line_variable = 0
self.max_line_description = 0
super().__init__()
super().__init__(with_family)
def title(
self,
@ -125,4 +125,4 @@ class Formater(CommonFormater):
self.max_line_description = self.max_line_variable
def to_phrase(self, text: str) -> str:
return escape(to_phrase(text))
return escape(text)

View file

@ -30,7 +30,7 @@ class Formater(GithubFormater):
def namespace_to_title(self, informations: dict, level: int) -> str:
"""manage namespace family"""
return self.title(
self.family_description(informations),
self.get_description("family", informations),
level,
)

View file

@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from json import dumps
from typing import Any
from ..utils import to_phrase
class Formater:
@ -27,20 +26,9 @@ class Formater:
name = "json"
level = 90
def __init__(self, with_family: bool):
pass
def run(self, dico: dict, *args) -> str: # pylint: disable=unused-argument
"""Transform to string"""
return dumps(dico, ensure_ascii=False, indent=2)
def italic(self, msg: Any) -> str:
"""Just return a string"""
return str(msg)
def bold(self, msg: Any) -> str:
"""Just return a string"""
return str(msg)
def to_phrase(self, text: str) -> str:
return to_phrase(text)
def list(self, lst: list) -> list:
return lst

View file

@ -16,7 +16,7 @@ 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 List
from typing import Tuple, List, Optional
from io import BytesIO
from ruamel.yaml import YAML
@ -24,6 +24,9 @@ import tabulate as tabulate_module
from tiramisu.error import display_list
from tabulate import tabulate
from rougail.tiramisu import normalize_family
from tiramisu import undefined
from .i18n import _
@ -123,15 +126,22 @@ def dump(informations):
return ret
def to_phrase(msg):
"""Add maj for the first character and ends with dot"""
def to_phrase(msg, type_="variable"):
"""Add maj for the first character and ends with dot
"""
if not msg:
# replace None to empty string
return ""
msg = str(msg).strip()
# a phrase must ends with a dot
if not msg.endswith("."):
msg += "."
if type_ == 'variable':
if not msg.endswith("."):
msg += "."
elif type_ == 'family':
if msg.endswith("."):
msg = msg[:-1]
else:
raise Exception('unknown type')
# and start with a maj
return msg[0].upper() + msg[1:]
@ -143,9 +153,10 @@ class CommonFormater:
# tabulate module name
name = None
def __init__(self):
def __init__(self, with_family: bool):
tabulate_module.PRESERVE_WHITESPACE = True
self.header_setted = False
self.with_family = with_family
# Class you needs implement to your Formater
def title(
@ -208,11 +219,27 @@ class CommonFormater:
def end_family_informations(self) -> str:
return ''
def display_path(
def display_paths(
self,
path: str,
informations: dict,
modified_attributes: dict,
) -> str:
return self.bold(path)
ret_paths = []
path = informations["path"]
if "identifiers" in modified_attributes:
name, previous, new = modified_attributes["identifiers"]
ret_paths.extend([self.bold(self.delete(calc_path(path, self, identifier))) for identifier in previous])
else:
new = []
if "identifiers" in informations:
for identifier in informations["identifiers"]:
path_ = calc_path(path, self, identifier)
if identifier in new:
path_ = self.underline(path_)
ret_paths.append(self.bold(path_))
else:
ret_paths.append(self.bold(path))
return ret_paths
def after_family_paths(self) -> str:
return ENTER
@ -227,54 +254,62 @@ class CommonFormater:
"""Manage the header of a table"""
return lst
def run(self, informations: dict, level: int) -> str:
def run(self, informations: dict, level: int, *, dico_is_already_treated=False) -> str:
"""Transform to string"""
if informations:
return self.dict_to_string(informations, level)
return self._run(informations, level, dico_is_already_treated)
return ""
def dict_to_dict(self, dico: dict, level: int) -> str:
def _run(self, dico: dict, level: int, dico_is_already_treated: bool) -> str:
"""Parse the dict to transform to dict"""
if dico_is_already_treated:
return "".join(dico)
return "".join([msg for msg in self.dict_to_dict(dico, level, init=True)])
def dict_to_dict(self, dico: dict, level: int, *, ori_table_datas: list = None, init: bool = False) -> str:
"""Parse the dict to transform to dict"""
msg = []
table_datas = []
if ori_table_datas is not None:
table_datas = ori_table_datas
else:
table_datas = []
ori_level = None
for value in dico.values():
if value["type"] == "namespace":
if ori_level is None:
ori_level = level
level += 1
informations = value["informations"]
msg.append(self.namespace_to_title(informations, ori_level))
msg.append(self.family_informations())
msg.append(self.display_path(get_display_path(informations, 0)))
msg.append(self.after_family_paths())
msg.append(self.property_to_string(informations, {}) + ENTER)
msg.append(self.end_family_informations())
msg.extend(self.dict_to_dict(value["children"], level))
msg.append(self.end_namespace(ori_level))
if value["type"] == "variable":
self.variable_to_string(value, table_datas)
else:
if value["type"] == "variable":
self.variable_to_string(value, table_datas)
if self.with_family:
if value["type"] == "namespace":
if ori_level is None:
ori_level = level
level += 1
informations = value["informations"]
msg.append(self.namespace_to_title(informations, ori_level))
msg.append(self.family_informations())
msg.extend(self.display_paths(informations, {}))
msg.append(self.after_family_paths())
msg.append(self.property_to_string(informations, {}, {})[1] + ENTER)
msg.append(self.end_family_informations())
msg.extend(self.dict_to_dict(value["children"], level))
msg.append(self.end_namespace(ori_level))
else:
if table_datas:
msg.append(self.table(table_datas))
table_datas = []
msg.extend(self.family_to_string(value["informations"], level))
msg.extend(self.dict_to_dict(value["children"], level + 1))
msg.append(self.end_family(level))
else:
if table_datas:
msg.append(self.table(table_datas))
table_datas = []
msg.extend(self.family_to_string(value["informations"], level))
msg.extend(self.dict_to_dict(value["children"], level + 1))
msg.append(self.end_family(level))
if table_datas:
self.dict_to_dict(value["children"], level + 1, ori_table_datas=table_datas)
if (init or ori_table_datas is None) and table_datas:
msg.append(self.table(table_datas))
return msg
def dict_to_string(self, dico: dict, level: int) -> str:
"""Parse the dict to transform to dict"""
return "".join([msg for msg in self.dict_to_dict(dico, level)])
# FAMILY
def namespace_to_title(self, informations: dict, level: int) -> str:
"""manage namespace family"""
return self.title(
_('Variables for "{0}"').format(self.family_description(informations)),
_('Variables for "{0}"').format(self.get_description("family", informations)),
level,
)
@ -283,26 +318,22 @@ class CommonFormater:
def family_to_string(self, informations: dict, level: int) -> str:
"""manage other family type"""
msg = [self.title(self.family_description(informations), level)]
msg = [self.title(self.get_description("family", informations), level)]
helps = informations.get("help")
if helps:
for help_ in helps:
msg.append(self.display_family_help(help_.strip()))
msg.append(self.family_informations())
msg.append(self.join(
[
self.display_path(get_display_path(informations, index))
for index in range(len(informations["paths"]))
]
msg.append(self.join(self.display_paths(informations, {})
) + self.after_family_paths()
)
calculated_properties = []
msg.append(self.property_to_string(informations, calculated_properties) + ENTER)
msg.append(self.property_to_string(informations, calculated_properties, {})[1] + ENTER)
if calculated_properties:
msg.append(self.join(calculated_properties) + self.after_family_properties())
if "identifiers" in informations:
if "identifier" in informations:
msg.append(
self.section(_("Identifiers"), informations["identifiers"]) + self.after_family_properties()
self.section(_("Identifiers"), informations["identifier"]) + self.after_family_properties()
)
msg.append(self.end_family_informations())
return msg
@ -310,117 +341,306 @@ class CommonFormater:
def end_family(self, level: int) -> str:
return ''
def family_description(self, informations: dict) -> str():
"""Get family name"""
if "description" in informations:
return informations["description"]
return display_list(
[
get_display_path(informations, index)
for index in range(len(informations["paths"]))
],
separator="or",
)
def convert_list_to_string(self, attribute: str, informations: dict, modified_attributes: dict) -> str():
datas = []
if attribute in modified_attributes:
name, previous, new = modified_attributes[attribute]
for data in previous:
datas.append(self.delete(self.to_phrase(data)))
else:
new = []
if attribute in informations:
for data in informations[attribute]:
if isinstance(data, dict):
if attribute.endswith('s'):
attr = attribute[:-1]
else:
attr = attribute
data = data[attr].replace('{{ identifier }}', self.italic(data["identifier"]))
if data in new:
data = self.underline(data)
datas.append(self.to_phrase(data))
return self.stripped(self.join(datas))
def get_description(self, type_: str, informations: dict, modified_attributes: dict={}) -> str():
def _get_description(description, identifiers, delete=False, new=[]):
if "{{ identifier }}" in description:
if type_ == "variable":
identifiers_text = display_list([self.italic(i[-1]) for i in identifiers], separator="or")
description = description.replace('{{ identifier }}', identifiers_text)
else:
d = []
for i in identifiers:
new_description = description.replace('{{ identifier }}', self.italic(i[-1]))
if new_description not in d:
d.append(self.to_phrase(new_description))
description = display_list(d, separator="or")
else:
description = self.to_phrase(description)
if description in new:
description = self.underline(description)
if delete:
description = self.delete(description)
return description
if "description" in modified_attributes:
name, previous, new = modified_attributes["description"]
modified_description = _get_description(previous, modified_attributes.get("identifiers", []), delete=True)
else:
modified_description = None
new = []
description = _get_description(informations["description"], informations.get("identifiers"), new=new)
if modified_description:
if description:
description = self.join([modified_description, description])
else:
description = modified_description
if not description:
return None
return self.stripped(description)
# VARIABLE
def variable_to_string(self, informations: dict, table_datas: dict) -> None:
def variable_to_string(self, informations: dict, table_datas: list, modified_attributes: dict={}) -> None:
"""Manage variable"""
calculated_properties = []
multi, first_column = self.variable_first_column(informations, calculated_properties, modified_attributes)
table_datas.append(
[
self.join(first_column),
self.join(
self.variable_first_column(informations, calculated_properties)
),
self.join(
self.variable_second_column(informations, calculated_properties)
self.variable_second_column(informations, calculated_properties, modified_attributes, multi=multi)
),
]
)
def variable_first_column(
self, informations: dict, calculated_properties: list
self, informations: dict, calculated_properties: list, modified_attributes: Optional[dict]
) -> list:
"""Collect string for the first column"""
multi, properties = self.property_to_string(informations, calculated_properties, modified_attributes)
first_col = [
self.join(
[
self.display_path(get_display_path(informations, index))
for index in range(len(informations["paths"]))
]
),
self.property_to_string(informations, calculated_properties),
self.display_paths(informations, modified_attributes)
), properties
]
self.columns(first_col)
return first_col
return multi, first_col
def variable_second_column(
self, informations: dict, calculated_properties: list
self, informations: dict, calculated_properties: list, modified_attributes: dict, multi: bool
) -> list:
"""Collect string for the second column"""
if "descriptions" in informations:
description = self.join(list(dict.fromkeys(informations["descriptions"])))
else:
description = to_phrase(
display_list(
list(dict.fromkeys(informations["names"])),
separator="or",
)
)
second_col = [self.stripped(description)]
for help_ in informations.get("help", []):
second_col.append(self.stripped(help_))
if "validators" in informations:
validators = informations["validators"]
if isinstance(validators["values"], list):
values = self.list(validators["values"])
else:
values = validators["values"]
second_col.append(self.section(validators["name"], values))
if "choices" in informations:
choices = informations["choices"]
second_col.append(self.section(choices["name"], choices["values"]))
if (
"default" in informations
and informations.get("default_is_already_set", False) is False
):
default = informations["default"]
second_col.append(self.section(default["name"], default["values"]))
if "examples" in informations:
examples = informations["examples"]
if isinstance(examples["values"], list):
values = self.list(examples["values"])
else:
values = examples["values"]
second_col.append(self.section(examples["name"], values))
second_col = []
#
if "description" in informations:
description = self.get_description("variable", informations, modified_attributes)
second_col.append(description)
#
help_ = self.convert_list_to_string("help", informations, modified_attributes)
if help_:
second_col.append(help_)
#
validators = self.convert_section_to_string("validators", informations, modified_attributes, multi=True)
if validators:
second_col.append(validators)
default_is_already_set, choices = self.convert_choices_to_string(informations, modified_attributes)
if choices:
second_col.append(choices)
if not default_is_already_set and "default" in informations:
self.convert_section_to_string("default", informations, modified_attributes, multi=multi)
second_col.append(self.convert_section_to_string("default", informations, modified_attributes, multi=multi))
examples = self.convert_section_to_string("examples", informations, modified_attributes, multi=True)
if examples:
second_col.append(examples)
second_col.extend(calculated_properties)
self.columns(second_col)
return second_col
def convert_section_to_string(self, attribute: str, informations: dict, modified_attributes: dict, multi: bool) -> str():
values = []
submessage = ""
if modified_attributes and attribute in modified_attributes:
name, previous, new = modified_attributes[attribute]
# if "identifiers" in modified_attributes:
# iname, iprevious, inew = modified_attributes["identifiers"]
# identifiers = iprevious.copy()
# for identifier in informations.get("identifiers", []):
# if identifier not in inew:
# identifiers.append(identifier)
#
# else:
# identifiers = informations.get("identifiers", [])
if isinstance(previous, list):
for p in previous:
submessage, m = self.message_to_string(p, submessage)
values.append(self.delete(m))
else:
submessage, old_values = self.message_to_string(previous, submessage)
values.append(self.delete(old_values))
else:
new = []
if attribute in informations:
old = informations[attribute]
name = old["name"]
if isinstance(old["values"], list):
for value in old["values"]:
submessage, old_value = self.message_to_string(value, submessage)
if value in new:
old_value = self.underline(old_value)
values.append(old_value)
if multi:
values = self.list(values)
else:
values = self.join(values)
elif values:
old_values = old["values"]
submessage, old_values = self.message_to_string(old_values, submessage)
if old["values"] in new:
old_values = self.underline(old_values)
values.append(old_values)
values = self.join(values)
else:
submessage, values = self.message_to_string(old["values"], submessage)
if old["values"] in new:
values = self.underline(values)
if values != []:
return self.section(name, values, submessage=submessage)
def convert_choices_to_string(self, informations: dict, modified_attributes: dict) -> str():
default_is_already_set = False
if "choices" in informations:
choices = informations["choices"]
choices_values = choices["values"]
if not isinstance(choices_values, list):
choices_values = [choices_values]
default_is_a_list = False
else:
default_is_a_list = True
if "default" in modified_attributes:
name, old_default, new_default = modified_attributes["default"]
if not old_default:
old_default = [None]
if not isinstance(old_default, list):
old_default = [old_default]
for value in old_default.copy():
if isinstance(value, str) and value.endswith(".") and value not in choices_values:
old_default.remove(value)
old_default.append(value[:-1])
else:
old_default = new_default = []
# check if all default values are in choices (could be from a calculation)
if "default" in informations:
default = informations["default"]["values"]
else:
default = []
if not isinstance(default, list):
default = [default]
default_value_not_in_choices = set(default) - set(choices_values)
if default_value_not_in_choices:
default_is_changed = False
for val in default_value_not_in_choices.copy():
if isinstance(val, str) and val.endswith('.') and val[:-1] in choices_values:
default.remove(val)
default.append(val[:-1])
default_is_changed = True
if val in new_default:
new_default.remove(val)
new_default.append(val[:-1])
if default_is_changed:
default_value_not_in_choices = set(default) - set(choices_values)
if default_value_not_in_choices:
old_default = []
new_default = []
default = []
else:
default_is_already_set = True
if "choices" in modified_attributes:
name, previous, new = modified_attributes["choices"]
for choice in reversed(previous):
if choice in old_default:
choices_values.insert(0, self.delete(dump(choice) + "" + _("(default)")))
else:
choices_values.insert(0, self.delete(dump(choice)))
else:
new = []
for idx, val in enumerate(choices_values):
if val in old_default:
choices_values[idx] = dump(val) + " " + self.delete("" + _("(default)"))
elif val in default:
if val in new_default:
if val in new:
choices_values[idx] = self.underline(dump(val) + " " + self.bold("" + _("(default)")))
else:
choices_values[idx] = dump(val) + " " + self.underline(self.bold("" + _("(default)")))
else:
choices_values[idx] = dump(val) + " " + self.bold("" + _("(default)"))
elif val in new:
choices_values[idx] = self.underline(dump(val))
# if old value and new value is a list, display a list
if not default_is_a_list and len(choices_values) == 1:
choices_values = choices_values[0]
return default_is_already_set, self.section(choices["name"], choices_values)
return default_is_already_set, None
# OTHERs
def to_phrase(self, text: str) -> str:
return text
def display_family_help(self, help_):
return help_ + ENTER
return self.to_phrase(help_) + ENTER
def property_to_string(
self, informations: dict, calculated_properties: list
self, informations: dict, calculated_properties: list, modified_attributes: dict,
) -> str:
"""Transform properties to string"""
properties = []
local_calculated_properties = {}
multi = False
if "properties" in modified_attributes:
previous, new = self.get_modified_properties(*modified_attributes["properties"][1:])
for p, annotation in previous.items():
if p not in new:
properties.append(self.prop(self.delete(p), italic=False))
if annotation is not None:
local_calculated_properties[p] = [self.delete(annotation)]
else:
previous = new = []
for prop in informations.get("properties", []):
if prop["type"] == "type":
properties.append(self.link(prop["name"], ROUGAIL_VARIABLE_TYPE))
else:
if prop["type"] == "multiple":
multi = True
prop_name = prop["name"]
if "annotation" in prop:
italic = True
calculated_properties.append(
self.section(prop["name"].capitalize(), prop["annotation"])
)
prop_annotation = prop["annotation"]
if prop_name in new and (prop_name not in previous or new[prop_name] != previous[prop_name]):
prop_annotation = self.underline(prop_annotation)
local_calculated_properties.setdefault(prop["name"], []).append(prop_annotation)
else:
italic = False
prop_str = self.prop(prop["name"], italic=italic)
properties.append(prop_str)
if prop_name not in previous and prop_name in new:
prop_name = self.underline(prop_name)
properties.append(self.prop(prop_name, italic=italic))
if local_calculated_properties:
for calculated_property_name, calculated_property in local_calculated_properties.items():
if len(calculated_property) > 1:
calculated_property = self.join(calculated_property)
else:
calculated_property = calculated_property[0]
calculated_properties.append(
self.section(calculated_property_name.capitalize(), calculated_property)
)
if not properties:
return ""
return " ".join(properties)
return multi, ""
return multi, " ".join(properties)
def get_modified_properties(self, previous: List[dict], new: List[dict]) -> Tuple[dict, dict]:
def modified_properties_parser(dico):
return {d["name"]: d.get("annotation") for d in dico}
return modified_properties_parser(previous), modified_properties_parser(new)
def columns(
self,
@ -442,23 +662,55 @@ class CommonFormater:
datas.clear()
return msg
def message_to_string(self, msg, ret, identifiers=[]):
if isinstance(msg, dict):
if "submessage" in msg:
ret += msg["submessage"]
msg = msg["values"]
elif "message" in msg:
path = calc_path(msg["path"], self, identifiers)
msg = msg["message"].format(path)
return ret, msg
def section(
self,
name: str,
msg: str,
submessage: str = "",
) -> str:
"""Return something like Name: msg"""
submessage, msg = self.message_to_string(msg, submessage)
if isinstance(msg, list):
if len(msg) == 1:
msg = msg[0]
msg = calc_path(msg[0], self)
else:
msg = self.list(msg)
lst = []
for p in msg:
submessage, elt = self.message_to_string(p, submessage)
lst.append(elt)
submessage += self.list(lst)
msg = ""
if not isinstance(msg, str):
msg = dump(msg)
return _("{0}: {1}").format(self.bold(name), msg)
submessage += dump(msg)
else:
submessage += msg
return _("{0}: {1}").format(self.bold(name), submessage)
def get_display_path(informations: dict, index: int) -> str:
if "display_paths" in informations and index in informations["display_paths"]:
return informations["display_paths"][index]
return informations["paths"][index]
def calc_path(path, formater=None, identifiers: List[str]=None) -> str:
def _path_with_identifier(path, identifier):
identifier = normalize_family(str(identifier))
if formater:
identifier = formater.italic(identifier)
return path.replace('{{ identifier }}', identifier, 1)
if isinstance(path, dict):
path_ = path["path"]
for identifier in path["identifiers"]:
path_ = _path_with_identifier(path_, identifier)
elif identifiers:
path_ = path
for identifier in identifiers:
path_ = _path_with_identifier(path_, identifier)
else:
path_ = path
return path_

View file

@ -0,0 +1,41 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,21 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
...

View file

@ -0,0 +1,30 @@
== New variables
[cols="1a,1a"]
|====
| Variable | Description
|
**family2.var2** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `standard` `mandatory` |
A variable2. +
**Default**: the value of the variable "family.var2".
|
**family2.var3** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `standard` `mandatory` |
A third variable. +
**Default**: string4 +
**Example**: string5
|
**family2.subfamily.variable** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `standard` `mandatory` `unique` `multiple` |
Fourth variable. +
**Default**:
* the value of the variable "var1"
* the value of the variable "family.var2"
* the value of the variable "family2.var3"
|====

View file

@ -0,0 +1,24 @@
New variables
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
family2.var2 │ A variable2. │
 string   standard   mandatory  │ Default: the value of the variable │
│ │ "family.var2". │
├───────────────────────────────────────┼──────────────────────────────────────┤
family2.var3 │ A third variable. │
 string   standard   mandatory  │ Default: string4 │
│ │ Example: string5 │
├───────────────────────────────────────┼──────────────────────────────────────┤
family2.subfamily.variable │ Fourth variable. │
 string   standard   mandatory    │ Default: │
unique   multiple  │ - the value of the variable "var1"
│ │ - the value of the variable │
│ │ "family.var2"
│ │ - the value of the variable │
│ │ "family2.var3"
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,8 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
variable_to_family: # a variable that became a family
...

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
variable_to_family: # a variable that became a family
var:
description: a second variable
...

View file

@ -0,0 +1,17 @@
== New variable
[cols="1a,1a"]
|====
| Variable | Description
|
**variable_to_family** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
A variable that became a family.
|====
== Deleted variable
* variable_to_family.var

View file

@ -0,0 +1,18 @@
New variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
variable_to_family │ A variable that became a family. │
 string   basic   mandatory  │ │
└───────────────────────────────────────┴──────────────────────────────────────┘
Deleted variable
- variable_to_family.var

View file

@ -0,0 +1,41 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,39 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,12 @@
== New variable
[cols="1a,1a"]
|====
| Variable | Description
|
**family.var3** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
A third variable.
|====

View file

@ -0,0 +1,11 @@
New variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
family.var3 │ A third variable. │
 string   basic   mandatory  │ │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
variable_to_family: # a variable that became a family
var:
description: a second variable
...

View file

@ -0,0 +1,8 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
variable_to_family: # a variable that became a family
...

View file

@ -0,0 +1,17 @@
== New variable
[cols="1a,1a"]
|====
| Variable | Description
|
**variable_to_family.var** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
A second variable.
|====
== Deleted variable
* variable_to_family

View file

@ -0,0 +1,18 @@
New variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
variable_to_family.var │ A second variable. │
 string   basic   mandatory  │ │
└───────────────────────────────────────┴──────────────────────────────────────┘
Deleted variable
- variable_to_family

View file

@ -0,0 +1,43 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
var4: # a fourth variable
...

View file

@ -0,0 +1,39 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,17 @@
== New variables
[cols="1a,1a"]
|====
| Variable | Description
|
**family.var3** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
A third variable.
|
**family2.var4** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
A fourth variable.
|====

View file

@ -0,0 +1,14 @@
New variables
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
family.var3 │ A third variable. │
 string   basic   mandatory  │ │
├───────────────────────────────────────┼──────────────────────────────────────┤
family2.var4 │ A fourth variable. │
 string   basic   mandatory  │ │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,21 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
...

View file

@ -0,0 +1,41 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,7 @@
== Deleted variables
* family2.var2
* family2.var3
* family2.subfamily.variable

View file

@ -0,0 +1,9 @@
Deleted variables
- family2.var2
- family2.var3
- family2.subfamily.variable

View file

@ -0,0 +1,39 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,41 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,5 @@
== Deleted variable
* family.var3

View file

@ -0,0 +1,7 @@
Deleted variable
- family.var3

View file

@ -0,0 +1,39 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
...

View file

@ -0,0 +1,43 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
family: # a family
var2:
description: a second variable
test:
- string6
subfamily: # a sub family
variable: # third variable
- variable: ___.var1
- variable: __.var2
var3: # a third variable
family2: # a family
var2:
description: a variable2
default:
variable: __.family.var2
var3:
description: a third variable
test:
- string5
default: string4
subfamily: # a sub family
variable: # fourth variable
- variable: ___.var1
- variable: ___.family.var2
- variable: __.var3
var4: # a fourth variable
...

View file

@ -0,0 +1,6 @@
== Deleted variables
* family.var3
* family2.var4

View file

@ -0,0 +1,8 @@
Deleted variables
- family.var3
- family2.var4

View file

@ -0,0 +1,6 @@
%YAML 1.2
---
version: 1.1
var1: # new description
...

View file

@ -0,0 +1,6 @@
%YAML 1.2
---
version: 1.1
var1: # first variable
...

View file

@ -0,0 +1,13 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
+++First variable.+++ +
#New description.#
|====

View file

@ -0,0 +1,11 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 string   basic   mandatory  │ New description. │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,8 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
help: modified help
...

View file

@ -0,0 +1,8 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
help: first help
...

View file

@ -0,0 +1,14 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
First variable. +
+++First help.+++ +
#Modified help.#
|====

View file

@ -0,0 +1,12 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 string   basic   mandatory  │ First help. │
│ │ Modified help. │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
validators:
- jinja: |
{% if _.var1 == "not valid2" %}
not valid2
{% endif %}
description: '"not valid2" is not allowed'
...

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
validators:
- jinja: |
{% if _.var1 == "not valid1" %}
not valid1
{% endif %}
description: '"not valid1" is not allowed'
...

View file

@ -0,0 +1,15 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
First variable. +
**Validator**:
+++"not valid1" is not allowed.+++ +
#"not valid2" is not allowed.#
|====

View file

@ -0,0 +1,13 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 string   basic   mandatory  │ Validator: "not valid1" is not  │
│ │ allowed. │
│ │ "not valid2" is not allowed. │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,18 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
validators:
- jinja: |
{% if _.var1 == "not valid1" %}
not valid1
{% endif %}
description: '"not valid1" is not allowed'
- jinja: |
{% if _.var1 == "not valid3" %}
not valid3
{% endif %}
description: '"not valid3" is not allowed'
...

View file

@ -0,0 +1,18 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
validators:
- jinja: |
{% if _.var1 == "not valid1" %}
not valid1
{% endif %}
description: '"not valid1" is not allowed'
- jinja: |
{% if _.var1 == "not valid2" %}
not valid2
{% endif %}
description: '"not valid2" is not allowed'
...

View file

@ -0,0 +1,17 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
First variable. +
**Validators**:
* +++"not valid2" is not allowed.+++
* '"not valid1" is not allowed.'
* '#"not valid3" is not allowed.#'
|====

View file

@ -0,0 +1,14 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 string   basic   mandatory  │ Validators: │
│ │ - "not valid2" is not allowed. │
│ │ - "not valid1" is not allowed. │
│ │ - "not valid3" is not allowed. │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,23 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
validators:
- jinja: |
{% if _.var1 == "not valid4" %}
not valid4
{% endif %}
description: '"not valid4" is not allowed'
- jinja: |
{% if _.var1 == "not valid2" %}
not valid2
{% endif %}
description: '"not valid2" is not allowed'
- jinja: |
{% if _.var1 == "not valid5" %}
not valid5
{% endif %}
description: '"not valid5" is not allowed'
...

View file

@ -0,0 +1,23 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
validators:
- jinja: |
{% if _.var1 == "not valid1" %}
not valid1
{% endif %}
description: '"not valid1" is not allowed'
- jinja: |
{% if _.var1 == "not valid2" %}
not valid2
{% endif %}
description: '"not valid2" is not allowed'
- jinja: |
{% if _.var1 == "not valid3" %}
not valid3
{% endif %}
description: '"not valid3" is not allowed'
...

View file

@ -0,0 +1,19 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` |
First variable. +
**Validators**:
* +++"not valid1" is not allowed.+++
* +++"not valid3" is not allowed.+++
* '#"not valid4" is not allowed.#'
* '"not valid2" is not allowed.'
* '#"not valid5" is not allowed.#'
|====

View file

@ -0,0 +1,16 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 string   basic   mandatory  │ Validators: │
│ │ - "not valid1" is not allowed. │
│ │ - "not valid3" is not allowed. │
│ │ - "not valid4" is not allowed. │
│ │ - "not valid2" is not allowed. │
│ │ - "not valid5" is not allowed. │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
default: val2
...

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
default: val1
...

View file

@ -0,0 +1,16 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `standard` `mandatory` |
First variable. +
**Choices**:
* val1 +++← (default)+++
* 'val2 #**← (default)**#'
|====

View file

@ -0,0 +1,13 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 choice   standard   mandatory  │ Choices: │
│ │ - val1 ← (default) │
│ │ - val2 ← (default) │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
source_variable_1: val1 # the first source variable
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
- variable: _.source_variable_1
- variable: _.source_variable_2
default:
variable: _.source_variable_1
...

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
source_variable_1: val1 # the first source variable
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
- val1
- val2
default: val1
...

View file

@ -0,0 +1,18 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**my_variable** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `standard` `mandatory` |
A variable. +
**Choices**:
* +++val1 ← (default)+++
* +++val2+++
* '#the value of the variable "source_variable_1" **← (default)**#'
* '#the value of the variable "source_variable_2"#'
|====

View file

@ -0,0 +1,17 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
my_variable │ A variable. │
 choice   standard   mandatory  │ Choices: │
│ │ - val1 ← (default) │
│ │ - val2 │
│ │ - the value of the variable  │
│ │ "source_variable_1" ← (default) │
│ │ - the value of the variable  │
│ │ "source_variable_2" │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
source_variable_1: val1 # the first source variable
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
- val1
- val2
default: val1
...

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
source_variable_1: val1 # the first source variable
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
- variable: _.source_variable_1
- variable: _.source_variable_2
default:
variable: _.source_variable_1
...

View file

@ -0,0 +1,18 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**my_variable** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `standard` `mandatory` |
A variable. +
**Choices**:
* +++the value of the variable "source_variable_1" ← (default)+++
* +++the value of the variable "source_variable_2"+++
* '#val1 **← (default)**#'
* '#val2#'
|====

View file

@ -0,0 +1,17 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
my_variable │ A variable. │
 choice   standard   mandatory  │ Choices: │
│ │ - the value of the variable  │
│ │ "source_variable_1"(default) │
│ │ - the value of the variable  │
│ │ "source_variable_2" │
│ │ - val1 ← (default) │
│ │ - val2 │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
source_variable_1: # the first source variable
- val1
- val2
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
variable: _.source_variable_1
...

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
source_variable_1: # the first source variable
- val1
- val2
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
- val1
- val2
...

View file

@ -0,0 +1,17 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**my_variable** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `basic` `mandatory` |
A variable. +
**Choices**:
* +++val1+++
* +++val2+++
* '#the value of the variable "source_variable_1".#'
|====

View file

@ -0,0 +1,15 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
my_variable │ A variable. │
 choice   basic   mandatory  │ Choices: │
│ │ - val1 │
│ │ - val2 │
│ │ - the value of the variable  │
│ │ "source_variable_1". │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
source_variable_1: # the first source variable
- val1
- val2
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
- val1
- val2
...

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
source_variable_1: # the first source variable
- val1
- val2
source_variable_2: val2 # the second source variable
my_variable:
description: a variable
choices:
variable: _.source_variable_1
...

View file

@ -0,0 +1,17 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**my_variable** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `basic` `mandatory` |
A variable. +
**Choices**:
* +++the value of the variable "source_variable_1".+++
* '#val1#'
* '#val2#'
|====

View file

@ -0,0 +1,15 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
my_variable │ A variable. │
 choice   basic   mandatory  │ Choices: │
│ │ - the value of the variable  │
│ │ "source_variable_1". │
│ │ - val1 │
│ │ - val2 │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
default: val2
...

View file

@ -0,0 +1,10 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
...

View file

@ -0,0 +1,16 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`+++basic+++` `https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `#standard#` `mandatory` |
First variable. +
**Choices**:
* val1
* 'val2 #**← (default)**#'
|====

View file

@ -0,0 +1,13 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 basic   choice   standard    │ Choices: │
mandatory  │ - val1 │
│ │ - val2 ← (default) │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,12 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- null
- val1
- val2
default: val2
...

View file

@ -0,0 +1,12 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- null
- val1
- val2
default: null
...

View file

@ -0,0 +1,17 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`+++basic+++` `+++mandatory+++` `https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `#standard#` |
First variable. +
**Choices**:
* null +++← (default)+++
* val1
* 'val2 #**← (default)**#'
|====

View file

@ -0,0 +1,14 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 basic   mandatory   choice    │ Choices: │
standard  │ - null ← (default) │
│ │ - val1 │
│ │ - val2 ← (default) │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
default: val2
...

View file

@ -0,0 +1,12 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
- val3
default: val3
...

View file

@ -0,0 +1,17 @@
== Modified variable
[cols="1a,1a"]
|====
| Variable | Description
|
**var1** +
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[choice]` `standard` `mandatory` |
First variable. +
**Choices**:
* +++val3 ← (default)+++
* val1
* 'val2 #**← (default)**#'
|====

View file

@ -0,0 +1,14 @@
Modified variable
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Variable  ┃ Description  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
var1 │ First variable. │
 choice   standard   mandatory  │ Choices: │
│ │ - val3 ← (default) │
│ │ - val1 │
│ │ - val2 ← (default) │
└───────────────────────────────────────┴──────────────────────────────────────┘

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
default: val2
...

View file

@ -0,0 +1,12 @@
%YAML 1.2
---
version: 1.1
var1:
description: first variable
choices:
- val1
- val2
- val3
default: val2
...

Some files were not shown because too many files have changed in this diff Show more