feat: add --mobile flag for readable archives of legacy sites

Cloning a 1990s/2000s site like paulgraham.com and opening it in Kiwix
on a phone produces microscopic text: the pages use <font size="2">,
table layouts, and no viewport declaration, so the mobile browser shrinks
everything to desktop scale and then the font-size attribute makes it
smaller still.

kage clone --mobile injects two things into every saved page:

- <meta name="viewport" content="width=device-width, initial-scale=1">
  so the browser stops shrinking the page
- a <style> block that lifts the base font to 18px, inherits it through
  <font> elements (overriding the in-HTML size/face attributes), caps the
  content width at 720px, loosens line height to 1.7, and hides
  image-map nav elements whose source GIFs 404 offline

The style block goes last in <head> to win specificity ties, and
ensureViewport skips pages that already carry a viewport meta.

Two tests cover the happy path and the no-duplicate case.
This commit is contained in:
Duc-Tam Nguyen
2026-06-19 15:14:19 +07:00
parent 3117c4c55c
commit 060b4b6449
6 changed files with 129 additions and 10 deletions
+3 -2
View File
@@ -305,8 +305,9 @@ func (c *Cloner) processPage(ctx context.Context, j pageItem) {
asset.RewriteHTML(root, j.u, sink)
sanitize.CleanTree(root, sanitize.Options{
KeepNoscript: c.cfg.KeepNoscript,
Banner: "cloned by kage from " + j.u.String(),
KeepNoscript: c.cfg.KeepNoscript,
MobileReadable: c.cfg.MobileReadable,
Banner: "cloned by kage from " + j.u.String(),
})
var buf strings.Builder
+7 -6
View File
@@ -56,12 +56,13 @@ type Config struct {
ScopePrefix string
ExcludePaths []string
RespectRobots bool
FollowSitemap bool
Headless bool
KeepNoscript bool
ChromeBin string
ControlURL string
RespectRobots bool
FollowSitemap bool
Headless bool
KeepNoscript bool
MobileReadable bool
ChromeBin string
ControlURL string
// Resume loads the prior run's visited set and skips pages already written,
// so an interrupted or repeated clone picks up where it left off instead of