diff --git a/.github/workflows/automatic-doc-checks.yml b/.github/workflows/automatic-doc-checks.yml
new file mode 100644
index 0000000..479ebcb
--- /dev/null
+++ b/.github/workflows/automatic-doc-checks.yml
@@ -0,0 +1,24 @@
+#
+name: Automatic doc checks
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ paths:
+ - 'docs/**' # Only run on changes to the docs directory
+
+ workflow_dispatch:
+ # Manual trigger
+
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ documentation-checks:
+ uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main
+ with:
+ working-directory: "docs"
+ fetch-depth: 0
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
deleted file mode 100644
index 665c2e5..0000000
--- a/.github/workflows/tests.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: Tests
-
-
-on:
- push:
- branches:
- - main
- pull_request:
- workflow_dispatch:
-
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-
-jobs:
- docs-check:
- name: "Check docs"
- uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main
- with:
- working-directory: "docs"
- fetch-depth: 0
-
- markdown-lint:
- name: "Lint Markdown"
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: DavidAnson/markdownlint-cli2-action@v19
- with:
- config: "docs/.sphinx/.markdownlint.json"
- globs: |
- **/*.{md,markdown}
- ! docs/.sphinx/**
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 0000000..ec26cd6
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,39 @@
+# .readthedocs.yaml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Set the version of Python and other tools you might need
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.11"
+ jobs:
+ post_checkout:
+ - git fetch --unshallow || true
+ # Cancel building pull requests when there aren't changed in the docs directory.
+ # If there are no changes (git diff exits with 0) we force the command to return with 183.
+ # This is a special exit code on Read the Docs that will cancel the build immediately.
+ # https://docs.readthedocs.io/en/stable/build-customization.html#cancel-build-based-on-a-condition
+ - |
+ if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/main -- 'docs/' '.readthedocs.yaml';
+ then
+ exit 183;
+ fi
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+ builder: dirhtml
+ configuration: docs/conf.py
+ fail_on_warning: true
+
+# If using Sphinx, optionally build your docs in additional formats such as PDF
+formats:
+- pdf
+
+# Optionally declare the Python requirements required to build your docs
+python:
+ install:
+ - requirements: docs/requirements.txt
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..aad78f1
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,26 @@
+# Environment
+*env*/
+.sphinx/venv/
+
+# Sphinx
+.sphinx/warnings.txt
+.sphinx/.wordlist.dic
+.sphinx/.doctrees/
+.sphinx/update/
+.sphinx/node_modules/
+
+# Vale
+.sphinx/styles/*
+.sphinx/vale.ini
+
+# Build outputs
+_build
+
+# Node.js
+package*.json
+
+# Unrelated cache and config files
+.DS_Store
+__pycache__
+.idea/
+.vscode/
diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml
deleted file mode 100644
index f170b00..0000000
--- a/docs/.readthedocs.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-# .readthedocs.yaml
-# Read the Docs configuration file
-# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
-
-# Required
-version: 2
-
-# Set the version of Python and other tools you might need
-build:
- os: ubuntu-22.04
- tools:
- python: "3.11"
- jobs:
- pre_install:
- - git fetch --unshallow || true
-
-# Build documentation in the docs/ directory with Sphinx
-sphinx:
- builder: dirhtml
- configuration: docs/conf.py
- fail_on_warning: true
-
-# If using Sphinx, optionally build your docs in additional formats such as PDF
-formats:
- - pdf
-
-# Optionally declare the Python requirements required to build your docs
-python:
- install:
- - requirements: docs/.sphinx/requirements.txt
diff --git a/docs/.sphinx/.markdownlint.json b/docs/.sphinx/.markdownlint.json
deleted file mode 100644
index 8aafaf6..0000000
--- a/docs/.sphinx/.markdownlint.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "default": false,
- "MD003": { "style": "atx" },
- "MD013": { "code_blocks": false, "tables": false, "stern": true, "line_length": 150},
- "MD014": true,
- "MD018": true,
- "MD022": true,
- "MD023": true,
- "MD026": { "punctuation": ".,;。,;"},
- "MD031": { "list_items": false},
- "MD032": true,
- "MD035": true,
- "MD042": true,
- "MD045": true,
- "MD052": true
-}
\ No newline at end of file
diff --git a/docs/.sphinx/.pre-commit-config.yaml b/docs/.sphinx/.pre-commit-config.yaml
new file mode 100644
index 0000000..07e0b48
--- /dev/null
+++ b/docs/.sphinx/.pre-commit-config.yaml
@@ -0,0 +1,23 @@
+repos:
+ - repo: local
+ hooks:
+ - id: make-spelling
+ name: Run make spelling
+ entry: make -C docs spelling
+ language: system
+ pass_filenames: false
+ files: ^docs/.*\.(rst|md|txt)$
+
+ - id: make-linkcheck
+ name: Run make linkcheck
+ entry: make -C docs linkcheck
+ language: system
+ pass_filenames: false
+ files: ^docs/.*\.(rst|md|txt)$
+
+ - id: make-woke
+ name: Run make woke
+ entry: make -C docs woke
+ language: system
+ pass_filenames: false
+ files: ^docs/.*\.(rst|md|txt)$
diff --git a/docs/.sphinx/.pymarkdown.json b/docs/.sphinx/.pymarkdown.json
new file mode 100644
index 0000000..2c4c669
--- /dev/null
+++ b/docs/.sphinx/.pymarkdown.json
@@ -0,0 +1,46 @@
+{
+ "plugins": {
+ "selectively_enable_rules": true,
+ "heading-style": {
+ "enabled": true,
+ "style": "atx"
+ },
+ "commands-show-output": {
+ "enabled": true
+ },
+ "no-missing-space-atx": {
+ "enabled": true
+ },
+ "blanks-around-headings": {
+ "enabled": true
+ },
+ "heading-start-left": {
+ "enabled": true
+ },
+ "no-trailing-punctuation": {
+ "enabled": true,
+ "punctuation": ".,;。,;"
+ },
+ "blanks-around-fences": {
+ "enabled": true,
+ "list_items": false
+ },
+ "blanks-around-lists": {
+ "enabled": true
+ },
+ "hr-style": {
+ "enabled": true
+ },
+ "no-empty-links": {
+ "enabled": true
+ },
+ "no-alt-text": {
+ "enabled": true
+ }
+ },
+ "extensions": {
+ "front-matter" : {
+ "enabled" : true
+ }
+ }
+}
diff --git a/docs/.sphinx/.wordlist.txt b/docs/.sphinx/.wordlist.txt
deleted file mode 100644
index b0cfc2c..0000000
--- a/docs/.sphinx/.wordlist.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-ACME
-ACME's
-addons
-AGPLv
-API
-APIs
-balancer
-Charmhub
-CLI
-crypto
-cryptographic
-DCO
-Diátaxis
-Dqlite
-dropdown
-EBS
-EKS
-Etag
-enablement
-favicon
-Furo
-Git
-GitHub
-github
-golang
-GPG
-Grafana
-gz
-IAM
-InRelease
-installable
-JSON
-Juju
-Kubeflow
-Kubernetes
-Launchpad
-linter
-LTS
-LXD
-Makefile
-Makefiles
-Matrix
-Mattermost
-MicroCeph
-MicroCloud
-MicroOVN
-MyST
-namespace
-namespaces
-NodePort
-Numbat
-observability
-OEM
-OLM
-openpgp
-Permalink
-PR
-pre
-PRs
-Quickstart
-ReadMe
-RSA
-reST
-reStructuredText
-roadmap
-RTD
-subdirectories
-subfolders
-subtree
-TODO
-Ubuntu
-UI
-UUID
-VM
-webhook
-YAML
-YAMLs
diff --git a/docs/.sphinx/_static/css/pdf.css b/docs/.sphinx/_static/css/pdf.css
deleted file mode 100644
index f9e28dd..0000000
--- a/docs/.sphinx/_static/css/pdf.css
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Only relevant for specific PDF generation issues */
-
-.rubric>.hclass2 {
- display: block;
- font-size: 2em;
- border-radius: .5rem;
- font-weight: 300;
- line-height: 1.25;
- margin-top: 1.75rem;
- margin-right: -0.5rem;
- margin-bottom: 0.5rem;
- margin-left: -0.5rem;
- padding-left: .5rem;
- padding-right: .5rem;
-}
\ No newline at end of file
diff --git a/docs/.sphinx/_static/favicon.png b/docs/.sphinx/_static/favicon.png
deleted file mode 100644
index 7f175e4..0000000
Binary files a/docs/.sphinx/_static/favicon.png and /dev/null differ
diff --git a/docs/.sphinx/_static/js/checkbox.js b/docs/.sphinx/_static/js/checkbox.js
deleted file mode 100644
index f0925b7..0000000
--- a/docs/.sphinx/_static/js/checkbox.js
+++ /dev/null
@@ -1,5 +0,0 @@
-document.addEventListener("DOMContentLoaded", () => {
- document.querySelectorAll("input[type='checkbox'][disabled]").forEach(cb => {
- cb.removeAttribute("disabled");
- });
-});
diff --git a/docs/.sphinx/_static/tag.png b/docs/.sphinx/_static/tag.png
deleted file mode 100644
index f6f6e5a..0000000
Binary files a/docs/.sphinx/_static/tag.png and /dev/null differ
diff --git a/docs/.sphinx/_templates/header.html b/docs/.sphinx/_templates/header.html
deleted file mode 100644
index 30c52c5..0000000
--- a/docs/.sphinx/_templates/header.html
+++ /dev/null
@@ -1,52 +0,0 @@
-
diff --git a/docs/.sphinx/fonts/LICENCE.txt b/docs/.sphinx/fonts/LICENCE.txt
deleted file mode 100644
index ae78a8f..0000000
--- a/docs/.sphinx/fonts/LICENCE.txt
+++ /dev/null
@@ -1,96 +0,0 @@
--------------------------------
-UBUNTU FONT LICENCE Version 1.0
--------------------------------
-
-PREAMBLE
-This licence allows the licensed fonts to be used, studied, modified and
-redistributed freely. The fonts, including any derivative works, can be
-bundled, embedded, and redistributed provided the terms of this licence
-are met. The fonts and derivatives, however, cannot be released under
-any other licence. The requirement for fonts to remain under this
-licence does not require any document created using the fonts or their
-derivatives to be published under this licence, as long as the primary
-purpose of the document is not to be a vehicle for the distribution of
-the fonts.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this licence and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Original Version" refers to the collection of Font Software components
-as received under this licence.
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to
-a new environment.
-
-"Copyright Holder(s)" refers to all individuals and companies who have a
-copyright ownership of the Font Software.
-
-"Substantially Changed" refers to Modified Versions which can be easily
-identified as dissimilar to the Font Software by users of the Font
-Software comparing the Original Version with the Modified Version.
-
-To "Propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification and with or without charging
-a redistribution fee), making available to the public, and in some
-countries other activities as well.
-
-PERMISSION & CONDITIONS
-This licence does not grant any rights under trademark law and all such
-rights are reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of the Font Software, to propagate the Font Software, subject to
-the below conditions:
-
-1) Each copy of the Font Software must contain the above copyright
-notice and this licence. These can be included either as stand-alone
-text files, human-readable headers or in the appropriate machine-
-readable metadata fields within text or binary files as long as those
-fields can be easily viewed by the user.
-
-2) The font name complies with the following:
-(a) The Original Version must retain its name, unmodified.
-(b) Modified Versions which are Substantially Changed must be renamed to
-avoid use of the name of the Original Version or similar names entirely.
-(c) Modified Versions which are not Substantially Changed must be
-renamed to both (i) retain the name of the Original Version and (ii) add
-additional naming elements to distinguish the Modified Version from the
-Original Version. The name of such Modified Versions must be the name of
-the Original Version, with "derivative X" where X represents the name of
-the new work, appended to that name.
-
-3) The name(s) of the Copyright Holder(s) and any contributor to the
-Font Software shall not be used to promote, endorse or advertise any
-Modified Version, except (i) as required by this licence, (ii) to
-acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with
-their explicit written permission.
-
-4) The Font Software, modified or unmodified, in part or in whole, must
-be distributed entirely under this licence, and must not be distributed
-under any other licence. The requirement for fonts to remain under this
-licence does not affect any document created using the Font Software,
-except any version of the Font Software extracted from a document
-created using the Font Software may only be distributed under this
-licence.
-
-TERMINATION
-This licence becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
-DEALINGS IN THE FONT SOFTWARE.
diff --git a/docs/.sphinx/fonts/Ubuntu-B.ttf b/docs/.sphinx/fonts/Ubuntu-B.ttf
deleted file mode 100644
index b173da2..0000000
Binary files a/docs/.sphinx/fonts/Ubuntu-B.ttf and /dev/null differ
diff --git a/docs/.sphinx/fonts/Ubuntu-R.ttf b/docs/.sphinx/fonts/Ubuntu-R.ttf
deleted file mode 100644
index d748728..0000000
Binary files a/docs/.sphinx/fonts/Ubuntu-R.ttf and /dev/null differ
diff --git a/docs/.sphinx/fonts/Ubuntu-RI.ttf b/docs/.sphinx/fonts/Ubuntu-RI.ttf
deleted file mode 100644
index 4f2d2bc..0000000
Binary files a/docs/.sphinx/fonts/Ubuntu-RI.ttf and /dev/null differ
diff --git a/docs/.sphinx/fonts/UbuntuMono-B.ttf b/docs/.sphinx/fonts/UbuntuMono-B.ttf
deleted file mode 100644
index 7bd6665..0000000
Binary files a/docs/.sphinx/fonts/UbuntuMono-B.ttf and /dev/null differ
diff --git a/docs/.sphinx/fonts/UbuntuMono-R.ttf b/docs/.sphinx/fonts/UbuntuMono-R.ttf
deleted file mode 100644
index fdd309d..0000000
Binary files a/docs/.sphinx/fonts/UbuntuMono-R.ttf and /dev/null differ
diff --git a/docs/.sphinx/fonts/UbuntuMono-RI.ttf b/docs/.sphinx/fonts/UbuntuMono-RI.ttf
deleted file mode 100644
index 18f81a2..0000000
Binary files a/docs/.sphinx/fonts/UbuntuMono-RI.ttf and /dev/null differ
diff --git a/docs/.sphinx/get_vale_conf.py b/docs/.sphinx/get_vale_conf.py
old mode 100644
new mode 100755
index 9ee2d0b..13e7966
--- a/docs/.sphinx/get_vale_conf.py
+++ b/docs/.sphinx/get_vale_conf.py
@@ -1,53 +1,151 @@
#! /usr/bin/env python
-import requests
import os
+import shutil
+import subprocess
+import tempfile
+import sys
+import logging
+import argparse
-DIR = os.getcwd()
+# Configure logging
+logging.basicConfig(
+ level=logging.INFO,
+ format='%(asctime)s - %(levelname)s - %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S'
+)
+SPHINX_DIR = os.path.join(os.getcwd(), ".sphinx")
-def main():
- if os.path.exists(f"{DIR}/.sphinx/styles/Canonical"):
- print("Vale directory exists")
- else:
- os.makedirs(f"{DIR}/.sphinx/styles/Canonical")
-
- url = (
- "https://api.github.com/repos/canonical/praecepta/"
- + "contents/styles/Canonical"
- )
- r = requests.get(url)
- for item in r.json():
- download = requests.get(item["download_url"])
- file = open(".sphinx/styles/Canonical/" + item["name"], "w")
- file.write(download.text)
- file.close()
-
- if os.path.exists(f"{DIR}/.sphinx/styles/config/vocabularies/Canonical"):
- print("Vocab directory exists")
- else:
- os.makedirs(f"{DIR}/.sphinx/styles/config/vocabularies/Canonical")
-
- url = (
- "https://api.github.com/repos/canonical/praecepta/"
- + "contents/styles/config/vocabularies/Canonical"
- )
- r = requests.get(url)
- for item in r.json():
- download = requests.get(item["download_url"])
- file = open(
- ".sphinx/styles/config/vocabularies/Canonical/" + item["name"],
- "w"
+GITHUB_REPO = "canonical/documentation-style-guide"
+GITHUB_CLONE_URL = f"https://github.com/{GITHUB_REPO}.git"
+
+# Source paths to copy from repo
+VALE_FILE_LIST = [
+ "styles/Canonical",
+ "styles/config/vocabularies/Canonical",
+ "styles/config/dictionaries",
+ "vale.ini"
+]
+
+def clone_repo_and_copy_paths(file_source_dest, overwrite=False):
+ """
+ Clone the repository to a temporary directory and copy required files
+
+ Args:
+ file_source_dest: dictionary of file paths to copy from the repository,
+ and their destination paths
+ overwrite: boolean flag to overwrite existing files in the destination
+
+ Returns:
+ bool: True if all files were copied successfully, False otherwise
+ """
+
+ if not file_source_dest:
+ logging.error("No files to copy")
+ return False
+
+ # Create temporary directory on disk for cloning
+ temp_dir = tempfile.mkdtemp()
+ logging.info("Cloning repository <%s> to temporary directory: %s", GITHUB_REPO, temp_dir)
+ clone_cmd = ["git", "clone", "--depth", "1", GITHUB_CLONE_URL, temp_dir]
+
+ try:
+ result = subprocess.run(
+ clone_cmd,
+ capture_output=True,
+ text=True,
+ check=True
)
- file.write(download.text)
- file.close()
- config = requests.get(
- "https://raw.githubusercontent.com/canonical/praecepta/main/vale.ini"
- )
- file = open(".sphinx/vale.ini", "w")
- file.write(config.text)
- file.close()
+ logging.debug("Git clone output: %s", result.stdout)
+ except subprocess.CalledProcessError as e:
+ logging.error("Git clone failed: %s", e.stderr)
+ return False
+
+ # Copy files from the cloned repository to the destination paths
+ is_copy_success = True
+ for source, dest in file_source_dest.items():
+ source_path = os.path.join(temp_dir, source)
+
+ if not os.path.exists(source_path):
+ is_copy_success = False
+ logging.error("Source path not found: %s", source_path)
+ continue
+
+ if not copy_files_to_path(source_path, dest, overwrite):
+ is_copy_success = False
+ logging.error("Failed to copy %s to %s", source_path, dest)
+
+ # Clean up temporary directory
+ logging.info("Cleaning up temporary directory: %s", temp_dir)
+ shutil.rmtree(temp_dir)
+
+ return is_copy_success
+
+def copy_files_to_path(source_path, dest_path, overwrite=False):
+ """
+ Copy a file or directory from source to destination
+
+ Args:
+ source_path: Path to the source file or directory
+ dest_path: Path to the destination
+ overwrite: Boolean flag to overwrite existing files in the destination
+
+ Returns:
+ bool: True if copy was successful, False otherwise
+ """
+ # Skip if source file doesn't exist
+ if not os.path.exists(source_path):
+ logging.warning("Source path not found: %s", source_path)
+ return False
+
+ logging.info("Copying %s to %s", source_path, dest_path)
+ # Handle existing files
+ if os.path.exists(dest_path):
+ if overwrite:
+ logging.info(" Destination exists, overwriting: %s", dest_path)
+ if os.path.isdir(dest_path):
+ shutil.rmtree(dest_path)
+ else:
+ os.remove(dest_path)
+ else:
+ logging.info(" Destination exists, skip copying (use overwrite=True to replace): %s",
+ dest_path)
+ return True # Skip copying
+
+ # Copy the source to destination
+ try:
+ if os.path.isdir(source_path):
+ # entire directory
+ shutil.copytree(source_path, dest_path)
+ else:
+ # individual files
+ shutil.copy2(source_path, dest_path)
+ return True
+ except (shutil.Error, OSError) as e:
+ logging.error("Copy failed: %s", e)
+ return False
+
+def parse_arguments():
+ parser = argparse.ArgumentParser(description="Download Vale configuration files")
+ parser.add_argument("--no-overwrite", action="store_true", help="Don't overwrite existing files")
+ return parser.parse_args()
+
+def main():
+ # Define local directory paths
+ vale_files_dict = {file: os.path.join(SPHINX_DIR, file) for file in VALE_FILE_LIST}
+
+ # Parse command line arguments, default to overwrite_enabled = True
+ overwrite_enabled = not parse_arguments().no_overwrite
+
+ # Download into /tmp through git clone
+ if not clone_repo_and_copy_paths(vale_files_dict, overwrite=overwrite_enabled):
+ logging.error("Failed to download files from repository")
+ return 1
+
+ logging.info("Download complete")
+ return 0
if __name__ == "__main__":
- main()
+ sys.exit(main()) # Keep return code
diff --git a/docs/.sphinx/images/Canonical-logo-4x.png b/docs/.sphinx/images/Canonical-logo-4x.png
deleted file mode 100644
index fd75696..0000000
Binary files a/docs/.sphinx/images/Canonical-logo-4x.png and /dev/null differ
diff --git a/docs/.sphinx/images/front-page-light.pdf b/docs/.sphinx/images/front-page-light.pdf
deleted file mode 100644
index bb68cdf..0000000
Binary files a/docs/.sphinx/images/front-page-light.pdf and /dev/null differ
diff --git a/docs/.sphinx/images/normal-page-footer.pdf b/docs/.sphinx/images/normal-page-footer.pdf
deleted file mode 100644
index dfd73cb..0000000
Binary files a/docs/.sphinx/images/normal-page-footer.pdf and /dev/null differ
diff --git a/docs/.sphinx/latex_elements_template.txt b/docs/.sphinx/latex_elements_template.txt
deleted file mode 100644
index 322412c..0000000
--- a/docs/.sphinx/latex_elements_template.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-{
- 'papersize': 'a4paper',
- 'pointsize': '11pt',
- 'fncychap': '',
- 'preamble': r'''
-%\usepackage{charter}
-%\usepackage[defaultsans]{lato}
-%\usepackage{inconsolata}
-\setmainfont[UprightFont = *-R, BoldFont = *-B, ItalicFont=*-RI, Extension = .ttf]{Ubuntu}
-\setmonofont[UprightFont = *-R, BoldFont = *-B, ItalicFont=*-RI, Extension = .ttf]{UbuntuMono}
-\usepackage[most]{tcolorbox}
-\tcbuselibrary{breakable}
-\usepackage{lastpage}
-\usepackage{tabto}
-\usepackage{ifthen}
-\usepackage{etoolbox}
-\usepackage{fancyhdr}
-\usepackage{graphicx}
-\usepackage{titlesec}
-\usepackage{fontspec}
-\usepackage{tikz}
-\usepackage{changepage}
-\usepackage{array}
-\usepackage{tabularx}
-\definecolor{yellowgreen}{RGB}{154, 205, 50}
-\definecolor{title}{RGB}{76, 17, 48}
-\definecolor{subtitle}{RGB}{116, 27, 71}
-\definecolor{label}{RGB}{119, 41, 100}
-\definecolor{copyright}{RGB}{174, 167, 159}
-\makeatletter
-\def\tcb@finalize@environment{%
- \color{.}% hack for xelatex
- \tcb@layer@dec%
-}
-\makeatother
-\newenvironment{sphinxclassprompt}{\color{yellowgreen}\setmonofont[Color = 9ACD32, UprightFont = *-R, Extension = .ttf]{UbuntuMono}}{}
-\tcbset{enhanced jigsaw, colback=black, fontupper=\color{white}}
-\newtcolorbox{termbox}{use color stack, breakable, colupper=white, halign=flush left}
-\newenvironment{sphinxclassterminal}{\setmonofont[Color = white, UprightFont = *-R, Extension = .ttf]{UbuntuMono}\sphinxsetup{VerbatimColor={black}}\begin{termbox}}{\end{termbox}}
-\newcommand{\dimtorightedge}{%
- \dimexpr\paperwidth-1in-\hoffset-\oddsidemargin\relax}
-\newcommand{\dimtotop}{%
- \dimexpr\height-1in-\voffset-\topmargin-\headheight-\headsep\relax}
-\newtoggle{tpage}
-\AtBeginEnvironment{titlepage}{\global\toggletrue{tpage}}
-\fancypagestyle{plain}{
- \fancyhf{}
- \fancyfoot[R]{\thepage\ of \pageref*{LastPage}}
- \renewcommand{\headrulewidth}{0pt}
- \renewcommand{\footrulewidth}{0pt}
-}
-\fancypagestyle{normal}{
- \fancyhf{}
- \fancyfoot[R]{\thepage\ of \pageref*{LastPage}}
- \renewcommand{\headrulewidth}{0pt}
- \renewcommand{\footrulewidth}{0pt}
-}
-\fancypagestyle{titlepage}{%
- \fancyhf{}
- \fancyfoot[L]{\footnotesize \textcolor{copyright}{© 2024 Canonical Ltd. All rights reserved.}}
-}
-\newcommand\sphinxbackoftitlepage{\thispagestyle{titlepage}}
-\titleformat{\chapter}[block]{\Huge \color{title} \bfseries\filright}{\thechapter .}{1.5ex}{}
-\titlespacing{\chapter}{0pt}{0pt}{0pt}
-\titleformat{\section}[block]{\huge \bfseries\filright}{\thesection .}{1.5ex}{}
-\titlespacing{\section}{0pt}{0pt}{0pt}
-\titleformat{\subsection}[block]{\Large \bfseries\filright}{\thesubsection .}{1.5ex}{}
-\titlespacing{\subsection}{0pt}{0pt}{0pt}
-\setcounter{tocdepth}{1}
-\renewcommand\pagenumbering[1]{}
-''',
- 'sphinxsetup': 'verbatimwithframe=false, pre_border-radius=0pt, verbatimvisiblespace=\\phantom{}, verbatimcontinued=\\phantom{}',
- 'extraclassoptions': 'openany,oneside',
- 'maketitle': r'''
-\begin{titlepage}
-\begin{flushleft}
- \begin{tikzpicture}[remember picture,overlay]
- \node[anchor=south east, inner sep=0] at (current page.south east) {
- \includegraphics[width=\paperwidth, height=\paperheight]{front-page-light}
- };
- \end{tikzpicture}
-\end{flushleft}
-
-\vspace*{3cm}
-
-\begin{adjustwidth}{8cm}{0pt}
-\begin{flushleft}
- \huge \textcolor{black}{\textbf{}{\raggedright{$PROJECT}}}
-\end{flushleft}
-\end{adjustwidth}
-
-\vfill
-
-\begin{adjustwidth}{8cm}{0pt}
-\begin{tabularx}{0.5\textwidth}{ l l }
- \textcolor{lightgray}{© 2024 Canonical Ltd.} & \hspace{3cm} \\
- \textcolor{lightgray}{All rights reserved.} & \hspace{3cm} \\
- & \hspace{3cm} \\
- & \hspace{3cm} \\
-
-\end{tabularx}
-\end{adjustwidth}
-
-\end{titlepage}
-\RemoveFromHook{shipout/background}
-\AddToHook{shipout/background}{
- \begin{tikzpicture}[remember picture,overlay]
- \node[anchor=south west, align=left, inner sep=0] at (current page.south west) {
- \includegraphics[width=\paperwidth]{normal-page-footer}
- };
- \end{tikzpicture}
- \begin{tikzpicture}[remember picture,overlay]
- \node[anchor=north east, opacity=0.5, inner sep=35] at (current page.north east) {
- \includegraphics[width=4cm]{Canonical-logo-4x}
- };
- \end{tikzpicture}
- }
-''',
-}
\ No newline at end of file
diff --git a/docs/.sphinx/metrics/build_metrics.py b/docs/.sphinx/metrics/build_metrics.py
new file mode 100755
index 0000000..529fb85
--- /dev/null
+++ b/docs/.sphinx/metrics/build_metrics.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python3
+
+import sys
+import argparse
+from pathlib import Path
+from html.parser import HTMLParser
+from urllib.parse import urlsplit
+
+
+class MetricsParser(HTMLParser):
+ def __init__(self):
+ super().__init__()
+ self.int_link_count = 0
+ self.ext_link_count = 0
+ self.fragment_count = 0
+ self.image_count = 0
+ self.in_object = 0
+
+ @property
+ def link_count(self):
+ return self.fragment_count + self.int_link_count + self.ext_link_count
+
+ def read(self, file):
+ """
+ Read *file* (a file-like object with a ``read`` method returning
+ strings) a chunk at a time, feeding each chunk to the parser.
+ """
+ # Ensure the parser state is reset before each file (just in case
+ # there's an erroneous dangling