Compare commits
132 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 948e0b49ed | |||
| 3cde479202 | |||
| 77e311dedf | |||
| 2b9c251780 | |||
| 0b7f1fe087 | |||
| e48c55a8f2 | |||
| 103adeddf4 | |||
| 4bf2f778ac | |||
| d0915ff83d | |||
| 4f475be53e | |||
| a400088e2d | |||
| 4b215ce407 | |||
| 64f448c141 | |||
| d8a0e22de9 | |||
| 8afb61c5ad | |||
| c754f5c654 | |||
| bd1d85442e | |||
| ecf3570b79 | |||
| 9d8be3880a | |||
| 2961a61aa6 | |||
| ce96cad54d | |||
| 9bbb60c460 | |||
| 72fa10208e | |||
| a913be6b52 | |||
| bd44db892c | |||
| afb85063ac | |||
| a0843e08ca | |||
| c1ab106ba5 | |||
| cb770dd8d7 | |||
| fc4c2221d1 | |||
| a92f447478 | |||
| b4ce22a0af | |||
| 6dd6df77a1 | |||
| bebea05e7c | |||
| e97f4b4ca6 | |||
| a79a420ba5 | |||
| 641ab723e0 | |||
| da1519071e | |||
| 622764bf53 | |||
| 856811805c | |||
| 38fa8447eb | |||
| c5134247a0 | |||
| a5dc507c65 | |||
| 550996f22a | |||
| 5652757787 | |||
| a307cb1c66 | |||
| 1cbe8377e0 | |||
| 3af6ee631c | |||
| d022e44e1d | |||
| 9a0219ce55 | |||
| 17b589c268 | |||
| 53e1261812 | |||
| ef0aca7e55 | |||
| 86dce82a57 | |||
| 777346d070 | |||
| 213c25c8f6 | |||
| 242b6505ce | |||
| f5dc501bf9 | |||
| 154238c46e | |||
| 1fe10dbe20 | |||
| 2652fc9db6 | |||
| 2a7f78103b | |||
| 02778fe53b | |||
| 1718a76ce9 | |||
| a8c682d76c | |||
| 706ddd369e | |||
| 25dc2874b2 | |||
| 3dfc3ab166 | |||
| 263dae2b2c | |||
| 561d117d4d | |||
| 8f2c4b0011 | |||
| 94c7922782 | |||
| c9a0f2d1ec | |||
| 5e325f744d | |||
| f911425e1a | |||
| b60792314e | |||
| 2886cf0348 | |||
| f0f3fc899d | |||
| 96866e99a4 | |||
| d8e52e26fd | |||
| 07027690a7 | |||
| 19767f346d | |||
| 726c64e23d | |||
| abbeb78dbb | |||
| aaf3f95126 | |||
| aeff3e8b7c | |||
| 0f96fa0123 | |||
| d69d0cc8e8 | |||
| 81ff417107 | |||
| a7ede66aa7 | |||
| b4dfa14602 | |||
| a2e1d7746e | |||
| b8f3e71314 | |||
| bb5caa5388 | |||
| fd8a2843ba | |||
| 8e5cc2622e | |||
| 22e839027d | |||
| fcac55ae92 | |||
| d3b1462db5 | |||
| 737ddc0f43 | |||
| 5c9c102245 | |||
| fd54b9ca00 | |||
| 83614a2a5e | |||
| 8e6200b321 | |||
| 1364083ffb | |||
| 604cfa0a1d | |||
| 97a8653b28 | |||
| 76d7c968fe | |||
| 693050b195 | |||
| d927f60769 | |||
| 53de7569ee | |||
| 3f3f6aa495 | |||
| affd645ebd | |||
| 7f003a574b | |||
| 495336c146 | |||
| 60b4a06807 | |||
| 88aca6b0ea | |||
| 1903ee8031 | |||
| 135936782f | |||
| 705239141e | |||
| 673e89e5e1 | |||
| cac294b800 | |||
| 58ee0f3106 | |||
| e6a38423ef | |||
| 1f37457b9f | |||
| 9f5d0e2497 | |||
| af652eda76 | |||
| 3d4b7b945c | |||
| 3cc85d7ba5 | |||
| 12622032a8 | |||
| d805cbf565 | |||
| 46eeb49c5f |
17291 changed files with 277479 additions and 26153 deletions
319
CHANGELOG.md
319
CHANGELOG.md
|
|
@ -1,3 +1,322 @@
|
|||
## 0.2.0a39 (2025-11-21)
|
||||
|
||||
### Feat
|
||||
|
||||
- change path in description
|
||||
- add anchor to markdown format and remove unsupported character in anchor id
|
||||
- use blockquote for family description
|
||||
|
||||
### Fix
|
||||
|
||||
- dynamic variables with identifier in description
|
||||
- gitlab id in anchor with dynamic variables
|
||||
|
||||
## 0.2.0a38 (2025-11-10)
|
||||
|
||||
### Feat
|
||||
|
||||
- better enter support
|
||||
|
||||
## 0.2.0a37 (2025-11-06)
|
||||
|
||||
### Feat
|
||||
|
||||
- delete/underline is inside tag for some format
|
||||
- can reload formatter
|
||||
- can document part by part with reloading structure
|
||||
|
||||
## 0.2.0a36 (2025-10-29)
|
||||
|
||||
### Feat
|
||||
|
||||
- anchor in gitlab output_format
|
||||
- can had comments with family/variable description in examples doc
|
||||
- comment variables from a family
|
||||
|
||||
## 0.2.0a35 (2025-10-27)
|
||||
|
||||
### Feat
|
||||
|
||||
- tags documentation
|
||||
|
||||
### Fix
|
||||
|
||||
- add changelog support for github/gitlab format
|
||||
- tests
|
||||
|
||||
## 0.2.0a34 (2025-10-22)
|
||||
|
||||
### Feat
|
||||
|
||||
- ca force true_color terminal when export to console
|
||||
|
||||
### Fix
|
||||
|
||||
- parse subtree for a dynamic
|
||||
- adapt api for rougail-web-ui
|
||||
- undocumented variable in dynamic
|
||||
|
||||
## 0.2.0a33 (2025-10-16)
|
||||
|
||||
### Feat
|
||||
|
||||
- can document a variable for a specified identifier
|
||||
- can remove header when generate a table
|
||||
- add html output
|
||||
- changelog for variables
|
||||
|
||||
### Fix
|
||||
|
||||
- support rougail-web-ui
|
||||
- black
|
||||
- remove extra '*'
|
||||
- always use name for informations key (sometime path was used)
|
||||
- update tests
|
||||
- translation for property is now in rougail
|
||||
|
||||
## 0.2.0a32 (2025-10-03)
|
||||
|
||||
### Fix
|
||||
|
||||
- property calculated with disabled variable
|
||||
- better disabled support
|
||||
|
||||
## 0.2.0a31 (2025-10-02)
|
||||
|
||||
### Feat
|
||||
|
||||
- limit warning when asked
|
||||
|
||||
## 0.2.0a30 (2025-10-02)
|
||||
|
||||
### Feat
|
||||
|
||||
- better support variable calculation for property
|
||||
|
||||
## 0.2.0a29 (2025-10-02)
|
||||
|
||||
### Fix
|
||||
|
||||
- property for namespace
|
||||
|
||||
## 0.2.0a28 (2025-10-02)
|
||||
|
||||
### Feat
|
||||
|
||||
- add gitlab plugin
|
||||
|
||||
### Fix
|
||||
|
||||
- tests for formatter
|
||||
- update translation
|
||||
|
||||
## 0.2.0a27 (2025-09-29)
|
||||
|
||||
### Fix
|
||||
|
||||
- doc network with CIDR format
|
||||
- better doc for calculation with unknown variable
|
||||
|
||||
## 0.2.0a26 (2025-09-29)
|
||||
|
||||
### Feat
|
||||
|
||||
- default value for a calculated variable with an unknown optional variable
|
||||
- add integer type which will replace number type
|
||||
|
||||
## 0.2.0a25 (2025-09-22)
|
||||
|
||||
### Feat
|
||||
|
||||
- adapt to tiramisu-web-ui
|
||||
|
||||
## 0.2.0a24 (2025-06-19)
|
||||
|
||||
### Feat
|
||||
|
||||
- could not change default value during annotator
|
||||
|
||||
## 0.2.0a23 (2025-06-18)
|
||||
|
||||
### Fix
|
||||
|
||||
- separation
|
||||
|
||||
## 0.2.0a22 (2025-06-18)
|
||||
|
||||
### Fix
|
||||
|
||||
- rougail separation
|
||||
|
||||
## 0.2.0a21 (2025-05-12)
|
||||
|
||||
### Fix
|
||||
|
||||
- update translation
|
||||
- black
|
||||
- doc example with leader example lower than leader default value
|
||||
|
||||
## 0.2.0a20 (2025-05-09)
|
||||
|
||||
### Fix
|
||||
|
||||
- undefined is a rougail object
|
||||
|
||||
## 0.2.0a19 (2025-05-05)
|
||||
|
||||
### Fix
|
||||
|
||||
- update translation
|
||||
|
||||
## 0.2.0a18 (2025-05-05)
|
||||
|
||||
### Fix
|
||||
|
||||
- doc default value with undocumented variable
|
||||
|
||||
## 0.2.0a17 (2025-05-05)
|
||||
|
||||
### Fix
|
||||
|
||||
- description for all calculations
|
||||
- better documentation variable with variable in default attribut
|
||||
|
||||
## 0.2.0a16 (2025-04-30)
|
||||
|
||||
### Fix
|
||||
|
||||
- update translation
|
||||
- remove negative_description support
|
||||
- better documentation with hidden variable in property calculation
|
||||
- use new information ymlfiles
|
||||
- update tests
|
||||
- better dynamic support
|
||||
|
||||
## 0.2.0a15 (2025-04-09)
|
||||
|
||||
### Fix
|
||||
|
||||
- version
|
||||
|
||||
## 0.2.0a14 (2025-04-07)
|
||||
|
||||
### Fix
|
||||
|
||||
- calculation for dynamic ans leadership variables
|
||||
|
||||
## 0.2.0a13 (2025-04-02)
|
||||
|
||||
### Fix
|
||||
|
||||
- error in disabled dynamic variable
|
||||
|
||||
## 0.2.0a12 (2025-04-01)
|
||||
|
||||
### Fix
|
||||
|
||||
- update tests
|
||||
- groups.namespace could be unexistant
|
||||
|
||||
## 0.2.0a11 (2025-03-31)
|
||||
|
||||
### Fix
|
||||
|
||||
- doc a param with a set but with only one item
|
||||
|
||||
## 0.2.0a10 (2025-03-30)
|
||||
|
||||
### Feat
|
||||
|
||||
- document unix file name parameters
|
||||
- better console output
|
||||
- do not document reference to undocumented variable
|
||||
|
||||
### Fix
|
||||
|
||||
- doc for param
|
||||
- support NamespaceCalculation
|
||||
- convert <ENV> to <ENV> for github plugin
|
||||
|
||||
## 0.2.0a9 (2025-02-19)
|
||||
|
||||
### Fix
|
||||
|
||||
- support suffix (in version 1.0 format) in calculation
|
||||
|
||||
## 0.2.0a8 (2025-02-19)
|
||||
|
||||
### Fix
|
||||
|
||||
- key is the path
|
||||
|
||||
## 0.2.0a7 (2025-02-19)
|
||||
|
||||
### Fix
|
||||
|
||||
- with_family => without_family and with_example => example
|
||||
|
||||
## 0.2.0a6 (2025-02-17)
|
||||
|
||||
### Feat
|
||||
|
||||
- add with_family parameter
|
||||
|
||||
## 0.2.0a5 (2025-02-17)
|
||||
|
||||
### Fix
|
||||
|
||||
- do not add multiple attribute several time in json export
|
||||
|
||||
## 0.2.0a4 (2025-02-10)
|
||||
|
||||
### Feat
|
||||
|
||||
- output return status too
|
||||
|
||||
## 0.2.0a3 (2025-01-04)
|
||||
|
||||
### Fix
|
||||
|
||||
- detect_symlink => only_self
|
||||
|
||||
## 0.2.0a2 (2025-01-04)
|
||||
|
||||
### Feat
|
||||
|
||||
- create tests
|
||||
|
||||
### Fix
|
||||
|
||||
- do not document symlink
|
||||
- remove prefix_path
|
||||
|
||||
## 0.2.0a1 (2024-11-28)
|
||||
|
||||
### Fix
|
||||
|
||||
- separation between run and print function
|
||||
|
||||
## 0.2.0a0 (2024-11-20)
|
||||
|
||||
### Feat
|
||||
|
||||
- personalize mode that we want disable documentation
|
||||
- add console output
|
||||
- better dynamique family support
|
||||
- add json output
|
||||
|
||||
### Fix
|
||||
|
||||
- correction for properties in italic
|
||||
|
||||
## 0.1.1a0 (2024-11-08)
|
||||
|
||||
### Fix
|
||||
|
||||
- generate documentation with force_optional configuration
|
||||
|
||||
## 0.1.0 (2024-11-06)
|
||||
|
||||
## 0.1.0rc1 (2024-11-06)
|
||||
|
||||
### Fix
|
||||
|
|
|
|||
81
README.fr.md
Normal file
81
README.fr.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
[🇬🇧 (EN)](README.md) - [🇫🇷 (FR)](README.fr.md)
|
||||
|
||||
## Générer la documentation depuis les fichiers de structure
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> Les fichiers de structure contiennent toutes les informations relatif aux variables. Cette sortie génère la documentation pour tout ou partie de ces variables.\
|
||||
> **Chemin** : doc\
|
||||
> *`désactivé`*\
|
||||
> **Désactivé** : si doc n'est pas spécifié dans "[Sélection pour sortie](#step.output)"
|
||||
|
||||
| Variable | Description | Valeur par défaut | Type | Contrôle des accès | Validateur |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|-------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.output_format" name="doc.output_format">doc.output_format</a>**<br/>**Ligne de commande** : -do, --doc.output_format<br/>**Variable d'environnement** : ROUGAILCLI_DOC.OUTPUT_FORMAT | Le format de sortie de la documentation générée. | console | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | | **Choix** : <br/>• console<br/>• asciidoc<br/>• html<br/>• github<br/>• gitlab<br/>• json |
|
||||
| **<a id="doc.tabular_template" name="doc.tabular_template">doc.tabular_template</a>**<br/>**Ligne de commande** : -dm, --doc.tabular_template<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TABULAR_TEMPLATE | Génère la documentation avec ce modèle de tableau.<br/>Les variables sont documentées avec une vue tableau. Une sélection de modèle vous permet de choisir le contenu de chaque colonne. | two_columns | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | *`désactivé`*<br/>**Désactivé** : "[Le format de sortie de la documentation générée](#doc.output_format)" en json n\'est pas compatible avec cette variable<br/> | **Choix** : <br/>• two_columns<br/>• three_columns<br/>• four_columns<br/>• five_columns<br/>• six_columns |
|
||||
| **<a id="doc.contents" name="doc.contents">doc.contents</a>**<br/>**Ligne de commande** : -dc, --doc.contents<br/>**Variable d'environnement** : ROUGAILCLI_DOC.CONTENTS | Contenu généré.<br/>Vous pouvez générer trois type de documentation. Toutes les variables ("variables"), un exemple de fichier au format YAML ("example") ou le journal des changements ("changelog"). | • variables | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` `obligatoire` | *`cachée`*<br/>**Cachée** : "[Le format de sortie de la documentation générée](#doc.output_format)" en json n'est pas compatible avec "[Contenu généré](#doc.contents)" changelog or example<br/> | `unique`<br/>**Choix** : <br/>• variables<br/>• example<br/>• changelog |
|
||||
| **<a id="doc.title_level" name="doc.title_level">doc.title_level</a>**<br/>**Ligne de commande** : -dt, --doc.title_level<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TITLE_LEVEL | Niveau de titre de départ. | 1 | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | | |
|
||||
| **<a id="doc.default_values" name="doc.default_values">doc.default_values</a>**<br/>**Ligne de commande** : <br/>• --doc.default_values<br/>• --doc.no-default_values<br/>**Variable d'environnement** : ROUGAILCLI_DOC.DEFAULT_VALUES | Modifier les valeurs pour documenter toutes les variables.<br/>Pour documenter les variables des leadership ou des familles dynamiques, il est parfois nécessaire de générer des valeurs, qui peuvent modifier les valeurs de la configuration. Soyez vigilent si vous réutilisez cette configuration. | true | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | | |
|
||||
| **<a id="doc.true_color" name="doc.true_color">doc.true_color</a>**<br/>**Ligne de commande** : <br/>• --doc.true_color<br/>• --doc.no-true_color<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TRUE_COLOR | Afficher la documentation dans la console en permanence avec un terminal en couleurs réelles. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | *`désactivé`*<br/>**Désactivé** : lorsque la variable "[Le format de sortie de la documentation générée](#doc.output_format)" n'a pas la valeur "console" | |
|
||||
| **<a id="doc.root" name="doc.root">doc.root</a>**<br/>**Ligne de commande** : -dr, --doc.root<br/>**Variable d'environnement** : ROUGAILCLI_DOC.ROOT | Documenter les variables enfants de cette famille.<br/>Par défaut, toute les variables accessibles sont incluent dans la documentation. Il est possible de définir une famille a partir de laquelle la documentation doit être générée. | | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | | |
|
||||
|
||||
### Les variables pour cette famille sont documentés dans un autre fichier
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> Si vous séparez les variables dans différents fichiers, le lien entre les variables va être cassé. Dans ce cas, vous devez définit différents nom de fichiers pour les fichiers contenant ces variables.\
|
||||
> Cette famille contient des listes de bloc de variable.\
|
||||
> **Chemin** : doc.other_root_filenames\
|
||||
> *`désactivé`*\
|
||||
> **Désactivé** : lorsque la variable "[Documenter les variables enfants de cette famille](#doc.root)" a la valeur "null"
|
||||
|
||||
| Variable | Description | Type | Validateur |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|---------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.other_root_filenames.root_path" name="doc.other_root_filenames.root_path">doc.other_root_filenames.root_path</a>**<br/>**Ligne de commande** : --doc.other_root_filenames.root_path<br/>**Variable d'environnement** : ROUGAILCLI_DOC.OTHER_ROOT_FILENAMES.ROOT_PATH | Ce fichier contient les variables enfants de la famille. | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` | `unique` |
|
||||
| **<a id="doc.other_root_filenames.filename" name="doc.other_root_filenames.filename">doc.other_root_filenames.filename</a>**<br/>**Ligne de commande** : --doc.other_root_filenames.filename<br/>**Variable d'environnement** : ROUGAILCLI_DOC.OTHER_ROOT_FILENAMES.FILENAME | Nom du fichier. | [`UNIX filename`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | • this filename could be a relative path<br/>• file type allowed: "file". |
|
||||
|
||||
### Documentation des variables et journal de changements
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> **Chemin** : doc.tabulars\
|
||||
> *`désactivé`*\
|
||||
> **Désactivé** : si "[Le format de sortie de la documentation générée](#doc.output_format)" en json ou si "[Contenu généré](#doc.contents)" n'est pas variables ou changelog
|
||||
|
||||
| Variable | Description | Valeur par défaut | Type | Contrôle des accès | Validateur |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
|
||||
| **<a id="doc.tabulars.without_family" name="doc.tabulars.without_family">doc.tabulars.without_family</a>**<br/>**Ligne de commande** : <br/>• -df, --doc.tabulars.without_family<br/>• -ndf, --doc.tabulars.no-without_family<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TABULARS.WITHOUT_FAMILY | Ne pas ajouter les familles dans la documentation. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | | |
|
||||
| **<a id="doc.tabulars.with_commandline" name="doc.tabulars.with_commandline">doc.tabulars.with_commandline</a>**<br/>**Ligne de commande** : <br/>• -dw, --doc.tabulars.with_commandline<br/>• -ndw, --doc.tabulars.no-with_commandline<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TABULARS.WITH_COMMANDLINE | Ajoute les informations de la ligne de commande dans la documentation. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | | |
|
||||
| **<a id="doc.tabulars.with_environment" name="doc.tabulars.with_environment">doc.tabulars.with_environment</a>**<br/>**Ligne de commande** : <br/>• -de, --doc.tabulars.with_environment<br/>• -nde, --doc.tabulars.no-with_environment<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TABULARS.WITH_ENVIRONMENT | Ajoute les informations de variable d'environnement dans la documentation. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | | |
|
||||
| **<a id="doc.tabulars.environment_prefix" name="doc.tabulars.environment_prefix">doc.tabulars.environment_prefix</a>**<br/>**Ligne de commande** : -dv, --doc.tabulars.environment_prefix<br/>**Variable d'environnement** : ROUGAILCLI_DOC.TABULARS.ENVIRONMENT_PREFIX | Préfixe du nom des variables d'environnement. | ROUGAIL | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | *`désactivé`*<br/>**Désactivé** : si "main_namespace" n'est pas défini ou "[Ajoute les informations de variable d'environnement dans la documentation](#doc.tabulars.with_environment)" est false | Doit seulement utilise des caractères en majuscule. |
|
||||
|
||||
### Documentation du journal des changements
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> **Chemin** : doc.changelog\
|
||||
> *`désactivé`*\
|
||||
> **Désactivé** : changelog n'est pas défini dans "[Contenu généré](#doc.contents)"
|
||||
|
||||
| Variable | Description | Type |
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.changelog.previous_json_file" name="doc.changelog.previous_json_file">doc.changelog.previous_json_file</a>**<br/>**Ligne de commande** : -dp, --doc.changelog.previous_json_file<br/>**Variable d'environnement** : ROUGAILCLI_DOC.CHANGELOG.PREVIOUS_JSON_FILE | Précédent fichier de description au format JSON.<br/>Pour générer le journal des changements, vous devez comparer l'ancienne liste des variables (au format json) avec les variables courantes. | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` |
|
||||
|
||||
### Configuration des exemples
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> **Chemin** : doc.examples\
|
||||
> *`désactivé`*\
|
||||
> **Désactivé** : si example n'est pas défini dans "[Contenu généré](#doc.contents)"
|
||||
|
||||
| Variable | Description | Valeur par défaut | Type | Contrôle des accès |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.examples.comment" name="doc.examples.comment">doc.examples.comment</a>**<br/>**Ligne de commande** : <br/>• -dx, --doc.examples.comment<br/>• -ndx, --doc.examples.no-comment<br/>**Variable d'environnement** : ROUGAILCLI_DOC.EXAMPLES.COMMENT | Ajouter la description des variables et des familles lorsqu'on génère des exemples. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | |
|
||||
| **<a id="doc.examples.comment_column" name="doc.examples.comment_column">doc.examples.comment_column</a>**<br/>**Ligne de commande** : --doc.examples.comment_column<br/>**Variable d'environnement** : ROUGAILCLI_DOC.EXAMPLES.COMMENT_COLUMN | Commentaire dans les exemples commence à la colonne. | 30 | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | *`désactivé`*<br/>**Désactivé** : lorsque la variable "[Ajouter la description des variables et des familles lorsqu'on génère des exemples](#doc.examples.comment)" a la valeur "false" |
|
||||
|
||||
|
||||
81
README.md
81
README.md
|
|
@ -1,2 +1,81 @@
|
|||
# rougaildoc
|
||||
---
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
[🇬🇧 (EN)](README.md) - [🇫🇷 (FR)](README.fr.md)
|
||||
|
||||
## Generate documentation from structural files
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> The structural files contain all the information related to the variables. This output generates the documentation for all or some of these variables.\
|
||||
> **Path**: doc\
|
||||
> *`disabled`*\
|
||||
> **Disabled**: if doc is not set in "[Select for output](#step.output)"
|
||||
|
||||
| Variable | Description | Default value | Type | Access control | Validator |
|
||||
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|-----------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.output_format" name="doc.output_format">doc.output_format</a>**<br/>**Command line**: -do, --doc.output_format<br/>**Environment variable**: ROUGAILCLI_DOC.OUTPUT_FORMAT | The output format of the generated documentation. | console | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | | **Choices**: <br/>• console<br/>• asciidoc<br/>• html<br/>• github<br/>• gitlab<br/>• json |
|
||||
| **<a id="doc.tabular_template" name="doc.tabular_template">doc.tabular_template</a>**<br/>**Command line**: -dm, --doc.tabular_template<br/>**Environment variable**: ROUGAILCLI_DOC.TABULAR_TEMPLATE | Generate document with this tabular model.<br/>The variables are documented with a tabular view. A template selection allows you to choose the content of each column. | two_columns | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | *`disabled`*<br/>**Disabled**: "[The output format of the generated documentation](#doc.output_format)" in json is not compatible with this variable<br/> | **Choices**: <br/>• two_columns<br/>• three_columns<br/>• four_columns<br/>• five_columns<br/>• six_columns |
|
||||
| **<a id="doc.contents" name="doc.contents">doc.contents</a>**<br/>**Command line**: -dc, --doc.contents<br/>**Environment variable**: ROUGAILCLI_DOC.CONTENTS | Generated content.<br/>You can generate three type of document. All variables ("variables"), an example file in YAML format ("example") or change log ("changelog"). | • variables | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` `mandatory` | *`hidden`*<br/>**Hidden**: "[The output format of the generated documentation](#doc.output_format)" in json is not compatible with changelog or example "[Generated content](#doc.contents)"<br/> | `unique`<br/>**Choices**: <br/>• variables<br/>• example<br/>• changelog |
|
||||
| **<a id="doc.title_level" name="doc.title_level">doc.title_level</a>**<br/>**Command line**: -dt, --doc.title_level<br/>**Environment variable**: ROUGAILCLI_DOC.TITLE_LEVEL | Starting title level. | 1 | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | | |
|
||||
| **<a id="doc.default_values" name="doc.default_values">doc.default_values</a>**<br/>**Command line**: <br/>• --doc.default_values<br/>• --doc.no-default_values<br/>**Environment variable**: ROUGAILCLI_DOC.DEFAULT_VALUES | Modify values to document all variables.<br/>To document leadership or dynamic family variables, it is sometimes necessary to generate values, which can change the values in the configuration. Be careful if you reuse this configuration. | true | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | | |
|
||||
| **<a id="doc.true_color" name="doc.true_color">doc.true_color</a>**<br/>**Command line**: <br/>• --doc.true_color<br/>• --doc.no-true_color<br/>**Environment variable**: ROUGAILCLI_DOC.TRUE_COLOR | Display documentation in console always with true color terminal. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | *`disabled`*<br/>**Disabled**: when the variable "[The output format of the generated documentation](#doc.output_format)" hasn't the value "console" | |
|
||||
| **<a id="doc.root" name="doc.root">doc.root</a>**<br/>**Command line**: -dr, --doc.root<br/>**Environment variable**: ROUGAILCLI_DOC.ROOT | Document the child variables of the family.<br/>By default, all accessible variables are included in the documentation. It is possible to define the family from which the documentation should be generated. | | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | | |
|
||||
|
||||
### The variables in this family are documented in another file
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> If you separate the variables into different files, the links between the variables will break. Therefore, you must define different filenames for the files containing these variables.\
|
||||
> This family contains lists of variable blocks.\
|
||||
> **Path**: doc.other_root_filenames\
|
||||
> *`disabled`*\
|
||||
> **Disabled**: when the variable "[Document the child variables of the family](#doc.root)" has the value "null"
|
||||
|
||||
| Variable | Description | Type | Validator |
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.other_root_filenames.root_path" name="doc.other_root_filenames.root_path">doc.other_root_filenames.root_path</a>**<br/>**Command line**: --doc.other_root_filenames.root_path<br/>**Environment variable**: ROUGAILCLI_DOC.OTHER_ROOT_FILENAMES.ROOT_PATH | This file contains child variables of the family. | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` | `unique` |
|
||||
| **<a id="doc.other_root_filenames.filename" name="doc.other_root_filenames.filename">doc.other_root_filenames.filename</a>**<br/>**Command line**: --doc.other_root_filenames.filename<br/>**Environment variable**: ROUGAILCLI_DOC.OTHER_ROOT_FILENAMES.FILENAME | Name of the file. | [`UNIX filename`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | • this filename could be a relative path<br/>• file type allowed: "file". |
|
||||
|
||||
### Variables and changelog documentation
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> **Path**: doc.tabulars\
|
||||
> *`disabled`*\
|
||||
> **Disabled**: if "[The output format of the generated documentation](#doc.output_format)" is json or "[Generated content](#doc.contents)" hasn't variables or changelog
|
||||
|
||||
| Variable | Description | Default value | Type | Access control | Validator |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|-----------------|-------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------|
|
||||
| **<a id="doc.tabulars.without_family" name="doc.tabulars.without_family">doc.tabulars.without_family</a>**<br/>**Command line**: <br/>• -df, --doc.tabulars.without_family<br/>• -ndf, --doc.tabulars.no-without_family<br/>**Environment variable**: ROUGAILCLI_DOC.TABULARS.WITHOUT_FAMILY | Do not add families in documentation. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | | |
|
||||
| **<a id="doc.tabulars.with_commandline" name="doc.tabulars.with_commandline">doc.tabulars.with_commandline</a>**<br/>**Command line**: <br/>• -dw, --doc.tabulars.with_commandline<br/>• -ndw, --doc.tabulars.no-with_commandline<br/>**Environment variable**: ROUGAILCLI_DOC.TABULARS.WITH_COMMANDLINE | Add command line informations in documentation. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | | |
|
||||
| **<a id="doc.tabulars.with_environment" name="doc.tabulars.with_environment">doc.tabulars.with_environment</a>**<br/>**Command line**: <br/>• -de, --doc.tabulars.with_environment<br/>• -nde, --doc.tabulars.no-with_environment<br/>**Environment variable**: ROUGAILCLI_DOC.TABULARS.WITH_ENVIRONMENT | Add environment variable informations in documentation. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | | |
|
||||
| **<a id="doc.tabulars.environment_prefix" name="doc.tabulars.environment_prefix">doc.tabulars.environment_prefix</a>**<br/>**Command line**: -dv, --doc.tabulars.environment_prefix<br/>**Environment variable**: ROUGAILCLI_DOC.TABULARS.ENVIRONMENT_PREFIX | Environment variables prefix name. | ROUGAIL | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | *`disabled`*<br/>**Disabled**: if "main_namespace" is not set or "[Add environment variable informations in documentation](#doc.tabulars.with_environment)" is false | Should only use uppercase characters. |
|
||||
|
||||
### Changelog documentation
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> **Path**: doc.changelog\
|
||||
> *`disabled`*\
|
||||
> **Disabled**: if changelog in not in "[Generated content](#doc.contents)"
|
||||
|
||||
| Variable | Description | Type |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.changelog.previous_json_file" name="doc.changelog.previous_json_file">doc.changelog.previous_json_file</a>**<br/>**Command line**: -dp, --doc.changelog.previous_json_file<br/>**Environment variable**: ROUGAILCLI_DOC.CHANGELOG.PREVIOUS_JSON_FILE | Previous description file in JSON format.<br/>To generate the changelog, you need to compare the old list of variables (in json format) with the current variables. | [`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` |
|
||||
|
||||
### Examples configuration
|
||||
|
||||
> **🛈 Informations**
|
||||
>
|
||||
> **Path**: doc.examples\
|
||||
> *`disabled`*\
|
||||
> **Disabled**: if example is not in "[Generated content](#doc.contents)"
|
||||
|
||||
| Variable | Description | Default value | Type | Access control |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|-----------------|-------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="doc.examples.comment" name="doc.examples.comment">doc.examples.comment</a>**<br/>**Command line**: <br/>• -dx, --doc.examples.comment<br/>• -ndx, --doc.examples.no-comment<br/>**Environment variable**: ROUGAILCLI_DOC.EXAMPLES.COMMENT | Add description of variables and families when generate examples. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | |
|
||||
| **<a id="doc.examples.comment_column" name="doc.examples.comment_column">doc.examples.comment_column</a>**<br/>**Command line**: --doc.examples.comment_column<br/>**Environment variable**: ROUGAILCLI_DOC.EXAMPLES.COMMENT_COLUMN | Comment in examples starts at column. | 30 | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | *`disabled`*<br/>**Disabled**: when the variable "[Add description of variables and families when generate examples](#doc.examples.comment)" has the value "false" |
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -5,8 +5,8 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2024-11-01 11:42+0100\n"
|
||||
"PO-Revision-Date: 2024-11-01 11:42+0100\n"
|
||||
"POT-Creation-Date: 2025-12-02 12:49+0100\n"
|
||||
"PO-Revision-Date: 2025-12-02 12:53+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr\n"
|
||||
|
|
@ -14,138 +14,566 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Generator: Poedit 3.5\n"
|
||||
"X-Generator: Poedit 3.8\n"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:40
|
||||
msgid "the domain name can starts by a dot"
|
||||
msgstr "le nom de domaine peut commencé par un point"
|
||||
#: src/rougail/output_doc/annotator.py:350
|
||||
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/__init__.py:41
|
||||
msgid "the domain name can be a hostname"
|
||||
msgstr "le nom de domaine peut être un nom d'hôte"
|
||||
#: src/rougail/output_doc/annotator.py:353
|
||||
msgid "the value of the global information \"{0}\""
|
||||
msgstr "la valeur de l'information globale \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:42
|
||||
msgid "the domain name can be an IP"
|
||||
msgstr "le nom de domaine peut être une IP"
|
||||
#: src/rougail/output_doc/annotator.py:360
|
||||
msgid "when the identifier is \"{0}\""
|
||||
msgstr "lorsque l'identifiant est \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:43
|
||||
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/annotator.py:362
|
||||
msgid "when the identifier is not \"{0}\""
|
||||
msgstr "lorsque l'identifiant n'est pas \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:48
|
||||
msgid "the minimum value is {0}"
|
||||
msgstr "le valeur minimal est {0}"
|
||||
#: src/rougail/output_doc/changelog.py:147
|
||||
msgid "New variable"
|
||||
msgstr "Nouvelle variable"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:49
|
||||
msgid "the maximum value is {0}"
|
||||
msgstr "le valeur maximal est {0}"
|
||||
#: src/rougail/output_doc/changelog.py:149
|
||||
msgid "New variables"
|
||||
msgstr "Nouvelles variables"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:55
|
||||
msgid "IP must be in CIDR format"
|
||||
msgstr "IP doit être au format CIDR"
|
||||
#: src/rougail/output_doc/changelog.py:163
|
||||
msgid "Modified variable"
|
||||
msgstr "Variable modifiée"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:56
|
||||
msgid "private IP are allowed"
|
||||
msgstr "les IP privées sont autorisés"
|
||||
#: src/rougail/output_doc/changelog.py:165
|
||||
msgid "Modified variables"
|
||||
msgstr "Variables modifiées"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:57
|
||||
msgid "reserved IP are allowed"
|
||||
msgstr "les IP réservés sont autorisés"
|
||||
#: src/rougail/output_doc/changelog.py:179
|
||||
msgid "Deleted variable"
|
||||
msgstr "Variable supprimée"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:62
|
||||
msgid "the host name can be an IP"
|
||||
msgstr "le nom d'hôte peut être une IP"
|
||||
#: src/rougail/output_doc/changelog.py:181
|
||||
msgid "Deleted variables"
|
||||
msgstr "Variables supprimées"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:67
|
||||
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/config.py:54
|
||||
msgid "duplicated level rougail-output-doc for {0} \"{1}\": {2} and {3}"
|
||||
msgstr "niveau dupliqué pour rougail-doc pour {0} \"{1}\": {2} et {3}"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:68
|
||||
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/config.py:60
|
||||
msgid "duplicated name \"{0}\" in rougail-output-doc"
|
||||
msgstr "nom dupliqué \"{0}\" dans rougail-output-doc"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:75
|
||||
msgid "can be range of port"
|
||||
msgstr "peut être un range de port"
|
||||
#: src/rougail/output_doc/config.py:123
|
||||
msgid "Generate documentation from structural files"
|
||||
msgstr "Générer la documentation depuis les fichiers de structure"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:76
|
||||
msgid "can have the protocol"
|
||||
msgstr "peut avoir un protocole"
|
||||
#: src/rougail/output_doc/config.py:124
|
||||
msgid ""
|
||||
"The structural files contain all the information related to the variables. "
|
||||
"This output generates the documentation for all or some of these variables."
|
||||
msgstr ""
|
||||
"Les fichiers de structure contiennent toutes les informations relatif aux "
|
||||
"variables. Cette sortie génère la documentation pour tout ou partie de ces "
|
||||
"variables."
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:77
|
||||
msgid "port 0 is allowed"
|
||||
msgstr "le port 0 est autorisé"
|
||||
#: src/rougail/output_doc/config.py:133
|
||||
msgid "if doc is not set in \"step.output\""
|
||||
msgstr "si doc n'est pas spécifié dans \"step.output\""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:78
|
||||
msgid "ports 1 to 1023 are allowed"
|
||||
msgstr "les ports entre 1 et 1023 sont autorisés"
|
||||
#: src/rougail/output_doc/config.py:136
|
||||
msgid "The output format of the generated documentation"
|
||||
msgstr "Le format de sortie de la documentation générée"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:79
|
||||
msgid "ports 1024 to 49151 are allowed"
|
||||
msgstr "les ports entre 1024 et 49151 sont autorisés"
|
||||
#: src/rougail/output_doc/config.py:145
|
||||
msgid "Generate document with this tabular model"
|
||||
msgstr "Génère la documentation avec ce modèle de tableau"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:80
|
||||
msgid "ports greater than 49152 are allowed"
|
||||
msgstr "les ports supérieurs à 49152 sont autorisés"
|
||||
#: src/rougail/output_doc/config.py:146
|
||||
msgid ""
|
||||
"The variables are documented with a tabular view. A template selection "
|
||||
"allows you to choose the content of each column."
|
||||
msgstr ""
|
||||
"Les variables sont documentées avec une vue tableau. Une sélection de modèle "
|
||||
"vous permet de choisir le contenu de chaque colonne."
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:125
|
||||
msgid "mandatory"
|
||||
msgstr "obligatoire"
|
||||
#: src/rougail/output_doc/config.py:153
|
||||
msgid "\"_.output_format\" in json is not compatible with this variable"
|
||||
msgstr "\"_.output_format\" en json n\\'est pas compatible avec cette variable"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:126
|
||||
msgid "hidden"
|
||||
msgstr "caché"
|
||||
#: src/rougail/output_doc/config.py:160
|
||||
msgid "Generated content"
|
||||
msgstr "Contenu généré"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:127
|
||||
msgid "disabled"
|
||||
msgstr "désactivé"
|
||||
#: src/rougail/output_doc/config.py:161
|
||||
msgid ""
|
||||
"You can generate three type of document. All variables (\"variables\"), an "
|
||||
"example file in YAML format (\"example\") or change log (\"changelog\")."
|
||||
msgstr ""
|
||||
"Vous pouvez générer trois type de documentation. Toutes les variables "
|
||||
"(\"variables\"), un exemple de fichier au format YAML (\"example\") ou le "
|
||||
"journal des changements (\"changelog\")."
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:128
|
||||
msgid "unique"
|
||||
msgstr "unique"
|
||||
#: src/rougail/output_doc/config.py:173
|
||||
msgid ""
|
||||
"\"_.output_format\" in json is not compatible with changelog or example "
|
||||
"\"_.contents\""
|
||||
msgstr ""
|
||||
"\"_.output_format\" en json n'est pas compatible avec \"_.contents\" "
|
||||
"changelog or example"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:129
|
||||
msgid "auto modified"
|
||||
msgstr "auto modifiée"
|
||||
#: src/rougail/output_doc/config.py:176
|
||||
msgid "Starting title level"
|
||||
msgstr "Niveau de titre de départ"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:163
|
||||
msgid "Variables for \"{0}\""
|
||||
msgstr "Variables pour \"{0}\""
|
||||
#: src/rougail/output_doc/config.py:181
|
||||
msgid "Modify values to document all variables"
|
||||
msgstr "Modifier les valeurs pour documenter toutes les variables"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:180
|
||||
msgid "Variables"
|
||||
msgstr "Variables"
|
||||
#: src/rougail/output_doc/config.py:182
|
||||
msgid ""
|
||||
"To document leadership or dynamic family variables, it is sometimes "
|
||||
"necessary to generate values, which can change the values in the "
|
||||
"configuration. Be careful if you reuse this configuration."
|
||||
msgstr ""
|
||||
"Pour documenter les variables des leadership ou des familles dynamiques, il "
|
||||
"est parfois nécessaire de générer des valeurs, qui peuvent modifier les "
|
||||
"valeurs de la configuration. Soyez vigilent si vous réutilisez cette "
|
||||
"configuration."
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:187
|
||||
msgid "Example with mandatory variables not filled in"
|
||||
msgstr "Exemple avec des variables obligatoire non renseignée"
|
||||
#: src/rougail/output_doc/config.py:186
|
||||
msgid "Display documentation in console always with true color terminal"
|
||||
msgstr ""
|
||||
"Afficher la documentation dans la console en permanence avec un terminal en "
|
||||
"couleurs réelles"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:493
|
||||
msgid "(default)"
|
||||
msgstr "(defaut)"
|
||||
#: src/rougail/output_doc/config.py:193
|
||||
msgid "Document the child variables of the family"
|
||||
msgstr "Documenter les variables enfants de cette famille"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:498
|
||||
msgid "Choices"
|
||||
msgstr "Choix"
|
||||
#: src/rougail/output_doc/config.py:194
|
||||
msgid ""
|
||||
"By default, all accessible variables are included in the documentation. It "
|
||||
"is possible to define the family from which the documentation should be "
|
||||
"generated."
|
||||
msgstr ""
|
||||
"Par défaut, toute les variables accessibles sont incluent dans la "
|
||||
"documentation. Il est possible de définir une famille a partir de laquelle "
|
||||
"la documentation doit être générée."
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:501
|
||||
#: src/rougail/output_doc/config.py:199
|
||||
msgid "The variables in this family are documented in another file"
|
||||
msgstr "Les variables pour cette famille sont documentés dans un autre fichier"
|
||||
|
||||
#: src/rougail/output_doc/config.py:200
|
||||
msgid ""
|
||||
"If you separate the variables into different files, the links between the "
|
||||
"variables will break. Therefore, you must define different filenames for the "
|
||||
"files containing these variables."
|
||||
msgstr ""
|
||||
"Si vous séparez les variables dans différents fichiers, le lien entre les "
|
||||
"variables va être cassé. Dans ce cas, vous devez définit différents nom de "
|
||||
"fichiers pour les fichiers contenant ces variables."
|
||||
|
||||
#: src/rougail/output_doc/config.py:207
|
||||
msgid "This file contains child variables of the family"
|
||||
msgstr "Ce fichier contient les variables enfants de la famille"
|
||||
|
||||
#: src/rougail/output_doc/config.py:211
|
||||
msgid "Name of the file"
|
||||
msgstr "Nom du fichier"
|
||||
|
||||
#: src/rougail/output_doc/config.py:219
|
||||
msgid "Variables and changelog documentation"
|
||||
msgstr "Documentation des variables et journal de changements"
|
||||
|
||||
#: src/rougail/output_doc/config.py:224
|
||||
msgid ""
|
||||
"if \"_.output_format\" is json or \"_.contents\" hasn't variables or "
|
||||
"changelog"
|
||||
msgstr ""
|
||||
"si \"_.output_format\" en json ou si \"_.contents\" n'est pas variables ou "
|
||||
"changelog"
|
||||
|
||||
#: src/rougail/output_doc/config.py:227
|
||||
msgid "Do not add families in documentation"
|
||||
msgstr "Ne pas ajouter les familles dans la documentation"
|
||||
|
||||
#: src/rougail/output_doc/config.py:232
|
||||
msgid "Add command line informations in documentation"
|
||||
msgstr "Ajoute les informations de la ligne de commande dans la documentation"
|
||||
|
||||
#: src/rougail/output_doc/config.py:237
|
||||
msgid "Add environment variable informations in documentation"
|
||||
msgstr ""
|
||||
"Ajoute les informations de variable d'environnement dans la documentation"
|
||||
|
||||
#: src/rougail/output_doc/config.py:242
|
||||
msgid "Environment variables prefix name"
|
||||
msgstr "Préfixe du nom des variables d'environnement"
|
||||
|
||||
#: src/rougail/output_doc/config.py:249
|
||||
msgid "should only use uppercase characters"
|
||||
msgstr "doit seulement utilise des caractères en majuscule"
|
||||
|
||||
#: src/rougail/output_doc/config.py:254
|
||||
msgid "if \"main_namespace\" is not set or \"_.with_environment\" is false"
|
||||
msgstr ""
|
||||
"si \"main_namespace\" n'est pas défini ou \"_.with_environment\" est false"
|
||||
|
||||
#: src/rougail/output_doc/config.py:257
|
||||
msgid "Changelog documentation"
|
||||
msgstr "Documentation du journal des changements"
|
||||
|
||||
#: src/rougail/output_doc/config.py:262
|
||||
msgid "if changelog in not in \"_.contents\""
|
||||
msgstr "changelog n'est pas défini dans \"_.contents\""
|
||||
|
||||
#: src/rougail/output_doc/config.py:265
|
||||
msgid "Previous description file in JSON format"
|
||||
msgstr "Précédent fichier de description au format JSON"
|
||||
|
||||
#: src/rougail/output_doc/config.py:266
|
||||
msgid ""
|
||||
"To generate the changelog, you need to compare the old list of variables (in "
|
||||
"json format) with the current variables."
|
||||
msgstr ""
|
||||
"Pour générer le journal des changements, vous devez comparer l'ancienne "
|
||||
"liste des variables (au format json) avec les variables courantes."
|
||||
|
||||
#: src/rougail/output_doc/config.py:270
|
||||
msgid "Examples configuration"
|
||||
msgstr "Configuration des exemples"
|
||||
|
||||
#: src/rougail/output_doc/config.py:275
|
||||
msgid "if example is not in \"_.contents\""
|
||||
msgstr "si example n'est pas défini dans \"_.contents\""
|
||||
|
||||
#: src/rougail/output_doc/config.py:278
|
||||
msgid "Add description of variables and families when generate examples"
|
||||
msgstr ""
|
||||
"Ajouter la description des variables et des familles lorsqu'on génère des "
|
||||
"exemples"
|
||||
|
||||
#: src/rougail/output_doc/config.py:283
|
||||
msgid "Comment in examples starts at column"
|
||||
msgstr "Commentaire dans les exemples commence à la colonne"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:329
|
||||
msgid "This family contains lists of variable blocks"
|
||||
msgstr "Cette famille contient des listes de bloc de variable"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:339
|
||||
msgid "This family builds families dynamically"
|
||||
msgstr "Cette famille construit des familles dynamiquement"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:353
|
||||
msgid "Default"
|
||||
msgstr "Défaut"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:559
|
||||
msgid "the value of the variable \"{0}\""
|
||||
msgstr "la valeur de la variable \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:564
|
||||
#: src/rougail/output_doc/__init__.py:566
|
||||
msgid "value of the {0}"
|
||||
msgstr "la valeur de {0}"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:638
|
||||
#: src/rougail/output_doc/__init__.py:651
|
||||
#: src/rougail/output_doc/doc.py:371
|
||||
msgid "Example"
|
||||
msgstr "Exemple"
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:649
|
||||
#: src/rougail/output_doc/doc.py:374
|
||||
msgid "Examples"
|
||||
msgstr "Exemples"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:383
|
||||
msgid "Tag"
|
||||
msgstr "Étiquette"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:386
|
||||
msgid "Tags"
|
||||
msgstr "Étiquettes"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:418
|
||||
msgid "No attribute \"description\" for \"{0}\" in {1}"
|
||||
msgstr "Aucun attribut \"description\" pour \"{0}\" dans {1}"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:553
|
||||
msgid "text based with regular expressions \"{0}\""
|
||||
msgstr "texte avec expression rationnelle \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:557
|
||||
#: src/rougail/output_doc/tabular/six_columns.py:65
|
||||
msgid "Validator"
|
||||
msgstr "Validateur"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:560
|
||||
msgid "Validators"
|
||||
msgstr "Validateurs"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:569
|
||||
msgid "Choices"
|
||||
msgstr "Choix"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:672
|
||||
msgid "the value of the identifier"
|
||||
msgstr "la valeur de l'identifiant"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:676
|
||||
msgid "the value of the {0}"
|
||||
msgstr "la valeur de l'{0}"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:685
|
||||
msgid "depends on a calculation"
|
||||
msgstr "dépend d'un calcul"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:691
|
||||
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:719
|
||||
msgid "the value of the variable \"{0}\""
|
||||
msgstr "la valeur de la variable \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:721
|
||||
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:741
|
||||
msgid "the value of an undocumented variable"
|
||||
msgstr "la valeur d'une variable non documentée"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:744
|
||||
msgid "the values of undocumented variables"
|
||||
msgstr "les valeurs de variables non documentées"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:767
|
||||
msgid "(from an undocumented variable)"
|
||||
msgstr "(issue d'une variable non documentée)"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:775
|
||||
msgid "{0} (from an undocumented variable)"
|
||||
msgstr "{0} (issue d'une variable non documentée)"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:779 src/rougail/output_doc/doc.py:831
|
||||
msgid "depends on an undocumented variable"
|
||||
msgstr "dépends d'une variable non documentée"
|
||||
|
||||
#: src/rougail/output_doc/doc.py:853
|
||||
msgid ""
|
||||
"when the variable \"{{0}}\" is defined, accessible and hasn't the value "
|
||||
"\"{0}\""
|
||||
msgstr ""
|
||||
"lorsque la variable \"{{0}}\" est définie, accessible et n'a pas la valeur "
|
||||
"\"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:857
|
||||
msgid "when the variable \"{{0}}\" is defined and hasn't the value \"{0}\""
|
||||
msgstr "lorsque la variable \"{{0}}\" est définie et n'a pas la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:861
|
||||
msgid "when the variable \"{{0}}\" is accessible and hasn't the value \"{0}\""
|
||||
msgstr ""
|
||||
"lorsque la variable \"{{0}}\" est acessible et n'a pas la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:863
|
||||
msgid "when the variable \"{{0}}\" hasn't the value \"{0}\""
|
||||
msgstr "lorsque la variable \"{{0}}\" n'a pas la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:867
|
||||
msgid ""
|
||||
"when the variable \"{{0}}\" is defined, is accessible and has the value "
|
||||
"\"{0}\""
|
||||
msgstr ""
|
||||
"lorsque la variable \"{{0}}\" est définie, accessible et a la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:871
|
||||
msgid "when the variable \"{{0}}\" is defined and has the value \"{0}\""
|
||||
msgstr "lorsque la variable \"{{0}}\" est définie et a la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:875
|
||||
msgid "when the variable \"{{0}}\" is accessible and has the value \"{0}\""
|
||||
msgstr "lorsque la variable \"{{0}}\" est accessible et a la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:877
|
||||
msgid "when the variable \"{{0}}\" has the value \"{0}\""
|
||||
msgstr "lorsque la variable \"{{0}}\" a la valeur \"{0}\""
|
||||
|
||||
#: src/rougail/output_doc/example.py:45
|
||||
msgid "Example with mandatory variables not filled in"
|
||||
msgstr "Exemple avec des variables obligatoire non renseignée"
|
||||
|
||||
#: src/rougail/output_doc/example.py:52
|
||||
msgid "Example with all variables modifiable"
|
||||
msgstr "Exemple avec toutes les variables modifiable"
|
||||
|
||||
#: src/rougail/output_doc/output/asciidoc.py:156
|
||||
#: src/rougail/output_doc/output/console.py:199
|
||||
#: src/rougail/output_doc/output/github.py:196
|
||||
#: src/rougail/output_doc/output/gitlab.py:44
|
||||
msgid "Informations"
|
||||
msgstr "Informations"
|
||||
|
||||
#: src/rougail/output_doc/tabular/five_columns.py:59
|
||||
msgid "Access control"
|
||||
msgstr "Contrôle des accès"
|
||||
|
||||
#: src/rougail/output_doc/tabular/four_columns.py:53
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#: src/rougail/output_doc/tabular/three_columns.py:46
|
||||
msgid "Default value"
|
||||
msgstr "Valeur par défaut"
|
||||
|
||||
#: src/rougail/output_doc/tabular/two_columns.py:45
|
||||
msgid "Variable"
|
||||
msgstr "Variable"
|
||||
|
||||
#: src/rougail/output_doc/tabular/two_columns.py:47
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#: src/rougail/output_doc/utils.py:152
|
||||
msgid "Command line"
|
||||
msgstr "Ligne de commande"
|
||||
|
||||
#: src/rougail/output_doc/utils.py:159
|
||||
msgid "Environment variable"
|
||||
msgstr "Variable d'environnement"
|
||||
|
||||
#: src/rougail/output_doc/utils.py:458
|
||||
msgid "Path"
|
||||
msgstr "Chemin"
|
||||
|
||||
#: src/rougail/output_doc/utils.py:468
|
||||
msgid "Identifiers"
|
||||
msgstr "Identifiants"
|
||||
|
||||
#: src/rougail/output_doc/utils.py:684 src/rougail/output_doc/utils.py:693
|
||||
#: src/rougail/output_doc/utils.py:699 src/rougail/output_doc/utils.py:705
|
||||
#: src/rougail/output_doc/utils.py:709
|
||||
msgid "(default)"
|
||||
msgstr "(défaut)"
|
||||
|
||||
#: src/rougail/output_doc/utils.py:960
|
||||
msgid "{0}: {1}"
|
||||
msgstr "{0} : {1}"
|
||||
|
||||
#~ msgid "variables is not selected in \"_.contents\""
|
||||
#~ msgstr "variables n'est pas sélectionné dans \"_.contents\""
|
||||
|
||||
#~ msgid "Name of the default environment prefix"
|
||||
#~ msgstr "Nom du préfixe d'environnement par défaut"
|
||||
|
||||
#~ msgid "documentation must be splitted"
|
||||
#~ msgstr "documentation doit être séparée"
|
||||
|
||||
#~ msgid "Root family name"
|
||||
#~ msgstr "Nom de la famille racine"
|
||||
|
||||
#~ msgid "disabled when there is no mode available"
|
||||
#~ msgstr "désactiver lorsqu'il n'y a pas de mode valable"
|
||||
|
||||
#~ msgid "verify if disable modes already exists"
|
||||
#~ msgstr "vérifier si le mode existe déjà"
|
||||
|
||||
#~ msgid "Modify values to document leaderships and dynamics families"
|
||||
#~ msgstr "Valeurs modifiées pour documenter les familles leader ou dynamique"
|
||||
|
||||
#~ msgid "Force true color terminal"
|
||||
#~ msgstr "Force les vrais couleurs dans le terminal"
|
||||
|
||||
#~ msgid "multiple"
|
||||
#~ msgstr "multiple"
|
||||
|
||||
#~ msgid "the domain name can starts by a dot"
|
||||
#~ msgstr "le nom de domaine peut commencer par un point"
|
||||
|
||||
#~ msgid "the domain name can be a hostname"
|
||||
#~ msgstr "le nom de domaine peut être un nom d'hôte"
|
||||
|
||||
#~ msgid "the domain name can be an IP"
|
||||
#~ msgstr "le nom de domaine peut être une IP"
|
||||
|
||||
#~ msgid "the domain name can be network in CIDR format"
|
||||
#~ msgstr "le nom de domaine peut être un réseau au format CIDR"
|
||||
|
||||
#~ msgid "the minimum value is {0}"
|
||||
#~ msgstr "le valeur minimal est {0}"
|
||||
|
||||
#~ msgid "the maximum value is {0}"
|
||||
#~ msgstr "le valeur maximal est {0}"
|
||||
|
||||
#~ msgid "IP must be in CIDR format"
|
||||
#~ msgstr "IP doit être au format CIDR"
|
||||
|
||||
#~ msgid "private IP are allowed"
|
||||
#~ msgstr "les IP privées sont autorisés"
|
||||
|
||||
#~ msgid "reserved IP are allowed"
|
||||
#~ msgstr "les IP réservés sont autorisés"
|
||||
|
||||
#~ msgid "network must be in CIDR format"
|
||||
#~ msgstr "réseau doit être au format CIDR"
|
||||
|
||||
#~ msgid "the host name can be an IP"
|
||||
#~ msgstr "le nom d'hôte peut être une IP"
|
||||
|
||||
#~ msgid "the domain name in web address can be an IP"
|
||||
#~ msgstr "le nom de domaine dans l'adresse web peut être une IP"
|
||||
|
||||
#~ 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"
|
||||
|
||||
#~ msgid "can be range of port"
|
||||
#~ msgstr "peut être un range de port"
|
||||
|
||||
#~ msgid "can have the protocol"
|
||||
#~ msgstr "peut avoir un protocole"
|
||||
|
||||
#~ msgid "port 0 is allowed"
|
||||
#~ msgstr "le port 0 est autorisé"
|
||||
|
||||
#~ msgid "well-known ports (1 to 1023) are allowed"
|
||||
#~ msgstr "les ports connus (de 1 à 1023) sont autorisés"
|
||||
|
||||
#~ msgid "registred ports (1024 to 49151) are allowed"
|
||||
#~ msgstr "les ports enregistrés (de 1024 à 49151) sont autorisés"
|
||||
|
||||
#~ msgid "private ports (greater than 49152) are allowed"
|
||||
#~ msgstr "les ports privés (supérieurs à 49152) sont autorisés"
|
||||
|
||||
#~ msgid "minimum length for the secret is {0} characters"
|
||||
#~ msgstr "longueur minimum pour le secret est de {0} caractères"
|
||||
|
||||
#~ msgid "maximum length for the secret is {0} characters"
|
||||
#~ msgstr "longueur maximal pour le secret est de {0} caractères"
|
||||
|
||||
#~ msgid "forbidden characters: {0}"
|
||||
#~ msgstr "caractères interdits: {0}"
|
||||
|
||||
#~ msgid "this filename could be a relative path"
|
||||
#~ msgstr "ce nom de fichier peut être un chemin relative"
|
||||
|
||||
#~ msgid "this file must exists"
|
||||
#~ msgstr "ce fichier doit exister"
|
||||
|
||||
#~ msgid "file type allowed: {0}"
|
||||
#~ msgstr "type de fichier autorisé : {0}"
|
||||
|
||||
#~ msgid "Configuration rougail-doc"
|
||||
#~ msgstr "Configuration de rougail-doc"
|
||||
|
||||
#~ msgid "Variables for \"{0}\""
|
||||
#~ msgstr "Variables pour \"{0}\""
|
||||
|
||||
#~ msgid "Generate example"
|
||||
#~ msgstr "Génération de l'exemple"
|
||||
|
||||
#~ msgid "Display example in documentation"
|
||||
#~ msgstr "Afficher un exemple dans la documentation"
|
||||
|
||||
#~ msgid "Hide example in documentation"
|
||||
#~ msgstr "Cacher l'exemple dans la documentation"
|
||||
|
||||
#, fuzzy
|
||||
#~| msgid ":"
|
||||
#~ msgid ": "
|
||||
#~ msgstr " : "
|
||||
|
||||
#~ msgid "when the variable \"{0}\" has the value \"True\""
|
||||
#~ msgstr "lorsque la variable \"{0}\" a la valeur \"True\""
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2024-11-01 11:42+0100\n"
|
||||
"POT-Creation-Date: 2025-12-02 12:54+0100\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,137 +15,381 @@ msgstr ""
|
|||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:40
|
||||
msgid "the domain name can starts by a dot"
|
||||
#: src/rougail/output_doc/annotator.py:350
|
||||
msgid "the value of the information \"{0}\" of the variable \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:41
|
||||
msgid "the domain name can be a hostname"
|
||||
#: src/rougail/output_doc/annotator.py:353
|
||||
msgid "the value of the global information \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:42
|
||||
msgid "the domain name can be an IP"
|
||||
#: src/rougail/output_doc/annotator.py:360
|
||||
msgid "when the identifier is \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:43
|
||||
msgid "the domain name can be network in CIDR format"
|
||||
#: src/rougail/output_doc/annotator.py:362
|
||||
msgid "when the identifier is not \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:48
|
||||
msgid "the minimum value is {0}"
|
||||
#: src/rougail/output_doc/changelog.py:147
|
||||
msgid "New variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:49
|
||||
msgid "the maximum value is {0}"
|
||||
#: src/rougail/output_doc/changelog.py:149
|
||||
msgid "New variables"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:55
|
||||
msgid "IP must be in CIDR format"
|
||||
#: src/rougail/output_doc/changelog.py:163
|
||||
msgid "Modified variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:56
|
||||
msgid "private IP are allowed"
|
||||
#: src/rougail/output_doc/changelog.py:165
|
||||
msgid "Modified variables"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:57
|
||||
msgid "reserved IP are allowed"
|
||||
#: src/rougail/output_doc/changelog.py:179
|
||||
msgid "Deleted variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:62
|
||||
msgid "the host name can be an IP"
|
||||
#: src/rougail/output_doc/changelog.py:181
|
||||
msgid "Deleted variables"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:67
|
||||
msgid "the domain name in web address can be an IP"
|
||||
#: src/rougail/output_doc/config.py:54
|
||||
msgid "duplicated level rougail-output-doc for {0} \"{1}\": {2} and {3}"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:68
|
||||
msgid "the domain name in web address can be only a hostname"
|
||||
#: src/rougail/output_doc/config.py:60
|
||||
msgid "duplicated name \"{0}\" in rougail-output-doc"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:75
|
||||
msgid "can be range of port"
|
||||
#: src/rougail/output_doc/config.py:123
|
||||
msgid "Generate documentation from structural files"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:76
|
||||
msgid "can have the protocol"
|
||||
#: src/rougail/output_doc/config.py:124
|
||||
msgid "The structural files contain all the information related to the variables. This output generates the documentation for all or some of these variables."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:77
|
||||
msgid "port 0 is allowed"
|
||||
#: src/rougail/output_doc/config.py:133
|
||||
msgid "if doc is not set in \"step.output\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:78
|
||||
msgid "ports 1 to 1023 are allowed"
|
||||
#: src/rougail/output_doc/config.py:136
|
||||
msgid "The output format of the generated documentation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:79
|
||||
msgid "ports 1024 to 49151 are allowed"
|
||||
#: src/rougail/output_doc/config.py:145
|
||||
msgid "Generate document with this tabular model"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:80
|
||||
msgid "ports greater than 49152 are allowed"
|
||||
#: src/rougail/output_doc/config.py:146
|
||||
msgid "The variables are documented with a tabular view. A template selection allows you to choose the content of each column."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:125
|
||||
msgid "mandatory"
|
||||
#: src/rougail/output_doc/config.py:153
|
||||
msgid "\"_.output_format\" in json is not compatible with this variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:126
|
||||
msgid "hidden"
|
||||
#: src/rougail/output_doc/config.py:160
|
||||
msgid "Generated content"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:127
|
||||
msgid "disabled"
|
||||
#: src/rougail/output_doc/config.py:161
|
||||
msgid "You can generate three type of document. All variables (\"variables\"), an example file in YAML format (\"example\") or change log (\"changelog\")."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:128
|
||||
msgid "unique"
|
||||
#: src/rougail/output_doc/config.py:173
|
||||
msgid "\"_.output_format\" in json is not compatible with changelog or example \"_.contents\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:129
|
||||
msgid "auto modified"
|
||||
#: src/rougail/output_doc/config.py:176
|
||||
msgid "Starting title level"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:163
|
||||
msgid "Variables for \"{0}\""
|
||||
#: src/rougail/output_doc/config.py:181
|
||||
msgid "Modify values to document all variables"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:180
|
||||
msgid "Variables"
|
||||
#: src/rougail/output_doc/config.py:182
|
||||
msgid "To document leadership or dynamic family variables, it is sometimes necessary to generate values, which can change the values in the configuration. Be careful if you reuse this configuration."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:187
|
||||
msgid "Example with mandatory variables not filled in"
|
||||
#: src/rougail/output_doc/config.py:186
|
||||
msgid "Display documentation in console always with true color terminal"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:493
|
||||
msgid "(default)"
|
||||
#: src/rougail/output_doc/config.py:193
|
||||
msgid "Document the child variables of the family"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:498
|
||||
msgid "Choices"
|
||||
#: src/rougail/output_doc/config.py:194
|
||||
msgid "By default, all accessible variables are included in the documentation. It is possible to define the family from which the documentation should be generated."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:501
|
||||
#: src/rougail/output_doc/config.py:199
|
||||
msgid "The variables in this family are documented in another file"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:200
|
||||
msgid "If you separate the variables into different files, the links between the variables will break. Therefore, you must define different filenames for the files containing these variables."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:207
|
||||
msgid "This file contains child variables of the family"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:211
|
||||
msgid "Name of the file"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:219
|
||||
msgid "Variables and changelog documentation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:224
|
||||
msgid "if \"_.output_format\" is json or \"_.contents\" hasn't variables or changelog"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:227
|
||||
msgid "Do not add families in documentation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:232
|
||||
msgid "Add command line informations in documentation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:237
|
||||
msgid "Add environment variable informations in documentation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:242
|
||||
msgid "Environment variables prefix name"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:249
|
||||
msgid "should only use uppercase characters"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:254
|
||||
msgid "if \"main_namespace\" is not set or \"_.with_environment\" is false"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:257
|
||||
msgid "Changelog documentation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:262
|
||||
msgid "if changelog in not in \"_.contents\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:265
|
||||
msgid "Previous description file in JSON format"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:266
|
||||
msgid "To generate the changelog, you need to compare the old list of variables (in json format) with the current variables."
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:270
|
||||
msgid "Examples configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:275
|
||||
msgid "if example is not in \"_.contents\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:278
|
||||
msgid "Add description of variables and families when generate examples"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/config.py:283
|
||||
msgid "Comment in examples starts at column"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:329
|
||||
msgid "This family contains lists of variable blocks"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:339
|
||||
msgid "This family builds families dynamically"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:353
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:559
|
||||
msgid "the value of the variable \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:564
|
||||
#: src/rougail/output_doc/__init__.py:566
|
||||
msgid "value of the {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:638
|
||||
#: src/rougail/output_doc/__init__.py:651
|
||||
#: src/rougail/output_doc/doc.py:371
|
||||
msgid "Example"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/__init__.py:649
|
||||
#: src/rougail/output_doc/doc.py:374
|
||||
msgid "Examples"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:383
|
||||
msgid "Tag"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:386
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:418
|
||||
msgid "No attribute \"description\" for \"{0}\" in {1}"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:553
|
||||
msgid "text based with regular expressions \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:557
|
||||
#: src/rougail/output_doc/tabular/six_columns.py:65
|
||||
msgid "Validator"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:560
|
||||
msgid "Validators"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:569
|
||||
msgid "Choices"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:672
|
||||
msgid "the value of the identifier"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:676
|
||||
msgid "the value of the {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:685
|
||||
msgid "depends on a calculation"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:691
|
||||
msgid "\"{0}\" is a calculation for {1} but has no description in {2}"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:719
|
||||
msgid "the value of the variable \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:721
|
||||
msgid "the value of the variable \"{0}\" if it is defined"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:741
|
||||
msgid "the value of an undocumented variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:744
|
||||
msgid "the values of undocumented variables"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:767
|
||||
msgid "(from an undocumented variable)"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:775
|
||||
msgid "{0} (from an undocumented variable)"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:779 src/rougail/output_doc/doc.py:831
|
||||
msgid "depends on an undocumented variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:853
|
||||
msgid "when the variable \"{{0}}\" is defined, accessible and hasn't the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:857
|
||||
msgid "when the variable \"{{0}}\" is defined and hasn't the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:861
|
||||
msgid "when the variable \"{{0}}\" is accessible and hasn't the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:863
|
||||
msgid "when the variable \"{{0}}\" hasn't the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:867
|
||||
msgid "when the variable \"{{0}}\" is defined, is accessible and has the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:871
|
||||
msgid "when the variable \"{{0}}\" is defined and has the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:875
|
||||
msgid "when the variable \"{{0}}\" is accessible and has the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/doc.py:877
|
||||
msgid "when the variable \"{{0}}\" has the value \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/example.py:45
|
||||
msgid "Example with mandatory variables not filled in"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/example.py:52
|
||||
msgid "Example with all variables modifiable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/output/asciidoc.py:156
|
||||
#: src/rougail/output_doc/output/console.py:199
|
||||
#: src/rougail/output_doc/output/github.py:196
|
||||
#: src/rougail/output_doc/output/gitlab.py:44
|
||||
msgid "Informations"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/tabular/five_columns.py:59
|
||||
msgid "Access control"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/tabular/four_columns.py:53
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/tabular/three_columns.py:46
|
||||
msgid "Default value"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/tabular/two_columns.py:45
|
||||
msgid "Variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/tabular/two_columns.py:47
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/utils.py:152
|
||||
msgid "Command line"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/utils.py:159
|
||||
msgid "Environment variable"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/utils.py:458
|
||||
msgid "Path"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/utils.py:468
|
||||
msgid "Identifiers"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/utils.py:684 src/rougail/output_doc/utils.py:693
|
||||
#: src/rougail/output_doc/utils.py:699 src/rougail/output_doc/utils.py:705
|
||||
#: src/rougail/output_doc/utils.py:709
|
||||
msgid "(default)"
|
||||
msgstr ""
|
||||
|
||||
#: src/rougail/output_doc/utils.py:960
|
||||
msgid "{0}: {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
|
|||
|
||||
[project]
|
||||
name = "rougail.output_doc"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0a39"
|
||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||
readme = "README.md"
|
||||
description = "Rougail output doc"
|
||||
|
|
@ -13,11 +13,10 @@ license = {file = "LICENSE"}
|
|||
classifiers = [
|
||||
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
"Natural Language :: English",
|
||||
|
|
@ -25,8 +24,9 @@ classifiers = [
|
|||
|
||||
]
|
||||
dependencies = [
|
||||
"rougail ~= 1.1,<2",
|
||||
"rougail-base > 1.1,<2",
|
||||
"tabulate ~= 0.9.0",
|
||||
"rich ~= 13.9.3",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
@ -37,5 +37,9 @@ name = "cz_conventional_commits"
|
|||
tag_format = "$version"
|
||||
version_scheme = "pep440"
|
||||
version_provider = "pep621"
|
||||
#update_changelog_on_bump = true
|
||||
version_files = [
|
||||
"src/rougail/output_doc/__version__.py",
|
||||
"pyproject.toml:version"
|
||||
]
|
||||
update_changelog_on_bump = true
|
||||
changelog_merge_prerelease = true
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
@ -16,671 +15,9 @@ details.
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
# FIXME si plusieurs example dont le 1er est none tester les autres : tests/dictionaries/00_8test_none
|
||||
from tiramisu import Calculation
|
||||
from tiramisu.error import display_list
|
||||
import tabulate as tabulate_module
|
||||
from tabulate import tabulate
|
||||
from warnings import warn
|
||||
from typing import Optional
|
||||
|
||||
from rougail.error import display_xmlfiles
|
||||
from rougail import RougailConfig, Rougail, CONVERT_OPTION
|
||||
from rougail.object_model import PROPERTY_ATTRIBUTE
|
||||
|
||||
from .config import OutPuts
|
||||
from .i18n import _
|
||||
|
||||
ENTER = "\n\n"
|
||||
|
||||
|
||||
DocTypes = {
|
||||
"domainname": {
|
||||
"params": {
|
||||
"allow_startswith_dot": _("the domain name can starts by a dot"),
|
||||
"allow_without_dot": _("the domain name can be a hostname"),
|
||||
"allow_ip": _("the domain name can be an IP"),
|
||||
"allow_cidr_network": _("the domain name can be network in CIDR format"),
|
||||
},
|
||||
},
|
||||
"number": {
|
||||
"params": {
|
||||
"min_number": _("the minimum value is {0}"),
|
||||
"max_number": _("the maximum value is {0}"),
|
||||
},
|
||||
},
|
||||
"ip": {
|
||||
"msg": "IP",
|
||||
"params": {
|
||||
"cidr": _("IP must be in CIDR format"),
|
||||
"private_only": _("private IP are allowed"),
|
||||
"allow_reserved": _("reserved IP are allowed"),
|
||||
},
|
||||
},
|
||||
"hostname": {
|
||||
"params": {
|
||||
"allow_ip": _("the host name can be an IP"),
|
||||
},
|
||||
},
|
||||
"web_address": {
|
||||
"params": {
|
||||
"allow_ip": _("the domain name in web address can be an IP"),
|
||||
"allow_without_dot": _(
|
||||
"the domain name in web address can be only a hostname"
|
||||
),
|
||||
},
|
||||
},
|
||||
"port": {
|
||||
"params": {
|
||||
"allow_range": _("can be range of port"),
|
||||
"allow_protocol": _("can have the protocol"),
|
||||
"allow_zero": _("port 0 is allowed"),
|
||||
"allow_wellknown": _("ports 1 to 1023 are allowed"),
|
||||
"allow_registred": _("ports 1024 to 49151 are allowed"),
|
||||
"allow_private": _("ports greater than 49152 are allowed"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
ROUGAIL_VARIABLE_TYPE = (
|
||||
"https://rougail.readthedocs.io/en/latest/variable.html#variables-types"
|
||||
)
|
||||
|
||||
|
||||
class RougailOutputDoc:
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
config: "Config" = None,
|
||||
rougailconfig: RougailConfig = None,
|
||||
**kwarg,
|
||||
):
|
||||
if rougailconfig is None:
|
||||
rougailconfig = RougailConfig
|
||||
if rougailconfig["step.output"] != "doc":
|
||||
rougailconfig["step.output"] = "doc"
|
||||
if rougailconfig["step.output"] != "doc":
|
||||
raise Exception("doc is not set as step.output")
|
||||
self.rougailconfig = rougailconfig
|
||||
outputs = OutPuts().get()
|
||||
output = self.rougailconfig["doc.output_format"]
|
||||
if output not in outputs:
|
||||
raise Exception(
|
||||
f'cannot find output "{output}", available outputs: {list(outputs)}'
|
||||
)
|
||||
if config is None:
|
||||
rougail = Rougail(self.rougailconfig)
|
||||
rougail.converted.plugins.append("output_doc")
|
||||
config = rougail.get_config()
|
||||
self.conf = config
|
||||
self.conf.property.setdefault(frozenset({"advanced"}), "read_write", "append")
|
||||
self.conf.property.read_write()
|
||||
self.conf.property.remove("cache")
|
||||
self.dynamic_paths = {}
|
||||
self.formater = outputs[output]()
|
||||
self.level = self.rougailconfig["doc.title_level"]
|
||||
# self.property_to_string = [('mandatory', 'obligatoire'), ('hidden', 'cachée'), ('disabled', 'désactivée'), ('unique', 'unique'), ('force_store_value', 'modifié automatiquement')]
|
||||
self.property_to_string = [
|
||||
("mandatory", _("mandatory")),
|
||||
("hidden", _("hidden")),
|
||||
("disabled", _("disabled")),
|
||||
("unique", _("unique")),
|
||||
("force_store_value", _("auto modified")),
|
||||
]
|
||||
|
||||
def run(self):
|
||||
print(self.gen_doc())
|
||||
|
||||
def gen_doc(self):
|
||||
tabulate_module.PRESERVE_WHITESPACE = True
|
||||
examples_mini = {}
|
||||
examples_all = {}
|
||||
return_string = self.formater.header()
|
||||
if self.rougailconfig["main_namespace"]:
|
||||
for namespace in self.conf.unrestraint.list():
|
||||
name = namespace.name()
|
||||
examples_mini[name] = {}
|
||||
examples_all[name] = {}
|
||||
doc = (
|
||||
self._display_doc(
|
||||
self.display_families(
|
||||
namespace,
|
||||
self.level + 1,
|
||||
examples_mini[name],
|
||||
examples_all[name],
|
||||
),
|
||||
[],
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
if not examples_mini[name]:
|
||||
del examples_mini[name]
|
||||
if not examples_all[name]:
|
||||
del examples_all[name]
|
||||
else:
|
||||
return_string += self.formater.title(
|
||||
_('Variables for "{0}"').format(namespace.name()), self.level
|
||||
)
|
||||
return_string += doc
|
||||
else:
|
||||
doc = (
|
||||
self._display_doc(
|
||||
self.display_families(
|
||||
self.conf.unrestraint,
|
||||
self.level + 1,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
),
|
||||
[],
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
if examples_all:
|
||||
return_string += self.formater.title(_("Variables"), self.level)
|
||||
return_string += doc
|
||||
if not examples_all:
|
||||
return ""
|
||||
if self.rougailconfig["doc.with_example"]:
|
||||
if examples_mini:
|
||||
return_string += self.formater.title(
|
||||
_("Example with mandatory variables not filled in"), self.level
|
||||
)
|
||||
return_string += self.formater.yaml(examples_mini)
|
||||
if examples_all:
|
||||
return_string += self.formater.title(
|
||||
"Example with all variables modifiable", self.level
|
||||
)
|
||||
return_string += self.formater.yaml(examples_all)
|
||||
return return_string
|
||||
|
||||
def _display_doc(self, variables, add_paths):
|
||||
return_string = ""
|
||||
for variable in variables:
|
||||
typ = variable["type"]
|
||||
path = variable["path"]
|
||||
if path in add_paths:
|
||||
continue
|
||||
if typ == "family":
|
||||
return_string += variable["title"]
|
||||
return_string += self._display_doc(variable["objects"], add_paths)
|
||||
else:
|
||||
for idx, path in enumerate(variable["paths"]):
|
||||
if path in self.dynamic_paths:
|
||||
paths_msg = display_list(
|
||||
[
|
||||
self.formater.bold(path_)
|
||||
for path_ in self.dynamic_paths[path]["paths"]
|
||||
],
|
||||
separator="or",
|
||||
)
|
||||
variable["objects"][idx][0] = variable["objects"][idx][
|
||||
0
|
||||
].replace("{{ ROUGAIL_PATH }}", paths_msg)
|
||||
identifiers = self.dynamic_paths[path]["identifiers"]
|
||||
description = variable["objects"][idx][1][0]
|
||||
if "{{ identifier }}" in description:
|
||||
if description.endswith("."):
|
||||
description = description[:-1]
|
||||
comment_msg = self.to_phrase(
|
||||
display_list(
|
||||
[
|
||||
description.replace(
|
||||
"{{ identifier }}",
|
||||
self.formater.italic(identifier),
|
||||
)
|
||||
for identifier in identifiers
|
||||
],
|
||||
separator="or",
|
||||
add_quote=True,
|
||||
)
|
||||
)
|
||||
variable["objects"][idx][1][0] = comment_msg
|
||||
variable["objects"][idx][1] = self.formater.join(
|
||||
variable["objects"][idx][1]
|
||||
)
|
||||
return_string += (
|
||||
self.formater.table(
|
||||
tabulate(
|
||||
variable["objects"],
|
||||
headers=self.formater.table_header(
|
||||
["Variable", "Description"]
|
||||
),
|
||||
tablefmt=self.formater.name,
|
||||
)
|
||||
)
|
||||
+ "\n\n"
|
||||
)
|
||||
add_paths.append(path)
|
||||
return return_string
|
||||
|
||||
def is_hidden(self, child):
|
||||
properties = child.property.get(uncalculated=True)
|
||||
for hidden_property in ["hidden", "disabled", "advanced"]:
|
||||
if hidden_property in properties:
|
||||
return True
|
||||
return False
|
||||
|
||||
def display_families(
|
||||
self,
|
||||
family,
|
||||
level,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
):
|
||||
variables = []
|
||||
for child in family.list():
|
||||
if self.is_hidden(child):
|
||||
continue
|
||||
if not child.isoptiondescription():
|
||||
if child.isfollower() and child.index() != 0:
|
||||
# only add to example
|
||||
self.display_variable(
|
||||
child,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
)
|
||||
continue
|
||||
path = child.path(uncalculated=True)
|
||||
if child.isdynamic():
|
||||
self.dynamic_paths.setdefault(
|
||||
path, {"paths": [], "identifiers": []}
|
||||
)["paths"].append(child.path())
|
||||
self.dynamic_paths[path]["identifiers"].append(
|
||||
child.identifiers()[-1]
|
||||
)
|
||||
if not variables or variables[-1]["type"] != "variables":
|
||||
variables.append(
|
||||
{
|
||||
"type": "variables",
|
||||
"objects": [],
|
||||
"path": path,
|
||||
"paths": [],
|
||||
}
|
||||
)
|
||||
variables[-1]["objects"].append(
|
||||
self.display_variable(
|
||||
child,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
)
|
||||
)
|
||||
variables[-1]["paths"].append(path)
|
||||
else:
|
||||
name = child.name()
|
||||
if child.isleadership():
|
||||
examples_mini[name] = []
|
||||
examples_all[name] = []
|
||||
else:
|
||||
examples_mini[name] = {}
|
||||
examples_all[name] = {}
|
||||
variables.append(
|
||||
{
|
||||
"type": "family",
|
||||
"title": self.display_family(
|
||||
child,
|
||||
level,
|
||||
),
|
||||
"path": child.path(uncalculated=True),
|
||||
"objects": self.display_families(
|
||||
child,
|
||||
level + 1,
|
||||
examples_mini[name],
|
||||
examples_all[name],
|
||||
),
|
||||
}
|
||||
)
|
||||
if not examples_mini[name]:
|
||||
del examples_mini[name]
|
||||
if not examples_all[name]:
|
||||
del examples_all[name]
|
||||
return variables
|
||||
|
||||
def display_family(
|
||||
self,
|
||||
family,
|
||||
level,
|
||||
):
|
||||
if family.name() != family.description(uncalculated=True):
|
||||
title = f"{family.description(uncalculated=True)}"
|
||||
else:
|
||||
warning = f'No attribute "description" for family "{family.path()}" in {display_xmlfiles(family.information.get("dictionaries"))}'
|
||||
warn(warning)
|
||||
title = f"{family.path()}"
|
||||
isdynamic = family.isdynamic(only_self=True)
|
||||
if isdynamic:
|
||||
identifiers = family.identifiers(only_self=True)
|
||||
if "{{ identifier }}" in title:
|
||||
title = display_list(
|
||||
[
|
||||
title.replace(
|
||||
"{{ identifier }}", self.formater.italic(identifier)
|
||||
)
|
||||
for identifier in identifiers
|
||||
],
|
||||
separator="or",
|
||||
add_quote=True,
|
||||
)
|
||||
msg = self.formater.title(title, level)
|
||||
subparameter = []
|
||||
self.manage_properties(family, subparameter)
|
||||
if subparameter:
|
||||
msg += self.subparameter_to_string(subparameter) + ENTER
|
||||
comment = []
|
||||
self.subparameter_to_parameter(subparameter, comment)
|
||||
if comment:
|
||||
msg += "\n".join(comment) + ENTER
|
||||
help = self.to_phrase(family.information.get("help", ""))
|
||||
if help:
|
||||
msg += "\n" + help + ENTER
|
||||
if family.isleadership():
|
||||
# help = "Cette famille contient des listes de bloc de variables."
|
||||
help = "This family contains lists of variable blocks."
|
||||
msg += "\n" + help + ENTER
|
||||
if isdynamic:
|
||||
identifiers = family.identifiers(only_self=True, uncalculated=True)
|
||||
if isinstance(identifiers, Calculation):
|
||||
identifiers = self.to_string(family, "dynamic")
|
||||
if isinstance(identifiers, list):
|
||||
for idx, val in enumerate(identifiers):
|
||||
if not isinstance(val, Calculation):
|
||||
continue
|
||||
identifiers[idx] = self.to_string(family, "dynamic", f"_{idx}")
|
||||
identifiers = self.formater.list(identifiers)
|
||||
# help = f"Cette famille construit des familles dynamiquement.\n\n{self.formater.bold('Identifiers')}: {identifiers}"
|
||||
help = f"This family builds families dynamically.\n\n{self.formater.bold('Identifiers')}: {identifiers}"
|
||||
msg += "\n" + help + ENTER
|
||||
return msg
|
||||
|
||||
def manage_properties(
|
||||
self,
|
||||
variable,
|
||||
subparameter,
|
||||
):
|
||||
properties = variable.property.get(uncalculated=True)
|
||||
for mode in self.rougailconfig["modes_level"]:
|
||||
if mode in properties:
|
||||
subparameter.append((self.formater.prop(mode), None, None))
|
||||
break
|
||||
for prop, msg in self.property_to_string:
|
||||
if prop in properties:
|
||||
subparameter.append((self.formater.prop(msg), None, None))
|
||||
elif variable.information.get(f"{prop}_calculation", False):
|
||||
subparameter.append(
|
||||
(self.formater.prop(msg), msg, self.to_string(variable, prop))
|
||||
)
|
||||
|
||||
def subparameter_to_string(
|
||||
self,
|
||||
subparameter,
|
||||
):
|
||||
subparameter_str = ""
|
||||
for param in subparameter:
|
||||
if param[1]:
|
||||
subparameter_str += f"_{param[0]}_ "
|
||||
else:
|
||||
subparameter_str += f"{param[0]} "
|
||||
return subparameter_str[:-1]
|
||||
|
||||
def subparameter_to_parameter(
|
||||
self,
|
||||
subparameter,
|
||||
comment,
|
||||
):
|
||||
for param in subparameter:
|
||||
if not param[1]:
|
||||
continue
|
||||
msg = param[2]
|
||||
comment.append(f"{self.formater.bold(param[1].capitalize())}: {msg}")
|
||||
|
||||
def to_phrase(self, msg):
|
||||
if not msg:
|
||||
return ""
|
||||
msg = str(msg).strip()
|
||||
if not msg.endswith("."):
|
||||
msg += "."
|
||||
return msg[0].upper() + msg[1:]
|
||||
|
||||
def display_variable(
|
||||
self,
|
||||
variable,
|
||||
examples_mini,
|
||||
examples_all,
|
||||
):
|
||||
if variable.isdynamic():
|
||||
parameter = ["{{ ROUGAIL_PATH }}"]
|
||||
else:
|
||||
parameter = [f"{self.formater.bold(variable.path())}"]
|
||||
subparameter = []
|
||||
description = variable.description(uncalculated=True)
|
||||
comment = [self.to_phrase(description)]
|
||||
help_ = self.to_phrase(variable.information.get("help", ""))
|
||||
if help_:
|
||||
comment.append(help_)
|
||||
self.type_to_string(
|
||||
variable,
|
||||
subparameter,
|
||||
comment,
|
||||
)
|
||||
self.manage_properties(
|
||||
variable,
|
||||
subparameter,
|
||||
)
|
||||
if variable.ismulti():
|
||||
multi = not variable.isfollower() or variable.issubmulti()
|
||||
else:
|
||||
multi = False
|
||||
if multi:
|
||||
subparameter.append((self.formater.prop("multiple"), None, None))
|
||||
if subparameter:
|
||||
parameter.append(self.subparameter_to_string(subparameter))
|
||||
if variable.name() == description:
|
||||
warning = f'No attribute "description" for variable "{variable.path()}" in {display_xmlfiles(variable.information.get("dictionaries"))}'
|
||||
warn(warning)
|
||||
default = self.get_default(
|
||||
variable,
|
||||
comment,
|
||||
)
|
||||
default_in_choices = False
|
||||
if variable.information.get("type") == "choice":
|
||||
choices = variable.value.list(uncalculated=True)
|
||||
if isinstance(choices, Calculation):
|
||||
choices = self.to_string(variable, "choice")
|
||||
if isinstance(choices, list):
|
||||
for idx, val in enumerate(choices):
|
||||
if not isinstance(val, Calculation):
|
||||
if default is not None and val == default:
|
||||
choices[idx] = str(val) + " ← " + _("(default)")
|
||||
default_in_choices = True
|
||||
continue
|
||||
choices[idx] = self.to_string(variable, "choice", f"_{idx}")
|
||||
choices = self.formater.list(choices)
|
||||
comment.append(f'{self.formater.bold(_("Choices"))}: {choices}')
|
||||
# choice
|
||||
if default is not None and not default_in_choices:
|
||||
comment.append(f"{self.formater.bold(_('Default'))}: {default}")
|
||||
self.manage_exemples(
|
||||
multi,
|
||||
variable,
|
||||
examples_all,
|
||||
examples_mini,
|
||||
comment,
|
||||
)
|
||||
self.subparameter_to_parameter(subparameter, comment)
|
||||
self.formater.columns(parameter, comment)
|
||||
return [self.formater.join(parameter), comment]
|
||||
|
||||
def get_default(
|
||||
self,
|
||||
variable,
|
||||
comment,
|
||||
):
|
||||
if variable.information.get("fake_default", False):
|
||||
default = None
|
||||
else:
|
||||
default = variable.value.get(uncalculated=True)
|
||||
if default in [None, []]:
|
||||
return
|
||||
if isinstance(default, Calculation):
|
||||
default = self.to_string(variable, "default")
|
||||
if isinstance(default, list):
|
||||
for idx, val in enumerate(default):
|
||||
if not isinstance(val, Calculation):
|
||||
continue
|
||||
default[idx] = self.to_string(variable, "default", f"_{idx}")
|
||||
default = self.formater.list(default)
|
||||
return default
|
||||
|
||||
def to_string(
|
||||
self,
|
||||
variable,
|
||||
prop,
|
||||
identifier="",
|
||||
):
|
||||
calculation_type = variable.information.get(
|
||||
f"{prop}_calculation_type{identifier}", None
|
||||
)
|
||||
if not calculation_type:
|
||||
raise Exception(
|
||||
f"cannot find {prop}_calculation_type{identifier} information, do you have declare doc has a plugins?"
|
||||
)
|
||||
calculation = variable.information.get(f"{prop}_calculation{identifier}")
|
||||
if calculation_type == "jinja":
|
||||
if calculation is not True:
|
||||
values = self.formater.to_string(calculation)
|
||||
else:
|
||||
values = "depends on a calculation"
|
||||
warning = f'"{prop}" is a calculation for {variable.path()} but has no description in {display_xmlfiles(variable.information.get("dictionaries"))}'
|
||||
warn(warning)
|
||||
elif calculation_type == "variable":
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
values = self.formater.to_string(calculation)
|
||||
else:
|
||||
values = _('the value of the variable "{0}"').format(calculation)
|
||||
elif calculation_type == "identifier":
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
values = self.formater.to_string(calculation)
|
||||
else:
|
||||
values = _("value of the {0}").format(calculation_type)
|
||||
else:
|
||||
values = _("value of the {0}").format(calculation_type)
|
||||
if not values.endswith("."):
|
||||
values += "."
|
||||
return values
|
||||
|
||||
def type_to_string(
|
||||
self,
|
||||
variable,
|
||||
subparameter,
|
||||
comment,
|
||||
):
|
||||
variable_type = variable.information.get("type")
|
||||
doc_type = DocTypes.get(variable_type, {"params": {}})
|
||||
subparameter.append(
|
||||
(
|
||||
self.formater.link(
|
||||
doc_type.get("msg", variable_type), ROUGAIL_VARIABLE_TYPE
|
||||
),
|
||||
None,
|
||||
)
|
||||
)
|
||||
option = variable.get()
|
||||
validators = []
|
||||
for param, msg in doc_type["params"].items():
|
||||
value = option.impl_get_extra(f"_{param}")
|
||||
if value is None:
|
||||
value = option.impl_get_extra(param)
|
||||
if value is not None and value is not False:
|
||||
validators.append(msg.format(value))
|
||||
valids = [
|
||||
name
|
||||
for name in variable.information.list()
|
||||
if name.startswith("validators_calculation_type_")
|
||||
]
|
||||
if valids:
|
||||
for idx in range(len(valids)):
|
||||
validators.append(
|
||||
self.to_string(
|
||||
variable,
|
||||
"validators",
|
||||
f"_{idx}",
|
||||
)
|
||||
)
|
||||
if validators:
|
||||
if len(validators) == 1:
|
||||
comment.append(f'{self.formater.bold("Validator")}: ' + validators[0])
|
||||
else:
|
||||
comment.append(
|
||||
f'{self.formater.bold("Validators")}:'
|
||||
+ self.formater.list(validators)
|
||||
)
|
||||
|
||||
def manage_exemples(
|
||||
self,
|
||||
multi,
|
||||
variable,
|
||||
examples_all,
|
||||
examples_mini,
|
||||
comment,
|
||||
):
|
||||
example_mini = None
|
||||
example_all = None
|
||||
example = variable.information.get("examples", None)
|
||||
if example is None:
|
||||
example = variable.information.get("test", None)
|
||||
default = variable.value.get()
|
||||
if isinstance(example, tuple):
|
||||
example = list(example)
|
||||
mandatory = "mandatory" in variable.property.get(uncalculated=True)
|
||||
if example:
|
||||
if not multi:
|
||||
example = example[0]
|
||||
title = _("Example")
|
||||
if mandatory:
|
||||
example_mini = example
|
||||
example_all = example
|
||||
else:
|
||||
if mandatory:
|
||||
example_mini = "\n - example"
|
||||
example_all = example
|
||||
len_test = len(example)
|
||||
example = self.formater.list(example)
|
||||
if len_test > 1:
|
||||
title = _("Examples")
|
||||
else:
|
||||
title = _("Example")
|
||||
comment.append(f"{self.formater.bold(title)}: {example}")
|
||||
elif default not in [None, []]:
|
||||
example_all = default
|
||||
else:
|
||||
example = CONVERT_OPTION.get(variable.information.get("type"), {}).get(
|
||||
"example", None
|
||||
)
|
||||
if example is None:
|
||||
example = "xxx"
|
||||
if multi:
|
||||
example = [example]
|
||||
if mandatory:
|
||||
example_mini = example
|
||||
example_all = example
|
||||
if variable.isleader():
|
||||
if example_mini is not None:
|
||||
for mini in example_mini:
|
||||
examples_mini.append({variable.name(): mini})
|
||||
if example_all is not None:
|
||||
for mall in example_all:
|
||||
examples_all.append({variable.name(): mall})
|
||||
elif variable.isfollower():
|
||||
if example_mini is not None:
|
||||
for idx in range(0, len(examples_mini)):
|
||||
examples_mini[idx][variable.name()] = example_mini
|
||||
if example_all is not None:
|
||||
for idx in range(0, len(examples_all)):
|
||||
examples_all[idx][variable.name()] = example_all
|
||||
else:
|
||||
if example_mini is not None:
|
||||
examples_mini[variable.name()] = example_mini
|
||||
examples_all[variable.name()] = example_all
|
||||
from .doc import RougailOutputDoc
|
||||
from .__version__ import __version__
|
||||
|
||||
|
||||
RougailOutput = RougailOutputDoc
|
||||
|
|
|
|||
1
src/rougail/output_doc/__version__.py
Normal file
1
src/rougail/output_doc/__version__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
__version__ = "0.2.0a39"
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
"""Annotate for documentation
|
||||
|
||||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
distribued with GPL-2 or later license
|
||||
|
||||
|
|
@ -20,12 +19,14 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
"""
|
||||
|
||||
from tiramisu import undefined
|
||||
from typing import Union
|
||||
from re import compile
|
||||
|
||||
from rougail.utils import undefined, PROPERTY_ATTRIBUTE
|
||||
from rougail.annotator.variable import Walk
|
||||
|
||||
from rougail.i18n import _
|
||||
from rougail.error import DictConsistencyError
|
||||
from rougail.object_model import (
|
||||
from rougail.output_doc.i18n import _
|
||||
from rougail.convert.object_model import (
|
||||
Calculation,
|
||||
JinjaCalculation,
|
||||
VariableCalculation,
|
||||
|
|
@ -34,8 +35,8 @@ from rougail.object_model import (
|
|||
IdentifierPropertyCalculation,
|
||||
InformationCalculation,
|
||||
IndexCalculation,
|
||||
NamespaceCalculation,
|
||||
CONVERT_OPTION,
|
||||
PROPERTY_ATTRIBUTE,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -47,113 +48,141 @@ class Annotator(Walk):
|
|||
def __init__(
|
||||
self,
|
||||
objectspace,
|
||||
*args,
|
||||
*args, # pylint: disable=unused-argument
|
||||
) -> None:
|
||||
if not objectspace.paths:
|
||||
return
|
||||
self.objectspace = objectspace
|
||||
self.default_values = self.objectspace.rougailconfig[
|
||||
"doc.default_values"
|
||||
]
|
||||
self.regexp_description_get_paths = None
|
||||
self.populate_family()
|
||||
self.populate_variable()
|
||||
|
||||
def get_examples_values(self, variable):
|
||||
def populate_family(self) -> None:
|
||||
"""Set doc, path, ... to family"""
|
||||
for family in self.get_families():
|
||||
self.add_informations_from_properties(family)
|
||||
if family.type == "dynamic":
|
||||
self.force_default_value_in_suffix_variable(family)
|
||||
self.calculation_to_information(
|
||||
family.path,
|
||||
"dynamic",
|
||||
family.dynamic,
|
||||
family.version,
|
||||
)
|
||||
path = family.path
|
||||
if path in self.objectspace.forced_descriptions:
|
||||
self.objectspace.informations.add(
|
||||
path,
|
||||
"forced_description",
|
||||
True,
|
||||
)
|
||||
|
||||
def force_default_value_in_suffix_variable(self, family) -> None:
|
||||
if not self.default_values:
|
||||
return
|
||||
if not isinstance(family.dynamic, list):
|
||||
self._force_default_value_in_suffix_variable(family, family.dynamic)
|
||||
else:
|
||||
for value in family.dynamic:
|
||||
self._force_default_value_in_suffix_variable(
|
||||
family, value, return_a_list=False
|
||||
)
|
||||
|
||||
def _force_default_value_in_suffix_variable(
|
||||
self,
|
||||
family,
|
||||
value,
|
||||
*,
|
||||
return_a_list=True,
|
||||
) -> None:
|
||||
"""For dynamic we must have values to document it"""
|
||||
if not isinstance(value, Calculation):
|
||||
return
|
||||
value_added = False
|
||||
if isinstance(value, (VariableCalculation, VariablePropertyCalculation)):
|
||||
variable = self.objectspace.paths.get_with_dynamic(
|
||||
value.variable,
|
||||
family.path,
|
||||
value.version,
|
||||
value.namespace,
|
||||
value.xmlfiles,
|
||||
)[0]
|
||||
if variable and not variable.default:
|
||||
values = self.add_examples_values(variable)
|
||||
value_added = True
|
||||
if not value_added:
|
||||
default_values = ["example"]
|
||||
if not return_a_list:
|
||||
default_values = default_values[0]
|
||||
value.default_values = default_values
|
||||
|
||||
def add_examples_values(self, variable) -> list:
|
||||
"""Check examples or test information to define examples values in a variable"""
|
||||
values = self.objectspace.informations.get(variable.path).get("examples", None)
|
||||
if not values:
|
||||
values = self.objectspace.informations.get(variable.path).get("test", None)
|
||||
if isinstance(values, tuple):
|
||||
values = list(values)
|
||||
if values:
|
||||
variable.default = list(values)
|
||||
else:
|
||||
variable.default = [CONVERT_OPTION[variable.type]["example"]]
|
||||
self.objectspace.informations.add(
|
||||
variable.path, "default_value_makes_sense", False
|
||||
)
|
||||
return values
|
||||
|
||||
def add_default_value(
|
||||
self,
|
||||
family,
|
||||
value,
|
||||
*,
|
||||
inside_list=False,
|
||||
) -> None:
|
||||
if isinstance(value, Calculation):
|
||||
default_values = "example"
|
||||
if not inside_list:
|
||||
default_values = [default_values]
|
||||
if isinstance(value, (VariableCalculation, VariablePropertyCalculation)):
|
||||
variable, identifier = self.objectspace.paths.get_with_dynamic(
|
||||
value.variable,
|
||||
value.path_prefix,
|
||||
family.path,
|
||||
value.version,
|
||||
value.namespace,
|
||||
value.xmlfiles,
|
||||
)
|
||||
values = self.get_examples_values(variable)
|
||||
if values:
|
||||
if inside_list:
|
||||
default_values = list(values)
|
||||
else:
|
||||
default_values = values
|
||||
value.default_values = default_values
|
||||
|
||||
def populate_family(self) -> None:
|
||||
"""Set doc, path, ... to family"""
|
||||
for family in self.get_families():
|
||||
self.objectspace.informations.add(
|
||||
family.path, "dictionaries", family.xmlfiles
|
||||
)
|
||||
self.convert_variable_property(family)
|
||||
if family.type != "dynamic":
|
||||
continue
|
||||
if not isinstance(family.dynamic, list):
|
||||
self.add_default_value(family, family.dynamic)
|
||||
else:
|
||||
for value in family.dynamic:
|
||||
self.add_default_value(family, value, inside_list=True)
|
||||
self.calculation_to_information(
|
||||
family.path,
|
||||
"dynamic",
|
||||
family.dynamic,
|
||||
family.version,
|
||||
)
|
||||
|
||||
def populate_variable(self) -> None:
|
||||
"""convert variables"""
|
||||
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 path in self.objectspace.default_multi:
|
||||
default = self.objectspace.default_multi[path]
|
||||
self.calculation_to_information(
|
||||
variable.path,
|
||||
path,
|
||||
"default",
|
||||
variable.default,
|
||||
default,
|
||||
variable.version,
|
||||
)
|
||||
self.calculation_to_information(
|
||||
variable.path,
|
||||
path,
|
||||
"validators",
|
||||
variable.validators,
|
||||
variable.version,
|
||||
)
|
||||
if variable.path in self.objectspace.leaders and not variable.default:
|
||||
values = self.get_examples_values(variable)
|
||||
if values:
|
||||
variable.default = list(values)
|
||||
else:
|
||||
variable.default = [CONVERT_OPTION[variable.type]["example"]]
|
||||
self.objectspace.informations.add(variable.path, "fake_default", True)
|
||||
self.objectspace.informations.add(
|
||||
variable.path, "dictionaries", variable.xmlfiles
|
||||
)
|
||||
self.convert_variable_property(variable)
|
||||
if (
|
||||
self.default_values
|
||||
and path in self.objectspace.leaders
|
||||
and not default
|
||||
):
|
||||
self.add_examples_values(variable)
|
||||
self.add_informations_from_properties(variable)
|
||||
if path in self.objectspace.forced_descriptions:
|
||||
self.objectspace.informations.add(
|
||||
path,
|
||||
"forced_description",
|
||||
True,
|
||||
)
|
||||
|
||||
def convert_variable_property(
|
||||
def add_informations_from_properties(
|
||||
self,
|
||||
variable: dict,
|
||||
) -> None:
|
||||
"""convert properties"""
|
||||
for prop in ["hidden", "disabled", "mandatory"]:
|
||||
for prop in PROPERTY_ATTRIBUTE:
|
||||
prop_value = getattr(variable, prop, None)
|
||||
if not prop_value:
|
||||
continue
|
||||
|
|
@ -163,6 +192,8 @@ class Annotator(Walk):
|
|||
prop_value,
|
||||
variable.version,
|
||||
)
|
||||
if isinstance(prop_value, Calculation):
|
||||
prop_value.default_values = False
|
||||
|
||||
def calculation_to_information(
|
||||
self,
|
||||
|
|
@ -171,76 +202,174 @@ class Annotator(Walk):
|
|||
values,
|
||||
version: str,
|
||||
):
|
||||
self._calculation_to_information(
|
||||
path,
|
||||
prop,
|
||||
values,
|
||||
version,
|
||||
)
|
||||
if isinstance(values, list):
|
||||
"""tranform calculation to an information"""
|
||||
one_is_calculation = False
|
||||
if not isinstance(values, list):
|
||||
if not isinstance(values, Calculation):
|
||||
return
|
||||
one_is_calculation = True
|
||||
datas = self.calculation_to_string(path, prop, values, version)
|
||||
else:
|
||||
datas = []
|
||||
for idx, val in enumerate(values):
|
||||
self._calculation_to_information(
|
||||
path,
|
||||
prop,
|
||||
val,
|
||||
version,
|
||||
identifier=f"_{idx}",
|
||||
)
|
||||
data = self.calculation_to_string(path, prop, val, version)
|
||||
if data is None:
|
||||
continue
|
||||
if "type" in data or "description" in data:
|
||||
one_is_calculation = True
|
||||
datas.append(data)
|
||||
if one_is_calculation:
|
||||
self.objectspace.informations.add(
|
||||
path,
|
||||
f"{prop}_calculation",
|
||||
datas,
|
||||
)
|
||||
|
||||
def _calculation_to_information(
|
||||
def calculation_to_string(
|
||||
self,
|
||||
path: str,
|
||||
prop: str,
|
||||
values,
|
||||
version: str,
|
||||
*,
|
||||
identifier: str = "",
|
||||
):
|
||||
if not isinstance(values, Calculation):
|
||||
return
|
||||
values_calculation = True
|
||||
return {"value": values}
|
||||
if values.description:
|
||||
if not self.regexp_description_get_paths:
|
||||
self.regexp_description_get_paths = compile('"(.*?)"')
|
||||
index = 0
|
||||
description = values.description
|
||||
variables = []
|
||||
for r_path in self.regexp_description_get_paths.findall(description):
|
||||
variable, identifiers = self.objectspace.paths.get_with_dynamic(
|
||||
r_path,
|
||||
path,
|
||||
values.version,
|
||||
values.namespace,
|
||||
values.xmlfiles,
|
||||
)
|
||||
if variable:
|
||||
description = description.replace(f'"{r_path}"', f'"{{{index}}}"')
|
||||
v = {"path": variable.path, "description": variable.description}
|
||||
if identifiers:
|
||||
v["identifiers"] = identifiers
|
||||
variables.append(v)
|
||||
index += 1
|
||||
ret = {"description": description}
|
||||
if variables:
|
||||
ret["variables"] = variables
|
||||
return ret
|
||||
if isinstance(values, JinjaCalculation):
|
||||
if values.description:
|
||||
values_calculation = values.description
|
||||
values_calculation_type = "jinja"
|
||||
elif isinstance(values, (VariableCalculation, VariablePropertyCalculation)):
|
||||
values_calculation = values.variable
|
||||
paths = self.objectspace.paths
|
||||
if version != "1.0" and paths.regexp_relative.search(values_calculation):
|
||||
calculation_path = paths.get_full_path(
|
||||
values_calculation,
|
||||
path,
|
||||
)
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
if values.when is not undefined:
|
||||
values_calculation = f'when the variable "{calculation_path}" has the value "{values.when}"'
|
||||
elif values.when_not is not undefined:
|
||||
values_calculation = f'when the variable "{calculation_path}" hasn\'t the value "{values.when_not}"'
|
||||
else:
|
||||
values_calculation = f'when the variable "{calculation_path}" has the value "True"'
|
||||
else:
|
||||
values_calculation = calculation_path
|
||||
values_calculation_type = "variable"
|
||||
elif isinstance(values, InformationCalculation):
|
||||
values_calculation_type = "information"
|
||||
elif isinstance(values, (IdentifierCalculation, IdentifierPropertyCalculation)):
|
||||
if version != "1.0" and prop in PROPERTY_ATTRIBUTE:
|
||||
if values.when is not undefined:
|
||||
values_calculation = f'when the identifier is "{values.when}"'
|
||||
elif values.when_not is not undefined:
|
||||
values_calculation = (
|
||||
f'when the identifier is not "{values.when_not}"'
|
||||
)
|
||||
values_calculation_type = "identifier"
|
||||
elif isinstance(values, IndexCalculation):
|
||||
values_calculation_type = "index"
|
||||
self.objectspace.informations.add(
|
||||
value = values.description
|
||||
else:
|
||||
value = True
|
||||
return {
|
||||
"type": "jinja",
|
||||
"value": value,
|
||||
}
|
||||
if isinstance(values, (VariableCalculation, VariablePropertyCalculation)):
|
||||
variable_path = self.get_path_from_variable(values, version, values.path)
|
||||
value = self.calculation_to_information_variable(
|
||||
variable_path, values, prop, version, path
|
||||
)
|
||||
if value is None:
|
||||
return
|
||||
return {
|
||||
"type": "variable",
|
||||
"value": value,
|
||||
"ori_path": variable_path,
|
||||
"optional": values.optional,
|
||||
"propertyerror": values.propertyerror,
|
||||
}
|
||||
if isinstance(values, InformationCalculation):
|
||||
return {
|
||||
"type": "information",
|
||||
"value": self.calculation_to_information_information(
|
||||
values, version, path
|
||||
),
|
||||
}
|
||||
if isinstance(values, (IdentifierCalculation, IdentifierPropertyCalculation)):
|
||||
return {
|
||||
"type": "identifier",
|
||||
"value": self.calculation_to_information_identifier(
|
||||
values, prop, version
|
||||
),
|
||||
}
|
||||
if isinstance(values, IndexCalculation):
|
||||
return {
|
||||
"type": "index",
|
||||
"value": True,
|
||||
}
|
||||
if isinstance(values, NamespaceCalculation):
|
||||
return {
|
||||
"type": "namespace",
|
||||
"value": True,
|
||||
}
|
||||
raise Exception(f'unknown calculation {type(values)} "{values}"')
|
||||
|
||||
def calculation_to_information_variable(
|
||||
self, variable_path: str, values, prop: str, version: str, path: str
|
||||
) -> str:
|
||||
# is optional
|
||||
variable = self.objectspace.paths.get_with_dynamic(
|
||||
variable_path,
|
||||
path,
|
||||
f"{prop}_calculation_type{identifier}",
|
||||
values_calculation_type,
|
||||
)
|
||||
self.objectspace.informations.add(
|
||||
path,
|
||||
f"{prop}_calculation{identifier}",
|
||||
values_calculation,
|
||||
)
|
||||
values.version,
|
||||
values.namespace,
|
||||
values.xmlfiles,
|
||||
)[0]
|
||||
if isinstance(values, VariableCalculation) and values.optional and not variable:
|
||||
return None
|
||||
if variable:
|
||||
variable_path = variable.path
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
# get comparative value
|
||||
if values.when_not is not undefined:
|
||||
value = values.when_not
|
||||
condition = "when_not"
|
||||
elif values.when is not undefined:
|
||||
value = values.when
|
||||
condition = "when"
|
||||
else:
|
||||
value = True
|
||||
condition = "when"
|
||||
|
||||
# set message
|
||||
values_calculation = (variable_path, value, condition)
|
||||
else:
|
||||
values_calculation = variable_path
|
||||
|
||||
return values_calculation
|
||||
|
||||
def calculation_to_information_information(
|
||||
self, values, version: str, path: str
|
||||
) -> Union[str, bool]:
|
||||
if values.variable:
|
||||
variable_path = self.get_path_from_variable(values, version, path)
|
||||
return _('the value of the information "{0}" of the variable "{1}"').format(
|
||||
values.information, variable_path
|
||||
)
|
||||
return _('the value of the global information "{0}"').format(values.information)
|
||||
|
||||
def calculation_to_information_identifier(
|
||||
self, values, prop: str, version: str
|
||||
) -> Union[str, bool]:
|
||||
if version != "1.0" and prop in PROPERTY_ATTRIBUTE:
|
||||
if values.when is not undefined:
|
||||
return _('when the identifier is "{0}"').format(values.when)
|
||||
if values.when_not is not undefined:
|
||||
return _('when the identifier is not "{0}"').format(values.when_not)
|
||||
return True
|
||||
|
||||
def get_path_from_variable(self, values, version: str, path: str) -> str:
|
||||
variable_path = values.variable
|
||||
paths = self.objectspace.paths
|
||||
if version != "1.0" and paths.regexp_relative.search(variable_path):
|
||||
variable_path = paths.get_full_path(
|
||||
variable_path,
|
||||
path,
|
||||
)
|
||||
elif version == "1.0" and "{{ suffix }}" in variable_path:
|
||||
variable_path = variable_path.replace("{{ suffix }}", "{{ identifier }}")
|
||||
return variable_path
|
||||
|
|
|
|||
191
src/rougail/output_doc/changelog.py
Normal file
191
src/rougail/output_doc/changelog.py
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
"""
|
||||
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 _
|
||||
from .utils import calc_path
|
||||
|
||||
|
||||
class Changelog: # pylint: disable=no-member,too-few-public-methods
|
||||
"""Build changelog"""
|
||||
|
||||
def gen_doc_changelog(self):
|
||||
"""Return changelog"""
|
||||
self.level = self.rougailconfig["doc.title_level"]
|
||||
self.previous_json_file = self.rougailconfig["doc.changelog.previous_json_file"]
|
||||
with Path(self.previous_json_file).open() as outfh:
|
||||
previous_doc = loads(outfh.read())
|
||||
self.load()
|
||||
self._added_variables = []
|
||||
self._modified_variables = []
|
||||
self._removed_variables = []
|
||||
root = self.rougailconfig["doc.root"]
|
||||
if root:
|
||||
informations = self.informations
|
||||
for family in root.split('.'):
|
||||
informations = informations[family]["children"]
|
||||
if previous_doc and family in previous_doc:
|
||||
previous_doc = previous_doc[family]['children']
|
||||
else:
|
||||
previous_doc = {}
|
||||
else:
|
||||
informations = self.informations
|
||||
self.formatter.options()
|
||||
self.parser(previous_doc, informations)
|
||||
return self.display()
|
||||
|
||||
def parser(self, previous_families, new_families):
|
||||
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":
|
||||
self._added_variables.append(new)
|
||||
else:
|
||||
self.parser({}, new["children"])
|
||||
elif not new:
|
||||
if previous["type"] == "variable":
|
||||
if "identifiers" in previous:
|
||||
for identifiers in previous["identifiers"]:
|
||||
self._removed_variables.append(calc_path(previous["path"], self.formatter, identifiers))
|
||||
else:
|
||||
self._removed_variables.append(calc_path(previous["path"], self.formatter))
|
||||
else:
|
||||
self.parser(previous["children"], {})
|
||||
elif previous["type"] != new["type"]:
|
||||
if previous["type"] == "variable":
|
||||
if "identifiers" in previous:
|
||||
for identifiers in previous["identifiers"]:
|
||||
self._removed_variables.append(calc_path(previous["path"], self.formatter, identifiers))
|
||||
else:
|
||||
self._removed_variables.append(calc_path(previous["path"], self.formatter))
|
||||
self.parser({}, new["children"])
|
||||
else:
|
||||
self._added_variables.append(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
|
||||
]
|
||||
elif isinstance(prop_previous, list):
|
||||
local_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 = []
|
||||
else:
|
||||
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._modified_variables.append((new, modified_attributes))
|
||||
|
||||
def display(self) -> str:
|
||||
msg = ""
|
||||
if self._added_variables:
|
||||
if len(self._added_variables) == 1:
|
||||
title = _("New variable")
|
||||
else:
|
||||
title = _("New variables")
|
||||
for add in self._added_variables:
|
||||
self.formatter.variable_to_string(add)
|
||||
msg += self.formatter._run(
|
||||
[
|
||||
self.formatter.title(title, self.level),
|
||||
self.formatter.tabular(),
|
||||
self.formatter.end_family(self.level)
|
||||
],
|
||||
self.level,
|
||||
dico_is_already_treated=True,
|
||||
)
|
||||
if self._modified_variables:
|
||||
if len(self._modified_variables) == 1:
|
||||
title = _("Modified variable")
|
||||
else:
|
||||
title = _("Modified variables")
|
||||
for mod, modified_attributes in self._modified_variables:
|
||||
self.formatter.variable_to_string(mod, modified_attributes)
|
||||
msg += self.formatter._run(
|
||||
[
|
||||
self.formatter.title(title, self.level),
|
||||
self.formatter.tabular(),
|
||||
self.formatter.end_family(self.level)
|
||||
],
|
||||
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.formatter._run(
|
||||
[
|
||||
self.formatter.title(title, self.level),
|
||||
self.formatter.list(self._removed_variables, inside_tabular=False),
|
||||
self.formatter.end_family(self.level)
|
||||
],
|
||||
self.level,
|
||||
dico_is_already_treated=True,
|
||||
)
|
||||
return msg
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
"""
|
||||
Config file for Rougail-doc
|
||||
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
@ -20,27 +18,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
from pathlib import Path
|
||||
from rougail.utils import load_modules
|
||||
from .i18n import _
|
||||
|
||||
|
||||
ROUGAIL_VARIABLE_TYPE = (
|
||||
"https://rougail.readthedocs.io/en/latest/variable.html#variables-types"
|
||||
)
|
||||
|
||||
|
||||
OUTPUTS = None
|
||||
TABULARS = None
|
||||
|
||||
|
||||
def get_outputs() -> None:
|
||||
module_name = "rougail.doc.output"
|
||||
def get_outputs_or_tabulars(type_) -> None:
|
||||
"""Load all outputs or tabulars"""
|
||||
module_name = f"rougail.output_doc.{type_}"
|
||||
outputs = {}
|
||||
for path in (Path(__file__).parent / "output").iterdir():
|
||||
names = []
|
||||
for path in (Path(__file__).parent / type_).iterdir():
|
||||
name = path.name
|
||||
if not name.endswith(".py") or name.endswith("__.py"):
|
||||
continue
|
||||
module = load_modules(module_name + "." + name, str(path))
|
||||
if "Formater" not in dir(module):
|
||||
continue
|
||||
level = module.Formater.level
|
||||
module = load_modules(module_name + "." + name[:-3], str(path))
|
||||
if type_ == "output":
|
||||
if "Formatter" not in dir(module):
|
||||
continue
|
||||
obj_class = module.Formatter
|
||||
elif type_ == "tabular":
|
||||
if "Tabular" not in dir(module):
|
||||
continue
|
||||
obj_class = module.Tabular
|
||||
level = obj_class.level
|
||||
if level in outputs:
|
||||
raise Exception(
|
||||
f'duplicated level rougail-doc for output "{level}": {module.Formater.name} and {outputs[level].name}'
|
||||
raise ImportError(
|
||||
_('duplicated level rougail-output-doc for {0} "{1}": {2} and {3}').format(
|
||||
type_, level, obj_class.name, outputs[level].name
|
||||
)
|
||||
)
|
||||
outputs[module.Formater.level] = module.Formater
|
||||
if obj_class.name in names:
|
||||
raise ImportError(
|
||||
_('duplicated name "{0}" in rougail-output-doc').format(
|
||||
obj_class.name
|
||||
)
|
||||
)
|
||||
names.append(obj_class.name)
|
||||
outputs[level] = obj_class
|
||||
return {outputs[level].name: outputs[level] for level in sorted(outputs)}
|
||||
|
||||
|
||||
|
|
@ -52,46 +74,220 @@ class OutPuts: # pylint: disable=R0903
|
|||
) -> None:
|
||||
global OUTPUTS
|
||||
if OUTPUTS is None:
|
||||
OUTPUTS = get_outputs()
|
||||
OUTPUTS = get_outputs_or_tabulars("output")
|
||||
|
||||
def get(self) -> dict:
|
||||
"""Get all outputs"""
|
||||
return OUTPUTS
|
||||
|
||||
|
||||
class Tabulars: # pylint: disable=R0903
|
||||
"""Transformations applied on a object instance"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
) -> None:
|
||||
global TABULARS
|
||||
if TABULARS is None:
|
||||
TABULARS = get_outputs_or_tabulars("tabular")
|
||||
|
||||
def get(self) -> dict:
|
||||
"""Get all tabulars"""
|
||||
return TABULARS
|
||||
|
||||
|
||||
def get_rougail_config(
|
||||
*,
|
||||
backward_compatibility=True,
|
||||
backward_compatibility=True, # pylint: disable=unused-argument
|
||||
) -> dict:
|
||||
"""Get documentation for output_doc modules"""
|
||||
outputs = list(OutPuts().get())
|
||||
output_format_default = outputs[0]
|
||||
rougail_options = """
|
||||
tabulars = list(Tabulars().get())
|
||||
tabular_default = tabulars[0]
|
||||
rougail_options = f"""
|
||||
cli:
|
||||
|
||||
read_write:
|
||||
redefine: true
|
||||
exists: true
|
||||
default:
|
||||
jinja: |-
|
||||
{{% if __.step.output is not propertyerror and "doc" in __.step.output %}}
|
||||
true
|
||||
{{% else %}}
|
||||
false
|
||||
{{% endif %}}
|
||||
|
||||
doc:
|
||||
description: Configuration rougail-doc
|
||||
description: {_('Generate documentation from structural files')}
|
||||
help: {_('The structural files contain all the information related to the variables. This output generates the documentation for all or some of these variables.')}
|
||||
disabled:
|
||||
type: jinja
|
||||
jinja: |
|
||||
{% if step.output != 'doc' %}
|
||||
disabled
|
||||
{% endif %}
|
||||
title_level:
|
||||
description: Start title level
|
||||
alternative_name: dt
|
||||
default: 1
|
||||
with_example:
|
||||
description: Display example in documentation
|
||||
negative_description: Hide example in documentation
|
||||
alternative_name: de
|
||||
default: false
|
||||
jinja: |-
|
||||
{{% if step.output is propertyerror or step.output != 'doc' %}}
|
||||
true
|
||||
{{% else %}}
|
||||
false
|
||||
{{% endif %}}
|
||||
return_type: boolean
|
||||
description: {_('if doc is not set in "step.output"')}
|
||||
|
||||
output_format:
|
||||
description: Generate document in format
|
||||
description: {_('The output format of the generated documentation')}
|
||||
alternative_name: do
|
||||
default: output_format_default
|
||||
default: { output_format_default }
|
||||
choices:
|
||||
""".replace(
|
||||
"output_format_default", output_format_default
|
||||
)
|
||||
"""
|
||||
for output in outputs:
|
||||
rougail_options += f" - {output}\n"
|
||||
rougail_options += f"""
|
||||
tabular_template:
|
||||
description: {_('Generate document with this tabular model')}
|
||||
help: {_("The variables are documented with a tabular view. A template selection allows you to choose the content of each column.")}
|
||||
alternative_name: dm
|
||||
default: { tabular_default }
|
||||
disabled:
|
||||
jinja: |-
|
||||
{{{{ _.output_format == 'json' }}}}
|
||||
return_type: boolean
|
||||
description: >
|
||||
{_('"_.output_format" in json is not compatible with this variable')}
|
||||
choices:
|
||||
"""
|
||||
for tabular in tabulars:
|
||||
rougail_options += f" - {tabular}\n"
|
||||
rougail_options += f"""
|
||||
contents:
|
||||
description: {_('Generated content')}
|
||||
help: {_('You can generate three type of document. All variables ("variables"), an example file in YAML format ("example") or change log ("changelog").')}
|
||||
alternative_name: dc
|
||||
choices:
|
||||
- variables
|
||||
- example
|
||||
- changelog
|
||||
default:
|
||||
- variables
|
||||
hidden:
|
||||
jinja: |-
|
||||
{{{{ _.output_format == 'json' }}}}
|
||||
return_type: boolean
|
||||
description: >
|
||||
{_('"_.output_format" in json is not compatible with changelog or example "_.contents"')}
|
||||
|
||||
title_level:
|
||||
description: {_('Starting title level')}
|
||||
alternative_name: dt
|
||||
default: 1
|
||||
|
||||
default_values:
|
||||
description: {_('Modify values to document all variables')}
|
||||
help: {_('To document leadership or dynamic family variables, it is sometimes necessary to generate values, which can change the values in the configuration. Be careful if you reuse this configuration.')}
|
||||
default: true
|
||||
|
||||
true_color:
|
||||
description: {_('Display documentation in console always with true color terminal')}
|
||||
default: false
|
||||
disabled:
|
||||
variable: _.output_format
|
||||
when_not: console
|
||||
|
||||
root:
|
||||
description: {_('Document the child variables of the family')}
|
||||
help: {_('By default, all accessible variables are included in the documentation. It is possible to define the family from which the documentation should be generated.')}
|
||||
alternative_name: dr
|
||||
mandatory: false
|
||||
|
||||
other_root_filenames:
|
||||
description: {_("The variables in this family are documented in another file")}
|
||||
help: {_("If you separate the variables into different files, the links between the variables will break. Therefore, you must define different filenames for the files containing these variables.")}
|
||||
type: leadership
|
||||
disabled:
|
||||
variable: _.root
|
||||
when: null
|
||||
|
||||
root_path:
|
||||
description: {_("This file contains child variables of the family")}
|
||||
mandatory: false
|
||||
|
||||
filename:
|
||||
description: {_("Name of the file")}
|
||||
type: unix_filename
|
||||
params:
|
||||
allow_relative: true
|
||||
types:
|
||||
- file
|
||||
|
||||
tabulars:
|
||||
description: {_('Variables and changelog documentation')}
|
||||
disabled:
|
||||
jinja: |-
|
||||
{{{{ step.output is propertyerror or "doc" not in step.output or _.output_format == "json" or ("variables" not in _.contents and "changelog" not in _.contents) }}}}
|
||||
return_type: boolean
|
||||
description: {_('if "_.output_format" is json or "_.contents" hasn\'t variables or changelog')}
|
||||
|
||||
without_family:
|
||||
description: {_('Do not add families in documentation')}
|
||||
default: false
|
||||
alternative_name: df
|
||||
|
||||
with_commandline:
|
||||
description: {_('Add command line informations in documentation')}
|
||||
alternative_name: dw
|
||||
default: false
|
||||
|
||||
with_environment:
|
||||
description: {_('Add environment variable informations in documentation')}
|
||||
alternative_name: de
|
||||
default: false
|
||||
|
||||
environment_prefix:
|
||||
description: {_("Environment variables prefix name")}
|
||||
alternative_name: dv
|
||||
default: ROUGAIL
|
||||
validators:
|
||||
- jinja: |-
|
||||
{{{{ (_.environment_prefix | upper) != _.environment_prefix }}}}
|
||||
return_type: boolean
|
||||
description: {_("should only use uppercase characters")}
|
||||
disabled:
|
||||
jinja: |-
|
||||
{{{{ ___.main_namespace is not defined or ___.main_namespace == none or _.with_environment is false }}}}
|
||||
return_type: boolean
|
||||
description: {_('if "main_namespace" is not set or "_.with_environment" is false')}
|
||||
|
||||
changelog:
|
||||
description: {_('Changelog documentation')}
|
||||
disabled:
|
||||
jinja: |-
|
||||
{{{{ step.output is propertyerror or "doc" not in step.output or _.output_format == "json" or "changelog" not in _.contents }}}}
|
||||
return_type: boolean
|
||||
description: {_('if changelog in not in "_.contents"')}
|
||||
|
||||
previous_json_file:
|
||||
description: {_('Previous description file in JSON format')}
|
||||
help: {_('To generate the changelog, you need to compare the old list of variables (in json format) with the current variables.')}
|
||||
alternative_name: dp
|
||||
|
||||
examples:
|
||||
description: {_('Examples configuration')}
|
||||
disabled:
|
||||
jinja: |-
|
||||
{{{{ step.output is propertyerror or "doc" not in step.output or "example" not in _.contents }}}}
|
||||
return_type: boolean
|
||||
description: {_('if example is not in "_.contents"')}
|
||||
|
||||
comment:
|
||||
description: {_('Add description of variables and families when generate examples')}
|
||||
alternative_name: dx
|
||||
default: false
|
||||
|
||||
comment_column:
|
||||
description: {_('Comment in examples starts at column')}
|
||||
default: 30
|
||||
disabled:
|
||||
variable: _.comment
|
||||
when: false
|
||||
"""
|
||||
return {
|
||||
"name": "doc",
|
||||
"process": "output",
|
||||
|
|
@ -100,5 +296,4 @@ doc:
|
|||
"level": 50,
|
||||
}
|
||||
|
||||
|
||||
__all__ = ("OutPuts", "get_rougail_config")
|
||||
|
|
|
|||
925
src/rougail/output_doc/doc.py
Normal file
925
src/rougail/output_doc/doc.py
Normal file
|
|
@ -0,0 +1,925 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from warnings import warn
|
||||
from typing import Optional
|
||||
from itertools import chain
|
||||
from re import compile
|
||||
|
||||
from tiramisu import Calculation, groups
|
||||
from tiramisu.error import ConfigError, display_list, PropertiesOptionError
|
||||
from rougail.tiramisu import display_xmlfiles, normalize_family
|
||||
from rougail.utils import undefined, get_properties_to_string, PROPERTY_ATTRIBUTE
|
||||
from rougail.error import VariableCalculationDependencyError, RougailWarning
|
||||
|
||||
from .config import OutPuts
|
||||
from .i18n import _
|
||||
from .utils import dump, to_phrase, calc_path
|
||||
from .example import Examples
|
||||
from .changelog import Changelog
|
||||
|
||||
|
||||
HIDDEN_PROPERTIES = [
|
||||
"hidden",
|
||||
"disabled",
|
||||
]
|
||||
|
||||
|
||||
class RougailOutputDoc(Examples, Changelog):
|
||||
"""Rougail Output Doc:
|
||||
Generate documentation from rougail description files
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: "Config",
|
||||
*,
|
||||
rougailconfig: "RougailConfig" = None,
|
||||
**kwargs,
|
||||
):
|
||||
# Import here to avoid circular import
|
||||
from rougail.tiramisu import CONVERT_OPTION
|
||||
|
||||
self.convert_option = CONVERT_OPTION
|
||||
if rougailconfig is None:
|
||||
from rougail import RougailConfig
|
||||
|
||||
rougailconfig = RougailConfig
|
||||
if rougailconfig["step.output"] != "doc":
|
||||
rougailconfig["step.output"] = "doc"
|
||||
if rougailconfig["step.output"] != "doc":
|
||||
raise Exception("doc is not set as step.output")
|
||||
self.outputs = OutPuts().get()
|
||||
self.conf = config
|
||||
self.modes_level = rougailconfig["modes_level"]
|
||||
self.disabled_modes = []
|
||||
if self.modes_level:
|
||||
for mode in self.modes_level:
|
||||
for prop in self.conf.property.get():
|
||||
if mode != prop:
|
||||
continue
|
||||
self.disabled_modes.append(prop)
|
||||
# self.conf.property.read_write()
|
||||
# # self.conf.property.remove("cache")
|
||||
self.rougailconfig = rougailconfig
|
||||
self.informations = None
|
||||
try:
|
||||
groups.namespace
|
||||
self.support_namespace = True
|
||||
except AttributeError:
|
||||
self.support_namespace = False
|
||||
self.property_to_string = get_properties_to_string()
|
||||
self.formatter = None
|
||||
super().__init__()
|
||||
|
||||
def run(self) -> str:
|
||||
"""Print documentation in stdout"""
|
||||
self.load()
|
||||
self.load_formatter()
|
||||
return_string = ""
|
||||
contents = self.rougailconfig["doc.contents"]
|
||||
if "variables" in contents:
|
||||
return_string += self.formatter.run(self.informations)
|
||||
if "example" in contents:
|
||||
return_string += self.gen_doc_examples()
|
||||
if "changelog" in contents:
|
||||
return_string += self.gen_doc_changelog()
|
||||
return True, return_string
|
||||
|
||||
def load_formatter(self) -> str:
|
||||
output_format = self.rougailconfig["doc.output_format"]
|
||||
self.formatter = self.outputs[output_format](self.rougailconfig, support_namespace=self.support_namespace)
|
||||
|
||||
def print(self) -> None:
|
||||
ret, data = self.run()
|
||||
print(data)
|
||||
return ret
|
||||
|
||||
def load(self):
|
||||
self.dynamic_paths = {}
|
||||
config = self.conf.unrestraint
|
||||
self.populate_dynamics(config=config)
|
||||
informations = self.parse_families(config)
|
||||
if informations is None:
|
||||
informations = {}
|
||||
self.informations = informations
|
||||
|
||||
def populate_dynamics(self, *, config=None, reload=False):
|
||||
if config is None:
|
||||
config = self.conf.unrestraint
|
||||
self._populate_dynamics(config, reload)
|
||||
|
||||
def _populate_dynamics(self, family, reload, uncalculated=False) -> None:
|
||||
def populate(child, uncalculated):
|
||||
if child.isoptiondescription():
|
||||
type_ = "family"
|
||||
else:
|
||||
type_ = "variable"
|
||||
if child.isdynamic():
|
||||
self.populate_dynamic(child, type_, reload, uncalculated)
|
||||
if child.isoptiondescription():
|
||||
self._populate_dynamics(child, reload, uncalculated)
|
||||
for child in family.list(uncalculated=uncalculated):
|
||||
populate(child, uncalculated)
|
||||
if not uncalculated:
|
||||
for child in family.list(uncalculated=True):
|
||||
if child.isdynamic() and child.path(uncalculated=True) not in self.dynamic_paths:
|
||||
populate(family, uncalculated=True)
|
||||
|
||||
def populate_dynamic(self, obj, type_, reload, uncalculated) -> None:
|
||||
path = obj.path(uncalculated=True)
|
||||
if path not in self.dynamic_paths:
|
||||
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, type_, its_a_path=False
|
||||
)
|
||||
elif obj.isoptiondescription():
|
||||
self.dynamic_paths[path]["description"] = self._convert_description(
|
||||
description, type_, its_a_path=True
|
||||
)
|
||||
if uncalculated:
|
||||
return
|
||||
dynamic_obj = self.dynamic_paths[path]
|
||||
if reload and obj.identifiers() in dynamic_obj["identifiers"]:
|
||||
return
|
||||
dynamic_obj["names"].append(obj.name())
|
||||
dynamic_obj["identifiers"].append(obj.identifiers())
|
||||
|
||||
def parse_families(self, family) -> dict:
|
||||
informations = {}
|
||||
leader = None
|
||||
for child in family.list():
|
||||
if self.is_inaccessible_user_data(child):
|
||||
continue
|
||||
if child.type(only_self=True) == "symlink":
|
||||
continue
|
||||
if not child.isoptiondescription():
|
||||
leader = self.parse_variable(child, leader, informations)
|
||||
else:
|
||||
self.parse_family(child, informations)
|
||||
return informations
|
||||
|
||||
def is_inaccessible_user_data(self, child):
|
||||
"""If family is not accessible in read_write mode (to load user_data),
|
||||
do not comment this family
|
||||
"""
|
||||
properties = child.property.get(uncalculated=True)
|
||||
for hidden_property in HIDDEN_PROPERTIES:
|
||||
if hidden_property in properties:
|
||||
return True
|
||||
|
||||
calculation = child.information.get(f"{hidden_property}_calculation", None)
|
||||
if calculation and calculation.get("type") == "variable":
|
||||
variable_path, value, condition = calculation["value"]
|
||||
variable = self.conf.forcepermissive.option(variable_path)
|
||||
try:
|
||||
variable.value.get()
|
||||
except AttributeError:
|
||||
variable = None
|
||||
if variable and self.is_inaccessible_user_data(variable):
|
||||
try:
|
||||
variable_value = self._get_unmodified_default_value(variable)
|
||||
except VariableCalculationDependencyError:
|
||||
pass
|
||||
else:
|
||||
if (condition == "when" and value == variable_value) or (condition == "when_not" and value != variable_value):
|
||||
return True
|
||||
if not child.isoptiondescription():
|
||||
for hidden_property in self.disabled_modes:
|
||||
if hidden_property in properties:
|
||||
return True
|
||||
return False
|
||||
|
||||
def parse_family(self, family, informations: dict, *, force_injection=False) -> None:
|
||||
path = family.path(uncalculated=True)
|
||||
name = family.name(uncalculated=True)
|
||||
sub_informations = self.parse_families(family)
|
||||
if not force_injection and 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,
|
||||
}
|
||||
|
||||
def parse_variable(
|
||||
self,
|
||||
variable,
|
||||
leader: dict,
|
||||
informations: dict,
|
||||
*,
|
||||
only_one=False,
|
||||
) -> Optional[dict]:
|
||||
path = variable.path(uncalculated=True)
|
||||
name = variable.name(uncalculated=True)
|
||||
potential_leader = None
|
||||
if variable.isdynamic():
|
||||
# information is already set
|
||||
potential_leader = self._parse_variable_dynamic(
|
||||
variable, leader, name, path, informations, only_one
|
||||
)
|
||||
elif variable.isfollower() and variable.index():
|
||||
self._parse_variable_follower_with_index(
|
||||
variable, leader, name, informations
|
||||
)
|
||||
else:
|
||||
potential_leader = self.parse_variable_normal(
|
||||
variable, leader, name, path, informations
|
||||
)
|
||||
if potential_leader:
|
||||
leader = potential_leader
|
||||
return leader
|
||||
|
||||
def parse_variable_normal(
|
||||
self, variable, leader, name: str, path: str, informations: dict
|
||||
) -> Optional[dict]:
|
||||
if variable.isdynamic():
|
||||
sub_informations = self.dynamic_paths[path]
|
||||
elif variable.isfollower() and path in informations: # variable.index():
|
||||
sub_informations = informations[name]
|
||||
else:
|
||||
sub_informations = {}
|
||||
if not self._populate_variable(
|
||||
variable,
|
||||
sub_informations,
|
||||
):
|
||||
return None
|
||||
self._add_examples(variable, sub_informations, leader)
|
||||
informations[name] = sub_informations
|
||||
if variable.isleader():
|
||||
return sub_informations
|
||||
return None
|
||||
|
||||
def _parse_variable_follower_with_index(
|
||||
self, variable, leader: dict, name: str, informations: dict
|
||||
) -> None:
|
||||
if (variable.index() + 1) > len(leader["gen_examples"][-1]):
|
||||
return
|
||||
informations[name]["gen_examples"][-1][variable.index()] = self._get_example(
|
||||
variable, informations[name], None
|
||||
)
|
||||
|
||||
def _parse_variable_dynamic(
|
||||
self, variable, leader, name, path, informations, only_one
|
||||
) -> None:
|
||||
# if path not in self.dynamic_paths:
|
||||
# self.populate_dynamic(variable, path)
|
||||
dynamic_variable = self.dynamic_paths[path]
|
||||
if (not only_one or path in informations) and "type" in dynamic_variable:
|
||||
dynamic_variable["gen_examples"].append(
|
||||
self._get_example(variable, dynamic_variable, leader)
|
||||
)
|
||||
if variable.isleader():
|
||||
return dynamic_variable
|
||||
if not only_one:
|
||||
return None
|
||||
return self.parse_variable_normal(variable, leader, name, path, informations)
|
||||
|
||||
def _get_family_type(self, family) -> str:
|
||||
if self.support_namespace and family.group_type() is groups.namespace:
|
||||
return "namespace"
|
||||
if family.isleadership():
|
||||
return "leadership"
|
||||
if family.isdynamic(only_self=True):
|
||||
return "dynamic"
|
||||
return "family"
|
||||
|
||||
def _populate_family(
|
||||
self,
|
||||
family,
|
||||
path: str,
|
||||
) -> dict:
|
||||
if family.isdynamic():
|
||||
informations = self.dynamic_paths[path]
|
||||
else:
|
||||
informations = {}
|
||||
if not self._populate(family, informations, "family"):
|
||||
return False
|
||||
if family.isleadership():
|
||||
informations.setdefault("help", []).append(
|
||||
_("This family contains lists of variable blocks")
|
||||
)
|
||||
if family.isdynamic(only_self=True):
|
||||
identifiers = self._to_string(family, "dynamic", do_not_raise=True)
|
||||
if identifiers is None:
|
||||
identifiers = family.identifiers(only_self=True)
|
||||
if not isinstance(identifiers, list):
|
||||
identifiers = [identifiers]
|
||||
informations["identifier"] = identifiers
|
||||
informations.setdefault("help", []).append(
|
||||
_("This family builds families dynamically")
|
||||
)
|
||||
return informations
|
||||
|
||||
def _populate_variable(
|
||||
self,
|
||||
variable,
|
||||
informations: dict,
|
||||
):
|
||||
informations["type"] = "variable"
|
||||
default = self._get_default(
|
||||
variable,
|
||||
)
|
||||
if default is not None:
|
||||
informations["default"] = {"name": _("Default"), "values": default}
|
||||
self._parse_type(
|
||||
variable,
|
||||
informations,
|
||||
)
|
||||
if not self._populate(variable, informations, "variable"):
|
||||
return False
|
||||
if variable.ismulti():
|
||||
multi = not variable.isfollower() or variable.issubmulti()
|
||||
else:
|
||||
multi = False
|
||||
if multi:
|
||||
informations["multiple"] = True
|
||||
examples = variable.information.get("examples", None)
|
||||
if examples is None:
|
||||
examples = variable.information.get("test", None)
|
||||
if examples is not None:
|
||||
if len(examples) == 1:
|
||||
name = _("Example")
|
||||
values = examples[0]
|
||||
else:
|
||||
name = _("Examples")
|
||||
values = list(examples)
|
||||
informations["examples"] = {
|
||||
"name": name,
|
||||
"values": values
|
||||
}
|
||||
tags = variable.information.get("tags", None)
|
||||
if tags:
|
||||
if len(tags) == 1:
|
||||
name = _("Tag")
|
||||
values = tags[0]
|
||||
else:
|
||||
name = _("Tags")
|
||||
values = list(tags)
|
||||
informations["tags"] = {
|
||||
"name": name,
|
||||
"values": values,
|
||||
}
|
||||
alternative_name = variable.information.get("alternative_name", None)
|
||||
if alternative_name:
|
||||
informations["alternative_name"] = alternative_name
|
||||
return True
|
||||
|
||||
def _populate(
|
||||
self,
|
||||
child,
|
||||
informations: dict,
|
||||
type_: str,
|
||||
):
|
||||
need_disabled, properties = self._parse_properties(child, informations)
|
||||
if not need_disabled:
|
||||
return False
|
||||
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), type_, its_a_path=True
|
||||
)
|
||||
else:
|
||||
description = None
|
||||
else:
|
||||
description = self._convert_description(
|
||||
child.description(uncalculated=True), 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"] = [to_phrase(help_)]
|
||||
if "properties" in informations:
|
||||
informations["properties"].extend(properties)
|
||||
else:
|
||||
informations["properties"] = properties
|
||||
properties = child.property.get(uncalculated=True)
|
||||
for mode in self.modes_level:
|
||||
if mode not in properties:
|
||||
continue
|
||||
informations["mode"] = mode
|
||||
break
|
||||
return True
|
||||
|
||||
def _convert_description(self, description, type_, its_a_path=False):
|
||||
if not its_a_path:
|
||||
description = to_phrase(description, type_)
|
||||
return description
|
||||
|
||||
def _add_examples(self, variable, informations: dict, leader) -> None:
|
||||
if not variable.index():
|
||||
example = self._get_example(variable, informations, leader)
|
||||
informations["gen_examples"] = [example]
|
||||
informations["mandatory_without_value"] = "mandatory" in variable.property.get(
|
||||
uncalculated=True
|
||||
) and (
|
||||
not variable.information.get("default_value_makes_sense", True)
|
||||
or variable.value.get(uncalculated=True) in [None, []]
|
||||
)
|
||||
|
||||
def _get_example(self, variable, informations: dict, leader):
|
||||
example = informations.get("examples", {}).get("values")
|
||||
if example is not None:
|
||||
if isinstance(example, tuple):
|
||||
example = list(example)
|
||||
if informations.get("multiple"):
|
||||
if not isinstance(example, list):
|
||||
example = [example]
|
||||
else:
|
||||
if isinstance(example, list):
|
||||
index = variable.index()
|
||||
if index is None or len(example) - 1 >= index:
|
||||
index = 0
|
||||
example = example[index]
|
||||
else:
|
||||
if variable.information.get("fake_default", False):
|
||||
default = None
|
||||
else:
|
||||
try:
|
||||
default = variable.value.get()
|
||||
except ConfigError:
|
||||
default = None
|
||||
if default not in [None, []]:
|
||||
example = default
|
||||
else:
|
||||
example = self.get_type_default_value(
|
||||
variable, informations
|
||||
)
|
||||
if leader is not None and variable.isfollower():
|
||||
example = [example] + [undefined] * (len(leader["gen_examples"][-1]) - 1)
|
||||
return example
|
||||
|
||||
def get_type_default_value(self, variable, informations):
|
||||
example = self.convert_option.get(variable.information.get("type"), {}).get(
|
||||
"example", None
|
||||
)
|
||||
if example is None:
|
||||
example = "xxx"
|
||||
if informations.get("multiple"):
|
||||
example = [example]
|
||||
return example
|
||||
|
||||
def _parse_type(
|
||||
self,
|
||||
child,
|
||||
informations,
|
||||
):
|
||||
variable_type = child.information.get("type")
|
||||
doc_type = self.convert_option.get(variable_type, {"params": {}})
|
||||
informations["variable_type"] = doc_type.get("msg", variable_type)
|
||||
# extra parameters for types
|
||||
option = child.get()
|
||||
validators = []
|
||||
if "params" in doc_type:
|
||||
for param, msg in doc_type["params"].items():
|
||||
value = option.impl_get_extra(f"_{param}")
|
||||
if value is None:
|
||||
value = option.impl_get_extra(param)
|
||||
if value is not None and value is not False:
|
||||
if isinstance(value, set):
|
||||
value = list(value)
|
||||
if isinstance(value, list):
|
||||
value = display_list(value, add_quote=True)
|
||||
if "doc" in msg:
|
||||
validators.append(msg['doc'].format(value))
|
||||
else:
|
||||
validators.append(msg['description'].format(value))
|
||||
|
||||
# get validation information from annotator
|
||||
for name in child.information.list():
|
||||
if not name.startswith("validators_calculation"):
|
||||
continue
|
||||
validators.extend(
|
||||
self._to_string(
|
||||
child,
|
||||
"validators",
|
||||
)
|
||||
)
|
||||
break
|
||||
if variable_type == "regexp":
|
||||
validators.append(
|
||||
_('text based with regular expressions "{0}"').format(child.pattern())
|
||||
)
|
||||
if validators:
|
||||
if len(validators) == 1:
|
||||
key = _("Validator")
|
||||
validators = validators[0]
|
||||
else:
|
||||
key = _("Validators")
|
||||
informations["validators"] = {"name": key, "values": validators}
|
||||
if variable_type == "choice":
|
||||
choices = self._to_string(child, "choice", do_not_raise=True)
|
||||
if choices is None:
|
||||
choices = child.value.list()
|
||||
for idx, val in enumerate(choices):
|
||||
if isinstance(val, Calculation):
|
||||
choices[idx] = self._to_string(child, "choice", f"_{idx}")
|
||||
informations["choices"] = {"name": _("Choices"), "values": choices}
|
||||
|
||||
def _parse_properties(
|
||||
self,
|
||||
child,
|
||||
child_informations,
|
||||
):
|
||||
informations = []
|
||||
properties = child.property.get(uncalculated=True)
|
||||
for prop, translated_prop in self.property_to_string:
|
||||
if "not_for_commandline" in properties:
|
||||
child_informations["not_for_commandline"] = True
|
||||
continue
|
||||
if prop in properties:
|
||||
prop_obj = {
|
||||
"type": "property",
|
||||
"name": translated_prop,
|
||||
"ori_name": prop,
|
||||
"access_control": prop in HIDDEN_PROPERTIES,
|
||||
}
|
||||
elif child.information.get(f"{prop}_calculation", False):
|
||||
annotation = self._to_string(child, prop)
|
||||
if annotation is None or isinstance(annotation, bool):
|
||||
if annotation is None and prop in HIDDEN_PROPERTIES:
|
||||
return False, {}
|
||||
if not annotation:
|
||||
continue
|
||||
prop_obj = {
|
||||
"type": "property",
|
||||
"name": translated_prop,
|
||||
"ori_name": prop,
|
||||
"access_control": prop in HIDDEN_PROPERTIES,
|
||||
}
|
||||
else:
|
||||
prop_obj = {
|
||||
"type": "property",
|
||||
"name": translated_prop,
|
||||
"ori_name": prop,
|
||||
"access_control": prop in HIDDEN_PROPERTIES,
|
||||
"annotation": annotation,
|
||||
}
|
||||
else:
|
||||
# this property is not in the variable so, do not comment it
|
||||
continue
|
||||
informations.append(prop_obj)
|
||||
return True, informations
|
||||
|
||||
def _get_default(
|
||||
self,
|
||||
variable,
|
||||
):
|
||||
default = self._to_string(variable, "default", do_not_raise=True)
|
||||
if default is not None:
|
||||
if default == []:
|
||||
default = None
|
||||
return default
|
||||
if variable.information.get("default_value_makes_sense", True):
|
||||
default_ = variable.value.get(uncalculated=True)
|
||||
if not isinstance(default_, Calculation):
|
||||
default = default_
|
||||
if default == []:
|
||||
default = None
|
||||
return default
|
||||
|
||||
def _to_string(
|
||||
self,
|
||||
child,
|
||||
prop,
|
||||
do_not_raise=False,
|
||||
):
|
||||
calculation = child.information.get(f"{prop}_calculation", None)
|
||||
if not calculation:
|
||||
if do_not_raise:
|
||||
return None
|
||||
raise Exception(
|
||||
f'cannot find "{prop}_calculation" information, '
|
||||
"do you have declare doc has a plugins?"
|
||||
)
|
||||
if isinstance(calculation, list):
|
||||
values = []
|
||||
for cal in calculation:
|
||||
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, inside_list=False):
|
||||
if "description" in calculation:
|
||||
values = calculation["description"]
|
||||
# if not values.endswith("."):
|
||||
# values += "."
|
||||
return calculation
|
||||
if "type" not in calculation:
|
||||
return calculation["value"]
|
||||
if calculation["type"] == "jinja":
|
||||
values = self._calculation_jinja_to_string(child, calculation, prop)
|
||||
elif calculation["type"] == "variable":
|
||||
values = self._calculation_variable_to_string(child, calculation, prop)
|
||||
elif calculation["type"] == "identifier":
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
values = calculation["value"]
|
||||
else:
|
||||
values = _("the value of the identifier")
|
||||
elif calculation["type"] == "information":
|
||||
values = calculation["value"]
|
||||
else:
|
||||
values = _("the value of the {0}").format(calculation["type"])
|
||||
# if not inside_list and isinstance(values, str) and not values.endswith("."):
|
||||
# values += "."
|
||||
return values
|
||||
|
||||
def _calculation_jinja_to_string(self, child, calculation, prop):
|
||||
if calculation["value"] is not True:
|
||||
values = calculation["value"]
|
||||
else:
|
||||
values = _("depends on a calculation")
|
||||
if (
|
||||
child.isoptiondescription()
|
||||
or not child.isfollower()
|
||||
or not child.index()
|
||||
):
|
||||
warning = _(
|
||||
'"{0}" is a calculation for {1} but has no description in {2}'
|
||||
).format(
|
||||
prop,
|
||||
child.path(),
|
||||
display_xmlfiles(child.information.get("ymlfiles")),
|
||||
)
|
||||
warn(
|
||||
warning,
|
||||
RougailWarning,
|
||||
)
|
||||
return values
|
||||
|
||||
def _calculation_variable_to_string(self, child, calculation, prop):
|
||||
if prop in PROPERTY_ATTRIBUTE:
|
||||
values = self._calculation_variable_to_string_known_property(child, calculation, prop)
|
||||
else:
|
||||
if calculation["optional"]:
|
||||
path = calculation["value"]
|
||||
if "{{ identifier }}" in path:
|
||||
if path not in self.dynamic_paths:
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
self.conf.forcepermissive.option(path).get()
|
||||
except AttributeError:
|
||||
return None
|
||||
if not calculation["optional"]:
|
||||
true_msg = _('the value of the variable "{0}"')
|
||||
else:
|
||||
true_msg = _('the value of the variable "{0}" if it is defined')
|
||||
if "{{ identifier }}" in calculation["ori_path"]:
|
||||
values = []
|
||||
all_is_undocumented = False
|
||||
for cpath, description, identifiers in self.get_annotation_variable(calculation["value"], calculation["ori_path"]):
|
||||
if cpath:
|
||||
all_is_undocumented = False
|
||||
path_obj = {
|
||||
"path": cpath,
|
||||
}
|
||||
if identifiers:
|
||||
path_obj["identifiers"] = identifiers
|
||||
values.append({
|
||||
"message": true_msg,
|
||||
"path": path_obj,
|
||||
"description": description,
|
||||
})
|
||||
else:
|
||||
if all_is_undocumented is None:
|
||||
all_is_undocumented = True
|
||||
values.append(_("the value of an undocumented variable"))
|
||||
if all_is_undocumented:
|
||||
if len(values) > 1:
|
||||
values = _("the values of undocumented variables")
|
||||
else:
|
||||
values = values[0]
|
||||
else:
|
||||
# FIXME A MUTUALISER AUSSI
|
||||
variable_path = calculation["ori_path"]
|
||||
variable = self.conf.unrestraint.option(variable_path)
|
||||
try:
|
||||
isfollower = variable.isfollower()
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
if not isfollower and self.is_inaccessible_user_data(variable):
|
||||
try:
|
||||
uncalculated = variable.value.get(uncalculated=True)
|
||||
except PropertiesOptionError:
|
||||
true_msg = None
|
||||
else:
|
||||
if uncalculated and not isinstance(
|
||||
uncalculated, Calculation
|
||||
):
|
||||
if isinstance(uncalculated, list):
|
||||
true_msg = {
|
||||
"submessage": _(
|
||||
"(from an undocumented variable)"
|
||||
),
|
||||
"values": uncalculated,
|
||||
}
|
||||
else:
|
||||
if not isinstance(uncalculated, str):
|
||||
uncalculated = dump(uncalculated)
|
||||
true_msg = _(
|
||||
"{0} (from an undocumented variable)"
|
||||
).format(uncalculated)
|
||||
else:
|
||||
true_msg = _("depends on an undocumented variable")
|
||||
if true_msg:
|
||||
if isinstance(true_msg, dict):
|
||||
values = true_msg
|
||||
else:
|
||||
try:
|
||||
description = self._convert_description(self.conf.option(calculation["ori_path"]).description(uncalculated=True), "description", its_a_path=False)
|
||||
except AttributeError:
|
||||
description = calculation["ori_path"]
|
||||
values = {
|
||||
"message": true_msg,
|
||||
"path": {
|
||||
"path": calculation["ori_path"],
|
||||
},
|
||||
"description": description,
|
||||
}
|
||||
else:
|
||||
values = None
|
||||
return values
|
||||
|
||||
def _calculation_variable_to_string_known_property(self, child, calculation, prop):
|
||||
variable_path, value, condition = calculation["value"]
|
||||
if isinstance(value, str):
|
||||
str_value = value
|
||||
else:
|
||||
str_value = dump(value)
|
||||
values = []
|
||||
if "{{ identifier }}" in calculation["ori_path"] or "{{ identifier }}" in variable_path:
|
||||
variables = self.get_annotation_variable(variable_path, calculation["ori_path"])
|
||||
else:
|
||||
option = self.conf.option(variable_path)
|
||||
try:
|
||||
is_inaccessible = self.is_inaccessible_user_data(option)
|
||||
except AttributeError as err:
|
||||
if err.code != "option-not-found":
|
||||
raise err from err
|
||||
is_inaccessible = True
|
||||
if is_inaccessible:
|
||||
variables = [[None, None, None]]
|
||||
else:
|
||||
description = self._convert_description(option.description(uncalculated=True), "description", its_a_path=False)
|
||||
variables = [[variable_path, description, None]]
|
||||
for cpath, description, identifiers in variables:
|
||||
if not cpath:
|
||||
variable = self.conf.forcepermissive.option(variable_path)
|
||||
try:
|
||||
variable_value = self._get_unmodified_default_value(variable)
|
||||
except PropertiesOptionError as err:
|
||||
if calculation["propertyerror"]:
|
||||
raise err from err
|
||||
variable_value = value
|
||||
except VariableCalculationDependencyError:
|
||||
values.append(_("depends on an undocumented variable"))
|
||||
continue
|
||||
except AttributeError as err:
|
||||
# if err.code != "option-not-found" or not calculation.get("optional", False):
|
||||
# raise err from err
|
||||
return calculation.get("default", False)
|
||||
if (
|
||||
condition == "when"
|
||||
and value == variable_value
|
||||
or condition == "when_not"
|
||||
and value != variable_value
|
||||
):
|
||||
if prop in HIDDEN_PROPERTIES:
|
||||
return False
|
||||
# always "prop"
|
||||
return True
|
||||
# never "prop"
|
||||
return False
|
||||
else:
|
||||
if condition == "when_not":
|
||||
if calculation["optional"]:
|
||||
if not calculation["propertyerror"]:
|
||||
msg = _(
|
||||
'when the variable "{{0}}" is defined, accessible and hasn\'t the value "{0}"'
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
'when the variable "{{0}}" is defined and hasn\'t the value "{0}"'
|
||||
)
|
||||
elif not calculation["propertyerror"]:
|
||||
msg = _('when the variable "{{0}}" is accessible and hasn\'t the value "{0}"')
|
||||
else:
|
||||
msg = _('when the variable "{{0}}" hasn\'t the value "{0}"')
|
||||
else:
|
||||
if calculation["optional"]:
|
||||
if not calculation["propertyerror"]:
|
||||
msg = _(
|
||||
'when the variable "{{0}}" is defined, is accessible and has the value "{0}"'
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
'when the variable "{{0}}" is defined and has the value "{0}"'
|
||||
)
|
||||
elif not calculation["propertyerror"]:
|
||||
msg = _('when the variable "{{0}}" is accessible and has the value "{0}"')
|
||||
else:
|
||||
msg = _('when the variable "{{0}}" has the value "{0}"')
|
||||
path_obj = {
|
||||
"path": variable_path,
|
||||
}
|
||||
if identifiers:
|
||||
path_obj["identifiers"] = identifiers
|
||||
|
||||
values.append({
|
||||
"message": msg.format(str_value),
|
||||
"path": path_obj,
|
||||
"description": description,
|
||||
})
|
||||
if len(values) == 1:
|
||||
return values[0]
|
||||
return values
|
||||
|
||||
def get_annotation_variable(self, current_path, ori_path):
|
||||
if current_path == ori_path:
|
||||
regexp = None
|
||||
else:
|
||||
regexp = compile(
|
||||
"^"
|
||||
+ ori_path.replace("{{ identifier }}", "(.*)")
|
||||
+ "$"
|
||||
)
|
||||
information = self.dynamic_paths[current_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(cpath)):
|
||||
yield None, None, None
|
||||
else:
|
||||
description = self._convert_description(self.conf.option(path).description(uncalculated=True), "description", its_a_path=False)
|
||||
if "{{ identifier }}" in path:
|
||||
yield path, description, identifiers.copy()
|
||||
else:
|
||||
yield path, description, None
|
||||
|
||||
def _get_unmodified_default_value(self, child):
|
||||
calculation = child.information.get(f"default_calculation", None)
|
||||
if not calculation:
|
||||
return child.value.get()
|
||||
if calculation["type"] == "variable":
|
||||
variable = self.conf.forcepermissive.option(calculation["value"])
|
||||
if variable and self.is_inaccessible_user_data(variable):
|
||||
return self._get_unmodified_default_value(variable)
|
||||
raise VariableCalculationDependencyError()
|
||||
238
src/rougail/output_doc/example.py
Normal file
238
src/rougail/output_doc/example.py
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from ruamel.yaml import CommentedMap
|
||||
|
||||
from .utils import _, calc_path
|
||||
|
||||
|
||||
class Examples: # pylint: disable=no-member,too-few-public-methods
|
||||
"""Build examples"""
|
||||
|
||||
def __init__(self):
|
||||
self.examples = None
|
||||
self.examples_mandatories = None
|
||||
|
||||
def gen_doc_examples(self):
|
||||
"""Return examples"""
|
||||
root = self.rougailconfig["doc.root"]
|
||||
self.comment_examples = self.rougailconfig["doc.examples.comment"]
|
||||
self.level = self.rougailconfig["doc.title_level"]
|
||||
if self.comment_examples:
|
||||
self.comment_examples_column = self.rougailconfig["doc.examples.comment_column"]
|
||||
self._build_examples(root)
|
||||
return_string = ""
|
||||
datas = []
|
||||
if self.examples_mandatories:
|
||||
datas.extend([
|
||||
self.formatter.title(
|
||||
_("Example with mandatory variables not filled in"), self.level
|
||||
),
|
||||
self.formatter.yaml(self.examples_mandatories),
|
||||
self.formatter.end_family(self.level),
|
||||
])
|
||||
if self.examples:
|
||||
datas.extend([self.formatter.title(
|
||||
_("Example with all variables modifiable"), self.level
|
||||
),
|
||||
self.formatter.yaml(self.examples),
|
||||
self.formatter.end_family(self.level),
|
||||
])
|
||||
return self.formatter.compute(datas)
|
||||
|
||||
def _build_examples(self, root):
|
||||
examples, examples_mandatories = self._parse_examples(
|
||||
self.informations
|
||||
)
|
||||
if root and examples:
|
||||
sub_examples = examples
|
||||
sub_examples_mandatories = examples_mandatories
|
||||
new_examples_mandatories = examples_mandatories = {}
|
||||
new_examples = examples = {}
|
||||
for sub in root.split('.'):
|
||||
new_examples[sub] = {}
|
||||
new_examples = new_examples[sub]
|
||||
sub_examples = sub_examples[sub]
|
||||
if examples_mandatories and sub in sub_examples_mandatories:
|
||||
new_examples_mandatories[sub] = {}
|
||||
new_examples_mandatories = new_examples_mandatories[sub]
|
||||
sub_examples_mandatories = sub_examples_mandatories[sub]
|
||||
else:
|
||||
new_examples_mandatories = {}
|
||||
sub_examples_mandatories = {}
|
||||
new_examples.update(sub_examples)
|
||||
new_examples_mandatories.update(sub_examples_mandatories)
|
||||
self.examples = examples
|
||||
self.examples_mandatories = examples_mandatories
|
||||
|
||||
def _parse_examples(self, dico, dyn_parent: Optional[str] = None) -> tuple:
|
||||
if self.comment_examples:
|
||||
examples = CommentedMap()
|
||||
examples_mandatories = CommentedMap()
|
||||
else:
|
||||
examples = {}
|
||||
examples_mandatories = {}
|
||||
for value in dico.values():
|
||||
if value["type"] == "variable":
|
||||
parse = self._parse_examples_variable
|
||||
else:
|
||||
parse = self._parse_examples_family
|
||||
parse(
|
||||
value, dyn_parent, examples, examples_mandatories
|
||||
)
|
||||
return examples, examples_mandatories
|
||||
|
||||
def _parse_examples_variable(
|
||||
self,
|
||||
variable,
|
||||
dyn_parent: Optional[str],
|
||||
examples: dict,
|
||||
examples_mandatories: dict,
|
||||
) -> None:
|
||||
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
|
||||
if len(variable["names"]) == 1:
|
||||
name = variable["names"][0]
|
||||
else:
|
||||
name = variable["names"][idx]
|
||||
value = variable["gen_examples"][idx]
|
||||
examples[name] = value
|
||||
if self.comment_examples and "description" in variable:
|
||||
description = variable["description"]
|
||||
if description.endswith('.'):
|
||||
description = description[:-1]
|
||||
examples.yaml_add_eol_comment(description, name, column=self.comment_examples_column)
|
||||
if variable["mandatory_without_value"]:
|
||||
examples_mandatories[name] = value
|
||||
if self.comment_examples and "description" in variable:
|
||||
description = variable["description"]
|
||||
if description.endswith('.'):
|
||||
description = description[:-1]
|
||||
examples_mandatories.yaml_add_eol_comment(description, name, column=self.comment_examples_column)
|
||||
break
|
||||
|
||||
def _parse_examples_family(
|
||||
self,
|
||||
family,
|
||||
dyn_parent: Optional[str],
|
||||
examples: dict,
|
||||
examples_mandatories: dict,
|
||||
) -> None:
|
||||
def _set_example(idx, identifiers):
|
||||
path = calc_path(ori_path, identifiers=identifiers)
|
||||
if dyn_parent is not None and not path.startswith(dyn_parent):
|
||||
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:
|
||||
func = self._parse_examples
|
||||
ret_e, ret_m = func(
|
||||
family["children"],
|
||||
path + "." if family["type"] == "dynamic" else dyn_parent,
|
||||
)
|
||||
if ret_m:
|
||||
examples_mandatories[name] = ret_m
|
||||
if self.comment_examples and "description" in family["informations"]:
|
||||
description = family["informations"]["description"]
|
||||
if description.endswith('.'):
|
||||
description = description[:-1]
|
||||
examples_mandatories.yaml_add_eol_comment(description, name, column=self.comment_examples_column)
|
||||
if ret_e:
|
||||
examples[name] = ret_e
|
||||
if self.comment_examples and "description" in family["informations"]:
|
||||
description = family["informations"]["description"]
|
||||
if description.endswith('.'):
|
||||
description = description[:-1]
|
||||
examples.yaml_add_eol_comment(description, name, column=self.comment_examples_column)
|
||||
|
||||
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
|
||||
) -> tuple:
|
||||
examples = []
|
||||
examples_mandatories = []
|
||||
leader = next(iter(leadership.values()))
|
||||
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["gen_examples"][path_idx])):
|
||||
if self.comment_examples:
|
||||
followers = CommentedMap()
|
||||
else:
|
||||
followers = {}
|
||||
for follower in leadership.values():
|
||||
if len(follower["names"]) == 1:
|
||||
name = follower["names"][0]
|
||||
else:
|
||||
name = follower["names"][path_idx]
|
||||
followers[name] = follower["gen_examples"][path_idx][leader_idx]
|
||||
if self.comment_examples and "description" in follower:
|
||||
description = follower["description"]
|
||||
if description.endswith('.'):
|
||||
description = description[:-1]
|
||||
followers.yaml_add_eol_comment(description, name, column=self.comment_examples_column)
|
||||
examples.append(followers)
|
||||
if leader["mandatory_without_value"]:
|
||||
if self.comment_examples:
|
||||
followers = CommentedMap()
|
||||
else:
|
||||
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["gen_examples"][path_idx][leader_idx]
|
||||
if self.comment_examples and "description" in follower:
|
||||
description = follower["description"]
|
||||
if description.endswith('.'):
|
||||
description = description[:-1]
|
||||
followers.yaml_add_eol_comment(description, name, column=self.comment_examples_column)
|
||||
examples_mandatories.append(followers)
|
||||
break
|
||||
return examples, examples_mandatories
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"""Internationalisation utilities
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
from gettext import translation
|
||||
from pathlib import Path
|
||||
|
||||
t = translation("rougail_output_doc", str(Path(__file__).parent / "locale"), fallback=True)
|
||||
t = translation(
|
||||
"rougail_output_doc", str(Path(__file__).parent / "locale"), fallback=True
|
||||
)
|
||||
|
||||
_ = t.gettext
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
"""Loads output
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
@ -16,124 +16,148 @@ You should have received a copy of the GNU Lesser General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from io import BytesIO
|
||||
from typing import List
|
||||
from itertools import chain
|
||||
from ruamel.yaml import YAML
|
||||
from ..utils import CommonFormatter, dump
|
||||
from ..i18n import _
|
||||
|
||||
|
||||
class Formater:
|
||||
class Formatter(CommonFormatter):
|
||||
"""The asciidoc formatter"""
|
||||
|
||||
name = "asciidoc"
|
||||
_tabular_name = "asciidoc"
|
||||
level = 40
|
||||
|
||||
def __init__(self):
|
||||
self._yaml = YAML()
|
||||
self._yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
|
||||
def header(self):
|
||||
return ""
|
||||
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
"""Display family name as a title"""
|
||||
char = "="
|
||||
return f"{char * (level + 1)} {title}\n\n"
|
||||
|
||||
def yaml(self, dump: dict) -> str:
|
||||
return f"[,yaml]\n----\n{self.dump(dump)}\n----\n"
|
||||
|
||||
def table(self, table: str) -> str:
|
||||
# add 'a' option in cols to display list
|
||||
stable = table.split("\n", 1)
|
||||
return stable[0].replace("<", "a") + "\n" + stable[1]
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
) -> str:
|
||||
return f"`{link}[{comment}]`"
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
) -> str:
|
||||
return f"`{prop}`"
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
) -> str:
|
||||
prefix = "\n\n* "
|
||||
char = "\n* "
|
||||
return prefix + char.join([self.dump(choice) for choice in choices])
|
||||
|
||||
def is_list(
|
||||
self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
return txt.startswith("* ")
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col1: List[str],
|
||||
col2: List[str],
|
||||
) -> None:
|
||||
self.max_line = 0
|
||||
for params in chain(col1, col2):
|
||||
for param in params.split("\n"):
|
||||
self.max_line = max(self.max_line, len(param))
|
||||
self.max_line += 1
|
||||
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
"""Display line in tabular from a list"""
|
||||
string = ""
|
||||
previous = ""
|
||||
for line in lst:
|
||||
if string:
|
||||
if self.is_list(previous.split("\n")[-1]):
|
||||
if self.is_list(previous.split("\n", 1)[-1]):
|
||||
string += "\n\n"
|
||||
else:
|
||||
string += " +\n"
|
||||
string += line
|
||||
|
||||
previous = line
|
||||
return "\n" + string
|
||||
|
||||
def to_string(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
return text
|
||||
|
||||
def table_header(
|
||||
self,
|
||||
lst,
|
||||
):
|
||||
return lst[0] + " " * (self.max_line - len(lst[0])), lst[1] + " " * (
|
||||
self.max_line - len(lst[1])
|
||||
)
|
||||
return string
|
||||
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to bold"""
|
||||
return f"**{msg}**"
|
||||
|
||||
def italic(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
return f"_{msg}_"
|
||||
"""Set a text to italic"""
|
||||
return f"__{msg}__"
|
||||
|
||||
def dump(self, dico):
|
||||
with BytesIO() as ymlfh:
|
||||
self._yaml.dump(dico, ymlfh)
|
||||
ret = ymlfh.getvalue().decode("utf-8").strip()
|
||||
if ret.endswith("..."):
|
||||
ret = ret[:-3].strip()
|
||||
return ret
|
||||
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,
|
||||
) -> str:
|
||||
"""Return stripped text (as help)"""
|
||||
return text.strip()
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
*,
|
||||
inside_tabular: bool=True,
|
||||
type_: str="variable",
|
||||
with_enter: bool = True,
|
||||
) -> str:
|
||||
"""Display a liste of element"""
|
||||
char = "\n* "
|
||||
if with_enter:
|
||||
prefix = "\n\n* "
|
||||
else:
|
||||
prefix = char
|
||||
return prefix + char.join([dump(choice) for choice in choices])
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
italic: bool,
|
||||
delete: bool,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Display property"""
|
||||
if italic:
|
||||
prop = self.italic(prop)
|
||||
if delete:
|
||||
prop = self.delete(prop)
|
||||
if underline:
|
||||
prop = self.underline(prop)
|
||||
return f"`{prop}`"
|
||||
|
||||
def yaml(self, _dump: dict) -> str:
|
||||
"""Dump yaml part of documentation"""
|
||||
return f"[,yaml]\n----\n---\n{dump(_dump)}\n----\n"
|
||||
|
||||
def tabular(self, with_header: bool = True) -> str:
|
||||
"""Transform list to a tabular in string format
|
||||
we change the first line because we want that col has the same width
|
||||
"""
|
||||
tabular = super().tabular(with_header)
|
||||
stable = tabular.split("\n", 1)
|
||||
return '[cols="1a,1a"]\n' + stable[1]
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Add a link"""
|
||||
if underline:
|
||||
link = self.underline(link)
|
||||
return f"`{link}[{comment}]`"
|
||||
|
||||
def is_list(
|
||||
self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
"""verify if a text is a list"""
|
||||
return txt.strip().startswith("* ")
|
||||
|
||||
def family_informations(self) -> str:
|
||||
info = self.bold(f"🛈 {_('Informations')}")
|
||||
return f"====\n{info}\n\n"
|
||||
|
||||
def end_family_informations(self) -> str:
|
||||
return f"\n====\n"
|
||||
|
||||
def family_informations_ends_line(self) -> str:
|
||||
return " +\n"
|
||||
|
|
|
|||
210
src/rougail/output_doc/output/console.py
Normal file
210
src/rougail/output_doc/output/console.py
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
|
||||
from ..i18n import _
|
||||
from ..utils import dump, CommonFormatter
|
||||
|
||||
|
||||
class Formatter(CommonFormatter):
|
||||
"""The console formatter"""
|
||||
|
||||
name = "console"
|
||||
level = 10
|
||||
enter_tabular = "\n"
|
||||
titles_color = {
|
||||
"title1": "bright_cyan underline bold",
|
||||
"title2": "bright_green underline bold",
|
||||
"title3": "green1 underline bold",
|
||||
"title4": "green3 underline bold",
|
||||
"title5": "dark_green underline bold",
|
||||
}
|
||||
|
||||
def __init__(self, rougailconfig, **kwargs) -> None:
|
||||
from rich.table import Table
|
||||
from rich.theme import Theme
|
||||
from rich.console import Console
|
||||
from rich.syntax import Syntax
|
||||
|
||||
self.rich_table = Table
|
||||
self.rich_console = Console
|
||||
self.rich_syntaxt = Syntax
|
||||
self.custom_theme = Theme(self.titles_color)
|
||||
self.max_line = 0
|
||||
super().__init__(rougailconfig, **kwargs)
|
||||
|
||||
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, init=True)
|
||||
return self.compute(dico)
|
||||
|
||||
def compute(self, dico):
|
||||
if self.rougailconfig["doc.true_color"]:
|
||||
force_terminal = 'xterm-256color'
|
||||
else:
|
||||
force_terminal = None
|
||||
console = self.rich_console(theme=self.custom_theme, force_terminal=force_terminal)
|
||||
with console.capture() as capture:
|
||||
for data in dico:
|
||||
console.print(data)
|
||||
return capture.get()
|
||||
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
"""Display family name as a title"""
|
||||
space = " " * (2 * (level - 1))
|
||||
return f"{space}[title{level}]{title}[/title{level}]\n"
|
||||
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
"""Display line in tabular from a list"""
|
||||
return self.enter_tabular.join(lst)
|
||||
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to bold"""
|
||||
return f"[bold]{msg}[/bold]"
|
||||
|
||||
def italic(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""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,
|
||||
) -> str:
|
||||
"""Return stripped text (as help)"""
|
||||
return text
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
*,
|
||||
inside_tabular: bool=True,
|
||||
type_: str="variable",
|
||||
with_enter: bool = True,
|
||||
) -> str:
|
||||
"""Display a liste of element"""
|
||||
|
||||
if type_ == "variable":
|
||||
if with_enter:
|
||||
char = first_char = f"{self.enter_tabular}• "
|
||||
else:
|
||||
first_char = "• "
|
||||
char = f"{self.enter_tabular}{first_char}"
|
||||
else:
|
||||
char = first_char = f"\n{self.family_informations_starts_line()} • "
|
||||
ret = ""
|
||||
for idx, choice in enumerate(choices):
|
||||
if not isinstance(choice, str):
|
||||
choice = dump(choice)
|
||||
if not idx:
|
||||
c = first_char
|
||||
else:
|
||||
c = char
|
||||
ret += c + choice
|
||||
return ret
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
italic: bool,
|
||||
delete: bool,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Display property"""
|
||||
if italic:
|
||||
prop = self.italic(prop)
|
||||
if delete:
|
||||
prop = self.delete(prop)
|
||||
if underline:
|
||||
prop = self.underline(prop)
|
||||
prop = f"[reverse][bold] {prop} [/bold][/reverse]"
|
||||
return prop
|
||||
|
||||
def yaml(self, _dump):
|
||||
"""Dump yaml part of documentation"""
|
||||
return self.rich_syntaxt(f'---\n{dump(_dump)}', 'yaml')
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Add a link"""
|
||||
return self.prop(comment, False, False, underline)
|
||||
# return f"{comment} ({link})"
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col: List[str],
|
||||
) -> None:
|
||||
"""count columns length"""
|
||||
for line in col:
|
||||
for l in line.split(self.enter_tabular):
|
||||
self.max_line = max(self.max_line, len(l) + 1)
|
||||
|
||||
def tabular(self, with_header: bool = True) -> str:
|
||||
"""Transform list to a tabular in string format"""
|
||||
tabular = self.rich_table(show_lines=True)
|
||||
if with_header:
|
||||
for column in self.tabular_datas.headers():
|
||||
tabular.add_column(column, width=self.max_line)
|
||||
for data in self.tabular_datas.get():
|
||||
tabular.add_row(*data)
|
||||
return tabular
|
||||
|
||||
def family_informations(self) -> str:
|
||||
info = "[blue]" + self.bold(f"🛈 {_('Informations')}") + "[/blue]"
|
||||
starts_line = self.family_informations_starts_line()
|
||||
return starts_line + info + "\n" + starts_line
|
||||
|
||||
def family_informations_starts_line(self) -> str:
|
||||
return "[blue]▌ [/blue]"
|
||||
|
||||
def family_informations_ends_line(self) -> str:
|
||||
return "\n"
|
||||
|
||||
def end_family_informations(self) -> str:
|
||||
return "\n"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
@ -16,112 +16,199 @@ You should have received a copy of the GNU Lesser General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from io import BytesIO
|
||||
from typing import List
|
||||
from itertools import chain
|
||||
from ruamel.yaml import YAML
|
||||
from typing import List, Optional
|
||||
from html import escape
|
||||
|
||||
from ..utils import dump, CommonFormatter
|
||||
from ..i18n import _
|
||||
|
||||
|
||||
class Formater:
|
||||
def to_id(path):
|
||||
# https://www.w3.org/TR/html4/types.html#type-name
|
||||
return ''.join(e if e in ["-", "_", ":", "."] or e.isalnum() else ":" for e in path )
|
||||
|
||||
|
||||
class Formatter(CommonFormatter):
|
||||
"""The markdown (for github) formatter"""
|
||||
|
||||
name = "github"
|
||||
_tabular_name = "github"
|
||||
level = 50
|
||||
enter_tabular = "<br/>"
|
||||
|
||||
def __init__(self):
|
||||
self._yaml = YAML()
|
||||
self._yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
self.header_setted = False
|
||||
|
||||
def header(self):
|
||||
if self.header_setted:
|
||||
return ""
|
||||
self.header_setted = True
|
||||
return "---\ngitea: none\ninclude_toc: true\n---\n"
|
||||
def __init__(self, rougailconfig, **kwarg) -> None:
|
||||
self.max_line_variable = 0
|
||||
self.max_line_description = 0
|
||||
super().__init__(rougailconfig, **kwarg)
|
||||
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
"""Display family name as a title"""
|
||||
char = "#"
|
||||
return f"{char * level} {title}\n\n"
|
||||
|
||||
def yaml(self, dump):
|
||||
return f"```yaml\n---\n{self.dump(dump)}\n```\n"
|
||||
|
||||
def table(self, table):
|
||||
return table
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
) -> str:
|
||||
return f"[`{comment}`]({link})"
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
) -> str:
|
||||
return f"`{prop}`"
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices,
|
||||
):
|
||||
prefix = "<br/>- "
|
||||
char = "<br/>- "
|
||||
return prefix + char.join([self.dump(choice) for choice in choices])
|
||||
|
||||
def is_list(
|
||||
self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
return txt.startswith("* ")
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col1: List[str],
|
||||
col2: List[str],
|
||||
) -> None:
|
||||
self.max_line = 0
|
||||
for params in chain(col1, col2):
|
||||
for param in params.split("\n"):
|
||||
self.max_line = max(self.max_line, len(param))
|
||||
self.max_line += 1
|
||||
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
return "<br/>".join(lst)
|
||||
|
||||
def to_string(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
return text.strip().replace("\n", "<br/>")
|
||||
|
||||
def table_header(self, lst):
|
||||
return lst[0] + " " * (self.max_line - len(lst[0])), lst[1] + " " * (
|
||||
self.max_line - len(lst[1])
|
||||
)
|
||||
"""Display line in tabular from a list"""
|
||||
return self.enter_tabular.join([l.replace("\n", self.enter_tabular) for l in lst])
|
||||
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to bold"""
|
||||
return f"**{msg}**"
|
||||
|
||||
def italic(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to italic"""
|
||||
return f"*{msg}*"
|
||||
|
||||
def dump(self, dico):
|
||||
with BytesIO() as ymlfh:
|
||||
self._yaml.dump(dico, ymlfh)
|
||||
ret = ymlfh.getvalue().decode("utf-8").strip()
|
||||
if ret.endswith("..."):
|
||||
ret = ret[:-3].strip()
|
||||
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"<ins>{msg}</ins>"
|
||||
|
||||
def stripped(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
"""Return stripped text (as help)"""
|
||||
return text.strip().replace("\n", self.enter_tabular)
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
*,
|
||||
inside_tabular: bool=True,
|
||||
type_: str="variable",
|
||||
with_enter: bool = True,
|
||||
):
|
||||
"""Display a liste of element"""
|
||||
if type_ == 'variable':
|
||||
if inside_tabular:
|
||||
if with_enter:
|
||||
char = first_char = f"{self.enter_tabular}• "
|
||||
else:
|
||||
first_char = f"• "
|
||||
char = f"{self.enter_tabular}{first_char}"
|
||||
else:
|
||||
first_char = char = "\n- "
|
||||
else:
|
||||
char = first_char = f"\n{self.family_informations_starts_line()}- "
|
||||
ret = ""
|
||||
for idx, choice in enumerate(choices):
|
||||
if not isinstance(choice, str):
|
||||
choice = dump(choice)
|
||||
if not idx:
|
||||
c = first_char
|
||||
else:
|
||||
c = char
|
||||
ret += c + choice
|
||||
return ret
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
italic: bool,
|
||||
delete: bool,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Display property"""
|
||||
prop = f"`{prop}`"
|
||||
if italic:
|
||||
prop = self.italic(prop)
|
||||
if delete:
|
||||
prop = self.delete(prop)
|
||||
if underline:
|
||||
prop = self.underline(prop)
|
||||
return prop
|
||||
|
||||
def tabular_header(self, lst):
|
||||
"""Manage the header of a tabular"""
|
||||
return lst
|
||||
return [l + " " * (self.max_line_variable - len(l)) for l in lst]
|
||||
|
||||
def yaml(self, _dump):
|
||||
"""Dump yaml part of documentation"""
|
||||
return f"```yaml\n---\n{dump(_dump)}\n```\n"
|
||||
|
||||
def link_variable(self,
|
||||
path: str,
|
||||
true_path: str,
|
||||
description: str,
|
||||
filename: Optional[str],
|
||||
) -> str:
|
||||
name = to_id(true_path)
|
||||
if filename:
|
||||
link = f'{filename}#{name}'
|
||||
else:
|
||||
link = f'#{name}'
|
||||
return f"[{description}]({link})"
|
||||
|
||||
def anchor(self,
|
||||
path: str,
|
||||
true_path: str,
|
||||
) -> str:
|
||||
name = to_id(true_path)
|
||||
return f'<a id="{name}" name="{name}">{path}</a>'
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Add a link"""
|
||||
comment = self.prop(comment, False, False, underline)
|
||||
return f"[{comment}]({link})"
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col: List[str],
|
||||
) -> None:
|
||||
"""count columns length"""
|
||||
for line in col:
|
||||
for l in line.split(self.enter_tabular):
|
||||
self.max_line_variable = max(self.max_line_variable, len(l) + 1)
|
||||
self.max_line_description = self.max_line_variable
|
||||
|
||||
def to_phrase(self, text: str) -> str:
|
||||
return escape(text)
|
||||
|
||||
def family_informations(self) -> str:
|
||||
info = self.bold(f"🛈 {_('Informations')}") # ℹ️
|
||||
starts_line = self.family_informations_starts_line()
|
||||
return starts_line + info + "\n" + starts_line + "\n"
|
||||
|
||||
def family_informations_starts_line(self) -> str:
|
||||
return "> "
|
||||
|
||||
def family_informations_ends_line(self) -> str:
|
||||
return "\\\n"
|
||||
#
|
||||
# def family_to_string(self, *args, **kwargs) -> List[str]:
|
||||
# lst = super().family_to_string(*args, **kwargs)
|
||||
# if self.name != 'github':
|
||||
# return lst
|
||||
# # remove the title
|
||||
# ret = lst.pop(0)
|
||||
# if lst:
|
||||
# ret = "\n> ".join([l.strip() for l in lst]).strip() + "\n\n"
|
||||
# return [ret]
|
||||
|
|
|
|||
48
src/rougail/output_doc/output/gitlab.py
Normal file
48
src/rougail/output_doc/output/gitlab.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
"""
|
||||
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 typing import List
|
||||
|
||||
|
||||
from .github import Formatter as GithubFormatter
|
||||
from ..i18n import _
|
||||
|
||||
|
||||
class Formatter(GithubFormatter):
|
||||
name = "gitlab"
|
||||
level = 51
|
||||
|
||||
def title(self, title: str, level: int) -> str:
|
||||
# self.max_line_variable = 0
|
||||
return "<details><summary>" + title + "</summary>\n\n"
|
||||
|
||||
def end_family(self, level):
|
||||
return "</details>\n\n"
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col: List[str],
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
def family_informations(self) -> str:
|
||||
return f"> [!note] 🛈 {_('Informations')}\n"
|
||||
|
||||
def table_header(self, lst):
|
||||
"""Manage the header of a table"""
|
||||
return lst
|
||||
146
src/rougail/output_doc/output/html.py
Normal file
146
src/rougail/output_doc/output/html.py
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
"""
|
||||
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 typing import List
|
||||
from html import escape
|
||||
from ..utils import CommonFormatter, dump
|
||||
|
||||
|
||||
class Formatter(CommonFormatter):
|
||||
"""The asciidoc formatter"""
|
||||
|
||||
name = "html"
|
||||
_tabular_name = "unsafehtml"
|
||||
level = 45
|
||||
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
"""Display family name as a title"""
|
||||
return f"<h{level}>{title}</h{level}>\n\n"
|
||||
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
"""Display line in tabular from a list"""
|
||||
string = ""
|
||||
previous = ""
|
||||
for line in lst:
|
||||
if string:
|
||||
# if self.is_list(previous.split("\n", 1)[-1]):
|
||||
# string += "<br/><br/>"
|
||||
# else:
|
||||
string += "<br/>"
|
||||
string += line
|
||||
|
||||
previous = line
|
||||
return string
|
||||
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to bold"""
|
||||
return f"<b>{msg}</b>"
|
||||
|
||||
def italic(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to italic"""
|
||||
return f"<i>{msg}</i>"
|
||||
|
||||
def delete(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to deleted"""
|
||||
return f"<del>{msg}</del>"
|
||||
|
||||
def underline(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to underline"""
|
||||
return f"<ins>{msg}</ins>"
|
||||
|
||||
def stripped(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
"""Return stripped text (as help)"""
|
||||
return text.strip()
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
*,
|
||||
inside_tabular: bool=True,
|
||||
type_: str="variable",
|
||||
with_enter: bool = True,
|
||||
) -> str:
|
||||
"""Display a liste of element"""
|
||||
prefix = "<ul>"
|
||||
char = "\n"
|
||||
return (
|
||||
"<ul>"
|
||||
+ char.join(["<li>" + dump(choice) + "</li>" for choice in choices])
|
||||
+ "</ul>"
|
||||
)
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
italic: bool,
|
||||
delete: bool,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Display property"""
|
||||
if italic:
|
||||
prop = self.italic(prop)
|
||||
if delete:
|
||||
prop = self.delete(prop)
|
||||
if underline:
|
||||
prop = self.underline(prop)
|
||||
return f"<mark>{prop}</mark>"
|
||||
|
||||
def yaml(self, _dump: dict) -> str:
|
||||
"""Dump yaml part of documentation"""
|
||||
return f"<pre>{dump(_dump)}</pre>"
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Add a link"""
|
||||
return self.prop(f"<a href='{link}'>{comment}</a>", False, False, underline)
|
||||
|
||||
def is_list(
|
||||
self,
|
||||
txt: str,
|
||||
) -> str:
|
||||
"""verify if a text is a list"""
|
||||
return txt.strip().startswith("<ul>")
|
||||
|
||||
def to_phrase(self, text: str) -> str:
|
||||
return escape(text)
|
||||
40
src/rougail/output_doc/output/ojson.py
Normal file
40
src/rougail/output_doc/output/ojson.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from json import dumps
|
||||
from typing import Any
|
||||
|
||||
|
||||
class Formatter:
|
||||
"""Just return internal structure to json"""
|
||||
|
||||
name = "json"
|
||||
level = 90
|
||||
|
||||
def __init__(self, rougailconfig, **kwargs):
|
||||
self.rougailconfig = rougailconfig
|
||||
|
||||
def run(self, informations: dict, *args) -> str: # pylint: disable=unused-argument
|
||||
"""Transform to string"""
|
||||
root = self.rougailconfig["doc.root"]
|
||||
if root:
|
||||
current = informations
|
||||
for path in root.split('.'):
|
||||
current = current[path]["children"]
|
||||
informations = current
|
||||
return dumps(informations, ensure_ascii=False, indent=2)
|
||||
17
src/rougail/output_doc/tabular/__init__.py
Normal file
17
src/rougail/output_doc/tabular/__init__.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
"""Loads output
|
||||
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/>.
|
||||
"""
|
||||
78
src/rougail/output_doc/tabular/five_columns.py
Normal file
78
src/rougail/output_doc/tabular/five_columns.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
"""
|
||||
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 ..i18n import _
|
||||
from ..config import ROUGAIL_VARIABLE_TYPE
|
||||
from .four_columns import Tabular as FourTabular
|
||||
|
||||
|
||||
class Tabular(FourTabular):
|
||||
"""The five columns tabular"""
|
||||
|
||||
name = "five_columns"
|
||||
level = 60
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
self.five_column = False
|
||||
|
||||
def _add(self) -> tuple:
|
||||
first_column = self.add_first_column()
|
||||
second_column = self.get_column(self.description, self.help_, self.validators, self.choices, self.examples, self.tags)
|
||||
if second_column:
|
||||
self.second_column = True
|
||||
third_column = self.get_column(self.default)
|
||||
if third_column:
|
||||
self.third_column = True
|
||||
types = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["type"],
|
||||
)
|
||||
four_column = self.get_column(types)
|
||||
if four_column:
|
||||
self.four_column = True
|
||||
mode = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["mode", "access_control"],
|
||||
)
|
||||
five_column = self.get_column(mode, *self.calculated_properties)
|
||||
if five_column:
|
||||
self.five_column = True
|
||||
return first_column, second_column, third_column, four_column, five_column
|
||||
|
||||
def headers(self) -> tuple:
|
||||
header = super().headers()
|
||||
if self.five_column:
|
||||
header.append(_("Access control"))
|
||||
return header
|
||||
|
||||
def get_columns(self):
|
||||
for column in self.columns:
|
||||
ret = [column[0]]
|
||||
if self.second_column:
|
||||
ret.append(column[1])
|
||||
if self.third_column:
|
||||
ret.append(column[2])
|
||||
if self.four_column:
|
||||
ret.append(column[3])
|
||||
if self.five_column:
|
||||
ret.append(column[4])
|
||||
yield ret
|
||||
|
||||
def set_properties(self):
|
||||
self.properties = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["properties", "validator"],
|
||||
)
|
||||
70
src/rougail/output_doc/tabular/four_columns.py
Normal file
70
src/rougail/output_doc/tabular/four_columns.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"""
|
||||
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 ..i18n import _
|
||||
from ..config import ROUGAIL_VARIABLE_TYPE
|
||||
from .three_columns import Tabular as ThreeTabular
|
||||
|
||||
|
||||
class Tabular(ThreeTabular):
|
||||
"""The four columns tabular"""
|
||||
|
||||
name = "four_columns"
|
||||
level = 50
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
self.four_column = False
|
||||
|
||||
def _add(self) -> tuple:
|
||||
first_column = self.add_first_column()
|
||||
second_column = self.get_column(self.description, self.help_, self.validators, self.choices, self.examples, self.tags, *self.calculated_properties)
|
||||
if second_column:
|
||||
self.second_column = True
|
||||
third_column = self.get_column(self.default)
|
||||
if third_column:
|
||||
self.third_column = True
|
||||
types = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents="type",
|
||||
)
|
||||
four_column = self.get_column(types)
|
||||
if four_column:
|
||||
self.four_column = True
|
||||
return first_column, second_column, third_column, four_column
|
||||
|
||||
def headers(self) -> tuple:
|
||||
header = super().headers()
|
||||
if self.four_column:
|
||||
header.append(_("Type"))
|
||||
return header
|
||||
|
||||
def get_columns(self):
|
||||
for column in self.columns:
|
||||
ret = [column[0]]
|
||||
if self.second_column:
|
||||
ret.append(column[1])
|
||||
if self.third_column:
|
||||
ret.append(column[2])
|
||||
if self.four_column:
|
||||
ret.append(column[3])
|
||||
yield ret
|
||||
|
||||
def set_properties(self):
|
||||
self.properties = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["properties", "mode", "access_control", "validator"],
|
||||
)
|
||||
91
src/rougail/output_doc/tabular/six_columns.py
Normal file
91
src/rougail/output_doc/tabular/six_columns.py
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
"""
|
||||
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 ..i18n import _
|
||||
from ..config import ROUGAIL_VARIABLE_TYPE
|
||||
from .five_columns import Tabular as FiveTabular
|
||||
|
||||
|
||||
class Tabular(FiveTabular):
|
||||
"""The six columns tabular"""
|
||||
|
||||
name = "six_columns"
|
||||
level = 70
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
self.six_column = False
|
||||
|
||||
def _add(self) -> tuple:
|
||||
first_column = self.add_first_column()
|
||||
second_column = self.get_column(self.description, self.help_, self.examples, self.tags)
|
||||
if second_column:
|
||||
self.second_column = True
|
||||
third_column = self.get_column(self.default)
|
||||
if third_column:
|
||||
self.third_column = True
|
||||
types = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["type"],
|
||||
)
|
||||
four_column = self.get_column(types)
|
||||
if four_column:
|
||||
self.four_column = True
|
||||
mode = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["mode", "access_control"],
|
||||
)
|
||||
five_column = self.get_column(mode, *self.calculated_properties)
|
||||
if five_column:
|
||||
self.five_column = True
|
||||
validators = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["validator"],
|
||||
)
|
||||
six_column = self.get_column(validators, self.validators, self.choices)
|
||||
if six_column:
|
||||
self.six_column = True
|
||||
return first_column, second_column, third_column, four_column, five_column, six_column
|
||||
|
||||
def headers(self) -> tuple:
|
||||
header = super().headers()
|
||||
if self.six_column:
|
||||
header.append(_("Validator"))
|
||||
return header
|
||||
|
||||
def get_columns(self):
|
||||
for column in self.columns:
|
||||
ret = [column[0]]
|
||||
if self.second_column:
|
||||
ret.append(column[1])
|
||||
if self.third_column:
|
||||
ret.append(column[2])
|
||||
if self.four_column:
|
||||
ret.append(column[3])
|
||||
if self.five_column:
|
||||
ret.append(column[4])
|
||||
if self.six_column:
|
||||
ret.append(column[5])
|
||||
yield ret
|
||||
|
||||
def set_properties(self):
|
||||
self.properties = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes, contents=["properties"],
|
||||
)
|
||||
|
||||
def set_validators(self):
|
||||
self.validators = self.formatter.convert_section_to_string(
|
||||
"validators", self.informations, self.modified_attributes, multi=True, section_name=False, with_to_phrase=True,
|
||||
)
|
||||
69
src/rougail/output_doc/tabular/three_columns.py
Normal file
69
src/rougail/output_doc/tabular/three_columns.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"""
|
||||
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 ..i18n import _
|
||||
from .two_columns import Tabular as TwoTabular
|
||||
|
||||
|
||||
class Tabular(TwoTabular):
|
||||
"""The three columns tabular"""
|
||||
|
||||
name = "three_columns"
|
||||
level = 30
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
self.third_column = False
|
||||
|
||||
def _add(self) -> tuple:
|
||||
first_column = self.add_first_column()
|
||||
second_column = self.get_column(self.description, self.help_, self.validators, self.choices, self.examples, self.tags, *self.calculated_properties)
|
||||
if second_column:
|
||||
self.second_column = True
|
||||
third_column = self.get_column(self.default)
|
||||
if third_column:
|
||||
self.third_column = True
|
||||
return first_column, second_column, third_column
|
||||
|
||||
def headers(self) -> tuple:
|
||||
headers = super().headers()
|
||||
if self.third_column:
|
||||
headers.append(_("Default value"))
|
||||
return headers
|
||||
|
||||
def get_columns(self):
|
||||
for column in self.columns:
|
||||
ret = [column[0]]
|
||||
if self.second_column:
|
||||
ret.append(column[1])
|
||||
if self.third_column:
|
||||
ret.append(column[2])
|
||||
yield ret
|
||||
|
||||
def set_default(self):
|
||||
if "default" in self.informations:
|
||||
self.default = self.formatter.convert_section_to_string(
|
||||
"default", self.informations, self.modified_attributes, multi=self.multi, section_name=False
|
||||
)
|
||||
else:
|
||||
self.default = None
|
||||
|
||||
def set_choices(self):
|
||||
self.default_is_already_set, self.choices = self.formatter.convert_choices_to_string(
|
||||
self.informations, self.modified_attributes, with_default=False
|
||||
)
|
||||
55
src/rougail/output_doc/tabular/two_columns.py
Normal file
55
src/rougail/output_doc/tabular/two_columns.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
"""
|
||||
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 ..i18n import _
|
||||
from ..utils import CommonTabular
|
||||
|
||||
|
||||
class Tabular(CommonTabular):
|
||||
"""The two columns tabular"""
|
||||
|
||||
name = "two_columns"
|
||||
level = 10
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
self.second_column = False
|
||||
|
||||
def _add(self) -> tuple:
|
||||
first_column = self.add_first_column()
|
||||
default = self.default if not self.default_is_already_set else None
|
||||
second_column = self.get_column(self.description, self.help_, self.validators, self.choices, default, self.examples, self.tags, *self.calculated_properties)
|
||||
if second_column:
|
||||
self.second_column = True
|
||||
return first_column, second_column
|
||||
|
||||
def add_first_column(self) -> str:
|
||||
return self.get_column(self.paths, self.properties, self.commandlines, self.environments)
|
||||
|
||||
def headers(self) -> tuple:
|
||||
headers = [_("Variable")]
|
||||
if self.second_column:
|
||||
headers.append(_("Description"))
|
||||
return headers
|
||||
|
||||
def get_columns(self):
|
||||
for column in self.columns:
|
||||
ret = [column[0]]
|
||||
if self.second_column:
|
||||
ret.append(column[1])
|
||||
yield ret
|
||||
984
src/rougail/output_doc/utils.py
Normal file
984
src/rougail/output_doc/utils.py
Normal file
|
|
@ -0,0 +1,984 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from typing import Tuple, List, Optional
|
||||
|
||||
from io import BytesIO
|
||||
from ruamel.yaml import YAML
|
||||
import tabulate as tabulate_module
|
||||
from tabulate import tabulate
|
||||
|
||||
from rougail.tiramisu import normalize_family
|
||||
from tiramisu import undefined
|
||||
from tiramisu.error import PropertiesOptionError, display_list
|
||||
try:
|
||||
from tiramisu_cmdline_parser.api import gen_argument_name
|
||||
except:
|
||||
gen_argument_name = None
|
||||
|
||||
from .i18n import _
|
||||
from .config import Tabulars, ROUGAIL_VARIABLE_TYPE
|
||||
|
||||
|
||||
ENTER = "\n\n"
|
||||
|
||||
|
||||
_yaml = YAML()
|
||||
_yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
|
||||
|
||||
def dump(informations):
|
||||
"""Dump variable, means transform bool, ... to yaml string"""
|
||||
with BytesIO() as ymlfh:
|
||||
_yaml.dump(informations, ymlfh)
|
||||
ret = ymlfh.getvalue().decode("utf-8").strip()
|
||||
if ret.endswith("..."):
|
||||
ret = ret[:-3].strip()
|
||||
return ret
|
||||
|
||||
|
||||
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 type_ == "variable":
|
||||
if not msg.endswith("."):
|
||||
msg += "."
|
||||
elif type_ in ["family", "description"]:
|
||||
if msg.endswith("."):
|
||||
msg = msg[:-1]
|
||||
else:
|
||||
raise Exception("unknown type")
|
||||
# and start with a maj
|
||||
return msg[0].upper() + msg[1:]
|
||||
|
||||
|
||||
class CommonTabular:
|
||||
"""Class with common function for tabular"""
|
||||
|
||||
def __init__(self, formatter: "CommonFormatter") -> None:
|
||||
self.formatter = formatter
|
||||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
self.columns = []
|
||||
|
||||
def get(self):
|
||||
columns = list(self.get_columns())
|
||||
self.clear()
|
||||
return columns
|
||||
|
||||
def add(self, informations: dict, modified_attributes: dict, force_identifiers: Optional[str]) -> tuple:
|
||||
self.informations = informations
|
||||
self.modified_attributes = modified_attributes
|
||||
self.force_identifiers = force_identifiers
|
||||
self.calculated_properties = []
|
||||
self.set_description()
|
||||
self.set_type()
|
||||
self.set_choices()
|
||||
self.set_properties()
|
||||
self.set_default()
|
||||
self.set_examples()
|
||||
self.set_paths()
|
||||
self.set_commandline()
|
||||
self.set_environment()
|
||||
self.set_validators()
|
||||
self.set_tags()
|
||||
self.columns.append(self._add())
|
||||
|
||||
def set_description(self):
|
||||
if "description" in self.informations:
|
||||
self.description = self.formatter.get_description(
|
||||
"variable", self.informations, self.modified_attributes, self.force_identifiers,
|
||||
)
|
||||
else:
|
||||
self.description = None
|
||||
self.help_ = self.formatter.convert_list_to_string("help", self.informations, self.modified_attributes)
|
||||
|
||||
def set_choices(self):
|
||||
self.default_is_already_set, self.choices = self.formatter.convert_choices_to_string(
|
||||
self.informations, self.modified_attributes
|
||||
)
|
||||
|
||||
def set_type(self):
|
||||
self.multi = self.informations.get("multiple", True)
|
||||
self.type = self.informations["variable_type"]
|
||||
|
||||
def set_default(self):
|
||||
if "default" in self.informations:
|
||||
self.default = self.formatter.convert_section_to_string(
|
||||
"default", self.informations, self.modified_attributes, multi=self.multi
|
||||
)
|
||||
else:
|
||||
self.default = None
|
||||
|
||||
def set_examples(self):
|
||||
self.examples = self.formatter.convert_section_to_string(
|
||||
"examples", self.informations, self.modified_attributes, multi=True
|
||||
)
|
||||
|
||||
def set_paths(self):
|
||||
self.paths = self.formatter.join(self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True))
|
||||
|
||||
def set_commandline(self):
|
||||
if self.formatter.with_commandline and not self.informations.get('not_for_commandline', False):
|
||||
commandlines = self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True, is_bold=False, variable_prefix="--", with_anchor=False)
|
||||
if self.type == 'boolean':
|
||||
for path in self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True, is_bold=False, is_upper=False, with_anchor=False, variable_prefix="--"):
|
||||
commandlines.append("--" + gen_argument_name(path[2:], False, True, False))
|
||||
if "alternative_name" in self.informations:
|
||||
alternative_name = self.informations["alternative_name"]
|
||||
commandlines[0] = f"-{alternative_name}, {commandlines[0]}"
|
||||
if self.type == 'boolean':
|
||||
commandlines[1] = "-" + gen_argument_name(alternative_name, True, True, False) + f", {commandlines[1]}"
|
||||
self.commandlines = self.formatter.section(_("Command line"), commandlines)
|
||||
else:
|
||||
self.commandlines = None
|
||||
|
||||
def set_environment(self):
|
||||
if self.formatter.with_environment:
|
||||
environments = self.formatter.display_paths(self.informations, self.modified_attributes, self.force_identifiers, is_variable=True, is_bold=False, is_upper=True, variable_prefix=self.formatter.prefix, with_anchor=False)
|
||||
self.environments = self.formatter.section(_("Environment variable"), environments)
|
||||
else:
|
||||
self.environments = None
|
||||
|
||||
def set_properties(self):
|
||||
self.properties = self.formatter.property_to_string(
|
||||
self.informations, self.calculated_properties, self.modified_attributes,
|
||||
)
|
||||
|
||||
def set_validators(self):
|
||||
self.validators = self.formatter.convert_section_to_string(
|
||||
"validators", self.informations, self.modified_attributes, multi=True
|
||||
)
|
||||
|
||||
def set_tags(self):
|
||||
self.tags = self.formatter.convert_section_to_string(
|
||||
"tags", self.informations, self.modified_attributes, multi=True
|
||||
)
|
||||
|
||||
def get_column(self, *args):
|
||||
contents = [arg for arg in args if arg]
|
||||
self.formatter.columns(contents)
|
||||
return self.formatter.join(contents)
|
||||
|
||||
|
||||
class CommonFormatter:
|
||||
"""Class with common function for formatter"""
|
||||
|
||||
enter_tabular = "\n"
|
||||
# tabulate module name
|
||||
name = None
|
||||
|
||||
def __init__(self, rougailconfig, support_namespace, **kwargs):
|
||||
tabulate_module.PRESERVE_WHITESPACE = True
|
||||
self.header_setted = False
|
||||
self.rougailconfig = rougailconfig
|
||||
self.support_namespace = support_namespace
|
||||
|
||||
def run(
|
||||
self, informations: dict, *, dico_is_already_treated=False
|
||||
) -> str:
|
||||
"""Transform to string"""
|
||||
if informations:
|
||||
level = self.rougailconfig["doc.title_level"]
|
||||
self.options()
|
||||
if self.root:
|
||||
current = informations
|
||||
for path in self.root.split('.'):
|
||||
info = current[path]['informations']
|
||||
current = current[path]["children"]
|
||||
informations = {"informations": info, "children": current}
|
||||
return self._run(informations, level, dico_is_already_treated)
|
||||
return ""
|
||||
|
||||
def options(self):
|
||||
self.with_commandline = self.rougailconfig["doc.tabulars.with_commandline"]
|
||||
self.with_environment = self.rougailconfig["doc.tabulars.with_environment"]
|
||||
if self.with_environment and not gen_argument_name:
|
||||
raise Exception('please install tiramisu_cmdline_parser')
|
||||
if not self.rougailconfig["main_namespace"] and self.with_environment:
|
||||
if self.support_namespace:
|
||||
self.prefix = ""
|
||||
else:
|
||||
self.prefix = self.rougailconfig["doc.tabulars.environment_prefix"] + "_"
|
||||
self.with_family = not self.rougailconfig["doc.tabulars.without_family"]
|
||||
self.root = self.rougailconfig["doc.root"]
|
||||
self.other_root_filenames = None
|
||||
if self.root:
|
||||
try:
|
||||
other_root_filenames = self.rougailconfig["doc.other_root_filenames"]
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
else:
|
||||
if other_root_filenames:
|
||||
self.other_root_filenames = dict(zip(other_root_filenames["root_path"], other_root_filenames["filename"]))
|
||||
tabular_template = self.rougailconfig["doc.tabular_template"]
|
||||
self.tabular_datas = Tabulars().get()[tabular_template](self)
|
||||
|
||||
def compute(self, data):
|
||||
return "".join([d for d in data if d])
|
||||
|
||||
# Class you needs implement to your Formatter
|
||||
def title(
|
||||
self,
|
||||
title: str,
|
||||
level: int,
|
||||
) -> str:
|
||||
"""Display family name as a title"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def join(
|
||||
self,
|
||||
lst: List[str],
|
||||
) -> str:
|
||||
"""Display line in tabular from a list"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def bold(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to bold"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def underline(
|
||||
self,
|
||||
msg: str,
|
||||
) -> str:
|
||||
"""Set a text to underline"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def anchor(self,
|
||||
path: str,
|
||||
true_path: str,
|
||||
) -> str:
|
||||
"""Set a text to a link anchor"""
|
||||
return path
|
||||
|
||||
def link_variable(self,
|
||||
path: str,
|
||||
true_path: str,
|
||||
description: str,
|
||||
filename: Optional[str],
|
||||
) -> str:
|
||||
"""Set a text link to variable anchor"""
|
||||
return path
|
||||
|
||||
def stripped(
|
||||
self,
|
||||
text: str,
|
||||
) -> str:
|
||||
"""Return stripped text (as help)"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def list(
|
||||
self,
|
||||
choices: list,
|
||||
*,
|
||||
inside_tabular: bool=True,
|
||||
type_: str="variable",
|
||||
with_enter: bool = False,
|
||||
) -> str:
|
||||
"""Display a liste of element"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def prop(
|
||||
self,
|
||||
prop: str,
|
||||
italic: bool,
|
||||
delete: bool,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Display property"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def link(
|
||||
self,
|
||||
comment: str,
|
||||
link: str,
|
||||
underline: bool,
|
||||
) -> str:
|
||||
"""Add a link"""
|
||||
raise NotImplementedError()
|
||||
|
||||
##################
|
||||
|
||||
def family_informations(self) -> str:
|
||||
return ""
|
||||
|
||||
def end_family_informations(self) -> str:
|
||||
return ENTER
|
||||
|
||||
def display_paths(
|
||||
self,
|
||||
informations: dict,
|
||||
modified_attributes: dict,
|
||||
force_identifiers: Optional[str],
|
||||
*,
|
||||
is_variable=False,
|
||||
variable_prefix: str="",
|
||||
is_bold: bool=True,
|
||||
is_upper: bool=False,
|
||||
with_anchor: bool=True,
|
||||
) -> str:
|
||||
if with_anchor:
|
||||
anchor = self.anchor
|
||||
else:
|
||||
def anchor(path, true_path):
|
||||
return path
|
||||
ret_paths = []
|
||||
path = informations["path"]
|
||||
if is_bold:
|
||||
bold = self.bold
|
||||
else:
|
||||
def bold(value):
|
||||
return value
|
||||
if is_upper:
|
||||
def upper(value):
|
||||
return value.upper()
|
||||
else:
|
||||
def upper(value):
|
||||
return value
|
||||
if "identifiers" in modified_attributes:
|
||||
name, previous, new = modified_attributes["identifiers"]
|
||||
ret_paths.extend(
|
||||
[
|
||||
bold(self.delete(upper(variable_prefix + calc_path(path, self, identifier))))
|
||||
for identifier in previous
|
||||
]
|
||||
)
|
||||
else:
|
||||
new = []
|
||||
if "identifiers" in informations:
|
||||
for idx, identifier in enumerate(informations["identifiers"]):
|
||||
if force_identifiers and identifier != force_identifiers:
|
||||
continue
|
||||
path_ = calc_path(path, self, identifier)
|
||||
if variable_prefix:
|
||||
path_ = variable_prefix + upper(path_)
|
||||
if not idx:
|
||||
path_ = anchor(path_, path)
|
||||
if identifier in new:
|
||||
path_ = self.underline(path_)
|
||||
ret_paths.append(bold(path_))
|
||||
else:
|
||||
ret_paths.append(bold(anchor(variable_prefix + upper(path), path)))
|
||||
return ret_paths
|
||||
|
||||
def tabular_header(
|
||||
self,
|
||||
lst: list,
|
||||
) -> tuple:
|
||||
"""Manage the header of a tabular"""
|
||||
return lst
|
||||
|
||||
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,
|
||||
*,
|
||||
init: bool = False,
|
||||
) -> str:
|
||||
"""Parse the dict to transform to dict"""
|
||||
msg = []
|
||||
if init and self.root:
|
||||
if self.with_family:
|
||||
msg.extend(self.family_to_string(dico["informations"], level, False))
|
||||
level += 1
|
||||
dico = dico["children"]
|
||||
for value in dico.values():
|
||||
if value["type"] == "variable":
|
||||
self.variable_to_string(value)
|
||||
elif self.with_family:
|
||||
if init and value["type"] == "namespace":
|
||||
namespace = True
|
||||
else:
|
||||
namespace = False
|
||||
if self.tabular_datas.columns:
|
||||
msg.append(self.tabular())
|
||||
msg.extend(self.family_to_string(value["informations"], level, namespace))
|
||||
msg.extend(self.dict_to_dict(value["children"], level + 1))
|
||||
msg.append(self.end_family(level))
|
||||
else:
|
||||
self.dict_to_dict(
|
||||
value["children"], level + 1,
|
||||
)
|
||||
if self.tabular_datas.columns and (init or self.with_family):
|
||||
msg.append(self.tabular())
|
||||
return msg
|
||||
|
||||
# FAMILY
|
||||
def namespace_to_title(self, informations: dict, level: int) -> str:
|
||||
"""manage namespace family"""
|
||||
return self.title(
|
||||
self.get_description("family", informations, {}, None),
|
||||
level,
|
||||
)
|
||||
|
||||
def family_to_string(self, informations: dict, level: int, namespace: bool) -> str:
|
||||
"""manage other family type"""
|
||||
if namespace:
|
||||
ret = [self.namespace_to_title(informations, level)]
|
||||
else:
|
||||
ret = [self.title(self.get_description("family", informations, {}, None), level)]
|
||||
# ret.append(self.anchor("", informations["path"]) + ENTER)
|
||||
fam_info = self.family_informations()
|
||||
if fam_info:
|
||||
ret.append(fam_info)
|
||||
msg = []
|
||||
helps = informations.get("help")
|
||||
if helps:
|
||||
for help_ in helps:
|
||||
msg.append(to_phrase(help_.strip()))
|
||||
msg.append(self.section(_("Path"), self.display_paths(informations, {}, None, with_anchor=False, is_bold=False), type_="family"))
|
||||
calculated_properties = []
|
||||
property_str = self.property_to_string(informations, calculated_properties, {})
|
||||
if property_str:
|
||||
msg.append(property_str)
|
||||
if calculated_properties:
|
||||
msg.append(self.join(calculated_properties)
|
||||
)
|
||||
if "identifier" in informations:
|
||||
msg.append(
|
||||
self.section(_("Identifiers"), informations["identifier"], type_="family")
|
||||
)
|
||||
starts_line = self.family_informations_starts_line()
|
||||
ret.append(self.family_informations_ends_line().join([starts_line + m for m in msg]) + self.end_family_informations())
|
||||
return ret
|
||||
|
||||
def family_informations_starts_line(self) -> str:
|
||||
return ""
|
||||
|
||||
def family_informations_ends_line(self) -> str:
|
||||
return ENTER
|
||||
|
||||
def end_family(self, level: int) -> str:
|
||||
return ""
|
||||
|
||||
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"])
|
||||
)
|
||||
data = self.to_phrase(data)
|
||||
if data in new:
|
||||
data = self.underline(data)
|
||||
datas.append(data)
|
||||
return self.stripped(self.join(datas))
|
||||
|
||||
def get_description(
|
||||
self, type_: str, informations: dict, modified_attributes: dict, force_identifiers: Optional[str]
|
||||
) -> str():
|
||||
def _get_description(description, identifiers, delete=False, new=[]):
|
||||
if identifiers and "{{ identifier }}" in description:
|
||||
if type_ == "variable":
|
||||
identifiers_text = display_list(
|
||||
[self.italic(i[-1]) for i in identifiers if not force_identifiers or i == force_identifiers], separator="or"
|
||||
)
|
||||
description = description.replace(
|
||||
"{{ identifier }}", identifiers_text
|
||||
)
|
||||
else:
|
||||
d = []
|
||||
for i in identifiers:
|
||||
if force_identifiers and i != force_identifiers:
|
||||
continue
|
||||
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"]
|
||||
if previous:
|
||||
modified_description = _get_description(
|
||||
previous[0], modified_attributes.get("identifiers", []), delete=True
|
||||
)
|
||||
else:
|
||||
modified_description = None
|
||||
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, modified_attributes: dict = {}, force_identifiers: Optional[str]=None
|
||||
) -> None:
|
||||
"""Manage variable"""
|
||||
self.tabular_datas.add(informations, modified_attributes, force_identifiers)
|
||||
|
||||
def convert_section_to_string(
|
||||
self, attribute: str, informations: dict, modified_attributes: dict, multi: bool, *, section_name: bool = True, with_to_phrase = False
|
||||
) -> str():
|
||||
values = []
|
||||
submessage = ""
|
||||
if modified_attributes and attribute in modified_attributes:
|
||||
name, previous, new = modified_attributes[attribute]
|
||||
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, with_enter=section_name)
|
||||
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, section_name=section_name, with_to_phrase=with_to_phrase)
|
||||
|
||||
def convert_choices_to_string(
|
||||
self, informations: dict, modified_attributes: dict, with_default: bool = True,
|
||||
) -> 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
|
||||
for idx, choice in enumerate(choices_values.copy()):
|
||||
if isinstance(choice, dict):
|
||||
choices_values[idx] = self.message_to_string(choice, None)[1]
|
||||
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 = [None]
|
||||
if not isinstance(default, list):
|
||||
default = [default]
|
||||
for idx, value in enumerate(default.copy()):
|
||||
if isinstance(value, dict):
|
||||
default[idx] = self.message_to_string(value, None)[1]
|
||||
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 isinstance(choice, dict):
|
||||
choice = self.message_to_string(choice, None)[1]
|
||||
if with_default and 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 with_default and val in old_default:
|
||||
choices_values[idx] = (
|
||||
dump(val) + " " + self.delete("← " + _("(default)"))
|
||||
)
|
||||
elif with_default and 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 property_to_string(
|
||||
self,
|
||||
informations: dict,
|
||||
calculated_properties: list,
|
||||
modified_attributes: dict,
|
||||
contents: list = ["type", "properties", "mode", "access_control", "validator"]
|
||||
) -> str:
|
||||
"""Transform properties to string"""
|
||||
properties = []
|
||||
modified_properties = []
|
||||
if "type" in contents:
|
||||
if "type" in modified_attributes:
|
||||
properties.append(self.prop(modified_attributes["type"], italic=False, delete=True, underline=False))
|
||||
if "multi" in modified_attributes:
|
||||
properties.append(self.prop("multiple", italic=False, delete=True, underline=False))
|
||||
if "properties" not in contents and "properties" in modified_attributes:
|
||||
for prop in modified_attributes["properties"]:
|
||||
if prop["ori_name"] == "mandatory":
|
||||
properties.append(self.prop(prop["ori_name"], italic=False, delete=True, underline=False))
|
||||
break
|
||||
if "mode" in contents and "mode" in modified_attributes:
|
||||
properties.append(self.prop(modified_attributes["mode"], italic=False, delete=True, underline=False))
|
||||
if "properties" in modified_attributes:
|
||||
if "properties" in contents:
|
||||
for props in modified_attributes["properties"]:
|
||||
if not props:
|
||||
continue
|
||||
for prop in props:
|
||||
if prop.get("access_control"):
|
||||
if "access_control" in contents:
|
||||
modified_properties.append(prop)
|
||||
elif prop["ori_name"] != "unique" or "unique" in contents:
|
||||
modified_properties.append(prop)
|
||||
elif "access_control" in contents:
|
||||
for prop in modified_attributes["properties"]:
|
||||
if prop.get("access_control"):
|
||||
modified_properties.append(prop)
|
||||
elif "validator" in contents:
|
||||
for prop in modified_attributes["properties"]:
|
||||
if prop["name"] == "unique":
|
||||
modified_properties.append(prop)
|
||||
local_calculated_properties = {}
|
||||
if "properties" in contents and "properties" in modified_attributes:
|
||||
previous, new = self.get_modified_properties(
|
||||
*modified_attributes["properties"][1:]
|
||||
)
|
||||
for p, data in previous.items():
|
||||
if "type" not in contents and data[0] == "mandatory":
|
||||
continue
|
||||
if "validator" not in contents and data[0] == "unique":
|
||||
continue
|
||||
if p not in new:
|
||||
properties.append(self.prop(p, italic=False, delete=True, underline=False))
|
||||
if data[1] is not None:
|
||||
local_calculated_properties[p] = [{"annotation": data[1], "delete": True}]
|
||||
else:
|
||||
previous = new = []
|
||||
others = []
|
||||
if "type" in contents and "variable_type" in informations:
|
||||
others.append({"name": informations["variable_type"], "type": "type"})
|
||||
if informations.get("multiple"):
|
||||
others.append({"name": "multiple", "type": "multiple"})
|
||||
if "properties" not in contents and "properties" in informations:
|
||||
for prop in informations["properties"]:
|
||||
if prop["ori_name"] == "mandatory":
|
||||
others.append(prop)
|
||||
break
|
||||
if "mode" in contents and "mode" in informations:
|
||||
others.append({"name": informations["mode"], "type": "mode"})
|
||||
if "properties" in informations:
|
||||
if "properties" in contents:
|
||||
for prop in informations["properties"]:
|
||||
if prop.get("access_control"):
|
||||
if "access_control" in contents:
|
||||
others.append(prop)
|
||||
elif prop["ori_name"] != "unique" or "validator" in contents:
|
||||
others.append(prop)
|
||||
elif "access_control" in contents:
|
||||
for prop in informations["properties"]:
|
||||
if prop.get("access_control"):
|
||||
others.append(prop)
|
||||
elif "validator" in contents:
|
||||
for prop in informations["properties"]:
|
||||
if prop["name"] == "unique":
|
||||
others.append(prop)
|
||||
for prop in others:
|
||||
prop_name = prop["name"]
|
||||
if "type" not in contents and prop.get("ori_name", prop_name) == "mandatory":
|
||||
continue
|
||||
if prop_name not in previous and prop_name in new:
|
||||
underline = True
|
||||
else:
|
||||
underline = False
|
||||
if prop["type"] == "type":
|
||||
properties.append(self.link(prop_name, ROUGAIL_VARIABLE_TYPE, underline=underline))
|
||||
else:
|
||||
if "annotation" in prop:
|
||||
italic = True
|
||||
prop_annotation = prop["annotation"]
|
||||
if prop_name in new and (
|
||||
prop_name not in previous
|
||||
or new[prop_name] != previous[prop_name]
|
||||
):
|
||||
underline_ = True
|
||||
# prop_annotation = self.underline(prop_annotation)
|
||||
else:
|
||||
underline_ = False
|
||||
local_calculated_properties.setdefault(prop["name"], []).append(
|
||||
{"annotation": prop_annotation, "underline": underline_}
|
||||
)
|
||||
else:
|
||||
italic = False
|
||||
properties.append(self.prop(prop_name, italic=italic, delete=False, underline=underline))
|
||||
if local_calculated_properties:
|
||||
for (
|
||||
calculated_property_name,
|
||||
calculated_property,
|
||||
) in local_calculated_properties.items():
|
||||
# calculated_property = calculated_property_data["annotation"]
|
||||
data = []
|
||||
for calc in calculated_property:
|
||||
annotation = self.message_to_string(calc["annotation"], None)[1]
|
||||
if calc.get("underline", False):
|
||||
annotation = self.underline(annotation)
|
||||
if calc.get("delete", False):
|
||||
annotation = self.delete(annotation)
|
||||
data.append(annotation)
|
||||
if len(calculated_property) > 1:
|
||||
calculated_property = self.join(data)
|
||||
else:
|
||||
calculated_property = data[0]
|
||||
calculated_properties.append(
|
||||
self.section(
|
||||
calculated_property_name.capitalize(), calculated_property
|
||||
)
|
||||
)
|
||||
if not properties:
|
||||
return ""
|
||||
return " ".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["ori_name"], d.get("annotation")) for d in dico}
|
||||
|
||||
return modified_properties_parser(previous), modified_properties_parser(new)
|
||||
|
||||
def columns(
|
||||
self,
|
||||
col: List[str], # pylint: disable=unused-argument
|
||||
) -> None:
|
||||
"""Manage column"""
|
||||
return
|
||||
|
||||
def tabular(self, with_header: bool = True) -> str:
|
||||
"""Transform list to a tabular in string format"""
|
||||
if with_header:
|
||||
headers = self.tabular_header(self.tabular_datas.headers())
|
||||
else:
|
||||
headers = ()
|
||||
msg = (
|
||||
tabulate(
|
||||
self.tabular_datas.get(),
|
||||
headers=headers,
|
||||
tablefmt=self._tabular_name,
|
||||
)
|
||||
+ "\n\n"
|
||||
)
|
||||
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:
|
||||
filename = None
|
||||
if self.other_root_filenames:
|
||||
path = msg["path"]["path"]
|
||||
for root in self.other_root_filenames:
|
||||
if path == root or path.startswith(f'{root}.'):
|
||||
filename = self.other_root_filenames[root]
|
||||
break
|
||||
if "identifiers" in msg["path"]:
|
||||
msg["identifiers"] = [msg["path"]["identifiers"]]
|
||||
path = self.link_variable(calc_path(msg["path"], self, identifiers), msg["path"]["path"], self.get_description("variable", msg, {}, None), filename=filename)
|
||||
msg = msg["message"].format(path)
|
||||
elif "description" in msg:
|
||||
if "variables" in msg:
|
||||
paths = []
|
||||
for variable in msg["variables"]:
|
||||
filename = None
|
||||
if self.other_root_filenames:
|
||||
path = msg["path"]
|
||||
for root in self.other_root_filenames:
|
||||
if path == root or path.startswith(f'{root}.'):
|
||||
filename = self.other_root_filenames[root]
|
||||
break
|
||||
identifiers = variable.get("identifiers")
|
||||
path = calc_path(variable, self, identifiers)
|
||||
paths.append(self.link_variable(path, variable["path"], self.get_description("variable", variable, {}, force_identifiers=identifiers), filename=filename))
|
||||
msg = msg["description"].format(*paths)
|
||||
else:
|
||||
msg = msg["description"]
|
||||
return ret, msg
|
||||
|
||||
def section(
|
||||
self,
|
||||
name: str,
|
||||
msg: str,
|
||||
submessage: str = "",
|
||||
type_ = "variable",
|
||||
section_name=True,
|
||||
with_to_phrase=False
|
||||
) -> str:
|
||||
"""Return something like Name: msg"""
|
||||
submessage, msg = self.message_to_string(msg, submessage)
|
||||
if isinstance(msg, list):
|
||||
if len(msg) == 1:
|
||||
submessage, elt = self.message_to_string(msg[0], submessage)
|
||||
if isinstance(elt, list):
|
||||
submessage += self.list(elt, type_=type_, with_enter=section_name)
|
||||
else:
|
||||
submessage += elt
|
||||
else:
|
||||
lst = []
|
||||
for p in msg:
|
||||
submessage, elt = self.message_to_string(p, submessage)
|
||||
lst.append(elt)
|
||||
submessage += self.list(lst, type_=type_, with_enter=section_name)
|
||||
msg = ""
|
||||
if not isinstance(msg, str):
|
||||
submessage += dump(msg)
|
||||
else:
|
||||
submessage += msg
|
||||
if section_name:
|
||||
return _("{0}: {1}").format(self.bold(name), submessage)
|
||||
if with_to_phrase:
|
||||
return to_phrase(submessage)
|
||||
return submessage
|
||||
|
||||
|
||||
def calc_path(path, formatter=None, identifiers: List[str] = None) -> str:
|
||||
def _path_with_identifier(path, identifier):
|
||||
identifier = normalize_family(str(identifier))
|
||||
if formatter:
|
||||
identifier = formatter.italic(identifier)
|
||||
return path.replace("{{ identifier }}", identifier, 1)
|
||||
|
||||
if isinstance(path, dict):
|
||||
path_ = path["path"]
|
||||
if "identifiers" in 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_
|
||||
41
tests/changelog/00add_family/after/rougail/00-base.yml
Normal file
41
tests/changelog/00add_family/after/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
21
tests/changelog/00add_family/before/rougail/00-base.yml
Normal file
21
tests/changelog/00add_family/before/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
21
tests/changelog/00add_family/result.adoc
Normal file
21
tests/changelog/00add_family/result.adoc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
== 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]` `multiple` `standard` `mandatory` `unique` | Fourth variable. +
|
||||
**Default**:
|
||||
|
||||
* the value of the variable "var1"
|
||||
* the value of the variable "family.var2"
|
||||
* the value of the variable "family2.var3"
|
||||
|====
|
||||
|
||||
10
tests/changelog/00add_family/result.gitlab.md
Normal file
10
tests/changelog/00add_family/result.gitlab.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<details><summary>New variables</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="family2.var2" name="family2.var2">family2.var2</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `standard` `mandatory` | A variable2.<br/>**Default**: the value of the variable "[A second variable](#family.var2)" |
|
||||
| **<a id="family2.var3" name="family2.var3">family2.var3</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `standard` `mandatory` | A third variable.<br/>**Default**: string4<br/>**Example**: string5 |
|
||||
| **<a id="family2.subfamily.variable" name="family2.subfamily.variable">family2.subfamily.variable</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` `standard` `mandatory` `unique` | Fourth variable.<br/>**Default**: <br/>• the value of the variable "[First variable](#var1)"<br/>• the value of the variable "[A second variable](#family.var2)"<br/>• the value of the variable "[A third variable](#family2.var3)" |
|
||||
|
||||
</details>
|
||||
|
||||
15
tests/changelog/00add_family/result.html
Normal file
15
tests/changelog/00add_family/result.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<h1>New variables</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>family2.var2</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>standard</mark> <mark>mandatory</mark> </td><td>A variable2.<br/><b>Default</b>: the value of the variable "family.var2" </td></tr>
|
||||
<tr><td><b>family2.var3</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>standard</mark> <mark>mandatory</mark> </td><td>A third variable.<br/><b>Default</b>: string4<br/><b>Example</b>: string5</td></tr>
|
||||
<tr><td><b>family2.subfamily.variable</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>multiple</mark> <mark>standard</mark> <mark>mandatory</mark> <mark>unique</mark></td><td>Fourth variable.<br/><b>Default</b>: <ul><li>the value of the variable "var1"</li>
|
||||
<li>the value of the variable "family.var2"</li>
|
||||
<li>the value of the variable "family2.var3"</li></ul> </td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
8
tests/changelog/00add_family/result.md
Normal file
8
tests/changelog/00add_family/result.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# New variables
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **<a id="family2.var2" name="family2.var2">family2.var2</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `standard` `mandatory` | A variable2.<br/>**Default**: the value of the variable "[A second variable](#family.var2)" |
|
||||
| **<a id="family2.var3" name="family2.var3">family2.var3</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `standard` `mandatory` | A third variable.<br/>**Default**: string4<br/>**Example**: string5 |
|
||||
| **<a id="family2.subfamily.variable" name="family2.subfamily.variable">family2.subfamily.variable</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `multiple` `standard` `mandatory` `unique` | Fourth variable.<br/>**Default**: <br/>• the value of the variable "[First variable](#var1)"<br/>• the value of the variable "[A second variable](#family.var2)"<br/>• the value of the variable "[A third variable](#family2.var3)" |
|
||||
|
||||
22
tests/changelog/00add_family/result.sh
Normal file
22
tests/changelog/00add_family/result.sh
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[1;4;96mNew variables[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mfamily2.var2[0m │ A variable2. │
|
||||
│ [1;7m string [0m [1;7m standard [0m [1;7m mandatory [0m │ [1mDefault[0m: the value of the variable │
|
||||
│ │ "family.var2" │
|
||||
├───────────────────────────────────────┼──────────────────────────────────────┤
|
||||
│ [1mfamily2.var3[0m │ A third variable. │
|
||||
│ [1;7m string [0m [1;7m standard [0m [1;7m mandatory [0m │ [1mDefault[0m: string4 │
|
||||
│ │ [1mExample[0m: string5 │
|
||||
├───────────────────────────────────────┼──────────────────────────────────────┤
|
||||
│ [1mfamily2.subfamily.variable[0m │ Fourth variable. │
|
||||
│ [1;7m string [0m [1;7m multiple [0m [1;7m standard [0m [1;7m [0m │ [1mDefault[0m: │
|
||||
│ [1;7mmandatory [0m [1;7m unique [0m │ • the value of the variable "var1" │
|
||||
│ │ • the value of the variable │
|
||||
│ │ "family.var2" │
|
||||
│ │ • the value of the variable │
|
||||
│ │ "family2.var3" │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # first variable
|
||||
|
||||
variable_to_family: # a variable that became a family
|
||||
...
|
||||
|
|
@ -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
|
||||
...
|
||||
14
tests/changelog/00add_family_to_variable/result.adoc
Normal file
14
tests/changelog/00add_family_to_variable/result.adoc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
== 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
|
||||
13
tests/changelog/00add_family_to_variable/result.gitlab.md
Normal file
13
tests/changelog/00add_family_to_variable/result.gitlab.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<details><summary>New variable</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------|
|
||||
| **<a id="variable_to_family" name="variable_to_family">variable_to_family</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A variable that became a family. |
|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Deleted variable</summary>
|
||||
|
||||
|
||||
- variable_to_family.var</details>
|
||||
|
||||
14
tests/changelog/00add_family_to_variable/result.html
Normal file
14
tests/changelog/00add_family_to_variable/result.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<h1>New variable</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>variable_to_family</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark></td><td>A variable that became a family.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1>Deleted variable</h1>
|
||||
|
||||
<ul><li>variable_to_family.var</li></ul>
|
||||
10
tests/changelog/00add_family_to_variable/result.md
Normal file
10
tests/changelog/00add_family_to_variable/result.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# New variable
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------|
|
||||
| **<a id="variable_to_family" name="variable_to_family">variable_to_family</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A variable that became a family. |
|
||||
|
||||
# Deleted variable
|
||||
|
||||
|
||||
- variable_to_family.var
|
||||
14
tests/changelog/00add_family_to_variable/result.sh
Normal file
14
tests/changelog/00add_family_to_variable/result.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[1;4;96mNew variable[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mvariable_to_family[0m │ A variable that became a family. │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
[1;4;96mDeleted variable[0m
|
||||
|
||||
|
||||
• variable_to_family.var
|
||||
|
||||
41
tests/changelog/00add_variable/after/rougail/00-base.yml
Normal file
41
tests/changelog/00add_variable/after/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
39
tests/changelog/00add_variable/before/rougail/00-base.yml
Normal file
39
tests/changelog/00add_variable/before/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
9
tests/changelog/00add_variable/result.adoc
Normal file
9
tests/changelog/00add_variable/result.adoc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
== 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.
|
||||
|====
|
||||
|
||||
8
tests/changelog/00add_variable/result.gitlab.md
Normal file
8
tests/changelog/00add_variable/result.gitlab.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<details><summary>New variable</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
|
||||
| **<a id="family.var3" name="family.var3">family.var3</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A third variable. |
|
||||
|
||||
</details>
|
||||
|
||||
11
tests/changelog/00add_variable/result.html
Normal file
11
tests/changelog/00add_variable/result.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<h1>New variable</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>family.var3</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark></td><td>A third variable.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
6
tests/changelog/00add_variable/result.md
Normal file
6
tests/changelog/00add_variable/result.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# New variable
|
||||
|
||||
| Variable | Description |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
|
||||
| **<a id="family.var3" name="family.var3">family.var3</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A third variable. |
|
||||
|
||||
9
tests/changelog/00add_variable/result.sh
Normal file
9
tests/changelog/00add_variable/result.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[1;4;96mNew variable[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mfamily.var3[0m │ A third variable. │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
|
|
@ -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
|
||||
...
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # first variable
|
||||
|
||||
variable_to_family: # a variable that became a family
|
||||
...
|
||||
14
tests/changelog/00add_variable_to_family/result.adoc
Normal file
14
tests/changelog/00add_variable_to_family/result.adoc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
== 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
|
||||
13
tests/changelog/00add_variable_to_family/result.gitlab.md
Normal file
13
tests/changelog/00add_variable_to_family/result.gitlab.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<details><summary>New variable</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
|
||||
| **<a id="variable_to_family.var" name="variable_to_family.var">variable_to_family.var</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A second variable. |
|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Deleted variable</summary>
|
||||
|
||||
|
||||
- variable_to_family</details>
|
||||
|
||||
14
tests/changelog/00add_variable_to_family/result.html
Normal file
14
tests/changelog/00add_variable_to_family/result.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<h1>New variable</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>variable_to_family.var</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark></td><td>A second variable.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1>Deleted variable</h1>
|
||||
|
||||
<ul><li>variable_to_family</li></ul>
|
||||
10
tests/changelog/00add_variable_to_family/result.md
Normal file
10
tests/changelog/00add_variable_to_family/result.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# New variable
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
|
||||
| **<a id="variable_to_family.var" name="variable_to_family.var">variable_to_family.var</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A second variable. |
|
||||
|
||||
# Deleted variable
|
||||
|
||||
|
||||
- variable_to_family
|
||||
14
tests/changelog/00add_variable_to_family/result.sh
Normal file
14
tests/changelog/00add_variable_to_family/result.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[1;4;96mNew variable[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mvariable_to_family.var[0m │ A second variable. │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
[1;4;96mDeleted variable[0m
|
||||
|
||||
|
||||
• variable_to_family
|
||||
|
||||
43
tests/changelog/00add_variables/after/rougail/00-base.yml
Normal file
43
tests/changelog/00add_variables/after/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
39
tests/changelog/00add_variables/before/rougail/00-base.yml
Normal file
39
tests/changelog/00add_variables/before/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
11
tests/changelog/00add_variables/result.adoc
Normal file
11
tests/changelog/00add_variables/result.adoc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
== 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.
|
||||
|====
|
||||
|
||||
9
tests/changelog/00add_variables/result.gitlab.md
Normal file
9
tests/changelog/00add_variables/result.gitlab.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<details><summary>New variables</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
|
||||
| **<a id="family.var3" name="family.var3">family.var3</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A third variable. |
|
||||
| **<a id="family2.var4" name="family2.var4">family2.var4</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A fourth variable. |
|
||||
|
||||
</details>
|
||||
|
||||
12
tests/changelog/00add_variables/result.html
Normal file
12
tests/changelog/00add_variables/result.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<h1>New variables</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>family.var3</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark> </td><td>A third variable. </td></tr>
|
||||
<tr><td><b>family2.var4</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark></td><td>A fourth variable.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
7
tests/changelog/00add_variables/result.md
Normal file
7
tests/changelog/00add_variables/result.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# New variables
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
|
||||
| **<a id="family.var3" name="family.var3">family.var3</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A third variable. |
|
||||
| **<a id="family2.var4" name="family2.var4">family2.var4</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | A fourth variable. |
|
||||
|
||||
12
tests/changelog/00add_variables/result.sh
Normal file
12
tests/changelog/00add_variables/result.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[1;4;96mNew variables[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mfamily.var3[0m │ A third variable. │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ │
|
||||
├───────────────────────────────────────┼──────────────────────────────────────┤
|
||||
│ [1mfamily2.var4[0m │ A fourth variable. │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
21
tests/changelog/00remove_family/after/rougail/00-base.yml
Normal file
21
tests/changelog/00remove_family/after/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
41
tests/changelog/00remove_family/before/rougail/00-base.yml
Normal file
41
tests/changelog/00remove_family/before/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
7
tests/changelog/00remove_family/result.adoc
Normal file
7
tests/changelog/00remove_family/result.adoc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
== Deleted variables
|
||||
|
||||
|
||||
|
||||
* family2.var2
|
||||
* family2.var3
|
||||
* family2.subfamily.variable
|
||||
7
tests/changelog/00remove_family/result.gitlab.md
Normal file
7
tests/changelog/00remove_family/result.gitlab.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<details><summary>Deleted variables</summary>
|
||||
|
||||
|
||||
- family2.var2
|
||||
- family2.var3
|
||||
- family2.subfamily.variable</details>
|
||||
|
||||
5
tests/changelog/00remove_family/result.html
Normal file
5
tests/changelog/00remove_family/result.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Deleted variables</h1>
|
||||
|
||||
<ul><li>family2.var2</li>
|
||||
<li>family2.var3</li>
|
||||
<li>family2.subfamily.variable</li></ul>
|
||||
6
tests/changelog/00remove_family/result.md
Normal file
6
tests/changelog/00remove_family/result.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Deleted variables
|
||||
|
||||
|
||||
- family2.var2
|
||||
- family2.var3
|
||||
- family2.subfamily.variable
|
||||
7
tests/changelog/00remove_family/result.sh
Normal file
7
tests/changelog/00remove_family/result.sh
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[1;4;96mDeleted variables[0m
|
||||
|
||||
|
||||
• family2.var2
|
||||
• family2.var3
|
||||
• family2.subfamily.variable
|
||||
|
||||
39
tests/changelog/00remove_variable/after/rougail/00-base.yml
Normal file
39
tests/changelog/00remove_variable/after/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
41
tests/changelog/00remove_variable/before/rougail/00-base.yml
Normal file
41
tests/changelog/00remove_variable/before/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
5
tests/changelog/00remove_variable/result.adoc
Normal file
5
tests/changelog/00remove_variable/result.adoc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
== Deleted variable
|
||||
|
||||
|
||||
|
||||
* family.var3
|
||||
5
tests/changelog/00remove_variable/result.gitlab.md
Normal file
5
tests/changelog/00remove_variable/result.gitlab.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<details><summary>Deleted variable</summary>
|
||||
|
||||
|
||||
- family.var3</details>
|
||||
|
||||
3
tests/changelog/00remove_variable/result.html
Normal file
3
tests/changelog/00remove_variable/result.html
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<h1>Deleted variable</h1>
|
||||
|
||||
<ul><li>family.var3</li></ul>
|
||||
4
tests/changelog/00remove_variable/result.md
Normal file
4
tests/changelog/00remove_variable/result.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Deleted variable
|
||||
|
||||
|
||||
- family.var3
|
||||
5
tests/changelog/00remove_variable/result.sh
Normal file
5
tests/changelog/00remove_variable/result.sh
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[1;4;96mDeleted variable[0m
|
||||
|
||||
|
||||
• family.var3
|
||||
|
||||
39
tests/changelog/00remove_variables/after/rougail/00-base.yml
Normal file
39
tests/changelog/00remove_variables/after/rougail/00-base.yml
Normal 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
|
||||
...
|
||||
|
|
@ -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
|
||||
...
|
||||
6
tests/changelog/00remove_variables/result.adoc
Normal file
6
tests/changelog/00remove_variables/result.adoc
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
== Deleted variables
|
||||
|
||||
|
||||
|
||||
* family.var3
|
||||
* family2.var4
|
||||
6
tests/changelog/00remove_variables/result.gitlab.md
Normal file
6
tests/changelog/00remove_variables/result.gitlab.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<details><summary>Deleted variables</summary>
|
||||
|
||||
|
||||
- family.var3
|
||||
- family2.var4</details>
|
||||
|
||||
4
tests/changelog/00remove_variables/result.html
Normal file
4
tests/changelog/00remove_variables/result.html
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<h1>Deleted variables</h1>
|
||||
|
||||
<ul><li>family.var3</li>
|
||||
<li>family2.var4</li></ul>
|
||||
5
tests/changelog/00remove_variables/result.md
Normal file
5
tests/changelog/00remove_variables/result.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Deleted variables
|
||||
|
||||
|
||||
- family.var3
|
||||
- family2.var4
|
||||
6
tests/changelog/00remove_variables/result.sh
Normal file
6
tests/changelog/00remove_variables/result.sh
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[1;4;96mDeleted variables[0m
|
||||
|
||||
|
||||
• family.var3
|
||||
• family2.var4
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # new description
|
||||
...
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1:
|
||||
...
|
||||
9
tests/changelog/10mod_variable_description/result.adoc
Normal file
9
tests/changelog/10mod_variable_description/result.adoc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
== Modified variable
|
||||
|
||||
[cols="1a,1a"]
|
||||
|====
|
||||
| Variable | Description
|
||||
| **var1** +
|
||||
`https://rougail.readthedocs.io/en/latest/variable.html#variables-types[string]` `basic` `mandatory` | #New description.#
|
||||
|====
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<details><summary>Modified variable</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|
|
||||
| **<a id="var1" name="var1">var1</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | <ins>New description.</ins> |
|
||||
|
||||
</details>
|
||||
|
||||
11
tests/changelog/10mod_variable_description/result.html
Normal file
11
tests/changelog/10mod_variable_description/result.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<h1>Modified variable</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>var1</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark></td><td><ins>New description.</ins></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
6
tests/changelog/10mod_variable_description/result.md
Normal file
6
tests/changelog/10mod_variable_description/result.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Modified variable
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|
|
||||
| **<a id="var1" name="var1">var1</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | <ins>New description.</ins> |
|
||||
|
||||
9
tests/changelog/10mod_variable_description/result.sh
Normal file
9
tests/changelog/10mod_variable_description/result.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[1;4;96mModified variable[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mvar1[0m │ [4mNew description.[0m │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # new description
|
||||
...
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # first variable
|
||||
...
|
||||
10
tests/changelog/10mod_variable_description2/result.adoc
Normal file
10
tests/changelog/10mod_variable_description2/result.adoc
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
== 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.#
|
||||
|====
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<details><summary>Modified variable</summary>
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
|
||||
| **<a id="var1" name="var1">var1</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | ~~First variable.~~<br/><ins>New description.</ins> |
|
||||
|
||||
</details>
|
||||
|
||||
11
tests/changelog/10mod_variable_description2/result.html
Normal file
11
tests/changelog/10mod_variable_description2/result.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<h1>Modified variable</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Variable </th><th>Description </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><b>var1</b><br/><mark><a href='https://rougail.readthedocs.io/en/latest/variable.html#variables-types'>string</a></mark> <mark>basic</mark> <mark>mandatory</mark></td><td><del>First variable.</del><br/><ins>New description.</ins></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
6
tests/changelog/10mod_variable_description2/result.md
Normal file
6
tests/changelog/10mod_variable_description2/result.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Modified variable
|
||||
|
||||
| Variable | Description |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
|
||||
| **<a id="var1" name="var1">var1</a>**<br/>[`string`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `basic` `mandatory` | ~~First variable.~~<br/><ins>New description.</ins> |
|
||||
|
||||
9
tests/changelog/10mod_variable_description2/result.sh
Normal file
9
tests/changelog/10mod_variable_description2/result.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[1;4;96mModified variable[0m
|
||||
|
||||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃[1m [0m[1mVariable [0m[1m [0m┃[1m [0m[1mDescription [0m[1m [0m┃
|
||||
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
||||
│ [1mvar1[0m │ [9mFirst variable.[0m │
|
||||
│ [1;7m string [0m [1;7m basic [0m [1;7m mandatory [0m │ [4mNew description.[0m │
|
||||
└───────────────────────────────────────┴──────────────────────────────────────┘
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue