pub mod typography;
pub mod whitespace;
#[cfg(test)]
mod test;
use regex::Regex;
#[derive(Debug)]
pub enum Replacer {
RegexReplace {
regex: Regex,
replacement: &'static str,
},
RegexSurround {
regex: Regex,
begin: &'static str,
end: &'static str,
},
}
impl Replacer {
fn replace(&self, text: &mut String, buffer: &mut String) {
use self::Replacer::*;
match *self {
RegexReplace {
ref regex,
replacement,
} => {
trace!(
"Running regex regular expression replacement (pattern {}, replacement {})",
regex.as_str(),
replacement,
);
let mut offset = 0;
while let Some(capture) = regex.captures_at(text, offset) {
let range = {
let mtch = capture
.name("repl")
.unwrap_or_else(|| capture.get(0).unwrap());
offset = mtch.start() + replacement.len();
mtch.range()
};
text.replace_range(range, replacement);
}
}
RegexSurround {
ref regex,
begin,
end,
} => {
trace!(
"Running surround regular expression capture replacement (pattern {}, begin {}, end {})",
regex.as_str(),
begin,
end,
);
let mut offset = 0;
while let Some(capture) = regex.captures_at(text, offset) {
let mtch = capture
.get(1)
.expect("Regular expression lacks a content group");
let range = {
let full_mtch = capture
.get(0)
.expect("Regular expression lacks a full match");
offset = full_mtch.start() + mtch.len() + begin.len() + end.len();
full_mtch.range()
};
buffer.clear();
buffer.push_str(begin);
buffer.push_str(mtch.as_str());
buffer.push_str(end);
text.replace_range(range, buffer);
}
}
}
}
}
pub fn preprocess(text: &mut String) {
info!("Beginning preprocessing of text ({} bytes)", text.len());
whitespace::substitute(text);
typography::substitute(text);
debug!("Finished preprocessing of text ({} bytes)", text.len());
}
#[test]
fn fn_type() {
type SubstituteFn = fn(&mut String);
let _: SubstituteFn = whitespace::substitute;
let _: SubstituteFn = typography::substitute;
}