WSA(7)
NAME
wsa - 本站现在是一套专用出版系统
SYNOPSIS
旧的 WSA 是 Markdown、Pandoc、模板、Makefile、RSS 脚本、Nginx 和 rsync。
新的 WSA 更窄。
Markdown 仍然是源头,但构建过程已经收束到一个 Rust 生成器里。
DESCRIPTION
这个项目现在不是通用静态站点生成器。
它只服务 thinker。
这很重要。
因为当一个系统只服务一个站点,它就不需要假装可以服务所有人。
它不需要主题,不需要插件,不需要配置文件,也不需要运行时行为。
它只需要把文章稳定地变成网页。
于是现在的架构变成这样:
posts/*.md
-> Rust generator
-> public/*.html
-> public/feed.xml
-> rsync
-> /var/www/thinker
读者最终看到的是静态文件。
没有客户端 JavaScript。
没有数据库。
没有服务端应用。
没有远程字体、远程图片、统计脚本或额外运行时。
复杂度没有消失。
只是被关在作者侧和构建侧。
CONTENT
文章仍然放在 posts/。
文件名的前十个字符是日期。
第一个一级标题是标题。
正文使用保守的 Markdown。
这条路径非常朴素:
posts/2026-05-13-WSA.md
比起以前依赖 Pandoc 的转换,现在文章由 pulldown-cmark 解析。
支持的语法也被限制在足够清楚的范围内。
标题、段落、列表、引用、代码块、表格、脚注、删除线和 task list。
如果一个 Markdown 结构不能让文档更像文档,就不应该使用它。
GENERATOR
生成器在 src/。
入口是 src/main.rs。
构建流程在 src/site.rs。
文章读取和 Markdown 渲染在 src/post.rs。
HTML 页面在 src/html.rs。
RSS 在 src/feed.rs。
RSS 日期格式在 src/time.rs。
这些文件没有试图抽象成框架。
它们更像一个窄工具。
main 接受 build 命令。
site 清理并重建 public/。
post 从文件名取 slug 和日期,从正文取标题,再把 Markdown 转成 HTML。
html 生成首页和文章页。
feed 生成 feed.xml。
time 只负责 RSS 需要的 RFC822 日期。
OUTPUT
public/ 是生成结果。
它不应该成为人工编辑的地方。
生成结果包含:
index.html- 每篇文章的 HTML
feed.xmlstyle.css- 本地
assets/
CSS 也很窄。
它使用 monospace 字体、有限宽度、清楚的标题层级和适合打印的样式。
视觉方向接近本地 manual page,而不是现代博客主题。
不是为了复古。
是为了耐久。
BUILD
本地构建入口仍然是 make。
但 make 现在只是外层门面。
真正的构建命令是:
cargo run --quiet --locked -- build
检查命令是:
make check
它会执行四件事:
- 检查 Rust 格式
- 重新生成站点
- 用 Python 校验
feed.xml - 检查生成 HTML 中不能出现
<script
这条检查很粗糙。
但它表达了本站的基本态度。
网页应该安静。
SERVER
服务器侧反而变得更简单。
它只需要托管 public/。
生产路径是:
/var/www/thinker
Nginx 或任何静态文件服务器都可以完成这件事。
服务器不理解文章。
服务器也不负责构建。
它只是发送文件。
CI/CD
GitHub Actions 现在是构建和部署边界。
Pull Request 只运行检查。
推送到 main 后才部署。
部署仍然通过 rsync。
这点没有变。
变化在于部署的对象不再是松散脚本临时产生的页面,而是经过 Rust 生成器和 make check 约束后的 public/。
旧的架构更像一组可以工作的小工具。
新的架构更像一条窄轨道。
它没有变得宏大。
它只是减少了含糊。
NOTES
这个项目现在最核心的约束是:
复杂度属于作者和构建过程;读者只接收安静的静态文档。
我越来越喜欢这种边界。
因为边界清楚,系统就不需要解释太多。
作者写 Markdown。
生成器生成 HTML 和 RSS。
CI 检查结果。
服务器发送文件。
读者阅读文档。
这已经足够。