mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-05 18:18:49 +00:00
Follow-up to #2981: a missing Chinese effect row draws English instead of failing the build, the font probe sees effect and category characters, coverage totals recounted
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3ae9c8dbc2
commit
d16c720e59
3 files changed
+31
-40
No files matched your search
@@ -105,6 +105,13 @@ pub(crate) fn name(id: &str, english: &str) -> String {
|
||||
catalog(current()).and_then(|c| c.row(id)).map_or_else(|| english.to_string(), |(_, translated)| translated.to_string())
|
||||
}
|
||||
|
||||
/// The characters of `language`'s effect names and category labels, so the interface's font probe
|
||||
/// registers a face for each of them as it does for the panel catalog's.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(super) fn characters(language: &str) -> impl Iterator<Item = char> {
|
||||
catalog(language).into_iter().flat_map(|c| c.rows.iter().map(|(_, _, t)| *t).chain(c.categories.iter().map(|(_, t)| *t))).flat_map(str::chars)
|
||||
}
|
||||
|
||||
/// The number of effect-name rows `language` translates, for the row-count report; 0 when it has
|
||||
/// no catalog or when it is English.
|
||||
#[cfg(test)]
|
||||
@@ -2248,8 +2255,8 @@ mod tests {
|
||||
}
|
||||
|
||||
/// The languages whose tables are complete: one row per effect in the registry and one row
|
||||
/// per category. A translator moves a language here from [`PARTIAL`] when its table is done;
|
||||
/// the completeness tests then fail if a new effect or category arrives without a row.
|
||||
/// per category when they were written. A new effect without a row draws its English name (as
|
||||
/// in every language), so it does not block other work; the rows are guarded like [`PARTIAL`]'s.
|
||||
const COMPLETE: &[(&str, &[Row])] = &[("zh-hans", SIMPLIFIED_CHINESE), ("zh-hant", TRADITIONAL_CHINESE)];
|
||||
|
||||
/// The languages whose tables are being filled in: guarded row by row.
|
||||
@@ -2276,35 +2283,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A complete language translates every effect the registry has and labels every category, so
|
||||
/// a new effect or category cannot ship in English to a Chinese interface.
|
||||
#[test]
|
||||
fn a_complete_language_covers_the_registry() {
|
||||
let registry = effects::registry();
|
||||
let categories = effects::categories();
|
||||
for (language, rows) in COMPLETE {
|
||||
for spec in registry {
|
||||
assert!(
|
||||
rows.iter().any(|(id, _, _)| *id == spec.id),
|
||||
"{language} has no row for {} ({}): a complete table covers every effect",
|
||||
spec.name,
|
||||
spec.id
|
||||
);
|
||||
}
|
||||
let labels = match *language {
|
||||
"zh-hans" => SIMPLIFIED_CHINESE_CATEGORIES,
|
||||
"zh-hant" => TRADITIONAL_CHINESE_CATEGORIES,
|
||||
other => panic!("{other} is complete but has no category table in this test"),
|
||||
};
|
||||
for source in &categories {
|
||||
assert!(
|
||||
labels.iter().any(|(english, _)| english == source),
|
||||
"{language} has no category label for {source}: a complete table covers every category"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Every category row of every language names a category that exists, else the generated
|
||||
/// Effect menu and Effects & Presets would carry a label no folder has.
|
||||
#[test]
|
||||
@@ -2420,6 +2398,17 @@ mod category_name_tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// The interface's font probe sees the effect names and category labels, not only the panel
|
||||
/// catalog: `鑲` appears only in Flange & Chorus (`鑲邊與合聲`), and a sparse Han face missing
|
||||
/// it would otherwise draw a box.
|
||||
#[test]
|
||||
fn the_font_probe_sees_effect_and_category_characters() {
|
||||
let chars = crate::i18n::catalog_characters("zh-hant");
|
||||
assert!(chars.contains(&'鑲'), "an effect name's character is probed");
|
||||
let (_, label) = TRADITIONAL_CHINESE_CATEGORIES.first().copied().unwrap_or_default();
|
||||
assert!(label.chars().all(|ch| chars.contains(&ch)), "{label}: a category label's characters are probed");
|
||||
}
|
||||
|
||||
/// The same for Traditional Chinese: one repeated label would hide a category behind another
|
||||
/// in the Effect menu.
|
||||
#[test]
|
||||
|
||||
@@ -145,11 +145,13 @@ fn string_literal(rest: &str) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Characters required by the fixed panel catalog, for system-font coverage selection.
|
||||
/// Sorted and deduplicated so fallback registration is deterministic.
|
||||
/// Characters required by the fixed panel catalog and the effect names and categories, for
|
||||
/// system-font coverage selection. Sorted and deduplicated so fallback registration is
|
||||
/// deterministic.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) fn catalog_characters(language: &str) -> Vec<char> {
|
||||
catalog(language).into_iter().flat_map(|c| c.values()).flat_map(|s| s.chars()).collect::<std::collections::BTreeSet<_>>().into_iter().collect()
|
||||
let panels = catalog(language).into_iter().flat_map(|c| c.values()).flat_map(|s| s.chars());
|
||||
panels.chain(super::effects::characters(language)).collect::<std::collections::BTreeSet<_>>().into_iter().collect()
|
||||
}
|
||||
|
||||
/// Translate one interface string: the current language's row for `text`, or `text` itself.
|
||||
|
||||
@@ -69,7 +69,7 @@ and recounted again at this tree after #1774 by counting catalog rows (`const` t
|
||||
`crates/ui-egui/src/i18n.rs`, `i18n/ui.rs` and `i18n/effects.rs`: 630 menu rows, 998
|
||||
panel/dialog sources in Simplified Chinese, 951 in Traditional Chinese and 996 in Japanese). The
|
||||
denominator, **≈ 4,200 user-visible strings**, is a rounded estimate: the 630 fixed menu entries,
|
||||
the 998 panel/dialog sources, 307 effect names, ≈ 1,650 distinct effect parameter names and
|
||||
the 998 panel/dialog sources, 308 effect names, ≈ 1,650 distinct effect parameter names and
|
||||
≈ 620 other unwrapped interface strings (Home screen literals, engine-built tooltips, error and
|
||||
status messages). It counts distinct strings, not catalog rows; engine messages are only partly
|
||||
counted, so the true percentages are slightly lower.
|
||||
@@ -93,18 +93,18 @@ Other languages EffectCraft ships (6):
|
||||
|
||||
| Language | Code | UI strings translated | Status | To `full` |
|
||||
|---|---|---|---|---|
|
||||
| Traditional Chinese | `zh-hant` | 1,910 (≈ 45%): menus 630 rows, panels 951, effect names 308 + 21 categories | partial; effect names complete, parameter names and engine text still in English | 3–5 h + review |
|
||||
| Traditional Chinese | `zh-hant` | 1,889 (≈ 45%): menus 630 rows, panels 951, effect names 308 (+ 21 categories, not counted, as for the other languages) | partial; effect names complete, parameter names and engine text still in English | 3–5 h + review |
|
||||
| Ukrainian | `uk` | 1,153 (≈ 29%): menus 629 rows, panels 524 | partial | 6–9 h + review |
|
||||
| Polish | `pl` | 1,325 (≈ 34%): menus 630 rows, panels 695 | partial; unwrapped UI, effects and engine text still in English; AI-drafted, native review welcome | Remaining strings + native review |
|
||||
| Czech | `cs` | 1,147 (≈ 29%): menus 629 rows, panels 518 | Existing catalog entries covered; unwrapped UI, effects and engine text still in English; AI-assisted, not yet native-speaker proofread | Remaining strings + independent native review |
|
||||
| Georgian | `ka` | 1,514 (≈ 39%): menus 629 rows, panels 885 (the Simplified Chinese catalog's 694 plus 191 Georgian-only rows: form dialogs, context menus, column headers), effect names 308 + 21 categories; native-speaker reviewed | partial | 5–8 h |
|
||||
| Georgian | `ka` | 1,822 (≈ 43%): menus 629 rows, panels 885 (the Simplified Chinese catalog's 694 plus 191 Georgian-only rows: form dialogs, context menus, column headers), effect names 308 + 21 categories; native-speaker reviewed | partial | 5–8 h |
|
||||
| Swedish | `sv` | menus 630 rows, panels 723, effect names 308 and categories 21; added after the measurement above | Settings, Edit menu and Match System (`sv-*` locales) offer it; parameter and engine text still in English; not yet native-speaker reviewed | Remaining strings + native review |
|
||||
|
||||
Russian (`ru`) has a menu catalog (630 rows, ≈ 15%); After Effects also ships Italian, which EffectCraft does not (8–12 h).
|
||||
|
||||
**Overall: ≈ 24%**, the average coverage of After Effects' 10 non-English languages
|
||||
(Simplified Chinese 46%, Traditional Chinese 38%, Japanese 46%, Brazilian Portuguese 34%,
|
||||
Spanish 29%, French, German and Russian 16%, Korean and Italian 0%; 241 / 10, was ≈ 21% on
|
||||
**Overall: ≈ 25%**, the average coverage of After Effects' 10 non-English languages
|
||||
(Simplified Chinese 46%, Traditional Chinese 45%, Japanese 46%, Brazilian Portuguese 34%,
|
||||
Spanish 29%, French, German and Russian 16%, Korean and Italian 0%; 248 / 10, was ≈ 24% before #2037's effect names and ≈ 21% on
|
||||
22 October; Ukrainian (≈ 29%) and Czech (≈ 29%) are EffectCraft-only and stay out of that
|
||||
average). This is the localization row in [target-app-parity.md](target-app-parity.md#by-dimension).
|
||||
|
||||
|
||||
Reference in new issue
Block a user