i18n: complete Turkish interface catalog with 2,170 entries and full … (#774)

* i18n: complete Turkish interface catalog with 2,253 entries and full parity

* Review fixes for #774: Turkish entry count after merging main (2,325)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-12 07:04:50 -04:00
1 parent 325e5a6157
commit 691e887004
8 files changed
+746 -355

No files matched your search

+4 -2
View File
@@ -2,7 +2,7 @@
**Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** trivial (Navigation heading truncation; previously trivial: Insert › SmartArt landed, #497: catalog 429/451 → 437/458 (95.4%); previously trivial: Turkish interface landed; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** trivial (Turkish interface catalog completed, #774; previously trivial: drag-select by whole units, #549; previously trivial: Insert › SmartArt landed, #497: catalog 429/451 → 437/458 (95.4%); previously trivial: Turkish interface landed; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
WordCraft aims for complete parity with Microsoft Word, then goes further on speed, openness and
agent control. This page is the summary; the assessment is
@@ -110,7 +110,7 @@ Weights and evidence per area: [docs/target-app-parity.md](docs/target-app-parit
| Korean | ko | none | 0% |
| Vietnamese | vi | none | 0% |
Also shipped: Traditional Chinese (`zh-hant`), Ukrainian (`uk`), Serbian (`sr`, `sr-latn`, #250), Russian (`ru`) and Polish (`pl`), all partial (~95%). Estonian (`et`), Turkish (`tr`), Italian (`it`, #594) and Czech (`cs`) now have complete interface catalogs with
Also shipped: Traditional Chinese (`zh-hant`), Ukrainian (`uk`), Serbian (`sr`, `sr-latn`, #250), Russian (`ru`) and Polish (`pl`), all partial (~95%). Estonian (`et`), Italian (`it`, #594) and Czech (`cs`) now have complete interface catalogs, and Turkish (`tr`) a complete 2,325-entry one (every key of the Russian catalog), all with
system-locale selection and a saved language choice (Italian also has 51 strings none of the others had yet); Estonian, Turkish, Italian and Czech proofing are not included. Hungarian (`hu`) has a
complete 2,419-entry catalog, also without proofing.
Proofing: English and Polish (spelling, grammar, hyphenation), chosen per run from its language. Word ships
@@ -135,6 +135,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
| 2026-10-11 | Hide White Space (#645): `view.hideWhiteSpace` (View › Show checkbox, or double-click the gap between pages) collapses margins, headers and footers between pages to a thin line in Print Layout; screen only, page count unchanged |
| 2026-10-11 | Fonts: Palatino Linotype and Book Antiqua fall back to Palatino (macOS) or TeX Gyre Pagella / P052 / URW Palladio (Linux) before generic serif (#670) |
|---|---|
| 2026-10-11 | Turkish (`tr`) interface completed (#774): 2,325 entries, every key of the Russian catalog (equation gallery, built-in style names, watermarks, paper sizes, preview tiles); the interface audit checks Turkish too |
| 2026-10-12 | Navigation headings truncate within the resizable pane, with an ellipsis for long titles and full text on hover (#759) |
| 2026-10-11 | Reading Mode: existing View ribbon button now opens a read-only, viewport-column layout with animated horizontal paging, transient display controls, heading navigation (Navigation pane) and resize anchoring; document layout and export unchanged |
| 2026-10-11 | DOCX open/save keeps inherited complex-script size, bold and italic independent of Latin formatting; explicit values are retained, and font commands still format both scripts. Covered by synthetic round trips and a local GUI save/reopen check. |
@@ -218,6 +219,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
| Date | Change | Summary |
|---|---|---|
| 2026-10-11 | trivial | Progress log and shipped languages: Turkish interface completed, 2,325 entries (#774) |
| 2026-10-12 | trivial | Progress log: Navigation heading truncation (#759) |
| 2026-10-11 | trivial | Progress log: Reading Mode implementation |
| 2026-10-11 | trivial | DOCX complex-script formatting inheritance fix and round-trip coverage |
+5 -1
View File
@@ -51,8 +51,12 @@ sync_github_name = false
[people.henno]
sync_github_name = true
[people.GhostMitra]
[people.yeniufuklar-com]
real_name = "Ufuk Efe"
display_name = "Ufuk Efe"
sync_github_name = true
[people.GhostMitra]
[people.DevCoderMax]
real_name = "Gleyson do Nascimento Carvalho"
display_name = "Gleyson Carvalho"
+3 -2
View File
@@ -530,7 +530,7 @@ fn envelopes_ui(app: &mut WordApp, ui: &mut Ui, f: &mut EnvelopeForm) -> bool {
}
/// `DL 110 × 220 mm` / `#10 4.13 × 9.5 in`: metric sizes in millimetres, the others in inches.
fn envelope_label(name: &str, w: f32, h: f32) -> String {
pub(crate) fn envelope_label(name: &str, w: f32, h: f32) -> String {
let short = name.strip_prefix("Envelope ").unwrap_or(name);
if short.starts_with('#') || short == "Monarch" {
let i = |pt: f32| ((pt / 72.0) * 100.0).round() / 100.0;
@@ -589,7 +589,8 @@ fn product_label(i: usize) -> String {
"return" => tl!("Return address labels"),
_ => tl!("Address labels"),
};
format!("{kind}, {} × {}, {} ({})", p.cols, p.rows, p.size_text(), p.paper)
let paper = tl!(p.paper);
format!("{kind}, {} × {}, {} ({paper})", p.cols, p.rows, p.size_text())
}
fn labels_ui(app: &mut WordApp, ui: &mut Ui, f: &mut LabelsForm) -> bool {
+27 -6
View File
@@ -314,9 +314,9 @@ fn untranslated_interface_text() {
complete_catalogs_have_every_string_the_interface_looked_up(pseudo::looked_up());
}
/// Russian and Hungarian cover everything the audit saw translated, plus the equation gallery's
/// labels (shown in menus the audit doesn't open one by one). Numbered style names go through a
/// template.
/// Russian, Hungarian and Turkish cover everything the audit saw translated, plus the equation
/// gallery's labels (shown in menus the audit doesn't open one by one). Numbered style names go
/// through a template.
fn complete_catalogs_have_every_string_the_interface_looked_up(mut keys: std::collections::BTreeSet<String>) {
use wordcraft_engine::math_gallery::{BUILT_INS, STRUCTURES, SYMBOL_SETS};
keys.extend(BUILT_INS.iter().map(|(_, label, _)| label.to_string()));
@@ -329,10 +329,31 @@ fn complete_catalogs_have_every_string_the_interface_looked_up(mut keys: std::co
}
}
let numbered = |s: &str| ["Heading ", "TOC "].iter().any(|p| s.strip_prefix(p).is_some_and(|n| n.chars().all(|c| c.is_ascii_digit())));
// Names that read the same in these languages.
let same = |s: &str| matches!(s, "LaTeX" | "LaTeX (*.tex)" | "Unicode" | "I. II. III." | "i. ii. iii.");
// Names that read the same in these languages (citation style names included).
let same = |s: &str| {
matches!(
s,
"LaTeX"
| "LaTeX (*.tex)"
| "Unicode"
| "I. II. III."
| "i. ii. iii."
| "APA"
| "Chicago"
| "GB/T 7714"
| "GOST (name sort)"
| "GOST (title sort)"
| "Harvard (Anglia)"
| "IEEE"
| "ISO 690 (author-date)"
| "ISO 690 (numerical)"
| "MLA"
| "SIST02"
| "Turabian"
)
};
let mut report = String::new();
for code in ["ru", "hu"] {
for code in ["ru", "hu", "tr"] {
let lang = super::Lang::from_code(code).unwrap_or(super::Lang::EN);
let missing: Vec<&String> = keys.iter().filter(|s| english_words(s) && !super::has(lang, s) && !numbered(s) && !same(s)).collect();
if !missing.is_empty() {
+9 -4
View File
@@ -699,8 +699,9 @@ fn turkish_locales_and_saved_preference_work_without_changing_the_document() {
fn turkish_covers_the_entire_existing_interface_catalog_and_preserves_templates() {
use std::collections::HashSet;
let keys = |source| parse_entries(source).0.into_iter().map(|e| e.source).collect::<HashSet<_>>();
// Spanish carries every key the interface looks up; Chinese lacks only a few newer labels.
assert_eq!(keys(lang("tr").0.source), keys(lang("es").0.source));
// Full parity with the Russian catalog: covers all UI strings, styles, math gallery, and presets.
assert_eq!(keys(lang("tr").0.source), keys(lang("ru").0.source));
assert!(keys(lang("es").0.source).is_subset(&keys(lang("tr").0.source)));
assert!(keys(lang("zh-hans").0.source).is_subset(&keys(lang("tr").0.source)));
let tr = lang("tr");
for (source, expected) in [
@@ -713,6 +714,10 @@ fn turkish_covers_the_entire_existing_interface_catalog_and_preserves_templates(
("Save", "Kaydet"),
("UPPERCASE", "BÜYÜK HARF"),
("lowercase", "küçük harf"),
("Square Root", "Karekök"),
("Euler's identity", "Euler Özdeşliği"),
("Default Paragraph Font", "Varsayılan Paragraf Yazı Tipi"),
("CONFIDENTIAL", "GİZLİ"),
("WordCraft", "WordCraft"),
("unknown future label", "unknown future label"),
] {
@@ -914,9 +919,9 @@ fn polish_covers_every_key_of_every_other_catalog() {
use std::collections::HashSet;
let keys = |source| parse_entries(source).0.into_iter().map(|e| e.source).collect::<HashSet<_>>();
let polish = keys(lang("pl").0.source);
// Russian, Italian and Hungarian also translate the built-in style names and the equation gallery,
// Russian, Italian, Hungarian and Turkish also translate the built-in style names and the equation gallery,
// which the others don't yet; Polish matches every other catalog.
for other in Lang::all().filter(|l| *l != Lang::EN && !matches!(l.code(), "pl" | "ru" | "it" | "hu")) {
for other in Lang::all().filter(|l| *l != Lang::EN && !matches!(l.code(), "pl" | "ru" | "it" | "hu" | "tr")) {
let mut missing: Vec<String> = keys(other.0.source).difference(&polish).cloned().collect();
missing.sort();
assert!(missing.is_empty(), "pl lacks {}'s {missing:?}", other.code());
File diff suppressed because it is too large. Load diff
+5 -4
View File
@@ -1,6 +1,6 @@
# Localization parity with Microsoft Word
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (Hungarian interface added; previously minor: Polish interface; Polish proofing — spelling, grammar, hyphenation — and a proofing language per run; previously minor: Turkish interface added; previously major: first version; catalogs measured from `crates/ui-egui/src/i18n`, Word's languages from its bundle listing) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (Turkish interface catalog completed, 2,325 entries, #774; previously minor: font list shows fonts by their names in the interface language, #505; previously minor: Turkish interface added; previously major: first version; catalogs measured from `crates/ui-egui/src/i18n`, Word's languages from its bundle listing) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
Interface languages, script support and proofing per language. How translation works (catalog
format, adding a language, clean-room rule): `crates/ui-egui/src/i18n/mod.rs`.
@@ -21,7 +21,7 @@ native-speaker review (human).
- **18 interface languages**: English plus `zh-hans`, `zh-hant`, `ja`, `uk`, `es`, `pt-br`,
Serbian `sr`/`sr-latn` (#250), Estonian `et`, Turkish `tr`, Russian `ru`, Italian `it` (#594), German `de` (#574), Polish `pl`, Czech `cs`, Hungarian `hu` and French `fr`. Catalogs have 2,021–2,419 entries
each; Polish has every key of every other catalog except the style names and equation gallery labels only Russian, Italian and Hungarian translate so far (a test checks it). A test (`every_tab_and_command_is_translated`) enforces that every ribbon tab, command
each; Polish has every key of every other catalog except the style names and equation gallery labels only Russian, Italian, Hungarian and Turkish translate so far (a test checks it). A test (`every_tab_and_command_is_translated`) enforces that every ribbon tab, command
label and ribbon location is translated in every language.
`pl`, `pl-PL` and `pl_PL.UTF-8` system locales pick Polish automatically.
- Of the 675 English strings a scan extracts from `tl!(…)` calls and command labels/locations, each
@@ -62,8 +62,8 @@ Cyrillic and Latin (`sr`, `sr-latn`, #250), Estonian (`et`), Turkish (`tr`), Rus
Estonian uses the existing fonts, follows `et-EE` system locales, and is available in Options or
through `ui.language` with `{"value":"et"}`. Its 1,307 entries cover the existing interface catalog.
Estonian spelling, grammar, dates and document templates are not added by the interface catalog.
Turkish works the same way (`tr-TR` and `tr-CY` system locales, `{"value":"tr"}`) with all 1,307
entries. Command search folds the Turkish dotted and dotless I (`italik` finds İtalik, `YAZI TİPİ`
Turkish works the same way (`tr-TR` and `tr-CY` system locales, `{"value":"tr"}`) with all 2,325
entries, the same keys as the Russian catalog. Command search folds the Turkish dotted and dotless I (`italik` finds İtalik, `YAZI TİPİ`
finds Yazı Tipi) while English labels and ASCII command ids keep their usual matching. Turkish
proofing is not included; terminology and checks: [`localization-tr.md`](localization-tr.md).
Hungarian follows `hu-HU` system locales and `{"value":"hu"}`, with a complete catalog of 2,419 entries: every key of
@@ -105,6 +105,7 @@ allows); all other text is written from the meaning of the English. No Italian p
| Date | Change | Summary |
|---|---|---|
| 2026-10-11 | minor | Turkish interface catalog completed (2,325 entries, the same keys as Russian): equation gallery, built-in style names, watermarks, paper sizes and preview tiles; the interface audit checks Turkish too (#774) |
| 2026-10-11 | minor | Czech (`cs`) interface catalog added |
| 2026-10-11 | minor | Polish interface (13 languages) and Polish proofing: SJP.PL spelling with suggestions, Polish grammar rules, TeX Polish hyphenation; proofing language per run; dimension ~25% → ~27% |
| 2026-10-11 | minor | German interface catalog (#574): 2,021 entries covering the full zh-hans key set; locale, saved-preference and bundled-font tests; no German proofing |
+12 -8
View File
@@ -1,6 +1,6 @@
# Turkish interface
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (Turkish interface catalog and regression checks) · **Target:** WordCraft 0.5.0
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (Turkish interface catalog completed, 2,325 entries, #774; previously minor: Turkish interface catalog and regression checks) · **Target:** WordCraft 0.5.0
Choose **File › Options › Interface language › Türkçe**, or follow a Turkish system display language
(`tr-TR`, `tr-CY`, `tr_TR.UTF-8`). The catalog code is `tr`; `ui.language` with `{"value":"tr"}`
@@ -8,7 +8,9 @@ selects it explicitly, and `WORDCRAFT_LANGUAGE=tr-TR` does the same for a headle
launch while the preference is `auto`. The choice is saved with the other interface settings.
Document text, command ids, CLI/MCP/control responses and file paths do not change.
`crates/ui-egui/src/i18n/tr.tsv` has all 1,307 keys of the Spanish catalog. It is written from the
`crates/ui-egui/src/i18n/tr.tsv` has all 2,325 entries of the Russian catalog (the same
keys). It covers all ribbon commands, dialogs, built-in style names, equation and math gallery
structures, watermark presets, paper sizes, and rendered preview tiles. It is written from the
meaning of the English labels; no proprietary translation resources were consulted. The catalog
format has no plural forms, and Turkish doesn't need them here: a noun after a number stays
singular (`0 sözcük`, `1 sözcük`, `21 sözcük`). Placeholders, `\n` breaks in ribbon labels and dialog
@@ -44,12 +46,13 @@ still work. Other interface languages and document search are unchanged.
## Verification and remaining scope
`cargo test -p wordcraft-ui-egui --lib i18n::tests` covers Turkish locale tags and preference order,
saving and restoring `tr`, unknown preferences, unchanged document content, key parity with
Spanish, placeholders, count wording, the font sample's capitals, English fallback, and the glyphs
`ÇçĞğİıÖöŞşÜü` in the bundled Inter (Regular, Medium, SemiBold) and JetBrains Mono. A dialog test
renders real command-search results in Turkish and English, including dotted and dotless I and
ASCII command ids. The shared catalog checks (validation, every tab and command translated) include
Turkish automatically.
saving and restoring `tr`, unknown preferences, unchanged document content, full key parity with
the Russian catalog (and superset of Spanish and Chinese), placeholders, count wording, the font
sample's capitals, English fallback, and the glyphs `ÇçĞğİıÖöŞşÜü` in the bundled Inter (Regular,
Medium, SemiBold) and JetBrains Mono. A dialog test renders real command-search results in Turkish
and English, including dotted and dotless I and ASCII command ids. The shared catalog checks
(validation, every tab and command translated, and interface audit strings) include Turkish
automatically.
Spelling, grammar and hyphenation stay English-only: this is an interface translation, not Turkish
proofing. A native-speaker skim of the catalog is welcome.
@@ -58,4 +61,5 @@ proofing. A native-speaker skim of the catalog is welcome.
| Date | Change | Summary |
|---|---|---|
| 2026-10-11 | minor | Turkish catalog completed (2,325 entries, #774), covering all math structures, built-in styles, presets and preview tiles |
| 2026-10-11 | minor | Turkish catalog (1,307 entries), terminology, scope and regression checks |