pub fn esc_label(s: &str) -> String {
const BR: char = '\u{E000}';
let mut s = s
.replace("<br/>", &BR.to_string())
.replace("<br>", &BR.to_string())
.replace("<", "<")
.replace(">", ">")
.replace("&", "&");
for (ch, rep) in [
('\\', "\\textbackslash{}"),
('&', "\\&"),
('%', "\\%"),
('$', "\\$"),
('#', "\\#"),
('_', "\\_"),
('{', "\\{"),
('}', "\\}"),
('~', "\\textasciitilde{}"),
('^', "\\textasciicircum{}"),
] {
s = s.replace(ch, rep);
}
s = s.replace(BR, "\\\\");
for (ch, rep) in [
('×', "$\\times$"),
('→', "$\\to$"),
('–', "--"),
('—', "---"),
('≤', "$\\leq$"),
('≥', "$\\geq$"),
('✓', "\\checkmark{}"),
] {
s = s.replace(ch, rep);
}
s
}
pub fn tikz_node(id: &str, x: f64, y: f64, style: &str, label: &str) -> String {
format!(
" \\node ({}) at ({:.1},{:.1}) [{style}] {{{}}};\n",
id,
x,
y,
esc_label(label)
)
}
pub fn cluster_rect(text: &str, r: (f64, f64, f64, f64), at: (f64, f64)) -> String {
format!(
" \\draw ({:.1},{:.1}) rectangle ({:.1},{:.1});\n \\node[anchor=north west,font=\\footnotesize\\itshape] at ({:.1},{:.1}) {{{}}};\n",
r.0, r.1, r.2, r.3, at.0, at.1, esc_label(text)
)
}
pub fn edge_label_node(lbl: &str) -> String {
format!(
"node[midway,above,fill=white,inner sep=1pt,font=\\footnotesize] {{{}}}",
esc_label(lbl)
)
}
pub const PICTURE_HEAD: &str =
"\\begin{tikzpicture}[>=Stealth,\n every node/.style={align=center,font=\\small},\n box/.style={draw,rounded corners=2pt,fill=gray!8},\n dia/.style={draw,diamond,aspect=2,fill=blue!8},\n stad/.style={draw,rounded corners=10pt,fill=gray!8},\n sub/.style={draw,double,fill=gray!8}]\n";
pub fn placed_label_node(lbl: &str, x: f64, y: f64) -> String {
format!(
"\\node[fill=white,inner sep=1pt,font=\\footnotesize] at ({x:.1},{y:.1}) {{{}}}",
esc_label(lbl)
)
}
pub fn unquote(s: &str) -> String {
let t = s.trim();
if t.len() >= 2 && t.starts_with('"') && t.ends_with('"') {
t[1..t.len() - 1].to_string()
} else {
t.to_string()
}
}