From 4fbbbfc6afae63cf33b5d50ba6683f85658c5f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Matczuk?= Date: Thu, 14 Nov 2024 09:35:34 +0100 Subject: [PATCH] html: refactor split point calculation --- src/html.rs | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/html.rs b/src/html.rs index df2ae5d..29f7f34 100644 --- a/src/html.rs +++ b/src/html.rs @@ -75,29 +75,35 @@ impl regex::Replacer for BionicWordReplacer { dst.push_str(space); let word = caps.get(2).unwrap().as_str(); - if word.len() <= 1 { + let idx = split_at(word); + if idx == 0 { dst.push_str(word); } else { - let midpoint = midpoint(word); dst.push_str(""); - dst.push_str(&word[..midpoint]); + dst.push_str(&word[..idx]); dst.push_str(""); - dst.push_str(&word[midpoint..]); + dst.push_str(&word[idx..]); } } } -fn midpoint(word: &str) -> usize { - let mut midpoint; - if word.len() <= 3 { - midpoint = 1; - } else { - midpoint = word.len() / 2; - } - while !word.is_char_boundary(midpoint) { - midpoint += 1; +fn split_at(word: &str) -> usize { + let n = match word.chars().count() { + c if c <= 1 => 0, + c if c <= 3 => 1, + c if c <= 8 => 2, + c if c <= 12 => 4, + _ => 5, + }; + if n == 0 { + return 0; } - midpoint + + word.char_indices() + .skip(n) + .next() + .map(|(p, _)| p) + .expect(word) } #[cfg(test)] @@ -107,15 +113,23 @@ mod tests { #[test] fn test_rewrite_to_bionic() { let tests = vec![ - ("

hello world

", "

hello world

"), - ("
  • hello
  • ", "
  • hello
  • "), + ("The", "The"), + ("Bionic", "Bionic"), + ("reading", "reading"), + ("method", "method"), + ("can", "can"), + ("be", "be"), + ("individually", "individually"), + ("flexibility", "flexibility"), + ("customization", "customization"), + ("highlighted", "highlighted"), ]; - for (input, expected) in tests { + let input = format!("

    {}

    ", input); let mut input = input.as_bytes(); let mut output = Vec::new(); rewrite_to_bionic(&mut output, &mut input).unwrap(); - assert_eq!(String::from_utf8(output).unwrap(), expected); + assert_eq!(String::from_utf8(output).unwrap(), format!("

    {}

    ", expected)); } } }