Tangled 使用 Pandoc 构建静态文档网站技术分析一、概述1. 背景Tangled 团队最近重新组织了文档，并将其发布到 https://docs.tangled.org，仅使用 Pandoc 工具实现。对于小型项目，使用 Pandoc 自建静态网站完全足够。2. 核心诉求A. 代码库集成文档必须存在于 monorepo 中B. 无 JavaScript 依赖纯文本页面不需要 JavaScript 即可浏览C. 可搜索性自带的搜索引擎效果较差，倾向于使用 Ctrl+F 或真实搜索引擎D. 低复杂度构建、测试、部署应当简单E. 易于样式化能够灵活定制外观二、生态系统评估1. 评估对象作者对多个文档引擎进行了评估：A. Mintlify特点：商业文档平台问题：官网显示正在进行 AI 转型，存在方向不明确的风险B. Docusaurus特点：生成精美的文档网站问题：将页面作为完整 React SPA 提供的价值存疑C. MkDocs优点：禁用 JS 后工作良好问题：需要通过 mkdocs.yml 维护目录结构，较为繁琐D. MdBook问题：需要 SUMMARY.md 文件控制目录2. 评估结论MkDocs 和 MdBook 仍在考虑范围内，以备将来需要更多功能时使用。三、Pandoc 方案1. Pandoc 介绍Pandoc 是一个高度可定制的标记转换工具，提供了 chunkedhtml 输出格式，非常适合生成文档网站。A. 默认特性基于文档布局自动生成目录（TOC）每个章节转换为独立页面2. 定制过程A. 合并文档将所有独立的 Markdown 文件合并为一个大的 DOCS.md 文件B. 模板修改修改默认模板，使 TOC 出现在每个页面上，形成侧边栏样式C. 样式统一插入 Tailwind prose 类，确保 Markdown 内容在 tangled.org 和 docs.tangled.org 之间渲染一致3. 生成命令pandoc docs/DOCS.md \ -o out/ \ -t chunkedhtml \ --variable toc \ --toc-depth=2 \ --css=docs/stylesheet.css \ --chunk-template="%i.html" \ --highlight-style=docs/highlight.theme \ --template=docs/template.html★ Insight ─────────────────────────────────────Pandoc 的 chunkedhtml 格式自动将单一大文档拆分为多个 HTML 页面，同时保持导航结构完整通过模板定制实现侧边栏 TOC，避免了复杂 JavaScript 代码的依赖─────────────────────────────────────────────────四、避免使用 JavaScript1. 移动端侧边栏侧边栏式目录需要在移动设备上折叠。大多数评估的文档引擎需要 JavaScript 来折叠和展开侧边栏，只有 MkDocs 使用 checkbox 的 :checked 伪类技巧来避免 JavaScript。2. 实现方案对比A. details/summary 方案优点：可实现折叠功能缺点：点击外部无法折叠，是明显的 hack 方案说明：Ctrl+F 或页面内查找仍然有效B. Popover API 方案（最终采用）优点：非常适合侧边栏组件实现：使用 HTML 原生 popover API触发按钮： Table of Contents 固定定位容器： Quick Start ... ... ... C. 方案特点TOC 可独立滚动点击侧边栏外部任何位置即可折叠页面内查找无法显示 popover 中的内容仅在小视口上可折叠，大视口上始终显示★ Insight ─────────────────────────────────────Popover API 是现代 HTML 原生功能，无需 JavaScript 即可实现复杂的交互效果通过 CSS 媒体查询实现响应式设计，小屏幕自动切换为折叠式侧边栏─────────────────────────────────────────────────五、搜索功能1. 搜索策略网站目前没有原生搜索功能。参考 htmx.org 的搜索栏，搜索栏直接重定向到 Google： ... 2. 单页版本考虑到 Ctrl+F 通常比 Docusaurus 提供的搜索引擎更好用，相同文档也导出为单页格式：pandoc docs/DOCS.md \ -o out/ \ --variable toc \ --toc-depth=2 \ --css=docs/stylesheet.css \ --highlight-style=docs/highlight.theme \ --template=docs/template.htmlA. 单页版本优势所有内容在一个页面上浏览器搜索功能可轻松遍历整个网站B. 未来考虑如果文档规模超出此方案支持范围，会考虑其他选项。六、构建与部署1. 技术栈Nix：包管理和构建工具Colmena：NixOS 部署工具2. Nix Derivation使用 runCommandLocal 辅助函数编写文档站点的 Nix derivation：runCommandLocal "docs" {} '' ... ${pandoc}/bin/pandoc ${src}/docs/DOCS.md ... ... ''3. Nginx 配置NixOS 机器配置为通过 nginx 提供站点：services.nginx = { enable = true; virtualHosts = { "docs.tangled.org" = { root = "${tangled-pkgs.docs}"; locations."/" = { tryFiles = "$uri $uri/ =404"; index = "index.html"; }; }; }; };4. 部署流程使用 Colmena 部署：nix run nixpkgs#colmena -- apply5. 更新流程更新站点时，首先运行：nix flake update tangled此命令会更新 tangled flake 输入，从而更新 tangled-pkgs.docs，然后通过 Colmena 应用更改。七、方案架构graph TB subgraph 源文件 A1[Markdown 文件] A2[样式表 CSS] A3[模板 HTML] A4[高亮主题] end subgraph Pandoc 构建 B1[合并文档] B2[chunkedhtml 输出] B3[TOC 生成] end subgraph 输出目录 C1[index.html] C2[页面 1.html] C3[页面 2.html] C4[单页版本.html] end subgraph NixOS 部署 D1[Nix Derivation] D2[Nginx 服务器] D3[Colmena 部署] end A1 --> B1 A2 --> B2 A3 --> B2 A4 --> B2 B1 --> B2 B2 --> B3 B2 --> C1 B2 --> C2 B2 --> C3 B2 --> C4 C1 --> D1 C2 --> D1 C3 --> D1 C4 --> D1 D1 --> D2 D2 --> D3八、工作流程图graph LR A[编写 Markdown] --> B[合并到 DOCS.md] B --> C[Pandoc 构建] C --> D[chunkedhtml 输出] C --> E[单页版本] D --> F[Nix 打包] E --> F F --> G[Colmena 部署] G --> H[Nginx 托管] H --> I[用户访问]★ Insight ─────────────────────────────────────Nix + Colmena 组合实现了声明式部署，确保构建环境可重现Pandoc 的多种输出格式能力允许同时生成分页和单页版本，满足不同使用场景─────────────────────────────────────────────────九、技术对比1. 方案对比表特性PandocDocusaurusMkDocsMdBook无 JS 依赖是否是是构建复杂度低高中中样式定制灵活有限中等中等目录维护自动自动mkdocs.ymlSUMMARY.md输出格式多种HTMLHTMLHTML学习曲线低高中中2. 核心差异A. JavaScript 依赖Pandoc/MkDocs/MdBook：支持无 JS 浏览Docusaurus：需要 React 运行时B. 目录结构Pandoc：基于 Markdown 标题自动生成其他：需要配置文件维护十、总结与展望1. 方案优势A. 简单性构建命令简洁部署流程清晰无需复杂依赖B. 灵活性模板可定制多种输出格式样式完全可控C. 性能静态 HTML无 JavaScript 开销浏览器缓存友好2. 当前局限A. 渲染差异Pandoc 的 Markdown 渲染与 Goldmark（Tangled 主站使用）仍存在一些差异B. 功能限制暂无原生搜索依赖外部搜索引擎3. 未来计划如果文档规模持续增长，可能会考虑：开发自己的 SSG（代号 TigerStyle）重新评估 MkDocs/MdBook参考资料we rolled our own documentation site - Tangled Blogdocs.tangled.orgPandoc - Universal markup converter