From f27b3033d59ba86a3edd6e341b8e6cc3783ef7de Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 27 Nov 2024 11:45:43 -0500 Subject: [PATCH 1/5] Update acronym filter to ignore word boundaries. Fixes #415 --- crates/weaver_forge/src/extensions/util.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index ffab931a..f2235858 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -8,7 +8,6 @@ use minijinja::{Environment, ErrorKind, Value}; use regex::Regex; use std::borrow::Cow; use std::collections::HashMap; -use std::sync::OnceLock; /// Add utility filters and tests to the environment. pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &WeaverConfig) { @@ -112,22 +111,23 @@ fn regex_replace( /// A function that takes an input string and returns a new string with the /// acronyms replaced. pub fn acronym(acronyms: Vec) -> impl Fn(&str) -> String { - static RE: OnceLock = OnceLock::new(); let acronym_map = acronyms .iter() .map(|acronym| (acronym.to_lowercase(), acronym.clone())) .collect::>(); move |input: &str| -> String { - // Pattern to match sequences of whitespace (\s+), non-whitespace - // non-punctuation (\w+), or any punctuation ([^\w\s]+) - let re = RE.get_or_init(|| Regex::new(r"(\s+|\w+|[^\w\s]+)").expect("Invalid regex")); - re.find_iter(input) - .map(|mat| match acronym_map.get(&mat.as_str().to_lowercase()) { - Some(acronym) => acronym.clone(), - None => mat.as_str().to_owned(), - }) - .collect() + // Arbitrarily replace all existence of an acronym. + // Note: This assumes lower + upper case have the same length. + // This may not be true for i18n strings. + let mut result = input.to_owned(); + let input_matcher = input.to_lowercase(); + for (acronymn, replacement) in acronym_map.iter() { + for (idx, _) in input_matcher.match_indices(acronymn) { + result.replace_range(idx..(idx + replacement.len()), &replacement); + } + } + result } } From 5fdb785c313abf52a4917babbe0a6ee81d6356e1 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 27 Nov 2024 11:56:18 -0500 Subject: [PATCH 2/5] Add test. --- crates/weaver_forge/src/extensions/util.rs | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index f2235858..8eb91545 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -122,8 +122,8 @@ pub fn acronym(acronyms: Vec) -> impl Fn(&str) -> String { // This may not be true for i18n strings. let mut result = input.to_owned(); let input_matcher = input.to_lowercase(); - for (acronymn, replacement) in acronym_map.iter() { - for (idx, _) in input_matcher.match_indices(acronymn) { + for (matcher, replacement) in acronym_map.iter() { + for (idx, _) in input_matcher.match_indices(matcher) { result.replace_range(idx..(idx + replacement.len()), &replacement); } } @@ -159,4 +159,23 @@ mod tests { "This A test with multiple A's" ); } + + #[test] + fn test_acronym_filter() { + let mut env = Environment::new(); + let ctx = serde_json::Value::Null; + let mut config = crate::config::WeaverConfig::default(); + config.acronyms = Some(vec!["Html".to_owned(), "iOS".to_owned(), "API".to_owned()]); + add_filters(&mut env, &config); + assert_eq!( + env.render_str("{{ 'api' | acronym }}", &ctx).unwrap(), + "API" + ); + + assert_eq!( + env.render_str("{{ 'iosapplyhtmlthings' | acronym }}", &ctx) + .unwrap(), + "iOSapplyHtmlthings" + ); + } } From 83b9d0a889ec8a3b2caa7cacaa0d56412d0aa949 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 27 Nov 2024 11:57:49 -0500 Subject: [PATCH 3/5] Fix clippy issue. --- crates/weaver_forge/src/extensions/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index 8eb91545..3e2cc9a7 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -124,7 +124,7 @@ pub fn acronym(acronyms: Vec) -> impl Fn(&str) -> String { let input_matcher = input.to_lowercase(); for (matcher, replacement) in acronym_map.iter() { for (idx, _) in input_matcher.match_indices(matcher) { - result.replace_range(idx..(idx + replacement.len()), &replacement); + result.replace_range(idx..(idx + replacement.len()), replacement); } } result From e707f75001b67fc5c83d11caf68b0f7f2d25834f Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 27 Nov 2024 11:59:52 -0500 Subject: [PATCH 4/5] Fix last clippy issue. --- crates/weaver_forge/src/extensions/util.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index 3e2cc9a7..74dcd927 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -133,14 +133,14 @@ pub fn acronym(acronyms: Vec) -> impl Fn(&str) -> String { #[cfg(test)] mod tests { - use crate::extensions::util::add_filters; + use crate::{config::WeaverConfig, extensions::util::add_filters}; use minijinja::Environment; #[test] fn test_regex_replace() { let mut env = Environment::new(); let ctx = serde_json::Value::Null; - let config = crate::config::WeaverConfig::default(); + let config = WeaverConfig::default(); add_filters(&mut env, &config); @@ -164,8 +164,11 @@ mod tests { fn test_acronym_filter() { let mut env = Environment::new(); let ctx = serde_json::Value::Null; - let mut config = crate::config::WeaverConfig::default(); - config.acronyms = Some(vec!["Html".to_owned(), "iOS".to_owned(), "API".to_owned()]); + let config = + WeaverConfig { + acronyms: Some(vec!["Html".to_owned(), "iOS".to_owned(), "API".to_owned()]), + ..Default::default() + }; add_filters(&mut env, &config); assert_eq!( env.render_str("{{ 'api' | acronym }}", &ctx).unwrap(), From 7e12de78f80ee7a390aa7a0c77971f5d9fa01c39 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 27 Nov 2024 12:00:58 -0500 Subject: [PATCH 5/5] Fix formatting. --- crates/weaver_forge/src/extensions/util.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index 74dcd927..12d90a64 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -164,11 +164,10 @@ mod tests { fn test_acronym_filter() { let mut env = Environment::new(); let ctx = serde_json::Value::Null; - let config = - WeaverConfig { - acronyms: Some(vec!["Html".to_owned(), "iOS".to_owned(), "API".to_owned()]), - ..Default::default() - }; + let config = WeaverConfig { + acronyms: Some(vec!["Html".to_owned(), "iOS".to_owned(), "API".to_owned()]), + ..Default::default() + }; add_filters(&mut env, &config); assert_eq!( env.render_str("{{ 'api' | acronym }}", &ctx).unwrap(),