Skip to content

zh-CN: complete the Day 1-4 translation - #3256

Open
TianfangChang wants to merge 10 commits into
google:mainfrom
TianfangChang:zh-cn-mechanical
Open

zh-CN: complete the Day 1-4 translation#3256
TianfangChang wants to merge 10 commits into
google:mainfrom
TianfangChang:zh-cn-mechanical

Conversation

@TianfangChang

@TianfangChang TianfangChang commented Aug 1, 2026

Copy link
Copy Markdown

This is translation work only — no msgmerge was run, and no msgid changed.

Days 1–4 of the course (welcome-day-1 through unsafe-rust) are now fully
translated: the 612 entries that were fuzzy, empty, or filled with the English
source are down to 0. Android / Chromium / bare-metal / concurrency / async are
untouched and still have 482 to go.

896 entries changed in total.

Why so much was rendering as English

Three causes, all of which make mdbook-i18n-helpers fall back to the msgid:

  • Fuzzy entries whose English had been reworded. Many were not merely stale
    but shifted — the msgstr held a neighbouring entry's text, so unfuzzying
    them blindly would have shipped the wrong Chinese. Every one was rediffed
    against the current English. A sample:

    msgid previous translation
    The [for loop] iterates over ranges… [Drop] 用于定义析构函数。
    Associated Types 共享类型
    Welcome to Day 4 欢迎来到第一天
    Show students the Ord trait… [“OsStr”](…)和[“OsString”](…)
  • Empty entries.

  • Entries whose msgstr was the English source verbatim. These render exactly
    like an empty entry but count as translated, so the translation report
    overstated coverage and msgmerge would never flag them again.

A separate class: entries that rendered, but rendered wrong

The last commit deals with 86 entries that were neither fuzzy nor empty, so they
never appeared as outstanding work:

  • 128 code spans had become pairs of Chinese quotation marks (“const” rather
    than `const`), rendering as proportional text
  • 5 markdown links pulled apart so nothing rendered as a link; one had lost its
    URL entirely
  • 3 unbalanced backticks
  • 3 cases of _x_ flanked by Han characters, which CommonMark does not treat as
    emphasis; in async/runtimes.md both closing underscores were missing, so the
    surviving pair italicised a whole clause

Also fixed earlier in the branch: `\*const i8` and `&\[u8\]` (a
backslash inside a code span renders literally), a row of the
memory-management/move.md svgbob diagram that was 8 characters short and broke
the dashed border, and `&str` described as C++'s const char* rather than
std::string_view.

Consistency

  • throughout, rather than a 99/230 split with
  • session (half-day) → 本场, segment (chapter) → 本节; both had been 本节
  • chapter names reuse the existing SUMMARY.md translations

Checks

Verified with a local MDBOOK_BOOK__LANGUAGE=zh-CN mdbook build (exit 0) —
标记为<code>const</code>的函数, <em>降级</em> and the restored System
Allocator anchor all render correctly. msgfmt was not available, so the file
was additionally validated by script: msgid set byte-for-byte unchanged, every
string literal correctly escaped, link targets in each msgstr matching its
msgid. i18n-report parses it cleanly and agrees on the counts.

dprint no longer formats .po files — the exec command was dropped in #2381
so nothing here was run through dprint fmt. TRANSLATIONS.md still tells
translators to do so; happy to send a separate PR fixing that.

Worth knowing: this PO file is two years behind

po/zh-CN.po was last synced on 2024-04-15. Regenerating the POT from the
current source with mdbook-xgettext gives:

strings in the current source 6376
entries in po/zh-CN.po 3783
…of those, still present in the source 2834
…no longer in the source 949
source strings with no entry at all 3542

So 353 of the 896 entries touched here are for strings the source has since
dropped, and they will become obsolete on the next msgmerge. The largest
single group is the agenda lists: - [Loops](./control-flow-basics/loops.md) (5 minutes) no longer exists anywhere in src/ — those tables are generated by
{{%segment outline}} now, and the duration column is emitted in English by the
plugin rather than going through the PO file at all.

