Tłumaczenie maszynowe, niezweryfikowane przez osobę, dla której polski jest językiem ojczystym. Wzorcem jest wersja angielska.

Na początekJeszcze nie na GitHubŹródło: docs/i18n.md

Lokalizacja silnika

Tekst silnika przeznaczony dla człowieka jest w 17 językach obok angielskiego: nl, pl, pt-BR, pt-PT, fi, sv, da, nb, cs, uk, ru, de, fr, es, et, ja, zh-Hans. Źródłem jest angielski; en-XA to pseudolokalizacja, która akcentuje, ujmuje w nawiasy i dopełnia każdy komunikat, aby test mógł zobaczyć, czy tekst został przeniesiony do katalogu. Framework to Project Fluent (fluent-bundle, unic-langid); kod to src/i18n/.

Co jest lokalizowane, a co nigdy#

Lokalizowane (czyta człowiek) Nigdy nielokalizowane (czyta program)
komunikaty i błędy wiersza poleceń klucze i wartości JSON w result.json i report.json
wiersz podsumowania każdego przebiegu nagłówki i wiersze CSV
tekst wykresów SVG (tytuły, osie, legendy, podpisy) nazwy plików
report.html: nagłówki, tabele, uwagi, podpisy kody błędów (E-CLOCK-VERSION)
słowa werdyktów (VALIDATED, MODELLED, PARTIAL) macierz weryfikacji, definicje jednostek, pochodzenie
opisy rodzajów scenariuszy (list_kinds(lang))
oświadczenia doradcze, zastrzeżenia i informacje (engine-legal-*) te same teksty wewnątrz JSON, które pozostają po angielsku
report.html kampanii iq, strony porównania badań, tabeli wyników bench, raportu odporności summary.html pakietu dowodowego i PNG obserwatorium: oba są skrótowane do manifestu (pakiet jest dodatkowo podpisany), więc powstają po angielsku niezależnie od języka

Liczby w tekście przeznaczonym dla człowieka używają znaku dziesiętnego danego języka (przecinek w 15 z 18 języków; kropka w en, ja, zh-Hans i en-XA). Liczby w plikach maszynowych zawsze używają kropki. Licznik (zmienna o nazwie n, count, n_*, num_* lub *_count) trafia do Fluent jako liczba, więc tłumaczenie może zapisać { $n -> [one] ... [few] ... *[other] ... }.

Wybór języka#

  • Wiersz poleceń: --lang <tag>, potem KSHANA_LANG, LC_ALL, LC_MESSAGES, LANG, a następnie angielski. pt to pt-BR; tylko pt-PT oznacza Portugalię. zh to uproszczony; tradycyjny jest odrzucany z listą obsługiwanych znaczników.
  • Biblioteka: api::run_toml_lang(toml, lang), run_toml_bilingual, run_toml_human, run_scenario_lang, list_scenario_kinds_json_lang(lang).
  • Python: lang=None w run, run_full, run_typed, validate_toml, error_kind, list_kinds, scenario_kinds; run_human(toml, lang); error_info(toml, lang).
  • WebAssembly: opcjonalny końcowy lang w run_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: lang w run_scenario i list_scenario_kinds.

Błędy i ich kody#

Każdy komunikat o błędzie ma stabilny kod, czyli identyfikator komunikatu wielkimi literami (e-clock-version to E-CLOCK-VERSION), taki sam w każdym języku. Angielski tekst wiersza poleceń pozostaje bez zmian. W innym języku wiersz ma postać text [E-CODE]; z --verbose w każdym języku następuje drugi wiersz code: E-CODE. API udostępnia KshanaError::code() i error_info ({kind, code, message}); błędy MCP niosą {kind, code, message} jako dane błędu. Dopasowuj po kodzie, nigdy po tekście.

Jak działa przebieg w innym języku (zasada podwójnego przebiegu)#

Plik maszynowy nie może zależeć od języka. Przebieg w innym języku wykonuje więc scenariusz dwa razy: raz po angielsku, a jego result.json, report.json i CSV są plikami maszynowymi, i raz w języku użytkownika, dla podsumowania, wykresu i report.html. Angielski to jeden przebieg, bajt w bajt taki, jaki był wcześniej.

Zmierzone, natywnie, kompilacja wydaniowa, angielski, a potem --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żdy inny dołączony scenariusz trwa poniżej 4 s; 173 scenariuszy dołączonych w chwili pomiaru zajęło razem 64 s po angielsku. Koszt dla innego języka jest dokładnie dwukrotny. WebAssembly nie zostało zmierzone (brak tu wasm-bindgen); przy współczynniku przeglądarki około 4 to minuta dla najwolniejszego rodzaju.

