module ToDot def self.escape str str.gsub(/([<>{} |\\])/) { "\\"+$1 } end end class String def to_dot_label; '\"'+ToDot::escape(self)+'\"'; end end class Array def to_dot_label; "..."; end def to_dot_edge src, shorten " #{src}" + (shorten ? "" : ":#{object_id}") + " -> #{object_id};\n" end def to_dot_subgraph return "" if nil ary = self[0].is_a?(Array) shorten = !ary && self[1..-1].detect{|o| !o.is_a?(Array)} == nil s = " #{object_id} [label=\"" if shorten s += self[0].to_dot_label + "\", shape=rect];\n" else s += collect { |o| "<#{o.object_id}> " + o.to_dot_label }.join("|") s += "\"];\n" end s += collect {|o| o.to_dot_edge(object_id,shorten) }.join s += collect {|o| o.to_dot_subgraph }.join s end end class Object def to_dot_subgraph; end def to_dot_edge src, shorten; end def to_dot_label; ToDot::escape(to_s); end def to_dot s = "digraph G {\n" s += " node [shape=record style=filled fillcolor=lightblue " s += "fontname=Verdana height=0.05 fontsize=10.0 ];\n" s += to_a.to_dot_subgraph s += "}\n" end end