I have deliberately not run msgmerge here, per TRANSLATIONS.md. But zh-CN
would benefit a lot from a sync, and the generated agenda tables may be worth a
look as a translation gap in their own right.

🤖 Generated with Claude Code

Agenda lists and course-structure tables rendered in English because their
entries were either fuzzy, empty, or filled with the English source verbatim
(msgstr == msgid), all three of which mdbook-i18n-helpers skips.

Translate all 146 of them, reusing the chapter titles already translated for
SUMMARY.md and the existing "(5 分钟)" / "(1 小时 5 分钟)" duration format.

Also fixes stale translations these entries carried:
  - [Lifetimes](../lifetimes.md) was translated as [引用](../references.md)
  - several durations left over from an older schedule (20/55/1 小时)
  - [Exercise: Geometry] rendered as 练习:面向 GUI 库的模块
  - a few agenda slots holding an unrelated sentence about pattern matching

Other correctness fixes:
  - SUMMARY.md "Copy Types" was 复合类型 ("compound types") -> Copy 类型
  - Labels -> 标签, Matching Values -> 匹配值, Source -> 源代码
  - memory-management/move.md svgbob diagram: the s1 "(无法访问)" row was
    8 characters short, breaking the dashed box border
  - borrowck.md: _借用检查器_ glued to CJK on both sides is not emphasis in
    CommonMark; spaced out to match the rest of the file

msgids are unchanged.
…y 1-4)

Mechanical pass over the 120 Day 1-4 entries that needed no translation
judgement. Two shapes:

  42x  the translation was already identical to the source, but carried a
       trailing \n the msgid does not have -- that injects a blank line into
       the rendered code block. Strip it and drop the fuzzy marker.

  72x  code comments and string literals whose msgstr had drifted onto some
       unrelated entry during past merges, e.g.
         "Alice"                      -> 切片
         "Optional box"               -> 异常
         "Calling function on {input}"-> 调用 Unsafe 函数
         "Size of none: {}"           -> "before: {a}"
         // undefined behavior.       -> Rust 没有运行时未定义行为:
       Restored to the source text, matching the convention already used by
       the other ~830 code-string entries in this file.

Six were prose that the code-string heuristic caught by mistake and are
translated instead:
  Lifetimes            结构体生命周期 -> 生命周期  (matches the agenda entries)
  Supertraits          更多 trait     -> 超特征
  Option               异常           -> Option
  Testing.                            -> 测试。
  `Iterator` implements               -> `Iterator` 实现了
  `PartialEq` and `Eq` / `PartialOrd` and `Ord` were already correct; only
  the fuzzy marker was dropped.

Verified: every rewritten msgstr equals its msgid byte for byte apart from
those six, no entry left fuzzy, msgids unchanged.

Day 1-4 remaining: 366 -> 246 (all prose).
The remaining 13 Day 3 entries, all previously untranslated:

  7  borrowing/interior-mutability.md speaker notes and body text
  2  smart-pointers/box.md notes on the null pointer optimization
  1  lifetimes/lifetime-elision.md speaker note
  2  the "Including 10 minute breaks, ..." session timings
  1  smart-pointers/trait-objects.md svgbob diagram

Terminology follows the Day 3 translations already live in this file:
共享引用 / 独占引用 / 内部可变性 / 借用规则 / 所有权.

The trait-objects diagram was fuzzy because the upstream art was redrawn; the
stale msgstr was the previous English diagram. Redrawn from the new source with
only the two floating labels translated (Stack/Heap -> 栈/堆, "Program text" ->
"程序文本"), matching the sibling diagrams in move.md and box.md. Neither label
sits on a box border, so every border row is still 81 characters wide.

Emphasis markers are spaced away from adjacent CJK (_安全_, _始终_); glued to a
Han character on both sides CommonMark does not treat `_` as emphasis.

