use super::contrast::{is_tool_noun, phrase_at, phrase_words, shared_tool_nouns};
use super::sentence::{bare, blocks, param_words, push_norm_hit, sentences, word_tokens};
use crate::engine::{CompiledPolicy, Hit};
use crate::input::Prepared;
use crate::views::NormView;
use crate::Config;
pub const HANDLED: &[&str] = &["SLOP-F005"];
pub fn evaluate(
cp: &CompiledPolicy,
prepared: &Prepared,
norm: &NormView,
config: &Config,
hits: &mut Vec<Hit>,
) {
let Some(idx) = super::active(cp, config, "SLOP-F005") else {
return;
};
let rule = &cp.pkg.rules[idx];
let mut markers = param_words(rule, "design_markers");
markers.extend(param_words(rule, "reception_markers"));
let markers = phrase_words(&markers);
let tool_nouns = shared_tool_nouns(cp);
let text = norm.text.as_str();
let src = prepared.text.as_str();
let lower = text.to_ascii_lowercase();
for block in blocks(norm) {
for sentence in sentences(text, &block) {
let toks = word_tokens(&lower[sentence.clone()]);
if !toks.iter().any(|t| is_tool_noun(&bare(t.1), &tool_nouns)) {
continue;
}
for i in 0..toks.len() {
for marker in &markers {
if !phrase_at(&toks, i, marker) {
continue;
}
let last = toks[i + marker.len() - 1];
let end = last.0
+ last
.1
.trim_end_matches(|c: char| !c.is_alphanumeric())
.len();
let span = sentence.start + toks[i].0..sentence.start + end;
push_norm_hit(idx, norm, src, span, hits);
}
}
}
}
}