//! ref: composer/src/Composer/Console/HtmlOutputFormatter.php use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::{CaptureKey, Preg}; use shirabe_external_packages::symfony::console::formatter::output_formatter::OutputFormatter; use shirabe_external_packages::symfony::console::formatter::output_formatter_style::OutputFormatterStyle; #[derive(Debug)] pub struct HtmlOutputFormatter { inner: OutputFormatter, } impl HtmlOutputFormatter { const AVAILABLE_FOREGROUND_COLORS: &'static [(i64, &'static str)] = &[ (30, "black"), (31, "red"), (32, "green"), (33, "yellow"), (34, "blue"), (35, "magenta"), (36, "cyan"), (37, "white"), ]; const AVAILABLE_BACKGROUND_COLORS: &'static [(i64, &'static str)] = &[ (40, "black"), (41, "red"), (42, "green"), (43, "yellow"), (44, "blue"), (45, "magenta"), (46, "cyan"), (47, "white"), ]; const AVAILABLE_OPTIONS: &'static [(i64, &'static str)] = &[ (1, "bold"), (4, "underscore"), //5 => "blink", //7 => "reverse", //8 => "conceal" ]; pub fn new(styles: IndexMap) -> Self { // TODO(phase-b): styles dropped until base OutputFormatter::new accepts a style map let _ = styles; Self { inner: OutputFormatter::new(true), } } pub fn format(&self, message: Option<&str>) -> Option { let formatted = self.inner.format(message.unwrap_or("")); let clear_escape_codes = "(?:39|49|0|22|24|25|27|28)"; let pattern = format!( "{{\\033\\[([0-9;]+)m(.*?)\\033\\[(?:{};)*?{}m}}s", clear_escape_codes, clear_escape_codes ); Preg::replace_callback(&pattern, |matches| self.format_html(matches), &formatted).ok() } fn format_html(&self, matches: &IndexMap) -> String { let codes_str = matches .get(&CaptureKey::ByIndex(1)) .map(|s| s.as_str()) .unwrap_or(""); let content = matches .get(&CaptureKey::ByIndex(2)) .map(|s| s.as_str()) .unwrap_or(""); let mut out = String::from(" out.push_str("font-weight:bold;"), "underscore" => out.push_str("text-decoration:underline;"), _ => {} } } } format!("{}\">{}", out, content) } }