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)
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
54 #ifndef LIB_DOT_GEN_H
55 #define LIB_DOT_GEN_H
56 
57 
58 #include "lib/format-util.hpp"
59 #include "lib/util.hpp"
60 
61 #include <utility>
62 #include <sstream>
63 #include <string>
64 #include <vector>
65 
66 
67 namespace lib {
68 namespace dot_gen {
69 
70  using util::toString;
71  using util::isnil;
72  using std::string;
73  using std::move;
74 
75 
77  struct Code : string
78  {
79  using string::string;
80  Code(string const& c) : string{c} { }
81  Code(string && c) : string{move(c)}{ }
82  };
83 
84 
86  struct Section
87  {
88  std::vector<string> lines;
89 
90  Section (string name)
91  : lines{"// "+name}
92  { }
93 
94  Section&&
95  operator+= (Code const& code)
96  {
97  lines.emplace_back(code);
98  return move(*this);
99  }
100  };
101 
102 
103 
107  struct Node : Code
108  {
109  Node (size_t id)
110  : Code{"N"+toString(id)}
111  { }
112 
113  Node&&
114  addAttrib (string def)
115  {
116  if (back() != ']')
117  append ("[");
118  else
119  {
120  resize (length()-2);
121  append (", ");
122  }
123  append (def+" ]");
124  return move(*this);
125  }
126 
127  Node&&
128  label (string text)
129  {
130  return addAttrib ("label=\""+text+"\"");
131  }
132 
133  Node&&
134  style (Code const& code)
135  {
136  if (not isnil(code))
137  addAttrib (code);
138  return move(*this);
139  }
140  };
141 
142 
144  struct Scope : Code
145  {
146  Scope (size_t id)
147  : Code{"{ /*"+toString(id)+"*/ }"}
148  { }
149 
150  Scope&&
151  add (Code const& code)
152  {
153  resize(length()-1);
154  append (code+" }");
155  return move(*this);
156  }
157 
158  Scope&&
159  rank (string rankSetting)
160  {
161  return add(Code{"rank="+rankSetting});
162  }
163  };
164 
165  inline Node node (size_t id) { return Node(id); }
166  inline Scope scope (size_t id) { return Scope(id); }
167 
169  inline Code
170  connect (size_t src, size_t dest)
171  {
172  return Code{Node(src) +" -> "+ Node(dest)};
173  }
174 
175 
177  class DotOut
178  {
179  std::ostringstream buff_;
180 
181  static uint const IDENT_STEP = 2;
182  public:
183  void
184  putLine (string line, uint indent=0)
185  {
186  if (indent)
187  buff_ << string(indent,' ');
188  buff_ << line
189  << '\n';
190  }
191 
192  void
193  put (Code const& code)
194  {
195  buff_ << code;
196  }
197 
198  void
199  put (Section const& sect)
200  {
201  for (string const& line : sect.lines)
202  putLine (line, IDENT_STEP);
203  }
204 
205  template<class P, class...PS>
206  void
207  put (P const& part, PS const& ...parts)
208  {
209  put (part);
210  putLine ("");
211  put (parts...);
212  }
213 
215  operator string() const
216  {
217  return buff_.str();
218  }
219  };
220 
226  template<class...COD>
227  inline DotOut
228  digraph (COD ...parts)
229  {
230  DotOut script;
231  script.putLine (Code{"digraph {"});
232  script.put (parts...);
233  script.putLine (Code{"}"});
234  return script;
235  }
236 
237 
238 }} // namespace lib::dot_gen
239 #endif /*LIB_DOT_GEN_H*/
generate a Node name or a node_statement defining attributes of that node.
Definition: dot-gen.hpp:107
Accumulator to collect lines of DOT code.
Definition: dot-gen.hpp:86
Code connect(size_t src, size_t dest)
generate a directed node connectivity clause
Definition: dot-gen.hpp:170
Implementation namespace for support and library code.
markup to generate a piece of code
Definition: dot-gen.hpp:77
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:191
accumulator to collect nodes grouped into a scope
Definition: dot-gen.hpp:144
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:71
Helper to collect DOT-Graphviz code for output.
Definition: dot-gen.hpp:177
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:228