.epub format.
|
|
||
|---|---|---|
| .forgejo/workflows | feat: add EPUB validation with epubcheck | |
| epubs | feat: flatten TOC and add kindlegen validation | |
| src | feat: flatten TOC and add kindlegen validation | |
| .gitignore | feat: add ziglang-docs-epub tool | |
| build.zig | feat: add ziglang-docs-epub tool | |
| build.zig.zon | feat: add ziglang-docs-epub tool | |
| LICENSE | feat: add ziglang-docs-epub tool | |
| README.md | feat: add EPUB validation with epubcheck | |
| validate.sh | feat: flatten TOC and add kindlegen validation | |
ziglang-docs-epub
Turns the Zig language reference into an
EPUB, one per Zig version. CI runs it on a schedule and commits the resulting
.epub files back into epubs/.
Why
The reference ships as a single self-contained HTML page. This tool repackages it as a standards-compliant EPUB3 so you can read it offline in any e-reader.
How it works
Four decoupled concerns, each a small module that does one thing:
| Module | Responsibility |
|---|---|
index.zig |
discover versions + docs URLs from download/index.json |
fetch.zig |
HTTP GET via std.http.Client |
html.zig |
HTML5 → XHTML5; extract the in-page TOC; drop the sidebar |
epub.zig |
assemble the EPUB3 container (TOC navigation + content) |
zip.zig |
minimal, reproducible ZIP writer (stored entries) |
No external runtime dependencies — Zig's standard library provides HTTP and CRC32. EPUB entries are stored uncompressed (Zig 0.15.2's std deflate compressor is unfinished), which keeps the writer trivial and fully spec-compliant at the cost of larger files. Output is byte-for-byte reproducible (fixed ZIP timestamps), so CI only commits when the upstream docs actually change.
Table of contents
The docs page renders its table of contents in a position: fixed sidebar, which
e-readers repaint on every page. The tool extracts that TOC into a proper EPUB3
navigation document (nav.xhtml): it shows in the reader's built-in Contents
menu, is the book's opening page, and each entry jumps to the matching section.
The original fixed sidebar (and its dead version-switcher dropdown) is removed
from the content so it no longer bleeds across pages.
Well-formedness gate
Each transformed page is checked for well-formed, balanced XHTML before
packaging; versions that fail are skipped (logged as NotWellFormed) rather
than shipped as invalid EPUB3. A handful of older docs pages (currently 0.1.1–0.8.1
and 0.10.x) contain malformed upstream HTML — unclosed <p>/<li> tags and
outright typos — that can't be repaired without a full HTML5 tree-builder. Every
EPUB this tool produces is therefore strictly well-formed; newer versions are
picked up automatically as they are released.
Usage
Requires Zig 0.15.2.
zig build run # build every version that has docs
zig build run -- 0.15.2 # build only specific version(s)
zig build test # run unit tests
EPUBs land in epubs/zig-<version>.epub.
Validating output
The tool guarantees well-formed XHTML, but full EPUB3 conformance (the kind of thing Kindle's "Send to Kindle" enforces) is checked with epubcheck, the official validator:
brew install epubcheck # one-time (needs a JRE)
./validate.sh # runs epubcheck on every epub; non-zero exit on errors
validate.sh fails loudly if any EPUB has errors, so it doubles as a CI gate.
Continuous integration
.forgejo/workflows/build-epubs.yml runs on Codeberg
(Forgejo Actions): daily, on push to main, and on manual dispatch. It installs
Zig, runs the tool, and commits any changed EPUBs with [skip ci].
License
Licensed under the Apache License 2.0.