Repository navigation
feat: the HTML book installs and reads offline - #16
Merged
Merged
Conversation
Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Themes declare the strings under html-refs:, merged through extends like page:. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pillow becomes a direct dependency: the book needs it without the pdf extra. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No inline TOC, and page-floated notes end their chapter instead. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
render_book writes a static directory: the theme CSS filtered for a browser, font sizes as shares of the reader's size, images as WebP, and a reader that pages with CSS columns, swipes, keeps rectos in a spread, follows in-book links and remembers the place by block. examples/html-book builds it next to two PDFs. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A manifest and icons (from the cover, or the title's letter), and a service worker that precaches every file under a cache named by the book's path and the hash of its content. An open reader is told when a new edition arrives. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # docs/superpowers/plans/2026-10-20-html-book.html # scriptorium/cli.py # scriptorium/render.py
Each chapter is its own file and its own column strip. index.html carries the TOC, which chapter holds each id and each chapter's length; the reader loads the chapter it needs, counts the others' pages out of sight in idle time (cached per geometry, font size and edition), and estimates until then. Each section restarts the theme's CSS counters where the previous chapters left them. On an 861-page book at a phone size: ready in 0.44 s (0.70 s at CPU x4), a font change re-lays out in 28 ms (66 ms), crossing into a chapter takes 8-21 ms (35-110 ms), and all pages are counted 2.7 s (7.7 s) after opening. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # scriptorium/book.py
# Conflicts: # scriptorium/book.py # tests/test_reader_browser.py # themes/base/reader/reader.js
Every declared face loads before the first layout, and image boxes take the column width and the attributes' ratio instead of the loaded image's size. A chapter counted in the hidden strip before its image or face arrived got another page count than the one the stage showed. A browser test now delays images and fonts and checks the count holds. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chrome on CI sometimes ignored one update() right after the first install. Refs #13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 3 of 3 for #13, stacked on #15. Plan tasks 8-9.
What changed
book.py:make_icons()(the cover cropped from its top, or the title's first letter on the brand colour, plus a maskable icon),write_manifest()(start_urlandscope./, standalone, the book'slang),site_version()andwrite_service_worker(). The version is the first 12 hex digits of sha256 over every file butsw.js.themes/base/reader/sw.js: precaches every file of the book underbook:<path>:<version>and deletes only caches with its own path prefix. It answers navigations with the cached./and everything else from the cache.reader.js: registers the worker withupdateViaCache: 'none'and checks for updates when the tab becomes visible. On a new edition it shows a notice with an Update button that reloads at the same place. It also shows "✓ offline" once cached, an Install button onbeforeinstallprompt, and a hint on iOS.sw.jscaching, manifest MIME type, a Caddy example with exclusive matchers),know-how/the-html-book.md, AGENTS.md entries, CHANGELOG, and a "superseded" line on the 2026-08-14 spec and plan.Measured
tests/test_book_pwa.py(5):sw.jslists exactly the site's files plus./; two builds are byte-identical and changing one word changes the version; the manifest fields; a book with no cover and no images builds with letter icons./a/and/b/, updating/a/replaces its cache and leaves/b/'s.outputs:example loads as written.Fixes found on CI after #15 merged
registration.update()until the new edition lands: Chrome on the runner sometimes ignored a single call made right after the first install.know-how/the-html-book.mddescribes the per-chapter reader and its measurements.🤖 Generated with Claude Code