21 #ifndef FST_SCRIPT_DRAW_IMPL_H_ 22 #define FST_SCRIPT_DRAW_IMPL_H_ 36 #include <string_view> 45 using Label =
typename Arc::Label;
51 std::string_view title,
float width,
float height,
bool portrait,
52 bool vertical,
float ranksep,
float nodesep,
int fontsize,
53 int precision, std::string_view float_format,
59 accep_(accep && fst.Properties(
kAcceptor, true)),
68 precision_(precision),
69 float_format_(float_format),
70 show_weight_one_(show_weight_one) {}
73 void Draw(std::ostream &strm, std::string_view dest) {
75 dest_ = std::string(dest);
76 const auto start = fst_.
Start();
78 strm <<
"digraph FST {\n";
80 strm <<
"rankdir = BT;\n";
82 strm <<
"rankdir = LR;\n";
84 strm <<
"size = \"" << width_ <<
"," << height_ <<
"\";\n";
85 if (!title_.empty()) strm <<
"label = \"" + title_ +
"\";\n";
86 strm <<
"center = 1;\n";
88 strm <<
"orientation = Portrait;\n";
90 strm <<
"orientation = Landscape;\n";
92 strm <<
"ranksep = \"" << ranksep_ <<
"\";\n" 93 <<
"nodesep = \"" << nodesep_ <<
"\";\n";
95 DrawState(strm, start);
97 const auto s = siter.Value();
98 if (s != start) DrawState(strm, s);
104 void SetStreamState(std::ostream &strm)
const {
105 strm << std::setprecision(precision_);
106 if (float_format_ ==
"e") strm << std::scientific;
107 if (float_format_ ==
"f") strm << std::fixed;
113 static std::string Escape(std::string_view str) {
116 if (c ==
'\\' || c ==
'"') ns.push_back(
'\\');
124 auto symbol = syms->
Find(
id);
125 if (symbol.empty()) {
126 FSTERROR() <<
"FstDrawer: Integer " <<
id 127 <<
" is not mapped to any textual symbol" 128 <<
", symbol table = " << syms->
Name()
129 <<
", destination = " << dest_;
132 return Escape(symbol);
134 return std::to_string(
id);
138 std::string FormatStateId(
StateId s)
const {
return FormatId(s, ssyms_); }
140 std::string FormatILabel(
Label label)
const {
141 return FormatId(label, isyms_);
144 std::string FormatOLabel(
Label label)
const {
145 return FormatId(label, osyms_);
148 std::string FormatWeight(
Weight w)
const {
149 std::stringstream ss;
153 return Escape(ss.str());
156 void DrawState(std::ostream &strm,
StateId s)
const {
157 strm << s <<
" [label = \"" << FormatStateId(s);
158 const auto weight = fst_.
Final(s);
159 if (weight != Weight::Zero()) {
160 if (show_weight_one_ || (weight != Weight::One())) {
161 strm <<
"/" << FormatWeight(weight);
163 strm <<
"\", shape = doublecircle,";
165 strm <<
"\", shape = circle,";
167 if (s == fst_.
Start()) {
168 strm <<
" style = bold,";
170 strm <<
" style = solid,";
172 strm <<
" fontsize = " << fontsize_ <<
"]\n";
174 const auto &arc = aiter.Value();
175 strm <<
"\t" << s <<
" -> " << arc.nextstate <<
" [label = \"" 176 << FormatILabel(arc.ilabel);
178 strm <<
":" << FormatOLabel(arc.olabel);
180 if (show_weight_one_ || (arc.weight != Weight::One())) {
181 strm <<
"/" << FormatWeight(arc.weight);
183 strm <<
"\", fontsize = " << fontsize_ <<
"];\n";
203 std::string float_format_;
204 bool show_weight_one_;
212 #endif // FST_SCRIPT_DRAW_IMPL_H_ const std::string & Name() const
typename Arc::Weight Weight
virtual Weight Final(StateId) const =0
FstDrawer(const Fst< Arc > &fst, const SymbolTable *isyms, const SymbolTable *osyms, const SymbolTable *ssyms, bool accep, std::string_view title, float width, float height, bool portrait, bool vertical, float ranksep, float nodesep, int fontsize, int precision, std::string_view float_format, bool show_weight_one)
virtual StateId Start() const =0
typename Arc::StateId StateId
std::string Find(int64_t key) const
typename Arc::Label Label
void Draw(std::ostream &strm, std::string_view dest)
constexpr uint64_t kAcceptor