bs: Add Bosnian (bs) to the interface languages (#2502)

* Add Bosnian (bs) to the interface languages

bs.tsv: Bosnian (Latin script, Ijekavian) catalog covering every key of
CADCraft's other catalogs, its wording shared with storytold/craft-i18n
locales/bs/ and the strings craft-i18n lacks translated new. Every bs-*
locale selects it; counts use one/few/other. Locale and plural tests,
localization docs and an attribution entry (AI-assisted, not yet
reviewed by a native speaker).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Tayw8nmxoLLmKv13jK93z

* docs(localization-parity): Bosnian in the Languages table (CodeRabbit)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
Nine
2026-10-30 15:46:30 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 Brandon Thomas
parent 18d3aa4ed8
commit 43c41b8e68
6 changed files with 1478 additions and 6 deletions
+1
View File
@@ -65,6 +65,7 @@ Generated-in-code assets are original and have no file to list:
| `crates/ui-egui/src/i18n/de.tsv` | the CADCraft contributors | Original German translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
| `crates/ui-egui/src/i18n/es.tsv` | @PedroGuille | Original Spanish translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
| `crates/ui-egui/src/i18n/pt_br.tsv` | @WladmirJunior | Original Brazilian Portuguese translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
| `crates/ui-egui/src/i18n/bs.tsv` | Nine (@nine-codes) with Claude Code (AI-assisted) | Original Bosnian translations of CADCraft English strings, shared with storytold/craft-i18n `locales/bs/` | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied; not yet reviewed by a native speaker |
| `crates/ui-egui/src/i18n/cs.tsv` | @Losminek (AI-assisted) | Original Czech translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
| `crates/ui-egui/src/i18n/ru.tsv` | @pechnikov2026-star | Original Russian translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
| `crates/ui-egui/src/i18n/fr.tsv` | @pechnikov2026-star | Original French translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
+12 -2
View File
@@ -45,10 +45,12 @@ pub enum Preference {
Hungarian,
#[serde(rename = "tr")]
Turkish,
#[serde(rename = "bs")]
Bosnian,
}
impl Preference {
pub const ALL: [Self; 17] = [
pub const ALL: [Self; 18] = [
Self::Auto,
Self::English,
Self::Greek,
@@ -66,6 +68,7 @@ impl Preference {
Self::Arabic,
Self::Hungarian,
Self::Turkish,
Self::Bosnian,
];
/// Every preference in the order the Interface Language dialog lists them: Auto, then English
@@ -113,6 +116,7 @@ impl Preference {
Self::Arabic => "ar",
Self::Hungarian => "hu",
Self::Turkish => "tr",
Self::Bosnian => "bs",
}
}
@@ -141,6 +145,7 @@ impl Preference {
Self::Arabic => "العربية",
Self::Hungarian => "Magyar",
Self::Turkish => "Türkçe",
Self::Bosnian => "Bosanski",
}
}
@@ -171,6 +176,7 @@ impl Preference {
Self::Arabic => "ar",
Self::Hungarian => "hu",
Self::Turkish => "tr",
Self::Bosnian => "bs",
Self::Auto => locales.iter().find_map(|s| locale_language(s)).unwrap_or("en"),
}
}
@@ -187,7 +193,7 @@ pub struct Language {
catalog: OnceLock<Catalog<'static>>,
}
pub static LANGUAGES: [Language; 16] = [
pub static LANGUAGES: [Language; 17] = [
Language { code: "en", name: "English", source: "", plural: plural_en, plural_forms: 2, catalog: OnceLock::new() },
// Greek: one for exactly 1; other for zero and all other integer counts.
Language {
@@ -234,6 +240,9 @@ pub static LANGUAGES: [Language; 16] = [
Language { code: "hu", name: "Magyar", source: include_str!("i18n/hu.tsv"), plural: plural_ko, plural_forms: 1, catalog: OnceLock::new() },
// Turkish keeps a noun singular after a number ("3 commit"), so like Korean it has one form.
Language { code: "tr", name: "Türkçe", source: include_str!("i18n/tr.tsv"), plural: plural_ko, plural_forms: 1, catalog: OnceLock::new() },
// Bosnian (Latin script, Ijekavian): one (1, 21), few (2–4, 22–24, not 12–14), other — the
// Ukrainian rule for integer counts.
Language { code: "bs", name: "Bosanski", source: include_str!("i18n/bs.tsv"), plural: plural_uk, plural_forms: 3, catalog: OnceLock::new() },
];
/// BCP 47 and POSIX locale tags, including `uk-UA`, `uk_UA.UTF-8` and `pt_BR.UTF-8`.
@@ -437,6 +446,7 @@ mod picker_order_tests {
assert!(pos(Preference::Czech) < pos(Preference::German), "Čeština sorts under C");
assert!(pos(Preference::Italian) < pos(Preference::Hungarian), "Magyar sorts under M");
assert!(pos(Preference::Turkish) < pos(Preference::Greek), "Latin names come before Greek");
assert!(pos(Preference::Bosnian) < pos(Preference::Czech), "Bosanski sorts under B");
assert_eq!(name_sort_key("Türkçe"), "turkce");
}
}
File diff suppressed because it is too large Load Diff
+10
View File
@@ -186,6 +186,7 @@ fn assert_additional_locale_aliases() {
("sv", &["sv", "sv-SE", "sv_SE.UTF-8", "SV-se", " sv-SE ", "sv-FI"]),
("hu", &["hu", "hu-HU", "hu_HU.UTF-8", "HU-hu", " hu-HU "]),
("tr", &["tr", "tr-TR", "tr_TR.UTF-8", "TR-tr", " tr-TR ", "tr-CY"]),
("bs", &["bs", "bs-BA", "bs_BA.UTF-8", "BS-ba", " bs-BA ", "bs-Latn-BA"]),
("el", &["el", "el-GR", "el_GR.UTF-8", "EL-cy"]),
("zh", &["zh", "zh-CN"]),
] {
@@ -556,3 +557,12 @@ fn production_font_chain_covers_latin_and_shortcut_symbols() {
assert!(view.has_glyph(&egui::FontId::monospace(12.0), '\u{21e7}'), "U+21E7 shift symbol missing in Monospace");
});
}
/// Bosnian counts: 1, 21 `one`; 2–4, 22–24 (not 12–14) `few`; everything else `other`.
#[test]
fn bosnian_counts_take_one_few_other() {
let forms: Vec<usize> = [0, 1, 2, 4, 5, 11, 12, 14, 21, 22, 25, 111].into_iter().map(plural_uk).collect();
assert_eq!(forms, [2, 0, 1, 1, 2, 2, 2, 2, 0, 1, 2, 2]);
assert_eq!(Preference::parse("bs"), Some(Preference::Bosnian));
assert_eq!(Preference::Bosnian.native_name(), "Bosanski");
}
+1 -1
View File
@@ -10,7 +10,7 @@
//! |---|---|
//! | `theme` | `"system"`, `"light"` or `"dark"` |
//! | `animations` | `"system"`, `"on"` or `"off"`: dialog and menu fades and smoothed scrolling |
//! | `interfaceLanguage` | `"auto"`, `"en"`, `"uk"`, `"pt-BR"`, `"de"`, `"es"`, `"cs"`, `"ru"`, `"fr"`, `"zh"`, `"it"`, `"ko"`, `"sv"`, `"ar"`, `"hu"`, `"tr"` or `"el"` |
//! | `interfaceLanguage` | `"auto"`, `"en"`, `"uk"`, `"pt-BR"`, `"de"`, `"es"`, `"cs"`, `"ru"`, `"fr"`, `"zh"`, `"it"`, `"ko"`, `"sv"`, `"ar"`, `"hu"`, `"tr"`, `"bs"` or `"el"` |
//! | `saveFormat` | `"dxf"` or `"dwg"`: the format Save As suggests for new drawings |
//! | `saveVersion` | `"2000"` … `"2018"`: the version drawings with no file yet are saved in |
//! | `SAVETIME` | minutes between automatic saves, 0–600 (0: off) |
+5 -3
View File
@@ -1,6 +1,6 @@
# Localization parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (the command line enables the OS IME and handles composition/commit, so single-line TEXT edits accept CJK input; previously: Brazilian Portuguese row updated and terminology reviewed; previously: Swedish catalog completed with the 95 strings added since; previously: Swedish catalog added: complete catalog, menu headings, native-speaker terminology review; previously: complete current Korean catalog with Hangul font coverage) · **Target:** Autodesk AutoCAD 2027 for Mac (26.0)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (Bosnian added; previously minor: the command line enables the OS IME and handles composition/commit, so single-line TEXT edits accept CJK input; previously: Brazilian Portuguese row updated and terminology reviewed; previously: Swedish catalog completed with the 95 strings added since; previously: Swedish catalog added: complete catalog, menu headings, native-speaker terminology review; previously: complete current Korean catalog with Hangul font coverage) · **Target:** Autodesk AutoCAD 2027 for Mac (26.0)
How far CADCraft's interface and drawing text are from AutoCAD's languages. Summarised in
[ROADMAP.md](../ROADMAP.md#languages); work items in [gaps.md](gaps.md#localization).
@@ -74,9 +74,10 @@ plus native review by a human; extending the catalog to the remaining English-on
| Italian | it | 1,227 catalog rows; reference catalog and marked UI literals covered | dialogs and tooltips yes; contextual menu headings (Visualizza / Vista, Edita / Modifica); command reference searchable in Italian | Latin: yes (bundled egui fonts; accented letters tested) | AI-assisted by Emanuele Bottelli (Claude), written from the English strings with Italian desktop-CAD vocabulary; no native proofreading pass yet | complete current catalog; English-only interface gaps remain | native review + shared English-only UI work |
| Hungarian | hu | 1,326 catalog rows; reference catalog, marked UI literals and menu headings covered (no gaps reported) | dialogs and tooltips yes; contextual menu headings; command reference searchable in Hungarian | Latin: yes (bundled egui proportional and monospace fonts; ő ű Ő Ű and the other accented letters tested) | translated by @Skaywalker from the English strings; independent native proofreading pending | complete current catalog; English-only interface gaps remain | native proofreading + shared English-only UI work |
| Turkish | tr | 1,330 catalog rows; reference catalog, marked UI literals and menu headings covered (no gaps reported) | dialogs and tooltips yes; contextual menu headings (Ölçülendirme / Ölçü); command reference searchable in Turkish | Latin: yes (bundled egui proportional and monospace fonts; Ç Ğ İ Ö Ş Ü ç ğ ı ö ş ü tested) | AI-assisted by @ogzhnklvz, written from the English strings with Turkish desktop-CAD vocabulary; the running app reviewed by a native speaker | complete current catalog; English-only interface gaps remain | line-by-line proofreading + shared English-only UI work |
| Bosnian | bs | 1,442 catalog rows; reference catalog and marked UI literals covered | dialogs and tooltips yes | Latin: yes (bundled egui fonts) | AI-assisted; independent native proofreading pending | complete current catalog; English-only interface gaps remain | native proofreading + shared English-only UI work |
Other languages shipped: Ukrainian, Brazilian Portuguese, German, Czech, Russian, French, Italian, Korean, Swedish, Hungarian and Turkish.
Czech, Swedish, Hungarian and Brazilian Portuguese cover the reference catalog and every marked UI literal; engine diagnostics and uncatalogued text
Other languages shipped: Ukrainian, Brazilian Portuguese, German, Czech, Russian, French, Italian, Korean, Swedish, Hungarian, Turkish and Bosnian.
Czech, Swedish, Hungarian, Brazilian Portuguese and Bosnian (1,442 rows, AI-assisted, not yet native-reviewed) cover the reference catalog and every marked UI literal; engine diagnostics and uncatalogued text
remain English. AutoCAD for Mac ships 7
non-English languages (zh-Hans, es, fr, ja, de, ko, it); of those, CADCraft now ships German and Korean,
and additionally Ukrainian, which AutoCAD for Mac doesn't ship.
@@ -89,6 +90,7 @@ each language, which needs humans. Translations parallelise fully once the catal
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | minor | Bosnian (`bs`, Latin, Ijekavian) added: 1,442 rows, one/few/other plurals, `bs-*` locales; AI-assisted, native proofreading pending |
| 2026-10-22 | minor | Command line IME: enabled while a prompt collects text, composition shown but not saved, commit inserted once; single-line TEXT edits accept CJK input (#1761) |
| 2026-10-19 | minor | Brazilian Portuguese: row brought up to date (it still read 0%); native-speaker terminology pass on 69 rows (Bind as Integrar, prompt keywords and SPDX kept in English, Thaw Layer, Snap type, Revolve fixed; snap, viewport, grip, offset, layer on/off and multiline wording made consistent with Brazilian usage) |
| 2026-10-15 | minor | Greek (`el`) catalog: 1,330 rows, context/plural/locale/font tests; review pending |