mirror of
https://github.com/storytold/filmcraft.git
synced 2026-11-02 18:09:21 +00:00
i18n: Russian catalog covers the whole interface
- ru.tsv: all 3,592 strings of the reference catalog (was 355), translated from the English sources with ordinary, Premiere-style Russian vocabulary. Fixes the known mistranslations (Sequence -> Последовательность, Bin -> Корзина, Lumetri Scopes -> Осциллограммы Lumetri, Wipe -> Вытеснение, Normalize Mix Track, «мастер-дорожка») and applies one glossary throughout. - Tests: russian_covers_the_whole_interface requires every Spanish entry and no dead ones; a font test covers the Cyrillic alphabet including «ё»; System Language maps ru-* to Russian. - Docs: localization-parity, roadmap, gaps, ROADMAP, the ui-egui README and the catalog's attribution sidecar.
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ iconography, images or other Adobe assets; open licences only; every asset attri
|
||||
| `crates/ui-egui/src/i18n/ko.tsv` | FilmCraft contributors | Original work: clean-room Korean interface translations | MIT OR Apache-2.0 |
|
||||
| `crates/ui-egui/src/i18n/fr.tsv` | FilmCraft contributors | Original work: clean-room French interface translations | MIT OR Apache-2.0 |
|
||||
| `crates/ui-egui/src/i18n/pt-br.tsv` | FilmCraft contributors | Original work: clean-room Brazilian Portuguese interface translations | MIT OR Apache-2.0 |
|
||||
| `crates/ui-egui/src/i18n/ru.tsv` | FilmCraft contributors | Original work: clean-room Russian interface translations | MIT OR Apache-2.0 |
|
||||
| `crates/ui-egui/src/i18n/ru.tsv` | FilmCraft contributors | Original work: clean-room Russian interface translation (full catalog) | MIT OR Apache-2.0 |
|
||||
| `crates/ui-egui/src/i18n/uk.tsv` | FilmCraft contributors | Original work: clean-room Ukrainian interface translations | MIT OR Apache-2.0 |
|
||||
| `assets/fonts/Inter-Regular.ttf` | The Inter Project Authors | https://github.com/rsms/inter | OFL-1.1 (`assets/fonts/OFL-Inter.txt`) |
|
||||
| `assets/fonts/Inter-Medium.ttf` | The Inter Project Authors | https://github.com/rsms/inter | OFL-1.1 (`assets/fonts/OFL-Inter.txt`) |
|
||||
|
||||
+2
-1
@@ -72,7 +72,7 @@ Evidence for every row: [docs/target-app-parity.md](docs/target-app-parity.md#by
|
||||
|
||||
## Languages
|
||||
|
||||
Premiere ships 10 interface languages. Measured from our catalogs (3,498 strings):
|
||||
Premiere ships 10 interface languages. Measured from our catalogs (3,593 strings, last measured 2026-10-19):
|
||||
|
||||
| Language | Status | Strings |
|
||||
|---|---|---|
|
||||
@@ -86,6 +86,7 @@ Premiere ships 10 interface languages. Measured from our catalogs (3,498 strings
|
||||
| Indonesian | partial (whole interface; native review welcome) | ~100% |
|
||||
| Italian | partial (whole interface; native review welcome) | ~100% |
|
||||
| Korean | partial (whole interface; needs an installed Hangul font; native review welcome) | ~100% |
|
||||
| Russian | partial (whole interface; native review welcome) | ~100% |
|
||||
| Japanese | partial (whole interface) | 99.7% |
|
||||
| German | partial (whole interface; menus native-reviewed, the rest welcome) | ~100% |
|
||||
| Vietnamese | none | 0% |
|
||||
|
||||
@@ -18,8 +18,8 @@ the committed span and undo. Set `FILMCRAFT_UI_SNAPSHOT_DIR` to render screensho
|
||||
## Localisation
|
||||
|
||||
Edit > Language offers English, Japanese, Spanish, Brazilian Portuguese, Ukrainian, Simplified
|
||||
Chinese, German, Russian, French, Indonesian, Korean and Italian (all but Ukrainian and Russian cover
|
||||
the whole interface; those two cover the core menus). The language is stored in the engine's `general.interfaceLanguage` preference,
|
||||
Chinese, German, Russian, French, Indonesian, Korean and Italian (all but Ukrainian cover
|
||||
the whole interface; Ukrainian covers the core menus). The language is stored in the engine's `general.interfaceLanguage` preference,
|
||||
restored on startup, and also available in Settings > General.
|
||||
Its default, System Language (`system`), follows the operating system: the first of the user's
|
||||
preferred languages that the interface has (the host supplies them through
|
||||
@@ -33,10 +33,11 @@ fills translated templates, and `i18n::t` translates names from registries. Plac
|
||||
(including user filenames containing braces) are inserted literally. Catalog translations are
|
||||
original work using ordinary language, without proprietary localisation resources.
|
||||
|
||||
Spanish, Japanese, Simplified Chinese, French, Brazilian Portuguese and German cover menus, panels, dialogs, settings and registry labels. Searches accept both the
|
||||
Spanish, Japanese, Simplified Chinese, French, Brazilian Portuguese, German and Russian cover
|
||||
menus, panels, dialogs, settings and registry labels. Searches accept both the
|
||||
translated label and its English source, including Unicode capitals. Project content, command ids
|
||||
and preference values retain their original values. Engine errors, CLI and MCP messages remain
|
||||
English. Ukrainian and Russian currently cover the core menus; they fall back to English elsewhere.
|
||||
English. Ukrainian currently covers the core menus; it falls back to English elsewhere.
|
||||
|
||||
Verification: `cargo test -p filmcraft-ui-egui` checks catalog syntax, duplicate keys, placeholders,
|
||||
literal/menu/registry coverage and UI behaviour; `cargo xtask ci` runs the workspace gates. Visual
|
||||
|
||||
@@ -1196,21 +1196,47 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// Russian covers the whole interface: every entry of the reference (Spanish) catalog, so the
|
||||
/// menus, panels, dialogs, settings, effects and status messages are all translated. Every
|
||||
/// entry must still have a Spanish counterpart, so a renamed or removed source can't leave a
|
||||
/// dead Russian entry.
|
||||
#[test]
|
||||
fn russian_entries_cover_the_original_menu_catalog() {
|
||||
let app = crate::FilmcraftApp::new(filmcraft_engine::Session::default());
|
||||
let items = crate::menus::menu_items(&app);
|
||||
let known = |text: &str| crate::menus::MENUS.contains(&text) || items.iter().any(|it| it.label == text || it.path.iter().any(|p| p == text));
|
||||
let (entries, _) = catalog::parse_entries(include_str!("ru.tsv"));
|
||||
for (_, en, _) in entries {
|
||||
assert!(known(&en) || en == "Settings", "not a menu label: {en}");
|
||||
fn russian_covers_the_whole_interface() {
|
||||
let (entries, errors) = catalog::parse_entries(include_str!("ru.tsv"));
|
||||
assert!(errors.is_empty(), "{errors:?}");
|
||||
for (ctx, en, _) in &entries {
|
||||
assert!(ctx.is_empty() && (Language::Es.has(en) || en == "Settings"), "Russian entry without a Spanish one: {ctx:?} {en:?}");
|
||||
}
|
||||
let (es, _) = catalog::parse_entries(include_str!("es.tsv"));
|
||||
let mut missing: Vec<&str> = es.iter().map(|(_, en, _)| en.as_str()).filter(|en| !Language::Ru.has(en)).collect();
|
||||
missing.sort_unstable();
|
||||
assert!(missing.is_empty(), "untranslated Russian strings ({}): {:?}", missing.len(), &missing[..missing.len().min(20)]);
|
||||
for en in core_menu_labels() {
|
||||
assert!(Language::Ru.has(&en), "missing Russian menu label: {en}");
|
||||
}
|
||||
for en in crate::menus::MENUS.into_iter().chain(["Audio", "Settings"]) {
|
||||
assert_ne!(Language::Ru.tr(en), en, "untranslated Russian menu: {en}");
|
||||
assert!(Language::Ru.has(en), "untranslated Russian menu: {en}");
|
||||
}
|
||||
// beyond the menus: panels, effects and their parameters, settings, status messages
|
||||
for (en, ru) in [
|
||||
("Settings", "Настройки"),
|
||||
("Gaussian Blur", "Размытие по Гауссу"),
|
||||
("Audio Track Mixer", "Микшер аудиодорожек"),
|
||||
("Sequence", "Последовательность"),
|
||||
("Playhead", "Курсор воспроизведения"),
|
||||
("Lumetri Scopes", "Осциллограммы Lumetri"),
|
||||
] {
|
||||
assert_eq!(Language::Ru.tr(en), ru);
|
||||
}
|
||||
assert_eq!(Language::Ru.name(), "Русский");
|
||||
assert_eq!(Language::parse("ru"), Some(Language::Ru));
|
||||
for tag in ["ru", "ru-RU", "ru_RU.UTF-8"] {
|
||||
assert_eq!(Language::from_locales(&[tag.to_string()]), Language::Ru, "{tag}");
|
||||
}
|
||||
set_current(Language::Ru);
|
||||
assert!(matches_query("Gaussian Blur", "размытие"));
|
||||
assert!(matches_query("Gaussian Blur", "gaussian"));
|
||||
set_current(Language::En);
|
||||
}
|
||||
|
||||
/// Indonesian covers the whole interface (the Spanish catalog's entries and the native macOS
|
||||
@@ -1315,6 +1341,16 @@ mod tests {
|
||||
assert_bundled_fonts_cover(alphabet.chars().chain(Language::Uk.name().chars()).chain(entries.iter().flat_map(|(_, _, uk)| uk.chars())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn russian_renders_with_bundled_fonts() {
|
||||
let (entries, _) = catalog::parse_entries(include_str!("ru.tsv"));
|
||||
// every Russian letter, including «ё», even ones no entry uses yet, and every letter the
|
||||
// entries use
|
||||
let alphabet = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя";
|
||||
let letters = entries.iter().flat_map(|(_, _, ru)| ru.chars()).filter(|ch| ch.is_alphabetic());
|
||||
assert_bundled_fonts_cover(alphabet.chars().chain(Language::Ru.name().chars()).chain(letters));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn portuguese_renders_with_bundled_fonts() {
|
||||
let (entries, _) = catalog::parse_entries(include_str!("pt-br.tsv"));
|
||||
|
||||
+3319
-84
File diff suppressed because it is too large
Load Diff
@@ -5,4 +5,9 @@ source: original work
|
||||
license: MIT OR Apache-2.0
|
||||
license-file: LICENSE-MIT and LICENSE-APACHE
|
||||
added: 2026-10-10 by grib_job
|
||||
notes: Original English-to-Russian menu translations using clean-room NLE vocabulary.
|
||||
notes: Original clean-room English-to-Russian translation of the full 3,592-string
|
||||
reference catalog, using ordinary Russian video-editing vocabulary (Premiere-style
|
||||
terms: последовательность, корзина, дорожка, визуализация). No proprietary
|
||||
localisation resource, string table or product interface was consulted. Drafted
|
||||
with the project's agents and reviewed against the tests; native-speaker review
|
||||
still welcome.
|
||||
|
||||
+7
-2
@@ -234,12 +234,12 @@ platforms** G4, G9, G17; **performance** G16; **ecosystem** G11; **measurement**
|
||||
## G14. Localization: 3 of the 12 key languages missing (Hindi, Arabic, Vietnamese)
|
||||
|
||||
- **Have:** Spanish, Japanese, Simplified Chinese, French (#498) and Portuguese (Brazil) (#859)
|
||||
catalogs cover ~99.6–100% of the ~3,500 cataloged strings; Ukrainian ~10% (menus).
|
||||
catalogs cover ~99.6–100% of the ~3,590 cataloged strings; Ukrainian ~10% (menus).
|
||||
- **Missing:** Hindi, Arabic (no RTL interface layout or catalog; the interface has Arabic and Hebrew
|
||||
fallback fonts and shows captions in reading order, but other names and fields keep egui's
|
||||
left-to-right run order; Arabic titles reported broken, #395),
|
||||
Korean (#508; needs Hangul fonts in craft-fonts),
|
||||
Vietnamese; Premiere also ships Russian. Engine errors,
|
||||
Vietnamese. Engine errors,
|
||||
CLI and MCP stay English. Apart from the German menus (#630), no language has a recorded
|
||||
native-speaker review.
|
||||
- **Done:** Indonesian (#867): `id.tsv` has every entry of the Spanish catalog (~100%), in Edit ▸
|
||||
@@ -251,6 +251,11 @@ platforms** G4, G9, G17; **performance** G16; **ecosystem** G11; **measurement**
|
||||
- **Done:** German: `de.tsv` has every entry of the Spanish catalog (~100%), beyond the menus of
|
||||
#630 (panels, dialogs, effects and their parameters, settings, status messages). The menus are
|
||||
native-reviewed; review of the rest welcome.
|
||||
- **Done:** Russian: `ru.tsv` has every entry of the Spanish catalog (100% of the reference
|
||||
catalog), translated from the English sources with Premiere-style Russian vocabulary
|
||||
(последовательность, корзина, дорожка, визуализация); Edit ▸ Language, Settings ▸ General and
|
||||
System Language (`ru-*`) reach it, the i18n test requires full coverage and a font test covers
|
||||
the Russian alphabet including «ё». Native-speaker review welcome.
|
||||
- **Estimate:** 150–230 h. Doc: [localization-parity.md](localization-parity.md).
|
||||
|
||||
## G15. Interchange never validated in Avid / Pro Tools; slow XML import
|
||||
|
||||
+15
-11
@@ -1,6 +1,6 @@
|
||||
# Localization parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (German covers the whole interface) · **Target:** Adobe Premiere Pro 2026 (26.5.2)
|
||||
> **Last reviewed:** 2026-10-19 · **Last updated:** 2026-10-19 · **Change:** Russian covers the whole interface · **Target:** Adobe Premiere Pro 2026 (26.5.2)
|
||||
|
||||
Per-language status of FilmCraft's interface. Premiere 26.5.2 ships 10 interface languages (the
|
||||
installed bundle's `.lproj` folders): German, English, Spanish, French, Italian, Japanese, Korean,
|
||||
@@ -19,7 +19,7 @@ displayed labels as well as English sources. Tests fail when a `tl!` literal, a
|
||||
registry name has no Spanish entry; `zh-cn.tsv` must also cover every `tl!` literal and menu
|
||||
label; `ja.tsv`, `fr.tsv`, `pt-br.tsv` and `de.tsv` have the same entries but are not yet required by tests
|
||||
(French and German must cover the core menus, Brazilian Portuguese every menu label, and neither may keep an
|
||||
entry without a Spanish one). Engine error messages, the
|
||||
entry without a Spanish one). `ru.tsv` must cover every entry of the Spanish catalog and must not keep an entry without a Spanish one. Engine error messages, the
|
||||
control channel, the CLI and MCP stay English.
|
||||
|
||||
Fonts come from [craft-fonts](https://github.com/storytold/craft-fonts) (`CRAFT_FONTS_DIR`, all
|
||||
@@ -34,16 +34,16 @@ right to left, but Arabic titles are reported broken (#395).
|
||||
|
||||
## Status
|
||||
|
||||
Measured 2026-10-10 by counting entries in each catalog. The denominator is the union of all
|
||||
catalogs' sources (**3,498 strings**); strings not yet wrapped in `tl!` and engine messages are
|
||||
Measured 2026-10-19 by counting entries in each catalog. The denominator is the union of all
|
||||
catalogs' sources (**3,593 strings**); strings not yet wrapped in `tl!` and engine messages are
|
||||
not in it, so real coverage is somewhat lower than shown. Estimates calibrated from #449 (Japanese,
|
||||
whole interface, one PR) at ~4–8 h per language for the catalog plus tests.
|
||||
|
||||
| Language | Code | UI strings | Dialogs / tooltips / help | Script support | Native review | Status | To `full` |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| English | en | 3,498 (100%, source) | yes; no help docs in-app | Latin | n/a | **full** | — |
|
||||
| English | en | 3,593 (100%, source) | yes; no help docs in-app | Latin | n/a | **full** | — |
|
||||
| Simplified Chinese | zh-cn | 3,485 (99.6%) | dialogs, Settings, effects, shortcuts, status; engine errors English | CJK font fallback; system IME via winit | not recorded | partial | 6–10 h + review |
|
||||
| Spanish | es | 3,496 (99.9%) | as above | Latin | not recorded | partial | 4–8 h + review |
|
||||
| Spanish | es | 3,592 (the reference catalog) | as above | Latin | not recorded | partial | 4–8 h + review |
|
||||
| Hindi | hi | 0 (0%) | — | **no Devanagari shaping in the interface** | — | none | 30–50 h (shaping in UI + catalog + fonts) |
|
||||
| Arabic | ar | 0 (0%) | — | **no RTL interface layout**; fallback fonts and shaping in the interface, captions in reading order, other text in egui's left-to-right run order; titles broken (#395) | — | none | 40–70 h |
|
||||
| French | fr | 3,526 (same entries as Spanish, plus the macOS Settings item) | as Spanish | Latin (bundled fonts) | not recorded; welcome | partial (#498) | review |
|
||||
@@ -52,27 +52,31 @@ whole interface, one PR) at ~4–8 h per language for the catalog plus tests.
|
||||
| Japanese | ja | 3,487 (99.7%) | as zh-cn; system-font kanji may pick the Chinese fallback (#547) | CJK fonts, vertical title text | not recorded | partial | 4–8 h + review |
|
||||
| German | de | 3,590 (same entries as Spanish); must cover the core menus and the macOS app menu, no entry without a Spanish one | as Spanish | Latin (bundled fonts) | menus yes (#630); the rest not recorded, welcome | partial | review |
|
||||
| Korean | ko | 3,573 (same entries as Spanish, plus the macOS Settings item) | as Spanish | installed system Hangul font (Malgun Gothic, Apple SD Gothic Neo, Noto Sans CJK KR…); refused without one | not recorded; welcome | partial (#508) | review; Hangul in craft-fonts for the web |
|
||||
| Russian | ru | 3,592 (100%; every Spanish entry) | dialogs, Settings, effects, shortcuts, status; engine errors English | Cyrillic (bundled fonts), «ё» | not recorded; welcome | partial | native review |
|
||||
| Vietnamese | vi | 0 (0%) | — | Latin with stacked diacritics (font coverage to check) | — | none | 6–12 h + review |
|
||||
| *Other shipped:* Italian | it | 3,573 (same entries as Spanish, plus the macOS Settings item); must cover the core menus, no entry without a Spanish one | as Spanish | Latin (bundled fonts) | not recorded; welcome | partial | review |
|
||||
| *Other shipped:* Ukrainian | uk | 351 (10.0%) | menus only | Cyrillic (bundled) | not recorded | menus only | 5–9 h |
|
||||
|
||||
UI strings are catalog entries (the non-comment lines of `src/i18n/<code>.tsv`; English counts the
|
||||
source strings in the code), so the rows were measured at different times: at this change the
|
||||
Spanish and German catalogs both have 3,590 entries, German every Spanish one. Strings added
|
||||
later may stay English in German until translated; only the core menus are required.
|
||||
Spanish catalog has 3,592 entries, German 3,590, and Russian every Spanish one. Strings added
|
||||
later may stay English in German until translated; Russian is required to cover every source.
|
||||
|
||||
Premiere also ships Italian, which we now cover like Spanish, and Russian (6–10 h).
|
||||
Premiere also ships Italian, which we cover like Spanish, and Russian, which now covers the whole
|
||||
interface (native review welcome).
|
||||
|
||||
**Localization dimension:** 9 of the 12 key languages near-complete (English, Spanish, Japanese,
|
||||
Simplified Chinese, French, Portuguese (Brazil), Indonesian, Korean, German), 3 none (Hindi, Arabic,
|
||||
Vietnamese); against Premiere's 10 languages we cover 9 well and Russian partly. **~35%, 150–230 h** for all twelve to `full` plus Italian and Russian, of which the script
|
||||
work (RTL and complex shaping in the egui interface) is the largest and least parallel part.
|
||||
Vietnamese); against Premiere's 10 languages we cover 10 at catalog level, Russian pending native
|
||||
review. **~35%, 150–230 h** for the twelve key languages to `full` plus Russian review, of which the
|
||||
script work (RTL and complex shaping in the egui interface) is the largest and least parallel part.
|
||||
Every language needs native-speaker review (human).
|
||||
|
||||
## Revision history
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-19 | major | Russian (ru) covers the whole interface: 3,592 entries (100% of the Spanish catalog), `ru.tsv` translated from the English sources with Premiere-style Russian vocabulary; the i18n test requires every Spanish entry, a font test covers the Russian alphabet including «ё», System Language maps `ru-*`; native review welcome |
|
||||
| 2026-10-13 | minor | German (de) covers the whole interface: every entry of the Spanish catalog (3,590); the tests require the core menus and the macOS app menu and reject entries without a Spanish one |
|
||||
| 2026-10-11 | minor | German (de) ships the menus (#630): 371 of 3,498 strings (10.6%), native-reviewed; dimension now 2 menus-only, 5 none |
|
||||
| 2026-10-10 | major | Created from ROADMAP.md's "Interface localization" section; catalog coverage measured (es 3,496, ja 3,487, zh-cn 3,485, pt-br 348, uk 351 of 3,498); the 12-language table and script-support gaps added |
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ Status: ✅ done · 🟡 in progress · ⬜ not started. Estimates are remaining
|
||||
| M11 | Interchange & project management | ✅ | `.fcproj` schema versions + migrations, atomic saves, Save a Copy/Revert, auto-save ring + crash-recovery journal (Preferences ▸ Auto Save, recovery prompt), FCP7 XML, FCPXML, EDL, OTIO; offline media (own slate) + Link Media (fingerprint-checked relink, folder remap, search, Align Timecode, Make Offline); proxies (ProRes Proxy/LT, H.264 ¼/½ background jobs, attach/detach/reconnect, monitor toggle, export full-res) + ingest (copy/transcode/proxies); Project Manager (collect, consolidate + transcode with handles, size estimate) | Rename media to clip names, image-sequence conversion, Media Browser-driven relink, smart (cross-drive) path tracking | 1–2 |
|
||||
| M12–M16 | Multicam, web (WASM), platform, long tail | 🟡 | Multicam: audio sync (GCC-PHAT, sub-sample), Merge Clips, multi-camera source sequences, Multi-Camera view with live switching (1–9); L0–L4 crates compile to wasm32 | Web app shell (file access, WebCodecs, audio), scene detection, auto reframe, ~800 remaining commands and dialogs, performance hardening | 35–55 |
|
||||
| HW | Hardware acceleration (#30) | 🟡 | Blend modes and 34 effect ids on the GPU incl. Lumetri basic / creative / vignette (#32, GPU2–GPU7); GPU export rendering (#421); decode: VideoToolbox (#33, #41), Media Foundation / D3D11 H.264 / HEVC / VP9 / AV1 (HW2, HW3), VA-API H.264 / HEVC (#358), NVDEC H.264 / HEVC (#549); encode: VideoToolbox H.264 / HEVC, NVENC H.264 (Windows, Linux) and HEVC incl. Main 10 HDR (#328, #360) | Zero-copy, remaining GPU effects, VideoToolbox Main 10, Quick Sync / AMF, VA-API VP9 / AV1 and encode | 120–200 |
|
||||
| L10N | Localization | 🟡 | Spanish, Japanese, Simplified Chinese whole interface; Portuguese (Brazil), Ukrainian menus | Hindi, Arabic (RTL), French, Indonesian, German, Korean, Vietnamese, Italian, Russian; native review | 150–230 |
|
||||
| L10N | Localization | 🟡 | Whole interface: Spanish, Japanese, Simplified Chinese, French, Portuguese (Brazil), Indonesian, Italian, Korean, German, Russian; Ukrainian the core menus | Hindi, Arabic (RTL), Vietnamese; native review of every language | 150–230 |
|
||||
|
||||
## After beta
|
||||
|
||||
|
||||
Reference in New Issue
Block a user