Lokalizace enginu
Text enginu určený lidem je v 17 jazycích vedle angličtiny: nl, pl, pt-BR, pt-PT, fi, sv, da, nb, cs, uk, ru, de, fr, es, et, ja, zh-Hans. Zdrojem je angličtina; en-XA je pseudolokalizace, která každou zprávu opatří diakritikou, závorkami a výplní, aby test mohl zjistit, zda se text přesunul do katalogu. Frameworkem je Project Fluent (fluent-bundle, unic-langid); kód je src/i18n/.
Co se lokalizuje a co nikdy#
| Lokalizuje se (čte to člověk) | Nikdy se nelokalizuje (čte to program) |
|---|---|
| zprávy a chyby příkazového řádku | klíče a hodnoty JSON v result.json a report.json |
| souhrnný řádek každého běhu | hlavičky a řádky CSV |
| text grafů SVG (názvy, osy, legendy, popisky) | názvy souborů |
report.html: nadpisy, tabulky, poznámky, popisky |
kódy chyb (E-CLOCK-VERSION) |
| slova verdiktů (VALIDATED, MODELLED, PARTIAL) | verifikační matice, definice jednotek, původ |
popisy druhů scénářů (list_kinds(lang)) |
|
poradní prohlášení, vyloučení odpovědnosti a upozornění (engine-legal-*) |
tytéž texty uvnitř JSON, které zůstávají anglicky |
report.html kampaně iq, stránky srovnání studií, žebříčku bench, zprávy o odolnosti |
summary.html balíčku důkazů a PNG observatoře: oba jsou zahrnuty do hashe manifestu (balíček je navíc podepsán), takže se vytvářejí anglicky bez ohledu na jazyk |
Čísla v textu určeném lidem používají desetinné znaménko daného jazyka (čárku v 15 z 18 jazyků; tečku v en, ja, zh-Hans a en-XA). Čísla ve strojových souborech vždy používají tečku. Počet (proměnná pojmenovaná n, count, n_*, num_* nebo *_count) se do Fluentu dostane jako číslo, takže překlad smí psát { $n -> [one] ... [few] ... *[other] ... }.
Volba jazyka#
- Příkazový řádek:
--lang <tag>, pakKSHANA_LANG,LC_ALL,LC_MESSAGES,LANG, pak angličtina.ptje pt-BR; jenpt-PTje portugalština z Portugalska.zhje zjednodušená; tradiční je odmítnuta se seznamem podporovaných značek. - Knihovna:
api::run_toml_lang(toml, lang),run_toml_bilingual,run_toml_human,run_scenario_lang,list_scenario_kinds_json_lang(lang). - Python:
lang=Noneurun,run_full,run_typed,validate_toml,error_kind,list_kinds,scenario_kinds;run_human(toml, lang);error_info(toml, lang). - WebAssembly: volitelné koncové
langurun_typed,run,chart_svg,summary,table_csv,run_all,error_kind,list_kinds,scenario_kinds;run_human(toml, lang);error_info(toml, lang);register_catalogue(tag, ftl_text). - MCP:
langurun_scenarioalist_scenario_kinds.
Chyby a jejich kódy#
Každá chybová zpráva má stabilní kód, id zprávy velkými písmeny (e-clock-version je E-CLOCK-VERSION), stejné ve všech jazycích. Anglický text příkazového řádku se nemění. V jiném jazyce je řádek text [E-CODE]; s --verbose následuje ve všech jazycích druhý řádek code: E-CODE. API poskytuje KshanaError::code() a error_info ({kind, code, message}); chyby MCP nesou {kind, code, message} jako data chyby. Porovnávejte podle kódu, nikdy podle textu.
Jak běh funguje v jiném jazyce (pravidlo dvojího běhu)#
Strojový soubor nesmí záviset na jazyku. Běh v jiném jazyce proto spouští scénář dvakrát: jednou v angličtině, jejíž result.json, report.json a CSV jsou strojové soubory, a jednou v jazyce uživatele pro souhrn, graf a report.html. Angličtina je jeden běh, bajt po bajtu stejný jako dříve.
Změřeno, nativně, sestavení release, angličtina a pak --lang de (sekundy): leo-navmsg-fit-interval-trade 9,2 -> 17,9, cislunar-arc-recovery 7,8 -> 14,1, lunar-station-coverage 7,8 -> 15,0, clock-ensemble 5,8 -> 11,6, leo-navmsg-model-comparison 5,1 -> 10,5, leo-ppp-convergence 2,8 -> 6,2; každý další přibalený scénář trvá méně než 4 s; 173 scénářů přibalených v době měření dohromady trvalo v angličtině 64 s. Cena je přesně dvojnásobná pro jiný jazyk. WebAssembly nebylo měřeno (zde není wasm-bindgen); při faktoru prohlížeče asi 4 je to u nejpomalejšího druhu minuta.
Stránka se čekání vyhne tím, že okamžitě ukáže anglický výsledek a poté zavolá run_human(toml, lang): to je samotný druhý běh, vrací {summary, svg} a Studio může říkat „překládám…“, dokud nedorazí.
Položka 0,41: jeden běh. Vykreslit obojí ze záznamu (message id, arguments). Bylo posouzeno a nebylo vybudováno: výsledky t! se po vytvoření kontrolují, měří a hashují (šířky textu grafů, hashe původu nad výstupním textem) a num() formátuje v místě volání, takže by záznam vložil zástupné tokeny do strojových souborů a učinil by jejich bajty závislými na přehrání. Vyžaduje t!/num vracející tokeny, finalizátor u každého zapisovače a důkaz bajtové shody u každého zapisovače.
WebAssembly#
Sestavení wasm vkládá jen anglický katalog. Ostatních šestnáct by přidalo každý asi 150 kB gzip. Stránka při volbě jazyka stáhne i18n/<lang>/engine.ftl a zavolá register_catalogue(tag, text); pokud selže stažení nebo registrace, stránka zůstane v angličtině. Nativně, příkazový řádek a wheel Pythonu vkládají všech 18.
Velikost neoptimalizovaného .wasm z cargo build --release --target wasm32-unknown-unknown --features wasm --lib (před wasm-bindgen a wasm-opt), základ bc04e98f proti této větvi: 18,71 MB -> 19,88 MB surově, 5,43 MB -> 5,79 MB gzip, +357 kB gzip. Anglický katalog má 521 kB surově, z toho 153 kB gzip; zbytek je fluent-bundle a jeho závislosti. Toto je přijato tak, jak bylo změřeno.
Katalog#
i18n/<tag>/engine.ftl obsahuje zprávy s id s předponou engine-. i18n/en/engine.ftl je zdroj; ostatní soubory jsou překladatelů a mohou některé zprávy postrádat (každá se vrací k angličtině po zprávách). Doprovodné seznamy v i18n/en/: engine-counts.txt (zprávy s proměnnými počtu, pro tvary množného čísla), engine-numbers.txt (čísla předávaná jako placeables), engine-fragments.txt (zprávy, které jsou kusy věty skládané za běhu: mají být sloučeny do zpráv o celé větě a nikdy nepřibývat).
Testy#
tests/i18n_catalogue.rs dokazuje angličtinu: každá zpráva má zaznamenanou původní šablonu a vykreslí se přesně na tento text; každé id je použito; proměnné souhlasí; pseudolokalizace vykreslí každou zprávu. i18n_api.rs, i18n_kinds.rs, i18n_legal.rs pokrývají vstupní body, popisy druhů a právní texty. i18n_ratchet.rs selže, pokud nový řetězcový literál, který by člověk četl, obejde katalog: povolení po souborech v tests/fixtures/i18n/allow.json, které smí klesat a nikdy růst. scripts/i18n_compare.py spouští celé scénáře s referenčním a současným binárním souborem a porovnává každý výstupní soubor.
Jak přesunout řetězec do katalogu: docs/design/i18n-migration.md.
Závislosti a licence#
Framework přidává fluent-bundle 0,16 (Apache-2.0 OR MIT) a unic-langid 0,9 (MIT OR Apache-2.0) s jejich tranzitivními crates: fluent-syntax a fluent-langneg (Apache-2.0 OR MIT), intl-memoizer (Apache-2.0 OR MIT), intl_pluralrules (Apache-2.0/MIT), type-map (MIT/Apache-2.0), self_cell (Apache-2.0 OR GPL-2.0-only: používá se alternativa Apache-2.0, kterou deny.toml povoluje), tinystr a zerovec (Unicode-3.0), rustc-hash, smallvec, thiserror, displaydoc (MIT OR Apache-2.0). Každá je permisivní podle seznamu allow v deny.toml; thiserror se objevuje ve dvou verzích (1 a 2), což multiple-versions = "warn" jen hlásí. Seznam licencí byl přečten z cargo metadata; cargo deny check není v autorském prostředí nainstalován a běží v integračním CI.