use super::*;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::vec::Vec;
const SEPARATOR: char = ';';
#[deprecated = "please use v3::categorise_text to move to API v3.0. \
this function will be removed with v3.0 of cansi"]
#[allow(deprecated)]
pub fn categorise_text(text: &str) -> CategorisedSlices {
categorise_text_v3(text)
.into_iter()
.map(Into::into)
.collect()
}
pub fn categorise_text_v3(text: &str) -> v3::CategorisedSlices {
let matches = parse(text);
let mut sgr = SGR::default();
let mut lo = 0;
let mut slices: Vec<v3::CategorisedSlice> = Vec::with_capacity(matches.len() + 1);
for m in matches {
if m.start != lo {
slices.push(v3::CategorisedSlice::with_sgr(
sgr,
&text[lo..m.start],
lo,
m.start,
));
}
sgr = handle_seq(&m);
lo = m.end;
}
if lo != text.len() {
slices.push(v3::CategorisedSlice::with_sgr(
sgr,
&text[lo..text.len()],
lo,
text.len(),
));
}
slices
}
fn handle_seq(m: &Match) -> SGR {
let slice = &m.text[2..(m.text.len() - 1)];
slice.split(SEPARATOR).fold(SGR::default(), adjust_sgr)
}
fn adjust_sgr(mut sgr: SGR, seq: &str) -> SGR {
match seq {
"0" => return SGR::default(), "1" => sgr.intensity = Some(Intensity::Bold), "2" => sgr.intensity = Some(Intensity::Faint), "3" => sgr.italic = Some(true), "4" => sgr.underline = Some(true), "5" => sgr.blink = Some(true), "7" => sgr.reversed = Some(true), "8" => sgr.hidden = Some(true), "9" => sgr.strikethrough = Some(true), "22" => sgr.intensity = Some(Intensity::Normal), "23" => sgr.italic = Some(false), "24" => sgr.underline = Some(false), "25" => sgr.blink = Some(false), "27" => sgr.reversed = Some(false), "28" => sgr.hidden = Some(false), "29" => sgr.strikethrough = Some(false), "30" => sgr.fg = Some(Color::Black), "31" => sgr.fg = Some(Color::Red), "32" => sgr.fg = Some(Color::Green), "33" => sgr.fg = Some(Color::Yellow), "34" => sgr.fg = Some(Color::Blue), "35" => sgr.fg = Some(Color::Magenta), "36" => sgr.fg = Some(Color::Cyan), "37" => sgr.fg = Some(Color::White), "40" => sgr.bg = Some(Color::Black), "41" => sgr.bg = Some(Color::Red), "42" => sgr.bg = Some(Color::Green), "43" => sgr.bg = Some(Color::Yellow), "44" => sgr.bg = Some(Color::Blue), "45" => sgr.bg = Some(Color::Magenta), "46" => sgr.bg = Some(Color::Cyan), "47" => sgr.bg = Some(Color::White), "90" => sgr.fg = Some(Color::BrightBlack), "91" => sgr.fg = Some(Color::BrightRed), "92" => sgr.fg = Some(Color::BrightGreen), "93" => sgr.fg = Some(Color::BrightYellow), "94" => sgr.fg = Some(Color::BrightBlue), "95" => sgr.fg = Some(Color::BrightMagenta), "96" => sgr.fg = Some(Color::BrightCyan), "97" => sgr.fg = Some(Color::BrightWhite), "100" => sgr.bg = Some(Color::BrightBlack), "101" => sgr.bg = Some(Color::BrightRed), "102" => sgr.bg = Some(Color::BrightGreen), "103" => sgr.bg = Some(Color::BrightYellow), "104" => sgr.bg = Some(Color::BrightBlue), "105" => sgr.bg = Some(Color::BrightMagenta), "106" => sgr.bg = Some(Color::BrightCyan), "107" => sgr.bg = Some(Color::BrightWhite), _ => (),
}
sgr
}
#[cfg(test)]
mod tests {
use super::*;
use colored::Colorize;
#[test]
fn cat_and_matches_len() {
let txt = "hello";
let matches = parse(&txt);
let cat = categorise_text(&txt);
assert!(matches.len() + 1 >= cat.len());
let txt = "hello".bright_green();
let matches = parse(&txt);
let cat = categorise_text(&txt);
assert!(matches.len() + 1 >= cat.len());
let txt = format!("{}{}{}", "hello".bright_green(), "world".red(), "whatever");
let matches = parse(&txt);
let cat = categorise_text(&txt);
assert!(matches.len() + 1 >= cat.len());
}
#[test]
fn malformed_escapes() {
let x = categorise_text_v3("oops\x1b[\n");
assert_eq!(
x,
vec![v3::CategorisedSlice {
text: "oops\x1b[\n",
start: 0,
end: 7,
fg: None,
bg: None,
blink: None,
underline: None,
hidden: None,
intensity: None,
italic: None,
reversed: None,
strikethrough: None
}]
);
}
}