|
| 1 | +# Documentation translations |
| 2 | + |
| 3 | +The English pages under `docs/` are the source of truth. This directory holds |
| 4 | +what steers their machine translation (human-authored) and the generated |
| 5 | +result; the public-facing explanation is [`docs/translations.md`](../docs/translations.md). |
| 6 | + |
| 7 | +- `languages.yml` — the language registry (one entry per translated site, |
| 8 | + served at `/<code>/`), the pages that stay English, the model IDs, and the |
| 9 | + English text of the notices staged onto every translated page. |
| 10 | +- `general-prompt.md` — the translation rules shared by every language. |
| 11 | +- `<code>/instructions.md` — register, voice, humour and typography for one |
| 12 | + language. Human-authored. |
| 13 | +- `<code>/glossary.json` — the termbase for one language: terms that stay in |
| 14 | + English, required renderings, and banned ones (`"enforce": true` makes a ban |
| 15 | + a hard check). Human-authored. |
| 16 | +- `<code>/pages/` and `<code>/state.json` — generated: the translated pages and |
| 17 | + the record of what each was made from (English content and section hashes, prompt |
| 18 | + inputs, model, timestamp), plus the translated sidebar labels and notices. Never |
| 19 | + edited by hand. |
| 20 | + |
| 21 | +## The tool |
| 22 | + |
| 23 | +`scripts/docs/translations.py` (run from the repository root): |
| 24 | + |
| 25 | +```bash |
| 26 | +uv run --frozen --group docs python scripts/docs/translations.py status # missing/outdated/current per language |
| 27 | +uv run --frozen --group docs python scripts/docs/translations.py translate --lang ja # translate what is missing or outdated |
| 28 | +uv run --frozen --group docs python scripts/docs/translations.py stage --lang ja # the docs tree the ja site builds from |
| 29 | +``` |
| 30 | + |
| 31 | +`translate` calls the Claude API (set `ANTHROPIC_API_KEY` or |
| 32 | +`ANTHROPIC_AUTH_TOKEN`). It re-translates only the `##` sections whose English |
| 33 | +changed and carries the rest of the page over byte-for-byte from the previous |
| 34 | +translation, then gates the result: heading anchors and code blocks are |
| 35 | +re-imposed from the English, the page's structure (headings, code fences, |
| 36 | +links, admonitions, glossary rules) is checked with the findings fed back for |
| 37 | +another attempt, and a stronger model reviews the meaning against the English. |
| 38 | +`--pages a.md b.md` narrows a run (a page that is already current comes back |
| 39 | +unchanged), `--fresh` re-translates from scratch instead of updating (every |
| 40 | +page when no `--pages` are given — the way to redo a language after a model |
| 41 | +change), `--dry-run` shows what it would do, and `--no-verify` skips the |
| 42 | +meaning review. A page that failed its gates keeps its previous translation and |
| 43 | +the run exits non-zero; translations whose English page has left the nav are |
| 44 | +deleted. Everything else is offline; `scripts/docs/build.sh` runs `stage` for |
| 45 | +each language and builds it at `site/<code>/`. |
| 46 | + |
| 47 | +## Correcting a translation |
| 48 | + |
| 49 | +Never edit a file under `<code>/pages/` — the next run overwrites it. Fix the |
| 50 | +input instead: a wrong term goes into `glossary.json`, a recurring style or |
| 51 | +register problem into `instructions.md`, and ambiguous English into the page |
| 52 | +under `docs/`. Editing a glossary or instructions marks that language's pages |
| 53 | +outdated, so the next `translate` run regenerates them with the fix in place. |
| 54 | +Readers report problems through the "Translation problem" issue form. |
| 55 | + |
| 56 | +## Staleness |
| 57 | + |
| 58 | +A page is *current* when the English content and the prompt inputs it was |
| 59 | +translated from are unchanged, *outdated* otherwise, and *missing* when it has |
| 60 | +no translation. The build serves an outdated translation with a warning |
| 61 | +notice, unless the English page's links or heading anchors moved under it — |
| 62 | +then the English page is served until the next `translate` run refreshes it. |
| 63 | +Untranslated and excluded pages are served in English with a notice. |
| 64 | + |
| 65 | +## Adding a language |
| 66 | + |
| 67 | +Add an entry to `languages.yml` (`code`, native `name`; `theme_language` and |
| 68 | +`hreflang` default to the code and must be values the theme knows), write |
| 69 | +`<code>/instructions.md` and `<code>/glossary.json` (start from an existing |
| 70 | +language), then run `translate --lang <code>` and commit the generated `pages/` |
| 71 | +and `state.json`. Also name the language in `docs/translations.md` and the |
| 72 | +"Translation problem" issue form's dropdown. |
0 commit comments