use petgraph::visit::{EdgeRef, IntoEdgeReferences, IntoNodeReferences};
use crate::error::{Error, Result};
use crate::graph::{Graph, GraphNodeType};
use super::GraphDisplay;
#[derive(Debug, Default)]
pub struct Tikz {}
impl Tikz {
pub fn new() -> Self {
Tikz {}
}
}
impl GraphDisplay for Tikz {
fn generate_from_graph(&self, graph: &Graph) -> Result<String> {
let mut res = r#"
\documentclass[tikz,border=10pt]{standalone}
\usepackage{ctex}
\usetikzlibrary{graphdrawing}
\usetikzlibrary{shapes}
\usepackage{spverbatim}
\usepackage{varwidth}
\usetikzlibrary{graphs}
\usegdlibrary{layered}
\usepackage[T1]{fontenc}% NOT OT1!
\usepackage{lmodern}% Latin Modern fonts,
% a modern variant of Computer Modern fonts
\let\ttdefault\rmdefault
\tikzstyle{block} = [%
draw,thick,fill=blue!0,
inner sep=0.3cm,
text centered, minimum height=1em,
execute at begin node={\begin{varwidth}{8em}},
execute at end node={\end{varwidth}}]
\begin{document}
\tikz [layered layout, sibling distance=3cm] {
"#
.to_string();
for (id, i) in graph.node_references() {
match i {
GraphNodeType::Begin => res.push_str(
format!(
"\\node[draw] (D{}) [rounded rectangle, block] {{ Begin }};\n",
id.index()
)
.as_str(),
),
GraphNodeType::End => res.push_str(
format!(
"\\node[draw] (D{}) [rounded rectangle, block] {{ End }};\n",
id.index()
)
.as_str(),
),
GraphNodeType::Node(str) => res.push_str(
format!(
"\\node[draw] (D{}) [rectangle, block] {{ \\spverb${}$ }};\n",
id.index(),
str.replace('%', "\\%")
)
.replace('\n', " ")
.as_str(),
),
GraphNodeType::Choice(str) => res.push_str(
format!(
"\\node[draw] (D{}) [diamond, aspect=2, block] {{ \\spverb${}$ }};\n",
id.index(),
str.replace('%', "\\%")
)
.replace('\n', " ")
.as_str(),
),
GraphNodeType::Dummy => {
return Err(Error::UnexpectedDummyGraphNode {
graph: graph.clone(),
});
} }
}
for i in graph.edge_references() {
match i.weight() {
crate::graph::EdgeType::Normal => res.push_str(
format!(
"\\draw (D{}) edge[->] (D{});\n",
i.source().index(),
i.target().index()
)
.as_str(),
),
crate::graph::EdgeType::Branch(t) => res.push_str(
format!(
"\\draw (D{}) edge[->, below] node {{ {} }} (D{});\n",
i.source().index(),
i.target().index(),
if *t { "Y" } else { "N" }
)
.as_str(),
),
}
}
res.push_str(
r#"
}
\end{document}
"#,
);
Ok(res)
}
}