mirror of
https://github.com/Anon-Planet/thgtoa.git
synced 2026-05-06 19:44:19 +02:00
Compare commits
26 Commits
2ae582359b
...
v1.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
| f667d020d5 | |||
| d0dfec95db | |||
| 783f02f404 | |||
| 6c8dba5d5f | |||
| ee32450516 | |||
| c7452ea796 | |||
| 3621967517 | |||
| 88896a4f15 | |||
| 14de26d77d | |||
| 3b430dc96a | |||
| 565f3b8516 | |||
| fd60ef8460 | |||
| fb5e1fca74 | |||
| 02764539f2 | |||
| 2e0b7a9716 | |||
| 239d1c632f | |||
| c76ccd3e43 | |||
| 37068765cc | |||
| 2c3dea5f41 | |||
| d623dda610 | |||
| 8e386addb8 | |||
| 7b3599df63 | |||
| ac870b1497 | |||
| 88cee5a3c0 | |||
| 56678b3567 | |||
| 3b1c5946ae |
@@ -0,0 +1,55 @@
|
|||||||
|
name: 📖 Build PDF
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
- "mkdocs.yml"
|
||||||
|
- "scripts/build_guide_pdf.py"
|
||||||
|
- ".github/workflows/build-pdf.yml"
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
- "mkdocs.yml"
|
||||||
|
- "scripts/build_guide_pdf.py"
|
||||||
|
- ".github/workflows/build-pdf.yml"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pdf:
|
||||||
|
name: MkDocs + print to PDF
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
|
||||||
|
- name: Install MkDocs Material
|
||||||
|
run: pip install mkdocs-material
|
||||||
|
|
||||||
|
- name: Install Chromium
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends chromium
|
||||||
|
|
||||||
|
- name: Build PDF
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
run: python scripts/build_guide_pdf.py
|
||||||
|
|
||||||
|
- name: Upload PDF artifact
|
||||||
|
uses: actions/upload-artifact@v7
|
||||||
|
with:
|
||||||
|
name: guide-pdf
|
||||||
|
path: export/guide.pdf
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 90
|
||||||
+14
-122
@@ -1,130 +1,22 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
# Visual Studio (Windows) solution metadata
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Python (MkDocs, scripts/build_guide_pdf.py)
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
.venv/
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
.eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
wheels/
|
|
||||||
pip-wheel-metadata/
|
|
||||||
share/python-wheels/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
MANIFEST
|
|
||||||
|
|
||||||
# PyInstaller
|
|
||||||
# Usually these files are written by a python script from a template
|
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
||||||
*.manifest
|
|
||||||
*.spec
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.nox/
|
|
||||||
.coverage
|
|
||||||
.coverage.*
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
*.cover
|
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
|
||||||
.pytest_cache/
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
local_settings.py
|
|
||||||
db.sqlite3
|
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
|
||||||
instance/
|
|
||||||
.webassets-cache
|
|
||||||
|
|
||||||
# Scrapy stuff:
|
|
||||||
.scrapy
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# PyBuilder
|
|
||||||
target/
|
|
||||||
|
|
||||||
# Jupyter Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
# IPython
|
|
||||||
profile_default/
|
|
||||||
ipython_config.py
|
|
||||||
|
|
||||||
# pyenv
|
|
||||||
.python-version
|
|
||||||
|
|
||||||
# pipenv
|
|
||||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
||||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
||||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
||||||
# install all needed dependencies.
|
|
||||||
#Pipfile.lock
|
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
||||||
__pypackages__/
|
|
||||||
|
|
||||||
# Celery stuff
|
|
||||||
celerybeat-schedule
|
|
||||||
celerybeat.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
|
||||||
*.sage.py
|
|
||||||
|
|
||||||
# Environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
venv/
|
||||||
|
env/
|
||||||
ENV/
|
ENV/
|
||||||
env.bak/
|
.env
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
# Cache
|
||||||
.spyderproject
|
.cache/
|
||||||
.spyproject
|
|
||||||
|
|
||||||
# Rope project settings
|
# MkDocs build output and local PDF export
|
||||||
.ropeproject
|
site/
|
||||||
|
|
||||||
# mkdocs documentation
|
|
||||||
/site
|
|
||||||
_site/
|
_site/
|
||||||
|
_site_test/
|
||||||
# mypy
|
export/
|
||||||
.mypy_cache/
|
|
||||||
.dmypy.json
|
|
||||||
dmypy.json
|
|
||||||
|
|
||||||
# Pyre type checker
|
|
||||||
.pyre/
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.2.1] - 2026-04-11
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- GitHub Actions workflow **Build guide PDF** (`.github/workflows/build-pdf.yml`): installs Chromium on `ubuntu-latest`, runs `scripts/build_guide_pdf.py`, uploads `export/guide.pdf` as the `guide-pdf` artifact. Runs on `workflow_dispatch`, on pushes to `main` that touch docs or build inputs, and on matching pull requests.
|
||||||
|
|
||||||
|
- `scripts/build_guide_pdf.py` to build the MkDocs site and render the guide to a single PDF (`export/guide.pdf` by default) using a Chromium-based browser (Chrome or Edge) headless print-to-PDF.
|
||||||
|
- `docs/stylesheets/extra.css` and `extra_css` in `mkdocs.yml` for shared site styling.
|
||||||
|
- This `CHANGELOG.md`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `README.md` “Ways to read or export the guide”: hosted link, local `mkdocs serve`, PDF build via the script, ODT note, raw Markdown link.
|
||||||
|
- Guide landing layout: wrap the opening block in `docs/guide/index.md` with a `guide-intro-lead` container so the logo and first sections share one layout context for web and print.
|
||||||
|
- `.gitignore` to exclude local build outputs `export/`, `site/`, and `_site_test/`.
|
||||||
|
- `scripts/build_guide_pdf.py`: when the `CI` environment variable is set, pass Chromium flags (`--no-sandbox`, `--disable-setuid-sandbox`, `--disable-dev-shm-usage`) so headless print works on typical CI images.
|
||||||
|
- `README.md`: note the **Build guide PDF** GitHub Actions workflow and the `guide-pdf` artifact.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `docs/guide/index.md`: replace broken reference-style internal links (`[label][label:]`) with working same-page fragment links to the correct headings; correct the mismatched “Real-Name System” cross-reference; fix a broken footnote marker on the “free (unallocated) space of your hard drive” list item.
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/Anon-Planet/thgtoa/compare/v1.2.1...HEAD
|
||||||
|
[1.2.1]: https://github.com/Anon-Planet/thgtoa/releases/tag/v1.2.1
|
||||||
@@ -7,19 +7,29 @@ This is a maintained guide with the aim of providing an introduction to various
|
|||||||
This guide is an open-source non-profit initiative, [licensed](LICENSE.html) under **Creative Commons Attribution-NonCommercial 4.0 International** ([cc-by-nc-4.0](https://creativecommons.org/licenses/by-nc/4.0/) <sup>[[Archive.org]](https://web.archive.org/web/https://creativecommons.org/licenses/by-nc/4.0/)</sup>) and is **not sponsored/endorsed by any commercial/governmental entity**. This means that you are free to use our guide for pretty much any purpose **excluding commercially** as long as you do attribute it. There are no ads or any affiliate links.
|
This guide is an open-source non-profit initiative, [licensed](LICENSE.html) under **Creative Commons Attribution-NonCommercial 4.0 International** ([cc-by-nc-4.0](https://creativecommons.org/licenses/by-nc/4.0/) <sup>[[Archive.org]](https://web.archive.org/web/https://creativecommons.org/licenses/by-nc/4.0/)</sup>) and is **not sponsored/endorsed by any commercial/governmental entity**. This means that you are free to use our guide for pretty much any purpose **excluding commercially** as long as you do attribute it. There are no ads or any affiliate links.
|
||||||
|
|
||||||
**If you would like to make a donation to help this project, you can do so from [here](donations.html) where you will also find the project goals. All the donations will be strictly used within the context of this project. All donations and spendings are logged on the donations page.**
|
**If you would like to make a donation to help this project, you can do so from [here](donations.html) where you will also find the project goals. All the donations will be strictly used within the context of this project. All donations and spendings are logged on the donations page.**
|
||||||
<!--
|
|
||||||
**View the guide:**
|
|
||||||
- [In your browser](guide.html)
|
|
||||||
- [PDF](export/guide.pdf)
|
|
||||||
- [OpenDocument (ODT)](export/guide.odt)
|
|
||||||
- Raw [Markdown](https://raw.githubusercontent.com/Anon-Planet/thgtoa/main/guide.md). -->
|
|
||||||
|
|
||||||
<!-- Mirrors:
|
**Ways to read or export the guide**
|
||||||
- Tor Onion Mirror: <http://thgtoa3jzy3doku7hkna32htpghjijefscwvh4dyjgfydbbjkeiohgid.onion/> -->
|
|
||||||
|
- **In your browser:** [Hitchhiker's Guide](https://www.anonymousplanet.org/guide/) (hosted site). After a local build you can also open `site/guide/index.html` directly.
|
||||||
|
- **Local HTML preview:** from the repository root, with Python 3 and [MkDocs Material](https://squidfunk.github.io/mkdocs-material/getting-started/) installed (`pip install mkdocs-material`), run `mkdocs serve` and open the URL printed in the terminal (for example `http://127.0.0.1:8000`).
|
||||||
|
- **PDF (local build):** from the repository root, using the same environment, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/build_guide_pdf.py
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs `mkdocs build` (output defaults to `./site`), then uses **Google Chrome** or **Microsoft Edge** in headless mode to print `site/guide/index.html` to **`export/guide.pdf`** (images and styling preserved). If the site is already built: `python scripts/build_guide_pdf.py --skip-mkdocs`. Other options: `--site-dir`, `--pdf`, and `python scripts/build_guide_pdf.py --help`.
|
||||||
|
|
||||||
|
On **GitHub Actions**, the [Build guide PDF](https://github.com/Anon-Planet/thgtoa/actions/workflows/build-pdf.yml) workflow does the same using Chromium on Ubuntu when you push to `main` or open a pull request that touches the guide or build inputs; download the **`guide-pdf`** artifact from a successful run. You can also run it manually (**Actions** → **Build guide PDF** → **Run workflow**).
|
||||||
|
- **OpenDocument (ODT):** not produced by this repository (previous hosted export removed).
|
||||||
|
- **Raw Markdown (very large):** [docs/guide/index.md on GitHub](https://raw.githubusercontent.com/Anon-Planet/thgtoa/refs/heads/main/docs/guide/index.md)
|
||||||
|
|
||||||
|
**Mirrors:**
|
||||||
|
- <del>Hidden service: <http://thgtoa3jzy3doku7hkna32htpghjijefscwvh4dyjgfydbbjkeiohgid.onion/></del> **Host down**
|
||||||
|
|
||||||
Feel free to submit issues using Github Issues with the repository link above. Criticism, opinions, and ideas are welcome!
|
Feel free to submit issues using Github Issues with the repository link above. Criticism, opinions, and ideas are welcome!
|
||||||
|
|
||||||
Follow or contact us on:
|
**Follow or contact us on:**
|
||||||
|
|
||||||
Discussion Channels:
|
Discussion Channels:
|
||||||
- Matrix room: <https://matrix.to/#/#anonymity:anonymousplanet.net>
|
- Matrix room: <https://matrix.to/#/#anonymity:anonymousplanet.net>
|
||||||
|
|||||||
+2
-2
@@ -35,7 +35,7 @@ This guide is a non-profit open-source initiative, licensed under Creative Commo
|
|||||||
|
|
||||||
- For mirrors see [Mirrors](../mirrors/index.md) and the links at the bottom right of the page. You should see these on every page.
|
- For mirrors see [Mirrors](../mirrors/index.md) and the links at the bottom right of the page. You should see these on every page.
|
||||||
|
|
||||||
- For help in comparing versions see [Comparing versions](../guide/index.md#appendix-a7-comparing-versions)
|
- For help in comparing versions see [Comparing versions](../guide/index.md#appendix-a6-comparing-versions)
|
||||||
|
|
||||||
Feel free to submit issues **(please do report anything wrong)** using GitHub Issues at: <https://github.com/Anon-Planet/thgtoa/issues>. We also accept Merge Requests (MR) from our Gitlab and many other places. Do not hesitate to report issues and suggestions!
|
Feel free to submit issues **(please do report anything wrong)** using GitHub Issues at: <https://github.com/Anon-Planet/thgtoa/issues>. We also accept Merge Requests (MR) from our Gitlab and many other places. Do not hesitate to report issues and suggestions!
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ Feel free to submit issues **(please do report anything wrong)** using GitHub Is
|
|||||||
- Read [the rules](https://psa.anonymousplanet.org/), please
|
- Read [the rules](https://psa.anonymousplanet.org/), please
|
||||||
- Matrix Room: https://matrix.to/#/#nth:anonymousplanet.net
|
- Matrix Room: https://matrix.to/#/#nth:anonymousplanet.net
|
||||||
- Matrix Space: https://matrix.to/#/#psa:anonymousplanet.net
|
- Matrix Space: https://matrix.to/#/#psa:anonymousplanet.net
|
||||||
- @daskolburn:anonymousplanet.net and @nope:anonymousplanet.net are the only administrators
|
- Admins: @daskolburn:thomcat.rocks and @thehidden:tchncs.de
|
||||||
|
|
||||||
Follow us on:
|
Follow us on:
|
||||||
|
|
||||||
|
|||||||
+208
-200
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -25,7 +25,7 @@ Anonymous Planet is a collective of volunteers and contributors. No one person i
|
|||||||
|
|
||||||
- [:simple-github: GitHub](https://github.com/NobodySpecial256 "@NobodySpecial256")
|
- [:simple-github: GitHub](https://github.com/NobodySpecial256 "@NobodySpecial256")
|
||||||
- [:fontawesome-solid-envelope: E-mail](mailto:contact@anonymousplanet.org)
|
- [:fontawesome-solid-envelope: E-mail](mailto:contact@anonymousplanet.org)
|
||||||
- @daskolburn:thomcat.rocks, @daskolburn:anonymousplanet.net
|
- [:simple-matrix: Personal Matrix](https://matrix.to/#/@daskolburn:thomcat.rocks "@daskolburn:thomcat.rocks"), [:simple-matrix: Org Matrix](https://matrix.to/#/@daskolburn:anonymousplanet.net "@daskolburn:anonymousplanet.net")
|
||||||
|
|
||||||
??? person "Nope"
|
??? person "Nope"
|
||||||
|
|
||||||
@@ -33,4 +33,4 @@ Anonymous Planet is a collective of volunteers and contributors. No one person i
|
|||||||
- [:simple-mastodon: Mastodon](https://ioc.exchange/@unknown "@unknown@ioc.exchange"){rel=me}
|
- [:simple-mastodon: Mastodon](https://ioc.exchange/@unknown "@unknown@ioc.exchange"){rel=me}
|
||||||
- [:fontawesome-solid-house: Homepage](https://www.itsnothing.net)
|
- [:fontawesome-solid-house: Homepage](https://www.itsnothing.net)
|
||||||
- [:fontawesome-solid-envelope: E-mail](mailto:contact@anonymousplanet.org)
|
- [:fontawesome-solid-envelope: E-mail](mailto:contact@anonymousplanet.org)
|
||||||
- @nope:anonymousplanet.net
|
- [:simple-matrix: Personal Matrix](https://matrix.to/#/@thehidden:tchncs.de "@thehidden:tchncs.de"), [:simple-matrix: Org Matrix](https://matrix.to/#/@nope:anonymousplanet.net "@nope:anonymousplanet.net")
|
||||||
|
|||||||
@@ -20,12 +20,16 @@ schema:
|
|||||||
!!! Note "Where to find the Hitchhiker's Guide"
|
!!! Note "Where to find the Hitchhiker's Guide"
|
||||||
|
|
||||||
- [Original](https://anonymousplanet.org)
|
- [Original](https://anonymousplanet.org)
|
||||||
<!-- - (offline) [Tor Onion Mirror](http://thgtoa27ujspeqxasrfvcf5aozqdczvgmwgorrmblh6jn4nino3spcqd.onion) -->
|
- [Tor v3](http://thgtoa3jzy3doku7hkna32htpghjijefscwvh4dyjgfydbbjkeiohgid.onion) **Down**
|
||||||
- [Archive.org](https://web.archive.org/web/https://anonymousplanet.org)
|
- [Archive.org](https://web.archive.org/web/https://anonymousplanet.org)
|
||||||
- [Archive.today](https://archive.fo/anonymousplanet.org)
|
- [Archive.today](https://archive.fo/anonymousplanet.org)
|
||||||
- [Archive.today over Tor](http://archiveiya74codqgiixo33q62qlrqtkgmcitqx5u2oeqnmn5bpcbiyd.onion/anonymousplanet.org)
|
- [Archive.today over Tor](http://archiveiya74codqgiixo33q62qlrqtkgmcitqx5u2oeqnmn5bpcbiyd.onion/anonymousplanet.org)
|
||||||
<!-- - (n/a) [PDF](https://anonymousplanet.org/export/guide.pdf) <sup>[[Archive.org]](https://web.archive.org/web/https://anonymousplanet.org/export/guide.pdf)</sup> <sup>[[Tor Mirror]](http://thgtoa27ujspeqxasrfvcf5aozqdczvgmwgorrmblh6jn4nino3spcqd.onion/export/guide.pdf)</sup> -->
|
|
||||||
<!-- - (n/a) [ODT](https://anonymousplanet.org/export/guide.odt) <sup>[[Archive.org]](https://web.archive.org/web/https://anonymousplanet.org/export/guide.odt)</sup> <sup>[[Tor Mirror]](http://thgtoa27ujspeqxasrfvcf5aozqdczvgmwgorrmblh6jn4nino3spcqd.onion/export/guide.odt)</sup> -->
|
!!! Note "PDF export (single file)"
|
||||||
|
|
||||||
|
The guide is also available as a **PDF** (images and layout preserved). It is built automatically in GitHub Actions: open [**Build guide PDF**](https://github.com/Anon-Planet/thgtoa/actions/workflows/build-pdf.yml) on the [**thgtoa** source repository](https://github.com/Anon-Planet/thgtoa), pick a successful run, and download the **`guide-pdf`** artifact. You can start a fresh build anytime (**Actions** → **Build guide PDF** → **Run workflow**).
|
||||||
|
|
||||||
|
To produce the same file locally, clone the repository and run `python scripts/build_guide_pdf.py` (Python, [MkDocs Material](https://squidfunk.github.io/mkdocs-material/getting-started/), and **Google Chrome** or **Microsoft Edge** required). More detail is in the [repository README](https://github.com/Anon-Planet/thgtoa#ways-to-read-or-export-the-guide).
|
||||||
|
|
||||||
!!! Note "Our official git mirrors"
|
!!! Note "Our official git mirrors"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/* Title sheet: visible only when printing / generating PDF (not on screen). */
|
||||||
|
.pdf-title-page {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.pdf-title-page {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5rem 2rem 4rem;
|
||||||
|
page-break-after: always;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdf-title-page__title {
|
||||||
|
font-size: 1.65rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
margin: 0 0 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdf-title-page__subtitle {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdf-title-page__meta {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
font-style: normal;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Guide landing: small floating logo so opening copy flows beside it (HTML + PDF). */
|
||||||
|
.guide-intro-lead {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-intro-lead > p:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-intro-lead > p:first-child img {
|
||||||
|
float: right;
|
||||||
|
max-width: 6.5rem;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 0 0.5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.guide-intro-lead > p:first-child img {
|
||||||
|
max-width: 5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-6
@@ -52,14 +52,14 @@ plugins:
|
|||||||
# - git-authors: {}
|
# - git-authors: {}
|
||||||
# - git-latest-release: {}
|
# - git-latest-release: {}
|
||||||
|
|
||||||
|
extra_css:
|
||||||
|
- stylesheets/extra.css
|
||||||
|
|
||||||
extra:
|
extra:
|
||||||
social:
|
social:
|
||||||
- icon: simple/mastodon
|
- icon: simple/mastodon
|
||||||
link: https://mastodon.social/@anonymousplanet
|
link: https://mastodon.social/@anonymousplanet
|
||||||
name: Mastodon
|
name: Mastodon
|
||||||
# - icon: simple/matrix
|
|
||||||
# link: https://matrix.to/#/#p-s-a:matrix.org
|
|
||||||
# name: Matrix Space
|
|
||||||
- icon: simple/gitlab
|
- icon: simple/gitlab
|
||||||
link: http://wmj5kiic7b6kjplpbvwadnht2nh2qnkbnqtcv3dyvpqtz7ssbssftxid.onion/
|
link: http://wmj5kiic7b6kjplpbvwadnht2nh2qnkbnqtcv3dyvpqtz7ssbssftxid.onion/
|
||||||
name: "0xacab"
|
name: "0xacab"
|
||||||
@@ -75,9 +75,9 @@ extra:
|
|||||||
- icon: simple/codeberg
|
- icon: simple/codeberg
|
||||||
link: https://codeberg.org/anonymousplanet
|
link: https://codeberg.org/anonymousplanet
|
||||||
name: Codeberg
|
name: Codeberg
|
||||||
- icon: simple/torbrowser
|
# - icon: simple/torbrowser
|
||||||
link: http://thgtoa3jzy3doku7hkna32htpghjijefscwvh4dyjgfydbbjkeiohgid.onion/
|
# link: http://thgtoa3jzy3doku7hkna32htpghjijefscwvh4dyjgfydbbjkeiohgid.onion/
|
||||||
name: Hidden service
|
# name: Hidden service
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- pymdownx.highlight:
|
- pymdownx.highlight:
|
||||||
|
|||||||
@@ -21,4 +21,3 @@ Primary key fingerprint: 8B3A 7489 0536 BAD5 0D93 76EB F1CB 32F6 7E33 02A1
|
|||||||
## All signing keys are signed by the Master Signing Key
|
## All signing keys are signed by the Master Signing Key
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Build the MkDocs site, then render docs/guide/ to a single PDF via a Chromium-based browser.
|
||||||
|
|
||||||
|
Uses headless Chrome/Edge print-to-PDF (embeds images). WeasyPrint-based mkdocs-with-pdf is
|
||||||
|
omitted here because it needs GTK/Pango (awkward on Windows).
|
||||||
|
|
||||||
|
Usage (from repo root):
|
||||||
|
python scripts/build_guide_pdf.py
|
||||||
|
python scripts/build_guide_pdf.py --site-dir build/html --pdf export/guide.pdf
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def repo_root() -> Path:
|
||||||
|
return Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
def find_chromium_executable() -> Path | None:
|
||||||
|
if sys.platform == "win32":
|
||||||
|
paths = [
|
||||||
|
Path(os.environ.get("PROGRAMFILES(X86)", "")) / "Microsoft/Edge/Application/msedge.exe",
|
||||||
|
Path(os.environ.get("LOCALAPPDATA", "")) / "Microsoft/Edge/Application/msedge.exe",
|
||||||
|
Path(os.environ.get("PROGRAMFILES", "")) / "Google/Chrome/Application/chrome.exe",
|
||||||
|
Path(os.environ.get("PROGRAMFILES(X86)", "")) / "Google/Chrome/Application/chrome.exe",
|
||||||
|
Path(os.environ.get("LOCALAPPDATA", "")) / "Google/Chrome/Application/chrome.exe",
|
||||||
|
]
|
||||||
|
for p in paths:
|
||||||
|
if p.is_file():
|
||||||
|
return p
|
||||||
|
for name in ("chrome", "msedge"):
|
||||||
|
w = shutil.which(name)
|
||||||
|
if w:
|
||||||
|
return Path(w)
|
||||||
|
elif sys.platform == "darwin":
|
||||||
|
for p in (
|
||||||
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||||
|
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
||||||
|
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
||||||
|
):
|
||||||
|
if os.path.isfile(p):
|
||||||
|
return Path(p)
|
||||||
|
for name in ("google-chrome-stable", "google-chrome", "chromium-browser", "chromium", "chrome"):
|
||||||
|
w = shutil.which(name)
|
||||||
|
if w:
|
||||||
|
return Path(w)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def run_mkdocs(site_dir: Path) -> None:
|
||||||
|
site_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
subprocess.run(
|
||||||
|
[sys.executable, "-m", "mkdocs", "build", "-d", str(site_dir)],
|
||||||
|
cwd=repo_root(),
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def print_to_pdf(browser: Path, html_file: Path, pdf_out: Path) -> Path:
|
||||||
|
"""Write PDF to ``pdf_out``. Uses a temp file first so an open ``guide.pdf`` on Windows
|
||||||
|
does not block the build: if the final path is locked, writes ``guide-new.pdf`` instead.
|
||||||
|
"""
|
||||||
|
pdf_out.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
partial = pdf_out.parent / f".{pdf_out.name}.writing"
|
||||||
|
partial.unlink(missing_ok=True)
|
||||||
|
|
||||||
|
uri = html_file.resolve().as_uri()
|
||||||
|
# Chromium headless print; allow time for fonts/images on very large pages.
|
||||||
|
cmd = [str(browser)]
|
||||||
|
if os.environ.get("CI"):
|
||||||
|
# GitHub Actions / other CI runners often need these for Chromium to start.
|
||||||
|
cmd += [
|
||||||
|
"--no-sandbox",
|
||||||
|
"--disable-setuid-sandbox",
|
||||||
|
"--disable-dev-shm-usage",
|
||||||
|
]
|
||||||
|
cmd += [
|
||||||
|
"--headless=new",
|
||||||
|
"--disable-gpu",
|
||||||
|
"--no-pdf-header-footer",
|
||||||
|
f"--print-to-pdf={partial.resolve()}",
|
||||||
|
uri,
|
||||||
|
]
|
||||||
|
subprocess.run(cmd, check=True, timeout=600)
|
||||||
|
deadline = time.time() + 120
|
||||||
|
while time.time() < deadline:
|
||||||
|
if partial.exists() and partial.stat().st_size > 0:
|
||||||
|
break
|
||||||
|
time.sleep(0.25)
|
||||||
|
else:
|
||||||
|
partial.unlink(missing_ok=True)
|
||||||
|
raise RuntimeError(f"PDF was not written to {partial}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
if pdf_out.exists():
|
||||||
|
pdf_out.unlink()
|
||||||
|
except PermissionError:
|
||||||
|
fallback = pdf_out.with_name(f"{pdf_out.stem}-new{pdf_out.suffix}")
|
||||||
|
fallback.unlink(missing_ok=True)
|
||||||
|
partial.replace(fallback)
|
||||||
|
return fallback
|
||||||
|
|
||||||
|
partial.replace(pdf_out)
|
||||||
|
return pdf_out
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
root = repo_root()
|
||||||
|
ap = argparse.ArgumentParser(description="Build MkDocs + single-page guide PDF.")
|
||||||
|
ap.add_argument(
|
||||||
|
"--site-dir",
|
||||||
|
type=Path,
|
||||||
|
default=root / "site",
|
||||||
|
help="MkDocs output directory (default: ./site)",
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
"--pdf",
|
||||||
|
type=Path,
|
||||||
|
default=root / "export" / "guide.pdf",
|
||||||
|
help="Output PDF path (default: ./export/guide.pdf)",
|
||||||
|
)
|
||||||
|
ap.add_argument("--skip-mkdocs", action="store_true", help="Reuse existing site dir; only run print-to-pdf.")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
guide_html = args.site_dir / "guide" / "index.html"
|
||||||
|
if not args.skip_mkdocs:
|
||||||
|
run_mkdocs(args.site_dir)
|
||||||
|
if not guide_html.is_file():
|
||||||
|
print(f"Missing {guide_html}; run without --skip-mkdocs first.", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
browser = find_chromium_executable()
|
||||||
|
if not browser:
|
||||||
|
print(
|
||||||
|
"No Chromium-based browser found (Chrome, Edge, or Chromium). "
|
||||||
|
"Install Google Chrome or Microsoft Edge, or add Chromium to PATH.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
out = print_to_pdf(browser, guide_html, args.pdf)
|
||||||
|
size_kb = out.stat().st_size // 1024
|
||||||
|
print(f"Wrote {out.resolve()} ({size_kb} KiB)")
|
||||||
|
if out.resolve() != args.pdf.resolve():
|
||||||
|
print(
|
||||||
|
f"Note: {args.pdf.name} was in use; close it and rename or replace with the file above.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user