Strona unika oczekiwania, pokazując od razu wynik angielski i wywołując potem run_human(toml, lang): to jest sam drugi przebieg, zwraca {summary, svg}, a Studio może wyświetlać „tłumaczenie...” do chwili jego nadejścia.

Pozycja 0,41: jeden przebieg. Wygenerować oba z zapisu (message id, arguments). Rozważono to i nie zbudowano: wyniki t! są sprawdzane, mierzone i skrótowane po ich utworzeniu (szerokości tekstu wykresów, skróty pochodzenia nad tekstem wyników), a num() formatuje w miejscu wywołania, więc zapis wprowadziłby do plików maszynowych znaczniki zastępcze i uzależniłby ich bajty od odtworzenia. Wymaga to t!/num zwracających znaczniki, finalizatora w każdym zapisującym oraz dowodu identyczności bajtów dla każdego zapisującego.

WebAssembly#

Kompilacja wasm zawiera tylko katalog angielski. Pozostałe szesnaście dodałoby około 150 kB gzip każdy. Strona pobiera i18n/<lang>/engine.ftl po wyborze języka i wywołuje register_catalogue(tag, text); jeśli pobranie lub rejestracja się nie powiedzie, strona pozostaje po angielsku. Natywnie wiersz poleceń i pakiet Pythona zawierają wszystkie 18.

Rozmiar, nieoptymalizowany .wasm z cargo build --release --target wasm32-unknown-unknown --features wasm --lib (przed wasm-bindgen i wasm-opt), podstawa bc04e98f wobec tej gałęzi: 18,71 MB -> 19,88 MB surowo, 5,43 MB -> 5,79 MB gzip, +357 kB gzip. Katalog angielski ma 521 kB surowo, z czego 153 kB gzip; reszta to fluent-bundle i jego zależności. Przyjęto to tak, jak zmierzono.

Katalog#

i18n/<tag>/engine.ftl zawiera komunikaty, z identyfikatorami z przedrostkiem engine-. i18n/en/engine.ftl jest źródłem; pozostałe pliki należą do tłumaczy i mogą nie zawierać komunikatów (każdy komunikat w razie braku wraca do angielskiego). Listy towarzyszące w i18n/en/: engine-counts.txt (komunikaty ze zmiennymi licznikowymi, dla form liczby), engine-numbers.txt (liczby przekazywane jako placeables), engine-fragments.txt (komunikaty będące fragmentami zdania składanego w czasie działania: do scalenia w komunikaty pełnych zdań, nigdy nie do powiększania).

Testy#

tests/i18n_catalogue.rs dowodzi poprawności angielskiego: każdy komunikat ma zapisany szablon oryginału i renderuje się dokładnie do tego tekstu; każdy identyfikator jest używany; zmienne się zgadzają; pseudolokalizacja renderuje każdy komunikat. i18n_api.rs, i18n_kinds.rs, i18n_legal.rs obejmują punkty wejścia, opisy rodzajów i teksty prawne. i18n_ratchet.rs kończy się niepowodzeniem, jeśli nowy literał łańcuchowy, który czytałby człowiek, omija katalog: dopuszczenie dla pliku w tests/fixtures/i18n/allow.json, które może maleć i nigdy rosnąć. scripts/i18n_compare.py uruchamia całe scenariusze plikiem binarnym bazowym i bieżącym i porównuje każdy plik wyjściowy.

Jak przenieść łańcuch do katalogu: docs/design/i18n-migration.md.

Zależności i licencje#

Framework dodaje fluent-bundle 0,16 (Apache-2.0 OR MIT) i unic-langid 0,9 (MIT OR Apache-2.0), z ich tranzytywnymi crate'ami: fluent-syntax i 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: używana jest alternatywa Apache-2.0, którą deny.toml dopuszcza), tinystr i zerovec (Unicode-3.0), rustc-hash, smallvec, thiserror, displaydoc (MIT OR Apache-2.0). Każda z nich jest permisywna według listy allow z deny.toml; thiserror występuje w dwóch wersjach (1 i 2), o czym multiple-versions = "warn" tylko informuje. Listę licencji odczytano z cargo metadata; cargo deny check nie jest zainstalowane w środowisku autorskim i działa w CI integracyjnym.