站点维护指南¶
一、这是什么形态¶
一套静态网站(MkDocs + Material 主题)。构建产物是纯 HTML / CSS / JS / 图片:
- 不需要数据库
- 不需要常驻的 Node / Python 服务
- 扔到任意静态服务器(Nginx / IIS /
python -m http.server)就能跑 - 打包成 zip 发给同事,解压双击
index.html也能看
为什么不用 CHM
详见知识库页《操作手册合集-交付格式选型(CHM评估)》。一句话: CHM 是 Windows 专属,且从网络/邮件拿到的 CHM 会被 Windows 标记「来自 Internet」 而拒绝打开,需要手动解除锁定——分享给非技术同事基本等于发不出去。
二、目录结构¶
操作手册站点/
├─ mkdocs.yml ← 站点配置(由脚本生成,勿手改)
├─ docs/
│ ├─ zh/ ← 中文站(默认语言,构建到 site/ 根)
│ │ ├─ index.md 首页
│ │ ├─ guide.md 本页
│ │ ├─ manual/ 官方手册中文层
│ │ │ ├─ index.md 手册导读与目录总览
│ │ │ ├─ _comm/ ★ 13 章中文导读(与英文侧同路径)
│ │ │ └─ <同英文路径>.md 样章译文(4 页)
│ │ ├─ assets/img/ 中文页引用的插图
│ │ ├─ handbook/ 我的操作手册合集
│ │ └─ kb/ 知识沉淀
│ └─ en/ ← 英文站(构建到 site/en/)
│ ├─ index.md
│ ├─ scope.md
│ ├─ manual/ ★ 官方手册全 13 章 / 2145 页正文
│ └─ assets/img/ 2083 张插图(约 37 MB)
├─ tools/ ← 构建脚本
│ ├─ 01_build_toc.py 解析官方目录树
│ ├─ 02_extract_pages.py 逐页提取(带图带链接)
│ ├─ 03_build_mkdocs.py 生成 mkdocs.yml
│ ├─ 04_build_zh_docs.py 生成中文侧清单页 / 知识页
│ ├─ 05_mirror_zh_assets.py 镜像中文页引用的插图
│ └─ verify_site.js 真实浏览器验收(25 项)
├─ build/ ← 中间产物(导航树 / 提取报告 / 验收证据)
└─ site/ ← ★ 构建产物(发布这个目录)
三、常用命令¶
托管 Python(已含 mkdocs-material 与 i18n 插件):
PY="C:/Users/Benda/.workbuddy/binaries/python/envs/default/Scripts/python.exe"
cd "E:/000_DW/LIB_OB/EPM-wiki/10-软件知识/输出/操作手册站点"
# 本地预览(改完内容立刻看效果,Ctrl+C 停止)
"$PY" -m mkdocs serve -a 127.0.0.1:8000
# 正式构建
"$PY" -m mkdocs build
# 严格构建(有坏链会直接报错,交付前跑一次)
"$PY" -m mkdocs build --strict
四、扩展内容¶
4.1 官方手册已全量收录(13 章 / 2145 页)¶
无需再做扩展。日常只有两种情况需要重跑提取:
# ① 换了 SP 版本或 jar 路径 → 全套重跑
"$PY" tools/01_build_toc.py
"$PY" tools/02_extract_pages.py --chapter all
"$PY" tools/03_build_mkdocs.py
"$PY" -m mkdocs build
# ② 只想重建某一章(调试用)
"$PY" tools/02_extract_pages.py --chapter "Reporting & Data Visualization"
# ③ 换语言(官方包内自带 fr / it / jp)
"$PY" tools/02_extract_pages.py --lang fr --docs docs/fr --chapter all
实测耗时(本机):全量提取 约 51 秒,全量构建 约 30–60 秒,产物 约 155 MB。
两个必须知道的坑
--clean会触发沙箱批量删除守卫(删除 2000+ 文件)。若被拦截, 在授权环境下运行,或手工删除docs/en/manual、docs/en/assets后重跑。mkdocs build自身也要清理site/,同样会触发守卫而静默中断 (表现为构建 2 秒就"成功"、site/却没更新)。遇到这种情况就用授权通道重跑。
4.2 加中文内容¶
直接在 docs/zh/ 下新建 .md,然后在 tools/03_build_mkdocs.py 的 ZH_NAV 里加一行,重新生成配置即可。
4.3 补一页中文译文(让语言切换按钮出现)¶
规则很简单:路径与英文页完全一致即可。
docs/en/manual/reportingfunctions/intro/rep_intro_c.md ← 英文
docs/zh/manual/reportingfunctions/intro/rep_intro_c.md ← 同名同路径,放中文
语言切换按钮会自动出现在这两页上。
中文页里不能用相对路径链接到英文页
实测:i18n 的 folder 模式把 docs/en 与 docs/zh 视为两套独立文档树,
中文页写 ../../../en/manual/xxx.md 会被判为无效链接(构建警告,且渲染成死链)。
正确写法是站点绝对路径,构建时会以 INFO 放行并原样输出:
中文页引用插图则写 ../../../assets/img/<文件名>,并让图存在于 docs/zh/assets/img/
(跑 tools/05_mirror_zh_assets.py 会自动把中文页引用到的图镜像过来)。
4.4 增加一种语言(fr / it / jp)¶
官方包内本来就带四语言:
然后在 tools/03_build_mkdocs.py 的 languages: 里加一个 locale 块(locale: fr、default: false),重新生成配置。
4.5 把 docx 手册并进站点¶
思路:markitdown(或 python-docx)把 10-软件知识/输出/操作手册/**/*.docx 转成 Markdown,
附件目录里的 imgNN.png 按文档中的引用顺序重命名后放到 docs/zh/handbook/<分类>/assets/,
再把生成的 md 挂进 ZH_NAV。
4.6 内网 / 离线部署:已经关掉了外网字体¶
Material 主题默认从 fonts.gstatic.com 拉 Roboto。内网或离线客户端访问不到外网时,
每页都会挂起等待 DNS / 连接超时,既拖慢首屏又产生一批失败请求。
配置里已用 theme.font: false 关闭,改走系统字体栈——站点现在零外网请求,100% 自包含。
中文场景下 Roboto 本来也用不到。如确需官方字体,可删掉该行或改为自托管字体。
4.7 全量翻译(官方没有中文时)¶
官方包只有 en / fr / it / jp。要"真正全译",不要试图在对话里逐页翻,走 API 批量流水线:
export DEEPSEEK_API_KEY=sk-xxxx
# ① 先规划:出批次 / token / 成本,不调用任何 API
"$PY" tools/06_translate_pages.py --all --dry-run --budget 40000
# ② 单章试跑,确认译文风格(本章 ¥0.3 左右)
"$PY" tools/06_translate_pages.py --chapter etl --budget 40000
# ③ 全量(193 次调用 / 约 15 分钟 / ¥12)
"$PY" tools/06_translate_pages.py --all --budget 40000 --workers 8
# ④ 导航标题也要译,否则"内容是中文、侧边栏是英文"
"$PY" tools/07_translate_nav.py
"$PY" tools/03_build_mkdocs.py # 用 build/nav_zh.json 重建中文导航
"$PY" -m mkdocs build
实测规模(Tagetik 手册):可译正文 720 万字符 → 193 次调用 → 4.20M tokens → ¥12。
四条设计铁律¶
- 保护块不送译:代码块 / 行内代码 / 图片 / 链接 URL / HTML 注释 / 标识符
(
A_COM_003、${...})原样保留 —— 省 token,且模型不可能改坏结构。 - 编号段落协议:发
<<<SEG n>>>,要求同编号返回;回收时校验编号集合, 缺号/串号即重试(批次大时对半拆开重试)。这是防"整段漏译"的唯一可靠闸门。 - 表格按行切:整表当一个 segment 时模型容易漏行。表头 + 每行独立送译,
分隔行
| --- |原样保留(实测表格行 0 丢失)。 - 回填侧做确定性修复(不必重译):段尾换行按原文补回、行首 Markdown 标记按原文补回。
⭐ 回环测试:改完切分逻辑必须先跑它¶
以原文当作译文走一遍 切分 → 回填,必须与原文逐字节一致。
这一步首轮就抓到两个真 bug(空行被吞、标题标记丢失),不改到 100% 通过就不要调 API —— 否则烧的是真钱。当前实测 2145/2145 通过。
生产必备¶
| 能力 | 说明 |
|---|---|
| 关思考模式 | deepseek-flash 默认开 reasoning,输出 token 会被放大 2–3 倍且按输出计费。必须传 thinking={"type":"disabled"} |
| 批次重试 | 指数退避 ×4;段数不符属可重试错误 |
| 段级断点续跑 | 状态里存译文本身(不是只存段号),否则已译页在下一轮会因"无新译文"而退回英文 |
| 跨页打包 | 固定开销 ≫ token 成本:逐页拆批会把 120 批变 2100 批,墙钟差一个数量级 |
| 术语表 + UI 标签「中文(English)」 | 便于用户在英文界面里对照 |
换客户 / 换版本时¶
或先算出哪些英文页变了(比对 md5),只清掉这些页的 translate_state.json 条目再重跑 ——
多数改动只涉及个位数页面,成本可忽略。
五、发布方式¶
| 方式 | 做法 | 适用 |
|---|---|---|
| 内网静态站(推荐) | 把 site/ 拷到 Nginx / IIS 的站点目录 |
团队长期访问,一个链接 |
| 打包分发 | site/ 压成 zip 发出 |
给客户 / 外部同事 |
| 临时共享 | "$PY" -m mkdocs serve -a 0.0.0.0:8000 |
局域网内临时演示 |
注意
若要绑到 0.0.0.0 对外提供访问,请确认所在网络环境与安全策略允许。
六、已知问题¶
| 问题 | 说明 | 处理 |
|---|---|---|
| 15 页官方缺失 | 目录有条目、英文包里没有文件(其他语言才有),属上游缺口 | 提取时自动剔除并记录到 build/missing_upstream.json,不进导航 |
| 部分插图破图 | 上游官方文档本身的引用路径错误(在线也是破的) | 提取脚本已做多级路径回退,能找到的都补上了 |
卡片链接渲染成字面 [](url) |
MadCap 的 <a><img><p>标题</p><p>描述</p></a> 转 Markdown 后链接文字跨空行,Markdown 不认 |
提取时把 <a> 内块级元素拍平 + <br>→空格 + 链接文字内空白压成单空格 |
| 译文吞掉空行 / 标题降级 | 模型返回的段尾换行缺失、行首 ##、- 被吃掉 |
回填时按原文做确定性修复,不必重译 |
title: "X"(中文) 让标题消失 |
引号外还有内容 → 非法 YAML → frontmatter 解析失败 → 无 H1 的页标题退化成文件名 | 后缀必须写进引号内:title: "X(中文)" |
| 少量结构残差 | 全量中译后 12 页次(0.56%)标题/列表/表格计数与原文不一致,另有约 210 页段内换行被重新折行 | 内容无缺失;需要时清掉对应 translate_state.json 条目重译 |
| 页内锚点不精确 | MadCap 的锚点名(如 #Salvatag)与 MkDocs 生成的标题锚点不一致 |
链接会落在正确页面,但不会滚到小节;属上游命名问题 |
sitemap.xml 探测 404 |
Material 会对每个 <link rel="alternate"> 去同目录探测 sitemap,只有根目录有该文件 |
已知无害;要彻底消除可在服务端加 301 重写 |
| 搜索索引请求"失败" | 8 MB 索引加载中被切页,浏览器主动取消(ERR_ABORTED) |
非缺陷;验收脚本已按 sitemap / 取消 / 站外 / 真实 四桶分开统计 |
mkdocs build --strict 报重复 nav |
官方目录树里若干条目指向同一页 | 属正常,不影响构建 |
--clean / mkdocs build 被沙箱拦截 |
批量删除触发安全守卫 | 在授权环境下运行(见 §4.1) |
| 网站体积 278 MB | 中英各 2145 页 + 2083 张插图 | 内网部署正常;分发可只打包 site/ 并压缩 |
七、环境依赖¶
| 组件 | 版本 |
|---|---|
| Python | 3.13 |
| mkdocs | 1.6.1 |
| mkdocs-material | 9.7.7 |
| mkdocs-static-i18n | 1.3.1 |
| beautifulsoup4 / lxml / markdownify | 用于 HTML → Markdown 提取 |
安装(如换机器):