Repository navigation
i18n: messages with literal braces match only their own catalog row - #7151
Conversation
The message scan read every message as a format string, so a plain
literal such as `expected {"dataBase64": "…"}` became the catalog key
`expected {"dataBase64"}`, a template whose placeholder took the rest of
any message starting with "expected". The plug-in output error
`expected value at line 1 column 1` was then shown in German as
"erwartet: value at line 1 column 1".
- The scan doubles every brace of a message that is not a format string
(a plain literal or a `&str` constant); `format!` strings and
`#[error(...)]` strings keep their `{{`, `}}` and placeholders.
- 150 `@msg` rows in 23 catalogs are keyed by the full message with its
braces doubled, and their translations write those braces doubled and
carry the full JSON example of the English.
- An `@msg` row with no placeholder is an exact message under its text
with `{{` and `}}` read as braces, so it is found at any length, and a
nested JSON part translated by such a row shows single braces.
- The Hindi row for `give {key, value} or {values}` translates the whole
message; it kept the English "or" and left out "give".
Docs: docs/development.md, the zh-hant.tsv header, docs/target-app-parity.md.
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Thanks @dotCooCoo, this is approved and CI was green, but main has since changed files this PR touches, so that run no longer covers it. Could you merge main (or rebase) so CI runs on current main? I'll merge it once it's green. |
|
@bflatastic Merged main in (eb5ecde). |
|
Merged, thanks @dotCooCoo! It passed its CI checks. |
What and why
The message scan in
crates/ui-egui/src/i18n/tests.rsread every message as a format string, so a plain string literal such as the plug-in errorexpected {"dataBase64": "…"}(crates/plugins/src/export.rs) became the catalog keyexpected {"dataBase64"}. The catalog parses that key as the textexpectedfollowed by a placeholder, so the row matched any message that starts with "expected". In German, the plug-in output errorplug-in output: expected value at line 1 column 1was shown asPlug-in-Ausgabe: erwartet: value at line 1 column 1. The same fault was in the rows forexpected {"objects": [...]}, the read-only object, stroke and effect errors of the plug-in host (22 catalogs), and 16 engine errors such asquotes must be {double?, single?}andgive {key, value} or {values}(hi and sv). The fix for escaped braces informat!strings (#7047) did not cover plain literals.&strconstant). Aformat!string and an#[error(...)]string keep their{{,}}and placeholders as before. The engine'serror(helper also occurs inside each#[error(attribute; the scan reads that one as a format string.@msgrows in 23 catalogs are keyed by the full message with its braces doubled. Their translations write those braces doubled, and the rows that had a shortened JSON example now carry the full one from the English ({{"dataBase64": "…"}},{{"objects": [...]}},{{"id": …}},{{"wght": 650}},{{"formats": [...]}},{{current: new}}). Eight of the 150 rows arenot an RTF file: it doesn't start with {{\rtf(crates/engine/src/cmd/place/rtf.rs), which is also a plain literal.Catalog::parse(crates/ui-egui/src/i18n/catalog.rs) stores an@msgrow that has braces and no placeholder as an exact message, under its text with{{and}}read as single braces. Before, such a row went to the templates, whereexact_messagedid not find it and messages over the template length limit were not matched. A JSON part inside a message that such a row translates is shown with single braces (exact_translationincrates/ui-egui/src/i18n.rs).give {key, value} or {values}now translates the whole message. Before, it kept the English "or" and left out "give".docs/development.mdand the catalog-format header inzh-hant.tsvsay how a literal brace is written in a row, anddocs/target-app-parity.mdhas one line for the change.This changes existing behavior in one way: a status or error message that only starts like one of these rows, such as a JSON reason after
plug-in output:, is no longer replaced by that row's translation and is shown in English.How it was tested
New tests in
crates/ui-egui/src/i18n/tests.rs, each failing without the change:plain_message_keys_double_their_braces: a plain literal, a&strconstant and the RTF message get keys with their braces doubled; aformat!string with a real placeholder and an#[error(...)]string keep their keys.literal_brace_rows_match_only_their_message: the rowexpected {{"dataBase64": "…"}}translates that error with single braces and does not matchexpected value at line 1 column 1orexpected {"dataBase64"}; a row of more than 3,000 characters without placeholders is found; and in the German catalogplug-in output: expected value at line 1 column 1keeps its English reason.Focused checks on the final tree, on Linux. The branch is one commit on
mainate8c7421a3dand merges cleanly with it. It conflicts with open #7084 indocs/development.md. It conflicts with open #1532 incrates/ui-egui/src/i18n/catalog.rs.cargo fmt --all -- --checkcargo clippy -p vectorcraft-ui-egui --all-targets -- -D warningscargo check --workspace --testscargo test -p vectorcraft-ui-egui --lib i18n: 103 passed, 0 failed.cargo xtask brands,layers(30 crates) andassets(337 files).cargo xtask ciruns in this pull request's CI.cargo xtask cipassed in this pull request's CI run oneb5ecde44a: https://github.com/storytold/vectorcraft/actions/runs/43525568871/job/132230334868. The gate on88012ed92bis pending.Checklist
cargo xtask cipasses (fmt, clippy, tests, assets, brands, layers, wasm).unwrap(),expect(),panic!,unreachable!,todo!orunimplemented!outside tests, and no unchecked indexing on data from files, parameters ormessages. Errors are returned as
Resultand shown to the user(why and how).
ASSETS.md.Summary by CodeRabbit