Files
pdfcraft/docs/localization.md
T
ec980d0743 fix(i18n): follow Windows display language for Chinese UI (#216)
* fix(i18n): follow Windows display language for Chinese UI

M14: resolve Auto through the Windows UI culture after locale environment
variables. Reuse Chinese region/script mapping and cover the query and
fallback behavior.

Refs #215

Co-authored-by: Codex <[email protected]>

* Windows Auto language: ask Windows directly instead of starting PowerShell

sys-locale (1Password, MIT OR Apache-2.0) reads GetUserPreferredUILanguages, so
Auto no longer launches a hidden powershell.exe at startup (slow, and the kind of
behaviour endpoint security tools flag). All preferred display languages are
tried in order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Codex <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-08 01:19:07 -04:00

5.6 KiB

Interface language

Choose Menu > Edit > Preferences… (Command-comma on macOS, Ctrl-comma elsewhere) > Interface language and select Auto, English, 日本語, 简体中文, 繁體中文, Čeština or Português (Brasil). 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. Any Portuguese locale (pt_BR, pt_PT) uses the Brazilian catalog, and Chinese locales for Taiwan, Hong Kong and Macau (zh_TW, zh_HK, zh_MO, zh-Hant) the Traditional Chinese one; other Chinese locales (zh, zh_CN, zh_SG, zh-Hans) the Simplified Chinese one. A system language without a catalog, such as French, shows English. On Windows, Auto uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. The query asks Windows directly (GetUserPreferredUILanguages, through the sys-locale crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English.

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, zh-hans, zh-hant, cs, pt-br), in any case. ui.state reports language as written in the preferences (auto, en, ja, zh-hans, zh-hant, cs or pt-br). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language.

Dialogs, panels, menus, notices and history labels go through the catalog (tl!). Japanese, Traditional Chinese and Simplified Chinese translate them (about 1,800 entries each); Czech and Brazilian Portuguese cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. 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. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the Hans faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Czech and Brazilian Portuguese need only the bundled Latin faces (tested in tests/fonts.rs).

Simplified Chinese coverage tests, following PhotoCraft's complete-catalog approach, check every registered command, All tools label and tl!("literal") in the UI source. Generated history labels and diagnostics are also tested with user-supplied names and error details. Catalog coverage does not guarantee glyph coverage: the release-pinned craft-fonts input currently has no Hans face, and the web build embeds only BIZ UDPGothic Regular. Chinese font delivery remains separate work, as discussed in #112 and #140.

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. @id keys an entry by command id (for example file.saveAs), so one menu item can read differently from another with the same English label. @plural holds plural forms. Any other context disambiguates an English word with several meanings (tr_ctx). The header of ja.tsv documents the format and escapes.
  • Placeholders ({name}) must appear in both columns. A trailing … must be kept. i18n::fmt fills 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 .tsv has an ATTRIBUTION.toml entry with kind = "translation" and its SHA-256, checked by cargo 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

  1. Copy the header of ja.tsv into xx.tsv and translate entries.
  2. Add one row to LANGUAGES in crates/ui-egui/src/i18n/mod.rs: code, native name, catalog and plural rule.
  3. Add an ATTRIBUTION.toml entry for the catalog (kind = "translation"), then run cargo xtask assets --write and cargo xtask assets.

The Preferences dropdown, the system-language match and the catalog tests (format, duplicates, placeholders, plural forms, command ids) then pick it up.