diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs
index 83d731c..b55d588 100644
--- a/src/handlers/graphical.rs
+++ b/src/handlers/graphical.rs
@@ -214,8 +214,7 @@ impl GraphicalReportHandler {
let opts = textwrap::Options::new(width)
.initial_indent(&initial_indent)
.subsequent_indent(&rest_indent);
- let mut message = diagnostic.to_string();
-
+ let message = self.apply_tags(diagnostic.to_string());
writeln!(f, "{}", textwrap::fill(&message, opts))?;
@@ -805,6 +804,31 @@ impl GraphicalReportHandler {
}
Ok((context_data, lines))
}
+
+ fn apply_tags(&self, message: String) -> String {
+ let mut message = message;
+
+ for (tag, style) in &self.theme.tags {
+ let open_tag = format!("<{}>", tag);
+ let close_tag = format!("{}>", tag);
+
+ while let Some(open_index) = message.find(&open_tag) {
+ if let Some(close_index) = message.find(&close_tag) {
+ let inner = &message[open_index + open_tag.len()..close_index];
+
+ message = message.replace(
+ &format!("{}{}{}", open_tag, inner, close_tag),
+ &inner.style(*style).to_string(),
+ );
+ } else {
+ // No closing? Just remove the opening...
+ message = message.replace(&open_tag, "");
+ }
+ }
+ }
+
+ message
+ }
}
impl ReportHandler for GraphicalReportHandler {
diff --git a/tests/graphical.rs b/tests/graphical.rs
index 34dc433..776c858 100644
--- a/tests/graphical.rs
+++ b/tests/graphical.rs
@@ -4,6 +4,7 @@ use miette::{
Diagnostic, GraphicalReportHandler, GraphicalTheme, MietteError, NamedSource,
NarratableReportHandler, Report, SourceSpan,
};
+use owo_colors::Style;
use thiserror::Error;
fn fmt_report(diag: Report) -> String {
@@ -1214,3 +1215,32 @@ fn zero_length_eol_span() {
assert_eq!(expected, out);
}
+
+#[test]
+fn message_tags() -> Result<(), MietteError> {
+ #[derive(Debug, Diagnostic, Error)]
+ #[error("this is a string with many style tags!")]
+ #[diagnostic(code(oops::my::bad))]
+ struct MyBad;
+
+ let mut theme = GraphicalTheme::unicode();
+ theme.tags.insert("green".to_string(), Style::new().green());
+ theme
+ .tags
+ .insert("yellow".to_string(), Style::new().yellow());
+ theme.tags.insert("blue".to_string(), Style::new().blue());
+
+ let err = MyBad;
+ let report: Report = err.into();
+ let mut out = String::new();
+
+ GraphicalReportHandler::new_themed(theme)
+ .with_width(80)
+ .render_report(&mut out, report.as_ref())
+ .unwrap();
+
+ println!("Error: {}", out);
+ let expected = "\u{1b}[31moops::my::bad\u{1b}[0m\n\n \u{1b}[31m×\u{1b}[0m this \u{1b}[32mis\u{1b}[0m a \u{1b}[33mstring \u{1b}[34mwith\u{1b}[0m\u{1b}[0m many \u{1b}[32mstyle\u{1b}[0m tags!\n";
+ assert_eq!(expected, out);
+ Ok(())
+}