Verified: msgids unchanged, no line over 80 columns, po syntax clean.

Day 3 remaining: 13 -> 0. Day 1-4 remaining: 246 -> 233.
… unsafe)

The remaining 53 Day 4 entries: 37 stale fuzzy translations rediffed against
the current English, 16 never translated.

Notable corrections in the stale ones -- these were rendering as English, so
the wrong text was not visible, but it was wrong:

  Welcome to Day 4                          欢迎来到第一天 -> 欢迎来到第四天
  Cargo Setup                               设置 -> Cargo 设置
  anyhow::Error is essentially a wrapper..  ”是“Result\<V, anyhow::Error>”的类型别名。
  anyhow::Result<V> is a type alias..       “anyhow::Result
  Actual error type inside of it..          “anyhow::Error”本质上是“Box

The three anyhow entries had their translations shifted one entry out of step,
so each carried the neighbour's text. Retranslated from the current English.

Also fixes four rendering defects in the FFI conversion list in
unsafe-rust/exercise.md, which were live (not fuzzy) and so shipping broken:

  `\*const i8`   backslash inside a code span renders literally  -> `*const i8`
  `&\[u8\]`      same                                            -> `&[u8]`
  “&OsStr”       curly quotes where the source has backticks     -> `&OsStr`
  plus a stray space before the full-width colon in three items

thiserror-and-anyhow.md and iterators/fromiterator.md were split/renamed
upstream (into thiserror.md + anyhow.md, and collect.md); their msgids are
still live in this po, and roughly half the sentences survived the move
verbatim, so they are translated here rather than skipped.

Verified: msgids unchanged, no line over 80 columns, po syntax clean.

Day 4 remaining: 53 -> 0. Day 1-4 remaining: 233 -> 180.
The remaining 83 Day 2 entries: 59 stale fuzzy translations rediffed against
the current English, 24 never translated.

Several were shifted onto a neighbouring entry, so the Chinese described
something else entirely:

  Associated Types                        共享类型 -> 关联类型
  Implementing Traits                     实现 Unsafe Trait -> 实现特征
  Generic Traits                          泛型 -> 泛型特征
  `let else` expressions                  `while let` 表达式 -> `let else` 表达式
  `|` as an `or`                          解释模式匹配中的绑定的原理…
  `..` can expand as much as…             你可以展示如何匹配一个引用。
  `1..=5` represents an inclusive range   现在是一个讲解不可反驳模式的好时机…
  Show students the `Ord` trait…          [“OsStr”](…)和[“OsString”](…)

Factual fixes:

  `Result` is the standard type…as we will see on Day 4   第 3 天 -> 第 4 天
  The `_` pattern…expressions _must_ be exhaustive        不可反驳 -> 穷尽的
  The partial struct initialization…                      结构体副本 -> 部分初始化
  Unlike `match`, `if let` does not have to cover all
  branches                                                the old text claimed
                                                          if let lacks guard
                                                          clauses, unrelated

Also repairs std-traits/default.md, which was live rather than fuzzy and so
was rendering mangled backticks:

  标准的 Rust 类型通常会以合理的值(例如 ` 0`\"\" \``等)实现`Default\``。
  -> 标准的 Rust 类型通常会用合理的值实现 `Default`(例如 `0`、`\"\"` 等)。

and std-types/string.md, where `&\*s1` had a backslash inside a code span and
the surrounding code spans used curly quotes.

Verified: msgids unchanged, po syntax clean. Four new lines exceed 80 columns;
each is a single unbreakable markdown link, same as the 14 already in the file.

Day 2 remaining: 83 -> 0. Day 1-4 remaining: 180 -> 97 (Day 1 only).
The file mixed both second-person forms: 99 你 against 230 您, the latter
mostly left over from the original machine translation. Every translation
written on this branch uses 你, so normalise the rest to match.

Mechanical replacement of every 您 with 你. 你 and 您 are both full-width, so
no line needed rewrapping. 您 appears in no msgid, and the 41 occurrences
outside live msgstr are in obsolete #~ entries, replaced for consistency in
case msgmerge ever revives one.

271 occurrences, no other change. msgids unchanged, po syntax clean.
…d types)

