From 76bd26cca036f8db811c6e7c102ddf9fce81e398 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sun, 8 Nov 2026 08:26:05 +0000 Subject: [PATCH] Don't capitalize the word after a decimal point in sentence case Found while testing crates/model/src/edit.rs:~505 (change_case_parts, sentence branch) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/model/src/edit.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/model/src/edit.rs b/crates/model/src/edit.rs index 8f79d9c4c..c5a325f5a 100644 --- a/crates/model/src/edit.rs +++ b/crates/model/src/edit.rs @@ -498,6 +498,11 @@ pub fn next_case(s: &str) -> &'static str { } } +/// Whether the `.` at `i` sits between two ASCII digits (a decimal point or version number). +fn is_decimal_point(all: &[char], i: usize) -> bool { + i > 0 && all[i - 1].is_ascii_digit() && all.get(i + 1).is_some_and(|n| n.is_ascii_digit()) +} + /// Change case: `upper`, `lower`, `sentence`, `title`, `toggle`. pub fn change_case(s: &str, mode: &str) -> String { change_case_parts(&[s], mode).concat() @@ -532,7 +537,7 @@ pub fn change_case_parts(parts: &[&str], mode: &str) -> Vec { } else { out.extend(c.to_lowercase()); } - if (title && c.is_whitespace()) || (!title && matches!(c, '.' | '!' | '?')) { + if (title && c.is_whitespace()) || (!title && matches!(c, '.' | '!' | '?') && !(c == '.' && is_decimal_point(&all, i))) { start = true; } } @@ -558,6 +563,13 @@ mod tests { assert_eq!(change_case("ΟΔΟΣ", "lower"), "οδος"); } + #[test] + fn sentence_case_decimal_point_is_not_a_boundary() { + assert_eq!(change_case("I HAVE 3.5 APPLES", "sentence"), "I have 3.5 apples"); + assert_eq!(change_case_parts(&["V 1.", "2 BETA"], "sentence").concat(), "V 1.2 beta"); + assert_eq!(change_case("HELLO. WORLD", "sentence"), "Hello. World"); + } + #[test] fn title_sigma_across_runs_is_not_final() { assert_eq!(change_case_parts(&["ΟΔΟΣ", "ΑΣ"], "title"), ["Οδοσ", "ας"]);