写了一部《周易》的读本,收工时是 72 卷、50.5 万字、A4 排版 704 页。到这一步,「它讲了什么」已经不是最难的问题,「别人怎么读到它」才是——在地铁上、在没网的地方、在手机上。
仓库:q1z2q3-debug/daokedao-yijing 在线阅读:q1z2q3-debug.github.io/daokedao-yijing
一个源,四件产物
规矩只有一条:HTML 是唯一成品,其余都从它派生。
| 产物 | 做法 | 体量 |
|---|---|---|
| 阅读页 | Markdown → pandoc → 单文件 HTML | 1.75 MB |
| 成书 PDF | Chromium 打印,分段后合并 | 29 MB/704 页 |
| 离线包 | 同一个 HTML 塞进 WebView 壳 | 3.0 MB APK |
| 检索站 | 由同一个 HTML 拆成 70 页 | 4.5 MB |
APK 不是第二套实现,它就是那个文件加字体内嵌。
第一步:让 HTML 真的能离线
原页面从 CDN 取字体,联网没事,飞行模式就是一片宋体缺失。构建时改成内嵌子集:
pyftsubset NotoSerifSC-Regular.otf \ --text-file=charset.txt \ --unicodes="U+4DC0-4DFF,U+2630-2640" \ --flavor=woff2 --layout-features='*' 两处值得抄:
- 字符集从正文里扫,不靠猜。 全书实际用字 3,100 个,两个字重压缩后约 2.5 MB;换成完整 CJK 字体就是 20 MB。
- 别漏符号区段。 卦符
䷀—䷿在 U+4DC0–U+4DFF,三爻符号☰—☷在 U+2630–U+2640,都不在 CJK 统一汉字区。按\u4e00-\u9fff取字集,这些字全变豆腐块。
结果:文件里外链清零,字体 base64 内嵌,1.75 MB,断网可开。
第二步:不上 Gradle 也能出 APK
环境里没有 Android Studio,而一个 WebView 壳本来也不需要它。六步:
aapt2 compile → res.zip aapt2 link → 资源 + R.java + assets + manifest javac → classes d8 → classes.dex zipalign → 4 字节对齐 apksigner → v1/v2/v3 两个坑:
-
platform-34_r03.zip是 404。build-tools_r34-linux.zip正常,配对的 platform 包已经下架;改用platform-35_r02.zip取android.jar,manifest 里targetSdk 34,没问题。 - 手机版式要用手机视口验,不是窄桌面窗口。 Chromium
--window-size=420不认<meta name="viewport">,页面按桌面宽度渲染,右边被裁掉——一个假溢出。Playwright 用is_mobile=True复核,scrollWidth == 390,其实一点没溢出。差点去改一段本来就对的 CSS。
manifest 里零权限,连 INTERNET 都没有:
<uses-permission android:name="android.permission.INTERNET" /> <!-- 删掉 --> 壳里再加 setBlockNetworkLoads(true),正文里就算混进一个 <img> 也发不出去。versionCode 15000 对应 1.50.0,下一版 15100,同一签名密钥可直接覆盖安装。
第三步:一本书拆成 70 页,因为单个大页面谁也搜不到
如果只发一个 1.75 MB 的整书页:只有一个 <title>、没有 description、没有 canonical,「未济卦 解读」这种长尾词一个也接不住。
于是站点构建按 <h1> 切分同一份 HTML,逐段套模板:
-
/p/64-weiji/—— 每卦一个目录,独立 canonical,描述取本段开头的卷眼(50–75 字) - 上一卦/下一卦链接,爬虫从任何一页都能走通全链
-
sitemap.xml(72 条)、robots.txt、llms.txt(给 AI 爬虫的纯文本摘要) - JSON-LD:每页
Article,首页Book+hasPart - 一张 1200×630 分享图,用 Pillow 确定性生成,不用手搓
生成器约 250 行 Python,一秒跑完:
python3 scripts/build-site.py # 70 页 + sitemap + robots + llms.txt 两条后见之明:
- 描述从正文取,不要拼标题。 第一版把标题、署名、首段拼在一起,产出
第 64 卦:未济。下 经|未济 润泽说易 到不了岸…这种垃圾;改取卷眼就干净了。 - 生成器要进仓库。 页面是构建产物,源一动,站点应该一条命令就重新正确,而不是一个手改过的 HTML 文件夹。
第四步:发版
GitHub 附件有几个脾气:
- 非 ASCII 文件名会被洗掉。
道可道-易传-1.50.0.apk传上去变成-.-1.50.0.apk。附件名一律 ASCII,中文标题放 release 正文。 - 上传要带
Accept: application/vnd.github+json,否则uploads.github.com回一个 HTML 400,什么也不说。 - 打
v*tag 的 workflow 会自动挂上 PDF、APK 与提示词 PDF,发版就是打一个 tag。
给同类项目的话
- 选一件产物当唯一真相,其余全部派生。书、PDF、APK 分开维护,两版之内必然打架。
- 字体子集从真实语料扫,符号区段单独补。
- 长文本要拆页、要有描述;一个巨页在搜索结果里等于不存在。
- 零权限是优点。一个连不上网的阅读器,也就泄不了任何东西——用户是看得见的。
书是 CC BY-NC-SA 4.0。APK 在 releases,3 MB,无权限,飞行模式可用。
做完之后再补一件事:让它能被引用
站点、PDF、APK 都是「给人看」的,但学术与档案场景要的是「能被引用」。所以这一版又加了两处:
- Zenodo 存档,DOI
10.5281/zenodo.24185930:成书 PDF、HTML、Markdown、提示词 PDF、APK 五件一并存缴,许可 CC BY-NC-SA 4.0,旧版 DOI 永不变更。 - HuggingFace 数据集
q1z2q3/daokedao-yijing:72 卷全文可直接做语料检索,卡片里带 DOI 回指。
站点也补了一页 /cite/,GB/T 7714、APA、BibTeX 三式直接粘。一句话:书要能被找到,也要能被署名引用。
润泽说易. 《润泽说 道可道之易传》: v1.50.0[M/OL]. 2026-11-13. https://doi.org/10.5281/zenodo.24185930

