cxx2flow_lib/display/
tikz.rs1use petgraph::visit::{EdgeRef, IntoEdgeReferences, IntoNodeReferences};
2
3use crate::error::{Error, Result};
4use crate::graph::{Graph, GraphNodeType};
5
6use super::GraphDisplay;
7#[derive(Debug, Default)]
8pub struct Tikz {}
9
10impl Tikz {
11 pub fn new() -> Self {
12 Tikz {}
13 }
14}
15
16impl GraphDisplay for Tikz {
17 fn generate_from_graph(&self, graph: &Graph) -> Result<String> {
18 let mut res = r#"
19\documentclass[tikz,border=10pt]{standalone}
20\usepackage{ctex}
21\usetikzlibrary{graphdrawing}
22\usetikzlibrary{shapes}
23\usepackage{spverbatim}
24\usepackage{varwidth}
25\usetikzlibrary{graphs}
26\usegdlibrary{layered}
27\usepackage[T1]{fontenc}% NOT OT1!
28\usepackage{lmodern}% Latin Modern fonts,
29 % a modern variant of Computer Modern fonts
30\let\ttdefault\rmdefault
31\tikzstyle{block} = [%
32 draw,thick,fill=blue!0,
33 inner sep=0.3cm,
34 text centered, minimum height=1em,
35 execute at begin node={\begin{varwidth}{8em}},
36 execute at end node={\end{varwidth}}]
37\begin{document}
38\tikz [layered layout, sibling distance=3cm] {
39 "#
40 .to_string();
41 for (id, i) in graph.node_references() {
42 match i {
43 GraphNodeType::Begin => res.push_str(
44 format!(
45 "\\node[draw] (D{}) [rounded rectangle, block] {{ Begin }};\n",
46 id.index()
47 )
48 .as_str(),
49 ),
50 GraphNodeType::End => res.push_str(
51 format!(
52 "\\node[draw] (D{}) [rounded rectangle, block] {{ End }};\n",
53 id.index()
54 )
55 .as_str(),
56 ),
57 GraphNodeType::Node(str) => res.push_str(
58 format!(
59 "\\node[draw] (D{}) [rectangle, block] {{ \\spverb${}$ }};\n",
60 id.index(),
61 str.replace('%', "\\%")
62 )
63 .replace('\n', " ")
64 .as_str(),
65 ),
66 GraphNodeType::Choice(str) => res.push_str(
67 format!(
68 "\\node[draw] (D{}) [diamond, aspect=2, block] {{ \\spverb${}$ }};\n",
69 id.index(),
70 str.replace('%', "\\%")
71 )
72 .replace('\n', " ")
73 .as_str(),
74 ),
75 GraphNodeType::Dummy => {
76 return Err(Error::UnexpectedDummyGraphNode {
77 graph: graph.clone(),
78 });
79 } }
81 }
82 for i in graph.edge_references() {
83 match i.weight() {
84 crate::graph::EdgeType::Normal => res.push_str(
85 format!(
86 "\\draw (D{}) edge[->] (D{});\n",
87 i.source().index(),
88 i.target().index()
89 )
90 .as_str(),
91 ),
92 crate::graph::EdgeType::Branch(t) => res.push_str(
93 format!(
94 "\\draw (D{}) edge[->, below] node {{ {} }} (D{});\n",
95 i.source().index(),
96 i.target().index(),
97 if *t { "Y" } else { "N" }
98 )
99 .as_str(),
100 ),
101 }
102 }
103 res.push_str(
104 r#"
105}
106\end{document}
107 "#,
108 );
109 Ok(res)
110 }
111}