* M14: translation catalogs, same system as PhotoCraft Move the interface translations to PhotoCraft's i18n system: one TSV catalog per language (crates/ui-egui/src/i18n/ja.tsv), the tl! macro, entries keyed by command id, context or plural forms, and catalog tests (format, duplicates, placeholders, command ids). The 49 existing Japanese strings move over unchanged, plus "Auto". The language preference now defaults to "auto" and follows the system language (English when it has no catalog); "en" and "ja" still persist and unknown values are rejected. Update docs/localization.md, ROADMAP.md and the misc.prefs-language parity entry. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> * M14: strict catalog validation, one-pass fmt, translation assets Fold in the infrastructure parts of #175: - `fmt` fills placeholders in one pass, so inserted values (a file name containing `{n}`) are never substituted again. - Catalog validation rejects unknown escapes, unknown `@` contexts, placeholder, ellipsis and plural-form mismatches and duplicates. The bundled catalogs must have no errors (tests); at run time a bad line is still only skipped and logged, so the rest of the catalog loads. - `.tsv` files count as assets in `cargo xtask assets`, with a `translation` kind that may never come from Adobe; ja.tsv gets its ATTRIBUTION.toml entry. - Control-channel test: switching the language keeps documents, their dirty state and command ids. Also make the drawing language thread-local, as in PhotoCraft, so parallel kittest harnesses can't change each other's language. Co-Authored-By: 才倾梦华V <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]> Co-authored-by: Brandon Thomas <[email protected]> Co-authored-by: 才倾梦华V <[email protected]>
3.4 KiB
Interface language
Choose Edit > Preferences > Interface language and select Auto, English or 日本語. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged.
Auto (the default) follows the system language: LC_ALL, LC_MESSAGES or LANG, then the preferred-languages list on macOS. A system language without a catalog, such as French, shows English. Windows has no system-language detection yet, so Auto shows English there unless LANG is set.
The control channel exposes the setting through ui.set:
{"method":"ui.set","params":{"key":"language","value":"ja"}}
The value is auto or a language code (en, ja), in any case. ui.state reports language as written in the preferences (auto, en or ja). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language.
This first translation pass covers the main menu and core registered menu commands. Untranslated labels use English. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing.
Japanese interface text uses BIZ UDPGothic from craft-fonts, an optional build input that every release includes (CRAFT_FONTS_DIR; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes.
How translations work
PdfCraft uses the same system as PhotoCraft (crates/ui-egui/src/i18n/):
- Strings in the code stay in English and serve as lookup keys. At draw time,
tl!("Save")returns the text in the current language, and falls back to English when there is no entry. - Each language has a catalog,
crates/ui-egui/src/i18n/<code>.tsv, with one entry per line:context<TAB>English<TAB>translation. An empty context marks a plain string.@idkeys an entry by command id (for examplefile.saveAs), so one menu item can read differently from another with the same English label.@pluralholds plural forms. Any other context disambiguates an English word with several meanings (tr_ctx). The header ofja.tsvdocuments the format and escapes. - Placeholders (
{name}) must appear in both columns. A trailing…must be kept.i18n::fmtfills placeholders in one pass, so a value such as a file name containing{n}is inserted as written. - Catalogs are validated strictly: unknown escapes, unknown
@contexts, placeholder or ellipsis mismatches, wrong plural form counts and duplicates are errors. The tests require the bundled catalogs to have none; at run time a bad line is skipped (and logged) and that string shows in English. - Catalogs are assets: each
.tsvhas anATTRIBUTION.tomlentry withkind = "translation"and its SHA-256, checked bycargo xtask assets. - Translations are clean-room: write them from the meaning of the English text, never from another product's string tables.
Adding a language
- Copy the header of
ja.tsvintoxx.tsvand translate entries. - Add one row to
LANGUAGESincrates/ui-egui/src/i18n/mod.rs: code, native name, catalog and plural rule. - Add an
ATTRIBUTION.tomlentry for the catalog (kind = "translation"), then runcargo xtask assets --writeandcargo xtask assets.
The Preferences dropdown, the system-language match and the catalog tests (format, duplicates, placeholders, plural forms, command ids) then pick it up.