Character: Kerning refuses (1,000) instead of reading it as 1

field_number read a decimal comma before it dropped Kerning's pair of
parentheses, the suffix, % and degrees, so the thousands check saw
(1,000) and 1,000% and read the comma as a decimal point: (1,000)
committed 1. The comma is now read after those are dropped, so
(1,000), 1,000% and 1,000 degrees are refused as 1,000 already is,
while (1,5) and 12,5% still read as 1.5 and 12.5.
This commit is contained in:
dotCooCoo
2026-11-05 01:08:30 +07:00
committed by bflatastic
parent 7f449cc3c8
commit d4f3ec6c96
3 changed files with 19 additions and 3 deletions
+14
View File
@@ -486,6 +486,20 @@ mod field_number_tests {
assert_eq!(field_number("45*2°", "°", false), Some(90.0));
assert_eq!(field_number("50% / 2", "%", false), Some(25.0));
}
/// A thousands comma is refused inside Kerning's pair of parentheses and before `%` or the
/// suffix, as it is in plain text, rather than read as a decimal comma (`(1,000)` as 1).
#[test]
fn a_thousands_comma_is_refused_inside_parentheses_and_before_a_suffix() {
for text in ["(1,000)", " (-1,000) ", "(12,500)"] {
assert_eq!(field_number(text, "", true), None, "{text}");
}
assert_eq!(field_number("1,000%", "%", false), None);
assert_eq!(field_number("1,000°", "°", false), None);
assert_eq!(field_number("(1,5)", "", true), Some(1.5));
assert_eq!(field_number("(0,125)", "", true), Some(0.125));
assert_eq!(field_number("12,5%", "%", false), Some(12.5));
}
}
#[cfg(test)]
+2
View File
@@ -494,5 +494,7 @@ fn kerning_reads_parentheses_around_its_text_with_a_manual_value_too() {
for automatic in [false, true] {
assert_eq!(typed(automatic, "(10+5)"), Some(SpinPick::Value(15.0)), "automatic: {automatic}");
assert_eq!(typed(automatic, "(10+5)*2"), None, "automatic: {automatic}");
assert_eq!(typed(automatic, "(1,000)"), None, "a thousands comma, automatic: {automatic}");
assert_eq!(typed(automatic, "(1,5)"), Some(SpinPick::Value(1.5)), "a decimal comma, automatic: {automatic}");
}
}
+3 -3
View File
@@ -511,15 +511,15 @@ fn bounded_field_reading(
/// may follow any operand: `45*2°`, `50% / 2`. With `parentheses` (Kerning, which shows its
/// automatic value as `(12)`), one pair of parentheses around the whole text is dropped first, so
/// `(12)` reads as 12. Any other parentheses are refused: `(10+5)*2` reads as nothing, not as
/// `10+5*2`.
/// `10+5*2`. A decimal comma is read ([`decimal_point`]) after the suffix, `%`, `°` and that pair
/// are dropped, so `(1,000)` and `1,000%` are refused as thousands rather than read as 1.
pub(super) fn field_number(buf: &str, suffix: &str, parentheses: bool) -> Option<f64> {
let suffix = suffix.trim();
let buf = decimal_point(buf);
let bare = if suffix.is_empty() { buf.to_string() } else { buf.replace(suffix, "") };
let bare = bare.replace(['%', '°'], "");
let bare = bare.trim();
let bare = if parentheses { bare.strip_prefix('(').and_then(|b| b.strip_suffix(')')).unwrap_or(bare) } else { bare };
vectorcraft_doc::parse_number(bare)
vectorcraft_doc::parse_number(&decimal_point(bare))
}
/// The text [`plain_field`] shows for `value`: at most `decimals` places, without trailing zeros,