Lumiera  0.pre.03
»edit your freedom«
dot-gen.hpp
Go to the documentation of this file.
1 /*
2  DOT-GEN.hpp - DSL to generate Graphviz-DOT code
3 
4  Copyright (C) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
63 #ifndef LIB_DOT_GEN_H
64 #define LIB_DOT_GEN_H
65 
66 
67 #include "lib/format-util.hpp"
68 #include "lib/util.hpp"
69 
70 #include <utility>
71 #include <sstream>
72 #include <string>
73 #include <vector>
74 
75 
76 namespace lib {
77 namespace dot_gen {
78 
79  using util::toString;
80  using util::isnil;
81  using std::string;
82  using std::move;
83 
84 
86  struct Code : string
87  {
88  using string::string;
89  Code(string const& c) : string{c} { }
90  Code(string && c) : string{move(c)}{ }
91  };
92 
93 
95  struct Section
96  {
97  std::vector<string> lines;
98 
99  Section (string name)
100  : lines{"// "+name}
101  { }
102 
103  Section&&
104  operator+= (Code const& code)
105  {
106  lines.emplace_back(code);
107  return move(*this);
108  }
109  };
110 
111 
112 
116  struct Node : Code
117  {
118  Node (size_t id)
119  : Code{"N"+toString(id)}
120  { }
121 
122  Node&&
123  addAttrib (string def)
124  {
125  if (back() != ']')
126  append ("[");
127  else
128  {
129  resize (length()-2);
130  append (", ");
131  }
132  append (def+" ]");
133  return move(*this);
134  }
135 
136  Node&&
137  label (string text)
138  {
139  return addAttrib ("label=\""+text+"\"");
140  }
141 
142  Node&&
143  style (Code const& code)
144  {
145  if (not isnil(code))
146  addAttrib (code);
147  return move(*this);
148  }
149  };
150 
151 
153  struct Scope : Code
154  {
155  Scope (size_t id)
156  : Code{"{ /*"+toString(id)+"*/ }"}
157  { }
158 
159  Scope&&
160  add (Code const& code)
161  {
162  resize(length()-1);
163  append (code+" }");
164  return move(*this);
165  }
166 
167  Scope&&
168  rank (string rankSetting)
169  {
170  return add(Code{"rank="+rankSetting});
171  }
172  };
173 
174  inline Node node (size_t id) { return Node(id); }
175  inline Scope scope (size_t id) { return Scope(id); }
176 
178  inline Code
179  connect (size_t src, size_t dest)
180  {
181  return Code{Node(src) +" -> "+ Node(dest)};
182  }
183 
184 
186  class DotOut
187  {
188  std::ostringstream buff_;
189 
190  static uint const IDENT_STEP = 2;
191  public:
192  void
193  putLine (string line, uint indent=0)
194  {
195  if (indent)
196  buff_ << string(indent,' ');
197  buff_ << line
198  << '\n';
199  }
200 
201  void
202  put (Code const& code)
203  {
204  buff_ << code;
205  }
206 
207  void
208  put (Section const& sect)
209  {
210  for (string const& line : sect.lines)
211  putLine (line, IDENT_STEP);
212  }
213 
214  template<class P, class...PS>
215  void
216  put (P const& part, PS const& ...parts)
217  {
218  put (part);
219  putLine ("");
220  put (parts...);
221  }
222 
224  operator string() const
225  {
226  return buff_.str();
227  }
228  };
229 
235  template<class...COD>
236  inline DotOut
237  digraph (COD ...parts)
238  {
239  DotOut script;
240  script.putLine (Code{"digraph {"});
241  script.put (parts...);
242  script.putLine (Code{"}"});
243  return script;
244  }
245 
246 
247 }} // namespace lib::dot_gen
248 #endif /*LIB_DOT_GEN_H*/
generate a Node name or a node_statement defining attributes of that node.
Definition: dot-gen.hpp:116
Accumulator to collect lines of DOT code.
Definition: dot-gen.hpp:95
Code connect(size_t src, size_t dest)
generate a directed node connectivity clause
Definition: dot-gen.hpp:179
Implementation namespace for support and library code.
markup to generate a piece of code
Definition: dot-gen.hpp:86
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:200
accumulator to collect nodes grouped into a scope
Definition: dot-gen.hpp:153
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:80
Helper to collect DOT-Graphviz code for output.
Definition: dot-gen.hpp:186
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption
DotOut digraph(COD ...parts)
Entrance-point: generate a graph spec in DOT-Language.
Definition: dot-gen.hpp:237