Typst 文档排版渲染架构
Typst 是面向学术文档(论文、学位论文、课堂讲义、试卷和行政公文)的标记语言排版系统。它以快速的增量构建编译为 PDF,内置脚本语言和包生态系统,是机构文档生产中 LaTeX 的现代替代方案。
openEduSuite 将 Typst 作为一等公民套件服务交付:上游跟踪的 fork、多架构容器镜像、HTTP 渲染 API,以及面向 Kubernetes(高等教育)与 Docker Compose(SME)两种技术栈的部署接线。
Fork 与上游策略
套件使用 tobias-weiss-ai-xr/typst——上游 typst/typst 的 fork:
- 每周同步:定时工作流将上游
main合并进 fork;合并冲突会显式失败,需人工解决。 - Fork 专属代码仅位于
render-service/与.github/workflows/,确保上游合并零冲突。 - 发布版本跟随上游版本号(
v0.15.1),每次同步后重置。每个 GitHub release 发布两个多架构镜像(linux/amd64 + arm64):ghcr.io/tobias-weiss-ai-xr/typst—— 原生 typst CLIghcr.io/tobias-weiss-ai-xr/typst-render—— 渲染服务(CLI + HTTP API + Liberation 字体)
渲染服务
渲染服务是围绕 typst CLI 的极简 HTTP 封装(仅依赖 Python 标准库):
POST /render {"source": "= 你好", "format": "pdf|png|svg",
"assets": {"data.csv": "..."}} -> 文档字节
GET /healthz -> {"status": "ok", "typst": "typst 0.15.1 ..."}
进程内强制执行的信任边界:
- 请求体大小限制(5 MB 请求、2 MB 源码)与单次编译超时(60 秒)。
- 资源名仅允许扁平的
[A-Za-z0-9._-]标识符——无路径穿越。 - 编译在隔离的临时目录中进行,并以
--root限定根目录;typst CLI 不发起任何网络访问。 - 编译并发有上限(默认 4),保护集群节点免受 CPU 饱和影响。
- 服务在容器内以非特权用户(UID 1000)运行。
镜像内置 Liberation 字体,覆盖大多数机构文档模板所需的 Arial/Times/Courier 度量兼容字体族。
部署
| 技术栈 | 接线方式 |
|---|---|
| Kubernetes(高等教育) | openEDU-hrz 部署仓库中的 typst-render Helmfile chart,按 release tag 锁定 |
| Docker Compose(SME) | openSME-compose 中的 typst-render 服务 profile |
两种部署均通过内部网络路径暴露服务,使用基于 /healthz 的存活探针,并按 release tag 锁定镜像——与套件中所有其他服务保持相同的纪律。该服务面向机器调用(模板流水线、管理工具、门户后端),不应直接暴露给最终用户浏览器。
集成边界
Typst 是套件中协作编辑器(Collabora、CryptPad、HedgeDoc)的补充而非替代:它们覆盖交互式协同编辑,Typst 覆盖确定性的、模板驱动的生产级排版——例如从模板仓库渲染试卷、批量生成证书,或根据登记数据批量生成公文。