diff --git a/docs/.gitlab-ci.yml b/docs/.gitlab-ci.yml
index 48da45a29f987d716aff9d1b5f210dd8f6a617a6..438f3d032f7f0259a0f5a3c54ffc9a28efdfba09 100644
--- a/docs/.gitlab-ci.yml
+++ b/docs/.gitlab-ci.yml
@@ -15,12 +15,9 @@ workflow:
   rules:
     # Do not run CI when commit title have
     # WIP, NO-CI or 🚧 (gitmoji for "work in progress", aka :construction:)
-    - if: |
-        $CI_COMMIT_TITLE =~ /.*WIP.*/ ||
-        $CI_COMMIT_TITLE =~ /.*NO-CI.*/ ||
-        $CI_COMMIT_TITLE =~ /.*🚧.*/
+    - if: $CI_COMMIT_TITLE =~ /.*(WIP|NO-CI|🚧|:construction:).*/
       when: never
-    # Run the CI otherwise (depending on `only/except` key per jobs)
+    # Run the CI otherwise (depending on `rules` key per jobs)
     - when: always
 
 # Stages jobs will pass through with anchors to avoid updating stage in multiple
@@ -107,6 +104,10 @@ variables:
         then
           export RSYNC_DEST="${RSYNC_DEST_DEV}"
         fi
+        if [[ -n "${RSYNC_BASE_PATH_DEV}" ]];
+        then
+          export RSYNC_BASE_PATH="${RSYNC_BASE_PATH_DEV}"
+        fi
       ;;
       "PRE_PROD")
         if [[ -n "${SSH_KNOWN_HOSTS_PRE_PROD}" ]];
@@ -125,6 +126,10 @@ variables:
         then
           export RSYNC_DEST="${RSYNC_DEST_PRE_PROD}"
         fi
+        if [[ -n "${RSYNC_BASE_PATH_PRE_PROD}" ]];
+        then
+          export RSYNC_BASE_PATH="${RSYNC_BASE_PATH_PRE_PROD}"
+        fi
       ;;
       "PROD")
         if [[ -n "${SSH_KNOWN_HOSTS_PROD}" ]];
@@ -143,6 +148,10 @@ variables:
         then
           export RSYNC_DEST="${RSYNC_DEST_PROD}"
         fi
+        if [[ -n "${RSYNC_BASE_PATH_PROD}" ]];
+        then
+          export RSYNC_BASE_PATH="${RSYNC_BASE_PATH_PROD}"
+        fi
       ;;
       *)
         echo -e "\e[31mERROR - Variable \`CI_DEPLOY_TYPE\` is not defined !"
@@ -150,59 +159,31 @@ variables:
       ;;
     esac
 
-# Only anchors
+# Rules anchors
 # -----------------------------------------------------------------------------
-# https://docs.gitlab.com/ee/ci/yaml/README.html#only
-# List all names of refs that can be used with key (only|except):refs using
-# anchors to avoid having to modify multiple times. Refs are:
-# - Branches names based on git flow: https://danielkummer.github.io/git-flow-cheatsheet/
-# - merge_requests (https://docs.gitlab.com/ee/ci/yaml/README.html#onlyexcept-basic)
-# - tags (https://docs.gitlab.com/ee/ci/yaml/README.html#onlyexcept-basic)
-.refs_names:
-  - &ref_release /release-*/
-  - &ref_feature /feature-*/
-  - &ref_hotfix /hotfix-*/
-  - &ref_bugfix /bugfix-*/
-  - &ref_develop develop
-  - &ref_master master
-  - &ref_merge_requests merge_requests
-  - &ref_tags tags
-
-# Specify on which branch, tags or on merge_requests CI should be done.
-# Jobs under only_dev anchor will be run if branch name are compliant with git
-# flow branch which are not `develop` neither `master` and will be run on
-# merge_request
-.only_dev: &only_dev
-  only:
-    refs:
-      - *ref_release
-      - *ref_feature
-      - *ref_hotfix
-      - *ref_bugfix
-      - *ref_merge_requests
-
-# Jobs under only_pre_prod anchor will be run on `develop` (i.e. pre-release)
-# and `master` (release) branch.
-.only_pre_prod: &only_pre_prod
-  only:
-    refs:
-      - *ref_develop
-      - *ref_master
+# https://docs.gitlab.com/ee/ci/yaml/README.html#rules
+# Defining bash regexp test
+.rules_regexp:
+  - &rules_regexp_dev $CI_COMMIT_BRANCH =~ /^((release|feature|hotfix|bugfix)-|merge_request_)*/
+  - &rules_regexp_pre_prod $CI_COMMIT_BRANCH =~ /(develop|master)/
+  - &rules_regexp_prod $CI_COMMIT_TAG
+
+# Defining rules that now replace only to run jobs under specific condition
+# and define variables
+.rules_dev: &rules_dev
+  if: *rules_regexp_dev
+  variables:
+    CI_DEPLOY_TYPE: "DEV"
 
-# Jobs under only_prod anchor will be run on tagged commit.
-.only_prod: &only_prod
-  only:
-    refs:
-      - *ref_tags
+.rules_pre_prod: &rules_pre_prod
+  if: *rules_regexp_pre_prod
+  variables:
+    CI_DEPLOY_TYPE: "PRE_PROD"
 
-# Jobs under only_trigger anchor will be run on `develop` (i.e. pre-release)
-# `master` (release) branch and tagged commit.
-.only_trigger: &only_trigger
-  only:
-    refs:
-      - *ref_develop
-      - *ref_master
-      - *ref_tags
+.rules_prod: &rules_prod
+  if: *rules_regexp_prod
+  variables:
+    CI_DEPLOY_TYPE: "PROD"
 
 # Tag anchors
 # -----------------------------------------------------------------------------
@@ -244,7 +225,7 @@ variables:
   cache:
     # Cache dependencies shared within the same branche
     # https://docs.gitlab.com/ee/ci/yaml/README.html#cachekey
-    key: "$CI_COMMIT_REF_NAME"
+    key: "$CI_COMMIT_BRANCH"
     # Let us cache python dependencies
     # https://docs.gitlab.com/ee/ci/caching/#caching-python-dependencies
     paths:
@@ -258,7 +239,7 @@ variables:
   cache:
     # Cache dependencies shared across all branches but separated by jobs
     # https://docs.gitlab.com/ee/ci/yaml/README.html#cachekey
-    key: "$CI_COMMIT_REF_NAME"
+    key: "$CI_COMMIT_BRANCH"
     # Let us cache python dependencies
     # https://docs.gitlab.com/ee/ci/caching/#caching-python-dependencies
     paths:
@@ -275,7 +256,7 @@ variables:
 # Jobs in pre_test stage
 # -----------------------------------------------------------------------------
 # Template jobs script to ensure required variables are sets.
-.script_pre_test_ensure_variable: &script_pre_test_ensure_variable
+script_pre_test_ensure_variable: &script_pre_test_ensure_variable
   <<: *tag_docker
   <<: *image_docker
   <<: *stage_pre_test
@@ -313,27 +294,10 @@ variables:
         echo -e "\e[31mERROR - At least one required variable is not defined !"
         return 1
       fi
-
-# Set variables for the dev branches CI.
-pre_test_dev:
-  <<: *script_pre_test_ensure_variable
-  <<: *only_dev
-  variables:
-    CI_DEPLOY_TYPE: "DEV"
-
-# Set variables for the pre-prod branches CI (master and develop).
-pre_test_pre_prod:
-  <<: *script_pre_test_ensure_variable
-  <<: *only_pre_prod
-  variables:
-    CI_DEPLOY_TYPE: "PRE_PROD"
-
-# Set variables for the prod CI, i.e. CI on tags.
-pre_test_prod:
-  <<: *script_pre_test_ensure_variable
-  <<: *only_prod
-  variables:
-    CI_DEPLOY_TYPE: "PROD"
+  rules:
+    - *rules_dev
+    - *rules_pre_prod
+    - *rules_prod
 
 # Jobs in test stage
 # -----------------------------------------------------------------------------
@@ -391,7 +355,7 @@ build_html:
 # Jobs in deploy stage
 # -----------------------------------------------------------------------------
 # Template jobs script deploy previously built html documentation.
-.script_deploy_html: &script_deploy_html
+script_deploy_html: &script_deploy_html
   <<: *tag_docker
   <<: *image_docker
   <<: *stage_deploy
@@ -405,15 +369,40 @@ build_html:
     - export LAST_TAG="$(git describe --tags `git rev-list --tags --max-count=1`)"
     - export LAST_TAG="${LAST_TAG/v/}"
     - export LAST_TAG="${LAST_TAG%.*}"
-    - export RSYNC_PATH="/${PROJECT_PATH}${LAST_TAG}"
-    - export ONLINE_PATH="${ONLINE_DEST}${PROJECT_PATH}${LAST_TAG}"
-    - mkdir -p "tmp/${RSYNC_PATH}"
     - |
