文档构建

构建并为本文档站点做出贡献。

技术栈

  • Sphinx — 文档生成器

  • Furo — 主题

  • MyST — Markdown 解析器

  • sphinx-intl — 国际化

  • sphinxcontrib-mermaid — 图表支持

本地构建

前提条件

# Python 3.12
pip install -r requirements.txt

构建英文版

make html

输出位于 build/html/。

构建中文版

make html-zh_CN

输出位于 build/html/zh_CN/。

同时构建两种语言

make html-all

本地预览

python -m http.server -d build/html 8000

打开 http://localhost:8000。中文树在 http://localhost:8000/zh_CN/。侧边栏语言下拉在切换时停留在同一页面(foo.html ↔ zh_CN/foo.html)。

语言切换

Furo 侧边栏使用 UniLab 风格的 <select>,放在品牌名下方、搜索框上方(source/_templates/sidebar/lang_switcher.html)。

本站仍用 sphinx-intl 双构建(英文在 HTML 根目录,中文在 zh_CN/)。没有采用 UniLab 那种并行 source/en/ + source/zh_CN/ 单次构建。因此对应页 URL 是在 conf.py(html-page-context)里注入的相对 href,而不是对另一语言做 pathto()(那个页面不在同一次 builder 的 found_docs 里)。

GitHub Pages 站点位于 /docs/。相对 href 会解析成 /docs/... ↔ /docs/zh_CN/...。不要链到域名根路径 /zh_CN/(会 404)。html_baseurl 是 https://fiveages-sim.github.io/docs/。

翻译工作流

更新源字符串

修改英文内容后:

make gettext
sphinx-intl update -p build/gettext -l zh_CN

检查译文

仅有非空 msgstr 不够。填完目录后请再跑:

python3 scripts/check_zh_coverage.py --threshold 95
python3 scripts/check_zh_mix.py

check_zh_mix.py 会在空译文、仍带 #, fuzzy 的条目、把英文散文原样写入 msgstr、以及中文句子里残留英文时失败。如何处理命中:.cursor/skills/zh-translation-qa/SKILL.md。

编辑译文