The remaining 97 Day 1 entries: 77 stale fuzzy translations rediffed against
the current English, 20 never translated. Day 1-4 is now fully translated.

Entries whose translation had drifted onto an unrelated one:

  The [`for` loop] iterates over ranges…   [`Drop`] 用于定义析构函数。
  The [`loop` statement] just loops…       [`Drop`] 用于定义析构函数。
  `println!(format, ..)` prints a line…    运算符重载是通过 [`std::ops`] 中的特征实现的:
  `s` is a reference to a slice of `i32`s  切片会从另外一个对象中借用数据…
  Slices always borrow from another object 关于修改 `a[3]` 的问题可能会引发…
  What is the type of this variable?       每个循环中的“word”是什么类型?
  Welcome Back                             欢迎

Factual fixes:

  think of `&str` as `std::string_view`    old text said `const char*`
  …wraps in a release build                封装 (wrapping/boxing) -> 回绕
  `static` is similar to mutable global
  variables in C++                         old text said it resembles `const`
  Be sure to note the difference between
  `let mut x_coord` and `let x_coord: &mut` old text called the first one a
                                            mutable reference
  Rust is very much like other languages…  old text added 「而非函数式」, not
                                            in the source
  Rust uses macros…[overloading](…)        link pointed at a path that has not
                                            existed since the 2023 restructure

Also makes the two timing strings consistent across all four days, which
previously both rendered as 本节:

  "In this session:" / "this session should take about"  -> 本场  (half-day)
  "In this segment:" / "This segment should take about"  -> 本节  (chapter)

That touches six entries outside Day 1 which were translated earlier on this
branch.

Verified: msgids unchanged, po syntax clean. Two new lines exceed 80 columns,
both a single unbreakable URL.

Day 1 remaining: 97 -> 0. Day 1-4 remaining: 97 -> 0.
@google-cla

google-cla Bot commented Aug 1, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

These 86 entries were neither fuzzy nor empty, so they never showed up as
outstanding work — they were already "translated" and were being rendered, just
rendered wrong.

75 entries / 128 occurrences: a code span in the source had become a pair of
Chinese quotation marks in the translation, so it rendered as proportional text
instead of monospace.

  EN: Only functions marked `const` can be called at compile time…
  ZH: 在编译时只能调用标记为“const”的函数…   ->   标记为 `const` 的函数

Applied only where the quoted text appears verbatim as a code span in the
msgid, which a genuine Chinese quotation never does; `“2”`, `“=>”` and similar
were left alone because the msgid has no matching span.

5 entries: a markdown link had been pulled apart so nothing rendered as a link.

  ZH: 适用于 [`rust_static_library` gn 模板] 的选项 (https://…)
  ->  [`rust_static_library` gn 模板](https://…)可用的选项

  memory-management/review.md had lost the System Allocator URL entirely and
  kept only \[系统分配器\].

3 entries: unbalanced backticks (`Cargo.toml``, `next() 及其, `LinesReader).

3 entries: `_x_` with a Han character on both sides, which CommonMark does not
treat as emphasis, so the underscores rendered literally. async/runtimes.md was
worse — both closing underscores were missing, so the surviving pair italicised
everything between 反应器 and 执行器.

Found by scanning all 3301 rendering entries for markdown that differs
structurally from its msgid. Verified against a local zh-CN `mdbook build`:
`标记为<code>const</code>的函数`, `<em>降级</em>`, and the System Allocator
anchor all render correctly now.

Of the 86, 72 correspond to strings still present in the source; the other 14
are in entries the source has since dropped.

msgids unchanged, po syntax clean.
@TianfangChang
TianfangChang marked this pull request as ready for review August 1, 2026 05:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant