feat(docs): Replace mdbook with mkdocs workflow (#1548)

* feat: add mdbook docs

* chore: add several articles to docs

* docs: add documentation at surface level

Using Discourse urls as fallback for missing content for now

docs: add missing image files

* docs: Add missing chapter emojis

docs: Add missing warning in Advanced docs in summary

docs: add missing waydroid guide

docs: rename files to avoid spaces

docs: fix badly set docs build params

docs: remove unnecesary placeholders

* docs: Realocate 'Gaming' section under 'General'

* docs: Add 'Introduction' section

This section contains a table of contents of the documentation

* docs: Add unstable documentation warning

* docs: Add missing github url

docs: add missing symlink to resources

* docs: Add discourse scrapper utility

* docs: minor discourse scrapper docs changes

* docs: Add youtube embeding preprocessor

* minor reformat for youtube-embed

* docs: Add mdbook preprocessor template

* docs: add format-author preprocessor

* docs: add git lib to mdbook toolset

* docs: Always fetch the highest quality image by fetch_discourse_md

* docs: fix youtube-embed ignoring new line requirement

* docs: Add documentation transcription guide

* docs: Missing url in transcription guide

* docs: Remove YAML header from doc guide

* docs: Minor tweaks to transcription guide

* docs: Add utilities preprocessor module

docs: Move debug preprocessor util to utils

* docs: tweak debug function

* docs: Add 'replace-urls' preprocessor

* chore: Move mappings parameter in replace-urls preprocessor

* docs: add ignore field to replace-urls

* docs: add Mdbook python types

* docs: Add ignore field to replace-urls

Now we can exclude files from being processed with blob patterns

* chore(ci): add deploy_docs

* chore(ci): Add dynamic edit url template to deploy_docs

* chore(ci): Add html.site-url to deploy_docs

* chore(readme): Use relative paths for repo_content

* chore(ci): Add README to included paths for deploy_docs

* chore(ci): Disable deploy_docs

* chore(ci): Use main in deploy_docs.on.push.branches

* docs: Rephrase unstable docs warning

* chore(ci): Exclude docs from triggering build workflow

* chore(ci): Enable deploy_docs

* fix(docs): Remove unnecessary imports in preprocessors

* docs: Move unstable docs warning to index.hbs

* docs: Add page metadata inclusion with fetch_discourse_md.py

* docs: Move fetch_discourse_md.py to docs/utils

* docs: Add 'fetched_at' metadata field in fetch_discourse_md.py

* docs: Update fetch_discourse_md.py to format metadata in json

* Revert "chore(readme): Use relative paths for repo_content"

This reverts commit 6a781c659607e0c83c19248241684c5785c7e93b.

* docs: Replace include with an url to repo README

* ci(docs): Add multilanguage doc build support

* docs: add Justfile utility

* docs: update Justfile utility

* ci(docs): Add stricter workflow trigger to deploy_docs

* docs: add 'preview_translation' to Justfile

* docs: add documentation translation guide

* ci(docs): Add mdbook cache

* ci(docs): Add i18n-report

* ci(docs): tweak deploy_docs workflow triggers

* ci(docs): remove unnecessary slash at build.yml

* ci(docs): remove unnecessary slash at deploy_docs.yml

* ci(docs): add docs/book.toml to deploy_docs trigger

* ci(docs): Add schedule trigger

* ci(docs): add github-pages cleaning

* ci(docs): Exclude docs from generate_changelog

* docs: Add dependencies installation script

* ci(docs): Add mdbook pdf build

* docs: Tweak Justfile to support pdf generation

* Revert "docs: Always fetch the highest quality image by fetch_discourse_md"

This reverts commit 74130ee1fe9264dc7a4c4c49fb416ef3dc12e322.

* ci(docs): Exclude deploy_docs.yml from cache-mdbook keys

* docs: Add 'mdbook_build' to Justfile

* docs: Add 'mdbook_serve' to Justfile

* docs: Add debug flag to fetch_discourse_md

* docs: Automate discourse documentation scrapping

* docs: Add flock to fetch_discourse_md

* docs: Add translation file generation with Justfile

* docs: Prefix url replacements with site-url in replace-urls.py preprocessor

* docs: Add installation guides

docs: Replace print button

* Revert "docs: Prefix url replacements with site-url in replace-urls.py preprocessor"

This reverts commit a685de4dce54debc900607d743069b79202a26ac.

* Reapply "docs: Prefix url replacements with site-url in replace-urls.py preprocessor"

This reverts commit 777d8055eac7543001200834939c960fb490e666.

* docs: fix replace-urls.py

* docs: fix fetch_discourse_md.py hitting discourse ip_10_secs_limit

* ci(docs): Remove duplicate '/' in build translation step

* ci(docs): Update actions/cache

* ci(docs): Reduce deploy_docs schedule timespan between triggers

* docs: update install-deps.sh

* docs: Update Advanced docs

* docs: Add favicon

* docs: Reword unstable documentation warning

* docs: Change default theme to 'navy'

* ci(docs): Move permisions to job scope

* docs: refactor fetch_discourse_md.py

Now it will export the function 'fetch', which other python scripts can
use

* docs: Add mkdocs skeleton

* docs: Add cmdrun hook

* ci(docs): Migrade deploy_docs to use mkdocs

* chore: remove mdbook leftover files

* docs: add support for markdown emojies

* docs: add support for i18n translations to mkdocs

* docs: add resource prefetching

* docs: enable navigation indexes in toc

* docs: add unstable documentation warning

* docs: normalize toc

docs: Add markdown magiclinks

* docs: remove unnecesary extensions

* ci(docs): Separate docs build into its own action

* ci(docs): fix build docs action

* ci(docs): Add default parameters to build_mkdocs action

* ci(docs): Clean up leftover mdbook files

* docs: remove leftover mkdocs-print-site-plugin

* chore: add mkdocs offline documentation

* docs: fix list indentation

* ci(docs): Add github links to mkdocs

* ci(docs): Add github authors to mkdocs

* docs: Update documentation guide and scripts to mkdocs

* docs: Add cache capabilities to cmdrun hook

* docs: Enable instant loading

docs: Enable toc in sidebar

* docs: Update summary and add more posts

* docs: Add mkdocs-material social plugin

* docs: Disable instant loading

* docs: Fix section url

* docs: Fix fetch_discourse not fetching images properly

* docs: Disable warning for using absolute links

* docs: Add url replacement hook

* docs: Restore 'General' section

* docs: Remove aditional languages for now

* docs: Add missing page titles

* docs: move and rename index.md to docs/src/Handheld_and_HTPC_edition/Steam_Gaming_Mode.md

* docs: remove leftover Bazzite_resources.md

* docs: Add time fallback to git-revision-date

* docs: Add navigation tabs

* docs: Clear cmdrun cache with Justfile

* docs: Add missing dual-boot guide url

* docs: Change to a shorter section name for handheld and HTPC

* docs: Add embed_youtube hook

* docs: Remove leftover resources entry in index

docs: Fix outdated 'Steam Gaming Overview' link in index

* docs: Limit vertical image size

* docs: add more url replacements

* docs: Enable search features
This commit is contained in:
Zeglius 2024-08-29 00:48:19 +02:00 committed by GitHub
parent 3acbbd0c13
commit 0e18978fe1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 1840 additions and 1313 deletions

View File

@ -131,11 +131,15 @@ jobs:
- name: Checkout Push to Registry action
uses: actions/checkout@v4
- name: Download offline documentation
# Prepare offline documentation
- run: mkdir -p ${{ github.workspace }}/system_files/desktop/shared/usr/share/ublue-os/docs/html
- name: Build offline documentation
uses: ./.github/workflows/build_mkdocs
continue-on-error: true
run: |
mkdir -p ${{ github.workspace }}/system_files/desktop/shared/usr/share/ublue-os/docs
curl -Lo ${{ github.workspace }}/system_files/desktop/shared/usr/share/ublue-os/docs/bazzite_docs.pdf https://ublue-os.github.io/bazzite/output.pdf
with:
github_token: ${{ github.token }}
output_dir: ${{ github.workspace }}/system_files/desktop/shared/usr/share/ublue-os/docs/html
upload_github_page: "false"
- name: Check just syntax
uses: ublue-os/just-action@v1

View File

@ -0,0 +1,87 @@
name: Build mkdocs
description: Parametrized mkdocs building
inputs:
github_token:
description: github token
required: true
site_url:
description: Set `MKDOCS_SITE_URL` env var
default: ""
required: true
working_dir:
description: Parent directory that contains mkdocs.yml
default: ${{ github.workspace }}/docs
output_dir:
description: Where we will output the resulting webpage
default: ${{ github.workspace }}/book
upload_github_page:
description: Upload github-page
default: "false"
repo_url:
description: URL of the repo
default: ${{ github.server_url }}/${{ github.repository }}
outputs:
artifact_id:
description: "Artifact id uploaded (is an empty string in case of `upload_github_page: false`)"
value: ${{ steps.upload-artifact.outputs.artifact_id }}
runs:
using: composite
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Poetry
uses: abatilo/actions-poetry@v2
- name: Configure Poetry
working-directory: ${{ inputs.working_dir }}
shell: bash
run: |
poetry config virtualenvs.create true --local
poetry config virtualenvs.in-project true --local
- name: Poetry install deps
shell: bash
working-directory: ${{ inputs.working_dir }}
run: poetry install
- name: Build book
shell: bash
working-directory: ${{ inputs.working_dir }}
env:
MKDOCS_SITE_URL: ${{ inputs.site_url }}
MKDOCS_REPO_URL: ${{ inputs.repo_url }}
_OUTPUT_DIR: ${{ inputs.output_dir }}
run: |
source .venv/bin/activate
mkdocs build --verbose -d $_OUTPUT_DIR
- name: Setup Pages
if: ${{ inputs.upload_github_page == 'true' }}
uses: actions/configure-pages@v4
with:
token: ${{ inputs.github_token }}
- name: Upload artifact
if: ${{ inputs.upload_github_page == 'true' }}
uses: actions/upload-pages-artifact@v3
id: upload-artifact
with:
path: ${{ inputs.output_dir }}
token: ${{ inputs.github_token }}
- name: Deploy to GitHub Pages
if: ${{ inputs.upload_github_page == 'true' }}
id: deployment
uses: actions/deploy-pages@v4
with:
token: ${{ inputs.github_token }}

View File

@ -14,11 +14,8 @@ on:
- docs/**/*.png
- docs/**/*.jpg
- docs/**/*.jpeg
- docs/**/*.po
- .github/workflows/deploy_docs.yml
- .github/workflows/install-mdbook/action.yml
- README*.md
- docs/book.toml
pull_request:
branches:
- main
@ -27,11 +24,8 @@ on:
- docs/**/*.png
- docs/**/*.jpg
- docs/**/*.jpeg
- docs/**/*.po
- .github/workflows/deploy_docs.yml
- .github/workflows/install-mdbook/action.yml
- README*.md
- docs/book.toml
workflow_dispatch:
concurrency:
@ -40,11 +34,9 @@ concurrency:
env:
runner: ubuntu-latest
cache-mdbook-name: cache-mdbook-bins
EXTRA_LANGUAGES:
SITE_URL: /bazzite/
MDBOOK_output__html__git_repository_url: "${{ github.server_url }}/${{ github.repository }}"
MDBOOK_output__html__edit_url_template: "${{ github.server_url }}/${{ github.repository }}/edit/${{ github.ref_name }}/docs/{path}"
cache-mkdocs-key: cache-mkdocs
SITE_SUFFIX: /bazzite/
REPO_URL: ${{ github.server_url }}/${{ github.repository }}
jobs:
deploy:
@ -65,93 +57,28 @@ jobs:
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install python dependencies
- name: Prepare env vars
run: |
pip install --user requests
- name: Cache mdbook
id: cache-mdbook
uses: actions/cache@v4
with:
path: |
~/.cargo/bin
~/.local/share/headless-chrome
key: ${{ runner.os }}-build-${{ env.cache-mdbook-name }}-${{ hashFiles('.github/workflows/install-mdbook/action.yml') }}
- name: Add mdbook to PATH
if: steps.cache-mdbook.outputs.cache-hit == 'true'
run: |
echo ~/.cargo/bin:$PATH >> $GITHUB_PATH
- name: Install mdbook
if: steps.cache-mdbook.outputs.cache-hit != 'true'
uses: ./.github/workflows/install-mdbook
_OWNER_NAME=${{ github.repository_owner }}
_OWNER_NAME=${_OWNER_NAME,,}
_SITE_PREFIX=${{ env.SITE_SUFFIX }}
_SITE_PREFIX=${_SITE_PREFIX#/}
echo "SITE_URL=https://${_OWNER_NAME}.github.io/$_SITE_PREFIX" >> $GITHUB_ENV
# Necessary in order to have fetch_discourse_md.py available for mdbook-cmd
- name: Add docs/utils to PATH
run: |
echo $PWD/utils:$PATH >> $GITHUB_PATH
- name: Test fetch_discourse_md.py
run: |
echo "::group::Try fetching a post from discourse"
fetch_discourse_md.py -d "https://universal-blue.discourse.group/docs?topic=31" 2>&1 >/dev/null
echo "::endgroup::"
- name: Build book in English
env:
MDBOOK_output__html__site_url: ${{ env.SITE_URL }}
DEBUG: "1"
run: |
# This assumes your book is in the root of your repository.
# Just add a `cd` here if you need to change to another directory.
mdbook build -d $GITHUB_WORKSPACE/book
(
cd $GITHUB_WORKSPACE/book
shopt -s dotglob
mv {html,pdf}/* ./
)
- name: Build all translations
env:
DEBUG: "1"
run: |
for po_lang in ${{ env.EXTRA_LANGUAGES }}; do
echo "::group::Building $po_lang translation"
MDBOOK_BOOK__LANGUAGE=$po_lang \
MDBOOK_OUTPUT__HTML__SITE_URL=${{ env.SITE_URL }}$po_lang/ \
mdbook build -d $GITHUB_WORKSPACE/book/$po_lang
(
cd $GITHUB_WORKSPACE/book/$po_lang
shopt -s dotglob
mv {html,pdf}/* ./
)
echo "::endgroup::"
done
- name: Generate translation progress report
if: env.EXTRA_LANGUAGES != ''
continue-on-error: true
run: |
i18n-report report $GITHUB_WORKSPACE/book/i18n_report.html po/*.po
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
- name: Build book
uses: ./.github/workflows/build_mkdocs
with:
path: ${{ github.workspace }}/book
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
with:
token: ${{ github.token }}
site_url: ${{ env.SITE_URL }}
repo_url: ${{ env.REPO_URL }}
working_dir: ${{ github.workspace }}/docs
output_dir: ${{ github.workspace }}/book
upload_github_page: "true"
github_token: ${{ github.token }}
clean_cache:
needs: deploy
@ -171,7 +98,7 @@ jobs:
set -x
old_caches=($(gh cache list \
--repo ${{ github.repository }} \
--key "${{ runner.os }}-build-${{ env.cache-mdbook-name }}-" \
--key "${{ runner.os }}-build-${{ env.cache-mkdocs-key }}-" \
--sort created_at -O asc --json id | jq '.[:-1][].id'))
for id in "${old_caches[@]}"; do
gh cache delete $id

View File

@ -1,32 +0,0 @@
name: Install mdbook and dependencies
description: Install mdbook with the dependencies we need.
runs:
using: composite
steps:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
# The --locked flag is important for reproducible builds. It also
# avoids breakage due to skews between mdbook and mdbook-svgbob.
- name: Install mdbook
run: cargo install --git https://github.com/HollowMan6/mdBook --rev b5ca7bc39ac2e8073dc2fb9d984c0e46c498c167 mdbook --locked
shell: bash
- name: Install mdbook-i18n-helpers
run: cargo install mdbook-i18n-helpers --locked --version 0.3.5
shell: bash
- name: Install i18n-report
run: cargo install i18n-report --locked --version 0.2.0
shell: bash
- name: Install mdbook-pdf
run: cargo install mdbook-pdf --locked --version 0.1.10 --features fetch
shell: bash
- name: Install mdbook-cmdrun
run: cargo install mdbook-cmdrun --locked --version 0.6.0
shell: bash

1
docs/.gitignore vendored
View File

@ -176,3 +176,4 @@ poetry.toml
pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python
*.code-workspace

View File

@ -1,4 +1,5 @@
export PATH := justfile_directory() + "/utils:" + env("PATH")
MKDOCS_DIR := justfile_directory()
_default:
just --list
@ -7,68 +8,9 @@ _default:
install_dependencies:
bash ./utils/install-deps.sh
_build_messages_pot:
#!/usr/bin/bash
DEBUG=1 ./utils/pre-build.py -s src -o src.tmp
MDBOOK_BOOK__SRC="src.tmp" \
MDBOOK_OUTPUT='{"xgettext": {}}' \
mdbook build -d po
rm -r src.tmp
mkdocs +ARGS="":
rm -rf {{ MKDOCS_DIR }}/.cache/cmdrun
poetry run mkdocs {{ ARGS }}
# Check that a translation file exists, otherwise exit with 1
_is_translation LANG:
[[ -f po/{{LANG}}.po ]] || { \
echo "ERROR: 'po/{{LANG}}.po' does not exist."; \
echo "Use 'just add_translation {{LANG}}' to create a new translation file"; \
exit 1; }
# Add a language to translate
add_translation LANG: _build_messages_pot
msginit -i po/messages.pot -l {{LANG}} -o po/{{LANG}}.po
# Flatten a directory containing multiple mdbook outputs
_flatten_outputs OUTPUTS_DIR="./book":
#!/usr/bin/bash
cd {{ OUTPUTS_DIR }}
to_flatten=( \
# Add here directories you want to flatten
$(ls -d "html" "pdf") \
) || true
for dir in "${to_flatten[@]}"; do
(
shopt -s dotglob
mv $dir/* ./
)
done
# Update a language with a fresh messages.pot
update_translation LANG: (_is_translation LANG) _build_messages_pot
msgmerge --update po/{{LANG}}.po po/messages.pot
# Equivalent to 'mdbook build'
mdbook_build LANG="":
#!/usr/bin/bash
mdbook clean
mdbook build -d ./book && just _flatten_outputs
if [[ -n "{{LANG}}" ]]; then
MDBOOK_BOOK__LANGUAGE={{LANG}} mdbook build -d book/{{LANG}} && \
just _flatten_outputs book/{{LANG}}
fi
_serve_http DIR="./book":
python -m http.server -d {{DIR}} -b 127.0.0.1 3000
# Start a lightweight web server with a preview of the mdbook
mdbook_serve LANG="":
#!/usr/bin/bash
set -meo pipefail
just mdbook_build {{LANG}}
just _serve_http &
sleep 1
printf '\n\n\n\n'
echo "Page ready at 'http://127.0.0.1:3000/{{LANG}}'"
fg
# Same as 'mdbook_serve' but for a specific language
preview_translation LANG: (_is_translation LANG)
just mdbook_serve {{LANG}}
mkdocs_clean:
rm -rf {{ MKDOCS_DIR }}/.cache

View File

@ -1,70 +1,58 @@
# Contributing to Bazzite mdBook documentation
# Contributing to Bazzite MkDocs documentation
## Introduction
This is a guide that will show you:
This is a guide that will show you how to write, or transcribe documentation from Discourse forums (https://universal-blue.discourse.group/) to MkDocs pages.
- How to write new documentation pages in mdBooks.
- How to transcribe documentation, from Discourse forums (https://universal-blue.discourse.group/) to mdBook pages.
## What is MkDocs
## Brief explanation in how to work with mdBook
> _mdBook is a command line tool to create books with Markdown. It is ideal for creating product or API documentation, tutorials, course materials or anything that requires a clean, easily navigable and customizable presentation_
> _MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. Documentation source files are written in Markdown, and configured with a single YAML configuration file._
>
> Source ~ https://rust-lang.github.io/mdBook/
> Source ~ https://www.mkdocs.org/
**TL;DR**: Its a fancy way tool that allows us to create a documentation website with basic [Markdown](https://commonmark.org/help/).
---
The essential part that cant be missing in a mdBook is the `mkdocs.yml` file.
The essential part that cant be missing in a mdBook is the `SUMMARY.md` file.
`mkdocs.yml` acts as our main configuration file. One of its main tasks is to configure the **Table of Contents** and to configure translation files.
```md
<!-- Example of SUMMARY.md contents -->
## Setup MkDocs tooling
# General
> ⚠️ WARNING ⚠️
>
> This step is **required** in order to setup previews of the resulting MkDocs
- [📜 Bazzite's README](Bazzite_README.md)
- [❓️ FAQ](General/FAQ.md)
- [📖 Installation Guide](General/Installation_Guide/index.md)
- [📝 Desktop Environment Tweaks](General/Desktop_Environment_Tweaks.md)
- [🤝 Contributing to Bazzite](General/Contributing_to_Bazzite.md)
- [🎲 Gaming](Gaming/index.md)
- [Game Launchers](Gaming/Game_Launchers.md)
To install our dependencies, run this:
# Steam Gaming Mode / Handheld & HTPC Hardware
- [📺️ Steam Gaming Mode Overview](Handheld_and_HTPC_edition/Steam_Gaming_Mode/index.md)
- [Change Physical Keyboard Layout for Steam Gaming Mode](Handheld_and_HTPC_edition/Change_Physical_Keyboard_Layout_for_Steam_Gaming_Mode.md)
```sh
bash docs/utils/install-deps.sh
```
`SUMMARY.md` acts not only as a nice looking table of contents, but as indexer as well.
<details>
<summary>
<big>Dependencies list</big><br>
<sup>Ignore if using install-deps.sh</sup>
</summary>
**If a page is not listed in `SUMMARY.md`, it wont be included in the mdBook**\*
- [Poetry](https://python-poetry.org/) (can be installed with Homebrew)
- [Just](https://just.systems/man/en/) (preinstalled in all [Universal Blue](https://universal-blue.org/) images)
<small>\* Just so you are aware </small>
</details>
---
You will need other tools as well, like:
## Transcribe Discourse docs to mdBooks
- A markdown compatible code editor (ex.: **Visual Studio Code**)
- **git** (comes preinstalled in most Linux distributions)
Requirements:
## Transcribe Discourse docs to MkDocs
- Markdown compatible code editor (ex.: Visual Studio Code)
- mdBook (can be installed with Homebrew\*)
- Git
<small>\* If you are using Bazzite or [similar](https://universal-blue.org/), chances are that you already have it installed.</small>
---
Best way to learn is with a real life example. We will transcribe https://universal-blue.discourse.group/docs?topic=2743
Best way to learn is with a real life example. We will transcribe <https://universal-blue.discourse.group/docs?topic=2657>, which at the time of writting is a post called _Managing and Modding Games_.
### 1. Basic preparation
We will start with getting our utilities ready:
1. A web browser with the Discourse doc page we want to transcribe. We will use <https://universal-blue.discourse.group/docs?topic=2743> for this example.
1. A web browser with the Discourse doc page we want to transcribe. We will use <https://universal-blue.discourse.group/docs?topic=2657> for this example.
2. Our code editor.
3. A terminal open in the `docs` directory
@ -87,7 +75,7 @@ We will start with getting our utilities ready:
2. In the terminal, pass the URL to `fetch_discourse_md.py`
```sh
$ ./utils/fetch_discourse_md.py "https://universal-blue.discourse.group/docs?topic=2743" | wl-copy
$ ./utils/fetch_discourse_md.py "https://universal-blue.discourse.group/docs?topic=2657" | wl-copy
```
Normally, `fetch_discourse_md.py` would dump the resulting markdown doc in the terminal output, with `wl-copy` we store it in our clipboard for now.
@ -109,129 +97,85 @@ We will start with getting our utilities ready:
We are almost done. The problem is `fetch_discourse_md.py` only will give us a dumped version of the Discourse document.
There is posibly URLs that are pointing to other documentation posts in Discourse that we might have already in our mdBook.
There is posibly URLs that are pointing to other documentation posts in Discourse that we might have already in our MkDocs.
![](./src/img/doc_guide_discourse_url.jpg)
The url in the image above is pointing to the _Steam Gaming Mode Overview (Handheld/HTPC)_ post.
At the time of writting this, we have that post avaliable in our mdBook, so we can simply replace that URL with ours
At the time of writting this, we have that post avaliable in our MkDocs, so we can simply replace that URL with ours
![](./src/img/doc_guide_rewrite_url.jpg)
In our case, the post is located in `../Handheld_and_HTPC_edition/Steam_Gaming_Mode/index.md`
### 6. Link back in `SUMMARY.md`
### 6. Add our page to navigation bar
We can check how our post looks in mdBook, run in the terminal
> [!TIP]
> You can skip this step if you dont need to show the page in the navigation bar
We can check how our post looks in MkDocs, run in the terminal
```sh
mdbook serve --open
just mkdocs serve
```
Now, more likely you wont find our new added post.
![](./src/img/doc_guide_where_did_go.jpg)
If you take a look at [the brief explanation](#brief-explanation-in-how-to-work-with-mdbook), you will read about `SUMMARY.md`. Files not listed in there wont be processed by mdBook.
If you take a look at [the brief explanation](#what-is-mkdocs), you will read about `mkdocs.yml`. Files not listed in there wont be added to the navigation bar, though still will be accessible with the search bar.
Lets add our file there.
Lets add our file there. Look for the `nav` field in there and add the new file as shown:
![](./src/img/doc_guide_add_summary.jpg)
And now our post is ready.
And now our post should be visible in the nav bar.
![](./src/img/doc_guide_there_you_are.jpg)
### 7. (Bonus) Set a proper page name
You can add more explicit page titles (used by the browser tab names) by using YAML metadata.
Adding this at the start of the markdown file would change the tab name to "Hello world":
```yaml
---
title: "Hello world"
---
```
## Translate documentation
> ⚠️ WARNING
>
> It is better to start translation once [transcription](#transcribe-discourse-docs-to-mdbooks) is settled to keep up.
> It is better to start translation once [transcription](#transcribe-discourse-docs-to-mkdocs) in a post is settled to keep up.
Translation isnt so straightforward as copying a markdown file and start working.
Translating documentation is as straightfoward as can be.
Lets say we want to translate `Homebrew.md` to Spanish. All what you would have to do is make a copy of the file with the name `Homebrew.es.md` and start translating.
We rely in [mdbook-i18n-helpers](https://github.com/google/mdbook-i18n-helpers) for translation, which uses [GNU Gettext](https://www.gnu.org/software/gettext/manual/html_node/index.html).
Perhaps you cant see your translation with `just mkdocs serve`.
Chances are we need to configure MkDocs to do so.
We need some more dependencies in order to do translations, which can be installed with this script:
Open `mkdocs.yml`, look for the field `languages`, should look something like this:
```sh
bash docs/utils/install-deps.sh
```yaml
languages:
- locale: en
default: true
name: English
build: true
```
<details>
<summary>
<big>Dependencies list</big><br>
<sup>Ignore if using install-deps.sh</sup>
</summary>
Add your language, in our case is Spanish:
- `.po` file editor (like [Poedit](https://flathub.org/apps/net.poedit.Poedit))
- Rust's `cargo` (you can install rust by running
`brew install rustup; rustup-init`)
- `mdbook-i18n-helpers` (after installing rust,
`cargo install mdbook-i18n-helpers`)
</details>
### 1. Basic preparation
Move to `docs`, then build the `.pot` file
```sh
cd docs
just build_messages_pot
```yaml
languages:
- locale: en
default: true
name: English
build: true
- locale: es
name: Spanish
build: true
```
This will create `po/messages.pot`, which acts as an index of text fragments
from all our markdown files.
### 2. (Optional) Add a new language
All translations files are stored in `docs/po/` in the form of `xx.po` files, `xx` referencing the language code following [ISO 639][ISO]. Per example, `es.po` would be an Spanish translation
file.
To add a new language to the documentation, follows these steps:
1. Get sure you did the [basic preparation](#1-basic-preparation-1)
2. Then run this, replacing `XX` with the [language code][ISO]:
```sh
just add_translation XX
```
In my case, I'm going to create an Spanish translation file:
```sh
just add_translation es
ls po/
# es.po messages.pot
```
### 3. Working with a translation file
![Poedit](./src/img/poedit.jpg)
We will now open that `.po` file with our po editor (in my case is Poedit).
We make some changes, hit <kbd>Ctrl</kbd>+<kbd>S</kbd> to save.
Lets see the changes we had done with a preview. Run this:
```sh
just preview_translation XX
```
In my case is `es`
```sh
just preview_translation es
```
And there it is!
![](./src/img/translation_example.jpg)
## Write new documentation
WIP
[ISO]: https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
And now MkDocs should show a language selector in the top bar.

View File

@ -1,42 +0,0 @@
[book]
authors = ["nicknamenamenick", "Zeglius"]
language = "en"
multilingual = false
src = "src"
title = "Bazzite Documentation"
[build]
use-default-preprocessors = false
create-missing = false
[preprocessor.links]
[output.html]
git-repository-url = "https://github.com/ublue-os/bazzite"
edit-url-template = "https://github.com/ublue-os/bazzite/edit/main/docs/{path}"
default-theme = "navy"
preferred-dark-theme = "navy"
additional-css = ["custom.css"]
[output.html.fold]
enable = true
[preprocessor.youtube-embed]
command = "python ./preprocessors/youtube-embed.py"
[preprocessor.replace-urls]
command = "python ./preprocessors/replace-urls.py"
after = ["youtube-embed", "links"]
ignore = ["Introduction*"]
[preprocessor.gettext]
after = ["links", "cmdrun"]
[preprocessor.cmdrun]
before = ["replace-urls"]
[output.pdf]
[preprocessor.replace-urls.mappings]
# Here we add urls to be overriden
"https://universal-blue.discourse.group/docs?topic=561" = "/Introduction"

View File

@ -1,8 +0,0 @@
h1.menu-title::before {
content: "";
background-image: url("./favicon.svg");
padding: 1em;
background-position: center center;
background-size: 1.5em;
background-repeat: no-repeat;
}

181
docs/hooks/cmdrun.py Normal file
View File

@ -0,0 +1,181 @@
import hashlib
import os
from pathlib import Path
import sys
from mkdocs.config.defaults import MkDocsConfig
from mkdocs import plugins
from mkdocs.structure.pages import Page
from mkdocs.structure.files import Files
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from copy import copy
import re
from fetch_discourse_md import fetch as fetch_md_discourse
########################### ONLY MODIFY THIS ###########################
URL_MAPPINGS = [
# region GENERAL
( # src/index.md
"https://universal-blue.discourse.group/docs?topic=561",
"/",
),
( # src/General/reporting_bugs.md
"https://universal-blue.discourse.group/docs?topic=3402",
"/General/reporting_bugs",
),
# region INSTALLATION GUIDE
( # src/General/Installation_Guide/Installing_Bazzite_for_HTPC_Setups.md
"https://universal-blue.discourse.group/docs?topic=1145",
"/General/Installation_Guide/Installing_Bazzite_for_HTPC_Setups/",
),
( # src/General/Installation_Guide/index.md
"https://universal-blue.discourse.group/docs?topic=35",
"/Installing_and_Managing_Software/",
),
( # src/General/Installation_Guide/dual_boot_setup_guide.md
"https://universal-blue.discourse.group/docs?topic=2743",
"/General/Installation_Guide/dual_boot_setup_guide/",
),
( # src/General/Installation_Guide/secure_boot.md
"https://universal-blue.discourse.group/docs?topic=2742",
"/General/Installation_Guide/secure_boot",
),
( # src/General/Installation_Guide/troubleshoot_guide.md
"https://universal-blue.discourse.group/docs?topic=2495",
"/General/Installation_Guide/troubleshoot_guide/",
),
# endregion INSTALLATION GUIDE
# endregion GENERAL
# region SOFTWARE
( # src/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/index.md
"https://universal-blue.discourse.group/docs?topic=36",
"/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/",
),
( # src/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/updating_guide.md
"https://universal-blue.discourse.group/docs?topic=2637",
"/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/updating_guide/",
),
( # src/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/rolling_back_system_updates.md
"https://universal-blue.discourse.group/docs?topic=2644",
"/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/rolling_back_system_updates/",
),
( # src/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/rebase_guide.md
"https://universal-blue.discourse.group/docs?topic=2646",
"/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/rebase_guide/",
),
( # src/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/bazzite_rollback_helper.md
"https://universal-blue.discourse.group/docs?topic=2647",
"/Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/bazzite_rollback_helper/",
),
# endregion SOFTWARE
( # src/Gaming/index.md
"https://universal-blue.discourse.group/docs?topic=31",
"/Gaming/",
),
# region HTPC
( # src/Handheld_and_HTPC_edition/Handheld_Wiki/index.md
"https://universal-blue.discourse.group/docs?topic=1038",
"/Handheld_and_HTPC_edition/Handheld_Wiki/",
),
( # src/Handheld_and_HTPC_edition/Handheld_Wiki/Steam_Deck.md
"https://universal-blue.discourse.group/docs?topic=1849",
"/Handheld_and_HTPC_edition/Handheld_Wiki/Steam_Deck/",
),
( # src/Handheld_and_HTPC_edition/Steam_Gaming_Mode.md
"https://universal-blue.discourse.group/docs?topic=37",
"/Handheld_and_HTPC_edition/Steam_Gaming_Mode/",
),
# endregion HTPC
# region ADVANCED
(
# src/Advanced/Auto-Mounting_Secondary_Drives.md
"https://universal-blue.discourse.group/docs?topic=970",
"/Advanced/Auto-Mounting_Secondary_Drives/",
),
# endregion ADVANCED
]
########################################################################
CMDRUN_PATTERN = r"<!--\s?cmdrun\s+fetch_discourse_md\.py\s+\"(.*)\"\s*-->"
PLUGIN_NAME = os.path.basename(__file__).rstrip(".py")
plugin_cache_dir: str
def _cache_filename_generator(text: str) -> str:
"""Generate a sha265 encoded cache file path of a piece of text inside the plugin cache dir"""
cache_file = os.path.join(
plugin_cache_dir, hashlib.sha256(text.encode()).hexdigest()
)
return cache_file
def _fetch_callback(url: str):
cache_file = _cache_filename_generator(url)
if os.path.exists(cache_file):
return Path(cache_file).read_text().strip()
elif content := fetch_md_discourse(url):
with open(cache_file, "w+t") as c_file:
c_file.write(content)
return content
else:
return ""
def _cmdrun_sub_handler(match: re.Match) -> str:
print(match.group(1))
url = match.group(1)
result = _fetch_callback(url)
return result or ""
def on_config(config: MkDocsConfig):
"""Initialize cache dir"""
global plugin_cache_dir
plugin_cache_dir = os.path.join(
os.path.dirname(config.config_file_path), ".cache", PLUGIN_NAME
)
try:
os.makedirs(plugin_cache_dir, exist_ok=True)
except FileExistsError:
pass
@plugins.event_priority(100)
def _on_page_markdown_fetch_discourse(markdown: str, **kargs):
markdown_orig = markdown
result = copy(markdown_orig)
try:
result = re.sub(CMDRUN_PATTERN, _cmdrun_sub_handler, markdown_orig)
except Exception as err:
print("ERROR", err)
return result
@plugins.event_priority(99)
def _on_page_markdown_replace_urls(
markdown: str,
page: Page,
config: MkDocsConfig,
files: Files,
**kargs,
):
"""Replace discourse urls"""
res = markdown
for src, dst in URL_MAPPINGS:
if config.site_url:
dst = f"{config.site_url.rstrip("/")}/{dst.lstrip("/")}"
res = res.replace(src, dst)
return res
on_page_markdown = plugins.CombinedEvent(
_on_page_markdown_fetch_discourse,
_on_page_markdown_replace_urls,
)

View File

@ -0,0 +1,28 @@
import re
from mkdocs import plugins
YOUTUBE_URL_PATTERN = r"(?<!<)https:\/\/(?:www\.youtube\.com\/watch\?v=|youtu\.be/)(?P<id>[a-zA-Z0-9_-]{11})"
def _generate_embed_from_id(
yt_id: str,
/,
*,
width: int = 560,
height: int = 315,
) -> str:
"""Generate a youtube embed from a video id"""
return f"""\
<iframe width="{width}" height="{height}" src="https://www.youtube.com/embed/{yt_id}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>"""
@plugins.event_priority(80)
def on_page_markdown(markdown: str, **kargs):
def resub_handler(match: re.Match) -> str:
id = match.group("id")
if id:
return _generate_embed_from_id(id)
return match.string
return re.sub(YOUTUBE_URL_PATTERN, resub_handler, markdown)

View File

@ -0,0 +1 @@
../utils/fetch_discourse_md.py

144
docs/mkdocs.yml Normal file
View File

@ -0,0 +1,144 @@
site_name: Bazzite Documentation
site_author: nicknamenamenick
site_url: !ENV MKDOCS_SITE_URL
repo_url: !ENV MKDOCS_REPO_URL
repo_name: !ENV GITHUB_REPOSITORY
site_description: Bazzite is a custom image built upon Fedora Atomic Desktops that brings the best of Linux gaming to all of your devices - including your favorite handheld.
validation:
links:
not_found: warn
absolute_links: relative_to_docs
anchors: warn
unrecognized_links: warn
extra_css:
- stylesheets/image_sizing.css
theme:
name: material
custom_dir: theme_overrides
palette:
- media: "(prefers-color-scheme)"
toggle:
icon: material/brightness-auto
name: Switch to light mode
- media: "(prefers-color-scheme: light)"
scheme: default
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
icon: material/brightness-4
name: Switch to system preference
favicon: img/favicon.svg
logo: img/logo_BW.svg
icon:
repo: fontawesome/brands/github
features:
- navigation.indexes
- navigation.sections
- navigation.tabs
# - navigation.instant # Incompatible with mkdocs_static_i18n
- toc.integrate
- search.suggest
- search.highlight
docs_dir: src
site_dir: book
hooks:
- hooks/cmdrun.py # 100-99
- hooks/embed_youtube.py # 80
plugins:
- privacy
- i18n:
languages:
- locale: en
default: true
name: English
build: true
- search
- git-revision-date-localized:
enable_creation_date: !ENV [CI, false]
fallback_to_build_date: true
- git-committers:
enabled: !ENV [CI, false]
token: !ENV ["GH_TOKEN"]
repository: !ENV GITHUB_REPOSITORY
branch: !ENV GITHUB_REF_NAME
- social
markdown_extensions:
- attr_list
- nl2br
- mdx_truly_sane_lists
- toc:
permalink: true
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.magiclink
nav:
- index.md
- General:
- "Bazzite's README": "Bazzite_README.md"
- "FAQ": "General/FAQ.md"
- "Installation Guide":
- General/Installation_Guide/index.md
- "Installing Bazzite for Desktop/Laptop Hardware": General/Installation_Guide/Installing_Bazzite_for_Desktop_or_Laptop_Hardware.md
- "Installing Bazzite for Framework Laptop 16": General/Installation_Guide/Installing_Bazzite_for_Framework_Laptop_16.md
- "Installing Bazzite for Framework Laptop 13 (AMD/Intel GPU)": General/Installation_Guide/Installing_Bazzite_Framework_Laptop_13.md
- "Installing Bazzite for Home Theater PC (HTPC) Setups": General/Installation_Guide/Installing_Bazzite_for_HTPC_Setups.md
- "Installing Bazzite on the Steam Deck": General/Installation_Guide/Installing_Bazzite_for_Steam_Deck.md
- "Installing Bazzite on Handheld PCs": General/Installation_Guide/Installing_Bazzite_for_Handheld_PCs.md
- "Installation Troubleshoot Guide": General/Installation_Guide/troubleshoot_guide.md
- "Secure Boot Instructions": General/Installation_Guide/secure_boot.md
- "Dual Boot Preliminary Setup and Post-Setup Guide": General/Installation_Guide/dual_boot_setup_guide.md
- "Gaming":
- Gaming/index.md
- "Game Launchers": Gaming/Game_Launchers.md
- "Managing & Modding Games": Gaming/Managing_and_modding_games.md
- "Common Gaming Issues": Gaming/Common_gaming_issues.md
- "Hardware Compatibility for Gaming": Gaming/Hardware_compatibility_for_gaming.md
- "Desktop Environment Tweaks": General/Desktop_Environment_Tweaks.md
- "Reporting Bugs": General/reporting_bugs.md
- Handheld & HTPC Hardware:
- "Steam Gaming Mode": Handheld_and_HTPC_edition/Steam_Gaming_Mode.md
- "Handheld Wiki":
- Handheld_and_HTPC_edition/Handheld_Wiki/index.md
- "Steam Deck": Handheld_and_HTPC_edition/Handheld_Wiki/Steam_Deck.md
- "Lenovo Legion Go": Handheld_and_HTPC_edition/Handheld_Wiki/Lenovo_Legion_Go.md
- "ASUS ROG Ally": Handheld_and_HTPC_edition/Handheld_Wiki/ASUS_ROG_Ally.md
- "Ayn Handhelds": Handheld_and_HTPC_edition/Handheld_Wiki/Ayn_Handhelds.md
- "GPD Handhelds": Handheld_and_HTPC_edition/Handheld_Wiki/GPD_Handhelds.md
- "Ayaneo Handhelds": Handheld_and_HTPC_edition/Handheld_Wiki/Ayaneo_Handhelds.md
- "Other Handhelds": Handheld_and_HTPC_edition/Handheld_Wiki/Other_Handhelds.md
- Software:
- "Installing and Managing Software":
- Installing_and_Managing_Software/index.md
- "Flatpak": Installing_and_Managing_Software/Flatpak.md
- "ujust": Installing_and_Managing_Software/ujust.md
- "Homebrew": Installing_and_Managing_Software/Homebrew.md
- "Distrobox": Installing_and_Managing_Software/Distrobox.md
- "Appimage": Installing_and_Managing_Software/AppImage.md
- "rpm-ostree": Installing_and_Managing_Software/rpm-ostree.md
- "Updates, Rollbacks, & Rebasing":
- "Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/index.md"
- "Updating Guide": "Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/updating_guide.md"
- "Rolling Back System Updates": "Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/rolling_back_system_updates.md"
- "Rebase Guide": "Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/rebase_guide.md"
- "Bazzite Rollback Helper": "Installing_and_Managing_Software/Updates_Rollbacks_&_Rebasing/bazzite_rollback_helper.md"
- "Waydroid Setup Guide": Installing_and_Managing_Software/Waydroid_Setup_Guide.md
- Advanced:
- "Auto-Mounting Secondary Drives": Advanced/Auto-Mounting_Secondary_Drives.md
- "Reset User Password": Advanced/Reset_User_Password.md
- "Creating A Custom Bazzite Image": Advanced/creating_custom_image.md
- "Contributing to Bazzite": General/Contributing_to_Bazzite.md

1143
docs/poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
__doc__ = """Example of a mdbook preprocessor"""
import datetime
import json
import os
import re
import sys
from typing import Any
_DEBUG = os.getenv("DEBUG", "")
def debug(*obj) -> Any:
return obj
if _DEBUG in ["1", "yes"]:
_DEBUG_OUTPUT = "./debug.txt"
if os.path.exists(_DEBUG_OUTPUT):
os.truncate(_DEBUG_OUTPUT, 0)
def debug(*obj) -> Any:
with open(_DEBUG_OUTPUT, "+a") as stdout:
print(f"DEBUG[{datetime.date.today()}]:", *obj, file=stdout)
return obj
def modify_content(content: str) -> str | None:
############## MODIFY 'content' HERE ##############
"""Alter the contents of each chapter
Args:
content (str): The contents of a chapter received. Is in markdown format.
Returns:
str | None: The chapter contents modified.
If `None`, the original content will be used instead
"""
author_template = "<div>" + r"""Publisher: \g<username>""" + "</div>"
author_pattern = r"\A(?P<username>\w+)\s\|\s(?P<date>(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2}))\s(?P<time>(?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})\s(?P<zone>\w+))\s\|\s#\d+"
if re.match(author_pattern, content, re.MULTILINE):
content = re.sub(author_pattern, author_template, content)
return content
###################################################
#
#
#
#
#
#
#
#
#
#
#
#
if __name__ == "__main__":
if len(sys.argv) > 1:
if sys.argv[1] == "supports":
sys.exit(0)
context, book = json.load(sys.stdin)
book: dict[str, list]
context: dict
debug(f"context: {context}")
sections = book["sections"]
for i, section in enumerate(sections):
section: dict
if not section.get("Chapter"):
continue
for chapter in section.values():
chapter: dict
debug(chapter)
content: str = chapter["content"]
if type(content) is str and (res := modify_content(content)):
content = res
chapter.update({"content": content})
debug(book)
print(json.dumps(book))

View File

@ -1,41 +0,0 @@
from collections import namedtuple
import os
from pathlib import Path, PurePath
import shlex
import subprocess
class Git:
"""Use git commands in mdbook preprocessors"""
def __init__(self, cwd: PurePath | str) -> None:
self._cwd = Path(cwd)
self._environ = os.environ.copy()
self._environ["LC_ALL"] = "C"
class CommandOutput(namedtuple("CommandOutput", ["stdout", "stderr"])):
def __str__(self) -> str:
return self.stdout
def _git(self, commands: list[str] | str) -> CommandOutput:
"""Run a git command
Args:
commands (list[str] | str): commands and args passed to git.
Returns:
CommandOutput: Tuple containing `stdout` and `stderr`
"""
if type(commands) is str:
commands = shlex.split(commands)
proc = subprocess.run(
["git", *commands],
capture_output=True,
text=True,
env=self._environ,
cwd=self._cwd,
)
return self.CommandOutput(stdout=proc.stdout, stderr=proc.stderr)
def log(self, *args: str) -> CommandOutput:
return self._git(["log", *args])

View File

@ -1,101 +0,0 @@
from typing import Any, Dict, List, Optional
class MdChapter:
def __init__(self, data: Dict[str, Any]):
self._data = data
@property
def name(self) -> str:
return self._data["name"]
@name.setter
def name(self, value: str):
self._data["name"] = value
@property
def content(self) -> str:
return self._data["content"]
@content.setter
def content(self, value: str):
self._data["content"] = value
@property
def number(self) -> List[int]:
return self._data["number"]
@number.setter
def number(self, value: List[int]):
self._data["number"] = value
@property
def sub_items(self) -> List[Any]:
return self._data["sub_items"]
@sub_items.setter
def sub_items(self, value: List[Any]):
self._data["sub_items"] = value
@property
def path(self) -> str:
return self._data["path"]
@path.setter
def path(self, value: str):
self._data["path"] = value
@property
def source_path(self) -> str:
return self._data["source_path"]
@source_path.setter
def source_path(self, value: str):
self._data["source_path"] = value
@property
def parent_names(self) -> List[Any]:
return self._data["parent_names"]
@parent_names.setter
def parent_names(self, value: List[Any]):
self._data["parent_names"] = value
class MdSection:
def __init__(self, data: Dict[str, Any]):
self._data = data
@property
def chapter(self) -> Optional[MdChapter]:
if "Chapter" in self._data:
return MdChapter(self._data["Chapter"])
return None
@property
def part_title(self) -> Optional[str]:
return self._data.get("PartTitle")
class MdBook:
def __init__(self, data: Dict[str, Any]):
self._data = data
@property
def sections(self) -> List[MdSection]:
return [MdSection(section) for section in self._data.get("sections", [])]
@sections.setter
def sections(self, value: List[Dict[str, Any]]):
self._data["sections"] = value
@property
def non_exhaustive(self) -> Any:
return self._data["__non_exhaustive"]
@non_exhaustive.setter
def non_exhaustive(self, value: Any):
self._data["__non_exhaustive"] = value
__all__ = ["MdBook", "MdChapter", "MdSection"]

View File

@ -1,69 +0,0 @@
import datetime
import os
from pathlib import Path
from typing import Any, Optional
# Example mdBook context
example_ctx = {
"root": "/var/home/zeglius/Documentos/Github/bazzite_mdbook/docs",
"config": {
"book": {
"authors": ["nicknamenamenick", "Zeglius"],
"language": "en",
"multilingual": False,
"src": "src",
"title": "Bazzite Documentation",
},
"build": {
"build-dir": "book",
"create-missing": False,
"extra-watch-dirs": [],
"use-default-preprocessors": False,
},
"output": {
"html": {
"edit-url-template": "https://github.com/ublue-os/bazzite/edit/main/docs/{path}",
"git-repository-url": "https://github.com/ublue-os/bazzite",
}
},
"preprocessor": {
"links": {},
"youtube-embed": {"command": "python ./preprocessors/youtube-embed.py"},
},
},
"renderer": "html",
"mdbook_version": "0.4.40",
}
class Utils:
@staticmethod
def get_config_from_ctx(preprocessor_name: str, ctx: dict) -> Optional[dict]:
"""Get the config from mdBook context
Returns:
"""
ctx.get("")
return ctx["config"]["preprocessor"][preprocessor_name]
####################### DEBUG UTILS #######################
_DEBUG = os.getenv("DEBUG", "")
_DEBUG_OUTPUT = Path("./debug.txt")
def debug(*obj: object):
"""Dump info into a debug.txt if env var DEBUG=1"""
if _DEBUG in ["1", "yes"]:
with open(_DEBUG_OUTPUT, "+a") as stdout:
print(f"DEBUG[{datetime.date.today()}]:", *obj, file=stdout)
###########################################################
__all__ = ["Utils", "debug"]

View File

@ -1,63 +0,0 @@
__doc__ = """Example of a mdbook preprocessor"""
import json
import sys
from libs.utils import debug
# TODO: This needs to be rewritten
def modify_content(content: str) -> str | None:
############## MODIFY 'content' HERE ##############
"""Alter the contents of each chapter
Args:
content (str): The contents of a chapter received. Is in markdown format.
Returns:
str | None: The chapter contents modified.
If `None`, the original content will be used instead
"""
return content
###################################################
#
#
#
#
#
#
#
#
#
#
#
#
if __name__ == "__main__":
if len(sys.argv) > 1:
if sys.argv[1] == "supports":
sys.exit(0)
context, book = json.load(sys.stdin)
book: dict[str, list]
context: dict
debug(f"context: {context}")
sections = book["sections"]
for i, section in enumerate(sections):
section: dict
if not section.get("Chapter"):
continue
for chapter in section.values():
chapter: dict
debug(chapter)
content: str = chapter["content"]
if type(content) is str and (res := modify_content(content)):
content = res
chapter.update({"content": content})
debug(book)
print(json.dumps(book))

View File

@ -1,109 +0,0 @@
__doc__ = """Replace urls across the entire book"""
import glob
import json
from pathlib import Path
import sys
from typing import List, cast
from urllib.parse import urljoin, urlparse
from libs.utils import debug as _debug
from libs.types import MdBook
PREPROCESSOR_NAME = "replace-urls"
def debug(*obj):
return _debug("REPLACE-URLS:", *obj)
_IGNORE_STRINGS = [
"before",
"after",
"command",
"renderers",
]
def is_url(url) -> bool:
res: bool = False
try:
tmp = urlparse(url)
res = tmp.netloc != "" and tmp.scheme != ""
except Exception as _:
res = False
return res
def main():
if len(sys.argv) > 1:
if sys.argv[1] == "supports":
sys.exit(0)
context, book = json.load(sys.stdin)
book = MdBook(book)
config = context["config"]["preprocessor"][PREPROCESSOR_NAME]
if not config:
print(json.dumps(book._data))
exit(0)
elif not isinstance(config, dict):
print(json.dumps(book._data))
exit(0)
book_src = cast(str, context["config"]["book"]["src"])
# Prefix to append to replaced urls if output.html.site-url is set and the replacement starts with `/`
try:
site_url_prefix = cast(str, context["config"]["output"]["html"]["site-url"])
except Exception as _:
site_url_prefix = ""
ignore_paths_list_globs = cast(list[str], list(config.get("ignore") or []))
ignore_paths: List[str] = list()
root_dir = Path(context["root"], book_src)
for p in ignore_paths_list_globs:
ignore_paths += glob.glob(p, root_dir=root_dir)
debug("My ignored paths:", ignore_paths)
config_mappings: dict = config["mappings"]
# Get the url mappings
# If replacement starts with `/`, prepend
url_mappings: list[tuple[str, str]] = [
(k, v)
for k, v in config_mappings.items()
if k not in _IGNORE_STRINGS and is_url(k)
]
# Replace the urls
# book_s = json.dumps(book)
# for mapp_old, map_new in url_mappings:
# book_s = book_s.replace(mapp_old, map_new)
for section in book.sections:
if not section.chapter:
debug("Section skipped, was parttitle:", section.part_title)
continue
debug("section.chapter.path =", section.chapter.path)
if section.chapter.path in ignore_paths:
debug("Section skipped, was in ignore_paths:", section.chapter.path)
continue
for old_url, new_url in url_mappings:
if new_url.startswith("/"):
new_url_aux = urljoin(site_url_prefix, new_url.lstrip("/"))
else:
new_url_aux = new_url
section.chapter.content = section.chapter.content.replace(
old_url, new_url_aux
)
print(json.dumps(book._data))
if __name__ == "__main__":
main()

View File

@ -1,52 +0,0 @@
__doc__ = """Transcribe youtube URLS into embededs iframes"""
import json
import re
import sys
from libs.utils import debug
######################## CONFIGURATION PARAMETERS ########################
YOUUTUBE_EMBED_WIDTH = 600
YOUUTUBE_EMBED_HEIGHT = YOUUTUBE_EMBED_WIDTH / (16 / 9)
##########################################################################
YOUTUBE_URL_PATTERN = r"^(?:\s|\t)*(?<!<)https:\/\/(?:www\.youtube\.com\/watch\?v=|youtu\.be\/(?!watch))(?P<id>[a-zA-Z0-9_-]{11})$"
YOUTUBE_EMBED_TEMPLATE = (
f"""<iframe width="{YOUUTUBE_EMBED_WIDTH}" height="{YOUUTUBE_EMBED_HEIGHT}" src="https://www.youtube-nocookie.com/embed/\\g<id>" """
+ """frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" """
+ """referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>"""
)
YOUTUBE_EMBED_TEMPLATE = f"<center>{YOUTUBE_EMBED_TEMPLATE}</center>"
if __name__ == "__main__":
if len(sys.argv) > 1:
if sys.argv[1] == "supports":
sys.exit(0)
context, book = json.load(sys.stdin)
book: dict[str, list]
context: dict
debug(f"context: {context}")
sections = book["sections"]
for i, section in enumerate(sections):
section: dict
if not section.get("Chapter"):
continue
for chapter in section.values():
chapter: dict
debug(chapter)
content: str = chapter["content"]
chapter.update(
{
"content": re.sub(
YOUTUBE_URL_PATTERN, YOUTUBE_EMBED_TEMPLATE, content
)
}
)
debug(book)
print(json.dumps(book))

22
docs/pyproject.toml Normal file
View File

@ -0,0 +1,22 @@
[tool.poetry]
name = "bazzite-docs"
version = "0.1.0"
description = ""
authors = ["Zeglius <33781398+Zeglius@users.noreply.github.com>"]
readme = "README.md"
package-mode = false
[tool.poetry.dependencies]
python = "^3.12"
mkdocs = "^1.6.0"
requests = "^2.32.3"
mkdocs-material = {extras = ["imaging"], version = "^9.5.33"}
mkdocs-static-i18n = {extras = ["material"], version = "^1.2.3"}
mdx-truly-sane-lists = "^1.3"
mkdocs-git-revision-date-localized-plugin = "^1.2.7"
mkdocs-git-committers-plugin-2 = "^2.3.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

View File

@ -1 +1,4 @@
---
title: Gaming
---
<!-- cmdrun fetch_discourse_md.py "https://universal-blue.discourse.group/docs?topic=31" -->

View File

@ -1,3 +1 @@
{{#title FAQ}}
<!-- cmdrun fetch_discourse_md.py "https://universal-blue.discourse.group/docs?topic=33" -->

View File

@ -1,3 +1,4 @@
{{#title Installation Guide}}
---
title: Installation Guide
---
<!-- cmdrun fetch_discourse_md.py "https://universal-blue.discourse.group/docs?topic=30" -->

View File

@ -1 +1,4 @@
---
title: Handheld Wiki
---
<!-- cmdrun fetch_discourse_md.py "https://universal-blue.discourse.group/docs?topic=1038" -->

View File

@ -1,3 +0,0 @@
{{#title Bazzite Documentation}}
{{#include SUMMARY.md}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

40
docs/src/img/logo_BW.svg Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="600"
height="600"
viewBox="0 0 600 600"
fill="none"
version="1.1"
id="svg6"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs6" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M 150,50 C 94.7715,50 50,94.7715 50,150 v 92 58 C 50,438.071 161.929,550 300,550 438.071,550 550,438.071 550,300 550,161.929 438.071,50 300,50 H 242 V 178 H 376.185 C 432.416,178 478,223.584 478,279.815 478,389.269 389.27,478 279.815,478 223.584,478 178,432.416 178,376.185 V 242 H 50 V 178 H 178 V 50 Z m 92,326.185 V 242 H 376.185 C 397.07,242 414,258.93 414,279.815 414,353.923 353.923,414 279.815,414 258.93,414 242,397.07 242,376.185 Z"
fill="#ffffff"
id="path1" />
<path
d="m 178,65 h -15 v 15 83 H 80 65 v 15 64 15 h 15 83 v 83 15 h 15 64 15 v -15 -83 h 83 15 V 242 178 163 H 340 257 V 80 65 h -15 z"
stroke="#ffffff"
stroke-width="30"
id="path2" />
<path
d="m 312.5,205.67 c 3.333,1.924 3.333,6.736 0,8.66 l -21,12.124 c -3.333,1.925 -7.5,-0.481 -7.5,-4.33 v -24.248 c 0,-3.849 4.167,-6.255 7.5,-4.33 z"
fill="#ffffff"
id="path3" />
<path
d="m 214.33,312.5 c -1.924,3.333 -6.736,3.333 -8.66,0 l -12.124,-21 c -1.925,-3.333 0.481,-7.5 4.33,-7.5 h 24.248 c 3.849,0 6.255,4.167 4.33,7.5 z"
fill="#ffffff"
id="path4" />
<path
d="m 205.67,107.5 c 1.924,-3.333 6.736,-3.333 8.66,0 l 12.124,21 c 1.925,3.333 -0.481,7.5 -4.33,7.5 h -24.248 c -3.849,0 -6.255,-4.167 -4.33,-7.5 z"
fill="#ffffff"
id="path5" />
<path
d="m 107.5,214.33 c -3.333,-1.924 -3.333,-6.736 0,-8.66 l 21,-12.124 c 3.333,-1.925 7.5,0.481 7.5,4.33 v 24.248 c 0,3.849 -4.167,6.255 -7.5,4.33 z"
fill="#ffffff"
id="path6" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,8 +1,7 @@
<div class="hidden">
[Introduction](Introduction.md)
</div>
---
hide:
- navigation
---
# Table of Contents
@ -32,7 +31,7 @@
# Handheld & HTPC Hardware
- [Steam Gaming Mode Overview](Handheld_and_HTPC_edition/Steam_Gaming_Mode/index.md)
- [Steam Gaming Mode Overview](Handheld_and_HTPC_edition/Steam_Gaming_Mode.md)
- [Handheld Wiki](Handheld_and_HTPC_edition/Handheld_Wiki/index.md)
- [Steam Deck](Handheld_and_HTPC_edition/Handheld_Wiki/Steam_Deck.md)
- [Lenovo Legion Go](Handheld_and_HTPC_edition/Handheld_Wiki/Lenovo_Legion_Go.md)

View File

@ -0,0 +1,3 @@
body > div.md-container > main > div > div.md-content > article img {
max-height: min(85vmax, 400px);
}

362
docs/theme/index.hbs vendored
View File

@ -1,362 +0,0 @@
<!DOCTYPE HTML>
<html lang="{{ language }}" class="{{ default_theme }}" dir="{{ text_direction }}">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>{{ title }}</title>
{{#if is_print }}
<meta name="robots" content="noindex">
{{/if}}
{{#if base_url}}
<base href="{{ base_url }}">
{{/if}}
<!-- Custom HTML head -->
{{> head}}
<meta name="description" content="{{ description }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
{{#if favicon_svg}}
<link rel="icon" href="{{ path_to_root }}favicon.svg">
{{/if}}
{{#if favicon_png}}
<link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
{{/if}}
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
{{#if print_enable}}
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
{{/if}}
<!-- Fonts -->
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
{{#if copy_fonts}}
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
{{/if}}
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
<!-- Custom theme stylesheets -->
{{#each additional_css}}
<link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
{{/each}}
{{#if mathjax_support}}
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
{{/if}}
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "{{ path_to_root }}";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('{{ default_theme }}')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
{{#toc}}{{/toc}}
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
{{> header}}
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
{{#if search_enabled}}
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
{{/if}}
</div>
<h1 class="menu-title">{{ book_title }}</h1>
<div class="right-buttons">
{{#if print_enable}}
<a href="{{ path_to_root }}output.pdf" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
{{/if}}
{{#if git_repository_url}}
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
</a>
{{/if}}
{{#if git_repository_edit_url}}
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
{{/if}}
</div>
</div>
{{#if search_enabled}}
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
{{/if}}
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<!-- ANCHOR: WARNING_UNSTABLE_DOC -->
{{!-- TODO: Remove me when documentation is all moved to mdBook --}}
<div class="warning">
<h2><b>⚠️ Warning ⚠️</b></h2>
<p>
This documentation is unstable<br>
Its possible that several pages are in need of being added.
Refer to <a href="https://universal-blue.discourse.group/docs?topic=561">Stable Bazzite Documentation</a>
</p>
</div>
<!-- ANCHOR_END: WARNING_UNSTABLE_DOC -->
{{{ content }}}
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
{{/previous}}
{{#next}}
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
{{#previous}}
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
{{/previous}}
{{#next}}
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
</nav>
</div>
{{#if live_reload_endpoint}}
<!-- Livereload script (if served using the cli tool) -->
<script>
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
{{/if}}
{{#if google_analytics}}
<!-- Google Analytics Tag -->
<script>
var localAddrs = ["localhost", "127.0.0.1", ""];
// make sure we don't activate google analytics if the developer is
// inspecting the book locally...
if (localAddrs.indexOf(document.location.hostname) === -1) {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '{{google_analytics}}', 'auto');
ga('send', 'pageview');
}
</script>
{{/if}}
{{#if playground_line_numbers}}
<script>
window.playground_line_numbers = true;
</script>
{{/if}}
{{#if playground_copyable}}
<script>
window.playground_copyable = true;
</script>
{{/if}}
{{#if playground_js}}
<script src="{{ path_to_root }}ace.js"></script>
<script src="{{ path_to_root }}editor.js"></script>
<script src="{{ path_to_root }}mode-rust.js"></script>
<script src="{{ path_to_root }}theme-dawn.js"></script>
<script src="{{ path_to_root }}theme-tomorrow_night.js"></script>
{{/if}}
{{#if search_js}}
<script src="{{ path_to_root }}elasticlunr.min.js"></script>
<script src="{{ path_to_root }}mark.min.js"></script>
<script src="{{ path_to_root }}searcher.js"></script>
{{/if}}
<script src="{{ path_to_root }}clipboard.min.js"></script>
<script src="{{ path_to_root }}highlight.js"></script>
<script src="{{ path_to_root }}book.js"></script>
<!-- Custom JS scripts -->
{{#each additional_js}}
<script src="{{ ../path_to_root }}{{this}}"></script>
{{/each}}
{{#if is_print}}
{{#if mathjax_support}}
<script>
window.addEventListener('load', function() {
MathJax.Hub.Register.StartupHook('End', function() {
window.setTimeout(window.print, 100);
});
});
</script>
{{else}}
<script>
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
{{/if}}
{{/if}}
</div>
</body>
</html>

View File

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block content %}
<blockquote style="border-left-color: orange;">
<big>⚠️ WARNING ⚠️</big>
<p>
This documentation in in development.
Its possible that several pages are in need of being added. Refer to <a href="https://universal-blue.discourse.group/docs?topic=561">Stable Bazzite Documentation</a>.
</p>
</blockquote>
{{ super() }}
{% endblock %}

View File

@ -94,7 +94,7 @@ import re
from string import Template
from sys import stdout, stderr
from time import sleep
from typing import NamedTuple, cast
from typing import NamedTuple
import requests
@ -230,6 +230,30 @@ def simple_replace_match(match: re.Match) -> str:
return ""
def fetch(url: str) -> str | None:
batch = DiscourseProcessor.transform_to_url_batch(url)
md_url = batch.raw_url
result = DiscourseProcessor.get_markdown_from_url(md_url)
# Replace images urls
result = re.sub(
DiscourseProcessor.Patterns.hashed_images_urls,
simple_replace_match,
result,
)
# Remove comments
result = DiscourseProcessor.Patterns.post_sep_markdown.split(result, 1)[0].rstrip()
# Add metadata
result = DiscourseProcessor.add_metadata_to_markdown(result, batch.source_url)
return result
def main():
argparser = ArgumentParser()
argparser.add_argument(
@ -250,20 +274,7 @@ def main():
global _is_debug
_is_debug = os.getenv("DEBUG") == "1" or args.debug
urls = cast(str, DiscourseProcessor.transform_to_url_batch(args.url).raw_url)
result = DiscourseProcessor.get_markdown_from_url(urls)
result = re.sub(
DiscourseProcessor.Patterns.hashed_images_urls,
simple_replace_match,
result,
)
# Remove comments
result = DiscourseProcessor.Patterns.post_sep_markdown.split(result, 1)[0].rstrip()
# Add metadata
result = DiscourseProcessor.add_metadata_to_markdown(result, urls)
result = fetch(args.url)
print(result, file=stdout)

View File

@ -1,43 +1,30 @@
#!/bin/env bash
REPO_DIR="$(git rev-parse --show-toplevel)"
function echod() { echo "[DEBUG]: $*"; }
if ! command -v brew >/dev/null; then
echod "[DEBUG]:This script needs 'brew' to run"
echod "This script needs 'brew' to run"
exit 1
fi
if ! command -v cargo >/dev/null; then
echod "Installing rust"
brew install rustup && rustup-init -y
if ! command -v poetry >/dev/null; then
echod "Installing Poetry"
brew install poetry
fi
if ! command -v just >/dev/null; then
echod "Installing just"
brew install just
fi
# Install mdbook and other
echod "Installing mdbook"
cargo install --git https://github.com/HollowMan6/mdBook --rev b5ca7bc39ac2e8073dc2fb9d984c0e46c498c167 mdbook --locked
cargo install mdbook-i18n-helpers --locked --version 0.3.5
cargo install i18n-report --locked --version 0.2.0
cargo install mdbook-pdf --locked --version 0.1.10 --features fetch
cargo install mdbook-cmdrun --locked --version 0.6.0
# Check if we are running Linux or MacOS, and install Poedit
os=$(uname -s)
case ${os,,} in
linux*)
set -x
flatpak install net.poedit.Poedit --system --noninteractive
sudo flatpak override --socket=wayland net.poedit.Poedit
set +x
;;
darwin*)
brew install --cask poedit
;;
*)
# Install poetry project
echod "Setting up poetry project"
(
cd "$REPO_DIR"/docs
mkdir -p .venv
poetry install
) || {
echod "Error setting up poetry project"
exit 1
;;
esac
}
echod "Dependencies installed succesfully"

View File

@ -2,7 +2,7 @@
Type=Application
NoDisplay=false
Terminal=false
Exec=xdg-open /usr/share/ublue-os/docs/bazzite_docs.pdf
Exec=/usr/share/ublue-os/docs/serve.sh
Icon=/usr/share/ublue-os/bazzite/docs.svg
Name=Documentation
Comment=View Bazzite Documentation

View File

@ -0,0 +1,16 @@
#!/usr/bin/bash
ADDRESS=127.0.0.1
PORT=1290
# Check if we are in an interactive bash session
if [[ $- == *i* ]]; then
set -m
fi
{ python -m http.server -b $ADDRESS $PORT -d "$(dirname "$0")"/html; } >/dev/null 2>&1 &
xdg-open "http://${ADDRESS}:${PORT}"
if [[ $- == *i* ]]; then
fg >/dev/null 2>&1 || true
fi