From 995abe4b206dca0cab2286c852e1a56a8d96c8b6 Mon Sep 17 00:00:00 2001
From: Krishna Lodha <47075664+krishnaglodha@users.noreply.github.com>
Date: Fri, 23 Jun 2023 05:40:32 +0530
Subject: [PATCH] Converted docs to using material theme (#132)
* Converted docs to using material theme
* removed olderd mkdocs
* removed unwanted js and css files
---
web/docs/assets/javascripts/custom.js | 180 ++++++++++++++++
web/docs/assets/javascripts/termynal.js | 264 +++++++++++++++++++++++
web/docs/assets/stylesheets/custom.css | 146 +++++++++++++
web/docs/assets/stylesheets/termynal.css | 109 ++++++++++
web/docs/docker.md | 5 +-
web/docs/index.md | 51 +++--
web/mkdocs.yml | 33 ++-
web/requirements.txt | 2 +-
8 files changed, 772 insertions(+), 18 deletions(-)
create mode 100644 web/docs/assets/javascripts/custom.js
create mode 100644 web/docs/assets/javascripts/termynal.js
create mode 100644 web/docs/assets/stylesheets/custom.css
create mode 100644 web/docs/assets/stylesheets/termynal.css
diff --git a/web/docs/assets/javascripts/custom.js b/web/docs/assets/javascripts/custom.js
new file mode 100644
index 0000000..8e3be4c
--- /dev/null
+++ b/web/docs/assets/javascripts/custom.js
@@ -0,0 +1,180 @@
+const div = document.querySelector('.github-topic-projects')
+
+async function getDataBatch(page) {
+ const response = await fetch(`https://api.github.com/search/repositories?q=topic:fastapi&per_page=100&page=${page}`, { headers: { Accept: 'application/vnd.github.mercy-preview+json' } })
+ const data = await response.json()
+ return data
+}
+
+async function getData() {
+ let page = 1
+ let data = []
+ let dataBatch = await getDataBatch(page)
+ data = data.concat(dataBatch.items)
+ const totalCount = dataBatch.total_count
+ while (data.length < totalCount) {
+ page += 1
+ dataBatch = await getDataBatch(page)
+ data = data.concat(dataBatch.items)
+ }
+ return data
+}
+
+function setupTermynal() {
+ document.querySelectorAll(".use-termynal").forEach(node => {
+ node.style.display = "block";
+ new Termynal(node, {
+ lineDelay: 500
+ });
+ });
+ const progressLiteralStart = "---> 100%";
+ const promptLiteralStart = "$ ";
+ const customPromptLiteralStart = "# ";
+ const termynalActivateClass = "termy";
+ let termynals = [];
+
+ function createTermynals() {
+ document
+ .querySelectorAll(`.${termynalActivateClass} .highlight`)
+ .forEach(node => {
+ const text = node.textContent;
+ const lines = text.split("\n");
+ const useLines = [];
+ let buffer = [];
+ function saveBuffer() {
+ if (buffer.length) {
+ let isBlankSpace = true;
+ buffer.forEach(line => {
+ if (line) {
+ isBlankSpace = false;
+ }
+ });
+ dataValue = {};
+ if (isBlankSpace) {
+ dataValue["delay"] = 0;
+ }
+ if (buffer[buffer.length - 1] === "") {
+ // A last single
won't have effect
+ // so put an additional one
+ buffer.push("");
+ }
+ const bufferValue = buffer.join("
");
+ dataValue["value"] = bufferValue;
+ useLines.push(dataValue);
+ buffer = [];
+ }
+ }
+ for (let line of lines) {
+ if (line === progressLiteralStart) {
+ saveBuffer();
+ useLines.push({
+ type: "progress"
+ });
+ } else if (line.startsWith(promptLiteralStart)) {
+ saveBuffer();
+ const value = line.replace(promptLiteralStart, "").trimEnd();
+ useLines.push({
+ type: "input",
+ value: value
+ });
+ } else if (line.startsWith("// ")) {
+ saveBuffer();
+ const value = "💬 " + line.replace("// ", "").trimEnd();
+ useLines.push({
+ value: value,
+ class: "termynal-comment",
+ delay: 0
+ });
+ } else if (line.startsWith(customPromptLiteralStart)) {
+ saveBuffer();
+ const promptStart = line.indexOf(promptLiteralStart);
+ if (promptStart === -1) {
+ console.error("Custom prompt found but no end delimiter", line)
+ }
+ const prompt = line.slice(0, promptStart).replace(customPromptLiteralStart, "")
+ let value = line.slice(promptStart + promptLiteralStart.length);
+ useLines.push({
+ type: "input",
+ value: value,
+ prompt: prompt
+ });
+ } else {
+ buffer.push(line);
+ }
+ }
+ saveBuffer();
+ const div = document.createElement("div");
+ node.replaceWith(div);
+ const termynal = new Termynal(div, {
+ lineData: useLines,
+ noInit: true,
+ lineDelay: 500
+ });
+ termynals.push(termynal);
+ });
+ }
+
+ function loadVisibleTermynals() {
+ termynals = termynals.filter(termynal => {
+ if (termynal.container.getBoundingClientRect().top - innerHeight <= 0) {
+ termynal.init();
+ return false;
+ }
+ return true;
+ });
+ }
+ window.addEventListener("scroll", loadVisibleTermynals);
+ createTermynals();
+ loadVisibleTermynals();
+}
+
+function shuffle(array) {
+ var currentIndex = array.length, temporaryValue, randomIndex;
+ while (0 !== currentIndex) {
+ randomIndex = Math.floor(Math.random() * currentIndex);
+ currentIndex -= 1;
+ temporaryValue = array[currentIndex];
+ array[currentIndex] = array[randomIndex];
+ array[randomIndex] = temporaryValue;
+ }
+ return array;
+}
+
+async function showRandomAnnouncement(groupId, timeInterval) {
+ const announceFastAPI = document.getElementById(groupId);
+ if (announceFastAPI) {
+ let children = [].slice.call(announceFastAPI.children);
+ children = shuffle(children)
+ let index = 0
+ const announceRandom = () => {
+ children.forEach((el, i) => {el.style.display = "none"});
+ children[index].style.display = "block"
+ index = (index + 1) % children.length
+ }
+ announceRandom()
+ setInterval(announceRandom, timeInterval
+ )
+ }
+}
+
+async function main() {
+ if (div) {
+ data = await getData()
+ div.innerHTML = '
'
+ const ul = document.querySelector('.github-topic-projects ul')
+ data.forEach(v => {
+ if (v.full_name === 'tiangolo/fastapi') {
+ return
+ }
+ const li = document.createElement('li')
+ li.innerHTML = `★ ${v.stargazers_count} - ${v.full_name} by @${v.owner.login}`
+ ul.append(li)
+ })
+ }
+
+ setupTermynal();
+ showRandomAnnouncement('announce-left', 5000)
+ showRandomAnnouncement('announce-right', 10000)
+}
+
+main()
diff --git a/web/docs/assets/javascripts/termynal.js b/web/docs/assets/javascripts/termynal.js
new file mode 100644
index 0000000..4ac3270
--- /dev/null
+++ b/web/docs/assets/javascripts/termynal.js
@@ -0,0 +1,264 @@
+/**
+ * termynal.js
+ * A lightweight, modern and extensible animated terminal window, using
+ * async/await.
+ *
+ * @author Ines Montani
+ * @version 0.0.1
+ * @license MIT
+ */
+
+'use strict';
+
+/** Generate a terminal widget. */
+class Termynal {
+ /**
+ * Construct the widget's settings.
+ * @param {(string|Node)=} container - Query selector or container element.
+ * @param {Object=} options - Custom settings.
+ * @param {string} options.prefix - Prefix to use for data attributes.
+ * @param {number} options.startDelay - Delay before animation, in ms.
+ * @param {number} options.typeDelay - Delay between each typed character, in ms.
+ * @param {number} options.lineDelay - Delay between each line, in ms.
+ * @param {number} options.progressLength - Number of characters displayed as progress bar.
+ * @param {string} options.progressChar – Character to use for progress bar, defaults to █.
+ * @param {number} options.progressPercent - Max percent of progress.
+ * @param {string} options.cursor – Character to use for cursor, defaults to ▋.
+ * @param {Object[]} lineData - Dynamically loaded line data objects.
+ * @param {boolean} options.noInit - Don't initialise the animation.
+ */
+ constructor(container = '#termynal', options = {}) {
+ this.container = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.pfx = `data-${options.prefix || 'ty'}`;
+ this.originalStartDelay = this.startDelay = options.startDelay
+ || parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || 600;
+ this.originalTypeDelay = this.typeDelay = options.typeDelay
+ || parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || 90;
+ this.originalLineDelay = this.lineDelay = options.lineDelay
+ || parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || 1500;
+ this.progressLength = options.progressLength
+ || parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || 40;
+ this.progressChar = options.progressChar
+ || this.container.getAttribute(`${this.pfx}-progressChar`) || 'â–ˆ';
+ this.progressPercent = options.progressPercent
+ || parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || 100;
+ this.cursor = options.cursor
+ || this.container.getAttribute(`${this.pfx}-cursor`) || 'â–‹';
+ this.lineData = this.lineDataToElements(options.lineData || []);
+ this.loadLines()
+ if (!options.noInit) this.init()
+ }
+
+ loadLines() {
+ // Load all the lines and create the container so that the size is fixed
+ // Otherwise it would be changing and the user viewport would be constantly
+ // moving as she/he scrolls
+ const finish = this.generateFinish()
+ finish.style.visibility = 'hidden'
+ this.container.appendChild(finish)
+ // Appends dynamically loaded lines to existing line elements.
+ this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat(this.lineData);
+ for (let line of this.lines) {
+ line.style.visibility = 'hidden'
+ this.container.appendChild(line)
+ }
+ const restart = this.generateRestart()
+ restart.style.visibility = 'hidden'
+ this.container.appendChild(restart)
+ this.container.setAttribute('data-termynal', '');
+ }
+
+ /**
+ * Initialise the widget, get lines, clear container and start animation.
+ */
+ init() {
+ /**
+ * Calculates width and height of Termynal container.
+ * If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS.
+ */
+ const containerStyle = getComputedStyle(this.container);
+ this.container.style.width = containerStyle.width !== '0px' ?
+ containerStyle.width : undefined;
+ this.container.style.minHeight = containerStyle.height !== '0px' ?
+ containerStyle.height : undefined;
+
+ this.container.setAttribute('data-termynal', '');
+ this.container.innerHTML = '';
+ for (let line of this.lines) {
+ line.style.visibility = 'visible'
+ }
+ this.start();
+ }
+
+ /**
+ * Start the animation and rener the lines depending on their data attributes.
+ */
+ async start() {
+ this.addFinish()
+ await this._wait(this.startDelay);
+
+ for (let line of this.lines) {
+ const type = line.getAttribute(this.pfx);
+ const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay;
+
+ if (type == 'input') {
+ line.setAttribute(`${this.pfx}-cursor`, this.cursor);
+ await this.type(line);
+ await this._wait(delay);
+ }
+
+ else if (type == 'progress') {
+ await this.progress(line);
+ await this._wait(delay);
+ }
+
+ else {
+ this.container.appendChild(line);
+ await this._wait(delay);
+ }
+
+ line.removeAttribute(`${this.pfx}-cursor`);
+ }
+ this.addRestart()
+ this.finishElement.style.visibility = 'hidden'
+ this.lineDelay = this.originalLineDelay
+ this.typeDelay = this.originalTypeDelay
+ this.startDelay = this.originalStartDelay
+ }
+
+ generateRestart() {
+ const restart = document.createElement('a')
+ restart.onclick = (e) => {
+ e.preventDefault()
+ this.container.innerHTML = ''
+ this.init()
+ }
+ restart.href = '#'
+ restart.setAttribute('data-terminal-control', '')
+ restart.innerHTML = "restart ↻"
+ return restart
+ }
+
+ generateFinish() {
+ const finish = document.createElement('a')
+ finish.onclick = (e) => {
+ e.preventDefault()
+ this.lineDelay = 0
+ this.typeDelay = 0
+ this.startDelay = 0
+ }
+ finish.href = '#'
+ finish.setAttribute('data-terminal-control', '')
+ finish.innerHTML = "fast →"
+ this.finishElement = finish
+ return finish
+ }
+
+ addRestart() {
+ const restart = this.generateRestart()
+ this.container.appendChild(restart)
+ }
+
+ addFinish() {
+ const finish = this.generateFinish()
+ this.container.appendChild(finish)
+ }
+
+ /**
+ * Animate a typed line.
+ * @param {Node} line - The line element to render.
+ */
+ async type(line) {
+ const chars = [...line.textContent];
+ line.textContent = '';
+ this.container.appendChild(line);
+
+ for (let char of chars) {
+ const delay = line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay;
+ await this._wait(delay);
+ line.textContent += char;
+ }
+ }
+
+ /**
+ * Animate a progress bar.
+ * @param {Node} line - The line element to render.
+ */
+ async progress(line) {
+ const progressLength = line.getAttribute(`${this.pfx}-progressLength`)
+ || this.progressLength;
+ const progressChar = line.getAttribute(`${this.pfx}-progressChar`)
+ || this.progressChar;
+ const chars = progressChar.repeat(progressLength);
+ const progressPercent = line.getAttribute(`${this.pfx}-progressPercent`)
+ || this.progressPercent;
+ line.textContent = '';
+ this.container.appendChild(line);
+
+ for (let i = 1; i < chars.length + 1; i++) {
+ await this._wait(this.typeDelay);
+ const percent = Math.round(i / chars.length * 100);
+ line.textContent = `${chars.slice(0, i)} ${percent}%`;
+ if (percent>progressPercent) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Helper function for animation delays, called with `await`.
+ * @param {number} time - Timeout, in ms.
+ */
+ _wait(time) {
+ return new Promise(resolve => setTimeout(resolve, time));
+ }
+
+ /**
+ * Converts line data objects into line elements.
+ *
+ * @param {Object[]} lineData - Dynamically loaded lines.
+ * @param {Object} line - Line data object.
+ * @returns {Element[]} - Array of line elements.
+ */
+ lineDataToElements(lineData) {
+ return lineData.map(line => {
+ let div = document.createElement('div');
+ div.innerHTML = `${line.value || ''}`;
+
+ return div.firstElementChild;
+ });
+ }
+
+ /**
+ * Helper function for generating attributes string.
+ *
+ * @param {Object} line - Line data object.
+ * @returns {string} - String of attributes.
+ */
+ _attributes(line) {
+ let attrs = '';
+ for (let prop in line) {
+ // Custom add class
+ if (prop === 'class') {
+ attrs += ` class=${line[prop]} `
+ continue
+ }
+ if (prop === 'type') {
+ attrs += `${this.pfx}="${line[prop]}" `
+ } else if (prop !== 'value') {
+ attrs += `${this.pfx}-${prop}="${line[prop]}" `
+ }
+ }
+
+ return attrs;
+ }
+}
+
+/**
+* HTML API: If current script has container(s) specified, initialise Termynal.
+*/
+if (document.currentScript.hasAttribute('data-termynal-container')) {
+ const containers = document.currentScript.getAttribute('data-termynal-container');
+ containers.split('|')
+ .forEach(container => new Termynal(container))
+}
diff --git a/web/docs/assets/stylesheets/custom.css b/web/docs/assets/stylesheets/custom.css
new file mode 100644
index 0000000..066b517
--- /dev/null
+++ b/web/docs/assets/stylesheets/custom.css
@@ -0,0 +1,146 @@
+.termynal-comment {
+ color: #4a968f;
+ font-style: italic;
+ display: block;
+}
+
+.termy {
+ /* For right to left languages */
+ direction: ltr;
+}
+
+.termy [data-termynal] {
+ white-space: pre-wrap;
+}
+
+a.external-link {
+ /* For right to left languages */
+ direction: ltr;
+ display: inline-block;
+}
+
+a.external-link::after {
+ /* \00A0 is a non-breaking space
+ to make the mark be on the same line as the link
+ */
+ content: "\00A0[↪]";
+}
+
+a.internal-link::after {
+ /* \00A0 is a non-breaking space
+ to make the mark be on the same line as the link
+ */
+ content: "\00A0↪";
+}
+
+.shadow {
+ box-shadow: 5px 5px 10px #999;
+}
+
+/* Give space to lower icons so Gitter chat doesn't get on top of them */
+.md-footer-meta {
+ padding-bottom: 2em;
+}
+
+.user-list {
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 2rem;
+}
+
+.user-list-center {
+ justify-content: space-evenly;
+}
+
+.user {
+ margin: 1em;
+ min-width: 7em;
+}
+
+.user .avatar-wrapper {
+ width: 80px;
+ height: 80px;
+ margin: 10px auto;
+ overflow: hidden;
+ border-radius: 50%;
+ position: relative;
+}
+
+.user .avatar-wrapper img {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.user .title {
+ text-align: center;
+}
+
+.user .count {
+ font-size: 80%;
+ text-align: center;
+}
+
+a.announce-link:link,
+a.announce-link:visited {
+ color: #fff;
+}
+
+a.announce-link:hover {
+ color: var(--md-accent-fg-color);
+}
+
+.announce-wrapper {
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ align-items: center;
+}
+
+.announce-wrapper div.item {
+ display: none;
+}
+
+.announce-wrapper .sponsor-badge {
+ display: block;
+ position: absolute;
+ top: -10px;
+ right: 0;
+ font-size: 0.5rem;
+ color: #999;
+ background-color: #666;
+ border-radius: 10px;
+ padding: 0 10px;
+ z-index: 10;
+}
+
+.announce-wrapper .sponsor-image {
+ display: block;
+ border-radius: 20px;
+}
+
+.announce-wrapper>div {
+ min-height: 40px;
+ display: flex;
+ align-items: center;
+}
+
+.twitter {
+ color: #00acee;
+}
+
+/* Right to left languages */
+code {
+ direction: ltr;
+ display: inline-block;
+}
+
+.md-content__inner h1 {
+ direction: ltr !important;
+}
+
+.illustration {
+ margin-top: 2em;
+ margin-bottom: 2em;
+}
diff --git a/web/docs/assets/stylesheets/termynal.css b/web/docs/assets/stylesheets/termynal.css
new file mode 100644
index 0000000..406c008
--- /dev/null
+++ b/web/docs/assets/stylesheets/termynal.css
@@ -0,0 +1,109 @@
+/**
+ * termynal.js
+ *
+ * @author Ines Montani
+ * @version 0.0.1
+ * @license MIT
+ */
+
+:root {
+ --color-bg: #252a33;
+ --color-text: #eee;
+ --color-text-subtle: #a2a2a2;
+}
+
+[data-termynal] {
+ width: 750px;
+ max-width: 100%;
+ background: var(--color-bg);
+ color: var(--color-text);
+ /* font-size: 18px; */
+ font-size: 15px;
+ /* font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; */
+ font-family: 'Roboto Mono', 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;
+ border-radius: 4px;
+ padding: 75px 45px 35px;
+ position: relative;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+[data-termynal]:before {
+ content: '';
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ display: inline-block;
+ width: 15px;
+ height: 15px;
+ border-radius: 50%;
+ /* A little hack to display the window buttons in one pseudo element. */
+ background: #d9515d;
+ -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
+ box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
+}
+
+[data-termynal]:after {
+ content: 'bash';
+ position: absolute;
+ color: var(--color-text-subtle);
+ top: 5px;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+
+a[data-terminal-control] {
+ text-align: right;
+ display: block;
+ color: #aebbff;
+}
+
+[data-ty] {
+ display: block;
+ line-height: 2;
+}
+
+[data-ty]:before {
+ /* Set up defaults and ensure empty lines are displayed. */
+ content: '';
+ display: inline-block;
+ vertical-align: middle;
+}
+
+[data-ty="input"]:before,
+[data-ty-prompt]:before {
+ margin-right: 0.75em;
+ color: var(--color-text-subtle);
+}
+
+[data-ty="input"]:before {
+ content: '$';
+}
+
+[data-ty][data-ty-prompt]:before {
+ content: attr(data-ty-prompt);
+}
+
+[data-ty-cursor]:after {
+ content: attr(data-ty-cursor);
+ font-family: monospace;
+ margin-left: 0.5em;
+ -webkit-animation: blink 1s infinite;
+ animation: blink 1s infinite;
+}
+
+
+/* Cursor animation */
+
+@-webkit-keyframes blink {
+ 50% {
+ opacity: 0;
+ }
+}
+
+@keyframes blink {
+ 50% {
+ opacity: 0;
+ }
+}
diff --git a/web/docs/docker.md b/web/docs/docker.md
index 9a91c5d..d508dc6 100644
--- a/web/docs/docker.md
+++ b/web/docs/docker.md
@@ -51,9 +51,12 @@ Some notes:
If all goes well, you should be able to run Docker from the command line as follows: [^2]
-```bash
+
+
+```console
$ docker --version
Docker version 20.10.17, build 100c701
$ docker-compose --version
Docker Compose version v2.6.1
```
+
diff --git a/web/docs/index.md b/web/docs/index.md
index 4476f9d..d5a8f57 100644
--- a/web/docs/index.md
+++ b/web/docs/index.md
@@ -46,11 +46,18 @@ Having said this, please feel free to bring your own! Examples:
Ensure Docker is running on your computer, then verify that the `docker`
and `docker-compose` commands are working and available:
-```bash
-docker version
-docker-compose --version
+
+
+
+```console
+$ docker version
+
+$ docker-compose --version
```
+
+
+
If `docker-compose` gives a 'program not found' error:
> In recent versions of Docker the Docker Compose program is part
@@ -66,43 +73,59 @@ If `docker-compose` gives a 'program not found' error:
Below we will download and run the workshop content.
-```bash
+
+
+```console
curl -O https://codeload.github.com/geopython/geopython-workshop/zip/master
unzip master
cd geopython-workshop-master/workshop
-# start the workshop
+// start the workshop
+
./geopython-workshop-ctl.sh start
-# display URL and open in default web browser
+// display URL and open in default web browser
+
./geopython-workshop-ctl.sh url
-# stop workshop
+// stop workshop
+
./geopython-workshop-ctl.sh stop
```
+
+
If the above `.sh` script does not work on your system
you can execute `docker-compose` directly via:
-```bash
-# in dir geopython-workshop-master/workshop
+
+
+```console
+// in dir geopython-workshop-master/workshop
docker-compose up -d
docker logs --follow geopython-workshop-jupyter
-# look for URL+Token and Copy/Paste in browser
+// look for URL+Token and Copy/Paste in browser
```
+
Below are utility commands. Use when stopped to clean and update.
-```bash
+
+
+```console
+// update the workshop Docker Images in case of new versions
-# update the workshop Docker Images in case of new versions
./geopython-workshop-ctl.sh update
-# clean your Docker environment from dangling Images/Containers
-# (does not remove the workshop's images, only obsolete ones)
+// clean your Docker environment from dangling Images/Containers
+// (does not remove the workshop's images, only obsolete ones)
+
./geopython-workshop-ctl.sh clean
```
+
+
+
## Installation Issues
diff --git a/web/mkdocs.yml b/web/mkdocs.yml
index a57fb8d..5c0dd8a 100644
--- a/web/mkdocs.yml
+++ b/web/mkdocs.yml
@@ -11,6 +11,35 @@ nav:
- Home: index.md
- Docker installation: docker.md
-theme: spacelab
+theme:
+ name: material
+ icon:
+ logo: material/language-python
+ palette:
+ # primary: light blue
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ toggle:
+ icon: material/brightness-7
+ name: Switch to dark mode
-plugins: []
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ toggle:
+ icon: material/brightness-4
+ name: Switch to light mode
+
+plugins:
+ - search
+
+extra_css:
+ - assets/stylesheets/termynal.css
+ - assets/stylesheets/custom.css
+
+extra_javascript:
+ - assets/javascripts/termynal.js
+ - assets/javascripts/custom.js
+
+markdown_extensions:
+ - pymdownx.superfences
\ No newline at end of file
diff --git a/web/requirements.txt b/web/requirements.txt
index 7be02d5..21f876b 100644
--- a/web/requirements.txt
+++ b/web/requirements.txt
@@ -1,2 +1,2 @@
mkdocs
-mkdocs-bootswatch
+mkdocs-material
\ No newline at end of file