Последняя активность 1 month ago

翻译文档为中文文档

Версия 16fff6a1f547479d28794db9b577363d35223ad3

README.md Исходник

XX 中文文档

本文档使用 AI 翻译

项目流程

首次使用

  1. 创建空分支
git switch --orphan docs
  1. 创建 README.md
cat > README.md <<EOF
# XX 中文文档

本文档使用 AI 翻译
EOF
  1. 首次提交
git add README.md
git commit -am init
git push origin docs
  1. 拉取上游源码
mkdir -p docsite
pushd docsite
if [[ -d .git ]]; then
    git remote set-url upstream https://github.com/xxx/docs.git
else
    git init
    git remote add upstream https://github.com/xxx/docs.git
fi
git reset --hard
git fetch upstream main
git merge upstream/main
popd
  1. 复制源文档
cp -r docsite/content .
rm -rf docs
mv content docs
  1. 全量翻译
aitr
  1. 本地测试与构建
git clone https://github.com/xxx/docs.git docsite
cp -r docs_zh/* ./docsite/content
cd docsite
  1. 启动或构建
# NodeJS
npm install
npm run dev

# Hugo
hugo server

...

2. AI 翻译

  • 安装 CLI 工具 (增量更新直接使用 AI CLI 工具直接对比)
curl -L https://fx4.cn/aitr | bash
  1. 设置环境变量 config.toml
...
[[providers]]
enabled = true
name = "grok"
api_key = "xxx"
base_url = "https://api.x.ai/v1"
model = "grok-3"
concurrency = 1 # 线程数
rate_delay = 3.0 # 每个请求后等待 1.0 秒(可根据限流调整)
  1. AI 翻译
aitr
config.example.toml Исходник
1# 根目录 - 包含需要翻译的 Markdown 文件
2root_dir = "./docs"
3
4# 输出目录 - 翻译后的文件保存位置
5output_dir = "./docs_zh"
6
7# 输出模式: "overwrite" (覆盖原文件) 或 "new_folder" (保存到新文件夹)
8output_mode = "new_folder"
9
10# 排除的目录 (逗号分隔)
11exclude_dir = "node_modules,.git,_build"
12
13# 最大 token 数
14max_tokens = 99999
15
16# 系统提示词(支持多行,使用 """ 包裹)
17system_prompt = """
18你是一个专业的技术文档翻译专家。请将以下英文 Markdown 文档翻译成流畅、自然的简体中文。
19
20严格要求:
211. 保留完整的 Markdown 格式,包括标题、列表、表格、代码块、链接、图片等一切结构完全不变。
222. 代码块、命令行、文件名、路径、API 名称、配置文件内容、技术术语等保持原样(不要翻译)。
233. 专有名词(如产品名、框架名、软件名,例如 Traefik、Docker、Kubernetes)保持英文原名。
244. Hugo 短代码和模板语法(如 {{< xxx >}}、{{ xxx }}、{{</ xxx >}} 等所有以 {{ 或 {{< 开头的标签)必须完整保留原样,不翻译、不修改其内部任何内容。
255. 对于 YAML frontmatter(文档开头的 --- 之间的内容):
26 - 只翻译实际需要本地化的字符串值内容(如 title、description、linkTitle 等字段的值)。
27 - tags 字段的值(通常为字符串或字符串列表)必须完全保持原英文不变,不进行任何翻译或修改。
28 - 其他字段(如 keywords 等)按正常规则处理:如果为字符串值则翻译(如 description),如果为列表则视情况保留英文(专有名词不翻译)。
29 - 严格保留原文档中的所有字段、键名、结构、格式、缩进和所有机制(包括已有的 YAML 锚点 &xxx 和别名 *xxx)。
30 - 如果原文档中已有锚点定义,则在翻译该锚点对应的字符串值时保留锚点标记(如 &desc);别名引用(如 *desc)保持原样不变。
31 - 如果原文档中没有锚点或别名,则翻译后绝对不得新增任何锚点、别名、params 块或其他额外字段。
32 - 绝对不得添加、删除或修改任何原有字段、锚点、别名或 params 等结构,仅对需要本地化的字符串值进行翻译。
33 - aliases、keywords、tags 等列表字段的值,按原文档格式保留(保持原有引号使用情况,不统一添加或移除引号)。
34 - 必须输出且仅输出一次完整的 YAML Front Matter(以 --- 开头,以 --- 结尾)。
35 - 结尾的 --- 必须独占一行,且在其后必须紧跟一个空行。
36 - 绝对不要在翻译后的 Front Matter 之前或之后保留原始的英文 Front Matter。
376. 翻译要准确、专业、易懂,技术术语使用业界通用中文表达。
387. 绝对禁止在文档开头或 YAML frontmatter 前后添加任何 Markdown 代码块标记(如 ```markdown 或 ```),保持文档结构的纯净。
398. 绝对禁止自作主张地添加任何原文档中不存在的内容,包括但不限于:完整的语言指南、示例代码、学习资源、最佳实践等。只翻译原文档中已有的内容,不多不少。
409. 只输出翻译后的完整 Markdown 内容,不要添加任何说明、注释或多余文本。
4110. Markdown 链接 `[text](url)` 中的 `url` 必须完全保持原样,绝对不要修改、翻译或移除路径中的任何部分。即使是相对路径或绝对路径,也都必须保持原样。
42"""
43
44[[providers]]
45name = "grok"
46api_key = "xxx"
47base_url = "https://api.x.ai/v1"
48model = "grok-3"
49concurrency = 4 # 线程数
50rate_delay = 3.0 # 每个请求后等待 1.0 秒(可根据限流调整)
deploy.sh Исходник
1#!/usr/bin/env bash
2
3#============================================================
4# File: deploy.sh
5# Description: 部署
6# URL:
7# Author: Jetsung Chan <[email protected]>
8# Version: 0.2.0
9# CreatedAt: 2025-12-16
10# UpdatedAt: 2026-01-08
11#============================================================
12
13
14if [[ -n "${DEBUG:-}" ]]; then
15 set -eux
16else
17 set -euo pipefail
18fi
19
20DEFAULT_BRANCH="main"
21HUGO_VERSION=${HUGO:-0.154.2}
22
23DELETE_FILE="deleted_docs.txt"
24ADD_FILE="new_docs.txt"
25MODIFIED_FILE="modified_docs.txt"
26TRANSLATE_LIST="translate_list.txt"
27
28install_hugo() {
29 curl -L https://fx4.cn/hugo | bash -s -- -v "$HUGO_VERSION" -w
30}
31
32# 增量更新
33incremental_update() {
34 [[ -d docsite ]] || mkdir docsite
35
36 pushd docsite
37 if [[ -d .git ]]; then
38 git remote set-url upstream https://github.com/xxx/docs.git
39 else
40 git init
41 git remote add upstream https://github.com/xxx/docs.git
42 fi
43 git reset --hard
44 git fetch upstream main
45 git merge upstream/main
46 popd
47
48 cp -r docsite/content .
49 rm -rf docs
50 mv content docs
51
52 # 记录删除的文件
53 git ls-files --deleted docs/ | tee "$DELETE_FILE"
54 export ROOT_DIR=$(grep root_dir config.toml | cut -d'"' -f 2 | sed 's|^\./||')
55 export OUTPUT_DIR=$(grep output_dir config.toml | cut -d'"' -f 2 | sed 's|^\./||')
56 # sed -i "s|^$ROOT_DIR/|$OUTPUT_DIR/|g" "$DELETE_FILE"
57 # 删除对应的输出文件
58 while read -r file; do
59 new_file="${file/$ROOT_DIR/$OUTPUT_DIR}"
60 echo "$new_file"
61 rm -rf "$new_file" || true
62 done < "$DELETE_FILE"
63
64 # 更新 git 索引
65 git add .
66 # 记录新增和修改的文件
67 git diff --cached --name-only --diff-filter=A docs/ | tee "$ADD_FILE"
68 git diff --cached --name-only --diff-filter=M docs/ | tee "$MODIFIED_FILE"
69
70 cat "$ADD_FILE" "$MODIFIED_FILE" | tee "$TRANSLATE_LIST"
71
72 # 移除以 .png .jpg .jpeg .gif 结尾的文件
73 sed -i '/\.\(png\|jpg\|jpeg\|gif\)$/d' "$TRANSLATE_LIST"
74
75 # 合并 config.toml
76 merge_config
77
78 # # 翻译增量文件
79 # if ! command -v aitr &> /dev/null; then
80 # echo "正在安装 aitr ..."
81 # curl -L https://fx4.cn/aitr | bash
82 # fi
83
84 # 调用 aitr 进行翻译
85 if command -v aitr &> /dev/null; then
86 aitr --input "$TRANSLATE_LIST" --list --output translated
87 cp -r "translated/${ROOT_DIR}/"* "${OUTPUT_DIR}"/
88 else
89 echo "aitr 未安装,跳过构建步骤。"
90 fi
91}
92
93merge_config() {
94 if [[ -f config.example.toml ]]; then
95 sed '/providers/,$d' ./config.example.toml | tee config.toml > /dev/null
96 fi
97
98 if [[ -f aitr.toml ]]; then
99 sed -n '/logging/,$p' aitr.toml | tee -a config.toml > /dev/null
100 fi
101}
102
103# Patch Hugo layouts to avoid errors on missing metadata
104patch_hugo_layouts() {
105 if [[ -d docsite/layouts ]]; then
106 sed -i 's/errorf "\[summary-bar\]/warnf "[summary-bar]/g' docsite/layouts/shortcodes/summary-bar.html || true
107 sed -i 's/errorf "\[tags\]/warnf "[tags]/g' docsite/layouts/partials/tags.html || true
108 sed -i 's/errorf "\[languages\]/warnf "[languages]/g' docsite/layouts/partials/languages.html || true
109 fi
110}
111
112# 复制 docs_zh 至 content
113copy_docs_zh() {
114 if [[ ! -d docsite ]]; then
115 git clone https://github.com/docker/docs.git docsite
116 fi
117 patch_hugo_layouts
118 if [[ -d "translated/docs" ]]; then
119 echo "使用 translated/docs 的文档覆盖 docs_zh"
120 cp -r translated/docs/* docs_zh/
121 fi
122 cp -r docs_zh/* docsite/content/
123}
124
125# 本地测试
126start_dev() {
127 copy_docs_zh
128 cd docsite
129 npm install
130 hugo server -D
131}
132
133# 构建网站
134build_site() {
135 copy_docs_zh
136 cd docsite
137 npm install
138 hugo --minify
139}
140
141# 调用翻译脚本
142translate() {
143 aitr
144}
145
146usage() {
147 cat << EOF
148用法: $0 [选项]
149
150选项:
151 -c --copy 复制 docs_zh
152 -b --build 构建网站
153 -i --incremental 增量更新
154 -s --start 本地测试
155 -x --hugo 安装 Hugo extended(linux-amd64)
156 -t --translate 调用翻译脚本
157 -h --help 显示此帮助信息
158
159示例:
160 $0 --hugo
161 $0 --translate
162EOF
163}
164
165main() {
166 if [[ $# -eq 0 ]]; then
167 usage
168 exit 1
169 fi
170
171 while [[ $# -gt 0 ]]; do
172 case $1 in
173 -c|--copy)
174 copy_docs_zh
175 shift
176 ;;
177 -i|--incremental)
178 incremental_update
179 shift
180 ;;
181 -x|--hugo)
182 install_hugo
183 shift
184 ;;
185 -b|--build)
186 build_site
187 shift
188 ;;
189 -s|--start)
190 start_dev
191 shift
192 ;;
193 -t|--translate)
194 translate
195 shift
196 ;;
197 --help|-h)
198 usage
199 exit 0
200 ;;
201 *)
202 echo "未知参数: $1" >&2
203 usage
204 exit 1
205 ;;
206 esac
207 done
208}
209
210main "$@"
docs.yml Исходник
1name: Documentation
2
3on:
4 push:
5 branches:
6 - docs
7 paths:
8 - 'docs_zh/**'
9 - '.github/workflows/docs.yml'
10 workflow_dispatch:
11
12permissions:
13 contents: write
14 pages: write
15 id-token: write
16
17concurrency:
18 group: pages
19 cancel-in-progress: false
20defaults:
21 run:
22 shell: bash
23
24jobs:
25 build:
26 env:
27 HUGO_VERSION: 0.154.2
28 TZ: Asia/Shanghai
29 runs-on: ubuntu-latest
30 steps:
31 - uses: actions/checkout@v6
32 - name: Install Hugo
33 run: |
34 curl -L https://fx4.cn/hugo | bash -s -- -v "$HUGO_VERSION" -w
35 - name: Verify installations
36 run: |
37 echo "Hugo: $(hugo version)"
38 echo "Node.js: $(node --version)"
39 - name: Fetch Source
40 run: |
41 git clone https://github.com/docker/docs.git docsite
42 - name: Fix
43 run: |
44 # sed -i 's/refLinksErrorLevel: WARNING/refLinksErrorLevel: ERROR/' docsite/hugo.yaml
45 sed -i '/baseURL/d' docsite/hugo.yaml
46 - name: Build Docs
47 run: |
48 cp -r docs_zh/* ./docsite/content
49 cd docsite/
50 npm install
51 hugo build
52 - name: Copy CNAME
53 run: cp CNAME docsite/public/
54 - name: Upload build artifacts
55 uses: actions/upload-artifact@v6
56 with:
57 name: docs-site
58 path: docsite/public
59 retention-days: 1
60
61 deploy-github-pages:
62 environment:
63 name: github-pages
64 url: ${{ steps.deployment.outputs.page_url }}
65 needs: build
66 runs-on: ubuntu-latest
67 steps:
68 # - uses: actions/configure-pages@v5
69 - name: Download build artifacts
70 uses: actions/download-artifact@v6
71 with:
72 name: docs-site
73 path: ./public
74 - name: Deploy to Branch
75 uses: peaceiris/actions-gh-pages@v4
76 with:
77 github_token: ${{ secrets.GITHUB_TOKEN }}
78 publish_dir: ./public
79 # - uses: actions/upload-pages-artifact@v4
80 # with:
81 # path: docsite/public
82 # - uses: actions/deploy-pages@v4
83 # id: deployment
84
85 deploy-ssh-server:
86 needs: build
87 runs-on: ubuntu-latest
88 steps:
89 - name: Download build artifacts
90 uses: actions/download-artifact@v6
91 with:
92 name: docs-site
93 path: ./public
94 - name: Compress to tar.xz
95 run: |
96 tar -cJf docs-site.tar.xz public/
97 - name: Set up SSH
98 uses: LuisEnMarroquin/[email protected]
99 with:
100 ORIGIN: ${{ secrets.SSH_HOSTNAME }}
101 SSHKEY: ${{ secrets.SSH_KEY }}
102 NAME: webserver
103 PORT: ${{ secrets.SSH_PORT }}
104 USER: ${{ secrets.SSH_USERNAME }}
105 - run: echo "" >> ~/.ssh/access # fix
106 - name: Deploy the website
107 env:
108 WEBROOT: /data/wwwroot/docker
109 run: |
110 ssh webserver "rm -rf $WEBROOT && mkdir -p $WEBROOT"
111 scp docs-site.tar.xz webserver:${WEBROOT}/
112 ssh webserver "cd $WEBROOT && tar -xJf docs-site.tar.xz --strip-components=1 && rm -f docs-site.tar.xz"
init.sh Исходник
1#!/usr/bin/env bash
2
3if [[ -n "${DEBUG:-}" ]]; then
4 set -eux
5else
6 set -euo pipefail
7fi
8
9BASE_URL="https://gist.asfd.cn/jetsung/gendocs/raw/HEAD"
10
11download_files() {
12 curl -fsSL -O "${BASE_URL}/deploy.sh"
13 chmod +x deploy.sh
14
15 curl -fsSL -O "${BASE_URL}/README.md"
16
17 curl -fsSL -O "${BASE_URL}/config.example.toml"
18
19 curl -fsSL -O "${BASE_URL}/config.example.toml"
20
21 curl -fsSL --create-dirs -o ".github/workflows/docs.yml" "${BASE_URL}/docs.yml"
22}
23
24main() {
25 download_files
26}
27
28main "$@"
29