-      if [[ -f "site/versions.json" ]]
-      then
-        cp site/versions.json versions.json
-      fi
+      case "${CI_DEPLOY_TYPE}" in
+        "DEV")
+          if [[ -n "${RSYNC_BASE_PATH}" ]];
+          then
+            export PROJECT_PATH="/${CI_COMMIT_BRANCH}/${RSYNC_BASE_PATH}/";
+          else
+            export PROJECT_PATH="/${CI_COMMIT_BRANCH}/"
+          fi
+          ;;
+        "PRE_PROD")
+          if [[ -n "${RSYNC_BASE_PATH}" ]];
+          then
+            export PROJECT_PATH="/${CI_COMMIT_BRANCH}/${RSYNC_BASE_PATH}/";
+          else
+            export PROJECT_PATH="/${CI_COMMIT_BRANCH}/"
+          fi
+          ;;
+        "PROD")
+          if [[ -n "${RSYNC_BASE_PATH}" ]];
+          then
+            export PROJECT_PATH="/${RSYNC_BASE_PATH}/";
+          else
+            export PROJECT_PATH="/"
+          fi
+          ;;
+      esac
+    - export RSYNC_PATH="${PROJECT_PATH}${LAST_TAG}"
+    - export ONLINE_PATH="${ONLINE_DEST}${PROJECT_PATH}latest"
+    - echo "$PROJECT_PATH"
+    - mkdir -p "tmp/${RSYNC_PATH}"
     - mv site/* "tmp/${RSYNC_PATH}/"
+    - ln -s "${LAST_TAG}" "latest"
+    - mv "latest" "tmp/${PROJECT_PATH}"
     - rsync -avz "tmp/" "${RSYNC_DEST}"
     - echo -e "
       <!DOCTYPE html>\n
@@ -433,54 +422,38 @@ build_html:
       </body>\n
       </html>" > index.html
     - rsync -avz index.html "${RSYNC_DEST}${PROJECT_PATH}/"
-    - rsync -avz versions.json "${RSYNC_DEST}${PROJECT_PATH}/"
-
-deploy_html_dev:
-  <<: *script_deploy_html
-  <<: *only_dev
-  variables:
-    CI_DEPLOY_TYPE: "DEV"
-    PROJECT_PATH: ${CI_COMMIT_REF_NAME%-*}/$CI_PROJECT_PATH/
-
-deploy_html_pre_prod:
-  <<: *script_deploy_html
-  <<: *only_pre_prod
-  variables:
-    CI_DEPLOY_TYPE: "PRE_PROD"
-    PROJECT_PATH: ${CI_COMMIT_REF_NAME%-*}/$CI_PROJECT_PATH/
-
-deploy_html_prod:
-  <<: *script_deploy_html
-  <<: *only_prod
-  variables:
-    CI_DEPLOY_TYPE: "PROD"
-    PROJECT_PATH: ${CI_COMMIT_REF_NAME%-*}/$CI_PROJECT_PATH/
+    - |
+      if [[ -f "site/versions.json" ]]
+      then
+        cp site/versions.json versions.json
+        rsync -avz versions.json "${RSYNC_DEST}${PROJECT_PATH}/"
+      fi
+  rules:
+    - *rules_dev
+    - *rules_pre_prod
+    - *rules_prod
 
 # Jobs in post_deploy stage
 # -----------------------------------------------------------------------------
 trigger_main_repo:
   <<: *stage_post_deploy
-  <<: *only_trigger
-  only:
-    variables:
-      - $MAIN_PROJECT && $MAIN_PROJECT != $CI_PROJECT_PATH
   trigger:
     include:
       - project: $MAIN_PROJECT
-        ref: $CI_COMMIT_REF_NAME
+        ref: $CI_COMMIT_BRANCH
         file: $MAIN_PROJECT_CI_PATH/.gitlab-ci.yml
     strategy: depend
   variables:
     MAIN_PROJECT_CI_PATH: ${MAIN_PROJECT_CI_PATH:-"."}
+  rules:
+    - *rules_pre_prod
+    - *rules_prod
+    - if: $MAIN_PROJECT && $MAIN_PROJECT != $CI_PROJECT_PATH
 
 inform_triggers_variables:
   <<: *tag_docker
   <<: *image_docker
   <<: *stage_post_deploy
-  <<: *only_trigger
-  except:
-    variables:
-      - $MAIN_PROJECT
   script:
     - |
       if [[ -z "${MAIN_PROJECT}" ]]
@@ -494,6 +467,10 @@ inform_triggers_variables:
           INFO - the path to the file \`gitlab-ci.yaml\` to be run in  \n
           INFO - the \`MAIN_PROJECT\`."
       fi
+  rules:
+    - *rules_pre_prod
+    - *rules_prod
+    - if: ! $MAIN_PROJECT
 
 # *****************************************************************************
 # VIM MODELINE
diff --git a/docs/_data/plugins.py b/docs/_data/plugins.py
index bf81013bf6702e18bbdf6e092c80004434f85585..ece11ce61938a63c5ebec85bad717ca3b054340d 100644
--- a/docs/_data/plugins.py
+++ b/docs/_data/plugins.py
@@ -1,7 +1,19 @@
 #!/usr/bin/env python3
 """
-Set of method for mkdocs-macros which also update nav entry to dynamically
-support subrepo with mkdocs monorepo plugin.
+Set of methods for
+[mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/) Set of
+which :
+
+- Define macros usable in jinja template
+- Update `env.conf`, i.e. mkdocs configuration based on variables files
+- Dynamically update `env` dictionary and `nav` entries to support subrepo
+  either internal subrepo, using
+  [mkdocs-monorepo-plugin](https://github.com/backstage/mkdocs-monorepo-plugin),
+  or external subrepo by using `online_url` of such subrepo.
+
+This script allow to make content of `mkdocs.yml` to be templated, i.e. using
+the same `mkdocs.yml` file for multiple repos and use variables files in
+`docs/_data/`
 """
 
 # pylint: disable=R0801
@@ -22,10 +34,6 @@ import os
 # https://docs.python.org/3/library/re.html
 import re
 
-# High-level file operations
-# https://docs.python.org/3/library/shutil.html
-import shutil
-
 # System-specific parameters and functions
 # https://docs.python.org/3/library/sys.html
 import sys
@@ -38,6 +46,10 @@ import time
 # https://pypi.org/project/GitPython/
 import git
 
+# Python implementation of Markdown
+# https://pypi.org/project/markdown/
+import markdown
+
 # YAML parser and emitter for Python
 # https://pypi.org/project/PyYAML/
 import yaml
@@ -49,13 +61,13 @@ from pykwalify.core import Core as yamlschema
 # pylint: disable=W0105
 # - W0105: String statement has no effect
 LOG = logging.getLogger(__name__)
-"""The logger facilty"""
+"""The logger facilty."""
 ERR_CLR = "\033[31m"
-"""String coloring error output in red"""
+"""String coloring error output in red."""
 INFO_CLR = "\033[32m"
-"""String coloring error output in green"""
+"""String coloring error output in green."""
 RESET_CLR = "\033[0m"
-"""String reseting coloring output"""
+"""String reseting coloring output."""
 
 
 def add_internal_to_nav(
@@ -65,8 +77,25 @@ def add_internal_to_nav(
     repo_parent: list,
     nav_parent: list = None,
 ) -> None:
-    """
-    @rdeville TODO
+    """Add internal subrepo to `nav` key of mkdocs.yml for monorepo.
+
+    This method recursively parse `nav_parent` arguments to know where to
+    include the internal subrepo into `nav` key.
+
+    Once determined, add the subrepo as a entry to the `nav` key, with the
+    format required by
+    [mkdocs-monorepo-plugin](https://github.com/backstage/mkdocs-monorepo-plugin).
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        nav : Navigation dictionary (subpart of it if called
+            recursively)
+        repo_dict : Repo dictionary from `subrepo.yml` file in `docs/_data/`
+        repo_parent : List of keys storing parent keys of the current
+            `repo_dict` from `subrepo.yml` file in `docs/_data`
+        nav_parent : List of keys storing parents `nav_entry` keys of the
+            current `repo_dict` from `subrepo.yml` file in `docs/_data`
     """
     if nav_parent:
         for i_nav in nav:
@@ -93,8 +122,24 @@ def add_internal_to_nav(
 def add_external_to_nav(
     env: dict, nav: dict, repo_dict: dict, repo_parent: list, nav_parent: list
 ) -> None:
-    """
-    @rdeville TODO
+    """Add external subrepo to `nav` key of mkdocs.yml.
+
+    This method recursively parse `nav_parent` arguments to know where to
+    include the external subrepo into `nav` key.
+
+    Once determined, add the subrepo as a entry to the `nav` key, with the
+    `online_url` key of the current subrepo defined with `repo_dict` in file
+    `subrepo.yml` in `docs/_data`.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        nav : Navigation dictionary (subpart of it if called recursively)
+        repo_dict : Repo dictionary from `subrepo.yml` file in `docs/_data/`
+        repo_parent : List of keys storing parent keys of the current
+            `repo_dict` from `subrepo.yml` file in `docs/_data`
+        nav_parent : List of keys storing parents `nav_entry` keys of the
+            current `repo_dict` from `subrepo.yml` file in `docs/_data`
     """
     if nav_parent:
         for i_nav in nav:
@@ -112,8 +157,14 @@ def add_external_to_nav(
 
 
 def add_nav_entry(nav: list, nav_parent: list = None) -> None:
-    """
-    @rdeville TODO
+    """Create missing entry into `nav` key of `env.conf`.
+
+    Recursively parse list `nav_parent` and create missing entry into key `nav`
+    of mkdocs.yml.
+
+    Args:
+        nav : Navigation dictionary (subpart of it if called recursively)
+        nav_parent : List of keys storing parents `nav_entry` keys
     """
     entry = dict()
 
@@ -137,8 +188,30 @@ def update_nav(
     nav_parent: list = None,
     first_iteration=False,
 ) -> None:
-    """
-    @rdeville TODO
+    """Meta method which dynamically update the `nav` key of `env.conf`.
+
+    Recursively parse `repo_dict` (provided from `subrepo.yml` file in
+    `docs/_data`), depending on the content of the keys, method will:
+
+    - Update the list of `nav_parent` and `repo_parent`,
+    - Call [add_nav_entry][plugins.add_nav_entry] to add missing entry to `nav`
+      key of `mkdocs.yml`,
+    - Call [add_external_to_nav][plugins.add_external_to_nav] to add external
+      subrepo to `nav` key of `mkdocs.yml`,
+    - Call [add_internal_to_nav][plugins.add_internal_to_nav] to add internal
+      subrepo to `nav` key of `mkdocs.yml`,
+    - Recursively call itself.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        repo_dict : Repo dictionary from `subrepo.yml` file in `docs/_data/`
+        repo_parent : List of keys storing parent keys of the current
+            `repo_dict` from `subrepo.yml` file in `docs/_data`
+        nav_parent : List of keys storing parents `nav_entry` keys of the
+            current `repo_dict` from `subrepo.yml` file in `docs/_data`
+        first_iteration : Simple boolean to know if it is the first recursive
+            call of the method.
     """
     for i_key in repo_dict:
         if not nav_parent or first_iteration:
@@ -166,17 +239,24 @@ def update_nav(
             update_nav(env, repo_dict[i_key], repo_parent, nav_parent)
 
 
-def get_repo_slug(env, git_repo):
-    """Compute the slug of the current repo and ensure repo dict is defined
+def get_repo_slug(env: dict, git_repo: git.Repo) -> str:
+    """Compute the slug of the `git_repo` and ensure repo dictionary is defined.
+
+    Compute the slug of the repo provided as `git_repo` based on the origin
+    remote. If no remo, then will use the folder name.
 
-    Compute the slug of the current repo based on the origin remote. If no remo,
-    then will use the folder name.
     Then ensure the repo dictionary is defined in `docs/_data/`. If not, print
     an error and exit.
 
+    Else, update value of `env.variables["git"]` and return the `repo_slug`.
+
     Arguments:
-        env: Mkdocs macro plugin environment dictionary.
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
         git_repo: Git python object of the current repo.
+
+    Returns:
+        Posix path from `os.path` python library.
     """
     if git_repo.remotes:
         repo_slug = (
@@ -189,7 +269,7 @@ def get_repo_slug(env, git_repo):
 
     if repo_slug not in env.variables:
         LOG.error(
-            "%s[macros] - Dictionnary %s is not defined.%s",
+            "%s[macros] - Dictionary %s is not defined.%s",
             ERR_CLR,
             repo_slug,
             RESET_CLR,
@@ -214,8 +294,16 @@ def get_repo_slug(env, git_repo):
     return repo_slug
 
 
-def set_site_name(env, repo_slug):
-    """Update content of the `site_name` key in mkdocs.yml
+def set_site_name(env: dict, repo_slug: str) -> None:
+    """Update content of the `site_name` key in `env.conf`.
+
+    Update the value of `site_name` keys for mkdocs documentation based on (in
+    precedence order):
+
+    - Value of `site_name` in `mkdocs.yml`,
+    - Value of `site_name` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `name` in `env.variables[repo_slug]` from `docs/_data/repo.yml`.
+
 
     If `site_name` key is not defined in `mkdocs.yml` then look to
     `docs/_data/vars.yml`, if defined, else look to the the current repo
@@ -232,12 +320,15 @@ def set_site_name(env, repo_slug):
             env.conf["site_name"] = env.variables[repo_slug]["name"]
 
 
-def set_site_desc(env, repo_slug):
-    """Update content of the `site_desc` key in mkdocs.yml
+def set_site_desc(env: dict, repo_slug: str) -> None:
+    """Update content of the `site_desc` key in `env.conf`.
 
-    If `site_desc` key is not defined in `mkdocs.yml` then look to
-    `docs/_data/vars.yml`, if defined, else look to the the current repo
-    dictionary to set value of `site_desc`.
+    Update the value of `site_desc` keys for mkdocs configuration based on (in
+    precedence order):
+
+    - Value of `site_desc` in `mkdocs.yml`,
+    - Value of `site_desc` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `desc` in `env.variables[repo_slug]` from `docs/_data/repo.yml`.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -250,12 +341,17 @@ def set_site_desc(env, repo_slug):
             env.conf["site_desc"] = env.variables[repo_slug]["desc"]
 
 
-def set_site_url(env, repo_slug):
-    """Update content of the `site_url` key in mkdocs.yml
+def set_site_url(env: dict, repo_slug: str) -> None:
+    """Update content of the `site_url` key in `env.conf`.
 
-    If `site_url` key is not defined in `mkdocs.yml` then look to
-    `docs/_data/vars.yml`, if defined, else build value from `site_base_url` and
-    the current repo dictionary.
+    Update the value of `site_url` key for mkdocs documentation based on (in
+    precedence order):
+
+    - Value of `site_url` in `mkdocs.yml`,
+    - Value of `site_url` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `site_base_url` in `env.variables`, from `docs/_data/vars.yml`,
+      concatenate with `env.variables[repo_slug]["url_slug_with_namespace"]`
+      from `docs/_data/repo.yml`.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -272,12 +368,21 @@ def set_site_url(env, repo_slug):
             env.conf["site_url"] = site_url
 
 
-def set_copyright(env, git_repo):
-    """Update content of the `copyright` key in mkdocs.yml
+def set_copyright(env: dict, git_repo: git.Repo) -> None:
+    """Update content of the `copyright` key in `env.conf`.
+
+    Update the value of `copyright` key for mkdocs documentation based on (in
+    precedence order):
+
+    - Value of `copyright` in `mkdocs.yml`,
+    - Value of `copyright` in `env.variables`, from `docs/_data/vars.yml`, then,
+      using this value:
+        - Value of the year of the first commit of the repo holding the
+          documentation and current year,
+        - Value of the current year only,
 
-    If `copyright` key is not defined in `mkdocs.yml` but is defined in
-    `docs/_data/vars.yml`, this override the content of the default `copyright`
-    key in `mkdocs.yml` with date based on the first commit of the repo.
+    If no `copyright` key defined, neither in `mkdocs.yml`, nor in
+    `docs/_data/vars.yml`, then not copyright will be set.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -295,18 +400,25 @@ def set_copyright(env, git_repo):
             first_year = time.strftime("%Y", time.localtime())
         curr_year = time.strftime("%Y", time.localtime())
 
-        env.conf["copyright"] = "Copyright &copy; {} - {} {}".format(
-            first_year, curr_year, env.variables["copyright"]
-        )
+        env.conf[
+            "copyright"
+        ] = f"Copyright &copy; {first_year} - {curr_year} {env.variables['copyright']}"
+
 
+def set_repo_name(env: dict, repo_slug: str) -> None:
+    """Update content of the `repo_name` key in `env.conf`.
 
-def set_repo_name(env, repo_slug):
-    """Update content of the `repo_url` key in mkdocs.yml
+    Update the value of `repo_name` key for mkdocs documentation based on (in
+    precedence order):
 
-    If `repo_url` key is defined in `docs/_data/vars.yml`, this override the
-    content of the default `repo_url` key in `mkdocs.yml`. Else, update the
-    repo_url based on the value of `git_platform` dictionary and the dictionary
-    corresponding of the repo.
+    - Value of `repo_name` in `mkdocs.yml`,
+    - Value of `repo_name` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `name` in `env.variables[repo_slug]`, from `docs/_data/repo.yml`,
+      then, depending on its value:
+      - If value is `!!git_platform`, then value of `repo_name` will be set to
+        the value of `env.variables['git_platform']['name']`, from
+        `docs/_data/vars.yml`
+      - Else, value is key `name` of `env.variables[repo_slug]
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -314,20 +426,26 @@ def set_repo_name(env, repo_slug):
     """
 
     if "repo_name" not in env.conf or not env.conf["repo_name"]:
-        if "name" in env.variables[repo_slug]:
+        if "repo_name" in env.variables:
+            env.conf["repo_name"] = env.variables["repo_name"]
+        elif "name" in env.variables[repo_slug]:
             if env.variables[repo_slug]["name"] == "!!git_platform":
                 env.conf["repo_name"] = env.variables["git_platform"]["name"]
             else:
                 env.conf["repo_name"] = env.variables[repo_slug]["name"]
 
 
-def set_repo_url(env, repo_slug):
-    """Update content of the `repo_url` key in mkdocs.yml
+def set_repo_url(env: dict, repo_slug: str) -> None:
+    """Update content of the `repo_url` key in `env.conf`.
 
-    If `repo_url` key is defined in `docs/_data/vars.yml`, this override the
-    content of the default `repo_url` key in `mkdocs.yml`. Else, update the
-    repo_url based on the value of `git_platform` dictionary and the dictionary
-    corresponding of the repo.
+    Update the value of `repo_url` key for mkdocs documentation based on (in
+    precedence order):
+
+    - Value of `repo_url` in `mkdocs.yml`,
+    - Value of `repo_url` in `env.variables`, from `docs/_data/vars.yml`,
+    - Concatenation of the `url` of `env.variables['git_platform']`, from
+      `docs/_data/vars.yml` and value `git_slug_with_namespace` in
+      `env.variables[repo_slug]`, from `docs/_data/repo.yml`.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -337,17 +455,17 @@ def set_repo_url(env, repo_slug):
         if "repo_url" in env.variables:
             env.conf["repo_url"] = env.variables["repo_url"]
         elif "repo_url" in env.conf:
-            env.conf["repo_url"] = "{}{}".format(
-                env.variables["git_platform"]["url"],
-                env.variables[repo_slug]["git_slug_with_namespace"],
+            env.conf["repo_url"] = (
+                f"{env.variables['git_platform']['url']}"
+                + f"{env.variables[repo_slug]['git_slug_with_namespace']}"
             )
 
 
-def update_theme(env, repo_slug):
-    """Update content of the `theme` key in mkdocs.yml
+def update_theme(env: dict, repo_slug: str) -> None:
+    """Update content of the `theme` key in `env.conf`.
 
     If `theme` key is defined in `docs/_data/vars.yml`, this override the
-    content of the default `theme` key in `mkdocs.yml`.
+    content of the default `theme` key in mkdocs documentation.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -385,13 +503,14 @@ def update_theme(env, repo_slug):
 
 
 def set_config(env: dict) -> None:
-    """Dynamically update mkdocs configuration
+    """Dynamically update mkdocs configuration.
 
-    Based on the repo slug (or folder name) load variables in
-    `docs/_data/vars.yml` and update content of mkdocs.yml accordingly.
+    Based on the `repo_slug` (or folder name) load variables in
+    `docs/_data/vars.yml`, in `docs/_data/repo.yml` and update content of mkdocs
+    documentation accordingly.
 
-    Especially, if `docs/_data/subrepo.yaml` exists and define valid subrepod,
-    dynamically add these subrepo to the `nav` key of the mkdocs.yml
+    Especially, if `docs/_data/subrepo.yaml` exists and define valid subrepos,
+    clone these subrepo and dynamically add them to the `nav` key of the mkdocs
     configuration.
 
     Arguments:
@@ -426,6 +545,9 @@ def load_yaml_file(path: str, filename: str) -> None:
     validate its content. If content is not valid, an error will be raised.
     Otherwise, its content will be returned.
 
+    If filename is `extra.yml` or `extra.yaml`, load content of the file
+    unconditionnally.
+
     Arguments:
         path: Base path where YAML files are.
         filename: Name of the YAML file to load.
@@ -434,19 +556,26 @@ def load_yaml_file(path: str, filename: str) -> None:
     schema_file = os.path.join(path, "schema")
     data_type = ""
 
-    if filename in ("subrepo.yaml", "subrepo.yml"):
-        schema_file = os.path.join(schema_file, "subrepo.schema.yaml")
-    elif filename in ("vars.yaml", "vars.yml"):
-        schema_file = os.path.join(schema_file, "vars.schema.yaml")
+    if filename not in ("extra.yaml", "extra.yml"):
+        if filename in ("subrepo.yaml", "subrepo.yml"):
+            schema_file = os.path.join(schema_file, "subrepo.schema.yaml")
+        elif filename in ("vars.yaml", "vars.yml"):
+            schema_file = os.path.join(schema_file, "vars.schema.yaml")
+        elif filename not in ("extra.yaml", "extra.yml"):
+            schema_file = os.path.join(schema_file, "repo.schema.yaml")
+            data_type = "repo"
+        schema = yamlschema(source_file=source_file, schema_files=[schema_file])
+        schema.validate(raise_exception=True)
+        data_content = schema.source
     else:
-        schema_file = os.path.join(schema_file, "repo.schema.yaml")
-        data_type = "repo"
+        with open(filename) as file:
+            data_content = yaml.safe_load(file)
 
-    schema = yamlschema(source_file=source_file, schema_files=[schema_file])
-    schema.validate(raise_exception=True)
-    return schema.source, data_type
+    return data_content, data_type
 
 
+# pylint: disable=R0913
+# - R0913: Too many arguments
 def update_subrepo_logo_src(
     env: dict,
     curr_repo: dict,
@@ -454,21 +583,29 @@ def update_subrepo_logo_src(
     subrepo_dict: dict,
     path: str,
     external: bool,
-    latest: str
 ) -> None:
+    """Update the content of the key `logo` and `src_path` of subrepo
+
+    Update value of keys `logo` and `src_path` of cloned subrepo, i.e. value
+    from file `docs/_data/repo.yaml` in the cloned subrepo, relative to the main
+    repo holding the documentation.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        curr_repo : Repo dictionary from `repo.yml` file in `docs/_data/` in the
+            cloned subrepo,
+        repo_name: Name of the repo,
+        subrepo_dict: Dictionary of the repo as defined in file `subrepo.yaml`
+            in `docs/_data`,
+        path: Absolute path of the location of the cloned subrepo,
+        external: Boolean to know if current repo is an external subrepo.
     """
-    @rdeville: TODO
-    """
-
     logo_subpath = ""
     src_subpath = ""
-
     if external:
         logo_subpath = os.path.join(subrepo_dict["online_url"])
 
-    if latest:
-        logo_subpath = os.path.join(logo_subpath,latest)
-
     src_subpath = os.path.join(
         path.replace(f"{env.project_dir}/", ""), repo_name
     )
@@ -483,14 +620,27 @@ def update_subrepo_logo_src(
             env.conf["plugins"]["mkdocstrings"].config.data["handlers"][
                 "python"
             ]["setup_commands"].append(f"sys.path.append('{i_src}')")
-    print(yaml.dump(curr_repo))
 
 
 def update_subrepo_info(
     env: dict, subrepo_list: dict, path: str, external: bool = False
 ) -> dict:
-    """
-    @rdeville TODO
+    """Clone subrepo, load repo information and update values if needed.
+
+    Recursively clone or pull repo defined from subpart of
+    `env.variables['subrepo'], load repo information from this cloned or pulled
+    repo, i.e. load file `docs/_data/repo.yaml` in the subrepo, and update
+    needed keys.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        subrepo_list: List of dictionary storing subrepo dict,
+        path: Absolute path of the location of the cloned subrepo,
+        external: Boolean to know if current repo is an external subrepo.
+
+    Return:
+        A updating dictionary storing subrepo information
     """
     return_dict = dict()
     for i_repo in subrepo_list:
@@ -506,24 +656,7 @@ def update_subrepo_info(
             print(
                 f"{INFO_CLR}INFO [macros] - Cloning repo {i_repo['name']}{RESET_CLR}"
             )
-            git_subrepo = git.Repo.clone_from(i_repo["git_url"], subrepo_root)
-
-        latest = ""
-        if git_subrepo.tags:
-            last_major = 0
-            last_minor = 0
-            for i_tag in git_subrepo.tags:
-                i_tag = yaml.dump(i_tag.path)
-                i_tag = re.sub(".*v", "", i_tag).split(".")
-                major = int(i_tag[0])
-                minor = int(i_tag[1])
-                if major > last_major:
-                    last_major = major
-                    last_minor = 0
-                if minor > last_minor:
-                    last_minor = minor
-                    last_patch = 0
-            latest = f"{last_major}.{last_minor}"
+            git.Repo.clone_from(i_repo["git_url"], subrepo_root)
 
         if "subpath" in i_repo:
             data_dir = os.path.join(
@@ -537,7 +670,7 @@ def update_subrepo_info(
         for i_repo_info in data:
             curr_repo = data[i_repo_info]
             update_subrepo_logo_src(
-                env, curr_repo, i_repo_info, i_repo, path, external, latest
+                env, curr_repo, i_repo_info, i_repo, path, external
             )
         return_dict.update(data)
     return return_dict
@@ -546,8 +679,23 @@ def update_subrepo_info(
 def update_subrepo(
     env: dict, subrepo_dict: dict, path: str, external: bool
 ) -> dict:
-    """
-    @rdeville TODO
+    """Recursively parse `env.variables['subrepo']`.
+
+    Recursively parse dictionary `env.variables['subrepo']`, from file
+    `docs/_data/subrepo.yaml`. Depending on the key:
+
+    - `nav_entry`: Do a recursion of this method,
+    - `external` or `internal`: Parse the list to update subrepo information
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        subrepo_dict: Dictionary storing subrepo,
+        path: Absolute path of the location of the cloned subrepo,
+        external: Boolean to know if current repo is an external subrepo.
+
+    Returns:
+        An updated dictionary of repo informations.
     """
     return_dict = dict()
     for i_key in subrepo_dict:
@@ -574,6 +722,20 @@ def update_subrepo(
 def update_logo_src_repo(
     env: dict, curr_repo: dict, repo_name: str, path: str = None
 ) -> None:
+    """Update the content of the key `logo` and `src_path` of current repo
+
+    Update value of keys `logo` and `src_path` of current repo holding the
+    documentation.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        curr_repo : Repo dictionary from `repo.yml` file in `docs/_data/` in the
+            cloned subrepo,
+        repo_name: Name of the repo,
+        path: Absolute path of the location of the current repo.
+    """
+
     subpath = ""
     if path:
         subpath = os.path.join(path.replace(env.project_dir, ""), repo_name)
@@ -591,13 +753,14 @@ def update_logo_src_repo(
 
 
 def load_var_file(env: dict) -> None:
-    """Load variables files in docs/_data/ and variable of subrepo
+    """Load variables files in `docs/_data/`
 
-    Load every yaml files in docs/_data/, if one of the file define a `subrepo`
-    key, load every variables associated to subrepo.
+    Load every yaml files in `docs/_data/`, if one of the file define the
+    current repo, then update keys `logo` and `src_path` for the current repo.
 
     Arguments:
-        env: Mkdocs macro plugin environment dictionary.
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
     """
     var_dir = os.path.join(env.project_dir, "docs", "_data")
 
@@ -611,10 +774,17 @@ def load_var_file(env: dict) -> None:
 
 
 def update_version(env: dict) -> None:
-    """Update docs/versions.json if last commit has a tag
+    """Parse every tags of the repo to build a `docs/versions.json`
+
+    To emulate mike version support for gitlab, this method will parse every
+    tags of the current repo holding the current documentation to create a file
+    `versions.json` which will be put in folder `docs`.
+
+    This is mainly used for the CI to build a documentation per repo tags.
 
     Arguments:
-        env: Mkdocs macro plugin environment dictionary.
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
     """
     if (
         "version" not in env.variables
@@ -685,6 +855,9 @@ def define_env(env: dict) -> None:
     See
     [https://mkdocs-macros-plugin.readthedocs.io/en/latest/](https://mkdocs-macros-plugin.readthedocs.io/en/latest/)
 
+    This hooks also start the initialization of the dynamic configuration of
+    mkdocs.
+
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
     """
@@ -713,10 +886,9 @@ def define_env(env: dict) -> None:
     @env.macro
     # pylint: disable=W0612
     # -  W0612: Unused variable (unused-variable)
-    def get_repo() -> dict:
-        """Return the content of the dictionary of the current repo"""
-        git_repo = git.Repo(search_parent_directories=True)
-        return env.variables[get_repo_slug(env, git_repo)]
+    def to_html(var: str) -> dict:
+        """Convert the content of the markdown string into HTML"""
+        return markdown.markdown(var)
 
 
 # -----------------------------------------------------------------------------
diff --git a/docs/assets/img/meta/mkdocs_template_logo.png b/docs/assets/img/meta/mkdocs_template_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..b0d4b2aa1a91374d3eee3cc1a19a024be4ad2475
Binary files /dev/null and b/docs/assets/img/meta/mkdocs_template_logo.png differ
diff --git a/docs/assets/img/meta/mkdocs_template_logo.svg b/docs/assets/img/meta/mkdocs_template_logo.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1ec682474016cba77b0f482dd5f7221d76450ba8
--- /dev/null
+++ b/docs/assets/img/meta/mkdocs_template_logo.svg
@@ -0,0 +1,352 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   viewBox="0 0 1250 967.88873"
+   id="svg4760"
+   sodipodi:docname="mkdocs_template_logo.svg"
+   width="1250"
+   height="967.88873"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+  <metadata
+     id="metadata4766">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs4764" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2030"
+     inkscape:window-height="648"
+     id="namedview4762"
+     showgrid="false"
+     inkscape:zoom="0.29344931"
+     inkscape:cx="-549.79311"
+     inkscape:cy="527.58136"
+     inkscape:window-x="6"
+     inkscape:window-y="688"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4760" />
+  <g
+     id="g4988"
+     transform="matrix(0.87409674,0,0,0.87409674,-396.65517,-470.11304)">
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4672"
+       ry="1.4669591"
+       height="728.01666"
+       width="223.46336"
+       y="546.03595"
+       x="935.35498" />
+    <rect
+       style="fill:#80e5ff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4674"
+       ry="1.3148954"
+       height="504.80328"
+       width="130.64072"
+       y="598.1051"
+       x="977.04626" />
+    <ellipse
+       ry="46.183907"
+       rx="46.235619"
+       style="fill:#00aa88;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round"
+       id="circle4676"
+       cy="1194.0358"
+       cx="1047.0867" />
+    <rect
+       x="1004.5499"
+       y="655.48639"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4678"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="708.26801"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4680"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="761.04962"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4682"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="813.83124"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4684"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="866.61279"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4686"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="972.17603"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4688"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="919.39441"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4690"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="1004.5499"
+       y="1024.9576"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4692"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       style="fill:#00aa88;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4698"
+       ry="1.4669591"
+       height="728.01666"
+       width="223.46336"
+       y="546.04388"
+       x="1228.2319" />
+    <rect
+       style="fill:#80e5ff;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4700"
+       ry="1.3148954"
+       height="504.80328"
+       width="130.64072"
+       y="598.11292"
+       x="1269.8969" />
+    <ellipse
+       ry="46.183907"
+       rx="46.235619"
+       style="fill:#00aa88;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round"
+       id="circle4702"
+       cy="1194.0436"
+       cx="1339.9636" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4704"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="655.48645"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4706"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="708.26807"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4708"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="761.04968"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4710"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="813.8313"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4712"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="866.61292"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4714"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="972.17609"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4716"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="919.39453"
+       x="1297.4004" />
+    <rect
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round"
+       id="rect4718"
+       ry="1.4669591"
+       height="20.604357"
+       width="75.633553"
+       y="1024.9578"
+       x="1297.4004" />
+    <rect
+       x="642.48505"
+       y="546.04388"
+       width="223.46336"
+       height="728.01666"
+       ry="1.4669591"
+       id="rect4722"
+       style="fill:#80e5ff;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="688.90558"
+       y="676.52002"
+       width="130.64072"
+       height="467.03806"
+       ry="1.2165104"
+       id="rect4724"
+       style="fill:#004455;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <ellipse
+       ry="39.586205"
+       rx="39.630531"
+       cx="754.21674"
+       cy="607.85126"
+       id="circle4726"
+       style="fill:#00aa88;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round" />
+    <ellipse
+       ry="39.586205"
+       rx="39.630531"
+       cx="754.21674"
+       cy="1212.2533"
+       id="circle4728"
+       style="fill:#00aa88;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="712.17401"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4732"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="764.95563"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4734"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="817.73724"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4736"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="870.51886"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4738"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="923.30048"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4740"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="976.08203"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4742"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="1028.8636"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4744"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="716.40955"
+       y="1081.6453"
+       width="75.633553"
+       height="20.604357"
+       ry="1.4669591"
+       id="rect4746"
+       style="fill:#55ddff;fill-rule:evenodd;stroke:#00aa88;stroke-width:16.41740227;stroke-linecap:round" />
+    <rect
+       x="461.99734"
+       y="1285.6647"
+       width="1127.6207"
+       height="65.245979"
+       ry="32.624313"
+       id="rect4752"
+       style="fill:#00aa88;fill-rule:evenodd;stroke:#004455;stroke-width:16.41740227;stroke-linecap:round" />
+  </g>
+  <g
+     id="g2161"
+     transform="matrix(1.4455056,0,0,1.4455056,638.61638,-441.93303)">
+    <path
+       sodipodi:nodetypes="ccccc"
+       id="path4-3"
+       d="m 156.93915,76.592584 c 22.84704,2.62334 39.24036,23.2709 36.61834,46.116866 -2.62335,22.84704 -23.2709,39.24036 -46.11688,36.61834 -22.84703,-2.62335 -39.24035,-23.2709 -36.61833,-46.11688 2.62334,-22.847026 23.2709,-39.240346 46.11687,-36.618326 z"
+       inkscape:connector-curvature="0"
+       style="fill:#0d47a1;fill-opacity:1;stroke-width:0.26458332"
+       transform="matrix(3.7795276,0,0,3.7795276,-325.20043,356.53121)" />
+    <path
+       id="path4"
+       d="M 269.73,630.56 C 174.844,619.665 89.09,687.754 78.2,782.64 67.305,877.526 135.394,963.28 230.28,974.17 325.166,985.06 410.92,916.976 421.81,822.09 432.705,727.204 364.616,641.45 269.73,630.56 Z m -1.7746,15.455 c 86.351,9.915 148.31,87.953 138.4,174.3 -9.915,86.351 -87.953,148.31 -174.3,138.4 -86.351,-9.915 -148.31,-87.953 -138.4,-174.3 9.915,-86.351 87.953,-148.31 174.3,-138.4 z"
+       inkscape:connector-curvature="0"
+       style="fill:#4caf50;fill-opacity:1" />
+    <path
+       id="path6"
+       d="m 345.92,701 a 2.462,2.462 0 0 0 -1.7766,0.71991 2.462,2.462 0 0 0 -0.45258,2.8523 l -4.4437,4.4437 c -7.4842,2.4304 -44.035,14.754 -61.222,29.083 -18.152,15.133 -42.419,44.599 -61.231,59.113 l -24.549,7.2286 c 5.5805,-9.6894 8.2454,-20.185 8.2454,-20.185 0,0 -12.886,3.1428 -23.239,10.001 -9.119,6.0407 -28.758,25.3 -33.535,30.026 l -1.4946,-1.4946 -3.869,3.869 2.6923,2.6923 c -0.61622,0.99132 -7.0276,11.315 -10.02,17.076 -2.2672,4.3652 -4.3616,11.658 -4.3616,11.658 0,0 7.2924,-2.0944 11.658,-4.3616 5.7611,-2.9923 16.085,-9.4037 17.076,-10.02 l 2.6923,2.6923 3.869,-3.869 -1.503,-1.503 c 0.94052,-0.95587 1.5333,-1.5478 3.688,-3.7743 l 12.498,2.3724 c 16.957,3.2194 5.0444,21.217 8.4559,24.629 3.4114,3.4114 21.411,-8.5009 24.631,8.4559 l 2.3702,12.479 c -2.2274,2.1636 -2.8208,2.7595 -3.7764,3.7027 l -1.4504,-1.4504 -3.8711,3.8711 2.6923,2.6923 c -0.6171,0.99272 -7.0258,11.315 -10.018,17.076 -2.2672,4.3652 -4.3616,11.656 -4.3616,11.656 0,0 7.2903,-2.0944 11.656,-4.3616 5.7608,-2.9921 16.085,-9.4008 17.078,-10.018 l 2.6902,2.6902 3.869,-3.869 -1.5451,-1.5451 c 4.7182,-4.7879 23.94,-24.464 29.961,-33.602 6.8353,-10.376 10.068,-23.17 10.068,-23.17 0,0 -10.489,2.5697 -20.145,8.1085 l 7.1887,-24.412 c 14.514,-18.812 43.98,-43.078 59.113,-61.231 14.329,-17.187 26.653,-53.738 29.083,-61.222 l 4.4437,-4.4437 a 2.462,2.462 0 0 0 2.8523,-0.45257 2.462,2.462 0 0 0 0,-3.4817 2.462,2.462 0 0 0 -1.7051,-0.71991 z m -55.872,46.521 a 11.951,11.951 0 0 1 8.277,3.5007 11.951,11.951 0 0 1 0,16.901 11.951,11.951 0 0 1 -16.903,0 11.951,11.951 0 0 1 0,-16.901 11.951,11.951 0 0 1 8.6264,-3.5007 z m -146.42,84.409 9.1905,9.1905 c -1.406,0.8014 -6.2265,3.5409 -9.6831,5.3362 -2.8977,1.505 -8.6558,3.8122 -8.6558,3.8122 0,0 2.3093,-5.7582 3.8143,-8.6559 1.7953,-3.4566 4.533,-8.2771 5.3341,-9.6831 z m 64.649,64.652 9.1884,9.1863 c -1.4072,0.80206 -6.2251,3.5412 -9.681,5.3362 -2.8977,1.505 -8.6558,3.8122 -8.6559,3.8122 0,0 2.3072,-5.756 3.8122,-8.6537 1.7947,-3.4554 4.5335,-8.2726 5.3362,-9.681 z"
+       inkscape:connector-curvature="0"
+       style="fill:#4caf50;fill-opacity:1;fill-rule:evenodd" />
+  </g>
+</svg>
diff --git a/templates/docs/_data/plugins.py b/templates/docs/_data/plugins.py
index f2a9800b7e8a906ef88aed257382c2d56c87cc6d..ece11ce61938a63c5ebec85bad717ca3b054340d 100644
--- a/templates/docs/_data/plugins.py
+++ b/templates/docs/_data/plugins.py
@@ -1,7 +1,19 @@
 #!/usr/bin/env python3
 """
-Set of method for mkdocs-macros which also update nav entry to dynamically
-support subrepo with mkdocs monorepo plugin.
+Set of methods for
+[mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/) Set of
+which :
+
+- Define macros usable in jinja template
+- Update `env.conf`, i.e. mkdocs configuration based on variables files
+- Dynamically update `env` dictionary and `nav` entries to support subrepo
+  either internal subrepo, using
+  [mkdocs-monorepo-plugin](https://github.com/backstage/mkdocs-monorepo-plugin),
+  or external subrepo by using `online_url` of such subrepo.
+
+This script allow to make content of `mkdocs.yml` to be templated, i.e. using
+the same `mkdocs.yml` file for multiple repos and use variables files in
+`docs/_data/`
 """
 
 # pylint: disable=R0801
@@ -22,10 +34,6 @@ import os
 # https://docs.python.org/3/library/re.html
 import re
 
-# High-level file operations
-# https://docs.python.org/3/library/shutil.html
-import shutil
-
 # System-specific parameters and functions
 # https://docs.python.org/3/library/sys.html
 import sys
@@ -38,6 +46,10 @@ import time
 # https://pypi.org/project/GitPython/
 import git
 
+# Python implementation of Markdown
+# https://pypi.org/project/markdown/
+import markdown
+
 # YAML parser and emitter for Python
 # https://pypi.org/project/PyYAML/
 import yaml
@@ -49,13 +61,13 @@ from pykwalify.core import Core as yamlschema
 # pylint: disable=W0105
 # - W0105: String statement has no effect
 LOG = logging.getLogger(__name__)
-"""The logger facilty"""
+"""The logger facilty."""
 ERR_CLR = "\033[31m"
-"""String coloring error output in red"""
+"""String coloring error output in red."""
 INFO_CLR = "\033[32m"
-"""String coloring error output in green"""
+"""String coloring error output in green."""
 RESET_CLR = "\033[0m"
-"""String reseting coloring output"""
+"""String reseting coloring output."""
 
 
 def add_internal_to_nav(
@@ -65,8 +77,25 @@ def add_internal_to_nav(
     repo_parent: list,
     nav_parent: list = None,
 ) -> None:
-    """
-    @rdeville TODO
+    """Add internal subrepo to `nav` key of mkdocs.yml for monorepo.
+
+    This method recursively parse `nav_parent` arguments to know where to
+    include the internal subrepo into `nav` key.
+
+    Once determined, add the subrepo as a entry to the `nav` key, with the
+    format required by
+    [mkdocs-monorepo-plugin](https://github.com/backstage/mkdocs-monorepo-plugin).
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        nav : Navigation dictionary (subpart of it if called
+            recursively)
+        repo_dict : Repo dictionary from `subrepo.yml` file in `docs/_data/`
+        repo_parent : List of keys storing parent keys of the current
+            `repo_dict` from `subrepo.yml` file in `docs/_data`
+        nav_parent : List of keys storing parents `nav_entry` keys of the
+            current `repo_dict` from `subrepo.yml` file in `docs/_data`
     """
     if nav_parent:
         for i_nav in nav:
@@ -93,8 +122,24 @@ def add_internal_to_nav(
 def add_external_to_nav(
     env: dict, nav: dict, repo_dict: dict, repo_parent: list, nav_parent: list
 ) -> None:
-    """
-    @rdeville TODO
+    """Add external subrepo to `nav` key of mkdocs.yml.
+
+    This method recursively parse `nav_parent` arguments to know where to
+    include the external subrepo into `nav` key.
+
+    Once determined, add the subrepo as a entry to the `nav` key, with the
+    `online_url` key of the current subrepo defined with `repo_dict` in file
+    `subrepo.yml` in `docs/_data`.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        nav : Navigation dictionary (subpart of it if called recursively)
+        repo_dict : Repo dictionary from `subrepo.yml` file in `docs/_data/`
+        repo_parent : List of keys storing parent keys of the current
+            `repo_dict` from `subrepo.yml` file in `docs/_data`
+        nav_parent : List of keys storing parents `nav_entry` keys of the
+            current `repo_dict` from `subrepo.yml` file in `docs/_data`
     """
     if nav_parent:
         for i_nav in nav:
@@ -112,8 +157,14 @@ def add_external_to_nav(
 
 
 def add_nav_entry(nav: list, nav_parent: list = None) -> None:
-    """
-    @rdeville TODO
+    """Create missing entry into `nav` key of `env.conf`.
+
+    Recursively parse list `nav_parent` and create missing entry into key `nav`
+    of mkdocs.yml.
+
+    Args:
+        nav : Navigation dictionary (subpart of it if called recursively)
+        nav_parent : List of keys storing parents `nav_entry` keys
     """
     entry = dict()
 
@@ -137,8 +188,30 @@ def update_nav(
     nav_parent: list = None,
     first_iteration=False,
 ) -> None:
-    """
-    @rdeville TODO
+    """Meta method which dynamically update the `nav` key of `env.conf`.
+
+    Recursively parse `repo_dict` (provided from `subrepo.yml` file in
+    `docs/_data`), depending on the content of the keys, method will:
+
+    - Update the list of `nav_parent` and `repo_parent`,
+    - Call [add_nav_entry][plugins.add_nav_entry] to add missing entry to `nav`
+      key of `mkdocs.yml`,
+    - Call [add_external_to_nav][plugins.add_external_to_nav] to add external
+      subrepo to `nav` key of `mkdocs.yml`,
+    - Call [add_internal_to_nav][plugins.add_internal_to_nav] to add internal
+      subrepo to `nav` key of `mkdocs.yml`,
+    - Recursively call itself.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        repo_dict : Repo dictionary from `subrepo.yml` file in `docs/_data/`
+        repo_parent : List of keys storing parent keys of the current
+            `repo_dict` from `subrepo.yml` file in `docs/_data`
+        nav_parent : List of keys storing parents `nav_entry` keys of the
+            current `repo_dict` from `subrepo.yml` file in `docs/_data`
+        first_iteration : Simple boolean to know if it is the first recursive
+            call of the method.
     """
     for i_key in repo_dict:
         if not nav_parent or first_iteration:
@@ -166,17 +239,24 @@ def update_nav(
             update_nav(env, repo_dict[i_key], repo_parent, nav_parent)
 
 
-def get_repo_slug(env, git_repo):
-    """Compute the slug of the current repo and ensure repo dict is defined
+def get_repo_slug(env: dict, git_repo: git.Repo) -> str:
+    """Compute the slug of the `git_repo` and ensure repo dictionary is defined.
+
+    Compute the slug of the repo provided as `git_repo` based on the origin
+    remote. If no remo, then will use the folder name.
 
-    Compute the slug of the current repo based on the origin remote. If no remo,
-    then will use the folder name.
     Then ensure the repo dictionary is defined in `docs/_data/`. If not, print
     an error and exit.
 
+    Else, update value of `env.variables["git"]` and return the `repo_slug`.
+
     Arguments:
-        env: Mkdocs macro plugin environment dictionary.
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
         git_repo: Git python object of the current repo.
+
+    Returns:
+        Posix path from `os.path` python library.
     """
     if git_repo.remotes:
         repo_slug = (
@@ -189,7 +269,7 @@ def get_repo_slug(env, git_repo):
 
     if repo_slug not in env.variables:
         LOG.error(
-            "%s[macros] - Dictionnary %s is not defined.%s",
+            "%s[macros] - Dictionary %s is not defined.%s",
             ERR_CLR,
             repo_slug,
             RESET_CLR,
@@ -214,8 +294,16 @@ def get_repo_slug(env, git_repo):
     return repo_slug
 
 
-def set_site_name(env, repo_slug):
-    """Update content of the `site_name` key in mkdocs.yml
+def set_site_name(env: dict, repo_slug: str) -> None:
+    """Update content of the `site_name` key in `env.conf`.
+
+    Update the value of `site_name` keys for mkdocs documentation based on (in
+    precedence order):
+
+    - Value of `site_name` in `mkdocs.yml`,
+    - Value of `site_name` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `name` in `env.variables[repo_slug]` from `docs/_data/repo.yml`.
+
 
     If `site_name` key is not defined in `mkdocs.yml` then look to
     `docs/_data/vars.yml`, if defined, else look to the the current repo
@@ -232,12 +320,15 @@ def set_site_name(env, repo_slug):
             env.conf["site_name"] = env.variables[repo_slug]["name"]
 
 
-def set_site_desc(env, repo_slug):
-    """Update content of the `site_desc` key in mkdocs.yml
+def set_site_desc(env: dict, repo_slug: str) -> None:
+    """Update content of the `site_desc` key in `env.conf`.
 
-    If `site_desc` key is not defined in `mkdocs.yml` then look to
-    `docs/_data/vars.yml`, if defined, else look to the the current repo
-    dictionary to set value of `site_desc`.
+    Update the value of `site_desc` keys for mkdocs configuration based on (in
+    precedence order):
+
+    - Value of `site_desc` in `mkdocs.yml`,
+    - Value of `site_desc` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `desc` in `env.variables[repo_slug]` from `docs/_data/repo.yml`.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -250,12 +341,17 @@ def set_site_desc(env, repo_slug):
             env.conf["site_desc"] = env.variables[repo_slug]["desc"]
 
 
-def set_site_url(env, repo_slug):
-    """Update content of the `site_url` key in mkdocs.yml
+def set_site_url(env: dict, repo_slug: str) -> None:
+    """Update content of the `site_url` key in `env.conf`.
+
+    Update the value of `site_url` key for mkdocs documentation based on (in
+    precedence order):
 
-    If `site_url` key is not defined in `mkdocs.yml` then look to
-    `docs/_data/vars.yml`, if defined, else build value from `site_base_url` and
-    the current repo dictionary.
+    - Value of `site_url` in `mkdocs.yml`,
+    - Value of `site_url` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `site_base_url` in `env.variables`, from `docs/_data/vars.yml`,
+      concatenate with `env.variables[repo_slug]["url_slug_with_namespace"]`
+      from `docs/_data/repo.yml`.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -272,12 +368,21 @@ def set_site_url(env, repo_slug):
             env.conf["site_url"] = site_url
 
 
-def set_copyright(env, git_repo):
-    """Update content of the `copyright` key in mkdocs.yml
+def set_copyright(env: dict, git_repo: git.Repo) -> None:
+    """Update content of the `copyright` key in `env.conf`.
+
+    Update the value of `copyright` key for mkdocs documentation based on (in
+    precedence order):
 
-    If `copyright` key is not defined in `mkdocs.yml` but is defined in
-    `docs/_data/vars.yml`, this override the content of the default `copyright`
-    key in `mkdocs.yml` with date based on the first commit of the repo.
+    - Value of `copyright` in `mkdocs.yml`,
+    - Value of `copyright` in `env.variables`, from `docs/_data/vars.yml`, then,
+      using this value:
+        - Value of the year of the first commit of the repo holding the
+          documentation and current year,
+        - Value of the current year only,
+
+    If no `copyright` key defined, neither in `mkdocs.yml`, nor in
+    `docs/_data/vars.yml`, then not copyright will be set.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -295,18 +400,25 @@ def set_copyright(env, git_repo):
             first_year = time.strftime("%Y", time.localtime())
         curr_year = time.strftime("%Y", time.localtime())
 
-        env.conf["copyright"] = "Copyright &copy; {} - {} {}".format(
-            first_year, curr_year, env.variables["copyright"]
-        )
+        env.conf[
+            "copyright"
+        ] = f"Copyright &copy; {first_year} - {curr_year} {env.variables['copyright']}"
+
 
+def set_repo_name(env: dict, repo_slug: str) -> None:
+    """Update content of the `repo_name` key in `env.conf`.
 
-def set_repo_name(env, repo_slug):
-    """Update content of the `repo_url` key in mkdocs.yml
+    Update the value of `repo_name` key for mkdocs documentation based on (in
+    precedence order):
 
-    If `repo_url` key is defined in `docs/_data/vars.yml`, this override the
-    content of the default `repo_url` key in `mkdocs.yml`. Else, update the
-    repo_url based on the value of `git_platform` dictionary and the dictionary
-    corresponding of the repo.
+    - Value of `repo_name` in `mkdocs.yml`,
+    - Value of `repo_name` in `env.variables`, from `docs/_data/vars.yml`,
+    - Value of `name` in `env.variables[repo_slug]`, from `docs/_data/repo.yml`,
+      then, depending on its value:
+      - If value is `!!git_platform`, then value of `repo_name` will be set to
+        the value of `env.variables['git_platform']['name']`, from
+        `docs/_data/vars.yml`
+      - Else, value is key `name` of `env.variables[repo_slug]
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -314,20 +426,26 @@ def set_repo_name(env, repo_slug):
     """
 
     if "repo_name" not in env.conf or not env.conf["repo_name"]:
-        if "name" in env.variables[repo_slug]:
+        if "repo_name" in env.variables:
+            env.conf["repo_name"] = env.variables["repo_name"]
+        elif "name" in env.variables[repo_slug]:
             if env.variables[repo_slug]["name"] == "!!git_platform":
                 env.conf["repo_name"] = env.variables["git_platform"]["name"]
             else:
                 env.conf["repo_name"] = env.variables[repo_slug]["name"]
 
 
-def set_repo_url(env, repo_slug):
-    """Update content of the `repo_url` key in mkdocs.yml
+def set_repo_url(env: dict, repo_slug: str) -> None:
+    """Update content of the `repo_url` key in `env.conf`.
 
-    If `repo_url` key is defined in `docs/_data/vars.yml`, this override the
-    content of the default `repo_url` key in `mkdocs.yml`. Else, update the
-    repo_url based on the value of `git_platform` dictionary and the dictionary
-    corresponding of the repo.
+    Update the value of `repo_url` key for mkdocs documentation based on (in
+    precedence order):
+
+    - Value of `repo_url` in `mkdocs.yml`,
+    - Value of `repo_url` in `env.variables`, from `docs/_data/vars.yml`,
+    - Concatenation of the `url` of `env.variables['git_platform']`, from
+      `docs/_data/vars.yml` and value `git_slug_with_namespace` in
+      `env.variables[repo_slug]`, from `docs/_data/repo.yml`.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -337,17 +455,17 @@ def set_repo_url(env, repo_slug):
         if "repo_url" in env.variables:
             env.conf["repo_url"] = env.variables["repo_url"]
         elif "repo_url" in env.conf:
-            env.conf["repo_url"] = "{}{}".format(
-                env.variables["git_platform"]["url"],
-                env.variables[repo_slug]["git_slug_with_namespace"],
+            env.conf["repo_url"] = (
+                f"{env.variables['git_platform']['url']}"
+                + f"{env.variables[repo_slug]['git_slug_with_namespace']}"
             )
 
 
-def update_theme(env, repo_slug):
-    """Update content of the `theme` key in mkdocs.yml
+def update_theme(env: dict, repo_slug: str) -> None:
+    """Update content of the `theme` key in `env.conf`.
 
     If `theme` key is defined in `docs/_data/vars.yml`, this override the
-    content of the default `theme` key in `mkdocs.yml`.
+    content of the default `theme` key in mkdocs documentation.
 
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
@@ -385,13 +503,14 @@ def update_theme(env, repo_slug):
 
 
 def set_config(env: dict) -> None:
-    """Dynamically update mkdocs configuration
+    """Dynamically update mkdocs configuration.
 
-    Based on the repo slug (or folder name) load variables in
-    `docs/_data/vars.yml` and update content of mkdocs.yml accordingly.
+    Based on the `repo_slug` (or folder name) load variables in
+    `docs/_data/vars.yml`, in `docs/_data/repo.yml` and update content of mkdocs
+    documentation accordingly.
 
-    Especially, if `docs/_data/subrepo.yaml` exists and define valid subrepod,
-    dynamically add these subrepo to the `nav` key of the mkdocs.yml
+    Especially, if `docs/_data/subrepo.yaml` exists and define valid subrepos,
+    clone these subrepo and dynamically add them to the `nav` key of the mkdocs
     configuration.
 
     Arguments:
@@ -426,6 +545,9 @@ def load_yaml_file(path: str, filename: str) -> None:
     validate its content. If content is not valid, an error will be raised.
     Otherwise, its content will be returned.
 
+    If filename is `extra.yml` or `extra.yaml`, load content of the file
+    unconditionnally.
+
     Arguments:
         path: Base path where YAML files are.
         filename: Name of the YAML file to load.
@@ -434,29 +556,64 @@ def load_yaml_file(path: str, filename: str) -> None:
     schema_file = os.path.join(path, "schema")
     data_type = ""
 
-    if filename in ("subrepo.yaml", "subrepo.yml"):
-        schema_file = os.path.join(schema_file, "subrepo.schema.yaml")
-    elif filename in ("vars.yaml", "vars.yml"):
-        schema_file = os.path.join(schema_file, "vars.schema.yaml")
+    if filename not in ("extra.yaml", "extra.yml"):
+        if filename in ("subrepo.yaml", "subrepo.yml"):
+            schema_file = os.path.join(schema_file, "subrepo.schema.yaml")
+        elif filename in ("vars.yaml", "vars.yml"):
+            schema_file = os.path.join(schema_file, "vars.schema.yaml")
+        elif filename not in ("extra.yaml", "extra.yml"):
+            schema_file = os.path.join(schema_file, "repo.schema.yaml")
+            data_type = "repo"
+        schema = yamlschema(source_file=source_file, schema_files=[schema_file])
+        schema.validate(raise_exception=True)
+        data_content = schema.source
     else:
-        schema_file = os.path.join(schema_file, "repo.schema.yaml")
-        data_type = "repo"
+        with open(filename) as file:
+            data_content = yaml.safe_load(file)
 
-    schema = yamlschema(source_file=source_file, schema_files=[schema_file])
-    schema.validate(raise_exception=True)
-    return schema.source, data_type
+    return data_content, data_type
 
 
-def update_subrepo_logo_src(env:dict,curr_repo:dict,repo_name:str,subrepo_dict:dict, path:str,external:bool) -> None:
+# pylint: disable=R0913
+# - R0913: Too many arguments
+def update_subrepo_logo_src(
+    env: dict,
+    curr_repo: dict,
+    repo_name: str,
+    subrepo_dict: dict,
+    path: str,
+    external: bool,
+) -> None:
+    """Update the content of the key `logo` and `src_path` of subrepo
+
+    Update value of keys `logo` and `src_path` of cloned subrepo, i.e. value
+    from file `docs/_data/repo.yaml` in the cloned subrepo, relative to the main
+    repo holding the documentation.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        curr_repo : Repo dictionary from `repo.yml` file in `docs/_data/` in the
+            cloned subrepo,
+        repo_name: Name of the repo,
+        subrepo_dict: Dictionary of the repo as defined in file `subrepo.yaml`
+            in `docs/_data`,
+        path: Absolute path of the location of the cloned subrepo,
+        external: Boolean to know if current repo is an external subrepo.
+    """
     logo_subpath = ""
     src_subpath = ""
     if external:
         logo_subpath = os.path.join(subrepo_dict["online_url"])
 
-    src_subpath = os.path.join(path.replace(f"{env.project_dir}/",""),repo_name)
+    src_subpath = os.path.join(
+        path.replace(f"{env.project_dir}/", ""), repo_name
+    )
 
     if "logo" not in curr_repo:
-        curr_repo["logo"] = os.path.join(logo_subpath, "assets", "img", "meta",f"{repo_name}_logo.png")
+        curr_repo["logo"] = os.path.join(
+            logo_subpath, "assets", "img", "meta", f"{repo_name}_logo.png"
+        )
     if "src_path" in curr_repo:
         for i_src in curr_repo["src_path"]:
             i_src = os.path.join(src_subpath, i_src)
@@ -465,9 +622,25 @@ def update_subrepo_logo_src(env:dict,curr_repo:dict,repo_name:str,subrepo_dict:d
             ]["setup_commands"].append(f"sys.path.append('{i_src}')")
 
 
-def update_subrepo_info(env: dict, subrepo_list: dict, path: str, external:bool = False) -> dict:
-    """
-    @rdeville TODO
+def update_subrepo_info(
+    env: dict, subrepo_list: dict, path: str, external: bool = False
+) -> dict:
+    """Clone subrepo, load repo information and update values if needed.
+
+    Recursively clone or pull repo defined from subpart of
+    `env.variables['subrepo'], load repo information from this cloned or pulled
+    repo, i.e. load file `docs/_data/repo.yaml` in the subrepo, and update
+    needed keys.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        subrepo_list: List of dictionary storing subrepo dict,
+        path: Absolute path of the location of the cloned subrepo,
+        external: Boolean to know if current repo is an external subrepo.
+
+    Return:
+        A updating dictionary storing subrepo information
     """
     return_dict = dict()
     for i_repo in subrepo_list:
@@ -496,14 +669,33 @@ def update_subrepo_info(env: dict, subrepo_list: dict, path: str, external:bool
         data, _ = load_yaml_file(data_dir, data_file)
         for i_repo_info in data:
             curr_repo = data[i_repo_info]
-            update_subrepo_logo_src(env,curr_repo,i_repo_info,i_repo,path,external)
+            update_subrepo_logo_src(
+                env, curr_repo, i_repo_info, i_repo, path, external
+            )
         return_dict.update(data)
     return return_dict
 
 
-def update_subrepo(env: dict, subrepo_dict: dict, path: str, external:bool) -> dict:
-    """
-    @rdeville TODO
+def update_subrepo(
+    env: dict, subrepo_dict: dict, path: str, external: bool
+) -> dict:
+    """Recursively parse `env.variables['subrepo']`.
+
+    Recursively parse dictionary `env.variables['subrepo']`, from file
+    `docs/_data/subrepo.yaml`. Depending on the key:
+
+    - `nav_entry`: Do a recursion of this method,
+    - `external` or `internal`: Parse the list to update subrepo information
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        subrepo_dict: Dictionary storing subrepo,
+        path: Absolute path of the location of the cloned subrepo,
+        external: Boolean to know if current repo is an external subrepo.
+
+    Returns:
+        An updated dictionary of repo informations.
     """
     return_dict = dict()
     for i_key in subrepo_dict:
@@ -513,24 +705,45 @@ def update_subrepo(env: dict, subrepo_dict: dict, path: str, external:bool) -> d
             elif i_key == "internal":
                 env.variables["internal_subdoc"] = True
             return_dict.update(
-                update_subrepo_info(env, subrepo_dict[i_key], path,external)
+                update_subrepo_info(env, subrepo_dict[i_key], path, external)
             )
         elif i_key not in ["nav_entry"]:
             return_dict.update(
                 update_subrepo(
-                    env, subrepo_dict[i_key], os.path.join(path, i_key),external
+                    env,
+                    subrepo_dict[i_key],
+                    os.path.join(path, i_key),
+                    external,
                 )
             )
     return return_dict
 
 
-def update_logo_src_repo(env:dict,curr_repo:dict,repo_name:str,path:str=None) -> None:
+def update_logo_src_repo(
+    env: dict, curr_repo: dict, repo_name: str, path: str = None
+) -> None:
+    """Update the content of the key `logo` and `src_path` of current repo
+
+    Update value of keys `logo` and `src_path` of current repo holding the
+    documentation.
+
+    Args:
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
+        curr_repo : Repo dictionary from `repo.yml` file in `docs/_data/` in the
+            cloned subrepo,
+        repo_name: Name of the repo,
+        path: Absolute path of the location of the current repo.
+    """
+
     subpath = ""
     if path:
-        subpath = os.path.join(path.replace(env.project_dir,""),repo_name)
+        subpath = os.path.join(path.replace(env.project_dir, ""), repo_name)
 
     if "logo" not in curr_repo:
-        curr_repo["logo"] = os.path.join(subpath, "assets", "img", "meta",f"{repo_name}_logo.png")
+        curr_repo["logo"] = os.path.join(
+            subpath, "assets", "img", "meta", f"{repo_name}_logo.png"
+        )
     if "src_path" in curr_repo:
         for i_src in curr_repo["src_path"]:
             i_src = os.path.join(subpath, i_src)
@@ -539,15 +752,15 @@ def update_logo_src_repo(env:dict,curr_repo:dict,repo_name:str,path:str=None) ->
             ]["setup_commands"].append(f"sys.path.append('{i_src}')")
 
 
-
 def load_var_file(env: dict) -> None:
-    """Load variables files in docs/_data/ and variable of subrepo
+    """Load variables files in `docs/_data/`
 
-    Load every yaml files in docs/_data/, if one of the file define a `subrepo`
-    key, load every variables associated to subrepo.
+    Load every yaml files in `docs/_data/`, if one of the file define the
+    current repo, then update keys `logo` and `src_path` for the current repo.
 
     Arguments:
-        env: Mkdocs macro plugin environment dictionary.
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
     """
     var_dir = os.path.join(env.project_dir, "docs", "_data")
 
@@ -556,15 +769,22 @@ def load_var_file(env: dict) -> None:
             data, data_type = load_yaml_file(var_dir, i_file)
             for i_key in data:
                 if data_type == "repo":
-                    update_logo_src_repo(env,data[i_key],i_key)
+                    update_logo_src_repo(env, data[i_key], i_key)
                 env.variables[i_key] = data[i_key]
 
 
 def update_version(env: dict) -> None:
-    """Update docs/versions.json if last commit has a tag
+    """Parse every tags of the repo to build a `docs/versions.json`
+
+    To emulate mike version support for gitlab, this method will parse every
+    tags of the current repo holding the current documentation to create a file
+    `versions.json` which will be put in folder `docs`.
+
+    This is mainly used for the CI to build a documentation per repo tags.
 
     Arguments:
-        env: Mkdocs macro plugin environment dictionary.
+        env : Environment dictionary provided by
+            [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/)
     """
     if (
         "version" not in env.variables
@@ -635,6 +855,9 @@ def define_env(env: dict) -> None:
     See
     [https://mkdocs-macros-plugin.readthedocs.io/en/latest/](https://mkdocs-macros-plugin.readthedocs.io/en/latest/)
 
+    This hooks also start the initialization of the dynamic configuration of
+    mkdocs.
+
     Arguments:
         env: Mkdocs macro plugin environment dictionary.
     """
@@ -644,7 +867,9 @@ def define_env(env: dict) -> None:
     if "subrepo" in env.variables:
         env.variables["internal_subdoc"] = False
         env.variables.update(
-            update_subrepo(env, env.variables["subrepo"], env.project_dir, False)
+            update_subrepo(
+                env, env.variables["subrepo"], env.project_dir, False
+            )
         )
 
     set_config(env)
@@ -661,10 +886,9 @@ def define_env(env: dict) -> None:
     @env.macro
     # pylint: disable=W0612
     # -  W0612: Unused variable (unused-variable)
-    def get_repo() -> dict:
-        """Return the content of the dictionary of the current repo"""
-        git_repo = git.Repo(search_parent_directories=True)
-        return env.variables[get_repo_slug(env, git_repo)]
+    def to_html(var: str) -> dict:
+        """Convert the content of the markdown string into HTML"""
+        return markdown.markdown(var)
 
 
 # -----------------------------------------------------------------------------