From 1f1661263c88cce03b6baf27b23f859b6f072c53 Mon Sep 17 00:00:00 2001 From: cos Date: Mon, 14 Jun 2021 13:06:12 +0200 Subject: Allow any ID string According to the grammar of The DOT Language[1], an ID can be given in one of four possible formats. Where the most permissive format is any string quoted within double quotes. For generated output to be valid, the ID strings better use that format. Since dotavious does not, and should not, enforce that the ID only contains characters from any of the more limited forms. [1]: https://www.graphviz.org/doc/info/lang.html --- src/dot.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dot.rs b/src/dot.rs index f154dc9..c211bdb 100644 --- a/src/dot.rs +++ b/src/dot.rs @@ -53,7 +53,7 @@ impl<'a> Dot<'a> { write!(w, "{}{}", strict, &graph.graph_type())?; if let Some(id) = &graph.id { - write!(w, " {}", id)?; + write!(w, r#" "{}""#, escape_doublequotes(id))?; } writeln!(w, " {{")?; @@ -185,11 +185,11 @@ impl<'a> Dot<'a> { write!( w, - "{}{} {} {}", + r#"{}"{}" {} "{}""#, get_indentation(indentation_level), - edge_source, + escape_doublequotes(&edge_source), edge_op, - edge_target + escape_doublequotes(&edge_source) )?; write!(w, "{}", fmt_attributes(&edge.attributes))?; writeln!(w, ";") @@ -638,7 +638,7 @@ impl<'a> Node<'a> { impl<'a> DotString<'a> for Node<'a> { fn dot_string(&self) -> Cow<'a, str> { - let mut dot_string = format!("{}", &self.id); + let mut dot_string = format!(r#""{}""#, escape_doublequotes(&self.id)); dot_string.push_str(fmt_attributes(&self.attributes).as_str()); dot_string.push_str(";"); dot_string.into() @@ -965,3 +965,7 @@ impl<'a> EdgeAttributeStatementBuilder<'a> { fn get_indentation(indentation_level: usize) -> String { INDENT.repeat(indentation_level) } + +fn escape_doublequotes(val: &String) -> String { + val.chars().map(|c| if c == '"' { format!("\\{}", c) } else { format!("{}", c)}).collect() +} -- cgit v1.2.3