编辑 locale/zh_CN/LC_MESSAGES/*.po 中的文件:

#: source/index.md:1
msgid "FiveAges Sim Documentation"
msgstr "FiveAges Sim 文档"

构建翻译版本

make html-zh_CN

文件结构

docs/
├── source/
│   ├── conf.py              # Sphinx configuration
│   ├── index.md             # Landing page
│   ├── 0-overview/          # Overview section
│   ├── 1-getting_started/   # Getting started
│   ├── 2-how_to/            # How-to guides
│   ├── 3-concepts/          # Concepts
│   ├── 4-reference/         # Reference
│   ├── 5-developer/         # Developer guide
│   ├── _static/             # Static files (CSS, images)
│   ├── _templates/          # Custom templates
│   └── _vendored/           # Pinned upstream README copies (see below)
├── locale/
│   └── zh_CN/
│       └── LC_MESSAGES/     # Chinese translations
├── Makefile
└── requirements.txt

写作指南

撰写约束(可以写什么、如何处理私有仓、读者页不要写给 agent 的元说明):.cursor/skills/docs-writing/SKILL.md。

Markdown (MyST)

使用 MyST 风格的 Markdown。切勿在 ```{admonition} 内部嵌套 ``` 围栏——这会破坏 zh_CN 渲染。当提示框需要包含代码块时,请使用冒号围栏(:::);展示围栏语法的示例请用 4 个反引号作为外层围栏:

# Heading

Paragraph text.

## Subheading

- List item
- Another item

```bash
code block
```

:::{admonition} Note
:class: tip

Admonition content.
:::

代码块

代码块要带语言标记(目录树用 {code-block} none)。无语言标记的 ``` 围栏会变成 RST 的 ::,zh_CN HTML 可能漏出裸的 ::。每个代码/目录树块的 .po msgstr 必须与 msgid 完全一致:翻译了注释、多一行或少一行,都会被再解析成 RST ::,然后 MyST colon_fence 丢掉真正的代码块。

Controllers
        ↓
Hardware

带语言标记的示例:

```bash
ros2 launch package launch.py
```

```python
from ros2_robot_interface import ROS2RobotInterface
```

提示框

仅当提示框正文中没有嵌套的 ``` 代码围栏时,才使用反引号围栏:

```{admonition} Warning
:class: warning

Warning content.
```

```{admonition} TODO
:class: warning

To be completed.
```

如果提示框正文需要围栏代码块,请改用冒号围栏:

:::{admonition} Path Verification
:class: tip

Verify the binary exists:

```bash
ls ~/isaacsim/python.sh
```
:::

交叉引用

See [Architecture](../0-overview/1-architecture.md).

See {doc}`../0-overview/1-architecture`.

表格

| Column 1 | Column 2 |
|----------|----------|
| Value 1  | Value 2  |

图表

使用 Mermaid 绘制图表:

```{mermaid}
flowchart LR
    A --> B --> C
```

Vendored upstream README

source/_vendored/ 存放公开上游 Markdown 的钉选提交副本,供 Sphinx {include} 一小段。本站只 vendoring README.md:ros2_robot_interface,以及 arms_ros2_control 里的 basic_joint_controller 与 adaptive_gripper_controller。ros2_robot_interface API_REFERENCE.md 保持 GitHub 链接,不复制进 _vendored/。

钉选:source/_vendored/SOURCES.json(repo、path、完整提交 sha、dest)。

# Re-fetch every pin in SOURCES.json
python3 scripts/vendor_upstream_md.py --sync
make vendor-upstream

# Verify header SHA / sha256 (CI; no network)
python3 scripts/vendor_upstream_md.py --check
make vendor-check

# Move one pin to latest main, or to a SHA
python3 scripts/vendor_upstream_md.py --bump ros2_robot_interface
python3 scripts/vendor_upstream_md.py --bump basic_joint_controller --sha <full-sha>
python3 scripts/vendor_upstream_md.py --bump adaptive_gripper_controller --sha <full-sha>

把 SOURCES.json 与 vendored markdown 一起提交。抓取时会去掉相对 / 私有图片,避免 HTML 构建依赖缺失文件。

bump 之后,重算切了 vendored README 的页面上 {include} 的 :start-line: / :end-line:(basic_joint_controller、夹爪插件、ros2_robot_interface)。行号从 1 起。把 :end-line: 设为切片的最后一行——通常是下一节标题之前的空行或 ---——然后重新构建,确认那个标题没有出现在 HTML 里。

不要用标题文字做 :end-before: / :start-after: 来切片段。这两个选项会在行中途截断,因此用 Demo Launch 去截 ## 7. Demo Launch 会留下 ## 7.,变成空荡荡的标题。这些选项值里也不能写 # —— Docutils 把 # 当注释。

conf.py 把 _vendored/ 列入 exclude_patterns,因此这份副本不会成为侧边栏页面。

CI/CD

GitHub Actions 会在以下情况构建文档:

  • 推送到 main(部署)

  • 提交 pull request(检查构建)

出现以下情况时 CI 会失败:

  • source/_vendored/SOURCES.json 中的 vendored README 钉选与已提交文件不一致

  • zh_CN 翻译覆盖率低于 95%

  • check_zh_mix.py 发现空译文、fuzzy、未译散文或中英混杂残留

  • 源文件在 ```{admonition} 内部嵌套了 ```

  • Sphinx 产生任何警告(SPHINXOPTS=-W)

  • 构建出的 HTML 中出现字面量 ``` 围栏(MyST 嵌套损坏)

  • 语言切换使用了域名根路径 /zh_CN/(缺少 GitHub Pages 的 /docs)

合并前构建必须通过。

贡献指南

  1. Fork 文档仓库

  2. 进行修改

  3. 使用 make html-all 在本地测试

  4. 提交 pull request