Vcsn  2.1
Be Rational
tikz.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <iostream>
5 #include <unordered_map>
6 #include <unordered_set>
7 #include <vector>
8 
9 #include <vcsn/algos/grail.hh> // outputter
10 
11 #include <vcsn/dyn/fwd.hh>
12 
13 namespace vcsn
14 {
15 
16  /*--------------------------.
17  | tikz(automaton, stream). |
18  `--------------------------*/
19 
20  namespace detail
21  {
25  template <typename Aut>
26  class tikzer: public outputter<Aut>
27  {
28  public:
30  using typename super_t::automaton_t;
31  using typename super_t::state_t;
32  using typename super_t::polynomial_t;
33  using typename super_t::transition_t;
34  using typename super_t::weight_t;
35 
36  using super_t::aut_;
37  using super_t::os_;
38  using super_t::ps_;
39  using super_t::ws_;
40 
41  using super_t::super_t;
42 
46  void print_finitial_(const std::string& kind, const weight_t& w) const
47  {
48  if (!ws_.is_zero(w))
49  {
50  os_ << ',' << kind;
51  if (ws_.show_one() || !ws_.is_one(w))
52  {
53  os_ << ',' << kind << " text=$\\left\\langle ";
54  ws_.print(w, os_, format::latex) << "\\right\\rangle$";
55  }
56  }
57  }
58 
59  void operator()()
60  {
61  os_ <<
62  "\\documentclass{standalone}\n"
63  " \\usepackage{tikz}\n"
64  " \\usetikzlibrary{arrows.meta, automata, bend,"
65  " positioning, shapes.misc}\n"
66  " \\tikzstyle{automaton}=[shorten >=1pt,"
67  " >={Stealth[bend,round]}, initial text=]\n"
68  " \\tikzstyle{accepting}=[accepting by arrow]\n"
69  "\n"
70  "\\begin{document}\n"
71  "\\begin{tikzpicture}[automaton, auto]\n"
72  ;
73 
74  print_states_();
76 
77  os_ <<
78  "\\end{tikzpicture}\n"
79  "\\end{document}";
80  }
81 
82  private:
84  void print_states_() const
85  {
86  state_t prev = aut_->null_state();
87  for (auto s : aut_->states())
88  {
89  os_ << " \\node[state";
90  print_finitial_("initial", aut_->get_initial_weight(s));
91  print_finitial_("accepting", aut_->get_final_weight(s));
92  if (aut_->state_has_name(s))
93  os_ << ",rounded rectangle";
94  os_ << "] (";
95  aut_->print_state(s, os_);
96  os_ << ')';
97  if (prev != aut_->null_state())
98  {
99  os_ << " [right=of ";
100  aut_->print_state(prev, os_);
101  os_ << ']';
102  }
103  os_ << " {$";
104  aut_->print_state_name(s, os_, format::latex);
105  os_ << "$};\n";
106  prev = s;
107  }
108  }
109 
111  void print_transitions_(const state_t src, const state_t dst,
112  const polynomial_t& entry) const
113  {
114  os_ << " \\path[->] (";
115  aut_->print_state(src, os_);
116  os_ << ") edge"
117  << (src == dst ? "[loop above]" : "")
118  << " node"
119  << " {$";
120  ps_.print(entry, os_, format::latex, ", ");
121  os_ << "$} (";
122  aut_->print_state(dst, os_);
123  os_ << ");\n";
124  }
125 
128  {
129  // For each src state, the destinations, sorted.
130  std::map<state_t, polynomial_t> dsts;
131  for (auto src : aut_->states())
132  {
133  dsts.clear();
134  for (auto t: aut_->out(src))
135  // Bypass weight_of(set), because we know that the weight is
136  // nonzero, and that there is only one weight per letter.
137  ps_.new_weight(dsts[aut_->dst_of(t)],
138  aut_->label_of(t), aut_->weight_of(t));
139  for (const auto& p: dsts)
140  print_transitions_(src, p.first, p.second);
141  }
142  }
143  };
144  }
145 
149  template <typename AutPtr>
150  std::ostream&
151  tikz(const AutPtr& aut, std::ostream& out)
152  {
153  detail::tikzer<AutPtr> t{aut, out};
154  t();
155  return out;
156  }
157 }
automaton_t aut_
The automaton we have to output.
Definition: grail.hh:124
void print_finitial_(const std::string &kind, const weight_t &w) const
Format an initial/final weight.
Definition: tikz.hh:46
std::ostream & tikz(const AutPtr &aut, std::ostream &out)
Print automaton to TikZ format.
Definition: tikz.hh:151
void print_states_() const
Pretty-print states.
Definition: tikz.hh:84
Format automaton to TikZ format.
Definition: tikz.hh:26
state_t_of< automaton_t > state_t
Definition: grail.hh:41
void print_transitions_()
Print all the transitions, sorted by src state, then dst state.
Definition: tikz.hh:127
void operator()()
Definition: tikz.hh:59
const polynomialset_t ps_
Short-hand to the polynomialset used to print the entries.
Definition: grail.hh:132
const weightset_t & ws_
Short-hand to the weightset.
Definition: grail.hh:130
std::ostream & os_
Output stream.
Definition: grail.hh:126
transition_t_of< automaton_t > transition_t
Definition: grail.hh:46
typename polynomialset_t::value_t polynomial_t
Definition: grail.hh:50
void print_transitions_(const state_t src, const state_t dst, const polynomial_t &entry) const
Print the transitions between state src and state dst.
Definition: tikz.hh:111
weight_t_of< automaton_t > weight_t
Definition: grail.hh:48
Factor common bits in automaton formatting.
Definition: grail.hh:28